Loading hw/scsi/scsi-generic.c +7 −33 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ static void scsi_free_request(SCSIRequest *req) static void scsi_command_complete_noio(SCSIGenericReq *r, int ret) { int status; SCSISense sense; assert(r->req.aiocb == NULL); Loading @@ -88,42 +89,15 @@ static void scsi_command_complete_noio(SCSIGenericReq *r, int ret) scsi_req_cancel_complete(&r->req); 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) { r->req.sense_len = r->io_header.sb_len_wr; } 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; scsi_req_build_sense(&r->req, sense); } } DPRINTF("Command complete 0x%p tag=0x%x status=%d\n", r, r->req.tag, status); Loading include/scsi/utils.h +3 −0 Original line number Diff line number Diff line Loading @@ -116,6 +116,9 @@ int scsi_cdb_length(uint8_t *buf); #define SG_ERR_DID_TIME_OUT 0x03 #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 scsi/utils.c +35 −0 Original line number Diff line number Diff line Loading @@ -501,3 +501,38 @@ const char *scsi_command_name(uint8_t 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
hw/scsi/scsi-generic.c +7 −33 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ static void scsi_free_request(SCSIRequest *req) static void scsi_command_complete_noio(SCSIGenericReq *r, int ret) { int status; SCSISense sense; assert(r->req.aiocb == NULL); Loading @@ -88,42 +89,15 @@ static void scsi_command_complete_noio(SCSIGenericReq *r, int ret) scsi_req_cancel_complete(&r->req); 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) { r->req.sense_len = r->io_header.sb_len_wr; } 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; scsi_req_build_sense(&r->req, sense); } } DPRINTF("Command complete 0x%p tag=0x%x status=%d\n", r, r->req.tag, status); Loading
include/scsi/utils.h +3 −0 Original line number Diff line number Diff line Loading @@ -116,6 +116,9 @@ int scsi_cdb_length(uint8_t *buf); #define SG_ERR_DID_TIME_OUT 0x03 #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
scsi/utils.c +35 −0 Original line number Diff line number Diff line Loading @@ -501,3 +501,38 @@ const char *scsi_command_name(uint8_t 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