From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 35/35] scsi-disk: add scsi-block for device passthrough
Date: Thu, 13 Oct 2011 13:04:05 +0200 [thread overview]
Message-ID: <1318503845-11473-36-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1318503845-11473-1-git-send-email-pbonzini@redhat.com>
scsi-block is a new device that supports device passthrough of Linux
block devices (i.e. /dev/sda, not /dev/sg0). It uses SG_IO for commands
other than I/O commands, and regular AIO read/writes for I/O commands.
Besides being simpler to configure (no mapping required to scsi-generic
device names), this removes the need for a large bounce buffer and,
in the future, will get scatter/gather support for free from scsi-disk.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/scsi-disk.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 111 insertions(+), 0 deletions(-)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 418b30d..b21fe1b 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -39,6 +39,10 @@ do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
#include "blockdev.h"
#include "block_int.h"
+#ifdef __linux
+#include <scsi/sg.h>
+#endif
+
#define SCSI_DMA_BUF_SIZE 131072
#define SCSI_MAX_INQUIRY_LEN 256
@@ -1601,6 +1605,98 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
return req;
}
+#ifdef __linux__
+static int get_device_type(SCSIDiskState *s)
+{
+ BlockDriverState *bdrv = s->qdev.conf.bs;
+ uint8_t cmd[16];
+ uint8_t buf[36];
+ uint8_t sensebuf[8];
+ sg_io_hdr_t io_header;
+ int ret;
+
+ memset(cmd, 0, sizeof(cmd));
+ memset(buf, 0, sizeof(buf));
+ cmd[0] = INQUIRY;
+ cmd[4] = sizeof(buf);
+
+ memset(&io_header, 0, sizeof(io_header));
+ io_header.interface_id = 'S';
+ io_header.dxfer_direction = SG_DXFER_FROM_DEV;
+ io_header.dxfer_len = sizeof(buf);
+ io_header.dxferp = buf;
+ io_header.cmdp = cmd;
+ io_header.cmd_len = sizeof(cmd);
+ io_header.mx_sb_len = sizeof(sensebuf);
+ io_header.sbp = sensebuf;
+ io_header.timeout = 6000; /* XXX */
+
+ ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
+ if (ret < 0 || io_header.driver_status || io_header.host_status) {
+ return -1;
+ }
+ s->qdev.type = buf[0];
+ s->removable = (buf[1] & 0x80) != 0;
+ s->qdev.blocksize = 0;
+ s->qdev.max_lba = 0;
+ return 0;
+}
+
+static int scsi_block_initfn(SCSIDevice *dev)
+{
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+ int sg_version;
+ int rc;
+
+ if (!s->qdev.conf.bs) {
+ error_report("scsi-block: drive property not set");
+ return -1;
+ }
+
+ /* check we are using a driver managing SG_IO (version 3 and after) */
+ if (bdrv_ioctl(s->qdev.conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
+ sg_version < 30000) {
+ error_report("scsi-block: scsi generic interface too old");
+ return -1;
+ }
+
+ /* get device type from INQUIRY data */
+ rc = get_device_type(s);
+ if (rc < 0) {
+ error_report("scsi-block: INQUIRY failed");
+ return -1;
+ }
+
+ return scsi_initfn(&s->qdev);
+}
+
+static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
+ uint32_t lun, uint8_t *buf,
+ void *hba_private)
+{
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
+
+ switch (buf[0]) {
+ case READ_6:
+ case READ_10:
+ case READ_12:
+ case READ_16:
+ case WRITE_6:
+ case WRITE_10:
+ case WRITE_12:
+ case WRITE_16:
+ case WRITE_VERIFY_10:
+ case WRITE_VERIFY_12:
+ case WRITE_VERIFY_16:
+ return scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun,
+ hba_private);
+ }
+
+ return scsi_req_alloc(&scsi_generic_req_ops, &s->qdev, tag, lun,
+ hba_private);
+}
+#endif
+
#define DEFINE_SCSI_DISK_PROPERTIES() \
DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf), \
DEFINE_PROP_STRING("ver", SCSIDiskState, version), \
@@ -1636,6 +1732,21 @@ static SCSIDeviceInfo scsi_disk_info[] = {
DEFINE_SCSI_DISK_PROPERTIES(),
DEFINE_PROP_END_OF_LIST(),
},
+#ifdef __linux__
+ },{
+ .qdev.name = "scsi-block",
+ .qdev.fw_name = "disk",
+ .qdev.desc = "SCSI block device passthrough",
+ .qdev.size = sizeof(SCSIDiskState),
+ .qdev.reset = scsi_disk_reset,
+ .init = scsi_block_initfn,
+ .destroy = scsi_destroy,
+ .alloc_req = scsi_block_new_request,
+ .qdev.props = (Property[]) {
+ DEFINE_SCSI_DISK_PROPERTIES(),
+ DEFINE_PROP_END_OF_LIST(),
+ },
+#endif
},{
.qdev.name = "scsi-disk", /* legacy -device scsi-disk */
.qdev.fw_name = "disk",
--
1.7.6
next prev parent reply other threads:[~2011-10-13 11:07 UTC|newest]
Thread overview: 68+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-13 11:03 [Qemu-devel] [PULL 00/35] SCSI uber-patch Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 01/35] scsi: pass correct sense code for ENOMEDIUM Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 02/35] atapi/scsi: unify definitions for MMC Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 03/35] atapi: move GESN definitions to scsi-defs.h Paolo Bonzini
2011-10-17 13:41 ` Kevin Wolf
2011-10-17 13:53 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 04/35] atapi: fill in AUDIO_CTL page correctly Paolo Bonzini
2011-10-17 14:05 ` Kevin Wolf
2011-10-17 14:04 ` Paolo Bonzini
2011-10-17 14:10 ` Kevin Wolf
2011-10-17 14:22 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 05/35] scsi: notify the device when unit attention is reported Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 06/35] scsi-disk: report media changed via unit attention sense codes Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 07/35] scsi-disk: add stubs for more MMC commands Paolo Bonzini
2011-10-17 14:27 ` Kevin Wolf
2011-10-17 14:28 ` Paolo Bonzini
2011-10-17 14:44 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 08/35] scsi-disk: store valid mode pages in a table Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 09/35] atapi/scsi-disk: make mode page values coherent between the two Paolo Bonzini
2011-10-17 15:05 ` Kevin Wolf
2011-10-17 15:06 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 10/35] scsi-disk: support DVD profile in GET CONFIGURATION Paolo Bonzini
2011-10-17 15:20 ` Kevin Wolf
2011-10-17 15:28 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 11/35] scsi-disk: support READ DVD STRUCTURE Paolo Bonzini
2011-10-21 11:42 ` Kevin Wolf
2011-10-21 13:11 ` Paolo Bonzini
2011-10-21 13:12 ` Paolo Bonzini
2011-10-21 13:32 ` Kevin Wolf
2011-10-21 13:36 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 12/35] scsi-disk: report media changed via GET EVENT STATUS NOTIFICATION Paolo Bonzini
2011-10-21 11:54 ` Kevin Wolf
2011-10-21 13:08 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 13/35] scsi: move tcq/ndev to SCSIBusOps (now SCSIBusInfo) Paolo Bonzini
2011-10-21 12:01 ` Kevin Wolf
2011-10-21 12:21 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 14/35] qdev: switch children device list to QTAILQ Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 15/35] scsi: remove devs array from SCSIBus Paolo Bonzini
2011-10-21 12:31 ` Kevin Wolf
2011-10-21 13:03 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 16/35] scsi: implement REPORT LUNS for arbitrary LUNs Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 17/35] scsi: allow " Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 18/35] scsi: add channel to addressing Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 19/35] scsi-disk: fail READ CAPACITY if LBA != 0 but PMI == 0 Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 20/35] scsi-disk: do not complete requests twice Paolo Bonzini
2011-10-19 13:13 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 21/35] scsi-disk: bump SCSIRequest reference count until aio completion runs Paolo Bonzini
2011-10-17 15:37 ` [Qemu-devel] [PATCH v2 " Paolo Bonzini
2011-10-19 13:13 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 22/35] scsi-disk: fix retrying a flush Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 23/35] scsi-generic: drop SCSIGenericState Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 24/35] scsi-generic: remove scsi_req_fixup Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 25/35] scsi-generic: check ioctl statuses when SG_IO succeeds Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 26/35] scsi-generic: look at host status Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 27/35] scsi-generic: snoop READ CAPACITY commands to get block size Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 28/35] scsi-disk: do not duplicate BlockDriverState member Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 29/35] scsi-disk: remove cluster_size Paolo Bonzini
2011-10-24 15:10 ` Kevin Wolf
2011-10-24 15:36 ` Paolo Bonzini
2011-10-13 11:04 ` [Qemu-devel] [PATCH 30/35] scsi-disk: small clean up to INQUIRY Paolo Bonzini
2011-10-13 11:04 ` [Qemu-devel] [PATCH 31/35] scsi: move max_lba to SCSIDevice Paolo Bonzini
2011-10-13 11:04 ` [Qemu-devel] [PATCH 32/35] scsi: make reqops static const Paolo Bonzini
2011-10-13 11:04 ` [Qemu-devel] [PATCH 33/35] scsi: export scsi_generic_reqops Paolo Bonzini
2011-10-13 11:04 ` [Qemu-devel] [PATCH 34/35] scsi: pass cdb to alloc_req Paolo Bonzini
2011-10-13 11:04 ` Paolo Bonzini [this message]
2011-10-24 15:28 ` [Qemu-devel] [PATCH 35/35] scsi-disk: add scsi-block for device passthrough Kevin Wolf
2011-10-24 15:28 ` Paolo Bonzini
2011-10-24 15:38 ` Kevin Wolf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1318503845-11473-36-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).