Signed-off-by: Alexander Bezzubikov <abezzubi...@ispras.ru> --- hw/ide/internal.h | 2 +- hw/scsi/scsi-disk.c | 43 +++++++++++++++++++++++++++++++++++++++++++ include/hw/scsi/scsi.h | 3 +++ 3 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/hw/ide/internal.h b/hw/ide/internal.h index 3ebc63c..fd385bc 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -495,7 +495,7 @@ struct IDEDevice { char *serial; char *model; uint64_t wwn; - SCSIBus *scsi_bus; + SCSIBus scsi_bus; }; /* These are used for the error_status field of IDEBus */ diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 64f0694..f67d816 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -2440,6 +2440,49 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun, return req; } +SCSIRequest *scsi_new_request_from_bridge(SCSIDevice *d, uint32_t tag, + uint32_t lun, uint8_t *buf, + void *hba_private) +{ + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); + SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(d); + SCSIRequest *req; + const SCSIReqOps *ops; + uint8_t command; + + command = buf[0]; + ops = scsi_disk_reqops_dispatch[command]; + if (!ops) { + ops = &scsi_disk_emulate_reqops; + } + req = scsi_req_alloc(ops, &s->qdev, tag, lun, hba_private); + memcpy(req->cmd.buf, buf, 16); + + SCSICommand cmd = { .len = 0 }; + + if (ops != NULL || !sc->parse_cdb) { + scsi_req_parse_cdb(d, &cmd, buf); + } else { + sc->parse_cdb(d, &cmd, buf, hba_private); + } + + req->cmd = cmd; + req->resid = req->cmd.xfer; + + #ifdef DEBUG_SCSI + DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]); + { + int i; + for (i = 1; i < scsi_cdb_length(buf); i++) { + printf(" 0x%02x", buf[i]); + } + printf("\n"); + } + #endif + + return req; +} + #ifdef __linux__ static int get_device_type(SCSIDiskState *s) { diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index cdaf0f8..881ed23 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -249,6 +249,9 @@ SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag, uint32_t lun, void *hba_private); SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun, uint8_t *buf, void *hba_private); +SCSIRequest *scsi_new_request_from_bridge(SCSIDevice *d, uint32_t tag, + uint32_t lun, uint8_t *buf, + void *hba_private); int32_t scsi_req_enqueue(SCSIRequest *req); void scsi_req_free(SCSIRequest *req); SCSIRequest *scsi_req_ref(SCSIRequest *req); -- 2.1.4