diff mbox series

[PULL,75/88] esp.c: improve ESP_RSEQ logic consolidation

Message ID 20240213194052.1162753-76-mark.cave-ayland@ilande.co.uk (mailing list archive)
State New, archived
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
The ESP_RSEQ logic is scattered in a few places throughout the ESP state machine
which is mainly because the ESP_RSEQ register isn't always reset when executing
an ESP select command. Once this is done, the ESP_RSEQ register only needs to be
updated at the point where the sequencer command completes.

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

Patch

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index aa7dec71e3..ca26415d5f 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -230,6 +230,7 @@  static int esp_select(ESPState *s)
     target = s->wregs[ESP_WBUSID] & BUSID_DID;
 
     s->ti_size = 0;
+    s->rregs[ESP_RSEQ] = SEQ_0;
 
     if (s->current_req) {
         /* Started a new command before the old one finished. Cancel it. */
@@ -241,7 +242,6 @@  static int esp_select(ESPState *s)
         /* No such drive */
         s->rregs[ESP_RSTAT] = 0;
         s->rregs[ESP_RINTR] = INTR_DC;
-        s->rregs[ESP_RSEQ] = SEQ_0;
         esp_raise_irq(s);
         return -1;
     }
@@ -250,7 +250,6 @@  static int esp_select(ESPState *s)
      * Note that we deliberately don't raise the IRQ here: this will be done
      * either in esp_transfer_data() or esp_command_complete()
      */
-    s->rregs[ESP_RSEQ] = SEQ_CD;
     return 0;
 }
 
@@ -358,7 +357,6 @@  static void handle_s_without_atn(ESPState *s)
     }
 
     esp_set_phase(s, STAT_CD);
-    s->rregs[ESP_RSEQ] = SEQ_CD;
     s->cmdfifo_cdb_offset = 0;
 
     if (s->dma) {
@@ -380,7 +378,6 @@  static void handle_satn_stop(ESPState *s)
     }
 
     esp_set_phase(s, STAT_MO);
-    s->rregs[ESP_RSEQ] = SEQ_MO;
     s->cmdfifo_cdb_offset = 0;
 
     if (s->dma) {
@@ -456,6 +453,7 @@  static void esp_do_dma(ESPState *s)
             if (fifo8_num_used(&s->cmdfifo) >= 1) {
                 /* First byte received, switch to command phase */
                 esp_set_phase(s, STAT_CD);
+                s->rregs[ESP_RSEQ] = SEQ_CD;
                 s->cmdfifo_cdb_offset = 1;
 
                 if (fifo8_num_used(&s->cmdfifo) > 1) {
@@ -468,11 +466,11 @@  static void esp_do_dma(ESPState *s)
         case CMD_SELATNS | CMD_DMA:
             if (fifo8_num_used(&s->cmdfifo) == 1) {
                 /* First byte received, stop in message out phase */
+                s->rregs[ESP_RSEQ] = SEQ_MO;
                 s->cmdfifo_cdb_offset = 1;
 
                 /* Raise command completion interrupt */
                 s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
-                s->rregs[ESP_RSEQ] = SEQ_CD;
                 esp_raise_irq(s);
             }
             break;
@@ -482,7 +480,6 @@  static void esp_do_dma(ESPState *s)
             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);
             }
@@ -726,6 +723,7 @@  static void esp_do_nodma(ESPState *s)
             if (fifo8_num_used(&s->cmdfifo) >= 1) {
                 /* First byte received, switch to command phase */
                 esp_set_phase(s, STAT_CD);
+                s->rregs[ESP_RSEQ] = SEQ_CD;
                 s->cmdfifo_cdb_offset = 1;
 
                 if (fifo8_num_used(&s->cmdfifo) > 1) {
@@ -738,6 +736,7 @@  static void esp_do_nodma(ESPState *s)
         case CMD_SELATNS:
             if (fifo8_num_used(&s->cmdfifo) >= 1) {
                 /* First byte received, stop in message out phase */
+                s->rregs[ESP_RSEQ] = SEQ_MO;
                 s->cmdfifo_cdb_offset = 1;
 
                 /* Raise command completion interrupt */
@@ -903,6 +902,7 @@  void esp_command_complete(SCSIRequest *req, size_t resid)
          * and function complete interrupt
          */
         s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
+        s->rregs[ESP_RSEQ] = SEQ_CD;
         break;
 
     case CMD_TI | CMD_DMA:
@@ -948,6 +948,7 @@  void esp_transfer_data(SCSIRequest *req, uint32_t len)
              * so raise deferred bus service and function complete interrupt
              */
              s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
+             s->rregs[ESP_RSEQ] = SEQ_CD;
              break;
 
         case CMD_SELATNS | CMD_DMA:
@@ -957,6 +958,7 @@  void esp_transfer_data(SCSIRequest *req, uint32_t len)
              * completion interrupt
              */
              s->rregs[ESP_RINTR] |= INTR_BS;
+             s->rregs[ESP_RSEQ] = SEQ_MO;
              break;
 
         case CMD_TI | CMD_DMA: