aboutsummaryrefslogtreecommitdiff
path: root/hw/lsi53c895a.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2011-07-28 18:02:13 +0200
committerKevin Wolf <kwolf@redhat.com>2011-10-28 19:25:51 +0200
commitf48a7a6e35bb6d50573cfb42f13878c593fb6c0c (patch)
tree7f867312c0062f25c182f0660ed92aafdc69ef4a /hw/lsi53c895a.c
parentd8bb00d6d72eba317f78501434fc37db4968fa31 (diff)
scsi: remove devs array from SCSIBus
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>
Diffstat (limited to 'hw/lsi53c895a.c')
-rw-r--r--hw/lsi53c895a.c22
1 files changed, 7 insertions, 15 deletions
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 4eeb49632c..c15f167c84 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);