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:
parent
251882b7e4
commit
ed3a34a3c8
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue