diff options
Diffstat (limited to 'scsi')
-rw-r--r-- | scsi/utils.c | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/scsi/utils.c b/scsi/utils.c index 793c3a6b9c..6b56e01002 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 || |