diff mbox series

[PULL,62/88] esp.c: zero command register when TI command terminates due to phase change

Message ID 20240213194052.1162753-63-mark.cave-ayland@ilande.co.uk
State New
Headers show
Series [PULL,01/88] esp.c: don't clear cmdfifo when esp_select() fails in get_cmd() | expand

Commit Message

Mark Cave-Ayland Feb. 13, 2024, 7:40 p.m. UTC
This is the behaviour documented in the datasheet and allows the state machine
to correctly process multiple consecutive TI commands.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20240112125420.514425-63-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 8 ++++++++
 1 file changed, 8 insertions(+)
diff mbox series

Patch

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 4c1ca63a57..ccb8ad4bae 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -519,6 +519,7 @@  static void esp_do_dma(ESPState *s)
             /* ATN remains asserted until TC == 0 */
             if (esp_get_tc(s) == 0) {
                 esp_set_phase(s, STAT_CD);
+                s->rregs[ESP_CMD] = 0;
                 s->rregs[ESP_RSEQ] = SEQ_CD;
                 s->rregs[ESP_RINTR] |= INTR_BS;
                 esp_raise_irq(s);
@@ -717,6 +718,7 @@  static void esp_do_nodma(ESPState *s)
          */
         s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo);
         esp_set_phase(s, STAT_CD);
+        s->rregs[ESP_CMD] = 0;
         s->rregs[ESP_RSEQ] = SEQ_CD;
         s->rregs[ESP_RINTR] |= INTR_BS;
         esp_raise_irq(s);
@@ -831,6 +833,11 @@  void esp_command_complete(SCSIRequest *req, size_t resid)
          */
         s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
         break;
+
+    case CMD_TI | CMD_DMA:
+    case CMD_TI:
+        s->rregs[ESP_CMD] = 0;
+        break;
     }
 
     /* Raise bus service interrupt to indicate change to STATUS phase */
@@ -885,6 +892,7 @@  void esp_transfer_data(SCSIRequest *req, uint32_t len)
              * Bus service interrupt raised because of initial change to
              * DATA phase
              */
+            s->rregs[ESP_CMD] = 0;
             s->rregs[ESP_RINTR] |= INTR_BS;
             break;
         }