diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2017-08-22 09:43:14 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2017-09-19 14:09:11 +0200 |
commit | 1ead6b4e242e59711976cdf2502dd5c7cd5d340a (patch) | |
tree | 22f471aaec74e17dbb5ee7bf8187c4228aaee61d /scsi | |
parent | a3760467c6b0ff5d1ff952fdc8cec69c65e19499 (diff) | |
download | qemu-1ead6b4e242e59711976cdf2502dd5c7cd5d340a.zip qemu-1ead6b4e242e59711976cdf2502dd5c7cd5d340a.tar.gz qemu-1ead6b4e242e59711976cdf2502dd5c7cd5d340a.tar.bz2 |
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')
-rw-r--r-- | scsi/utils.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/scsi/utils.c b/scsi/utils.c index 89d9167..6ee9f40 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 |