aboutsummaryrefslogtreecommitdiff
path: root/scsi/utils.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2021-02-24 16:30:09 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2021-02-25 14:14:32 +0100
commitd7a84021db8eeddcd5d24ab591a1434763caff6c (patch)
treeb176dbb666400680650b9f5a0fc8b22855ffcb65 /scsi/utils.c
parent424740def9a42da88550410de9a41ef07cc4a010 (diff)
downloadqemu-d7a84021db8eeddcd5d24ab591a1434763caff6c.zip
qemu-d7a84021db8eeddcd5d24ab591a1434763caff6c.tar.gz
qemu-d7a84021db8eeddcd5d24ab591a1434763caff6c.tar.bz2
scsi: introduce scsi_sense_from_errno()
The new function is an extension of the switch statement in scsi-disk.c which also includes the errno cases only found in sg_io_sense_from_errno. This allows us to consolidate the errno handling. Extracted from a patch by Hannes Reinecke <hare@suse.de>. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'scsi/utils.c')
-rw-r--r--scsi/utils.c51
1 files changed, 41 insertions, 10 deletions
diff --git a/scsi/utils.c b/scsi/utils.c
index 793c3a6..6b56e01 100644
--- a/scsi/utils.c
+++ b/scsi/utils.c
@@ -565,21 +565,52 @@ const char *scsi_command_name(uint8_t cmd)
return names[cmd];
}
+int scsi_sense_from_errno(int errno_value, SCSISense *sense)
+{
+ switch (errno_value) {
+ case 0:
+ return GOOD;
+ case EDOM:
+ return TASK_SET_FULL;
+#ifdef CONFIG_LINUX
+ /* These errno mapping are specific to Linux. For more information:
+ * - scsi_decide_disposition in drivers/scsi/scsi_error.c
+ * - scsi_result_to_blk_status in drivers/scsi/scsi_lib.c
+ * - blk_errors[] in block/blk-core.c
+ */
+ case EBADE:
+ return RESERVATION_CONFLICT;
+ case ENODATA:
+ *sense = SENSE_CODE(READ_ERROR);
+ return CHECK_CONDITION;
+ case EREMOTEIO:
+ *sense = SENSE_CODE(LUN_COMM_FAILURE);
+ return CHECK_CONDITION;
+#endif
+ case ENOMEDIUM:
+ *sense = SENSE_CODE(NO_MEDIUM);
+ return CHECK_CONDITION;
+ case ENOMEM:
+ *sense = SENSE_CODE(TARGET_FAILURE);
+ return CHECK_CONDITION;
+ case EINVAL:
+ *sense = SENSE_CODE(INVALID_FIELD);
+ return CHECK_CONDITION;
+ case ENOSPC:
+ *sense = SENSE_CODE(SPACE_ALLOC_FAILED);
+ return CHECK_CONDITION;
+ default:
+ *sense = SENSE_CODE(IO_ERROR);
+ return CHECK_CONDITION;
+ }
+}
+
#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;
- }
+ return scsi_sense_from_errno(errno_value, sense);
} else {
if (io_hdr->host_status == SG_ERR_DID_NO_CONNECT ||
io_hdr->host_status == SG_ERR_DID_BUS_BUSY ||