diff options
author | Jarkko Lavinen <jarkko.lavinen@iki.fi> | 2016-06-28 21:51:52 +0300 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-07-12 18:31:26 +0200 |
commit | 297b044a7fccd1571cf94713a7caf2fc1a980841 (patch) | |
tree | b6da155b287cff3504e1c1c7c648e5671fa4b911 /hw/scsi/scsi-bus.c | |
parent | a91a4e7d8cfe6ece610aacf7c52738188f5b5cb5 (diff) |
scsi-bus: Add SCSI scanner support
Add support for missing scanner specific SCSI commands and their xfer
lenghts as per ANSI spec section 15.
Signed-off-by: Jarkko Lavinen <jarkko.lavinen@iki.fi>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/scsi/scsi-bus.c')
-rw-r--r-- | hw/scsi/scsi-bus.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index ad6f398c32..14c0aa557f 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -1132,6 +1132,29 @@ static int scsi_req_medium_changer_xfer(SCSICommand *cmd, SCSIDevice *dev, uint8 return 0; } +static int scsi_req_scanner_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf) +{ + switch (buf[0]) { + /* Scanner commands */ + case OBJECT_POSITION: + cmd->xfer = 0; + break; + case SCAN: + cmd->xfer = buf[4]; + break; + case READ_10: + case SEND: + case GET_WINDOW: + case SET_WINDOW: + cmd->xfer = buf[8] | (buf[7] << 8) | (buf[6] << 16); + break; + default: + /* GET_DATA_BUFFER_STATUS xfer handled by scsi_req_xfer */ + return scsi_req_xfer(cmd, dev, buf); + } + + return 0; +} static void scsi_cmd_xfer_mode(SCSICommand *cmd) { @@ -1178,6 +1201,11 @@ static void scsi_cmd_xfer_mode(SCSICommand *cmd) case SEND_DVD_STRUCTURE: case PERSISTENT_RESERVE_OUT: case MAINTENANCE_OUT: + case SET_WINDOW: + case SCAN: + /* SCAN conflicts with START_STOP. START_STOP has cmd->xfer set to 0 for + * non-scanner devices, so we only get here for SCAN and not for START_STOP. + */ cmd->mode = SCSI_XFER_TO_DEV; break; case ATA_PASSTHROUGH_12: @@ -1258,6 +1286,9 @@ int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf) case TYPE_MEDIUM_CHANGER: rc = scsi_req_medium_changer_xfer(cmd, dev, buf); break; + case TYPE_SCANNER: + rc = scsi_req_scanner_length(cmd, dev, buf); + break; default: rc = scsi_req_xfer(cmd, dev, buf); break; |