scsi: move status to SCSIRequest.

Also add and use the scsi_req_complete() helper function for calling the
completion callback.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Gerd Hoffmann 2009-11-26 15:34:00 +01:00 committed by Anthony Liguori
parent 251882b7e4
commit ed3a34a3c8
4 changed files with 27 additions and 15 deletions

View File

@ -132,6 +132,7 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t l
req->dev = d; req->dev = d;
req->tag = tag; req->tag = tag;
req->lun = lun; req->lun = lun;
req->status = -1;
QTAILQ_INSERT_TAIL(&d->requests, req, next); QTAILQ_INSERT_TAIL(&d->requests, req, next);
return req; return req;
} }
@ -362,3 +363,11 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf)
req->cmd.lba = scsi_req_lba(req); req->cmd.lba = scsi_req_lba(req);
return 0; return 0;
} }
void scsi_req_complete(SCSIRequest *req)
{
assert(req->status != -1);
req->bus->complete(req->bus, SCSI_REASON_DONE,
req->tag,
req->status);
}

View File

@ -84,16 +84,19 @@ static SCSIDiskReq *scsi_find_request(SCSIDiskState *s, uint32_t tag)
return DO_UPCAST(SCSIDiskReq, req, scsi_req_find(&s->qdev, tag)); return DO_UPCAST(SCSIDiskReq, req, scsi_req_find(&s->qdev, tag));
} }
static void scsi_req_set_status(SCSIRequest *req, int status, int sense_code)
{
req->status = status;
scsi_dev_set_sense(req->dev, sense_code);
}
/* Helper function for command completion. */ /* Helper function for command completion. */
static void scsi_command_complete(SCSIDiskReq *r, int status, int sense) static void scsi_command_complete(SCSIDiskReq *r, int status, int sense)
{ {
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
uint32_t tag;
DPRINTF("Command complete tag=0x%x status=%d sense=%d\n", DPRINTF("Command complete tag=0x%x status=%d sense=%d\n",
r->req.tag, status, sense); r->req.tag, status, sense);
scsi_dev_set_sense(&s->qdev, sense); scsi_req_set_status(&r->req, status, sense);
tag = r->req.tag; scsi_req_complete(&r->req);
r->req.bus->complete(r->req.bus, SCSI_REASON_DONE, tag, status);
scsi_remove_request(r); scsi_remove_request(r);
} }

View File

@ -88,30 +88,28 @@ static void scsi_command_complete(void *opaque, int ret)
{ {
SCSIGenericReq *r = (SCSIGenericReq *)opaque; SCSIGenericReq *r = (SCSIGenericReq *)opaque;
SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev); SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
uint32_t tag;
int status;
s->driver_status = r->io_header.driver_status; s->driver_status = r->io_header.driver_status;
if (s->driver_status & SG_ERR_DRIVER_SENSE) if (s->driver_status & SG_ERR_DRIVER_SENSE)
s->senselen = r->io_header.sb_len_wr; s->senselen = r->io_header.sb_len_wr;
if (ret != 0) if (ret != 0)
status = BUSY << 1; r->req.status = BUSY << 1;
else { else {
if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) { if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
status = BUSY << 1; r->req.status = BUSY << 1;
BADF("Driver Timeout\n"); BADF("Driver Timeout\n");
} else if (r->io_header.status) } else if (r->io_header.status)
status = r->io_header.status; r->req.status = r->io_header.status;
else if (s->driver_status & SG_ERR_DRIVER_SENSE) else if (s->driver_status & SG_ERR_DRIVER_SENSE)
status = CHECK_CONDITION << 1; r->req.status = CHECK_CONDITION << 1;
else else
status = GOOD << 1; r->req.status = GOOD << 1;
} }
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, r->req.status);
tag = r->req.tag;
r->req.bus->complete(r->req.bus, SCSI_REASON_DONE, tag, status); scsi_req_complete(&r->req);
scsi_remove_request(r); scsi_remove_request(r);
} }

View File

@ -33,6 +33,7 @@ typedef struct SCSIRequest {
SCSIDevice *dev; SCSIDevice *dev;
uint32_t tag; uint32_t tag;
uint32_t lun; uint32_t lun;
uint32_t status;
struct { struct {
uint8_t buf[SCSI_CMD_BUF_SIZE]; uint8_t buf[SCSI_CMD_BUF_SIZE];
int len; int len;
@ -106,5 +107,6 @@ SCSIRequest *scsi_req_find(SCSIDevice *d, uint32_t tag);
void scsi_req_free(SCSIRequest *req); void scsi_req_free(SCSIRequest *req);
int scsi_req_parse(SCSIRequest *req, uint8_t *buf); int scsi_req_parse(SCSIRequest *req, uint8_t *buf);
void scsi_req_complete(SCSIRequest *req);
#endif #endif