From 1bcaf71b41120acce0803c06dd48750e54583ce2 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 12 Jan 2024 12:52:57 +0000 Subject: [PATCH] esp.c: move esp_select() to ESP selection commands from get_cmd() Since the DREQ value depends upon the result of the selection process, add a workaround to each esp_select() to manually assert DREQ durring the MESSAGE OUT and COMMAND phases. Signed-off-by: Mark Cave-Ayland Tested-by: Helge Deller Tested-by: Thomas Huth Message-Id: <20240112125420.514425-6-mark.cave-ayland@ilande.co.uk> Signed-off-by: Mark Cave-Ayland --- hw/scsi/esp.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c index 89fce05e58..8c1c6bfc1c 100644 --- a/hw/scsi/esp.c +++ b/hw/scsi/esp.c @@ -263,10 +263,6 @@ static uint32_t get_cmd(ESPState *s, uint32_t maxlen) dmalen = MIN(fifo8_num_free(&s->cmdfifo), dmalen); fifo8_push_all(&s->cmdfifo, buf, dmalen); } else { - if (esp_select(s) < 0) { - return -1; - } - esp_raise_drq(s); return 0; } } else { @@ -280,9 +276,6 @@ static uint32_t get_cmd(ESPState *s, uint32_t maxlen) } trace_esp_get_cmd(dmalen, target); - if (esp_select(s) < 0) { - return -1; - } return dmalen; } @@ -380,12 +373,18 @@ static void handle_satn(ESPState *s) return; } esp_set_pdma_cb(s, SATN_PDMA_CB); + if (esp_select(s) < 0) { + return; + } cmdlen = get_cmd(s, ESP_CMDFIFO_SZ); if (cmdlen > 0) { s->cmdfifo_cdb_offset = 1; s->do_cmd = 0; do_cmd(s); } else if (cmdlen == 0) { + if (s->dma) { + esp_raise_drq(s); + } s->do_cmd = 1; /* Target present, but no cmd yet - switch to command phase */ s->rregs[ESP_RSEQ] = SEQ_CD; @@ -411,12 +410,18 @@ static void handle_s_without_atn(ESPState *s) return; } esp_set_pdma_cb(s, S_WITHOUT_SATN_PDMA_CB); + if (esp_select(s) < 0) { + return; + } cmdlen = get_cmd(s, ESP_CMDFIFO_SZ); if (cmdlen > 0) { s->cmdfifo_cdb_offset = 0; s->do_cmd = 0; do_cmd(s); } else if (cmdlen == 0) { + if (s->dma) { + esp_raise_drq(s); + } s->do_cmd = 1; /* Target present, but no cmd yet - switch to command phase */ s->rregs[ESP_RSEQ] = SEQ_CD; @@ -446,6 +451,9 @@ static void handle_satn_stop(ESPState *s) return; } esp_set_pdma_cb(s, SATN_STOP_PDMA_CB); + if (esp_select(s) < 0) { + return; + } cmdlen = get_cmd(s, 1); if (cmdlen > 0) { trace_esp_handle_satn_stop(fifo8_num_used(&s->cmdfifo)); @@ -456,6 +464,9 @@ static void handle_satn_stop(ESPState *s) s->rregs[ESP_RSEQ] = SEQ_MO; esp_raise_irq(s); } else if (cmdlen == 0) { + if (s->dma) { + esp_raise_drq(s); + } s->do_cmd = 1; /* Target present, switch to message out phase */ s->rregs[ESP_RSEQ] = SEQ_MO;