/* Helper function for command completion. */ static void scsi_command_complete_noio(SCSIGenericReq *r, int ret) { int status; SCSISense sense; assert(r->req.aiocb == NULL); if (r->req.io_canceled) { 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; } else { scsi_req_build_sense(&r->req, sense); } } DPRINTF("Command complete 0x%p tag=0x%x status=%d\n", r, r->req.tag, status); scsi_req_complete(&r->req, status); done: scsi_req_unref(&r->req); }
static int do_sgio_worker(void *opaque) { PRHelperSGIOData *data = opaque; struct sg_io_hdr io_hdr; int ret; int status; SCSISense sense_code; memset(data->sense, 0, PR_HELPER_SENSE_SIZE); memset(&io_hdr, 0, sizeof(io_hdr)); io_hdr.interface_id = 'S'; io_hdr.cmd_len = PR_HELPER_CDB_SIZE; io_hdr.cmdp = (uint8_t *)data->cdb; io_hdr.sbp = data->sense; io_hdr.mx_sb_len = PR_HELPER_SENSE_SIZE; io_hdr.timeout = 1; io_hdr.dxfer_direction = data->dir; io_hdr.dxferp = (char *)data->buf; io_hdr.dxfer_len = data->sz; ret = ioctl(data->fd, SG_IO, &io_hdr); status = sg_io_sense_from_errno(ret < 0 ? errno : 0, &io_hdr, &sense_code); if (status == GOOD) { data->sz -= io_hdr.resid; } else { data->sz = 0; } if (status == CHECK_CONDITION && !(io_hdr.driver_status & SG_ERR_DRIVER_SENSE)) { scsi_build_sense(data->sense, sense_code); } return status; }