mirror of https://github.com/xemu-project/xemu.git
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>
This commit is contained in:
parent
d31347f5ff
commit
bdf9613b7f
|
@ -454,14 +454,13 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_failed)
|
||||||
* pause the host.
|
* pause the host.
|
||||||
*/
|
*/
|
||||||
assert(r->status && *r->status);
|
assert(r->status && *r->status);
|
||||||
error = scsi_sense_buf_to_errno(r->req.sense, sizeof(r->req.sense));
|
if (scsi_sense_buf_is_guest_recoverable(r->req.sense, sizeof(r->req.sense))) {
|
||||||
if (error == ECANCELED || error == EAGAIN || error == ENOTCONN ||
|
|
||||||
error == 0) {
|
|
||||||
/* These errors are handled by guest. */
|
/* These errors are handled by guest. */
|
||||||
sdc->update_sense(&r->req);
|
sdc->update_sense(&r->req);
|
||||||
scsi_req_complete(&r->req, *r->status);
|
scsi_req_complete(&r->req, *r->status);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
error = scsi_sense_buf_to_errno(r->req.sense, sizeof(r->req.sense));
|
||||||
break;
|
break;
|
||||||
case ENOMEDIUM:
|
case ENOMEDIUM:
|
||||||
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
|
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
|
||||||
|
|
|
@ -106,6 +106,7 @@ extern const struct SCSISense sense_code_SPACE_ALLOC_FAILED;
|
||||||
|
|
||||||
int scsi_sense_to_errno(int key, int asc, int ascq);
|
int scsi_sense_to_errno(int key, int asc, int ascq);
|
||||||
int scsi_sense_buf_to_errno(const uint8_t *sense, size_t sense_size);
|
int scsi_sense_buf_to_errno(const uint8_t *sense, size_t sense_size);
|
||||||
|
bool scsi_sense_buf_is_guest_recoverable(const uint8_t *sense, size_t sense_size);
|
||||||
|
|
||||||
int scsi_convert_sense(uint8_t *in_buf, int in_len,
|
int scsi_convert_sense(uint8_t *in_buf, int in_len,
|
||||||
uint8_t *buf, int len, bool fixed);
|
uint8_t *buf, int len, bool fixed);
|
||||||
|
|
43
scsi/utils.c
43
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)
|
int scsi_sense_to_errno(int key, int asc, int ascq)
|
||||||
{
|
{
|
||||||
switch (key) {
|
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);
|
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)
|
const char *scsi_command_name(uint8_t cmd)
|
||||||
{
|
{
|
||||||
static const char *names[] = {
|
static const char *names[] = {
|
||||||
|
|
Loading…
Reference in New Issue