From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 15/35] scsi: remove devs array from SCSIBus
Date: Thu, 13 Oct 2011 13:03:45 +0200 [thread overview]
Message-ID: <1318503845-11473-16-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1318503845-11473-1-git-send-email-pbonzini@redhat.com>
Change the devs array into a linked list, and add a scsi_device_find
function to navigate the children list instead. This lets the SCSI
bus use more complex addressing.
scsi_device_find may return another LUN on the same target if none is
found that matches exactly.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/esp.c | 5 +++--
hw/lsi53c895a.c | 22 +++++++---------------
hw/qdev.h | 2 +-
hw/scsi-bus.c | 53 ++++++++++++++++++++++++++++++-----------------------
hw/scsi.h | 3 +--
hw/spapr_vscsi.c | 14 ++++++--------
6 files changed, 48 insertions(+), 51 deletions(-)
diff --git a/hw/esp.c b/hw/esp.c
index d3fb1c6..8e17005 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -217,7 +217,8 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
s->async_len = 0;
}
- if (target >= ESP_MAX_DEVS || !s->bus.devs[target]) {
+ s->current_dev = scsi_device_find(&s->bus, target, 0);
+ if (!s->current_dev) {
// No such drive
s->rregs[ESP_RSTAT] = 0;
s->rregs[ESP_RINTR] = INTR_DC;
@@ -225,7 +226,6 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
esp_raise_irq(s);
return 0;
}
- s->current_dev = s->bus.devs[target];
return dmalen;
}
@@ -236,6 +236,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
trace_esp_do_busid_cmd(busid);
lun = busid & 7;
+ s->current_dev = scsi_device_find(&s->bus, s->current_dev->id, lun);
s->current_req = scsi_req_new(s->current_dev, 0, lun, buf, NULL);
datalen = scsi_req_enqueue(s->current_req);
s->ti_size = datalen;
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 4eeb496..c15f167 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -531,7 +531,7 @@ static void lsi_bad_selection(LSIState *s, uint32_t id)
/* Initiate a SCSI layer data transfer. */
static void lsi_do_dma(LSIState *s, int out)
{
- uint32_t count, id;
+ uint32_t count;
target_phys_addr_t addr;
SCSIDevice *dev;
@@ -542,12 +542,8 @@ static void lsi_do_dma(LSIState *s, int out)
return;
}
- id = (s->current->tag >> 8) & 0xf;
- dev = s->bus.devs[id];
- if (!dev) {
- lsi_bad_selection(s, id);
- return;
- }
+ dev = s->current->req->dev;
+ assert(dev);
count = s->dbc;
if (count > s->current->dma_len)
@@ -771,7 +767,7 @@ static void lsi_do_command(LSIState *s)
s->command_complete = 0;
id = (s->select_tag >> 8) & 0xf;
- dev = s->bus.devs[id];
+ dev = scsi_device_find(&s->bus, id, s->current_lun);
if (!dev) {
lsi_bad_selection(s, id);
return;
@@ -1202,7 +1198,7 @@ again:
}
s->sstat0 |= LSI_SSTAT0_WOA;
s->scntl1 &= ~LSI_SCNTL1_IARB;
- if (id >= LSI_MAX_DEVS || !s->bus.devs[id]) {
+ if (!scsi_device_find(&s->bus, id, 0)) {
lsi_bad_selection(s, id);
break;
}
@@ -1684,13 +1680,9 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
if (val & LSI_SCNTL1_RST) {
if (!(s->sstat0 & LSI_SSTAT0_RST)) {
DeviceState *dev;
- int id;
- for (id = 0; id < LSI_MAX_DEVS; id++) {
- if (s->bus.devs[id]) {
- dev = &s->bus.devs[id]->qdev;
- dev->info->reset(dev);
- }
+ QTAILQ_FOREACH(dev, &s->bus.qbus.children, sibling) {
+ dev->info->reset(dev);
}
s->sstat0 |= LSI_SSTAT0_RST;
lsi_script_scsi_interrupt(s, LSI_SIST0_RST, 0);
diff --git a/hw/qdev.h b/hw/qdev.h
index ff524cb..e5ad781 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -73,7 +73,7 @@ struct BusState {
const char *name;
int allow_hotplug;
int qdev_allocated;
- QTAILQ_HEAD(, DeviceState) children;
+ QTAILQ_HEAD(ChildrenHead, DeviceState) children;
QLIST_ENTRY(BusState) sibling;
};
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index d9d4e18..7104e98 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -37,12 +37,16 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
SCSIDeviceInfo *info = DO_UPCAST(SCSIDeviceInfo, qdev, base);
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
+ SCSIDevice *olddev;
int rc = -1;
if (dev->id == -1) {
- for (dev->id = 0; dev->id < bus->info->ndev; dev->id++) {
- if (bus->devs[dev->id] == NULL)
+ int id;
+ for (id = 0; id < bus->info->ndev; id++) {
+ if (!scsi_device_find(bus, id, 0)) {
+ dev->id = id;
break;
+ }
}
}
if (dev->id >= bus->info->ndev) {
@@ -50,17 +54,14 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
goto err;
}
- if (bus->devs[dev->id]) {
- qdev_free(&bus->devs[dev->id]->qdev);
+ olddev = scsi_device_find(bus, dev->id, dev->lun);
+ if (olddev && dev->lun == olddev->lun) {
+ qdev_free(&olddev->qdev);
}
- bus->devs[dev->id] = dev;
dev->info = info;
QTAILQ_INIT(&dev->requests);
rc = dev->info->init(dev);
- if (rc != 0) {
- bus->devs[dev->id] = NULL;
- }
err:
return rc;
@@ -69,13 +70,10 @@ err:
static int scsi_qdev_exit(DeviceState *qdev)
{
SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
- SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
- assert(bus->devs[dev->id] != NULL);
- if (bus->devs[dev->id]->info->destroy) {
- bus->devs[dev->id]->info->destroy(bus->devs[dev->id]);
+ if (dev->info->destroy) {
+ dev->info->destroy(dev);
}
- bus->devs[dev->id] = NULL;
return 0;
}
@@ -1157,19 +1155,28 @@ void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense)
static char *scsibus_get_fw_dev_path(DeviceState *dev)
{
SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev);
- SCSIBus *bus = scsi_bus_from_device(d);
char path[100];
- int i;
- for (i = 0; i < bus->info->ndev; i++) {
- if (bus->devs[i] == d) {
- break;
- }
- }
+ snprintf(path, sizeof(path), "%s@%d:%d:%d", qdev_fw_name(dev),
+ 0, d->id, d->lun);
- assert(i != bus->info->ndev);
+ return strdup(path);
+}
+
+SCSIDevice *scsi_device_find(SCSIBus *bus, int id, int lun)
+{
+ DeviceState *qdev;
+ SCSIDevice *target_dev = NULL;
- snprintf(path, sizeof(path), "%s@%x", qdev_fw_name(dev), i);
+ QTAILQ_FOREACH_REVERSE(qdev, &bus->qbus.children, ChildrenHead, sibling) {
+ SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
- return strdup(path);
+ if (dev->id == id) {
+ if (dev->lun == lun) {
+ return dev;
+ }
+ target_dev = dev;
+ }
+ }
+ return target_dev;
}
diff --git a/hw/scsi.h b/hw/scsi.h
index b76c4ee..add3d2d 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -110,8 +110,6 @@ struct SCSIBus {
SCSISense unit_attention;
const SCSIBusInfo *info;
-
- SCSIDevice *devs[MAX_SCSI_DEVS];
};
void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info);
@@ -195,5 +193,6 @@ void scsi_req_abort(SCSIRequest *req, int status);
void scsi_req_cancel(SCSIRequest *req);
void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense);
int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed);
+SCSIDevice *scsi_device_find(SCSIBus *bus, int target, int lun);
#endif
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index 6c5faf2..aae845a 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -129,11 +129,12 @@ static void vscsi_put_req(vscsi_req *req)
req->active = 0;
}
-static void vscsi_decode_id_lun(uint64_t srp_lun, int *id, int *lun)
+static SCSIDevice *vscsi_device_find(SCSIBus *bus, uint64_t srp_lun, int *lun)
{
/* XXX Figure that one out properly ! This is crackpot */
- *id = (srp_lun >> 56) & 0x7f;
+ int id = (srp_lun >> 56) & 0x7f;
*lun = (srp_lun >> 48) & 0xff;
+ return scsi_device_find (bus, id, *lun);
}
static int vscsi_send_iu(VSCSIState *s, vscsi_req *req,
@@ -582,14 +583,11 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)
{
union srp_iu *srp = &req->iu.srp;
SCSIDevice *sdev;
- int n, id, lun;
+ int n, lun;
- vscsi_decode_id_lun(be64_to_cpu(srp->cmd.lun), &id, &lun);
-
- /* Qemu vs. linux issue with LUNs to be sorted out ... */
- sdev = (id < 8 && lun < 16) ? s->bus.devs[id] : NULL;
+ sdev = vscsi_device_find(&s->bus, be64_to_cpu(srp->cmd.lun), &lun);
if (!sdev) {
- dprintf("VSCSI: Command for id %d with no drive\n", id);
+ dprintf("VSCSI: Command for lun %08" PRIx64 " with no drive\n", be64_to_cpu(srp->cmd.lun));
if (srp->cmd.cdb[0] == INQUIRY) {
vscsi_inquiry_no_target(s, req);
} else {
--
1.7.6
next prev parent reply other threads:[~2011-10-13 11:05 UTC|newest]
Thread overview: 68+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-13 11:03 [Qemu-devel] [PULL 00/35] SCSI uber-patch Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 01/35] scsi: pass correct sense code for ENOMEDIUM Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 02/35] atapi/scsi: unify definitions for MMC Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 03/35] atapi: move GESN definitions to scsi-defs.h Paolo Bonzini
2011-10-17 13:41 ` Kevin Wolf
2011-10-17 13:53 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 04/35] atapi: fill in AUDIO_CTL page correctly Paolo Bonzini
2011-10-17 14:05 ` Kevin Wolf
2011-10-17 14:04 ` Paolo Bonzini
2011-10-17 14:10 ` Kevin Wolf
2011-10-17 14:22 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 05/35] scsi: notify the device when unit attention is reported Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 06/35] scsi-disk: report media changed via unit attention sense codes Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 07/35] scsi-disk: add stubs for more MMC commands Paolo Bonzini
2011-10-17 14:27 ` Kevin Wolf
2011-10-17 14:28 ` Paolo Bonzini
2011-10-17 14:44 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 08/35] scsi-disk: store valid mode pages in a table Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 09/35] atapi/scsi-disk: make mode page values coherent between the two Paolo Bonzini
2011-10-17 15:05 ` Kevin Wolf
2011-10-17 15:06 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 10/35] scsi-disk: support DVD profile in GET CONFIGURATION Paolo Bonzini
2011-10-17 15:20 ` Kevin Wolf
2011-10-17 15:28 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 11/35] scsi-disk: support READ DVD STRUCTURE Paolo Bonzini
2011-10-21 11:42 ` Kevin Wolf
2011-10-21 13:11 ` Paolo Bonzini
2011-10-21 13:12 ` Paolo Bonzini
2011-10-21 13:32 ` Kevin Wolf
2011-10-21 13:36 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 12/35] scsi-disk: report media changed via GET EVENT STATUS NOTIFICATION Paolo Bonzini
2011-10-21 11:54 ` Kevin Wolf
2011-10-21 13:08 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 13/35] scsi: move tcq/ndev to SCSIBusOps (now SCSIBusInfo) Paolo Bonzini
2011-10-21 12:01 ` Kevin Wolf
2011-10-21 12:21 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 14/35] qdev: switch children device list to QTAILQ Paolo Bonzini
2011-10-13 11:03 ` Paolo Bonzini [this message]
2011-10-21 12:31 ` [Qemu-devel] [PATCH 15/35] scsi: remove devs array from SCSIBus Kevin Wolf
2011-10-21 13:03 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 16/35] scsi: implement REPORT LUNS for arbitrary LUNs Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 17/35] scsi: allow " Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 18/35] scsi: add channel to addressing Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 19/35] scsi-disk: fail READ CAPACITY if LBA != 0 but PMI == 0 Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 20/35] scsi-disk: do not complete requests twice Paolo Bonzini
2011-10-19 13:13 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 21/35] scsi-disk: bump SCSIRequest reference count until aio completion runs Paolo Bonzini
2011-10-17 15:37 ` [Qemu-devel] [PATCH v2 " Paolo Bonzini
2011-10-19 13:13 ` Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 22/35] scsi-disk: fix retrying a flush Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 23/35] scsi-generic: drop SCSIGenericState Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 24/35] scsi-generic: remove scsi_req_fixup Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 25/35] scsi-generic: check ioctl statuses when SG_IO succeeds Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 26/35] scsi-generic: look at host status Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 27/35] scsi-generic: snoop READ CAPACITY commands to get block size Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 28/35] scsi-disk: do not duplicate BlockDriverState member Paolo Bonzini
2011-10-13 11:03 ` [Qemu-devel] [PATCH 29/35] scsi-disk: remove cluster_size Paolo Bonzini
2011-10-24 15:10 ` Kevin Wolf
2011-10-24 15:36 ` Paolo Bonzini
2011-10-13 11:04 ` [Qemu-devel] [PATCH 30/35] scsi-disk: small clean up to INQUIRY Paolo Bonzini
2011-10-13 11:04 ` [Qemu-devel] [PATCH 31/35] scsi: move max_lba to SCSIDevice Paolo Bonzini
2011-10-13 11:04 ` [Qemu-devel] [PATCH 32/35] scsi: make reqops static const Paolo Bonzini
2011-10-13 11:04 ` [Qemu-devel] [PATCH 33/35] scsi: export scsi_generic_reqops Paolo Bonzini
2011-10-13 11:04 ` [Qemu-devel] [PATCH 34/35] scsi: pass cdb to alloc_req Paolo Bonzini
2011-10-13 11:04 ` [Qemu-devel] [PATCH 35/35] scsi-disk: add scsi-block for device passthrough Paolo Bonzini
2011-10-24 15:28 ` Kevin Wolf
2011-10-24 15:28 ` Paolo Bonzini
2011-10-24 15:38 ` Kevin Wolf
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=1318503845-11473-16-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).