diff options
author | Hannes Reinecke <hare@suse.de> | 2020-11-16 19:40:39 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2021-03-06 11:41:54 +0100 |
commit | db66a15cb80f09da24a5311a3f3b8f0c1835bf71 (patch) | |
tree | 06f20faec9f5b7fba7dfdc4c2d05a4156922909a /scsi | |
parent | 41af878b96582fc8c83303ab8921e40468403702 (diff) | |
download | qemu-db66a15cb80f09da24a5311a3f3b8f0c1835bf71.zip qemu-db66a15cb80f09da24a5311a3f3b8f0c1835bf71.tar.gz qemu-db66a15cb80f09da24a5311a3f3b8f0c1835bf71.tar.bz2 |
scsi: Add mapping for generic SCSI_HOST status to sense codes
As we don't have a driver-specific mapping (yet) we should provide
for a detailed mapping from host_status to SCSI sense codes.
Signed-off-by: Hannes Reinecke <hare@suse.de>
Message-Id: <20201116184041.60465-6-hare@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'scsi')
-rw-r--r-- | scsi/utils.c | 65 |
1 files changed, 58 insertions, 7 deletions
diff --git a/scsi/utils.c b/scsi/utils.c index 4d994b6..28eb327 100644 --- a/scsi/utils.c +++ b/scsi/utils.c @@ -257,6 +257,21 @@ const struct SCSISense sense_code_LUN_COMM_FAILURE = { .key = ABORTED_COMMAND, .asc = 0x08, .ascq = 0x00 }; +/* Command aborted, LUN does not respond to selection */ +const struct SCSISense sense_code_LUN_NOT_RESPONDING = { + .key = ABORTED_COMMAND, .asc = 0x05, .ascq = 0x00 +}; + +/* Command aborted, Command Timeout during processing */ +const struct SCSISense sense_code_COMMAND_TIMEOUT = { + .key = ABORTED_COMMAND, .asc = 0x2e, .ascq = 0x02 +}; + +/* Command aborted, Commands cleared by device server */ +const struct SCSISense sense_code_COMMAND_ABORTED = { + .key = ABORTED_COMMAND, .asc = 0x2f, .ascq = 0x02 +}; + /* Medium Error, Unrecovered read error */ const struct SCSISense sense_code_READ_ERROR = { .key = MEDIUM_ERROR, .asc = 0x11, .ascq = 0x00 @@ -605,6 +620,45 @@ int scsi_sense_from_errno(int errno_value, SCSISense *sense) } } +int scsi_sense_from_host_status(uint8_t host_status, + SCSISense *sense) +{ + switch (host_status) { + case SCSI_HOST_NO_LUN: + *sense = SENSE_CODE(LUN_NOT_RESPONDING); + return CHECK_CONDITION; + case SCSI_HOST_BUSY: + return BUSY; + case SCSI_HOST_TIME_OUT: + *sense = SENSE_CODE(COMMAND_TIMEOUT); + return CHECK_CONDITION; + case SCSI_HOST_BAD_RESPONSE: + *sense = SENSE_CODE(LUN_COMM_FAILURE); + return CHECK_CONDITION; + case SCSI_HOST_ABORTED: + *sense = SENSE_CODE(COMMAND_ABORTED); + return CHECK_CONDITION; + case SCSI_HOST_RESET: + *sense = SENSE_CODE(RESET); + return CHECK_CONDITION; + case SCSI_HOST_TRANSPORT_DISRUPTED: + *sense = SENSE_CODE(I_T_NEXUS_LOSS); + return CHECK_CONDITION; + case SCSI_HOST_TARGET_FAILURE: + *sense = SENSE_CODE(TARGET_FAILURE); + return CHECK_CONDITION; + case SCSI_HOST_RESERVATION_ERROR: + return RESERVATION_CONFLICT; + case SCSI_HOST_ALLOCATION_FAILURE: + *sense = SENSE_CODE(SPACE_ALLOC_FAILED); + return CHECK_CONDITION; + case SCSI_HOST_MEDIUM_ERROR: + *sense = SENSE_CODE(READ_ERROR); + return CHECK_CONDITION; + } + return GOOD; +} + #ifdef CONFIG_LINUX int sg_io_sense_from_errno(int errno_value, struct sg_io_hdr *io_hdr, SCSISense *sense) @@ -612,14 +666,11 @@ int sg_io_sense_from_errno(int errno_value, struct sg_io_hdr *io_hdr, if (errno_value != 0) { return scsi_sense_from_errno(errno_value, sense); } else { - if (io_hdr->host_status == SCSI_HOST_NO_LUN || - io_hdr->host_status == SCSI_HOST_BUSY || - io_hdr->host_status == SCSI_HOST_TIME_OUT || - (io_hdr->driver_status & SG_ERR_DRIVER_TIMEOUT)) { + int status = scsi_sense_from_host_status(io_hdr->host_status, sense); + if (status) { + return status; + } else if (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) { |