esp.c: separate logic based upon ESP command in esp_command_complete()

The handling of the INTR_FC and INTR_BS bits is different depending upon the
last command executed by the ESP. Note that currently INTR_FC is managed
elsewhere, but that will change soon.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Tested-by: Helge Deller <deller@gmx.de>
Tested-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20240112125420.514425-59-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
This commit is contained in:
Mark Cave-Ayland 2024-01-12 12:53:50 +00:00
parent 8dded6de15
commit 8bb2249585

View File

@ -823,25 +823,27 @@ void esp_command_complete(SCSIRequest *req, size_t resid)
* Switch to status phase. For non-DMA transfers from the target the last * Switch to status phase. For non-DMA transfers from the target the last
* byte is still in the FIFO * byte is still in the FIFO
*/ */
esp_set_phase(s, STAT_ST); s->ti_size = 0;
if (s->ti_size == 0) {
switch (s->rregs[ESP_CMD]) {
case CMD_SEL | CMD_DMA:
case CMD_SEL:
case CMD_SELATN | CMD_DMA:
case CMD_SELATN:
/* /*
* Transfer complete: force TC to zero just in case a TI command was * No data phase for sequencer command so raise deferred bus service
* requested for more data than the command returns (Solaris 8 does * interrupt
* this)
*/
esp_set_tc(s, 0);
esp_dma_ti_check(s);
} else {
/*
* Transfer truncated: raise INTR_BS to indicate early change of
* phase
*/ */
s->rregs[ESP_RINTR] |= INTR_BS; s->rregs[ESP_RINTR] |= INTR_BS;
esp_raise_irq(s); break;
s->ti_size = 0;
} }
/* Raise bus service interrupt to indicate change to STATUS phase */
esp_set_phase(s, STAT_ST);
s->rregs[ESP_RINTR] |= INTR_BS;
esp_raise_irq(s);
esp_lower_drq(s);
if (s->current_req) { if (s->current_req) {
scsi_req_unref(s->current_req); scsi_req_unref(s->current_req);
s->current_req = NULL; s->current_req = NULL;