diff mbox series

[PULL,14/88] esp.c: introduce esp_set_phase() helper function

Message ID 20240213194052.1162753-15-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:39 p.m. UTC
This function is used to set the current SCSI bus phase in the ESP_RSTAT register
without affecting any of flag bits.

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-15-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c        | 51 ++++++++++++++++++++++++++++++--------------
 hw/scsi/trace-events |  1 +
 2 files changed, 36 insertions(+), 16 deletions(-)
diff mbox series

Patch

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index f08b816aba..3fc7417d7c 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -183,6 +183,19 @@  static uint32_t esp_get_stc(ESPState *s)
     return dmalen;
 }
 
+static const char *esp_phase_names[8] = {
+    "DATA OUT", "DATA IN", "COMMAND", "STATUS",
+    "(reserved)", "(reserved)", "MESSAGE OUT", "MESSAGE IN"
+};
+
+static void esp_set_phase(ESPState *s, uint8_t phase)
+{
+    s->rregs[ESP_RSTAT] &= ~7;
+    s->rregs[ESP_RSTAT] |= phase;
+
+    trace_esp_set_phase(esp_phase_names[phase]);
+}
+
 static uint8_t esp_pdma_read(ESPState *s)
 {
     uint8_t val;
@@ -316,9 +329,9 @@  static void do_command_phase(ESPState *s)
              * complete before raising the command completion interrupt
              */
             s->data_in_ready = false;
-            s->rregs[ESP_RSTAT] |= STAT_DI;
+            esp_set_phase(s, STAT_DI);
         } else {
-            s->rregs[ESP_RSTAT] |= STAT_DO;
+            esp_set_phase(s, STAT_DO);
             s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
             esp_raise_irq(s);
             esp_lower_drq(s);
@@ -394,7 +407,7 @@  static void handle_satn(ESPState *s)
         s->do_cmd = 1;
         /* Target present, but no cmd yet - switch to command phase */
         s->rregs[ESP_RSEQ] = SEQ_CD;
-        s->rregs[ESP_RSTAT] = STAT_CD;
+        esp_set_phase(s, STAT_CD);
     }
 }
 
@@ -439,7 +452,7 @@  static void handle_s_without_atn(ESPState *s)
         s->do_cmd = 1;
         /* Target present, but no cmd yet - switch to command phase */
         s->rregs[ESP_RSEQ] = SEQ_CD;
-        s->rregs[ESP_RSTAT] = STAT_CD;
+        esp_set_phase(s, STAT_CD);
     }
 }
 
@@ -457,7 +470,8 @@  static void satn_stop_pdma_cb(ESPState *s)
         trace_esp_handle_satn_stop(fifo8_num_used(&s->cmdfifo));
         s->do_cmd = 1;
         s->cmdfifo_cdb_offset = 1;
-        s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
+        esp_set_phase(s, STAT_CD);
+        s->rregs[ESP_RSTAT] |= STAT_TC;
         s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
         s->rregs[ESP_RSEQ] = SEQ_CD;
         esp_raise_irq(s);
@@ -481,7 +495,7 @@  static void handle_satn_stop(ESPState *s)
         trace_esp_handle_satn_stop(fifo8_num_used(&s->cmdfifo));
         s->do_cmd = 1;
         s->cmdfifo_cdb_offset = 1;
-        s->rregs[ESP_RSTAT] = STAT_MO;
+        esp_set_phase(s, STAT_MO);
         s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
         s->rregs[ESP_RSEQ] = SEQ_MO;
         esp_raise_irq(s);
@@ -492,13 +506,14 @@  static void handle_satn_stop(ESPState *s)
         s->do_cmd = 1;
         /* Target present, switch to message out phase */
         s->rregs[ESP_RSEQ] = SEQ_MO;
