diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-07-14 13:44:06 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-07-14 13:44:06 +0100 |
commit | 190c93c98283e75e1a9e01babd1ec14624cb6204 (patch) | |
tree | 076088bb5b665d34db5920a1c3ca03071ae59289 /hw/scsi | |
parent | 9358450e98ed4a5350df4754863d116ff2e6186c (diff) | |
parent | 2aece63c8a9d2c3a8ff41d2febc4cdeff2633331 (diff) |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* SCSI scanner support
* fixes to qemu-char and net exit
* FreeBSD fixes
* Other small bugfixes
# gpg: Signature made Wed 13 Jul 2016 12:30:11 BST
# gpg: using RSA key 0xBFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* remotes/bonzini/tags/for-upstream:
hostmem: detect host backend memory is being used properly
hostmem: fix QEMU crash by 'info memdev'
char: do not use atexit cleanup handler
net: do not use atexit for cleanup
slirp: use exit notifier for slirp_smb_cleanup
tap: use an exit notifier to call down_script
util: Fix MIN_NON_ZERO
qemu-sockets: use qapi_free_SocketAddress in cleanup
disas: avoid including everything in headers compiled from C++
json-streamer: fix double-free on exiting during a parse
main-loop: check return value before using pointer
Use "-s" instead of "--quiet" to resolve non-fatal build error on FreeBSD.
scsi-bus: Use longer sense buffer with scanners
scsi-bus: Add SCSI scanner support
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/scsi')
-rw-r--r-- | hw/scsi/scsi-bus.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index ad6f398c32..297216dfcb 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -461,6 +461,14 @@ static bool scsi_target_emulate_inquiry(SCSITargetReq *r) return true; } +static size_t scsi_sense_len(SCSIRequest *req) +{ + if (req->dev->type == TYPE_SCANNER) + return SCSI_SENSE_LEN_SCANNER; + else + return SCSI_SENSE_LEN; +} + static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf) { SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req); @@ -477,7 +485,7 @@ static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf) } break; case REQUEST_SENSE: - scsi_target_alloc_buf(&r->req, SCSI_SENSE_LEN); + scsi_target_alloc_buf(&r->req, scsi_sense_len(req)); r->len = scsi_device_get_sense(r->req.dev, r->buf, MIN(req->cmd.xfer, r->buf_len), (req->cmd.buf[1] & 1) == 0); @@ -1132,6 +1140,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 +1209,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 +1294,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; |