Le 09/02/2021 à 20:30, Mark Cave-Ayland a écrit : > Currently the target selection for PDMA is done after the SCSI command has > been > delivered which is not correct. Perform target selection as part of the > initial > get_cmd() call when the command is submitted: if no target is present, don't > raise DRQ. > > If the target is present then switch to the command phase since the MacOS > toolbox > ROM checks for this before attempting to submit the SCSI command. > > Signed-off-by: Mark Cave-Ayland <mark.cave-ayl...@ilande.co.uk> > --- > hw/scsi/esp.c | 53 +++++++++++++++++++++++++++++++++------------------ > 1 file changed, 34 insertions(+), 19 deletions(-) > > diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c > index 6736e7142c..b7ab5a5592 100644 > --- a/hw/scsi/esp.c > +++ b/hw/scsi/esp.c > @@ -243,6 +243,9 @@ static uint32_t get_cmd(ESPState *s) > s->dma_memory_read(s->dma_opaque, buf, dmalen); > } else { > set_pdma(s, TI); > + if (esp_select(s) < 0) { > + return -1; > + } > esp_raise_drq(s); > return 0; > } > @@ -257,7 +260,7 @@ static uint32_t get_cmd(ESPState *s) > trace_esp_get_cmd(dmalen, target); > > if (esp_select(s) < 0) { > - return 0; > + return -1; > } > return dmalen; > } > @@ -299,9 +302,6 @@ static void do_cmd(ESPState *s) > > static void satn_pdma_cb(ESPState *s) > { > - if (esp_select(s) < 0) { > - return; > - } > s->do_cmd = 0; > if (s->cmdlen) { > do_cmd(s); > @@ -310,24 +310,28 @@ static void satn_pdma_cb(ESPState *s) > > static void handle_satn(ESPState *s) > { > + int32_t cmdlen; > + > if (s->dma && !s->dma_enabled) { > s->dma_cb = handle_satn; > return; > } > s->pdma_cb = satn_pdma_cb; > - s->cmdlen = get_cmd(s); > - if (s->cmdlen) { > + cmdlen = get_cmd(s); > + if (cmdlen > 0) { > + s->cmdlen = cmdlen; > do_cmd(s); > - } else { > + } else if (cmdlen == 0) { > + s->cmdlen = 0; > s->do_cmd = 1; > + /* Target present, but no cmd yet - switch to command phase */ > + s->rregs[ESP_RSEQ] = SEQ_CD; > + s->rregs[ESP_RSTAT] = STAT_CD; > } > } > > static void s_without_satn_pdma_cb(ESPState *s) > { > - if (esp_select(s) < 0) { > - return; > - } > s->do_cmd = 0; > if (s->cmdlen) { > do_busid_cmd(s, s->cmdbuf, 0); > @@ -336,24 +340,28 @@ static void s_without_satn_pdma_cb(ESPState *s) > > static void handle_s_without_atn(ESPState *s) > { > + int32_t cmdlen; > + > if (s->dma && !s->dma_enabled) { > s->dma_cb = handle_s_without_atn; > return; > } > s->pdma_cb = s_without_satn_pdma_cb; > - s->cmdlen = get_cmd(s); > - if (s->cmdlen) { > + cmdlen = get_cmd(s); > + if (cmdlen > 0) { > + s->cmdlen = cmdlen; > do_busid_cmd(s, s->cmdbuf, 0); > - } else { > + } else if (cmdlen == 0) { > + s->cmdlen = 0; > s->do_cmd = 1; > + /* Target present, but no cmd yet - switch to command phase */ > + s->rregs[ESP_RSEQ] = SEQ_CD; > + s->rregs[ESP_RSTAT] = STAT_CD; > } > } > > static void satn_stop_pdma_cb(ESPState *s) > { > - if (esp_select(s) < 0) { > - return; > - } > s->do_cmd = 0; > if (s->cmdlen) { > trace_esp_handle_satn_stop(s->cmdlen); > @@ -367,21 +375,28 @@ static void satn_stop_pdma_cb(ESPState *s) > > static void handle_satn_stop(ESPState *s) > { > + int32_t cmdlen; > + > if (s->dma && !s->dma_enabled) { > s->dma_cb = handle_satn_stop; > return; > } > s->pdma_cb = satn_stop_pdma_cb; > - s->cmdlen = get_cmd(s); > - if (s->cmdlen) { > + cmdlen = get_cmd(s); > + if (cmdlen > 0) { > trace_esp_handle_satn_stop(s->cmdlen); > + s->cmdlen = cmdlen; > s->do_cmd = 1; > s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; > s->rregs[ESP_RINTR] = INTR_BS | INTR_FC; > s->rregs[ESP_RSEQ] = SEQ_CD; > esp_raise_irq(s); > - } else { > + } else if (cmdlen == 0) { > + s->cmdlen = 0; > s->do_cmd = 1; > + /* Target present, but no cmd yet - switch to command phase */ > + s->rregs[ESP_RSEQ] = SEQ_CD; > + s->rregs[ESP_RSTAT] = STAT_CD; > } > } > >
Reviewed-by: Laurent Vivier <laur...@vivier.eu>