diff options
author | Paolo Bonzini | 2011-08-03 10:49:06 +0200 |
---|---|---|
committer | Anthony Liguori | 2011-08-12 15:27:00 +0200 |
commit | 682a9b213ca3c47c4de5b0518c59c2e550299106 (patch) | |
tree | 3bb4e98871f5fe44a1a3ccb93288548fde22a53b /hw/scsi-generic.c | |
parent | vscsi: always use get_sense (diff) | |
download | qemu-682a9b213ca3c47c4de5b0518c59c2e550299106.tar.gz qemu-682a9b213ca3c47c4de5b0518c59c2e550299106.tar.xz qemu-682a9b213ca3c47c4de5b0518c59c2e550299106.zip |
scsi: pass status when completing
A small improvement in the SCSI request API. Pass the status
at the time the request is completed, so that we can assert that
no request is completed twice. This would have detected the
problem fixed in the previous patch.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw/scsi-generic.c')
-rw-r--r-- | hw/scsi-generic.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 7b0026eb98..71cbfb0a44 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -115,6 +115,7 @@ static void scsi_free_request(SCSIRequest *req) /* Helper function for command completion. */ static void scsi_command_complete(void *opaque, int ret) { + int status; SCSIGenericReq *r = (SCSIGenericReq *)opaque; SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev); @@ -126,36 +127,37 @@ static void scsi_command_complete(void *opaque, int ret) if (ret != 0) { switch (ret) { case -EDOM: - r->req.status = TASK_SET_FULL; + status = TASK_SET_FULL; break; case -EINVAL: - r->req.status = CHECK_CONDITION; + status = CHECK_CONDITION; scsi_set_sense(s, SENSE_CODE(INVALID_FIELD)); break; case -ENOMEM: - r->req.status = CHECK_CONDITION; + status = CHECK_CONDITION; scsi_set_sense(s, SENSE_CODE(TARGET_FAILURE)); break; default: - r->req.status = CHECK_CONDITION; + status = CHECK_CONDITION; scsi_set_sense(s, SENSE_CODE(IO_ERROR)); break; } } else { if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) { - r->req.status = BUSY; + status = BUSY; BADF("Driver Timeout\n"); - } else if (r->io_header.status) - r->req.status = r->io_header.status; - else if (s->driver_status & SG_ERR_DRIVER_SENSE) - r->req.status = CHECK_CONDITION; - else - r->req.status = GOOD; + } else if (r->io_header.status) { + status = r->io_header.status; + } else if (s->driver_status & SG_ERR_DRIVER_SENSE) { + status = CHECK_CONDITION; + } else { + status = GOOD; + } } DPRINTF("Command complete 0x%p tag=0x%x status=%d\n", - r, r->req.tag, r->req.status); + r, r->req.tag, status); - scsi_req_complete(&r->req); + scsi_req_complete(&r->req, status); } /* Cancel a pending data transfer. */ @@ -341,8 +343,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd) if (cmd[0] != REQUEST_SENSE && req->lun != s->lun) { DPRINTF("Unimplemented LUN %d\n", req->lun); scsi_set_sense(s, SENSE_CODE(LUN_NOT_SUPPORTED)); - r->req.status = CHECK_CONDITION; - scsi_req_complete(&r->req); + scsi_req_complete(&r->req, CHECK_CONDITION); return 0; } |