From 6f5b0bce327dc75eeeebff097b5de0c535e57360 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Mon, 7 Aug 2023 07:53:00 +0100 Subject: 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 Message-ID: <20230807065300.366070-4-mark.cave-ayland@ilande.co.uk> Signed-off-by: Gerd Hoffmann --- src/hw/esp-scsi.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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); -- cgit v1.1