Skip to content
Snippets Groups Projects
Commit 49691315 authored by Mark Cave-Ayland's avatar Mark Cave-Ayland
Browse files

esp: fix PDMA target selection


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: default avatarMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: default avatarLaurent Vivier <laurent@vivier.eu>
Message-Id: <20210304221103.6369-28-mark.cave-ayland@ilande.co.uk>
parent c7bce09c
No related branches found
No related tags found
No related merge requests found
......@@ -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;
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment