aboutsummaryrefslogtreecommitdiff
path: root/hw/scsi/virtio-scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/scsi/virtio-scsi.c')
-rw-r--r--hw/scsi/virtio-scsi.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 358c0e70b0..6d80730287 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -500,6 +500,51 @@ static void virtio_scsi_complete_cmd_req(VirtIOSCSIReq *req)
virtio_scsi_complete_req(req);
}
+static void virtio_scsi_command_failed(SCSIRequest *r)
+{
+ VirtIOSCSIReq *req = r->hba_private;
+
+ if (r->io_canceled) {
+ return;
+ }
+
+ req->resp.cmd.status = GOOD;
+ switch (r->host_status) {
+ case SCSI_HOST_NO_LUN:
+ req->resp.cmd.response = VIRTIO_SCSI_S_INCORRECT_LUN;
+ break;
+ case SCSI_HOST_BUSY:
+ req->resp.cmd.response = VIRTIO_SCSI_S_BUSY;
+ break;
+ case SCSI_HOST_TIME_OUT:
+ case SCSI_HOST_ABORTED:
+ req->resp.cmd.response = VIRTIO_SCSI_S_ABORTED;
+ break;
+ case SCSI_HOST_BAD_RESPONSE:
+ req->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET;
+ break;
+ case SCSI_HOST_RESET:
+ req->resp.cmd.response = VIRTIO_SCSI_S_RESET;
+ break;
+ case SCSI_HOST_TRANSPORT_DISRUPTED:
+ req->resp.cmd.response = VIRTIO_SCSI_S_TRANSPORT_FAILURE;
+ break;
+ case SCSI_HOST_TARGET_FAILURE:
+ req->resp.cmd.response = VIRTIO_SCSI_S_TARGET_FAILURE;
+ break;
+ case SCSI_HOST_RESERVATION_ERROR:
+ req->resp.cmd.response = VIRTIO_SCSI_S_NEXUS_FAILURE;
+ break;
+ case SCSI_HOST_ALLOCATION_FAILURE:
+ case SCSI_HOST_MEDIUM_ERROR:
+ case SCSI_HOST_ERROR:
+ default:
+ req->resp.cmd.response = VIRTIO_SCSI_S_FAILURE;
+ break;
+ }
+ virtio_scsi_complete_cmd_req(req);
+}
+
static void virtio_scsi_command_complete(SCSIRequest *r, size_t resid)
{
VirtIOSCSIReq *req = r->hba_private;
@@ -908,6 +953,7 @@ static struct SCSIBusInfo virtio_scsi_scsi_info = {
.max_lun = VIRTIO_SCSI_MAX_LUN,
.complete = virtio_scsi_command_complete,
+ .fail = virtio_scsi_command_failed,
.cancel = virtio_scsi_request_cancelled,
.change = virtio_scsi_change,
.parse_cdb = virtio_scsi_parse_cdb,