[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH v2 03/13] scsi: add initiator field to SCSIReque
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [RFC PATCH v2 03/13] scsi: add initiator field to SCSIRequest |
Date: |
Mon, 6 Jun 2011 18:04:12 +0200 |
Rather than relaying requests across multiple levels, I'm just
skipping the intermediate layers after the LUN has been parsed,
and letting the device know the bus which ultimately knows how
to process the request.
Signed-off-by: Paolo Bonzini <address@hidden>
---
hw/esp.c | 6 +++---
hw/lsi53c895a.c | 8 ++++----
hw/scsi-bus.c | 15 +++++++++------
hw/scsi-disk.c | 6 +++---
hw/scsi-generic.c | 5 +++--
hw/scsi.h | 21 ++++++++++++++++-----
hw/spapr_vscsi.c | 6 +++---
hw/usb-msd.c | 6 +++---
8 files changed, 44 insertions(+), 29 deletions(-)
diff --git a/hw/esp.c b/hw/esp.c
index 6d3f5d2..e47dfec 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -190,7 +190,7 @@ static void esp_dma_enable(void *opaque, int irq, int level)
static void esp_request_cancelled(SCSIRequest *req)
{
- ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
+ ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->initiator);
if (req == s->current_req) {
scsi_req_unref(s->current_req);
@@ -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, &s->busdev.qdev, 0, lun);
datalen = scsi_req_enqueue(s->current_req, buf);
s->ti_size = datalen;
if (datalen != 0) {
@@ -397,7 +397,7 @@ static void esp_do_dma(ESPState *s)
static void esp_command_complete(SCSIRequest *req, uint32_t status)
{
- ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
+ ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->initiator);
DPRINTF("SCSI Command complete\n");
if (s->ti_size != 0) {
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 83084b6..96b19f9 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -660,7 +660,7 @@ static lsi_request *lsi_find_by_tag(LSIState *s, uint32_t
tag)
static void lsi_request_cancelled(SCSIRequest *req)
{
- LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
+ LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->initiator);
lsi_request *p;
if (s->current && req == s->current->req) {
@@ -715,7 +715,7 @@ static int lsi_queue_tag(LSIState *s, uint32_t tag,
uint32_t len)
/* Callback to indicate that the SCSI layer has completed a command. */
static void lsi_command_complete(SCSIRequest *req, uint32_t status)
{
- LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
+ LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->initiator);
int out;
out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
@@ -789,8 +789,8 @@ 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->dev.qdev, s->current->tag,
+ s->current_lun);
n = scsi_req_enqueue(s->current->req, buf);
if (n) {
if (n > 0) {
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 3b80541..24e91bf 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -143,14 +143,16 @@ 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, DeviceState *initiator,
+ uint32_t tag, uint32_t lun)
{
SCSIRequest *req;
req = qemu_mallocz(size);
req->refcount = 1;
- req->bus = scsi_bus_from_device(d);
+ req->bus = scsi_bus_from_device(d, initiator);
req->dev = d;
+ req->initiator = initiator;
req->tag = tag;
req->lun = lun;
req->status = -1;
@@ -158,9 +160,10 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d,
uint32_t tag, uint32_t l
return req;
}
-SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun)
+SCSIRequest *scsi_req_new(SCSIDevice *d, DeviceState *initiator,
+ uint32_t tag, uint32_t lun)
{
- return d->info->alloc_req(d, tag, lun);
+ return d->info->alloc_req(d, initiator, tag, lun);
}
uint8_t *scsi_req_get_buf(SCSIRequest *req)
@@ -724,8 +727,8 @@ void scsi_device_purge_requests(SCSIDevice *sdev)
static char *scsibus_get_fw_dev_path(DeviceState *dev)
{
- SCSIDevice *d = (SCSIDevice*)dev;
- SCSIBus *bus = scsi_bus_from_device(d);
+ SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev);
+ SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
char path[100];
int i;
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 76c1748..87e5ac8 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -80,14 +80,14 @@ 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, DeviceState *initiator,
+ uint32_t tag, uint32_t lun)
{
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, initiator, tag, lun);
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 b67e154..94aca18 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -96,11 +96,12 @@ 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, DeviceState *initiator,
+ uint32_t tag, uint32_t lun)
{
SCSIRequest *req;
- req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun);
+ req = scsi_req_alloc(sizeof(SCSIGenericReq), d, initiator, tag, lun);
return req;
}
diff --git a/hw/scsi.h b/hw/scsi.h
index 4ba1801..fa3ca9b 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -35,6 +35,7 @@ typedef struct SCSISense {
struct SCSIRequest {
SCSIBus *bus;
+ DeviceState *initiator;
SCSIDevice *dev;
uint32_t refcount;
uint32_t tag;
@@ -73,7 +74,8 @@ struct SCSIDeviceInfo {
int (*init)(SCSIDevice *dev);
void (*destroy)(SCSIDevice *s);
void (*reset)(SCSIDevice *s);
- SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun);
+ SCSIRequest *(*alloc_req)(SCSIDevice *s, DeviceState *initiator,
+ uint32_t tag, uint32_t lun);
void (*free_req)(SCSIRequest *req);
int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
void (*read_data)(SCSIRequest *req);
@@ -103,9 +105,16 @@ void scsi_bus_new(SCSIBus *bus, DeviceState *host, int
tcq, int ndev,
const SCSIBusOps *ops);
void scsi_qdev_register(SCSIDeviceInfo *info);
-static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
+static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d, DeviceState
*initiator)
{
- return DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
+ SCSIBus *bus;
+ DeviceState *dev;
+ dev = &d->qdev;
+ do {
+ bus = DO_UPCAST(SCSIBus, qbus, dev->parent_bus);
+ dev = bus->qbus.parent;
+ } while (dev != initiator);
+ return bus;
}
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
@@ -145,8 +154,10 @@ int scsi_build_sense(SCSISense sense, uint8_t *buf, int
len, int fixed);
int scsi_sense_valid(SCSISense sense);
SCSIDevice *scsi_decode_lun(SCSIBus *sbus, uint64_t sam_lun, int *lun);
-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, DeviceState *initiator,
+ uint32_t tag, uint32_t lun);
+SCSIRequest *scsi_req_new(SCSIDevice *d, DeviceState *initiator, uint32_t tag,
+ uint32_t lun);
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 038b9e4..5b5fa87 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -475,7 +475,7 @@ static void vscsi_send_request_sense(VSCSIState *s,
vscsi_req *req)
/* Callback to indicate that the SCSI layer has completed a transfer. */
static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len)
{
- VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
+ VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->initiator);
vscsi_req *req = vscsi_find_req(s, sreq);
uint8_t *buf;
int rc = 0;
@@ -561,7 +561,7 @@ static void vscsi_command_complete(SCSIRequest *sreq,
uint32_t status)
static void vscsi_request_cancelled(SCSIRequest *sreq)
{
- VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
+ VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->initiator);
vscsi_req *req = vscsi_find_req(s, sreq);
vscsi_put_req(s, req);
@@ -649,7 +649,7 @@ 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, &s->vdev.qdev, req->qtag, lun);
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",
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index c59797b..195089c 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -212,7 +212,7 @@ static void usb_msd_send_status(MSDState *s, USBPacket *p)
static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len)
{
- MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
+ MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->initiator);
USBPacket *p = s->packet;
if (req->tag != s->tag) {
@@ -275,7 +275,7 @@ static void usb_msd_command_complete(SCSIRequest *req,
uint32_t status)
static void usb_msd_request_cancelled(SCSIRequest *req)
{
- MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
+ MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->initiator);
if (req == s->req) {
scsi_req_unref(s->req);
@@ -386,7 +386,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, &s->dev.qdev, s->tag, 0);
scsi_req_enqueue(s->req, cbw.cmd);
/* ??? Should check that USB and SCSI data transfer
directions match. */
--
1.7.4.4
- [Qemu-devel] [RFC PATCH v2 00/13] support hierarchical LUNs, Paolo Bonzini, 2011/06/06
- [Qemu-devel] [RFC PATCH v2 02/13] scsi: support parsing of SAM logical unit numbers, Paolo Bonzini, 2011/06/06
- [Qemu-devel] [RFC PATCH v2 01/13] scsi: cleanup reset and destroy callbacks, Paolo Bonzini, 2011/06/06
- [Qemu-devel] [RFC PATCH v2 03/13] scsi: add initiator field to SCSIRequest,
Paolo Bonzini <=
- [Qemu-devel] [RFC PATCH v2 04/13] scsi: let a SCSIDevice have children devices, Paolo Bonzini, 2011/06/06
- [Qemu-devel] [RFC PATCH v2 05/13] scsi: let the bus pick a LUN for the child device, Paolo Bonzini, 2011/06/06
- [Qemu-devel] [RFC PATCH v2 06/13] scsi-generic: fix passthrough of devices with LUN != 0, Paolo Bonzini, 2011/06/06
- [Qemu-devel] [RFC PATCH v2 07/13] scsi: add walking of hierarchical LUNs, Paolo Bonzini, 2011/06/06
- [Qemu-devel] [RFC PATCH v2 08/13] scsi: introduce the scsi-path device, Paolo Bonzini, 2011/06/06
- [Qemu-devel] [RFC PATCH v2 09/13] scsi: introduce the scsi-target device, Paolo Bonzini, 2011/06/06
- [Qemu-devel] [RFC PATCH v2 10/13] scsi: include bus and device levels, Paolo Bonzini, 2011/06/06
- [Qemu-devel] [RFC PATCH v2 11/13] qdev: introduce automatic creation of buses, Paolo Bonzini, 2011/06/06
- [Qemu-devel] [RFC PATCH v2 12/13] scsi: create scsi-path and scsi-target devices automatically, Paolo Bonzini, 2011/06/06