From: Kevin Wolf <kwolf@redhat.com>
To: anthony@codemonkey.ws
Cc: kwolf@redhat.com, qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 33/55] scsi: remove devs array from SCSIBus
Date: Mon, 31 Oct 2011 14:30:08 +0100 [thread overview]
Message-ID: <1320067830-12093-34-git-send-email-kwolf@redhat.com> (raw)
In-Reply-To: <1320067830-12093-1-git-send-email-kwolf@redhat.com>
From: Paolo Bonzini <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, and HBAs can talk to the correct device
when there are multiple LUNs per target.
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>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
hw/esp.c | 8 +++++---
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, 50 insertions(+), 52 deletions(-)
diff --git a/hw/esp.c b/hw/esp.c
index d3fb1c6..aad290f 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;
}
@@ -233,10 +233,12 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
{
int32_t datalen;
int lun;
+ SCSIDevice *current_lun;
trace_esp_do_busid_cmd(busid);
lun = busid & 7;
- s->current_req = scsi_req_new(s->current_dev, 0, lun, buf, NULL);
+ current_lun = scsi_device_find(&s->bus, s->current_dev->id, lun);
+ s->current_req = scsi_req_new(current_lun, 0, lun, buf, NULL);
datalen = scsi_req_enqueue(s->current_req);
s->ti_size = datalen;
if (datalen != 0) {
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 a7cc48b..36a4198 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 33ae9b4..ea3bb08 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.4
next prev parent reply other threads:[~2011-10-31 13:28 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-31 13:29 [Qemu-devel] [PULL 00/55] Block patches Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 01/55] iSCSI block driver Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 02/55] Documentation: Add iSCSI section Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 03/55] Teach block/vdi about "discarded" (no longer allocated) blocks Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 04/55] qcow2: fix some errors and typo in qcow2.txt Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 05/55] block: Remove dead code Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 06/55] block: Fix bdrv_open use after free Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 07/55] qcow: Fix bdrv_write_compressed error handling Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 08/55] ide: Fix off-by-one error in array index check Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 09/55] vmdk: Fix use of uninitialised value Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 10/55] vmdk: Improve error handling Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 11/55] vmdk: Fix possible segfaults Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 12/55] Documentation: Describe NBD URL syntax Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 13/55] block: fix qcow2_co_flush deadlock Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 14/55] qemu-io: delete bs instead of leaking it Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 15/55] block: set bs->read_only before .bdrv_open() Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 16/55] block: reinitialize across bdrv_close()/bdrv_open() Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 17/55] Documentation: Add syntax for using sheepdog devices Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 18/55] scsi: pass correct sense code for ENOMEDIUM Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 19/55] atapi/scsi: unify definitions for MMC Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 20/55] atapi: move GESN definitions to scsi-defs.h Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 21/55] atapi: cleanup/fix mode sense results Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 22/55] scsi: notify the device when unit attention is reported Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 23/55] scsi-disk: report media changed via unit attention sense codes Kevin Wolf
2011-10-31 13:29 ` [Qemu-devel] [PATCH 24/55] scsi-disk: fix coding style issues (braces) Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 25/55] scsi-disk: add stubs for more MMC commands Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 26/55] scsi-disk: store valid mode pages in a table Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 27/55] atapi/scsi-disk: make mode page values coherent between the two Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 28/55] scsi-disk: support DVD profile in GET CONFIGURATION Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 29/55] scsi-disk: support READ DVD STRUCTURE Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 30/55] scsi-disk: report media changed via GET EVENT STATUS NOTIFICATION Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 31/55] scsi: move tcq/ndev to SCSIBusOps (now SCSIBusInfo) Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 32/55] qdev: switch children device list to QTAILQ Kevin Wolf
2011-10-31 13:30 ` Kevin Wolf [this message]
2011-10-31 13:30 ` [Qemu-devel] [PATCH 34/55] scsi: implement REPORT LUNS for arbitrary LUNs Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 35/55] scsi: allow " Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 36/55] scsi: add channel to addressing Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 37/55] scsi-disk: fail READ CAPACITY if LBA != 0 but PMI == 0 Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 38/55] scsi-disk: fix retrying a flush Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 39/55] scsi-generic: drop SCSIGenericState Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 40/55] scsi-generic: remove scsi_req_fixup Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 41/55] scsi-generic: check ioctl statuses when SG_IO succeeds Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 42/55] scsi-generic: look at host status Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 43/55] scsi-generic: snoop READ CAPACITY commands to get block size Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 44/55] scsi-disk: do not duplicate BlockDriverState member Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 45/55] scsi-disk: remove cluster_size Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 46/55] scsi-disk: small clean up to INQUIRY Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 47/55] scsi: move max_lba to SCSIDevice Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 48/55] scsi: make reqops const Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 49/55] scsi: export scsi_generic_reqops Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 50/55] scsi: pass cdb to alloc_req Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 51/55] scsi: do not call transfer_data after canceling a request Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 52/55] scsi-disk: bump SCSIRequest reference count until aio completion runs Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 53/55] scsi-generic: " Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 54/55] scsi: push request restart to SCSIDevice Kevin Wolf
2011-10-31 13:30 ` [Qemu-devel] [PATCH 55/55] scsi-disk: add scsi-block for device passthrough Kevin Wolf
2011-10-31 16:52 ` [Qemu-devel] [PULL 00/55] Block patches Anthony Liguori
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=1320067830-12093-34-git-send-email-kwolf@redhat.com \
--to=kwolf@redhat.com \
--cc=anthony@codemonkey.ws \
--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).