diff mbox series

[58/88] esp.c: separate logic based upon ESP command in esp_command_complete()

Message ID 20240112125420.514425-59-mark.cave-ayland@ilande.co.uk
State New
Headers show
Series esp: rework ESP emulation to use a SCSI phase-based state machine | expand

Commit Message

Mark Cave-Ayland Jan. 12, 2024, 12:53 p.m. UTC
The handling of the INTR_FC and INTR_BS bits is different depending upon the
last command executed by the ESP. Note that currently INTR_FC is managed
elsewhere, but that will change soon.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)
diff mbox series

Patch

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 73c723afcc..75538f5859 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -823,25 +823,27 @@  void esp_command_complete(SCSIRequest *req, size_t resid)
      * Switch to status phase. For non-DMA transfers from the target the last
      * byte is still in the FIFO
      */
-    esp_set_phase(s, STAT_ST);
-    if (s->ti_size == 0) {
-        /*
-         * Transfer complete: force TC to zero just in case a TI command was
-         * requested for more data than the command returns (Solaris 8 does
-         * this)
-         */
-        esp_set_tc(s, 0);
-        esp_dma_ti_check(s);
-    } else {
+    s->ti_size = 0;
+
+    switch (s->rregs[ESP_CMD]) {
+    case CMD_SEL | CMD_DMA:
+    case CMD_SEL:
+    case CMD_SELATN | CMD_DMA:
+    case CMD_SELATN:
         /*
-         * Transfer truncated: raise INTR_BS to indicate early change of
-         * phase
+         * No data phase for sequencer command so raise deferred bus service
+         * interrupt
          */
         s->rregs[ESP_RINTR] |= INTR_BS;
-        esp_raise_irq(s);
-        s->ti_size = 0;
+        break;
     }
 
+    /* Raise bus service interrupt to indicate change to STATUS phase */
+    esp_set_phase(s, STAT_ST);
+    s->rregs[ESP_RINTR] |= INTR_BS;
+    esp_raise_irq(s);
+    esp_lower_drq(s);
+
     if (s->current_req) {
         scsi_req_unref(s->current_req);
         s->current_req = NULL;