aboutsummaryrefslogtreecommitdiff
path: root/hw/lsi53c895a.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2011-04-18 12:01:45 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2011-05-26 12:14:15 +0200
commit11257187e122f1b33e4983b881a2b6009f5993ca (patch)
tree0e0b568efbe12c2725b8a526ffeff804e02f4046 /hw/lsi53c895a.c
parentad2d30f79d3b0812f02c741be2189796b788d6d7 (diff)
downloadqemu-11257187e122f1b33e4983b881a2b6009f5993ca.zip
qemu-11257187e122f1b33e4983b881a2b6009f5993ca.tar.gz
qemu-11257187e122f1b33e4983b881a2b6009f5993ca.tar.bz2
lsi: extract lsi_find_by_tag
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'hw/lsi53c895a.c')
-rw-r--r--hw/lsi53c895a.c63
1 files changed, 38 insertions, 25 deletions
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 704e8ad..1ebcde7 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -652,38 +652,51 @@ static void lsi_reselect(LSIState *s, lsi_request *p)
}
}
-/* Record that data is available for a queued command. Returns zero if
- the device was reselected, nonzero if the IO is deferred. */
-static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg)
+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) {
- if (p->pending) {
- BADF("Multiple IO pending for tag %d\n", tag);
- }
- p->pending = arg;
- /* Reselect if waiting for it, or if reselection triggers an IRQ
- and the bus is free.
- Since no interrupt stacking is implemented in the emulation, it
- is also required that there are no pending interrupts waiting
- for service from the device driver. */
- if (s->waiting == 1 ||
- (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) &&
- !(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) {
- /* Reselect device. */
- lsi_reselect(s, p);
- return 0;
- } else {
- DPRINTF("Queueing IO tag=0x%x\n", tag);
- p->pending = arg;
- return 1;
- }
+ return p;
}
}
- BADF("IO with unknown tag %d\n", tag);
- return 1;
+
+ return NULL;
+}
+
+/* Record that data is available for a queued command. Returns zero if
+ the device was reselected, nonzero if the IO is deferred. */
+static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg)
+{
+ lsi_request *p;
+
+ p = lsi_find_by_tag(s, tag);
+ if (!p) {
+ BADF("IO with unknown tag %d\n", tag);
+ return 1;
+ }
+
+ if (p->pending) {
+ BADF("Multiple IO pending for tag %d\n", tag);
+ }
+ p->pending = arg;
+ /* Reselect if waiting for it, or if reselection triggers an IRQ
+ and the bus is free.
+ Since no interrupt stacking is implemented in the emulation, it
+ is also required that there are no pending interrupts waiting
+ for service from the device driver. */
+ if (s->waiting == 1 ||
+ (lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) &&
+ !(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) {
+ /* Reselect device. */
+ lsi_reselect(s, p);
+ return 0;
+ } else {
+ DPRINTF("Queueing IO tag=0x%x\n", tag);
+ p->pending = arg;
+ return 1;
+ }
}
/* Callback to indicate that the SCSI layer has completed a transfer. */