scsi: introduce sg_io_sense_from_errno
Move more knowledge of SG_IO out of hw/scsi/scsi-generic.c, for reusability. Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
a3760467c6
commit
1ead6b4e24
@ -81,6 +81,7 @@ static void scsi_free_request(SCSIRequest *req)
|
|||||||
static void scsi_command_complete_noio(SCSIGenericReq *r, int ret)
|
static void scsi_command_complete_noio(SCSIGenericReq *r, int ret)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
SCSISense sense;
|
||||||
|
|
||||||
assert(r->req.aiocb == NULL);
|
assert(r->req.aiocb == NULL);
|
||||||
|
|
||||||
@ -88,42 +89,15 @@ static void scsi_command_complete_noio(SCSIGenericReq *r, int ret)
|
|||||||
scsi_req_cancel_complete(&r->req);
|
scsi_req_cancel_complete(&r->req);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
status = sg_io_sense_from_errno(-ret, &r->io_header, &sense);
|
||||||
|
if (status == CHECK_CONDITION) {
|
||||||
if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
|
if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
|
||||||
r->req.sense_len = r->io_header.sb_len_wr;
|
r->req.sense_len = r->io_header.sb_len_wr;
|
||||||
|
} else {
|
||||||
|
scsi_req_build_sense(&r->req, sense);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
switch (ret) {
|
|
||||||
case -EDOM:
|
|
||||||
status = TASK_SET_FULL;
|
|
||||||
break;
|
|
||||||
case -ENOMEM:
|
|
||||||
status = CHECK_CONDITION;
|
|
||||||
scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
status = CHECK_CONDITION;
|
|
||||||
scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT ||
|
|
||||||
r->io_header.host_status == SG_ERR_DID_BUS_BUSY ||
|
|
||||||
r->io_header.host_status == SG_ERR_DID_TIME_OUT ||
|
|
||||||
(r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) {
|
|
||||||
status = BUSY;
|
|
||||||
BADF("Driver Timeout\n");
|
|
||||||
} else if (r->io_header.host_status) {
|
|
||||||
status = CHECK_CONDITION;
|
|
||||||
scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS));
|
|
||||||
} else if (r->io_header.status) {
|
|
||||||
status = r->io_header.status;
|
|
||||||
} else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
|
|
||||||
status = CHECK_CONDITION;
|
|
||||||
} else {
|
|
||||||
status = GOOD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
|
DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
|
||||||
r, r->req.tag, status);
|
r, r->req.tag, status);
|
||||||
|
|
||||||
|
@ -116,6 +116,9 @@ int scsi_cdb_length(uint8_t *buf);
|
|||||||
#define SG_ERR_DID_TIME_OUT 0x03
|
#define SG_ERR_DID_TIME_OUT 0x03
|
||||||
|
|
||||||
#define SG_ERR_DRIVER_SENSE 0x08
|
#define SG_ERR_DRIVER_SENSE 0x08
|
||||||
|
|
||||||
|
int sg_io_sense_from_errno(int errno_value, struct sg_io_hdr *io_hdr,
|
||||||
|
SCSISense *sense);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
35
scsi/utils.c
35
scsi/utils.c
@ -501,3 +501,38 @@ const char *scsi_command_name(uint8_t cmd)
|
|||||||
}
|
}
|
||||||
return names[cmd];
|
return names[cmd];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (io_hdr->host_status == SG_ERR_DID_NO_CONNECT ||
|
||||||
|
io_hdr->host_status == SG_ERR_DID_BUS_BUSY ||
|
||||||
|
io_hdr->host_status == SG_ERR_DID_TIME_OUT ||
|
||||||
|
(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) {
|
||||||
|
return CHECK_CONDITION;
|
||||||
|
} else {
|
||||||
|
return GOOD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user