sim-card
/
qemu
Archived
10
0
Fork 0

lsi: extract lsi_find_by_tag

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
Paolo Bonzini 2011-04-18 12:01:45 +02:00
parent ad2d30f79d
commit 11257187e1
1 changed files with 38 additions and 25 deletions

View File

@ -652,38 +652,51 @@ static void lsi_reselect(LSIState *s, lsi_request *p)
} }
} }
static lsi_request *lsi_find_by_tag(LSIState *s, uint32_t tag)
{
lsi_request *p;
QTAILQ_FOREACH(p, &s->queue, next) {
if (p->tag == tag) {
return p;
}
}
return NULL;
}
/* Record that data is available for a queued command. Returns zero if /* Record that data is available for a queued command. Returns zero if
the device was reselected, nonzero if the IO is deferred. */ the device was reselected, nonzero if the IO is deferred. */
static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg) static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg)
{ {
lsi_request *p; lsi_request *p;
QTAILQ_FOREACH(p, &s->queue, next) { p = lsi_find_by_tag(s, tag);
if (p->tag == tag) { if (!p) {
if (p->pending) { BADF("IO with unknown tag %d\n", tag);
BADF("Multiple IO pending for tag %d\n", tag); return 1;
} }
p->pending = arg;
/* Reselect if waiting for it, or if reselection triggers an IRQ if (p->pending) {
and the bus is free. BADF("Multiple IO pending for tag %d\n", tag);
Since no interrupt stacking is implemented in the emulation, it }
is also required that there are no pending interrupts waiting p->pending = arg;
for service from the device driver. */ /* Reselect if waiting for it, or if reselection triggers an IRQ
if (s->waiting == 1 || and the bus is free.
(lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) && Since no interrupt stacking is implemented in the emulation, it
!(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) { is also required that there are no pending interrupts waiting
/* Reselect device. */ for service from the device driver. */
lsi_reselect(s, p); if (s->waiting == 1 ||
return 0; (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) &&
} else { !(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) {
DPRINTF("Queueing IO tag=0x%x\n", tag); /* Reselect device. */
p->pending = arg; lsi_reselect(s, p);
return 1; return 0;
} } else {
} DPRINTF("Queueing IO tag=0x%x\n", tag);
p->pending = arg;
return 1;
} }
BADF("IO with unknown tag %d\n", tag);
return 1;
} }
/* Callback to indicate that the SCSI layer has completed a transfer. */ /* Callback to indicate that the SCSI layer has completed a transfer. */