Revision 11257187 hw/lsi53c895a.c
b/hw/lsi53c895a.c | ||
---|---|---|
652 | 652 |
} |
653 | 653 |
} |
654 | 654 |
|
655 |
/* Record that data is available for a queued command. Returns zero if |
|
656 |
the device was reselected, nonzero if the IO is deferred. */ |
|
657 |
static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg) |
|
655 |
static lsi_request *lsi_find_by_tag(LSIState *s, uint32_t tag) |
|
658 | 656 |
{ |
659 | 657 |
lsi_request *p; |
660 | 658 |
|
661 | 659 |
QTAILQ_FOREACH(p, &s->queue, next) { |
662 | 660 |
if (p->tag == tag) { |
663 |
if (p->pending) { |
|
664 |
BADF("Multiple IO pending for tag %d\n", tag); |
|
665 |
} |
|
666 |
p->pending = arg; |
|
667 |
/* Reselect if waiting for it, or if reselection triggers an IRQ |
|
668 |
and the bus is free. |
|
669 |
Since no interrupt stacking is implemented in the emulation, it |
|
670 |
is also required that there are no pending interrupts waiting |
|
671 |
for service from the device driver. */ |
|
672 |
if (s->waiting == 1 || |
|
673 |
(lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) && |
|
674 |
!(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) { |
|
675 |
/* Reselect device. */ |
|
676 |
lsi_reselect(s, p); |
|
677 |
return 0; |
|
678 |
} else { |
|
679 |
DPRINTF("Queueing IO tag=0x%x\n", tag); |
|
680 |
p->pending = arg; |
|
681 |
return 1; |
|
682 |
} |
|
661 |
return p; |
|
683 | 662 |
} |
684 | 663 |
} |
685 |
BADF("IO with unknown tag %d\n", tag); |
|
686 |
return 1; |
|
664 |
|
|
665 |
return NULL; |
|
666 |
} |
|
667 |
|
|
668 |
/* Record that data is available for a queued command. Returns zero if |
|
669 |
the device was reselected, nonzero if the IO is deferred. */ |
|
670 |
static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg) |
|
671 |
{ |
|
672 |
lsi_request *p; |
|
673 |
|
|
674 |
p = lsi_find_by_tag(s, tag); |
|
675 |
if (!p) { |
|
676 |
BADF("IO with unknown tag %d\n", tag); |
|
677 |
return 1; |
|
678 |
} |
|
679 |
|
|
680 |
if (p->pending) { |
|
681 |
BADF("Multiple IO pending for tag %d\n", tag); |
|
682 |
} |
|
683 |
p->pending = arg; |
|
684 |
/* Reselect if waiting for it, or if reselection triggers an IRQ |
|
685 |
and the bus is free. |
|
686 |
Since no interrupt stacking is implemented in the emulation, it |
|
687 |
is also required that there are no pending interrupts waiting |
|
688 |
for service from the device driver. */ |
|
689 |
if (s->waiting == 1 || |
|
690 |
(lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) && |
|
691 |
!(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) { |
|
692 |
/* Reselect device. */ |
|
693 |
lsi_reselect(s, p); |
|
694 |
return 0; |
|
695 |
} else { |
|
696 |
DPRINTF("Queueing IO tag=0x%x\n", tag); |
|
697 |
p->pending = arg; |
|
698 |
return 1; |
|
699 |
} |
|
687 | 700 |
} |
688 | 701 |
|
689 | 702 |
/* Callback to indicate that the SCSI layer has completed a transfer. */ |
Also available in: Unified diff