[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/3] scsi: replace 'tag' with 'hba_private' pointer
From: |
Hannes Reinecke |
Subject: |
[Qemu-devel] [PATCH 2/3] scsi: replace 'tag' with 'hba_private' pointer |
Date: |
Fri, 1 Jul 2011 09:42:51 +0200 |
'tag' is just an abstraction to identify the command
from the driver. So we should make that explicit by
replacing 'tag' with a driver-defined pointer 'hba_private'.
This saves the lookup for driver handling several commands
in parallel.
Signed-off-by: Hannes Reinecke <address@hidden>
---
hw/esp.c | 2 +-
hw/lsi53c895a.c | 17 ++++++++---------
hw/scsi-bus.c | 22 +++++++++++-----------
hw/scsi-disk.c | 5 ++---
hw/scsi-generic.c | 4 ++--
hw/scsi.h | 8 ++++----
hw/spapr_vscsi.c | 41 ++++++++++++-----------------------------
hw/usb-msd.c | 10 +++++-----
trace-events | 14 +++++++-------
9 files changed, 52 insertions(+), 71 deletions(-)
diff --git a/hw/esp.c b/hw/esp.c
index 6d3f5d2..912ff89 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -244,7 +244,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t
busid)
DPRINTF("do_busid_cmd: busid 0x%x\n", busid);
lun = busid & 7;
- s->current_req = scsi_req_new(s->current_dev, 0, lun);
+ s->current_req = scsi_req_new(s->current_dev, lun, s);
datalen = scsi_req_enqueue(s->current_req, buf);
s->ti_size = datalen;
if (datalen != 0) {
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 940b43a..272e919 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -670,7 +670,7 @@ static void lsi_request_cancelled(SCSIRequest *req)
return;
}
- p = lsi_find_by_tag(s, req->tag);
+ p = req->hba_private;
if (p) {
QTAILQ_REMOVE(&s->queue, p, next);
scsi_req_unref(req);
@@ -680,18 +680,17 @@ static void lsi_request_cancelled(SCSIRequest *req)
/* Record that data is available for a queued command. Returns zero if
the device was reselected, nonzero if the IO is deferred. */
-static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t len)
+static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len)
{
- lsi_request *p;
+ lsi_request *p = req->hba_private;
- p = lsi_find_by_tag(s, tag);
if (!p) {
- BADF("IO with unknown tag %d\n", tag);
+ BADF("IO with unknown reference %p\n", req->hba_private);
return 1;
}
if (p->pending) {
- BADF("Multiple IO pending for tag %d\n", tag);
+ BADF("Multiple IO pending for request %p\n", p);
}
p->pending = len;
/* Reselect if waiting for it, or if reselection triggers an IRQ
@@ -743,9 +742,9 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t
len)
LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
int out;
- if (s->waiting == 1 || !s->current || req->tag != s->current->tag ||
+ if (s->waiting == 1 || !s->current || req->hba_private != s->current ||
(lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) {
- if (lsi_queue_tag(s, req->tag, len)) {
+ if (lsi_queue_req(s, req, len)) {
return;
}
}
@@ -789,7 +788,7 @@ static void lsi_do_command(LSIState *s)
assert(s->current == NULL);
s->current = qemu_mallocz(sizeof(lsi_request));
s->current->tag = s->select_tag;
- s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun);
+ s->current->req = scsi_req_new(dev, s->current_lun, s->current);
n = scsi_req_enqueue(s->current->req, buf);
if (n) {
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index ad6a730..d1fc481 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -131,7 +131,7 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
return res;
}
-SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t
lun)
+SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t lun, void
*hba_private)
{
SCSIRequest *req;
@@ -139,16 +139,16 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d,
uint32_t tag, uint32_t l
req->refcount = 1;
req->bus = scsi_bus_from_device(d);
req->dev = d;
- req->tag = tag;
req->lun = lun;
+ req->hba_private = hba_private;
req->status = -1;
- trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
+ trace_scsi_req_alloc(req->dev->id, req->lun, req->hba_private);
return req;
}
-SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun)
+SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t lun, void *hba_private)
{
- return d->info->alloc_req(d, tag, lun);
+ return d->info->alloc_req(d, lun, hba_private);
}
uint8_t *scsi_req_get_buf(SCSIRequest *req)
@@ -182,7 +182,7 @@ int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf)
static void scsi_req_dequeue(SCSIRequest *req)
{
- trace_scsi_req_dequeue(req->dev->id, req->lun, req->tag);
+ trace_scsi_req_dequeue(req->dev->id, req->lun, req->hba_private);
if (req->enqueued) {
QTAILQ_REMOVE(&req->dev->requests, req, next);
req->enqueued = false;
@@ -214,7 +214,7 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd)
req->cmd.len = 12;
break;
default:
- trace_scsi_req_parse_bad(req->dev->id, req->lun, req->tag, cmd[0]);
+ trace_scsi_req_parse_bad(req->dev->id, req->lun, req->hba_private,
cmd[0]);
return -1;
}
@@ -412,10 +412,10 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf)
memcpy(req->cmd.buf, buf, req->cmd.len);
scsi_req_xfer_mode(req);
req->cmd.lba = scsi_req_lba(req);
- trace_scsi_req_parsed(req->dev->id, req->lun, req->tag, buf[0],
+ trace_scsi_req_parsed(req->dev->id, req->lun, req->hba_private, buf[0],
req->cmd.mode, req->cmd.xfer);
if (req->cmd.lba != -1) {
- trace_scsi_req_parsed_lba(req->dev->id, req->lun, req->tag, buf[0],
+ trace_scsi_req_parsed_lba(req->dev->id, req->lun, req->hba_private,
buf[0],
req->cmd.lba);
}
return 0;
@@ -624,7 +624,7 @@ void scsi_req_unref(SCSIRequest *req)
will start the next chunk or complete the command. */
void scsi_req_continue(SCSIRequest *req)
{
- trace_scsi_req_continue(req->dev->id, req->lun, req->tag);
+ trace_scsi_req_continue(req->dev->id, req->lun, req->hba_private);
if (req->cmd.mode == SCSI_XFER_TO_DEV) {
req->dev->info->write_data(req);
} else {
@@ -637,7 +637,7 @@ void scsi_req_continue(SCSIRequest *req)
Once it completes, calling scsi_req_continue will restart I/O. */
void scsi_req_data(SCSIRequest *req, int len)
{
- trace_scsi_req_data(req->dev->id, req->lun, req->tag, len);
+ trace_scsi_req_data(req->dev->id, req->lun, req->hba_private, len);
req->bus->ops->transfer_data(req, len);
}
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index a8c7372..3098b62 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -80,14 +80,13 @@ struct SCSIDiskState
static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
-static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
- uint32_t lun)
+static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t lun, void
*hba_private)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
SCSIRequest *req;
SCSIDiskReq *r;
- req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, tag, lun);
+ req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, lun, hba_private);
r = DO_UPCAST(SCSIDiskReq, req, req);
r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
return req;
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 8e59c7e..fa34ca3 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -96,11 +96,11 @@ static int scsi_get_sense(SCSIRequest *req, uint8_t
*outbuf, int len)
return size;
}
-static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
+static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t lun, void
*hba_private)
{
SCSIRequest *req;
- req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
+ req = scsi_req_alloc(sizeof(SCSIGenericReq), d, lun, hba_private);
return req;
}
diff --git a/hw/scsi.h b/hw/scsi.h
index c1dca35..883309e 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -31,7 +31,6 @@ struct SCSIRequest {
SCSIBus *bus;
SCSIDevice *dev;
uint32_t refcount;
- uint32_t tag;
uint32_t lun;
uint32_t status;
struct {
@@ -43,6 +42,7 @@ struct SCSIRequest {
} cmd;
BlockDriverAIOCB *aiocb;
bool enqueued;
+ void *hba_private;
QTAILQ_ENTRY(SCSIRequest) next;
};
@@ -67,7 +67,7 @@ struct SCSIDeviceInfo {
DeviceInfo qdev;
scsi_qdev_initfn init;
void (*destroy)(SCSIDevice *s);
- SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun);
+ SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t lun, void *hba_private);
void (*free_req)(SCSIRequest *req);
int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
void (*read_data)(SCSIRequest *req);
@@ -138,8 +138,8 @@ extern const struct SCSISense sense_code_LUN_FAILURE;
int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed);
int scsi_sense_valid(SCSISense sense);
-SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t
lun);
-SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun);
+SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t lun, void
*hba_private);
+SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t lun, void *hba_private);
int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf);
void scsi_req_free(SCSIRequest *req);
SCSIRequest *scsi_req_ref(SCSIRequest *req);
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index 1c901ef..f119194 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -75,7 +75,6 @@ typedef struct vscsi_req {
/* SCSI request tracking */
SCSIRequest *sreq;
- uint32_t qtag; /* qemu tag != srp tag */
int lun;
int active;
long data_len;
@@ -113,7 +112,6 @@ static struct vscsi_req *vscsi_get_req(VSCSIState *s)
req = &s->reqs[i];
if (!req->active) {
memset(req, 0, sizeof(*req));
- req->qtag = i;
req->active = 1;
return req;
}
@@ -121,7 +119,7 @@ static struct vscsi_req *vscsi_get_req(VSCSIState *s)
return NULL;
}
-static void vscsi_put_req(VSCSIState *s, vscsi_req *req)
+static void vscsi_put_req(vscsi_req *req)
{
if (req->sreq != NULL) {
scsi_req_unref(req->sreq);
@@ -130,15 +128,6 @@ static void vscsi_put_req(VSCSIState *s, vscsi_req *req)
req->active = 0;
}
-static vscsi_req *vscsi_find_req(VSCSIState *s, SCSIRequest *req)
-{
- uint32_t tag = req->tag;
- if (tag >= VSCSI_REQ_LIMIT || !s->reqs[tag].active) {
- return NULL;
- }
- return &s->reqs[tag];
-}
-
static void vscsi_decode_id_lun(uint64_t srp_lun, int *id, int *lun)
{
/* XXX Figure that one out properly ! This is crackpot */
@@ -454,7 +443,7 @@ static void vscsi_send_request_sense(VSCSIState *s,
vscsi_req *req)
if (n) {
req->senselen = n;
vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
- vscsi_put_req(s, req);
+ vscsi_put_req(req);
return;
}
@@ -467,7 +456,7 @@ static void vscsi_send_request_sense(VSCSIState *s,
vscsi_req *req)
cdb[5] = 0;
req->sensing = 1;
n = scsi_req_enqueue(req->sreq, cdb);
- dprintf("VSCSI: Queued request sense tag 0x%x\n", req->qtag);
+ dprintf("VSCSI: Queued request sense 0x%p\n", req);
if (n < 0) {
fprintf(stderr, "VSCSI: REQUEST_SENSE wants write data !?!?!?\n");
vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0);
@@ -483,7 +472,7 @@ static void vscsi_send_request_sense(VSCSIState *s,
vscsi_req *req)
static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len)
{
VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
- vscsi_req *req = vscsi_find_req(s, sreq);
+ vscsi_req *req = sreq->hba_private;
uint8_t *buf;
int rc = 0;
@@ -530,8 +519,7 @@ static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t
len)
/* Callback to indicate that the SCSI layer has completed a transfer. */
static void vscsi_command_complete(SCSIRequest *sreq, uint32_t status)
{
- VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
- vscsi_req *req = vscsi_find_req(s, sreq);
+ vscsi_req *req = sreq->hba_private;
int32_t res_in = 0, res_out = 0;
dprintf("VSCSI: SCSI cmd complete, r=0x%x tag=0x%x status=0x%x, req=%p\n",
@@ -563,15 +551,14 @@ static void vscsi_command_complete(SCSIRequest *sreq,
uint32_t status)
}
}
vscsi_send_rsp(s, req, 0, res_in, res_out);
- vscsi_put_req(s, req);
+ vscsi_put_req(req);
}
static void vscsi_request_cancelled(SCSIRequest *sreq)
{
- VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
- vscsi_req *req = vscsi_find_req(s, sreq);
+ vscsi_req *req = sreq->hba_private;
- vscsi_put_req(s, req);
+ vscsi_put_req(req);
}
static void vscsi_process_login(VSCSIState *s, vscsi_req *req)
@@ -659,11 +646,11 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)
}
req->lun = lun;
- req->sreq = scsi_req_new(sdev, req->qtag, lun);
+ req->sreq = scsi_req_new(sdev, lun, req);
n = scsi_req_enqueue(req->sreq, srp->cmd.cdb);
- dprintf("VSCSI: Queued command tag 0x%x CMD 0x%x ID %d LUN %d ret: %d\n",
- req->qtag, srp->cmd.cdb[0], id, lun, n);
+ dprintf("VSCSI: Queued command 0x%p CMD 0x%x ID %d LUN %d ret: %d\n",
+ req, srp->cmd.cdb[0], id, lun, n);
if (n) {
/* Transfer direction must be set before preprocessing the
@@ -858,7 +845,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq)
}
if (done) {
- vscsi_put_req(s, req);
+ vscsi_put_req(req);
}
}
@@ -935,11 +922,7 @@ static int spapr_vscsi_init(VIOsPAPRDevice *dev)
dbg_vscsi_state = s;
- /* Initialize qemu request tags */
memset(s->reqs, 0, sizeof(s->reqs));
- for (i = 0; i < VSCSI_REQ_LIMIT; i++) {
- s->reqs[i].qtag = i;
- }
dev->crq.SendFunc = vscsi_do_crq;
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index 86582cc..4e2ea03 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -216,8 +216,8 @@ static void usb_msd_transfer_data(SCSIRequest *req,
uint32_t len)
MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
USBPacket *p = s->packet;
- if (req->tag != s->tag) {
- fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", req->tag);
+ if (req->hba_private != s) {
+ fprintf(stderr, "usb-msd: Unexpected SCSI command 0x%p\n", req);
}
assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode ==
SCSI_XFER_TO_DEV));
@@ -241,8 +241,8 @@ static void usb_msd_command_complete(SCSIRequest *req,
uint32_t status)
MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
USBPacket *p = s->packet;
- if (req->tag != s->tag) {
- fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", req->tag);
+ if (req->hba_private != s) {
+ fprintf(stderr, "usb-msd: Unexpected SCSI command 0x%p\n", req);
}
DPRINTF("Command complete %d\n", status);
s->residue = s->data_len;
@@ -387,7 +387,7 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
s->tag, cbw.flags, cbw.cmd_len, s->data_len);
s->residue = 0;
s->scsi_len = 0;
- s->req = scsi_req_new(s->scsi_dev, s->tag, 0);
+ s->req = scsi_req_new(s->scsi_dev, 0, s);
scsi_req_enqueue(s->req, cbw.cmd);
/* ??? Should check that USB and SCSI data transfer
directions match. */
diff --git a/trace-events b/trace-events
index bebf612..8c52148 100644
--- a/trace-events
+++ b/trace-events
@@ -226,13 +226,13 @@ disable usb_clear_device_feature(int addr, int feature,
int ret) "dev %d, featur
disable usb_set_device_feature(int addr, int feature, int ret) "dev %d,
feature %d, ret %d"
# hw/scsi-bus.c
-disable scsi_req_alloc(int target, int lun, int tag) "target %d lun %d tag %d"
-disable scsi_req_data(int target, int lun, int tag, int len) "target %d lun %d
tag %d len %d"
-disable scsi_req_dequeue(int target, int lun, int tag) "target %d lun %d tag
%d"
-disable scsi_req_continue(int target, int lun, int tag) "target %d lun %d tag
%d"
-disable scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int
xfer) "target %d lun %d tag %d command %d dir %d length %d"
-disable scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t
lba) "target %d lun %d tag %d command %d lba %"PRIu64""
-disable scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d
lun %d tag %d command %d"
+disable scsi_req_alloc(int target, int lun, void *private) "target %d lun %d
private %p"
+disable scsi_req_data(int target, int lun, void *private, int len) "target %d
lun %d private %p len %d"
+disable scsi_req_dequeue(int target, int lun, void *private) "target %d lun %d
p %p"
+disable scsi_req_continue(int target, int lun, void *private) "target %d lun
%d private %p"
+disable scsi_req_parsed(int target, int lun, void *private, int cmd, int mode,
int xfer) "target %d lun %d private %p command %d dir %d length %d"
+disable scsi_req_parsed_lba(int target, int lun, void *private, int cmd,
uint64_t lba) "target %d lun %d private %p command %d lba %"PRIu64""
+disable scsi_req_parse_bad(int target, int lun, void *private, int cmd)
"target %d lun %d private %p command %d"
# vl.c
disable vm_state_notify(int running, int reason) "running %d reason %d"
--
1.6.0.2
- [Qemu-devel] [PATCH 0/3] [v4] Megasas HBA emulation, Hannes Reinecke, 2011/07/01
- [Qemu-devel] [PATCH 1/3] iov: Add 'offset' parameter to iov_to_buf(), Hannes Reinecke, 2011/07/01
- [Qemu-devel] [PATCH 2/3] scsi: replace 'tag' with 'hba_private' pointer,
Hannes Reinecke <=
- Re: [Qemu-devel] [PATCH 2/3] scsi: replace 'tag' with 'hba_private' pointer, Paolo Bonzini, 2011/07/01
- Re: [Qemu-devel] [PATCH 2/3] scsi: replace 'tag' with 'hba_private' pointer, Hannes Reinecke, 2011/07/01
- Re: [Qemu-devel] [PATCH 2/3] scsi: replace 'tag' with 'hba_private' pointer, Hannes Reinecke, 2011/07/01
- Re: [Qemu-devel] [PATCH 2/3] scsi: replace 'tag' with 'hba_private' pointer, Paolo Bonzini, 2011/07/01
Re: [Qemu-devel] [PATCH 1/3] iov: Add 'offset' parameter to iov_to_buf(), Alexander Graf, 2011/07/01