aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2023-08-07 07:53:00 +0100
committerHelge Deller <deller@gmx.de>2023-09-16 16:29:36 +0200
commit6f5b0bce327dc75eeeebff097b5de0c535e57360 (patch)
treedd4a8b9d7d0b4f5cc34b7b73dce460d9d6eedd8f
parenta0527d3de1354b482313757a0c8b4a5debf4d4c6 (diff)
downloadseabios-hppa-6f5b0bce327dc75eeeebff097b5de0c535e57360.zip
seabios-hppa-6f5b0bce327dc75eeeebff097b5de0c535e57360.tar.gz
seabios-hppa-6f5b0bce327dc75eeeebff097b5de0c535e57360.tar.bz2
esp-scsi: handle non-DMA SCSI commands with no data phase
The existing esp-scsi state machine checks for the STAT_TC bit to exit state 1 but in the case where there is no data phase, a non-DMA command is executed which doesn't set STAT_TC. This only works because QEMU currently always sets STAT_TC just after issuing every SCSI command. Update the esp-scsi state machine so that in the case where there is no data phase, we immediately execute CMD_ICCS instead of waiting for STAT_TC to be set which will never happen with a non-DMA CMD_SELATN command. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Message-ID: <20230807065300.366070-4-mark.cave-ayland@ilande.co.uk> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r--src/hw/esp-scsi.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/hw/esp-scsi.c b/src/hw/esp-scsi.c
index b8631ea6..38c95c1 100644
--- a/src/hw/esp-scsi.c
+++ b/src/hw/esp-scsi.c
@@ -137,6 +137,9 @@ esp_scsi_process_op(struct disk_op_s *op)
esp_scsi_dma(iobase, (u32)op->buf_fl, count, scsi_is_read(op));
outb(ESP_CMD_TI | ESP_CMD_DMA, iobase + ESP_CMD);
continue;
+ } else {
+ /* No data phase. */
+ state++;
}
}
}
@@ -144,12 +147,18 @@ esp_scsi_process_op(struct disk_op_s *op)
/* At end of DMA TC is set again -> complete command. */
if (state == 1 && (stat & ESP_STAT_TC)) {
state++;
+ continue;
+ }
+
+ /* Request message in data. */
+ if (state == 2) {
+ state++;
outb(ESP_CMD_ICCS, iobase + ESP_CMD);
continue;
}
/* Finally read data from the message in phase. */
- if (state == 2 && (stat & ESP_STAT_MSG)) {
+ if (state == 3 && (stat & ESP_STAT_MSG)) {
state++;
status = inb(iobase + ESP_FIFO);
inb(iobase + ESP_FIFO);