aboutsummaryrefslogtreecommitdiff
path: root/hw/scsi
diff options
context:
space:
mode:
authorMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2024-01-12 12:53:02 +0000
committerMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2024-02-13 19:37:20 +0000
commitf366622366807ce7e11cd74e501620840d8a3cda (patch)
treec07860d70109c71ec30d07bec9e269d4ce02424e /hw/scsi
parent0f2eb11071bfc2fe40e2007c1934a2afdde61953 (diff)
downloadqemu-f366622366807ce7e11cd74e501620840d8a3cda.zip
qemu-f366622366807ce7e11cd74e501620840d8a3cda.tar.gz
qemu-f366622366807ce7e11cd74e501620840d8a3cda.tar.bz2
esp.c: move buffer and TC logic into separate to/from device paths in esp_do_dma()
The ultimate aim is to for esp_do_dma() behaviour to be determined by the SCSI bus phase, in which case it is necessary to have separate to/from device paths. 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-11-mark.cave-ayland@ilande.co.uk> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Diffstat (limited to 'hw/scsi')
-rw-r--r--hw/scsi/esp.c65
1 files changed, 40 insertions, 25 deletions
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 63c828c..9893840 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -678,14 +678,53 @@ static void esp_do_dma(ESPState *s)
if (to_device) {
if (s->dma_memory_read) {
s->dma_memory_read(s->dma_opaque, s->async_buf, len);
+
+ esp_set_tc(s, esp_get_tc(s) - len);
+ s->async_buf += len;
+ s->async_len -= len;
+ s->ti_size += len;
+
+ if (s->async_len == 0) {
+ scsi_req_continue(s->current_req);
+ /*
+ * If there is still data to be read from the device then
+ * complete the DMA operation immediately. Otherwise defer
+ * until the scsi layer has completed.
+ */
+ return;
+ }
+
+ /* Partially filled a scsi buffer. Complete immediately. */
+ esp_dma_done(s);
+ esp_lower_drq(s);
} else {
esp_set_pdma_cb(s, DO_DMA_PDMA_CB);
esp_raise_drq(s);
- return;
}
} else {
if (s->dma_memory_write) {
s->dma_memory_write(s->dma_opaque, s->async_buf, len);
+
+ esp_set_tc(s, esp_get_tc(s) - len);
+ s->async_buf += len;
+ s->async_len -= len;
+ s->ti_size -= len;
+
+ if (s->async_len == 0) {
+ scsi_req_continue(s->current_req);
+ /*
+ * If there is still data to be read from the device then
+ * complete the DMA operation immediately. Otherwise defer
+ * until the scsi layer has completed.
+ */
+ if (esp_get_tc(s) != 0 || s->ti_size == 0) {
+ return;
+ }
+ }
+
+ /* Partially filled a scsi buffer. Complete immediately. */
+ esp_dma_done(s);
+ esp_lower_drq(s);
} else {
/* Adjust TC for any leftover data in the FIFO */
if (!fifo8_is_empty(&s->fifo)) {
@@ -713,32 +752,8 @@ static void esp_do_dma(ESPState *s)
esp_set_tc(s, esp_get_tc(s) - len);
esp_set_pdma_cb(s, DO_DMA_PDMA_CB);
esp_raise_drq(s);
- return;
}
}
- esp_set_tc(s, esp_get_tc(s) - len);
- s->async_buf += len;
- s->async_len -= len;
- if (to_device) {
- s->ti_size += len;
- } else {
- s->ti_size -= len;
- }
- if (s->async_len == 0) {
- scsi_req_continue(s->current_req);
- /*
- * If there is still data to be read from the device then
- * complete the DMA operation immediately. Otherwise defer
- * until the scsi layer has completed.
- */
- if (to_device || esp_get_tc(s) != 0 || s->ti_size == 0) {
- return;
- }
- }
-
- /* Partially filled a scsi buffer. Complete immediately. */
- esp_dma_done(s);
- esp_lower_drq(s);
}
static void esp_do_nodma(ESPState *s)