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:
parent
ad2d30f79d
commit
11257187e1
|
@ -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. */
|
||||||
|
|
Reference in New Issue