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>
This commit is contained in:
parent
0c5ae734c2
commit
f21fe39d9c
177
hw/scsi/esp.c
177
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;
|
||||
|
Loading…
Reference in New Issue
Block a user