qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [RFC PATCH v2 03/13] scsi: add initiator field to SCSIRequest
Date: Mon,  6 Jun 2011 18:04:12 +0200	[thread overview]
Message-ID: <1307376262-1255-4-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1307376262-1255-1-git-send-email-pbonzini@redhat.com>

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 <pbonzini@redhat.com>
---
 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

  parent reply	other threads:[~2011-06-06 16:05 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-06 16:04 [Qemu-devel] [RFC PATCH v2 00/13] support hierarchical LUNs Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 01/13] scsi: cleanup reset and destroy callbacks Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 02/13] scsi: support parsing of SAM logical unit numbers Paolo Bonzini
2011-06-06 16:04 ` Paolo Bonzini [this message]
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 04/13] scsi: let a SCSIDevice have children devices Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 05/13] scsi: let the bus pick a LUN for the child device Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 06/13] scsi-generic: fix passthrough of devices with LUN != 0 Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 07/13] scsi: add walking of hierarchical LUNs Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 08/13] scsi: introduce the scsi-path device Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 09/13] scsi: introduce the scsi-target device Paolo Bonzini
2011-06-07  8:09   ` Stefan Hajnoczi
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 10/13] scsi: include bus and device levels Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 11/13] qdev: introduce automatic creation of buses Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 12/13] scsi: create scsi-path and scsi-target devices automatically Paolo Bonzini
2011-06-06 16:04 ` [Qemu-devel] [RFC PATCH v2 13/13] scsi: delete handling of REPORT LUNS and unknown LUNs outside scsi-target Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1307376262-1255-4-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).