-        s->rregs[ESP_RSTAT] = STAT_MO;
+        esp_set_phase(s, STAT_MO);
     }
 }
 
 static void write_response_pdma_cb(ESPState *s)
 {
-    s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
+    esp_set_phase(s, STAT_ST);
+    s->rregs[ESP_RSTAT] |= STAT_TC;
     s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
     s->rregs[ESP_RSEQ] = SEQ_CD;
     esp_raise_irq(s);
@@ -516,7 +531,8 @@  static void write_response(ESPState *s)
     if (s->dma) {
         if (s->dma_memory_write) {
             s->dma_memory_write(s->dma_opaque, buf, 2);
-            s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
+            esp_set_phase(s, STAT_ST);
+            s->rregs[ESP_RSTAT] |= STAT_TC;
             s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
             s->rregs[ESP_RSEQ] = SEQ_CD;
         } else {
@@ -575,7 +591,8 @@  static void do_dma_pdma_cb(ESPState *s)
              * and then switch to command phase
              */
             s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo);
-            s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
+            esp_set_phase(s, STAT_CD);
+            s->rregs[ESP_RSTAT] |= STAT_TC;
             s->rregs[ESP_RSEQ] = SEQ_CD;
             s->rregs[ESP_RINTR] |= INTR_BS;
             esp_raise_irq(s);
@@ -681,7 +698,8 @@  static void esp_do_dma(ESPState *s)
              * and then switch to command phase
              */
             s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo);
-            s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
+            esp_set_phase(s, STAT_CD);
+            s->rregs[ESP_RSTAT] |= STAT_TC;
             s->rregs[ESP_RSEQ] = SEQ_CD;
             s->rregs[ESP_RINTR] |= INTR_BS;
             esp_raise_irq(s);
@@ -810,7 +828,8 @@  static void esp_do_nodma(ESPState *s)
              * and then switch to command phase
              */
             s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo);
-            s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
+            esp_set_phase(s, STAT_CD);
+            s->rregs[ESP_RSTAT] |= STAT_TC;
             s->rregs[ESP_RSEQ] = SEQ_CD;
             s->rregs[ESP_RINTR] |= INTR_BS;
             esp_raise_irq(s);
@@ -904,8 +923,7 @@  void esp_command_complete(SCSIRequest *req, size_t resid)
      * transfers from the target the last byte is still in the FIFO
      */
     if (s->ti_size == 0) {
-        s->rregs[ESP_RSTAT] &= ~7;
-        s->rregs[ESP_RSTAT] |= STAT_ST;
+        esp_set_phase(s, STAT_ST);
         esp_dma_done(s);
         esp_lower_drq(s);
     }
@@ -1065,7 +1083,7 @@  static void esp_run_cmd(ESPState *s)
         trace_esp_mem_writeb_cmd_iccs(cmd);
         write_response(s);
         s->rregs[ESP_RINTR] |= INTR_FC;
-        s->rregs[ESP_RSTAT] |= STAT_MI;
+        esp_set_phase(s, STAT_MI);
         break;
     case CMD_MSGACC:
         trace_esp_mem_writeb_cmd_msgacc(cmd);
@@ -1133,7 +1151,8 @@  uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
                      * The last byte of a non-DMA transfer has been read out
                      * of the FIFO so switch to status phase
                      */
-                    s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
+                    esp_set_phase(s, STAT_ST);
+                    s->rregs[ESP_RSTAT] |= STAT_TC;
                 }
             }
             s->rregs[ESP_FIFO] = esp_fifo_pop(&s->fifo);
diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
index bdd4e2c7c7..d72f741ed8 100644
--- a/hw/scsi/trace-events
+++ b/hw/scsi/trace-events
@@ -197,6 +197,7 @@  esp_mem_writeb_cmd_selatns(uint32_t val) "Select with ATN & stop (0x%2.2x)"
 esp_mem_writeb_cmd_ensel(uint32_t val) "Enable selection (0x%2.2x)"
 esp_mem_writeb_cmd_dissel(uint32_t val) "Disable selection (0x%2.2x)"
 esp_mem_writeb_cmd_ti(uint32_t val) "Transfer Information (0x%2.2x)"
+esp_set_phase(const char *phase) "setting bus phase to %s"
 
 # esp-pci.c
 esp_pci_error_invalid_dma_direction(void) "invalid DMA transfer direction"