aboutsummaryrefslogtreecommitdiff
path: root/hw/scsi
diff options
context:
space:
mode:
authorMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2024-01-12 12:54:08 +0000
committerMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2024-02-13 19:37:28 +0000
commitacdee66d077371de049489f55a4bda5d1f4246c0 (patch)
treeba97e180dbf632dcae5a56b9df8d9d4fb84aa17e /hw/scsi
parent9b2cdca2d9511e460dc2235bcd8058c9faeea3d9 (diff)
esp.c: only transfer non-DMA COMMAND phase data for specific commands
The contents of the FIFO should only be copied to cmdfifo for ESP commands that are sending data to the SCSI bus, which are the SEL_* commands and the TI command. Otherwise any incoming data should be held in the FIFO as normal. This fixes booting of really old 32-bit SPARC Linux kernels such as Aurelien's debian_etch_sparc_small.qcow2 test image. 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-77-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.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index ca26415d5f..17e2db442c 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -757,13 +757,13 @@ static void esp_do_nodma(ESPState *s)
break;
case STAT_CD:
- /* Copy FIFO into cmdfifo */
- n = esp_fifo_pop_buf(&s->fifo, buf, fifo8_num_used(&s->fifo));
- n = MIN(fifo8_num_free(&s->cmdfifo), n);
- fifo8_push_all(&s->cmdfifo, buf, n);
-
switch (s->rregs[ESP_CMD]) {
case CMD_TI:
+ /* Copy FIFO into cmdfifo */
+ n = esp_fifo_pop_buf(&s->fifo, buf, fifo8_num_used(&s->fifo));
+ n = MIN(fifo8_num_free(&s->cmdfifo), n);
+ fifo8_push_all(&s->cmdfifo, buf, n);
+
cmdlen = fifo8_num_used(&s->cmdfifo);
trace_esp_handle_ti_cmd(cmdlen);
@@ -788,6 +788,11 @@ static void esp_do_nodma(ESPState *s)
case CMD_SEL | CMD_DMA:
case CMD_SELATN | CMD_DMA:
+ /* Copy FIFO into cmdfifo */
+ n = esp_fifo_pop_buf(&s->fifo, buf, fifo8_num_used(&s->fifo));
+ n = MIN(fifo8_num_free(&s->cmdfifo), n);
+ fifo8_push_all(&s->cmdfifo, buf, n);
+
/* Handle when DMA transfer is terminated by non-DMA FIFO write */
if (esp_cdb_length(s) && esp_cdb_length(s) ==
fifo8_num_used(&s->cmdfifo) - s->cmdfifo_cdb_offset) {
@@ -798,7 +803,11 @@ static void esp_do_nodma(ESPState *s)
case CMD_SEL:
case CMD_SELATN:
- /* FIFO already contain entire CDB */
+ /* FIFO already contain entire CDB: copy to cmdfifo and execute */
+ n = esp_fifo_pop_buf(&s->fifo, buf, fifo8_num_used(&s->fifo));
+ n = MIN(fifo8_num_free(&s->cmdfifo), n);
+ fifo8_push_all(&s->cmdfifo, buf, n);
+
do_cmd(s);
break;
}