diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2019-07-02 10:23:20 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2019-07-15 11:20:42 +0200 |
commit | bdf9613b7f87248eb84884b0bdff94e8ad0eab9b (patch) | |
tree | d4317b6e2fda7ceea1fe3b95295c0b9cbc7c84c2 /scsi/utils.c | |
parent | d31347f5ff6c637a11245d244ff5449a94bf8256 (diff) |
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 <pbonzini@redhat.com>
Diffstat (limited to 'scsi/utils.c')
-rw-r--r-- | scsi/utils.c | 43 |
1 files changed, 43 insertions, 0 deletions
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[] = { |