提交 ff34c32c 编写于 作者: P Paolo Bonzini

scsi-bus: introduce parse_cdb in SCSIDeviceClass and SCSIBusInfo

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.
Reviewed-by: NFam Zheng <famz@redhat.com>
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
上级 769998a1
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
static char *scsibus_get_dev_path(DeviceState *dev); static char *scsibus_get_dev_path(DeviceState *dev);
static char *scsibus_get_fw_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 void scsi_req_dequeue(SCSIRequest *req);
static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len); static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len);
static void scsi_target_free_buf(SCSIRequest *req); static void scsi_target_free_buf(SCSIRequest *req);
...@@ -54,6 +54,20 @@ static void scsi_device_destroy(SCSIDevice *s) ...@@ -54,6 +54,20 @@ 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);
int rc;
assert(cmd->len == 0);
rc = scsi_req_parse_cdb(dev, cmd, buf);
if (bus->info->parse_cdb) {
rc = bus->info->parse_cdb(dev, cmd, buf, hba_private);
}
return rc;
}
static SCSIRequest *scsi_device_alloc_req(SCSIDevice *s, uint32_t tag, uint32_t lun, static SCSIRequest *scsi_device_alloc_req(SCSIDevice *s, uint32_t tag, uint32_t lun,
uint8_t *buf, void *hba_private) uint8_t *buf, void *hba_private)
{ {
...@@ -562,6 +576,7 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, ...@@ -562,6 +576,7 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
{ {
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus); SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
const SCSIReqOps *ops; const SCSIReqOps *ops;
SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(d);
SCSIRequest *req; SCSIRequest *req;
SCSICommand cmd = { .len = 0 }; SCSICommand cmd = { .len = 0 };
int ret; int ret;
...@@ -587,7 +602,12 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, ...@@ -587,7 +602,12 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
ops = NULL; ops = NULL;
} }
ret = scsi_req_parse(&cmd, d, buf); 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 (ret != 0) { if (ret != 0) {
trace_scsi_req_parse_bad(d->id, lun, tag, 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); req = scsi_req_alloc(&reqops_invalid_opcode, d, tag, lun, hba_private);
...@@ -1190,7 +1210,7 @@ static uint64_t scsi_cmd_lba(SCSICommand *cmd) ...@@ -1190,7 +1210,7 @@ static uint64_t scsi_cmd_lba(SCSICommand *cmd)
return lba; 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; int rc;
......
...@@ -76,6 +76,8 @@ typedef struct SCSIDeviceClass { ...@@ -76,6 +76,8 @@ typedef struct SCSIDeviceClass {
DeviceClass parent_class; DeviceClass parent_class;
int (*init)(SCSIDevice *dev); int (*init)(SCSIDevice *dev);
void (*destroy)(SCSIDevice *s); 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, SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
uint8_t *buf, void *hba_private); uint8_t *buf, void *hba_private);
void (*unit_attention_reported)(SCSIDevice *s); void (*unit_attention_reported)(SCSIDevice *s);
...@@ -131,6 +133,8 @@ struct SCSIReqOps { ...@@ -131,6 +133,8 @@ struct SCSIReqOps {
struct SCSIBusInfo { struct SCSIBusInfo {
int tcq; int tcq;
int max_channel, max_target, max_lun; 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 (*transfer_data)(SCSIRequest *req, uint32_t arg);
void (*complete)(SCSIRequest *req, uint32_t arg, size_t resid); void (*complete)(SCSIRequest *req, uint32_t arg, size_t resid);
void (*cancel)(SCSIRequest *req); void (*cancel)(SCSIRequest *req);
...@@ -244,6 +248,8 @@ void scsi_req_free(SCSIRequest *req); ...@@ -244,6 +248,8 @@ void scsi_req_free(SCSIRequest *req);
SCSIRequest *scsi_req_ref(SCSIRequest *req); SCSIRequest *scsi_req_ref(SCSIRequest *req);
void scsi_req_unref(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_build_sense(SCSIRequest *req, SCSISense sense);
void scsi_req_print(SCSIRequest *req); void scsi_req_print(SCSIRequest *req);
void scsi_req_continue(SCSIRequest *req); void scsi_req_continue(SCSIRequest *req);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册