* [Qemu-devel] [PATCH 1/5] scsi-bus: prepare scsi_req_new for introduction of parse_cdb
2014-07-16 12:54 [Qemu-devel] [PATCH for-2.2 0/5] scsi: enable passthrough of vendor-specific commands Paolo Bonzini
@ 2014-07-16 12:54 ` Paolo Bonzini
2014-07-16 12:54 ` [Qemu-devel] [PATCH 2/5] scsi-bus: introduce parse_cdb in SCSIDeviceClass and SCSIBusInfo Paolo Bonzini
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Paolo Bonzini @ 2014-07-16 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: TAMUKI Shoichi
The per-SCSIDevice parse_cdb callback must not be called if the
request will go through special SCSIReqOps, so detect the special
cases early enough.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/scsi/scsi-bus.c | 44 +++++++++++++++++++++++++-------------------
1 file changed, 25 insertions(+), 19 deletions(-)
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 4341754..bf7ba8c 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -561,9 +561,32 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
uint8_t *buf, void *hba_private)
{
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
+ const SCSIReqOps *ops;
SCSIRequest *req;
SCSICommand cmd;
+ if ((d->unit_attention.key == UNIT_ATTENTION ||
+ bus->unit_attention.key == UNIT_ATTENTION) &&
+ (buf[0] != INQUIRY &&
+ buf[0] != REPORT_LUNS &&
+ buf[0] != GET_CONFIGURATION &&
+ buf[0] != GET_EVENT_STATUS_NOTIFICATION &&
+
+ /*
+ * If we already have a pending unit attention condition,
+ * report this one before triggering another one.
+ */
+ !(buf[0] == REQUEST_SENSE && d->sense_is_ua))) {
+ ops = &reqops_unit_attention;
+ } else if (lun != d->lun ||
+ buf[0] == REPORT_LUNS ||
+ (buf[0] == REQUEST_SENSE && d->sense_len)) {
+ ops = &reqops_target_command;
+ } else {
+ ops = NULL;
+ }
+
+
if (scsi_req_parse(&cmd, d, buf) != 0) {
trace_scsi_req_parse_bad(d->id, lun, tag, buf[0]);
req = scsi_req_alloc(&reqops_invalid_opcode, d, tag, lun, hba_private);
@@ -577,25 +600,8 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
if (cmd.xfer > INT32_MAX) {
req = scsi_req_alloc(&reqops_invalid_field, d, tag, lun, hba_private);
- } else if ((d->unit_attention.key == UNIT_ATTENTION ||
- bus->unit_attention.key == UNIT_ATTENTION) &&
- (buf[0] != INQUIRY &&
- buf[0] != REPORT_LUNS &&
- buf[0] != GET_CONFIGURATION &&
- buf[0] != GET_EVENT_STATUS_NOTIFICATION &&
-
- /*
- * If we already have a pending unit attention condition,
- * report this one before triggering another one.
- */
- !(buf[0] == REQUEST_SENSE && d->sense_is_ua))) {
- req = scsi_req_alloc(&reqops_unit_attention, d, tag, lun,
- hba_private);
- } else if (lun != d->lun ||
- buf[0] == REPORT_LUNS ||
- (buf[0] == REQUEST_SENSE && d->sense_len)) {
- req = scsi_req_alloc(&reqops_target_command, d, tag, lun,
- hba_private);
+ } else if (ops) {
+ req = scsi_req_alloc(ops, d, tag, lun, hba_private);
} else {
req = scsi_device_alloc_req(d, tag, lun, buf, hba_private);
}
--
1.9.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 2/5] scsi-bus: introduce parse_cdb in SCSIDeviceClass and SCSIBusInfo
2014-07-16 12:54 [Qemu-devel] [PATCH for-2.2 0/5] scsi: enable passthrough of vendor-specific commands Paolo Bonzini
2014-07-16 12:54 ` [Qemu-devel] [PATCH 1/5] scsi-bus: prepare scsi_req_new for introduction of parse_cdb Paolo Bonzini
@ 2014-07-16 12:54 ` Paolo Bonzini
2014-07-16 12:54 ` [Qemu-devel] [PATCH 3/5] scsi-block: extract scsi_block_is_passthrough Paolo Bonzini
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Paolo Bonzini @ 2014-07-16 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: TAMUKI Shoichi
These callbacks will let devices do their own request parsing, or
defer it to the bus. If the bus does not provide an implementation,
in turn, fall back to the default parsing routine.
Swap the first two arguments to scsi_req_parse, and rename it to
scsi_req_parse_cdb, for consistency.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/scsi/scsi-bus.c | 25 ++++++++++++++++++++++---
include/hw/scsi/scsi.h | 6 ++++++
2 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index bf7ba8c..54fbf29 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -9,7 +9,7 @@
static char *scsibus_get_dev_path(DeviceState *dev);
static char *scsibus_get_fw_dev_path(DeviceState *dev);
-static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
+static int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf);
static void scsi_req_dequeue(SCSIRequest *req);
static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len);
static void scsi_target_free_buf(SCSIRequest *req);
@@ -54,6 +54,18 @@ static void scsi_device_destroy(SCSIDevice *s)
}
}
+int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
+ void *hba_private)
+{
+ SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
+
+ if (bus->info->parse_cdb) {
+ return bus->info->parse_cdb(dev, cmd, buf, hba_private);
+ } else {
+ return scsi_req_parse_cdb(dev, cmd, buf);
+ }
+}
+
static SCSIRequest *scsi_device_alloc_req(SCSIDevice *s, uint32_t tag, uint32_t lun,
uint8_t *buf, void *hba_private)
{
@@ -562,8 +574,10 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
{
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
const SCSIReqOps *ops;
+ SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(d);
SCSIRequest *req;
SCSICommand cmd;
+ int ret;
if ((d->unit_attention.key == UNIT_ATTENTION ||
bus->unit_attention.key == UNIT_ATTENTION) &&
@@ -586,8 +600,13 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
ops = NULL;
}
+ if (ops != NULL || !sc->parse_cdb) {
+ ret = scsi_req_parse_cdb(d, &cmd, buf);
+ } else {
+ ret = sc->parse_cdb(d, &cmd, buf, hba_private);
+ }
- if (scsi_req_parse(&cmd, d, buf) != 0) {
+ if (ret != 0) {
trace_scsi_req_parse_bad(d->id, lun, tag, buf[0]);
req = scsi_req_alloc(&reqops_invalid_opcode, d, tag, lun, hba_private);
} else {
@@ -1188,7 +1207,7 @@ static uint64_t scsi_cmd_lba(SCSICommand *cmd)
return lba;
}
-static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
+static int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf)
{
int rc;
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 1adb549..4a0b860 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -76,6 +76,8 @@ typedef struct SCSIDeviceClass {
DeviceClass parent_class;
int (*init)(SCSIDevice *dev);
void (*destroy)(SCSIDevice *s);
+ int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
+ void *hba_private);
SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
uint8_t *buf, void *hba_private);
void (*unit_attention_reported)(SCSIDevice *s);
@@ -131,6 +133,8 @@ struct SCSIReqOps {
struct SCSIBusInfo {
int tcq;
int max_channel, max_target, max_lun;
+ int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
+ void *hba_private);
void (*transfer_data)(SCSIRequest *req, uint32_t arg);
void (*complete)(SCSIRequest *req, uint32_t arg, size_t resid);
void (*cancel)(SCSIRequest *req);
@@ -244,6 +248,8 @@ void scsi_req_free(SCSIRequest *req);
SCSIRequest *scsi_req_ref(SCSIRequest *req);
void scsi_req_unref(SCSIRequest *req);
+int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
+ void *hba_private);
void scsi_req_build_sense(SCSIRequest *req, SCSISense sense);
void scsi_req_print(SCSIRequest *req);
void scsi_req_continue(SCSIRequest *req);
--
1.9.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 3/5] scsi-block: extract scsi_block_is_passthrough
2014-07-16 12:54 [Qemu-devel] [PATCH for-2.2 0/5] scsi: enable passthrough of vendor-specific commands Paolo Bonzini
2014-07-16 12:54 ` [Qemu-devel] [PATCH 1/5] scsi-bus: prepare scsi_req_new for introduction of parse_cdb Paolo Bonzini
2014-07-16 12:54 ` [Qemu-devel] [PATCH 2/5] scsi-bus: introduce parse_cdb in SCSIDeviceClass and SCSIBusInfo Paolo Bonzini
@ 2014-07-16 12:54 ` Paolo Bonzini
2014-07-16 12:54 ` [Qemu-devel] [PATCH 4/5] scsi-block, scsi-generic: implement parse_cdb Paolo Bonzini
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Paolo Bonzini @ 2014-07-16 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: TAMUKI Shoichi
This will be used for both scsi_block_new_request and the scsi-block
implementation of parse_cdb.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/scsi/scsi-disk.c | 38 ++++++++++++++++++++++++++------------
1 file changed, 26 insertions(+), 12 deletions(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index d47ecd6..81b7276 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2501,12 +2501,8 @@ static int scsi_block_initfn(SCSIDevice *dev)
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)
+static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf)
{
- SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
-
switch (buf[0]) {
case READ_6:
case READ_10:
@@ -2523,9 +2519,9 @@ static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
case WRITE_VERIFY_12:
case WRITE_VERIFY_16:
/* If we are not using O_DIRECT, we might read stale data from the
- * host cache if writes were made using other commands than these
- * ones (such as WRITE SAME or EXTENDED COPY, etc.). So, without
- * O_DIRECT everything must go through SG_IO.
+ * host cache if writes were made using other commands than these
+ * ones (such as WRITE SAME or EXTENDED COPY, etc.). So, without
+ * O_DIRECT everything must go through SG_IO.
*/
if (!(bdrv_get_flags(s->qdev.conf.bs) & BDRV_O_NOCACHE)) {
break;
@@ -2542,13 +2538,31 @@ static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
* just make scsi-block operate the same as scsi-generic for them.
*/
if (s->qdev.type != TYPE_ROM) {
- return scsi_req_alloc(&scsi_disk_dma_reqops, &s->qdev, tag, lun,
- hba_private);
+ return false;
}
+ break;
+
+ default:
+ break;
}
- return scsi_req_alloc(&scsi_generic_req_ops, &s->qdev, tag, lun,
- hba_private);
+ return true;
+}
+
+
+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);
+
+ if (scsi_block_is_passthrough(s, buf)) {
+ return scsi_req_alloc(&scsi_generic_req_ops, &s->qdev, tag, lun,
+ hba_private);
+ } else {
+ return scsi_req_alloc(&scsi_disk_dma_reqops, &s->qdev, tag, lun,
+ hba_private);
+ }
}
#endif
--
1.9.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 4/5] scsi-block, scsi-generic: implement parse_cdb
2014-07-16 12:54 [Qemu-devel] [PATCH for-2.2 0/5] scsi: enable passthrough of vendor-specific commands Paolo Bonzini
` (2 preceding siblings ...)
2014-07-16 12:54 ` [Qemu-devel] [PATCH 3/5] scsi-block: extract scsi_block_is_passthrough Paolo Bonzini
@ 2014-07-16 12:54 ` Paolo Bonzini
2014-07-16 12:54 ` [Qemu-devel] [PATCH 5/5] virtio-scsi: " Paolo Bonzini
2014-07-18 12:17 ` [Qemu-devel] [PATCH for-2.2 0/5] scsi: enable passthrough of vendor-specific commands TAMUKI Shoichi
5 siblings, 0 replies; 7+ messages in thread
From: Paolo Bonzini @ 2014-07-16 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: TAMUKI Shoichi
The callback lets the bus provide the direction and transfer count
for passthrough commands, enabling passthrough of vendor-specific
commands.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/scsi/scsi-bus.c | 3 +--
hw/scsi/scsi-disk.c | 14 ++++++++++++++
hw/scsi/scsi-generic.c | 7 +++++++
include/hw/scsi/scsi.h | 1 +
4 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 54fbf29..6167bea 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -9,7 +9,6 @@
static char *scsibus_get_dev_path(DeviceState *dev);
static char *scsibus_get_fw_dev_path(DeviceState *dev);
-static int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf);
static void scsi_req_dequeue(SCSIRequest *req);
static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len);
static void scsi_target_free_buf(SCSIRequest *req);
@@ -1207,7 +1206,7 @@ static uint64_t scsi_cmd_lba(SCSICommand *cmd)
return lba;
}
-static int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf)
+int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf)
{
int rc;
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 81b7276..d55521d 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2564,6 +2564,19 @@ static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
hba_private);
}
}
+
+static int scsi_block_parse_cdb(SCSIDevice *d, SCSICommand *cmd,
+ uint8_t *buf, void *hba_private)
+{
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
+
+ if (scsi_block_is_passthrough(s, buf)) {
+ return scsi_bus_parse_cdb(&s->qdev, cmd, buf, hba_private);
+ } else {
+ return scsi_req_parse_cdb(&s->qdev, cmd, buf);
+ }
+}
+
#endif
#define DEFINE_SCSI_DISK_PROPERTIES() \
@@ -2672,6 +2685,7 @@ static void scsi_block_class_initfn(ObjectClass *klass, void *data)
sc->init = scsi_block_initfn;
sc->destroy = scsi_destroy;
sc->alloc_req = scsi_block_new_request;
+ sc->parse_cdb = scsi_block_parse_cdb;
dc->fw_name = "disk";
dc->desc = "SCSI block device passthrough";
dc->reset = scsi_disk_reset;
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 3733d2c..0b2ff90 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -490,6 +490,12 @@ static Property scsi_generic_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
+static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
+ uint8_t *buf, void *hba_private)
+{
+ return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
+}
+
static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -498,6 +504,7 @@ static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
sc->init = scsi_generic_initfn;
sc->destroy = scsi_destroy;
sc->alloc_req = scsi_new_request;
+ sc->parse_cdb = scsi_generic_parse_cdb;
dc->fw_name = "disk";
dc->desc = "pass through generic scsi device (/dev/sg*)";
dc->reset = scsi_generic_reset;
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 4a0b860..a7a28e6 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -250,6 +250,7 @@ void scsi_req_unref(SCSIRequest *req);
int scsi_bus_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
void *hba_private);
+int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf);
void scsi_req_build_sense(SCSIRequest *req, SCSISense sense);
void scsi_req_print(SCSIRequest *req);
void scsi_req_continue(SCSIRequest *req);
--
1.9.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH 5/5] virtio-scsi: implement parse_cdb
2014-07-16 12:54 [Qemu-devel] [PATCH for-2.2 0/5] scsi: enable passthrough of vendor-specific commands Paolo Bonzini
` (3 preceding siblings ...)
2014-07-16 12:54 ` [Qemu-devel] [PATCH 4/5] scsi-block, scsi-generic: implement parse_cdb Paolo Bonzini
@ 2014-07-16 12:54 ` Paolo Bonzini
2014-07-18 12:17 ` [Qemu-devel] [PATCH for-2.2 0/5] scsi: enable passthrough of vendor-specific commands TAMUKI Shoichi
5 siblings, 0 replies; 7+ messages in thread
From: Paolo Bonzini @ 2014-07-16 12:54 UTC (permalink / raw)
To: qemu-devel; +Cc: TAMUKI Shoichi
Enable passthrough of vendor-specific commands.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/scsi/virtio-scsi.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 0eb069a..e8f4c0c 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -406,6 +406,29 @@ static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
virtio_scsi_complete_cmd_req(req);
}
+static int virtio_scsi_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
+ uint8_t *buf, void *hba_private)
+{
+ VirtIOSCSIReq *req = hba_private;
+
+ cmd->lba = -1;
+ cmd->len = MIN(VIRTIO_SCSI_CDB_SIZE, SCSI_CMD_BUF_SIZE);
+ memcpy(cmd->buf, buf, cmd->len);
+
+ /* Extract the direction and mode directly from the request, for
+ * host device passthrough.
+ */
+ cmd->xfer = req->qsgl.size;
+ if (cmd->xfer == 0) {
+ cmd->mode = SCSI_XFER_NONE;
+ } else if (iov_size(req->elem.in_sg, req->elem.in_num) > req->resp_size) {
+ cmd->mode = SCSI_XFER_FROM_DEV;
+ } else {
+ cmd->mode = SCSI_XFER_TO_DEV;
+ }
+ return 0;
+}
+
static QEMUSGList *virtio_scsi_get_sg_list(SCSIRequest *r)
{
VirtIOSCSIReq *req = r->hba_private;
@@ -658,6 +681,7 @@ static struct SCSIBusInfo virtio_scsi_scsi_info = {
.change = virtio_scsi_change,
.hotplug = virtio_scsi_hotplug,
.hot_unplug = virtio_scsi_hot_unplug,
+ .parse_cdb = virtio_scsi_parse_cdb,
.get_sg_list = virtio_scsi_get_sg_list,
.save_request = virtio_scsi_save_request,
.load_request = virtio_scsi_load_request,
--
1.9.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH for-2.2 0/5] scsi: enable passthrough of vendor-specific commands
2014-07-16 12:54 [Qemu-devel] [PATCH for-2.2 0/5] scsi: enable passthrough of vendor-specific commands Paolo Bonzini
` (4 preceding siblings ...)
2014-07-16 12:54 ` [Qemu-devel] [PATCH 5/5] virtio-scsi: " Paolo Bonzini
@ 2014-07-18 12:17 ` TAMUKI Shoichi
5 siblings, 0 replies; 7+ messages in thread
From: TAMUKI Shoichi @ 2014-07-18 12:17 UTC (permalink / raw)
To: qemu-devel; +Cc: Paolo Bonzini, TAMUKI Shoichi
Hello,
From: Paolo Bonzini <pbonzini@redhat.com>
Subject: [PATCH for-2.2 0/5] scsi: enable passthrough of vendor-specific commands
Date: Wed, 16 Jul 2014 14:54:45 +0200
> Right now scsi-generic is parsing the CDB, in order to compute
> the expected number of bytes to be transferred. This is necessary
> if DMA is done by the HBA via scsi_req_data, but it prevents executing
> vendor-specific commands via scsi-generic because we don't know how
> to parse them.
>
> If DMA is delegated to the SCSI layer via get_sg_list, we know in
> advance how many bytes the guest will want to receive and we can pass
> the information straight from the guest to SG_IO. In this case, it is
> unnecessary to parse the CDB to get the same information. scsi-disk needs
> it to detect underruns and overruns, but scsi-generic and scsi-block can
> just ask the HBA about the transfer direction and size.
>
> This series introduces a new parse_cdb callback in both the device and
> the HBA. The latter is called by scsi_bus_parse_cdb, which devices can
> call for passthrough requests in their implementation of parse_cdb.
Great, thanks a lot.
> Tamuki-san, can you please test if these patches are okay for your
> usecase?
I tested these patches against 5a73480 (Update version for v2.1.0-rc2
release,) and confirmed that a vendor-specific command sent from the
initiator in a guest successfully reach (at least) the host using
sg_raw and ftrace. That works fine.
Regards,
TAMUKI Shoichi
^ permalink raw reply [flat|nested] 7+ messages in thread