diff options
author | Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> | 2024-01-12 12:53:00 +0000 |
---|---|---|
committer | Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> | 2024-02-13 19:37:13 +0000 |
commit | f21fe39d9ccc4485f6bc12eaae8271282921d42c (patch) | |
tree | fda370b44347bb7c7e67e8f25891d8a56a8032c3 /hw/scsi | |
parent | 0c5ae734c2942e1b71eaffab95ea9b7ce974d8db (diff) | |
download | qemu-f21fe39d9ccc4485f6bc12eaae8271282921d42c.zip qemu-f21fe39d9ccc4485f6bc12eaae8271282921d42c.tar.gz qemu-f21fe39d9ccc4485f6bc12eaae8271282921d42c.tar.bz2 |
esp.c: move command execution logic to new esp_run_cmd() function
This helps to simplify esp_reg_write() and potentially allows for a 2-level
deep FIFO to be implemented in future.
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-9-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Diffstat (limited to 'hw/scsi')
-rw-r--r-- | hw/scsi/esp.c | 177 |
1 files changed, 92 insertions, 85 deletions
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c index e717b2e..fecfef7 100644 --- a/hw/scsi/esp.c +++ b/hw/scsi/esp.c @@ -980,6 +980,97 @@ static void parent_esp_reset(ESPState *s, int irq, int level) } } +static void esp_run_cmd(ESPState *s) +{ + uint8_t cmd = s->rregs[ESP_CMD]; + + if (cmd & CMD_DMA) { + s->dma = 1; + /* Reload DMA counter. */ + if (esp_get_stc(s) == 0) { + esp_set_tc(s, 0x10000); + } else { + esp_set_tc(s, esp_get_stc(s)); + } + } else { + s->dma = 0; + } + switch (cmd & CMD_CMD) { + case CMD_NOP: + trace_esp_mem_writeb_cmd_nop(cmd); + break; + case CMD_FLUSH: + trace_esp_mem_writeb_cmd_flush(cmd); + fifo8_reset(&s->fifo); + break; + case CMD_RESET: + trace_esp_mem_writeb_cmd_reset(cmd); + esp_soft_reset(s); + break; + case CMD_BUSRESET: + trace_esp_mem_writeb_cmd_bus_reset(cmd); + esp_bus_reset(s); + if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) { + s->rregs[ESP_RINTR] |= INTR_RST; + esp_raise_irq(s); + } + break; + case CMD_TI: + trace_esp_mem_writeb_cmd_ti(cmd); + handle_ti(s); + break; + case CMD_ICCS: + trace_esp_mem_writeb_cmd_iccs(cmd); + write_response(s); + s->rregs[ESP_RINTR] |= INTR_FC; + s->rregs[ESP_RSTAT] |= STAT_MI; + break; + case CMD_MSGACC: + trace_esp_mem_writeb_cmd_msgacc(cmd); + s->rregs[ESP_RINTR] |= INTR_DC; + s->rregs[ESP_RSEQ] = 0; + s->rregs[ESP_RFLAGS] = 0; + esp_raise_irq(s); + break; + case CMD_PAD: + trace_esp_mem_writeb_cmd_pad(cmd); + s->rregs[ESP_RSTAT] = STAT_TC; + s->rregs[ESP_RINTR] |= INTR_FC; + s->rregs[ESP_RSEQ] = 0; + break; + case CMD_SATN: + trace_esp_mem_writeb_cmd_satn(cmd); + break; + case CMD_RSTATN: + trace_esp_mem_writeb_cmd_rstatn(cmd); + break; + case CMD_SEL: + trace_esp_mem_writeb_cmd_sel(cmd); + handle_s_without_atn(s); + break; + case CMD_SELATN: + trace_esp_mem_writeb_cmd_selatn(cmd); + handle_satn(s); + break; + case CMD_SELATNS: + trace_esp_mem_writeb_cmd_selatns(cmd); + handle_satn_stop(s); + break; + case CMD_ENSEL: + trace_esp_mem_writeb_cmd_ensel(cmd); + s->rregs[ESP_RINTR] = 0; + break; + case CMD_DISSEL: + trace_esp_mem_writeb_cmd_dissel(cmd); + s->rregs[ESP_RINTR] = 0; + esp_raise_irq(s); + break; + default: + trace_esp_error_unhandled_command(cmd); + break; + } +} + uint64_t esp_reg_read(ESPState *s, uint32_t saddr) { uint32_t val; @@ -1076,91 +1167,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) break; case ESP_CMD: s->rregs[saddr] = val; - if (val & CMD_DMA) { - s->dma = 1; - /* Reload DMA counter. */ - if (esp_get_stc(s) == 0) { - esp_set_tc(s, 0x10000); - } else { - esp_set_tc(s, esp_get_stc(s)); - } - } else { - s->dma = 0; - } - switch (val & CMD_CMD) { - case CMD_NOP: - trace_esp_mem_writeb_cmd_nop(val); - break; - case CMD_FLUSH: - trace_esp_mem_writeb_cmd_flush(val); - fifo8_reset(&s->fifo); - break; - case CMD_RESET: - trace_esp_mem_writeb_cmd_reset(val); - esp_soft_reset(s); - break; - case CMD_BUSRESET: - trace_esp_mem_writeb_cmd_bus_reset(val); - esp_bus_reset(s); - if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) { - s->rregs[ESP_RINTR] |= INTR_RST; - esp_raise_irq(s); - } - break; - case CMD_TI: - trace_esp_mem_writeb_cmd_ti(val); - handle_ti(s); - break; - case CMD_ICCS: - trace_esp_mem_writeb_cmd_iccs(val); - write_response(s); - s->rregs[ESP_RINTR] |= INTR_FC; - s->rregs[ESP_RSTAT] |= STAT_MI; - break; - case CMD_MSGACC: - trace_esp_mem_writeb_cmd_msgacc(val); - s->rregs[ESP_RINTR] |= INTR_DC; - s->rregs[ESP_RSEQ] = 0; - s->rregs[ESP_RFLAGS] = 0; - esp_raise_irq(s); - break; - case CMD_PAD: - trace_esp_mem_writeb_cmd_pad(val); - s->rregs[ESP_RSTAT] = STAT_TC; - s->rregs[ESP_RINTR] |= INTR_FC; - s->rregs[ESP_RSEQ] = 0; - break; - case CMD_SATN: - trace_esp_mem_writeb_cmd_satn(val); - break; - case CMD_RSTATN: - trace_esp_mem_writeb_cmd_rstatn(val); - break; - case CMD_SEL: - trace_esp_mem_writeb_cmd_sel(val); - handle_s_without_atn(s); - break; - case CMD_SELATN: - trace_esp_mem_writeb_cmd_selatn(val); - handle_satn(s); - break; - case CMD_SELATNS: - trace_esp_mem_writeb_cmd_selatns(val); - handle_satn_stop(s); - break; - case CMD_ENSEL: - trace_esp_mem_writeb_cmd_ensel(val); - s->rregs[ESP_RINTR] = 0; - break; - case CMD_DISSEL: - trace_esp_mem_writeb_cmd_dissel(val); - s->rregs[ESP_RINTR] = 0; - esp_raise_irq(s); - break; - default: - trace_esp_error_unhandled_command(val); - break; - } + esp_run_cmd(s); break; case ESP_WBUSID ... ESP_WSYNO: break; |