esp.c: zero command register when TI command terminates due to phase change

This is the behaviour documented in the datasheet and allows the state machine
to correctly process multiple consecutive TI commands.

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-63-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
This commit is contained in:
Mark Cave-Ayland 2024-01-12 12:53:54 +00:00
parent 036120f3af
commit cb22ce5038

View File

@ -519,6 +519,7 @@ static void esp_do_dma(ESPState *s)
/* ATN remains asserted until TC == 0 */
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);
@ -717,6 +718,7 @@ static void esp_do_nodma(ESPState *s)
*/
s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo);
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);
@ -831,6 +833,11 @@ void esp_command_complete(SCSIRequest *req, size_t resid)
*/
s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
break;
case CMD_TI | CMD_DMA:
case CMD_TI:
s->rregs[ESP_CMD] = 0;
break;
}
/* Raise bus service interrupt to indicate change to STATUS phase */
@ -885,6 +892,7 @@ void esp_transfer_data(SCSIRequest *req, uint32_t len)
* Bus service interrupt raised because of initial change to
* DATA phase
*/
s->rregs[ESP_CMD] = 0;
s->rregs[ESP_RINTR] |= INTR_BS;
break;
}