From bdf9613b7f87248eb84884b0bdff94e8ad0eab9b Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 2 Jul 2019 10:23:20 +0200 Subject: scsi: explicitly list guest-recoverable sense codes It's not really possible to fit all sense codes into errno codes, especially in such a way that sense codes can be properly categorized as either guest-recoverable or host-handled. Create a new function that checks for guest recoverable sense, then scsi_sense_buf_to_errno only needs to be called for host handled sense codes. Signed-off-by: Paolo Bonzini --- scsi/utils.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'scsi') diff --git a/scsi/utils.c b/scsi/utils.c index 8738522955..ad243a982b 100644 --- a/scsi/utils.c +++ b/scsi/utils.c @@ -336,6 +336,38 @@ int scsi_convert_sense(uint8_t *in_buf, int in_len, } } +static bool scsi_sense_is_guest_recoverable(int key, int asc, int ascq) +{ + switch (key) { + case NO_SENSE: + case RECOVERED_ERROR: + case UNIT_ATTENTION: + case ABORTED_COMMAND: + return true; + case NOT_READY: + case ILLEGAL_REQUEST: + case DATA_PROTECT: + /* Parse ASCQ */ + break; + default: + return false; + } + + switch ((asc << 8) | ascq) { + case 0x1a00: /* PARAMETER LIST LENGTH ERROR */ + case 0x2000: /* INVALID OPERATION CODE */ + case 0x2400: /* INVALID FIELD IN CDB */ + case 0x2500: /* LOGICAL UNIT NOT SUPPORTED */ + case 0x2600: /* INVALID FIELD IN PARAMETER LIST */ + + case 0x0401: /* NOT READY, IN PROGRESS OF BECOMING READY */ + case 0x0402: /* NOT READY, INITIALIZING COMMAND REQUIRED */ + return true; + default: + return false; + } +} + int scsi_sense_to_errno(int key, int asc, int ascq) { switch (key) { @@ -391,6 +423,17 @@ int scsi_sense_buf_to_errno(const uint8_t *in_buf, size_t in_len) return scsi_sense_to_errno(sense.key, sense.asc, sense.ascq); } +bool scsi_sense_buf_is_guest_recoverable(const uint8_t *in_buf, size_t in_len) +{ + SCSISense sense; + if (in_len < 1) { + return false; + } + + sense = scsi_parse_sense_buf(in_buf, in_len); + return scsi_sense_is_guest_recoverable(sense.key, sense.asc, sense.ascq); +} + const char *scsi_command_name(uint8_t cmd) { static const char *names[] = { -- cgit v1.2.3