summary refs log tree commit diff stats
path: root/scsi/utils.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2017-08-22 09:43:14 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2017-09-19 14:09:11 +0200
commit1ead6b4e242e59711976cdf2502dd5c7cd5d340a (patch)
tree22f471aaec74e17dbb5ee7bf8187c4228aaee61d /scsi/utils.c
parenta3760467c6b0ff5d1ff952fdc8cec69c65e19499 (diff)
downloadfocaccia-qemu-1ead6b4e242e59711976cdf2502dd5c7cd5d340a.tar.gz
focaccia-qemu-1ead6b4e242e59711976cdf2502dd5c7cd5d340a.zip
scsi: introduce sg_io_sense_from_errno
Move more knowledge of SG_IO out of hw/scsi/scsi-generic.c, for
reusability.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'scsi/utils.c')
-rw-r--r--scsi/utils.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/scsi/utils.c b/scsi/utils.c
index 89d9167d9d..6ee9f4095b 100644
--- a/scsi/utils.c
+++ b/scsi/utils.c
@@ -501,3 +501,38 @@ const char *scsi_command_name(uint8_t cmd)
     }
     return names[cmd];
 }
+
+#ifdef CONFIG_LINUX
+int sg_io_sense_from_errno(int errno_value, struct sg_io_hdr *io_hdr,
+                           SCSISense *sense)
+{
+    if (errno_value != 0) {
+        switch (errno_value) {
+        case EDOM:
+            return TASK_SET_FULL;
+        case ENOMEM:
+            *sense = SENSE_CODE(TARGET_FAILURE);
+            return CHECK_CONDITION;
+        default:
+            *sense = SENSE_CODE(IO_ERROR);
+            return CHECK_CONDITION;
+        }
+    } else {
+        if (io_hdr->host_status == SG_ERR_DID_NO_CONNECT ||
+            io_hdr->host_status == SG_ERR_DID_BUS_BUSY ||
+            io_hdr->host_status == SG_ERR_DID_TIME_OUT ||
+            (io_hdr->driver_status & SG_ERR_DRIVER_TIMEOUT)) {
+            return BUSY;
+        } else if (io_hdr->host_status) {
+            *sense = SENSE_CODE(I_T_NEXUS_LOSS);
+            return CHECK_CONDITION;
+        } else if (io_hdr->status) {
+            return io_hdr->status;
+        } else if (io_hdr->driver_status & SG_ERR_DRIVER_SENSE) {
+            return CHECK_CONDITION;
+        } else {
+            return GOOD;
+        }
+    }
+}
+#endif