diff options
author | Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> | 2024-01-12 12:53:06 +0000 |
---|---|---|
committer | Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> | 2024-02-13 19:37:23 +0000 |
commit | abc139cda0817ed4682b6d3eabef65094eb82600 (patch) | |
tree | 4438b0bf2811b285a6b2e5d38ca91d3b92e7f186 /hw | |
parent | a034765161b22fdd12d51ec7a30e65750e821107 (diff) | |
download | qemu-abc139cda0817ed4682b6d3eabef65094eb82600.zip qemu-abc139cda0817ed4682b6d3eabef65094eb82600.tar.gz qemu-abc139cda0817ed4682b6d3eabef65094eb82600.tar.bz2 |
esp.c: introduce esp_set_phase() helper function
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>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/scsi/esp.c | 51 | ||||
-rw-r--r-- | hw/scsi/trace-events | 1 |
2 files changed, 36 insertions, 16 deletions
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c index f08b816..3fc7417 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 bdd4e2c..d72f741 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" |