qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/25] esp: consolidate PDMA transfer buffers
@ 2020-12-30 15:37 Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 01/25] esp: checkpatch fixes Mark Cave-Ayland
                   ` (26 more replies)
  0 siblings, 27 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

This patch series comes from an experimental branch that I've been working on
to try and boot a MacOS toolbox ROM under the QEMU q800 machine. The effort is
far from complete, but it seems worth submitting these patches separately since
they are limited to the ESP device and form a substantial part of the work to
date.

As part of Laurent's recent q800 work so-called PDMA (pseudo-DMA) support was
added to the ESP device. This is whereby the DREQ (DMA request) line is used
to signal to the host CPU that it can transfer data to/from the device over
the SCSI bus.

The existing PDMA tracks 4 separate transfer data sources as indicated by the
ESP pdma_origin variable: PDMA, TI, CMD and ASYNC with an independent variable
pdma_len to store the transfer length. This works well with Linux which uses a
single PDMA request to transfer a number of sectors in a single request.

Unfortunately the MacOS toolbox ROM has other ideas here: it sends data to the
ESP as a mixture of FIFO and PDMA transfers and then uses a mixture of the FIFO
and DMA counters to confirm that the correct number of bytes have been
transferred. For this to work correctly the PDMA buffers and separate pdma_len
transfer counter must be consolidated into the FIFO to allow mixing of both
types of transfer within a single request.

The patchset is split into several sections:

- Patches 1-4 are minor patches which make esp.c checkpatch friendly whilst also
  fixing up some trace events ready for later patches in the series
  
- Patches 5-11 unify the DMA transfer count. In particular there are 2 synthetic
  variables dma_counter and dma_left within ESPState which do not need to exist. 
  DMA transfer lengths are programmed into the TC (transfer count) register which is 
  decremented for each byte transferred, generating an interrupt when it reaches zero.
  These patches add helper functions to read the TC and STC registers directly and
  remove these synthetic variables so that the DMA transfer length is now tracked in
  a single place.

- Now that the TC register represents the authoritative DMA transfer length, patches
  12-20 work to eliminate the separate PDMA variables pdma_start, pdma_cur, pdma_len
  and separate PDMA buffers PDMA and CMD. The PDMA position variables can be replaced
  by the existing ESP cmdlen and ti_wptr/ti_rptr, whilst the FIFO (TI) buffer is used
  for incoming data with commands being accumulated in cmdbuf as per standard DMA
  requests.

- Patches 21 and 22 fix the detection of missing SCSI targets by the MacOS toolbox ROM
  on startup at which point it will attempt to start reading information from a CDROM
  attached to the q800 machine.

- Patch 23 is the main rework of the PDMA buffer transfers: instead of tracking the
  SCSI transfers using a separate ASYNC pdma_origin, the contents of the ESPState
  async_buf are copied to the FIFO buffer in 16-byte chunks with the transfer status
  and IRQs being set accordingly.

- Patch 24 removes the last separate PDMA variable pdma_origin, including the separate
  PDMA migration subsection which is no longer required (see note below about migration
  compatibility).
  
- Finally patch 25 enables 4 byte PDMA reads/writes over the SCSI bus which are used
  by MacOS when reading the next stage bootloader from CDROM (this is an increase from
  2 bytes currently implemented and used by Linux).


Testing
=======

I've tested this on my SPARC32 OpenBIOS images which include Linux, OpenBSD, NetBSD,
and Solaris and all of these continue to boot as before.

Similarly the q800 m68k Linux test image still boots as before with these patches
applied. It is possible with lots of hacks to load Laurent's EMILE bootloader using
a MacOS toolbox ROM - the hope is to try and start upstreaming more of these changes
as time allows.


Migration
=========

The patchset ensures that ESP devices without PDMA (i.e. everything except the q800
machine) will migrate successfully. This is fairly simple: the only change required
here is to copy the old synthetic dma_left value over into the TC.

Unfortunately migrating the PDMA subsection is a lot harder due to the change in the
way that the DMA TC and changes to the point at which transfer counters are updated.
For this reason the patchset will not migrate from older q800 snapshots: I don't
believe this to be a problem since some devices are still missing VMStateDescription
plus there are likely to be more breaking changes as the q800 machine matures.


Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>


Mark Cave-Ayland (25):
  esp: checkpatch fixes
  esp: add trace event when receiving a TI command
  esp: fix esp_reg_read() trace event
  esp: add PDMA trace events
  esp: determine transfer direction directly from SCSI phase
  esp: introduce esp_get_tc() and esp_set_tc()
  esp: introduce esp_get_stc()
  esp: apply transfer length adjustment when STC is zero at TC load time
  esp: remove dma_counter from ESPState
  esp: remove dma_left from ESPState
  esp: remove minlen restriction in handle_ti
  esp: introduce esp_pdma_read() and esp_pdma_write() functions
  esp: use pdma_origin directly in esp_pdma_read()/esp_pdma_write()
  esp: move pdma_len and TC logic into esp_pdma_read()/esp_pdma_write()
  esp: accumulate SCSI commands for PDMA transfers in cmdbuf instead of
    pdma_buf
  esp: remove redundant pdma_start from ESPState
  esp: move PDMA length adjustments into
    esp_pdma_read()/esp_pdma_write()
  esp: use ti_wptr/ti_rptr to manage the current FIFO position for PDMA
  esp: use in-built TC to determine PDMA transfer length
  esp: remove CMD pdma_origin
  esp: rename get_cmd_cb() to esp_select()
  esp: fix PDMA target selection
  esp: use FIFO for PDMA transfers between initiator and device
  esp: remove pdma_origin from ESPState
  esp: add 4 byte PDMA read and write transfers

 hw/scsi/esp.c         | 461 +++++++++++++++++++++++++-----------------
 hw/scsi/trace-events  |   5 +
 include/hw/scsi/esp.h |  20 +-
 3 files changed, 279 insertions(+), 207 deletions(-)

-- 
2.20.1



^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 01/25] esp: checkpatch fixes
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2021-01-01 16:53   ` Philippe Mathieu-Daudé
  2020-12-30 15:37 ` [PATCH 02/25] esp: add trace event when receiving a TI command Mark Cave-Ayland
                   ` (25 subsequent siblings)
  26 siblings, 1 reply; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 52 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 31 insertions(+), 21 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index b84e0fe33e..7073166ad1 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -241,8 +241,9 @@ static void handle_satn(ESPState *s)
     }
     s->pdma_cb = satn_pdma_cb;
     len = get_cmd(s, buf, sizeof(buf));
-    if (len)
+    if (len) {
         do_cmd(s, buf);
+    }
 }
 
 static void s_without_satn_pdma_cb(ESPState *s)
@@ -398,8 +399,8 @@ static void esp_do_dma(ESPState *s)
          * handle_ti_cmd() with do_cmd != NULL (see the assert())
          */
         trace_esp_do_dma(s->cmdlen, len);
-        assert (s->cmdlen <= sizeof(s->cmdbuf) &&
-                len <= sizeof(s->cmdbuf) - s->cmdlen);
+        assert(s->cmdlen <= sizeof(s->cmdbuf) &&
+               len <= sizeof(s->cmdbuf) - s->cmdlen);
         if (s->dma_memory_read) {
             s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
         } else {
@@ -445,15 +446,18 @@ static void esp_do_dma(ESPState *s)
     s->dma_left -= len;
     s->async_buf += len;
     s->async_len -= len;
-    if (to_device)
+    if (to_device) {
         s->ti_size += len;
-    else
+    } 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 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 || s->dma_left != 0 || s->ti_size == 0) {
             return;
         }
@@ -491,7 +495,8 @@ void esp_command_complete(SCSIRequest *req, uint32_t status,
     ESPState *s = req->hba_private;
 
     if (s->rregs[ESP_RSTAT] & STAT_INT) {
-        /* Defer handling command complete until the previous
+        /*
+         * Defer handling command complete until the previous
          * interrupt has been handled.
          */
         trace_esp_command_complete_deferred();
@@ -513,8 +518,10 @@ void esp_transfer_data(SCSIRequest *req, uint32_t len)
     if (s->dma_left) {
         esp_do_dma(s);
     } else if (s->dma_counter != 0 && s->ti_size <= 0) {
-        /* If this was the last part of a DMA transfer then the
-           completion interrupt is deferred to here.  */
+        /*
+         * If this was the last part of a DMA transfer then the
+         * completion interrupt is deferred to here.
+         */
         esp_dma_done(s);
     }
 }
@@ -531,17 +538,18 @@ static void handle_ti(ESPState *s)
     dmalen = s->rregs[ESP_TCLO];
     dmalen |= s->rregs[ESP_TCMID] << 8;
     dmalen |= s->rregs[ESP_TCHI] << 16;
-    if (dmalen==0) {
-      dmalen=0x10000;
+    if (dmalen == 0) {
+        dmalen = 0x10000;
     }
     s->dma_counter = dmalen;
 
-    if (s->do_cmd)
+    if (s->do_cmd) {
         minlen = (dmalen < ESP_CMDBUF_SZ) ? dmalen : ESP_CMDBUF_SZ;
-    else if (s->ti_size < 0)
+    } else if (s->ti_size < 0) {
         minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
-    else
+    } else {
         minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
+    }
     trace_esp_handle_ti(minlen);
     if (s->dma) {
         s->dma_left = minlen;
@@ -606,8 +614,10 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
         }
         break;
     case ESP_RINTR:
-        /* Clear sequence step, interrupt register and all status bits
-           except TC */
+        /*
+         * Clear sequence step, interrupt register and all status bits
+         * except TC
+         */
         old_val = s->rregs[ESP_RINTR];
         s->rregs[ESP_RINTR] = 0;
         s->rregs[ESP_RSTAT] &= ~STAT_TC;
@@ -665,13 +675,13 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
         } else {
             s->dma = 0;
         }
-        switch(val & CMD_CMD) {
+        switch (val & CMD_CMD) {
         case CMD_NOP:
             trace_esp_mem_writeb_cmd_nop(val);
             break;
         case CMD_FLUSH:
             trace_esp_mem_writeb_cmd_flush(val);
-            //s->ti_size = 0;
+            /*s->ti_size = 0;*/
             s->rregs[ESP_RINTR] = INTR_FC;
             s->rregs[ESP_RSEQ] = 0;
             s->rregs[ESP_RFLAGS] = 0;
@@ -787,7 +797,7 @@ static const VMStateDescription vmstate_esp_pdma = {
 };
 
 const VMStateDescription vmstate_esp = {
-    .name ="esp",
+    .name = "esp",
     .version_id = 4,
     .minimum_version_id = 3,
     .fields = (VMStateField[]) {
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 02/25] esp: add trace event when receiving a TI command
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 01/25] esp: checkpatch fixes Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2021-01-01 16:54   ` Philippe Mathieu-Daudé
  2020-12-30 15:37 ` [PATCH 03/25] esp: fix esp_reg_read() trace event Mark Cave-Ayland
                   ` (24 subsequent siblings)
  26 siblings, 1 reply; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

This enables us to determine whether the command being issued is for a DMA or a
non-DMA transfer.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c        | 1 +
 hw/scsi/trace-events | 1 +
 2 files changed, 2 insertions(+)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 7073166ad1..5f2c352029 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -698,6 +698,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
             }
             break;
         case CMD_TI:
+            trace_esp_mem_writeb_cmd_ti(val);
             handle_ti(s);
             break;
         case CMD_ICCS:
diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
index 9a4a60ca63..261eecf0cf 100644
--- a/hw/scsi/trace-events
+++ b/hw/scsi/trace-events
@@ -189,6 +189,7 @@ esp_mem_writeb_cmd_selatn(uint32_t val) "Select with ATN (0x%2.2x)"
 esp_mem_writeb_cmd_selatns(uint32_t val) "Select with ATN & stop (0x%2.2x)"
 esp_mem_writeb_cmd_ensel(uint32_t val) "Enable selection (0x%2.2x)"
 esp_mem_writeb_cmd_dissel(uint32_t val) "Disable selection (0x%2.2x)"
+esp_mem_writeb_cmd_ti(uint32_t val) "Transfer Information (0x%2.2x)"
 
 # esp-pci.c
 esp_pci_error_invalid_dma_direction(void) "invalid DMA transfer direction"
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 03/25] esp: fix esp_reg_read() trace event
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 01/25] esp: checkpatch fixes Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 02/25] esp: add trace event when receiving a TI command Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2021-01-01 16:54   ` Philippe Mathieu-Daudé
  2020-12-30 15:37 ` [PATCH 04/25] esp: add PDMA trace events Mark Cave-Ayland
                   ` (23 subsequent siblings)
  26 siblings, 1 reply; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

Move the trace event to the end of the function so that it correctly reports
the returned value if it doesn't come directly from the rregs array.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 5f2c352029..df15e3e7cf 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -595,9 +595,8 @@ static void parent_esp_reset(ESPState *s, int irq, int level)
 
 uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
 {
-    uint32_t old_val;
+    uint32_t val;
 
-    trace_esp_mem_readb(saddr, s->rregs[saddr]);
     switch (saddr) {
     case ESP_FIFO:
         if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
@@ -612,13 +611,14 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
             s->ti_rptr = 0;
             s->ti_wptr = 0;
         }
+        val = s->rregs[ESP_FIFO];
         break;
     case ESP_RINTR:
         /*
          * Clear sequence step, interrupt register and all status bits
          * except TC
          */
-        old_val = s->rregs[ESP_RINTR];
+        val = s->rregs[ESP_RINTR];
         s->rregs[ESP_RINTR] = 0;
         s->rregs[ESP_RSTAT] &= ~STAT_TC;
         s->rregs[ESP_RSEQ] = SEQ_CD;
@@ -627,16 +627,22 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
             esp_report_command_complete(s, s->deferred_status);
             s->deferred_complete = false;
         }
-        return old_val;
+        break;
     case ESP_TCHI:
         /* Return the unique id if the value has never been written */
         if (!s->tchi_written) {
-            return s->chip_id;
+            val = s->chip_id;
+        } else {
+            val = s->rregs[saddr];
         }
+        break;
     default:
+        val = s->rregs[saddr];
         break;
     }
-    return s->rregs[saddr];
+
+    trace_esp_mem_readb(saddr, val);
+    return val;
 }
 
 void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 04/25] esp: add PDMA trace events
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (2 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 03/25] esp: fix esp_reg_read() trace event Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2021-01-01 16:55   ` Philippe Mathieu-Daudé
  2020-12-30 15:37 ` [PATCH 05/25] esp: determine transfer direction directly from SCSI phase Mark Cave-Ayland
                   ` (22 subsequent siblings)
  26 siblings, 1 reply; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

This will become more useful later when trying to debug mixed FIFO and PDMA
requests.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c        | 6 ++++++
 hw/scsi/trace-events | 4 ++++
 2 files changed, 10 insertions(+)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index df15e3e7cf..619c3e9e28 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -63,11 +63,13 @@ static void esp_lower_irq(ESPState *s)
 static void esp_raise_drq(ESPState *s)
 {
     qemu_irq_raise(s->irq_data);
+    trace_esp_raise_drq();
 }
 
 static void esp_lower_drq(ESPState *s)
 {
     qemu_irq_lower(s->irq_data);
+    trace_esp_lower_drq();
 }
 
 void esp_dma_enable(ESPState *s, int irq, int level)
@@ -866,6 +868,8 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
     uint32_t dmalen;
     uint8_t *buf = get_pdma_buf(s);
 
+    trace_esp_pdma_write(size);
+
     dmalen = s->rregs[ESP_TCLO];
     dmalen |= s->rregs[ESP_TCMID] << 8;
     dmalen |= s->rregs[ESP_TCHI] << 16;
@@ -903,6 +907,8 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr,
     uint8_t *buf = get_pdma_buf(s);
     uint64_t val = 0;
 
+    trace_esp_pdma_read(size);
+
     if (s->pdma_len == 0) {
         return 0;
     }
diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
index 261eecf0cf..ed387dc7fd 100644
--- a/hw/scsi/trace-events
+++ b/hw/scsi/trace-events
@@ -159,8 +159,12 @@ esp_error_unhandled_command(uint32_t val) "unhandled command (0x%2.2x)"
 esp_error_invalid_write(uint32_t val, uint32_t addr) "invalid write of 0x%02x at [0x%x]"
 esp_raise_irq(void) "Raise IRQ"
 esp_lower_irq(void) "Lower IRQ"
+esp_raise_drq(void) "Raise DREQ"
+esp_lower_drq(void) "Lower DREQ"
 esp_dma_enable(void) "Raise enable"
 esp_dma_disable(void) "Lower enable"
+esp_pdma_read(int size) "pDMA read %u bytes"
+esp_pdma_write(int size) "pDMA write %u bytes"
 esp_get_cmd(uint32_t dmalen, int target) "len %d target %d"
 esp_do_busid_cmd(uint8_t busid) "busid 0x%x"
 esp_handle_satn_stop(uint32_t cmdlen) "cmdlen %d"
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 05/25] esp: determine transfer direction directly from SCSI phase
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (3 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 04/25] esp: add PDMA trace events Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 06/25] esp: introduce esp_get_tc() and esp_set_tc() Mark Cave-Ayland
                   ` (21 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

The transfer direction is currently determined by checking the sign of ti_size
but as this series progresses ti_size can be zero at the end of the transfer.

Use the SCSI phase to determine the transfer direction as used in other SCSI
controller implementations.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 619c3e9e28..7169294437 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -356,7 +356,7 @@ static void esp_dma_done(ESPState *s)
 
 static void do_dma_pdma_cb(ESPState *s)
 {
-    int to_device = (s->ti_size < 0);
+    int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
     int len = s->pdma_cur - s->pdma_start;
     if (s->do_cmd) {
         s->ti_size = 0;
@@ -392,7 +392,7 @@ static void do_dma_pdma_cb(ESPState *s)
 static void esp_do_dma(ESPState *s)
 {
     uint32_t len;
-    int to_device;
+    int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
 
     len = s->dma_left;
     if (s->do_cmd) {
@@ -425,7 +425,6 @@ static void esp_do_dma(ESPState *s)
     if (len > s->async_len) {
         len = s->async_len;
     }
-    to_device = (s->ti_size < 0);
     if (to_device) {
         if (s->dma_memory_read) {
             s->dma_memory_read(s->dma_opaque, s->async_buf, len);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 06/25] esp: introduce esp_get_tc() and esp_set_tc()
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (4 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 05/25] esp: determine transfer direction directly from SCSI phase Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2021-01-01 16:56   ` Philippe Mathieu-Daudé
  2020-12-30 15:37 ` [PATCH 07/25] esp: introduce esp_get_stc() Mark Cave-Ayland
                   ` (20 subsequent siblings)
  26 siblings, 1 reply; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

This simplifies reading and writing the TC register value without having to
manually shift each individual 8-bit value.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 34 ++++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 7169294437..42cbc1da9b 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -98,6 +98,24 @@ void esp_request_cancelled(SCSIRequest *req)
     }
 }
 
+static uint32_t esp_get_tc(ESPState *s)
+{
+    uint32_t dmalen;
+
+    dmalen = s->rregs[ESP_TCLO];
+    dmalen |= s->rregs[ESP_TCMID] << 8;
+    dmalen |= s->rregs[ESP_TCHI] << 16;
+
+    return dmalen;
+}
+
+static void esp_set_tc(ESPState *s, uint32_t dmalen)
+{
+    s->rregs[ESP_TCLO] = dmalen & 0xff;
+    s->rregs[ESP_TCMID] = dmalen >> 8;
+    s->rregs[ESP_TCHI] = dmalen >> 16;
+}
+
 static void set_pdma(ESPState *s, enum pdma_origin_id origin,
                      uint32_t index, uint32_t len)
 {
@@ -157,9 +175,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
 
     target = s->wregs[ESP_WBUSID] & BUSID_DID;
     if (s->dma) {
-        dmalen = s->rregs[ESP_TCLO];
-        dmalen |= s->rregs[ESP_TCMID] << 8;
-        dmalen |= s->rregs[ESP_TCHI] << 16;
+        dmalen = esp_get_tc(s);
         if (dmalen > buflen) {
             return 0;
         }
@@ -536,9 +552,7 @@ static void handle_ti(ESPState *s)
         return;
     }
 
-    dmalen = s->rregs[ESP_TCLO];
-    dmalen |= s->rregs[ESP_TCMID] << 8;
-    dmalen |= s->rregs[ESP_TCHI] << 16;
+    dmalen = esp_get_tc(s);
     if (dmalen == 0) {
         dmalen = 0x10000;
     }
@@ -869,9 +883,7 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
 
     trace_esp_pdma_write(size);
 
-    dmalen = s->rregs[ESP_TCLO];
-    dmalen |= s->rregs[ESP_TCMID] << 8;
-    dmalen |= s->rregs[ESP_TCHI] << 16;
+    dmalen = esp_get_tc(s);
     if (dmalen == 0 || s->pdma_len == 0) {
         return;
     }
@@ -888,9 +900,7 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
         dmalen -= 2;
         break;
     }
-    s->rregs[ESP_TCLO] = dmalen & 0xff;
-    s->rregs[ESP_TCMID] = dmalen >> 8;
-    s->rregs[ESP_TCHI] = dmalen >> 16;
+    esp_set_tc(s, dmalen);
     if (s->pdma_len == 0 && s->pdma_cb) {
         esp_lower_drq(s);
         s->pdma_cb(s);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 07/25] esp: introduce esp_get_stc()
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (5 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 06/25] esp: introduce esp_get_tc() and esp_set_tc() Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 08/25] esp: apply transfer length adjustment when STC is zero at TC load time Mark Cave-Ayland
                   ` (19 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

This simplifies reading the STC register value without having to manually shift
each individual 8-bit value.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 42cbc1da9b..c716a97847 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -116,6 +116,17 @@ static void esp_set_tc(ESPState *s, uint32_t dmalen)
     s->rregs[ESP_TCHI] = dmalen >> 16;
 }
 
+static uint32_t esp_get_stc(ESPState *s)
+{
+    uint32_t dmalen;
+
+    dmalen = s->wregs[ESP_TCLO];
+    dmalen |= s->wregs[ESP_TCMID] << 8;
+    dmalen |= s->wregs[ESP_TCHI] << 16;
+
+    return dmalen;
+}
+
 static void set_pdma(ESPState *s, enum pdma_origin_id origin,
                      uint32_t index, uint32_t len)
 {
@@ -690,9 +701,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
         if (val & CMD_DMA) {
             s->dma = 1;
             /* Reload DMA counter.  */
-            s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
-            s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
-            s->rregs[ESP_TCHI] = s->wregs[ESP_TCHI];
+            esp_set_tc(s, esp_get_stc(s));
         } else {
             s->dma = 0;
         }
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 08/25] esp: apply transfer length adjustment when STC is zero at TC load time
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (6 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 07/25] esp: introduce esp_get_stc() Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 09/25] esp: remove dma_counter from ESPState Mark Cave-Ayland
                   ` (18 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

Perform the length adjustment whereby a value of 0 in the STC represents
a transfer length of 0x10000 at the point where the TC is loaded at the
start of a DMA command rather than just when a TI (Transfer Information)
command is executed. This better matches the description as given in the
datasheet.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index c716a97847..f38b4a2ecd 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -564,9 +564,6 @@ static void handle_ti(ESPState *s)
     }
 
     dmalen = esp_get_tc(s);
-    if (dmalen == 0) {
-        dmalen = 0x10000;
-    }
     s->dma_counter = dmalen;
 
     if (s->do_cmd) {
@@ -701,7 +698,11 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
         if (val & CMD_DMA) {
             s->dma = 1;
             /* Reload DMA counter.  */
-            esp_set_tc(s, esp_get_stc(s));
+            if (esp_get_stc(s) == 0) {
+                esp_set_tc(s, 0x10000);
+            } else {
+                esp_set_tc(s, esp_get_stc(s));
+            }
         } else {
             s->dma = 0;
         }
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 09/25] esp: remove dma_counter from ESPState
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (7 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 08/25] esp: apply transfer length adjustment when STC is zero at TC load time Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 10/25] esp: remove dma_left " Mark Cave-Ayland
                   ` (17 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

The value of dma_counter is set once at the start of the transfer and remains
the same until the transfer is complete. This allows the check in esp_transfer_data
to be simplified since dma_left will always be non-zero until the transfer is
completed.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c         | 5 ++---
 include/hw/scsi/esp.h | 3 ---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index f38b4a2ecd..5b47d035ab 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -229,7 +229,6 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
     if (datalen != 0) {
         s->rregs[ESP_RSTAT] = STAT_TC;
         s->dma_left = 0;
-        s->dma_counter = 0;
         if (datalen > 0) {
             s->rregs[ESP_RSTAT] |= STAT_DI;
         } else {
@@ -538,6 +537,7 @@ void esp_command_complete(SCSIRequest *req, uint32_t status,
 void esp_transfer_data(SCSIRequest *req, uint32_t len)
 {
     ESPState *s = req->hba_private;
+    int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
 
     assert(!s->do_cmd);
     trace_esp_transfer_data(s->dma_left, s->ti_size);
@@ -545,7 +545,7 @@ void esp_transfer_data(SCSIRequest *req, uint32_t len)
     s->async_buf = scsi_req_get_buf(req);
     if (s->dma_left) {
         esp_do_dma(s);
-    } else if (s->dma_counter != 0 && s->ti_size <= 0) {
+    } else if (to_device) {
         /*
          * If this was the last part of a DMA transfer then the
          * completion interrupt is deferred to here.
@@ -564,7 +564,6 @@ static void handle_ti(ESPState *s)
     }
 
     dmalen = esp_get_tc(s);
-    s->dma_counter = dmalen;
 
     if (s->do_cmd) {
         minlen = (dmalen < ESP_CMDBUF_SZ) ? dmalen : ESP_CMDBUF_SZ;
diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
index 60cc3047a5..b307f5d261 100644
--- a/include/hw/scsi/esp.h
+++ b/include/hw/scsi/esp.h
@@ -45,9 +45,6 @@ struct ESPState {
 
     /* The amount of data left in the current DMA transfer.  */
     uint32_t dma_left;
-    /* The size of the current DMA transfer.  Zero if no transfer is in
-       progress.  */
-    uint32_t dma_counter;
     int dma_enabled;
 
     uint32_t async_len;
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 10/25] esp: remove dma_left from ESPState
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (8 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 09/25] esp: remove dma_counter from ESPState Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 11/25] esp: remove minlen restriction in handle_ti Mark Cave-Ayland
                   ` (16 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

The ESP device already keeps track of the remaining bytes left to transfer via
its TC (transfer counter) register which is decremented for each byte that
is transferred across the SCSI bus.

Switch the transfer logic to use the value of TC instead of dma_left and then
remove dma_left completely.

In order to preserve migration bump the version of vmstate_sysbus_esp_scsi to
2 and add a post_load function to transfer the old dma_left value to the TC
register.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c         | 47 +++++++++++++++++++++++++++----------------
 include/hw/scsi/esp.h |  5 +++--
 2 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 5b47d035ab..69fed3cb22 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -228,7 +228,7 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
     s->ti_size = datalen;
     if (datalen != 0) {
         s->rregs[ESP_RSTAT] = STAT_TC;
-        s->dma_left = 0;
+        esp_set_tc(s, 0);
         if (datalen > 0) {
             s->rregs[ESP_RSTAT] |= STAT_DI;
         } else {
@@ -384,6 +384,7 @@ static void do_dma_pdma_cb(ESPState *s)
 {
     int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
     int len = s->pdma_cur - s->pdma_start;
+
     if (s->do_cmd) {
         s->ti_size = 0;
         s->cmdlen = 0;
@@ -391,7 +392,6 @@ static void do_dma_pdma_cb(ESPState *s)
         do_cmd(s, s->cmdbuf);
         return;
     }
-    s->dma_left -= len;
     s->async_buf += len;
     s->async_len -= len;
     if (to_device) {
@@ -406,7 +406,7 @@ static void do_dma_pdma_cb(ESPState *s)
          * complete the DMA operation immediately.  Otherwise defer
          * until the scsi layer has completed.
          */
-        if (to_device || s->dma_left != 0 || s->ti_size == 0) {
+        if (to_device || esp_get_tc(s) != 0 || s->ti_size == 0) {
             return;
         }
     }
@@ -420,7 +420,7 @@ static void esp_do_dma(ESPState *s)
     uint32_t len;
     int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
 
-    len = s->dma_left;
+    len = esp_get_tc(s);
     if (s->do_cmd) {
         /*
          * handle_ti_cmd() case: esp_do_dma() is called only from
@@ -470,7 +470,7 @@ static void esp_do_dma(ESPState *s)
             return;
         }
     }
-    s->dma_left -= len;
+    esp_set_tc(s, esp_get_tc(s) - len);
     s->async_buf += len;
     s->async_len -= len;
     if (to_device) {
@@ -485,7 +485,7 @@ static void esp_do_dma(ESPState *s)
          * complete the DMA operation immediately.  Otherwise defer
          * until the scsi layer has completed.
          */
-        if (to_device || s->dma_left != 0 || s->ti_size == 0) {
+        if (to_device || esp_get_tc(s) != 0 || s->ti_size == 0) {
             return;
         }
     }
@@ -501,7 +501,6 @@ static void esp_report_command_complete(ESPState *s, uint32_t status)
         trace_esp_command_complete_unexpected();
     }
     s->ti_size = 0;
-    s->dma_left = 0;
     s->async_len = 0;
     if (status) {
         trace_esp_command_complete_fail();
@@ -538,12 +537,13 @@ void esp_transfer_data(SCSIRequest *req, uint32_t len)
 {
     ESPState *s = req->hba_private;
     int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
+    uint32_t dmalen = esp_get_tc(s);
 
     assert(!s->do_cmd);
-    trace_esp_transfer_data(s->dma_left, s->ti_size);
+    trace_esp_transfer_data(dmalen, s->ti_size);
     s->async_len = len;
     s->async_buf = scsi_req_get_buf(req);
-    if (s->dma_left) {
+    if (dmalen) {
         esp_do_dma(s);
     } else if (to_device) {
         /*
@@ -574,7 +574,6 @@ static void handle_ti(ESPState *s)
     }
     trace_esp_handle_ti(minlen);
     if (s->dma) {
-        s->dma_left = minlen;
         s->rregs[ESP_RSTAT] &= ~STAT_TC;
         esp_do_dma(s);
     } else if (s->do_cmd) {
@@ -846,7 +845,7 @@ const VMStateDescription vmstate_esp = {
         VMSTATE_BUFFER_START_MIDDLE_V(cmdbuf, ESPState, 16, 4),
         VMSTATE_UINT32(cmdlen, ESPState),
         VMSTATE_UINT32(do_cmd, ESPState),
-        VMSTATE_UINT32(dma_left, ESPState),
+        VMSTATE_UINT32(mig_dma_left, ESPState),
         VMSTATE_END_OF_LIST()
     },
     .subsections = (const VMStateDescription * []) {
@@ -887,12 +886,11 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
 {
     SysBusESPState *sysbus = opaque;
     ESPState *s = &sysbus->esp;
-    uint32_t dmalen;
+    uint32_t dmalen = esp_get_tc(s);
     uint8_t *buf = get_pdma_buf(s);
 
     trace_esp_pdma_write(size);
 
-    dmalen = esp_get_tc(s);
     if (dmalen == 0 || s->pdma_len == 0) {
         return;
     }
@@ -922,27 +920,30 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr,
 {
     SysBusESPState *sysbus = opaque;
     ESPState *s = &sysbus->esp;
+    uint32_t dmalen = esp_get_tc(s);
     uint8_t *buf = get_pdma_buf(s);
     uint64_t val = 0;
 
     trace_esp_pdma_read(size);
 
-    if (s->pdma_len == 0) {
+    if (dmalen == 0 || s->pdma_len == 0) {
         return 0;
     }
     switch (size) {
     case 1:
         val = buf[s->pdma_cur++];
         s->pdma_len--;
+        dmalen--;
         break;
     case 2:
         val = buf[s->pdma_cur++];
         val = (val << 8) | buf[s->pdma_cur++];
         s->pdma_len -= 2;
+        dmalen -= 2;
         break;
     }
-
-    if (s->pdma_len == 0 && s->pdma_cb) {
+    esp_set_tc(s, dmalen);
+    if (dmalen == 0 || (s->pdma_len == 0 && s->pdma_cb)) {
         esp_lower_drq(s);
         s->pdma_cb(s);
         s->pdma_cb = NULL;
@@ -1012,10 +1013,22 @@ static void sysbus_esp_hard_reset(DeviceState *dev)
     esp_hard_reset(&sysbus->esp);
 }
 
+static int sysbus_esp_scsi_post_load(void *opaque, int version_id)
+{
+    ESPState *s = opaque;
+
+    if (version_id < 2) {
+        esp_set_tc(s, s->mig_dma_left);
+    }
+
+    return 1;
+}
+
 static const VMStateDescription vmstate_sysbus_esp_scsi = {
     .name = "sysbusespscsi",
-    .version_id = 1,
+    .version_id = 2,
     .minimum_version_id = 1,
+    .post_load = sysbus_esp_scsi_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_STRUCT(esp, SysBusESPState, 0, vmstate_esp, ESPState),
         VMSTATE_END_OF_LIST()
diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
index b307f5d261..f45bbde23c 100644
--- a/include/hw/scsi/esp.h
+++ b/include/hw/scsi/esp.h
@@ -43,8 +43,6 @@ struct ESPState {
     uint32_t cmdlen;
     uint32_t do_cmd;
 
-    /* The amount of data left in the current DMA transfer.  */
-    uint32_t dma_left;
     int dma_enabled;
 
     uint32_t async_len;
@@ -60,6 +58,9 @@ struct ESPState {
     uint32_t pdma_start;
     uint32_t pdma_cur;
     void (*pdma_cb)(ESPState *s);
+
+    /* Legacy field for vmstate_sysbus_esp_scsi version < 2 */
+    uint32_t mig_dma_left;
 };
 
 #define TYPE_ESP "esp"
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 11/25] esp: remove minlen restriction in handle_ti
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (9 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 10/25] esp: remove dma_left " Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 12/25] esp: introduce esp_pdma_read() and esp_pdma_write() functions Mark Cave-Ayland
                   ` (15 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

The limiting of DMA transfers to the maximum size of the available data is already
handled by esp_do_dma() and do_dma_pdma_cb().

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 69fed3cb22..39c5eeb57c 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -556,7 +556,7 @@ void esp_transfer_data(SCSIRequest *req, uint32_t len)
 
 static void handle_ti(ESPState *s)
 {
-    uint32_t dmalen, minlen;
+    uint32_t dmalen;
 
     if (s->dma && !s->dma_enabled) {
         s->dma_cb = handle_ti;
@@ -564,16 +564,8 @@ static void handle_ti(ESPState *s)
     }
 
     dmalen = esp_get_tc(s);
-
-    if (s->do_cmd) {
-        minlen = (dmalen < ESP_CMDBUF_SZ) ? dmalen : ESP_CMDBUF_SZ;
-    } else if (s->ti_size < 0) {
-        minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
-    } else {
-        minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
-    }
-    trace_esp_handle_ti(minlen);
     if (s->dma) {
+        trace_esp_handle_ti(dmalen);
         s->rregs[ESP_RSTAT] &= ~STAT_TC;
         esp_do_dma(s);
     } else if (s->do_cmd) {
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 12/25] esp: introduce esp_pdma_read() and esp_pdma_write() functions
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (10 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 11/25] esp: remove minlen restriction in handle_ti Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 13/25] esp: use pdma_origin directly in esp_pdma_read()/esp_pdma_write() Mark Cave-Ayland
                   ` (14 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 39c5eeb57c..80f7f73002 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -151,6 +151,20 @@ static uint8_t *get_pdma_buf(ESPState *s)
     return NULL;
 }
 
+static uint8_t esp_pdma_read(ESPState *s)
+{
+    uint8_t *buf = get_pdma_buf(s);
+
+    return buf[s->pdma_cur++];
+}
+
+static void esp_pdma_write(ESPState *s, uint8_t val)
+{
+    uint8_t *buf = get_pdma_buf(s);
+
+    buf[s->pdma_cur++] = val;
+}
+
 static int get_cmd_cb(ESPState *s)
 {
     int target;
@@ -879,7 +893,6 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
     SysBusESPState *sysbus = opaque;
     ESPState *s = &sysbus->esp;
     uint32_t dmalen = esp_get_tc(s);
-    uint8_t *buf = get_pdma_buf(s);
 
     trace_esp_pdma_write(size);
 
@@ -888,13 +901,13 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
     }
     switch (size) {
     case 1:
-        buf[s->pdma_cur++] = val;
+        esp_pdma_write(s, val);
         s->pdma_len--;
         dmalen--;
         break;
     case 2:
-        buf[s->pdma_cur++] = val >> 8;
-        buf[s->pdma_cur++] = val;
+        esp_pdma_write(s, val >> 8);
+        esp_pdma_write(s, val);
         s->pdma_len -= 2;
         dmalen -= 2;
         break;
@@ -913,7 +926,6 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr,
     SysBusESPState *sysbus = opaque;
     ESPState *s = &sysbus->esp;
     uint32_t dmalen = esp_get_tc(s);
-    uint8_t *buf = get_pdma_buf(s);
     uint64_t val = 0;
 
     trace_esp_pdma_read(size);
@@ -923,13 +935,13 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr,
     }
     switch (size) {
     case 1:
-        val = buf[s->pdma_cur++];
+        val = esp_pdma_read(s);
         s->pdma_len--;
         dmalen--;
         break;
     case 2:
-        val = buf[s->pdma_cur++];
-        val = (val << 8) | buf[s->pdma_cur++];
+        val = esp_pdma_read(s);
+        val = (val << 8) | esp_pdma_read(s);
         s->pdma_len -= 2;
         dmalen -= 2;
         break;
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 13/25] esp: use pdma_origin directly in esp_pdma_read()/esp_pdma_write()
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (11 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 12/25] esp: introduce esp_pdma_read() and esp_pdma_write() functions Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 14/25] esp: move pdma_len and TC logic into esp_pdma_read()/esp_pdma_write() Mark Cave-Ayland
                   ` (13 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

This is the first step in removing get_pdma_buf() from esp.c.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 34 ++++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 80f7f73002..6a3a4cbc80 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -153,16 +153,38 @@ static uint8_t *get_pdma_buf(ESPState *s)
 
 static uint8_t esp_pdma_read(ESPState *s)
 {
-    uint8_t *buf = get_pdma_buf(s);
-
-    return buf[s->pdma_cur++];
+    switch (s->pdma_origin) {
+    case PDMA:
+        return s->pdma_buf[s->pdma_cur++];
+    case TI:
+        return s->ti_buf[s->pdma_cur++];
+    case CMD:
+        return s->cmdbuf[s->pdma_cur++];
+    case ASYNC:
+        return s->async_buf[s->pdma_cur++];
+    default:
+        g_assert_not_reached();
+    }
 }
 
 static void esp_pdma_write(ESPState *s, uint8_t val)
 {
-    uint8_t *buf = get_pdma_buf(s);
-
-    buf[s->pdma_cur++] = val;
+    switch (s->pdma_origin) {
+    case PDMA:
+        s->pdma_buf[s->pdma_cur++] = val;
+        break;
+    case TI:
+        s->ti_buf[s->pdma_cur++] = val;
+        break;
+    case CMD:
+        s->cmdbuf[s->pdma_cur++] = val;
+        break;
+    case ASYNC:
+        s->async_buf[s->pdma_cur++] = val;
+        break;
+    default:
+        g_assert_not_reached();
+    }
 }
 
 static int get_cmd_cb(ESPState *s)
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 14/25] esp: move pdma_len and TC logic into esp_pdma_read()/esp_pdma_write()
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (12 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 13/25] esp: use pdma_origin directly in esp_pdma_read()/esp_pdma_write() Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 15/25] esp: accumulate SCSI commands for PDMA transfers in cmdbuf instead of pdma_buf Mark Cave-Ayland
                   ` (12 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 50 ++++++++++++++++++++++++++++++++------------------
 1 file changed, 32 insertions(+), 18 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 6a3a4cbc80..2b307341ad 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -153,22 +153,45 @@ static uint8_t *get_pdma_buf(ESPState *s)
 
 static uint8_t esp_pdma_read(ESPState *s)
 {
+    uint32_t dmalen = esp_get_tc(s);
+    uint8_t val;
+
+    if (dmalen == 0 || s->pdma_len == 0) {
+        return 0;
+    }
+
     switch (s->pdma_origin) {
     case PDMA:
-        return s->pdma_buf[s->pdma_cur++];
+        val = s->pdma_buf[s->pdma_cur++];
+        break;
     case TI:
-        return s->ti_buf[s->pdma_cur++];
+        val = s->ti_buf[s->pdma_cur++];
+        break;
     case CMD:
-        return s->cmdbuf[s->pdma_cur++];
+        val = s->cmdbuf[s->pdma_cur++];
+        break;
     case ASYNC:
-        return s->async_buf[s->pdma_cur++];
+        val = s->async_buf[s->pdma_cur++];
+        break;
     default:
         g_assert_not_reached();
     }
+
+    s->pdma_len--;
+    dmalen--;
+    esp_set_tc(s, dmalen);
+
+    return val;
 }
 
 static void esp_pdma_write(ESPState *s, uint8_t val)
 {
+    uint32_t dmalen = esp_get_tc(s);
+
+    if (dmalen == 0 || s->pdma_len == 0) {
+        return;
+    }
+
     switch (s->pdma_origin) {
     case PDMA:
         s->pdma_buf[s->pdma_cur++] = val;
@@ -185,6 +208,10 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
     default:
         g_assert_not_reached();
     }
+
+    s->pdma_len--;
+    dmalen--;
+    esp_set_tc(s, dmalen);
 }
 
 static int get_cmd_cb(ESPState *s)
@@ -914,27 +941,18 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
 {
     SysBusESPState *sysbus = opaque;
     ESPState *s = &sysbus->esp;
-    uint32_t dmalen = esp_get_tc(s);
 
     trace_esp_pdma_write(size);
 
-    if (dmalen == 0 || s->pdma_len == 0) {
-        return;
-    }
     switch (size) {
     case 1:
         esp_pdma_write(s, val);
-        s->pdma_len--;
-        dmalen--;
         break;
     case 2:
         esp_pdma_write(s, val >> 8);
         esp_pdma_write(s, val);
-        s->pdma_len -= 2;
-        dmalen -= 2;
         break;
     }
-    esp_set_tc(s, dmalen);
     if (s->pdma_len == 0 && s->pdma_cb) {
         esp_lower_drq(s);
         s->pdma_cb(s);
@@ -958,17 +976,13 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr,
     switch (size) {
     case 1:
         val = esp_pdma_read(s);
-        s->pdma_len--;
-        dmalen--;
         break;
     case 2:
         val = esp_pdma_read(s);
         val = (val << 8) | esp_pdma_read(s);
-        s->pdma_len -= 2;
-        dmalen -= 2;
         break;
     }
-    esp_set_tc(s, dmalen);
+    dmalen = esp_get_tc(s);
     if (dmalen == 0 || (s->pdma_len == 0 && s->pdma_cb)) {
         esp_lower_drq(s);
         s->pdma_cb(s);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 15/25] esp: accumulate SCSI commands for PDMA transfers in cmdbuf instead of pdma_buf
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (13 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 14/25] esp: move pdma_len and TC logic into esp_pdma_read()/esp_pdma_write() Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 16/25] esp: remove redundant pdma_start from ESPState Mark Cave-Ayland
                   ` (11 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

ESP SCSI commands are already accumulated in cmdbuf and so there is no need to
keep a separate pdma_buf buffer. Accumulate SCSI commands for PDMA transfers in
cmdbuf instead of pdma_buf so update cmdlen accordingly and change pdma_origin
for PDMA transfers to CMD which allows the PDMA origin to be removed.

This commit also removes a stray memcpy() from get_cmd() which is a no-op because
cmdlen is always zero at the start of a command.

Notionally the removal of pdma_buf from vmstate_esp_pdma also breaks migration
compatibility for the PDMA subsection until its complete removal by the end of
the series.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c         | 56 +++++++++++++++++++------------------------
 include/hw/scsi/esp.h |  3 ---
 2 files changed, 25 insertions(+), 34 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 2b307341ad..3bebd832aa 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -139,8 +139,6 @@ static void set_pdma(ESPState *s, enum pdma_origin_id origin,
 static uint8_t *get_pdma_buf(ESPState *s)
 {
     switch (s->pdma_origin) {
-    case PDMA:
-        return s->pdma_buf;
     case TI:
         return s->ti_buf;
     case CMD:
@@ -161,14 +159,12 @@ static uint8_t esp_pdma_read(ESPState *s)
     }
 
     switch (s->pdma_origin) {
-    case PDMA:
-        val = s->pdma_buf[s->pdma_cur++];
-        break;
     case TI:
         val = s->ti_buf[s->pdma_cur++];
         break;
     case CMD:
-        val = s->cmdbuf[s->pdma_cur++];
+        val = s->cmdbuf[s->cmdlen++];
+        s->pdma_cur++;
         break;
     case ASYNC:
         val = s->async_buf[s->pdma_cur++];
@@ -193,14 +189,12 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
     }
 
     switch (s->pdma_origin) {
-    case PDMA:
-        s->pdma_buf[s->pdma_cur++] = val;
-        break;
     case TI:
         s->ti_buf[s->pdma_cur++] = val;
         break;
     case CMD:
-        s->cmdbuf[s->pdma_cur++] = val;
+        s->cmdbuf[s->cmdlen++] = val;
+        s->pdma_cur++;
         break;
     case ASYNC:
         s->async_buf[s->pdma_cur++] = val;
@@ -256,8 +250,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
         if (s->dma_memory_read) {
             s->dma_memory_read(s->dma_opaque, buf, dmalen);
         } else {
-            memcpy(s->pdma_buf, buf, dmalen);
-            set_pdma(s, PDMA, 0, dmalen);
+            set_pdma(s, CMD, 0, dmalen);
             esp_raise_drq(s);
             return 0;
         }
@@ -316,24 +309,24 @@ static void satn_pdma_cb(ESPState *s)
     if (get_cmd_cb(s) < 0) {
         return;
     }
-    if (s->pdma_cur != s->pdma_start) {
-        do_cmd(s, get_pdma_buf(s) + s->pdma_start);
+    s->do_cmd = 0;
+    if (s->cmdlen) {
+        do_cmd(s, s->cmdbuf);
     }
 }
 
 static void handle_satn(ESPState *s)
 {
-    uint8_t buf[32];
-    int len;
-
     if (s->dma && !s->dma_enabled) {
         s->dma_cb = handle_satn;
         return;
     }
     s->pdma_cb = satn_pdma_cb;
-    len = get_cmd(s, buf, sizeof(buf));
-    if (len) {
-        do_cmd(s, buf);
+    s->cmdlen = get_cmd(s, s->cmdbuf, sizeof(s->cmdbuf));
+    if (s->cmdlen) {
+        do_cmd(s, s->cmdbuf);
+    } else {
+        s->do_cmd = 1;
     }
 }
 
@@ -342,24 +335,24 @@ static void s_without_satn_pdma_cb(ESPState *s)
     if (get_cmd_cb(s) < 0) {
         return;
     }
-    if (s->pdma_cur != s->pdma_start) {
+    s->do_cmd = 0;
+    if (s->cmdlen) {
         do_busid_cmd(s, get_pdma_buf(s) + s->pdma_start, 0);
     }
 }
 
 static void handle_s_without_atn(ESPState *s)
 {
-    uint8_t buf[32];
-    int len;
-
     if (s->dma && !s->dma_enabled) {
         s->dma_cb = handle_s_without_atn;
         return;
     }
     s->pdma_cb = s_without_satn_pdma_cb;
-    len = get_cmd(s, buf, sizeof(buf));
-    if (len) {
-        do_busid_cmd(s, buf, 0);
+    s->cmdlen = get_cmd(s, s->cmdbuf, sizeof(s->cmdbuf));
+    if (s->cmdlen) {
+        do_busid_cmd(s, s->cmdbuf, 0);
+    } else {
+        s->do_cmd = 1;
     }
 }
 
@@ -368,7 +361,7 @@ static void satn_stop_pdma_cb(ESPState *s)
     if (get_cmd_cb(s) < 0) {
         return;
     }
-    s->cmdlen = s->pdma_cur - s->pdma_start;
+    s->do_cmd = 0;
     if (s->cmdlen) {
         trace_esp_handle_satn_stop(s->cmdlen);
         s->do_cmd = 1;
@@ -394,6 +387,8 @@ static void handle_satn_stop(ESPState *s)
         s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
         s->rregs[ESP_RSEQ] = SEQ_CD;
         esp_raise_irq(s);
+    } else {
+        s->do_cmd = 1;
     }
 }
 
@@ -868,11 +863,10 @@ static bool esp_pdma_needed(void *opaque)
 
 static const VMStateDescription vmstate_esp_pdma = {
     .name = "esp/pdma",
-    .version_id = 1,
-    .minimum_version_id = 1,
+    .version_id = 2,
+    .minimum_version_id = 2,
     .needed = esp_pdma_needed,
     .fields = (VMStateField[]) {
-        VMSTATE_BUFFER(pdma_buf, ESPState),
         VMSTATE_INT32(pdma_origin, ESPState),
         VMSTATE_UINT32(pdma_len, ESPState),
         VMSTATE_UINT32(pdma_start, ESPState),
diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
index f45bbde23c..fd4779b497 100644
--- a/include/hw/scsi/esp.h
+++ b/include/hw/scsi/esp.h
@@ -16,7 +16,6 @@ typedef void (*ESPDMAMemoryReadWriteFunc)(void *opaque, uint8_t *buf, int len);
 typedef struct ESPState ESPState;
 
 enum pdma_origin_id {
-    PDMA,
     TI,
     CMD,
     ASYNC,
@@ -52,10 +51,8 @@ struct ESPState {
     ESPDMAMemoryReadWriteFunc dma_memory_write;
     void *dma_opaque;
     void (*dma_cb)(ESPState *s);
-    uint8_t pdma_buf[32];
     int pdma_origin;
     uint32_t pdma_len;
-    uint32_t pdma_start;
     uint32_t pdma_cur;
     void (*pdma_cb)(ESPState *s);
 
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 16/25] esp: remove redundant pdma_start from ESPState
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (14 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 15/25] esp: accumulate SCSI commands for PDMA transfers in cmdbuf instead of pdma_buf Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 17/25] esp: move PDMA length adjustments into esp_pdma_read()/esp_pdma_write() Mark Cave-Ayland
                   ` (10 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

Now that PDMA SCSI commands are accumulated in cmdbuf in the same way as normal
commands, the existing logic for locating the start of the SCSI command in
cmdbuf via cmdlen can be used. This enables the PDMA-specific pdma_start and
also get_pdma_buf() to be removed.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 3bebd832aa..ca1472962d 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -131,24 +131,10 @@ static void set_pdma(ESPState *s, enum pdma_origin_id origin,
                      uint32_t index, uint32_t len)
 {
     s->pdma_origin = origin;
-    s->pdma_start = index;
     s->pdma_cur = index;
     s->pdma_len = len;
 }
 
-static uint8_t *get_pdma_buf(ESPState *s)
-{
-    switch (s->pdma_origin) {
-    case TI:
-        return s->ti_buf;
-    case CMD:
-        return s->cmdbuf;
-    case ASYNC:
-        return s->async_buf;
-    }
-    return NULL;
-}
-
 static uint8_t esp_pdma_read(ESPState *s)
 {
     uint32_t dmalen = esp_get_tc(s);
@@ -337,7 +323,7 @@ static void s_without_satn_pdma_cb(ESPState *s)
     }
     s->do_cmd = 0;
     if (s->cmdlen) {
-        do_busid_cmd(s, get_pdma_buf(s) + s->pdma_start, 0);
+        do_busid_cmd(s, s->cmdbuf, 0);
     }
 }
 
@@ -441,7 +427,7 @@ static void esp_dma_done(ESPState *s)
 static void do_dma_pdma_cb(ESPState *s)
 {
     int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
-    int len = s->pdma_cur - s->pdma_start;
+    int len = s->pdma_cur;
 
     if (s->do_cmd) {
         s->ti_size = 0;
@@ -869,7 +855,6 @@ static const VMStateDescription vmstate_esp_pdma = {
     .fields = (VMStateField[]) {
         VMSTATE_INT32(pdma_origin, ESPState),
         VMSTATE_UINT32(pdma_len, ESPState),
-        VMSTATE_UINT32(pdma_start, ESPState),
         VMSTATE_UINT32(pdma_cur, ESPState),
         VMSTATE_END_OF_LIST()
     }
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 17/25] esp: move PDMA length adjustments into esp_pdma_read()/esp_pdma_write()
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (15 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 16/25] esp: remove redundant pdma_start from ESPState Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 18/25] esp: use ti_wptr/ti_rptr to manage the current FIFO position for PDMA Mark Cave-Ayland
                   ` (9 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

Here the updates to async_len and ti_size are moved into the corresponding
esp_pdma_read()/esp_pdma_write() function to eliminate the reference to
pdma_cur in do_dma_pdma_cb().

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index ca1472962d..23ec93c8ed 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -153,12 +153,18 @@ static uint8_t esp_pdma_read(ESPState *s)
         s->pdma_cur++;
         break;
     case ASYNC:
-        val = s->async_buf[s->pdma_cur++];
+        val = s->async_buf[0];
+        if (s->async_len > 0) {
+            s->async_len--;
+            s->async_buf++;
+        }
+        s->pdma_cur++;
         break;
     default:
         g_assert_not_reached();
     }
 
+    s->ti_size--;
     s->pdma_len--;
     dmalen--;
     esp_set_tc(s, dmalen);
@@ -183,12 +189,18 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
         s->pdma_cur++;
         break;
     case ASYNC:
-        s->async_buf[s->pdma_cur++] = val;
+        s->async_buf[0] = val;
+        if (s->async_len > 0) {
+            s->async_len--;
+            s->async_buf++;
+        }
+        s->pdma_cur++;
         break;
     default:
         g_assert_not_reached();
     }
 
+    s->ti_size++;
     s->pdma_len--;
     dmalen--;
     esp_set_tc(s, dmalen);
@@ -427,7 +439,6 @@ static void esp_dma_done(ESPState *s)
 static void do_dma_pdma_cb(ESPState *s)
 {
     int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
-    int len = s->pdma_cur;
 
     if (s->do_cmd) {
         s->ti_size = 0;
@@ -436,13 +447,6 @@ static void do_dma_pdma_cb(ESPState *s)
         do_cmd(s, s->cmdbuf);
         return;
     }
-    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);
         /*
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 18/25] esp: use ti_wptr/ti_rptr to manage the current FIFO position for PDMA
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (16 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 17/25] esp: move PDMA length adjustments into esp_pdma_read()/esp_pdma_write() Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 19/25] esp: use in-built TC to determine PDMA transfer length Mark Cave-Ayland
                   ` (8 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

This eliminates the last user of the PDMA-specific pdma_cur variable which can
now be removed.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c         | 23 ++++++++---------------
 include/hw/scsi/esp.h |  1 -
 2 files changed, 8 insertions(+), 16 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 23ec93c8ed..b43d0941f0 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -127,11 +127,9 @@ static uint32_t esp_get_stc(ESPState *s)
     return dmalen;
 }
 
-static void set_pdma(ESPState *s, enum pdma_origin_id origin,
-                     uint32_t index, uint32_t len)
+static void set_pdma(ESPState *s, enum pdma_origin_id origin, uint32_t len)
 {
     s->pdma_origin = origin;
-    s->pdma_cur = index;
     s->pdma_len = len;
 }
 
@@ -146,11 +144,10 @@ static uint8_t esp_pdma_read(ESPState *s)
 
     switch (s->pdma_origin) {
     case TI:
-        val = s->ti_buf[s->pdma_cur++];
+        val = s->ti_buf[s->ti_rptr++];
         break;
     case CMD:
         val = s->cmdbuf[s->cmdlen++];
-        s->pdma_cur++;
         break;
     case ASYNC:
         val = s->async_buf[0];
@@ -158,7 +155,6 @@ static uint8_t esp_pdma_read(ESPState *s)
             s->async_len--;
             s->async_buf++;
         }
-        s->pdma_cur++;
         break;
     default:
         g_assert_not_reached();
@@ -182,11 +178,10 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
 
     switch (s->pdma_origin) {
     case TI:
-        s->ti_buf[s->pdma_cur++] = val;
+        s->ti_buf[s->ti_wptr++] = val;
         break;
     case CMD:
         s->cmdbuf[s->cmdlen++] = val;
-        s->pdma_cur++;
         break;
     case ASYNC:
         s->async_buf[0] = val;
@@ -194,7 +189,6 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
             s->async_len--;
             s->async_buf++;
         }
-        s->pdma_cur++;
         break;
     default:
         g_assert_not_reached();
@@ -248,7 +242,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
         if (s->dma_memory_read) {
             s->dma_memory_read(s->dma_opaque, buf, dmalen);
         } else {
-            set_pdma(s, CMD, 0, dmalen);
+            set_pdma(s, CMD, dmalen);
             esp_raise_drq(s);
             return 0;
         }
@@ -410,7 +404,7 @@ static void write_response(ESPState *s)
             s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
             s->rregs[ESP_RSEQ] = SEQ_CD;
         } else {
-            set_pdma(s, TI, 0, 2);
+            set_pdma(s, TI, 2);
             s->pdma_cb = write_response_pdma_cb;
             esp_raise_drq(s);
             return;
@@ -480,7 +474,7 @@ static void esp_do_dma(ESPState *s)
         if (s->dma_memory_read) {
             s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
         } else {
-            set_pdma(s, CMD, s->cmdlen, len);
+            set_pdma(s, CMD, len);
             s->pdma_cb = do_dma_pdma_cb;
             esp_raise_drq(s);
             return;
@@ -503,7 +497,7 @@ static void esp_do_dma(ESPState *s)
         if (s->dma_memory_read) {
             s->dma_memory_read(s->dma_opaque, s->async_buf, len);
         } else {
-            set_pdma(s, ASYNC, 0, len);
+            set_pdma(s, ASYNC, len);
             s->pdma_cb = do_dma_pdma_cb;
             esp_raise_drq(s);
             return;
@@ -512,7 +506,7 @@ static void esp_do_dma(ESPState *s)
         if (s->dma_memory_write) {
             s->dma_memory_write(s->dma_opaque, s->async_buf, len);
         } else {
-            set_pdma(s, ASYNC, 0, len);
+            set_pdma(s, ASYNC, len);
             s->pdma_cb = do_dma_pdma_cb;
             esp_raise_drq(s);
             return;
@@ -859,7 +853,6 @@ static const VMStateDescription vmstate_esp_pdma = {
     .fields = (VMStateField[]) {
         VMSTATE_INT32(pdma_origin, ESPState),
         VMSTATE_UINT32(pdma_len, ESPState),
-        VMSTATE_UINT32(pdma_cur, ESPState),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
index fd4779b497..292136344a 100644
--- a/include/hw/scsi/esp.h
+++ b/include/hw/scsi/esp.h
@@ -53,7 +53,6 @@ struct ESPState {
     void (*dma_cb)(ESPState *s);
     int pdma_origin;
     uint32_t pdma_len;
-    uint32_t pdma_cur;
     void (*pdma_cb)(ESPState *s);
 
     /* Legacy field for vmstate_sysbus_esp_scsi version < 2 */
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 19/25] esp: use in-built TC to determine PDMA transfer length
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (17 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 18/25] esp: use ti_wptr/ti_rptr to manage the current FIFO position for PDMA Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 20/25] esp: remove CMD pdma_origin Mark Cave-Ayland
                   ` (7 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

Real hardware simply counts down using the in-built TC to determine when the
the PDMA request is complete. Use the TC to determine the PDMA transfer length
which then enables us to remove the redundant pdma_len variable.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c         | 28 +++++++++++++---------------
 include/hw/scsi/esp.h |  1 -
 2 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index b43d0941f0..35cc274747 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -127,10 +127,9 @@ static uint32_t esp_get_stc(ESPState *s)
     return dmalen;
 }
 
-static void set_pdma(ESPState *s, enum pdma_origin_id origin, uint32_t len)
+static void set_pdma(ESPState *s, enum pdma_origin_id origin)
 {
     s->pdma_origin = origin;
-    s->pdma_len = len;
 }
 
 static uint8_t esp_pdma_read(ESPState *s)
@@ -138,7 +137,7 @@ static uint8_t esp_pdma_read(ESPState *s)
     uint32_t dmalen = esp_get_tc(s);
     uint8_t val;
 
-    if (dmalen == 0 || s->pdma_len == 0) {
+    if (dmalen == 0) {
         return 0;
     }
 
@@ -161,7 +160,6 @@ static uint8_t esp_pdma_read(ESPState *s)
     }
 
     s->ti_size--;
-    s->pdma_len--;
     dmalen--;
     esp_set_tc(s, dmalen);
 
@@ -172,7 +170,7 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
 {
     uint32_t dmalen = esp_get_tc(s);
 
-    if (dmalen == 0 || s->pdma_len == 0) {
+    if (dmalen == 0) {
         return;
     }
 
@@ -195,7 +193,6 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
     }
 
     s->ti_size++;
-    s->pdma_len--;
     dmalen--;
     esp_set_tc(s, dmalen);
 }
@@ -242,7 +239,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
         if (s->dma_memory_read) {
             s->dma_memory_read(s->dma_opaque, buf, dmalen);
         } else {
-            set_pdma(s, CMD, dmalen);
+            set_pdma(s, CMD);
             esp_raise_drq(s);
             return 0;
         }
@@ -404,7 +401,7 @@ static void write_response(ESPState *s)
             s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
             s->rregs[ESP_RSEQ] = SEQ_CD;
         } else {
-            set_pdma(s, TI, 2);
+            set_pdma(s, TI);
             s->pdma_cb = write_response_pdma_cb;
             esp_raise_drq(s);
             return;
@@ -474,7 +471,7 @@ static void esp_do_dma(ESPState *s)
         if (s->dma_memory_read) {
             s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
         } else {
-            set_pdma(s, CMD, len);
+            set_pdma(s, CMD);
             s->pdma_cb = do_dma_pdma_cb;
             esp_raise_drq(s);
             return;
@@ -497,7 +494,7 @@ static void esp_do_dma(ESPState *s)
         if (s->dma_memory_read) {
             s->dma_memory_read(s->dma_opaque, s->async_buf, len);
         } else {
-            set_pdma(s, ASYNC, len);
+            set_pdma(s, ASYNC);
             s->pdma_cb = do_dma_pdma_cb;
             esp_raise_drq(s);
             return;
@@ -506,7 +503,7 @@ static void esp_do_dma(ESPState *s)
         if (s->dma_memory_write) {
             s->dma_memory_write(s->dma_opaque, s->async_buf, len);
         } else {
-            set_pdma(s, ASYNC, len);
+            set_pdma(s, ASYNC);
             s->pdma_cb = do_dma_pdma_cb;
             esp_raise_drq(s);
             return;
@@ -852,7 +849,6 @@ static const VMStateDescription vmstate_esp_pdma = {
     .needed = esp_pdma_needed,
     .fields = (VMStateField[]) {
         VMSTATE_INT32(pdma_origin, ESPState),
-        VMSTATE_UINT32(pdma_len, ESPState),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -917,6 +913,7 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
 {
     SysBusESPState *sysbus = opaque;
     ESPState *s = &sysbus->esp;
+    uint32_t dmalen;
 
     trace_esp_pdma_write(size);
 
@@ -929,7 +926,8 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
         esp_pdma_write(s, val);
         break;
     }
-    if (s->pdma_len == 0 && s->pdma_cb) {
+    dmalen = esp_get_tc(s);
+    if (dmalen == 0 && s->pdma_cb) {
         esp_lower_drq(s);
         s->pdma_cb(s);
         s->pdma_cb = NULL;
@@ -946,7 +944,7 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr,
 
     trace_esp_pdma_read(size);
 
-    if (dmalen == 0 || s->pdma_len == 0) {
+    if (dmalen == 0) {
         return 0;
     }
     switch (size) {
@@ -959,7 +957,7 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr,
         break;
     }
     dmalen = esp_get_tc(s);
-    if (dmalen == 0 || (s->pdma_len == 0 && s->pdma_cb)) {
+    if (dmalen == 0 && s->pdma_cb) {
         esp_lower_drq(s);
         s->pdma_cb(s);
         s->pdma_cb = NULL;
diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
index 292136344a..ecad5d8471 100644
--- a/include/hw/scsi/esp.h
+++ b/include/hw/scsi/esp.h
@@ -52,7 +52,6 @@ struct ESPState {
     void *dma_opaque;
     void (*dma_cb)(ESPState *s);
     int pdma_origin;
-    uint32_t pdma_len;
     void (*pdma_cb)(ESPState *s);
 
     /* Legacy field for vmstate_sysbus_esp_scsi version < 2 */
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 20/25] esp: remove CMD pdma_origin
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (18 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 19/25] esp: use in-built TC to determine PDMA transfer length Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 21/25] esp: rename get_cmd_cb() to esp_select() Mark Cave-Ayland
                   ` (6 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

The cmdbuf is really just a copy of FIFO data (including extra message phase
bytes) so its pdma_origin is effectively TI. Fortunately we already know when
we are receiving a SCSI command since do_cmd == 1 which enables us to
distinguish between the two cases in esp_pdma_read()/esp_pdma_write().

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c         | 22 ++++++++++++----------
 include/hw/scsi/esp.h |  1 -
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 35cc274747..33e3cf657b 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -143,10 +143,11 @@ static uint8_t esp_pdma_read(ESPState *s)
 
     switch (s->pdma_origin) {
     case TI:
-        val = s->ti_buf[s->ti_rptr++];
-        break;
-    case CMD:
-        val = s->cmdbuf[s->cmdlen++];
+        if (s->do_cmd) {
+            val = s->cmdbuf[s->cmdlen++];
+        } else {
+            val = s->ti_buf[s->ti_rptr++];
+        }
         break;
     case ASYNC:
         val = s->async_buf[0];
@@ -176,10 +177,11 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
 
     switch (s->pdma_origin) {
     case TI:
-        s->ti_buf[s->ti_wptr++] = val;
-        break;
-    case CMD:
-        s->cmdbuf[s->cmdlen++] = val;
+        if (s->do_cmd) {
+            s->cmdbuf[s->cmdlen++] = val;
+        } else {
+            s->ti_buf[s->ti_wptr++] = val;
+        }
         break;
     case ASYNC:
         s->async_buf[0] = val;
@@ -239,7 +241,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
         if (s->dma_memory_read) {
             s->dma_memory_read(s->dma_opaque, buf, dmalen);
         } else {
-            set_pdma(s, CMD);
+            set_pdma(s, TI);
             esp_raise_drq(s);
             return 0;
         }
@@ -471,7 +473,7 @@ static void esp_do_dma(ESPState *s)
         if (s->dma_memory_read) {
             s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
         } else {
-            set_pdma(s, CMD);
+            set_pdma(s, TI);
             s->pdma_cb = do_dma_pdma_cb;
             esp_raise_drq(s);
             return;
diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
index ecad5d8471..b8170e58ca 100644
--- a/include/hw/scsi/esp.h
+++ b/include/hw/scsi/esp.h
@@ -17,7 +17,6 @@ typedef struct ESPState ESPState;
 
 enum pdma_origin_id {
     TI,
-    CMD,
     ASYNC,
 };
 
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 21/25] esp: rename get_cmd_cb() to esp_select()
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (19 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 20/25] esp: remove CMD pdma_origin Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2021-01-01 16:57   ` Philippe Mathieu-Daudé
  2020-12-30 15:37 ` [PATCH 22/25] esp: fix PDMA target selection Mark Cave-Ayland
                   ` (5 subsequent siblings)
  26 siblings, 1 reply; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

This better describes the purpose of the function.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 33e3cf657b..50bddc7d68 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -199,7 +199,7 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
     esp_set_tc(s, dmalen);
 }
 
-static int get_cmd_cb(ESPState *s)
+static int esp_select(ESPState *s)
 {
     int target;
 
@@ -255,7 +255,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
     }
     trace_esp_get_cmd(dmalen, target);
 
-    if (get_cmd_cb(s) < 0) {
+    if (esp_select(s) < 0) {
         return 0;
     }
     return dmalen;
@@ -297,7 +297,7 @@ static void do_cmd(ESPState *s, uint8_t *buf)
 
 static void satn_pdma_cb(ESPState *s)
 {
-    if (get_cmd_cb(s) < 0) {
+    if (esp_select(s) < 0) {
         return;
     }
     s->do_cmd = 0;
@@ -323,7 +323,7 @@ static void handle_satn(ESPState *s)
 
 static void s_without_satn_pdma_cb(ESPState *s)
 {
-    if (get_cmd_cb(s) < 0) {
+    if (esp_select(s) < 0) {
         return;
     }
     s->do_cmd = 0;
@@ -349,7 +349,7 @@ static void handle_s_without_atn(ESPState *s)
 
 static void satn_stop_pdma_cb(ESPState *s)
 {
-    if (get_cmd_cb(s) < 0) {
+    if (esp_select(s) < 0) {
         return;
     }
     s->do_cmd = 0;
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 22/25] esp: fix PDMA target selection
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (20 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 21/25] esp: rename get_cmd_cb() to esp_select() Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 23/25] esp: use FIFO for PDMA transfers between initiator and device Mark Cave-Ayland
                   ` (4 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

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-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 55 ++++++++++++++++++++++++++++++++-------------------
 1 file changed, 35 insertions(+), 20 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 50bddc7d68..69c03e59f0 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -227,7 +227,7 @@ static int esp_select(ESPState *s)
     return 0;
 }
 
-static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
+static int32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
 {
     uint32_t dmalen;
     int target;
@@ -242,6 +242,9 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
             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;
         }
@@ -256,7 +259,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
     trace_esp_get_cmd(dmalen, target);
 
     if (esp_select(s) < 0) {
-        return 0;
+        return -1;
     }
     return dmalen;
 }
@@ -297,9 +300,6 @@ static void do_cmd(ESPState *s, uint8_t *buf)
 
 static void satn_pdma_cb(ESPState *s)
 {
-    if (esp_select(s) < 0) {
-        return;
-    }
     s->do_cmd = 0;
     if (s->cmdlen) {
         do_cmd(s, s->cmdbuf);
@@ -308,24 +308,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, s->cmdbuf, sizeof(s->cmdbuf));
-    if (s->cmdlen) {
+    cmdlen = get_cmd(s, s->cmdbuf, sizeof(s->cmdbuf));
+    if (cmdlen > 0) {
+        s->cmdlen = cmdlen;
         do_cmd(s, s->cmdbuf);
-    } 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);
@@ -334,24 +338,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, s->cmdbuf, sizeof(s->cmdbuf));
-    if (s->cmdlen) {
+    cmdlen = get_cmd(s, s->cmdbuf, sizeof(s->cmdbuf));
+    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);
@@ -365,21 +373,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, s->cmdbuf, sizeof(s->cmdbuf));
-    if (s->cmdlen) {
+    cmdlen = get_cmd(s, s->cmdbuf, sizeof(s->cmdbuf));
+    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;
     }
 }
 
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 23/25] esp: use FIFO for PDMA transfers between initiator and device
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (21 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 22/25] esp: fix PDMA target selection Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 24/25] esp: remove pdma_origin from ESPState Mark Cave-Ayland
                   ` (3 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

PDMA as implemented on the Quadra 800 uses DREQ to load data into the FIFO
up to a maximum of 16 bytes at a time. The MacOS toolbox ROM requires this
because it mixes FIFO and PDMA transfers whilst checking the FIFO status
and counter registers to ensure success.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 104 +++++++++++++++++++++++++++++++++++---------------
 1 file changed, 73 insertions(+), 31 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 69c03e59f0..d2a70998aa 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -134,13 +134,8 @@ static void set_pdma(ESPState *s, enum pdma_origin_id origin)
 
 static uint8_t esp_pdma_read(ESPState *s)
 {
-    uint32_t dmalen = esp_get_tc(s);
     uint8_t val;
 
-    if (dmalen == 0) {
-        return 0;
-    }
-
     switch (s->pdma_origin) {
     case TI:
         if (s->do_cmd) {
@@ -161,8 +156,6 @@ static uint8_t esp_pdma_read(ESPState *s)
     }
 
     s->ti_size--;
-    dmalen--;
-    esp_set_tc(s, dmalen);
 
     return val;
 }
@@ -447,28 +440,71 @@ static void esp_dma_done(ESPState *s)
 static void do_dma_pdma_cb(ESPState *s)
 {
     int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
+    int len;
 
     if (s->do_cmd) {
         s->ti_size = 0;
         s->cmdlen = 0;
         s->do_cmd = 0;
         do_cmd(s, s->cmdbuf);
+        esp_lower_drq(s);
         return;
     }
-    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) {
+
+    if (to_device) {
+        /* Copy FIFO data to device */
+        len = MIN(s->ti_wptr, TI_BUFSZ);
+        memcpy(s->async_buf, s->ti_buf, len);
+        s->ti_wptr = 0;
+        s->ti_rptr = 0;
+        s->async_buf += len;
+        s->async_len -= 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);
+        if (esp_get_tc(s) == 0) {
+            esp_lower_drq(s);
+            esp_dma_done(s);
+        }
+
+        return;
+    } else {
+        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) {
+                return;
+            }
+        }
+
+        if (esp_get_tc(s) != 0) {
+            /* Copy device data to FIFO */
+            s->ti_wptr = 0;
+            s->ti_rptr = 0;
+            len = MIN(s->async_len, TI_BUFSZ);
+            memcpy(s->ti_buf, s->async_buf, len);
+            s->ti_wptr += len;
+            s->async_buf += len;
+            s->async_len -= len;
+            esp_set_tc(s, esp_get_tc(s) - len);
+            return;
+        }
+
+        /* Partially filled a scsi buffer. Complete immediately.  */
+        esp_lower_drq(s);
+        esp_dma_done(s);
+    }
 }
 
 static void esp_do_dma(ESPState *s)
@@ -511,7 +547,7 @@ static void esp_do_dma(ESPState *s)
         if (s->dma_memory_read) {
             s->dma_memory_read(s->dma_opaque, s->async_buf, len);
         } else {
-            set_pdma(s, ASYNC);
+            set_pdma(s, TI);
             s->pdma_cb = do_dma_pdma_cb;
             esp_raise_drq(s);
             return;
@@ -520,9 +556,19 @@ static void esp_do_dma(ESPState *s)
         if (s->dma_memory_write) {
             s->dma_memory_write(s->dma_opaque, s->async_buf, len);
         } else {
-            set_pdma(s, ASYNC);
+            /* Copy device data to FIFO */
+            len = MIN(len, TI_BUFSZ - s->ti_wptr);
+            memcpy(&s->ti_buf[s->ti_wptr], s->async_buf, len);
+            s->ti_wptr += len;
+            s->async_buf += len;
+            s->async_len -= len;
+            esp_set_tc(s, esp_get_tc(s) - len);
+            set_pdma(s, TI);
             s->pdma_cb = do_dma_pdma_cb;
             esp_raise_drq(s);
+
+            /* Indicate transfer to FIFO is complete */
+            s->rregs[ESP_RSTAT] |= STAT_TC;
             return;
         }
     }
@@ -548,6 +594,7 @@ static void esp_do_dma(ESPState *s)
 
     /* Partially filled a scsi buffer. Complete immediately.  */
     esp_dma_done(s);
+    esp_lower_drq(s);
 }
 
 static void esp_report_command_complete(ESPState *s, uint32_t status)
@@ -564,6 +611,7 @@ static void esp_report_command_complete(ESPState *s, uint32_t status)
     s->status = status;
     s->rregs[ESP_RSTAT] = STAT_ST;
     esp_dma_done(s);
+    esp_lower_drq(s);
     if (s->current_req) {
         scsi_req_unref(s->current_req);
         s->current_req = NULL;
@@ -607,6 +655,7 @@ void esp_transfer_data(SCSIRequest *req, uint32_t len)
          * completion interrupt is deferred to here.
          */
         esp_dma_done(s);
+        esp_lower_drq(s);
     }
 }
 
@@ -944,10 +993,8 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
         break;
     }
     dmalen = esp_get_tc(s);
-    if (dmalen == 0 && s->pdma_cb) {
-        esp_lower_drq(s);
+    if (dmalen == 0 || (s->ti_wptr == TI_BUFSZ)) {
         s->pdma_cb(s);
-        s->pdma_cb = NULL;
     }
 }
 
@@ -956,14 +1003,10 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr,
 {
     SysBusESPState *sysbus = opaque;
     ESPState *s = &sysbus->esp;
-    uint32_t dmalen = esp_get_tc(s);
     uint64_t val = 0;
 
     trace_esp_pdma_read(size);
 
-    if (dmalen == 0) {
-        return 0;
-    }
     switch (size) {
     case 1:
         val = esp_pdma_read(s);
@@ -973,11 +1016,10 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr,
         val = (val << 8) | esp_pdma_read(s);
         break;
     }
-    dmalen = esp_get_tc(s);
-    if (dmalen == 0 && s->pdma_cb) {
-        esp_lower_drq(s);
+    if (s->ti_rptr == s->ti_wptr) {
+        s->ti_wptr = 0;
+        s->ti_rptr = 0;
         s->pdma_cb(s);
-        s->pdma_cb = NULL;
     }
     return val;
 }
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 24/25] esp: remove pdma_origin from ESPState
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (22 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 23/25] esp: use FIFO for PDMA transfers between initiator and device Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2020-12-30 15:37 ` [PATCH 25/25] esp: add 4 byte PDMA read and write transfers Mark Cave-Ayland
                   ` (2 subsequent siblings)
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

Now that all data is transferred via the FIFO (ti_buf) there is no need to track
the source buffer being used for the data transfer. This also eliminates the
need for a separate subsection for PDMA state migration.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c         | 74 +++++--------------------------------------
 include/hw/scsi/esp.h |  6 ----
 2 files changed, 8 insertions(+), 72 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index d2a70998aa..773fe09c49 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -127,32 +127,14 @@ static uint32_t esp_get_stc(ESPState *s)
     return dmalen;
 }
 
-static void set_pdma(ESPState *s, enum pdma_origin_id origin)
-{
-    s->pdma_origin = origin;
-}
-
 static uint8_t esp_pdma_read(ESPState *s)
 {
     uint8_t val;
 
-    switch (s->pdma_origin) {
-    case TI:
-        if (s->do_cmd) {
-            val = s->cmdbuf[s->cmdlen++];
-        } else {
-            val = s->ti_buf[s->ti_rptr++];
-        }
-        break;
-    case ASYNC:
-        val = s->async_buf[0];
-        if (s->async_len > 0) {
-            s->async_len--;
-            s->async_buf++;
-        }
-        break;
-    default:
-        g_assert_not_reached();
+    if (s->do_cmd) {
+        val = s->cmdbuf[s->cmdlen++];
+    } else {
+        val = s->ti_buf[s->ti_rptr++];
     }
 
     s->ti_size--;
@@ -168,23 +150,10 @@ static void esp_pdma_write(ESPState *s, uint8_t val)
         return;
     }
 
-    switch (s->pdma_origin) {
-    case TI:
-        if (s->do_cmd) {
-            s->cmdbuf[s->cmdlen++] = val;
-        } else {
-            s->ti_buf[s->ti_wptr++] = val;
-        }
-        break;
-    case ASYNC:
-        s->async_buf[0] = val;
-        if (s->async_len > 0) {
-            s->async_len--;
-            s->async_buf++;
-        }
-        break;
-    default:
-        g_assert_not_reached();
+    if (s->do_cmd) {
+        s->cmdbuf[s->cmdlen++] = val;
+    } else {
+        s->ti_buf[s->ti_wptr++] = val;
     }
 
     s->ti_size++;
@@ -234,7 +203,6 @@ static int32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
         if (s->dma_memory_read) {
             s->dma_memory_read(s->dma_opaque, buf, dmalen);
         } else {
-            set_pdma(s, TI);
             if (esp_select(s) < 0) {
                 return -1;
             }
@@ -411,7 +379,6 @@ static void write_response(ESPState *s)
             s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
             s->rregs[ESP_RSEQ] = SEQ_CD;
         } else {
-            set_pdma(s, TI);
             s->pdma_cb = write_response_pdma_cb;
             esp_raise_drq(s);
             return;
@@ -524,7 +491,6 @@ static void esp_do_dma(ESPState *s)
         if (s->dma_memory_read) {
             s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
         } else {
-            set_pdma(s, TI);
             s->pdma_cb = do_dma_pdma_cb;
             esp_raise_drq(s);
             return;
@@ -547,7 +513,6 @@ static void esp_do_dma(ESPState *s)
         if (s->dma_memory_read) {
             s->dma_memory_read(s->dma_opaque, s->async_buf, len);
         } else {
-            set_pdma(s, TI);
             s->pdma_cb = do_dma_pdma_cb;
             esp_raise_drq(s);
             return;
@@ -563,7 +528,6 @@ static void esp_do_dma(ESPState *s)
             s->async_buf += len;
             s->async_len -= len;
             esp_set_tc(s, esp_get_tc(s) - len);
-            set_pdma(s, TI);
             s->pdma_cb = do_dma_pdma_cb;
             esp_raise_drq(s);
 
@@ -901,24 +865,6 @@ static bool esp_mem_accepts(void *opaque, hwaddr addr,
     return (size == 1) || (is_write && size == 4);
 }
 
-static bool esp_pdma_needed(void *opaque)
-{
-    ESPState *s = opaque;
-    return s->dma_memory_read == NULL && s->dma_memory_write == NULL &&
-           s->dma_enabled;
-}
-
-static const VMStateDescription vmstate_esp_pdma = {
-    .name = "esp/pdma",
-    .version_id = 2,
-    .minimum_version_id = 2,
-    .needed = esp_pdma_needed,
-    .fields = (VMStateField[]) {
-        VMSTATE_INT32(pdma_origin, ESPState),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
 const VMStateDescription vmstate_esp = {
     .name = "esp",
     .version_id = 4,
@@ -941,10 +887,6 @@ const VMStateDescription vmstate_esp = {
         VMSTATE_UINT32(mig_dma_left, ESPState),
         VMSTATE_END_OF_LIST()
     },
-    .subsections = (const VMStateDescription * []) {
-        &vmstate_esp_pdma,
-        NULL
-    }
 };
 
 static void sysbus_esp_mem_write(void *opaque, hwaddr addr,
diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
index b8170e58ca..45c15e0650 100644
--- a/include/hw/scsi/esp.h
+++ b/include/hw/scsi/esp.h
@@ -15,11 +15,6 @@ typedef void (*ESPDMAMemoryReadWriteFunc)(void *opaque, uint8_t *buf, int len);
 
 typedef struct ESPState ESPState;
 
-enum pdma_origin_id {
-    TI,
-    ASYNC,
-};
-
 struct ESPState {
     uint8_t rregs[ESP_REGS];
     uint8_t wregs[ESP_REGS];
@@ -50,7 +45,6 @@ struct ESPState {
     ESPDMAMemoryReadWriteFunc dma_memory_write;
     void *dma_opaque;
     void (*dma_cb)(ESPState *s);
-    int pdma_origin;
     void (*pdma_cb)(ESPState *s);
 
     /* Legacy field for vmstate_sysbus_esp_scsi version < 2 */
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 25/25] esp: add 4 byte PDMA read and write transfers
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (23 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 24/25] esp: remove pdma_origin from ESPState Mark Cave-Ayland
@ 2020-12-30 15:37 ` Mark Cave-Ayland
  2021-01-06 15:18 ` [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
  2021-01-13 14:39 ` Paolo Bonzini
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2020-12-30 15:37 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

The MacOS toolbox ROM performs 4 byte reads/writes when transferring data to
and from the target.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/scsi/esp.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 773fe09c49..b356a65f5c 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -933,6 +933,12 @@ static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
         esp_pdma_write(s, val >> 8);
         esp_pdma_write(s, val);
         break;
+    case 4:
+        esp_pdma_write(s, val >> 24);
+        esp_pdma_write(s, val >> 16);
+        esp_pdma_write(s, val >> 8);
+        esp_pdma_write(s, val);
+        break;
     }
     dmalen = esp_get_tc(s);
     if (dmalen == 0 || (s->ti_wptr == TI_BUFSZ)) {
@@ -957,6 +963,12 @@ static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr,
         val = esp_pdma_read(s);
         val = (val << 8) | esp_pdma_read(s);
         break;
+    case 4:
+        val = esp_pdma_read(s);
+        val = (val << 8) | esp_pdma_read(s);
+        val = (val << 8) | esp_pdma_read(s);
+        val = (val << 8) | esp_pdma_read(s);
+        break;
     }
     if (s->ti_rptr == s->ti_wptr) {
         s->ti_wptr = 0;
@@ -971,7 +983,7 @@ static const MemoryRegionOps sysbus_esp_pdma_ops = {
     .write = sysbus_esp_pdma_write,
     .endianness = DEVICE_NATIVE_ENDIAN,
     .valid.min_access_size = 1,
-    .valid.max_access_size = 2,
+    .valid.max_access_size = 4,
 };
 
 static const struct SCSIBusInfo esp_scsi_info = {
@@ -1014,7 +1026,7 @@ static void sysbus_esp_realize(DeviceState *dev, Error **errp)
                           sysbus, "esp-regs", ESP_REGS << sysbus->it_shift);
     sysbus_init_mmio(sbd, &sysbus->iomem);
     memory_region_init_io(&sysbus->pdma, OBJECT(sysbus), &sysbus_esp_pdma_ops,
-                          sysbus, "esp-pdma", 2);
+                          sysbus, "esp-pdma", 4);
     sysbus_init_mmio(sbd, &sysbus->pdma);
 
     qdev_init_gpio_in(dev, sysbus_esp_gpio_demux, 2);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH 01/25] esp: checkpatch fixes
  2020-12-30 15:37 ` [PATCH 01/25] esp: checkpatch fixes Mark Cave-Ayland
@ 2021-01-01 16:53   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 35+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-01 16:53 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel, pbonzini, fam, laurent

On 12/30/20 4:37 PM, Mark Cave-Ayland wrote:
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
>  hw/scsi/esp.c | 52 ++++++++++++++++++++++++++++++---------------------
>  1 file changed, 31 insertions(+), 21 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 02/25] esp: add trace event when receiving a TI command
  2020-12-30 15:37 ` [PATCH 02/25] esp: add trace event when receiving a TI command Mark Cave-Ayland
@ 2021-01-01 16:54   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 35+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-01 16:54 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel, pbonzini, fam, laurent

On 12/30/20 4:37 PM, Mark Cave-Ayland wrote:
> This enables us to determine whether the command being issued is for a DMA or a
> non-DMA transfer.
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
>  hw/scsi/esp.c        | 1 +
>  hw/scsi/trace-events | 1 +
>  2 files changed, 2 insertions(+)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 03/25] esp: fix esp_reg_read() trace event
  2020-12-30 15:37 ` [PATCH 03/25] esp: fix esp_reg_read() trace event Mark Cave-Ayland
@ 2021-01-01 16:54   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 35+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-01 16:54 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel, pbonzini, fam, laurent

On 12/30/20 4:37 PM, Mark Cave-Ayland wrote:
> Move the trace event to the end of the function so that it correctly reports
> the returned value if it doesn't come directly from the rregs array.
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
>  hw/scsi/esp.c | 18 ++++++++++++------
>  1 file changed, 12 insertions(+), 6 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 04/25] esp: add PDMA trace events
  2020-12-30 15:37 ` [PATCH 04/25] esp: add PDMA trace events Mark Cave-Ayland
@ 2021-01-01 16:55   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 35+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-01 16:55 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel, pbonzini, fam, laurent

On 12/30/20 4:37 PM, Mark Cave-Ayland wrote:
> This will become more useful later when trying to debug mixed FIFO and PDMA
> requests.
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
>  hw/scsi/esp.c        | 6 ++++++
>  hw/scsi/trace-events | 4 ++++
>  2 files changed, 10 insertions(+)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 06/25] esp: introduce esp_get_tc() and esp_set_tc()
  2020-12-30 15:37 ` [PATCH 06/25] esp: introduce esp_get_tc() and esp_set_tc() Mark Cave-Ayland
@ 2021-01-01 16:56   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 35+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-01 16:56 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel, pbonzini, fam, laurent

On 12/30/20 4:37 PM, Mark Cave-Ayland wrote:
> This simplifies reading and writing the TC register value without having to
> manually shift each individual 8-bit value.
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
>  hw/scsi/esp.c | 34 ++++++++++++++++++++++------------
>  1 file changed, 22 insertions(+), 12 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 21/25] esp: rename get_cmd_cb() to esp_select()
  2020-12-30 15:37 ` [PATCH 21/25] esp: rename get_cmd_cb() to esp_select() Mark Cave-Ayland
@ 2021-01-01 16:57   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 35+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-01 16:57 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel, pbonzini, fam, laurent

On 12/30/20 4:37 PM, Mark Cave-Ayland wrote:
> This better describes the purpose of the function.
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
>  hw/scsi/esp.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/25] esp: consolidate PDMA transfer buffers
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (24 preceding siblings ...)
  2020-12-30 15:37 ` [PATCH 25/25] esp: add 4 byte PDMA read and write transfers Mark Cave-Ayland
@ 2021-01-06 15:18 ` Mark Cave-Ayland
  2021-01-13 14:39 ` Paolo Bonzini
  26 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2021-01-06 15:18 UTC (permalink / raw)
  To: qemu-devel, pbonzini, fam, laurent

On 30/12/2020 15:37, Mark Cave-Ayland wrote:

> This patch series comes from an experimental branch that I've been working on
> to try and boot a MacOS toolbox ROM under the QEMU q800 machine. The effort is
> far from complete, but it seems worth submitting these patches separately since
> they are limited to the ESP device and form a substantial part of the work to
> date.
> 
> As part of Laurent's recent q800 work so-called PDMA (pseudo-DMA) support was
> added to the ESP device. This is whereby the DREQ (DMA request) line is used
> to signal to the host CPU that it can transfer data to/from the device over
> the SCSI bus.
> 
> The existing PDMA tracks 4 separate transfer data sources as indicated by the
> ESP pdma_origin variable: PDMA, TI, CMD and ASYNC with an independent variable
> pdma_len to store the transfer length. This works well with Linux which uses a
> single PDMA request to transfer a number of sectors in a single request.
> 
> Unfortunately the MacOS toolbox ROM has other ideas here: it sends data to the
> ESP as a mixture of FIFO and PDMA transfers and then uses a mixture of the FIFO
> and DMA counters to confirm that the correct number of bytes have been
> transferred. For this to work correctly the PDMA buffers and separate pdma_len
> transfer counter must be consolidated into the FIFO to allow mixing of both
> types of transfer within a single request.
> 
> The patchset is split into several sections:
> 
> - Patches 1-4 are minor patches which make esp.c checkpatch friendly whilst also
>    fixing up some trace events ready for later patches in the series
>    
> - Patches 5-11 unify the DMA transfer count. In particular there are 2 synthetic
>    variables dma_counter and dma_left within ESPState which do not need to exist.
>    DMA transfer lengths are programmed into the TC (transfer count) register which is
>    decremented for each byte transferred, generating an interrupt when it reaches zero.
>    These patches add helper functions to read the TC and STC registers directly and
>    remove these synthetic variables so that the DMA transfer length is now tracked in
>    a single place.
> 
> - Now that the TC register represents the authoritative DMA transfer length, patches
>    12-20 work to eliminate the separate PDMA variables pdma_start, pdma_cur, pdma_len
>    and separate PDMA buffers PDMA and CMD. The PDMA position variables can be replaced
>    by the existing ESP cmdlen and ti_wptr/ti_rptr, whilst the FIFO (TI) buffer is used
>    for incoming data with commands being accumulated in cmdbuf as per standard DMA
>    requests.
> 
> - Patches 21 and 22 fix the detection of missing SCSI targets by the MacOS toolbox ROM
>    on startup at which point it will attempt to start reading information from a CDROM
>    attached to the q800 machine.
> 
> - Patch 23 is the main rework of the PDMA buffer transfers: instead of tracking the
>    SCSI transfers using a separate ASYNC pdma_origin, the contents of the ESPState
>    async_buf are copied to the FIFO buffer in 16-byte chunks with the transfer status
>    and IRQs being set accordingly.
> 
> - Patch 24 removes the last separate PDMA variable pdma_origin, including the separate
>    PDMA migration subsection which is no longer required (see note below about migration
>    compatibility).
>    
> - Finally patch 25 enables 4 byte PDMA reads/writes over the SCSI bus which are used
>    by MacOS when reading the next stage bootloader from CDROM (this is an increase from
>    2 bytes currently implemented and used by Linux).
> 
> 
> Testing
> =======
> 
> I've tested this on my SPARC32 OpenBIOS images which include Linux, OpenBSD, NetBSD,
> and Solaris and all of these continue to boot as before.
> 
> Similarly the q800 m68k Linux test image still boots as before with these patches
> applied. It is possible with lots of hacks to load Laurent's EMILE bootloader using
> a MacOS toolbox ROM - the hope is to try and start upstreaming more of these changes
> as time allows.
> 
> 
> Migration
> =========
> 
> The patchset ensures that ESP devices without PDMA (i.e. everything except the q800
> machine) will migrate successfully. This is fairly simple: the only change required
> here is to copy the old synthetic dma_left value over into the TC.
> 
> Unfortunately migrating the PDMA subsection is a lot harder due to the change in the
> way that the DMA TC and changes to the point at which transfer counters are updated.
> For this reason the patchset will not migrate from older q800 snapshots: I don't
> believe this to be a problem since some devices are still missing VMStateDescription
> plus there are likely to be more breaking changes as the q800 machine matures.
> 
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> 
> 
> Mark Cave-Ayland (25):
>    esp: checkpatch fixes
>    esp: add trace event when receiving a TI command
>    esp: fix esp_reg_read() trace event
>    esp: add PDMA trace events
>    esp: determine transfer direction directly from SCSI phase
>    esp: introduce esp_get_tc() and esp_set_tc()
>    esp: introduce esp_get_stc()
>    esp: apply transfer length adjustment when STC is zero at TC load time
>    esp: remove dma_counter from ESPState
>    esp: remove dma_left from ESPState
>    esp: remove minlen restriction in handle_ti
>    esp: introduce esp_pdma_read() and esp_pdma_write() functions
>    esp: use pdma_origin directly in esp_pdma_read()/esp_pdma_write()
>    esp: move pdma_len and TC logic into esp_pdma_read()/esp_pdma_write()
>    esp: accumulate SCSI commands for PDMA transfers in cmdbuf instead of
>      pdma_buf
>    esp: remove redundant pdma_start from ESPState
>    esp: move PDMA length adjustments into
>      esp_pdma_read()/esp_pdma_write()
>    esp: use ti_wptr/ti_rptr to manage the current FIFO position for PDMA
>    esp: use in-built TC to determine PDMA transfer length
>    esp: remove CMD pdma_origin
>    esp: rename get_cmd_cb() to esp_select()
>    esp: fix PDMA target selection
>    esp: use FIFO for PDMA transfers between initiator and device
>    esp: remove pdma_origin from ESPState
>    esp: add 4 byte PDMA read and write transfers
> 
>   hw/scsi/esp.c         | 461 +++++++++++++++++++++++++-----------------
>   hw/scsi/trace-events  |   5 +
>   include/hw/scsi/esp.h |  20 +-
>   3 files changed, 279 insertions(+), 207 deletions(-)

Please ignore this patchset for now - whilst the changes allow mixed PDMA and FIFO 
requests, they assume that the FIFO request sizes have the same alignment as the PDMA 
request sizes. I've just found a case where this isn't true in the MacOS toolbox ROM, 
so I'll investigate further and then resubmit.


ATB,

Mark.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/25] esp: consolidate PDMA transfer buffers
  2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
                   ` (25 preceding siblings ...)
  2021-01-06 15:18 ` [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
@ 2021-01-13 14:39 ` Paolo Bonzini
  2021-01-13 19:29   ` Mark Cave-Ayland
  26 siblings, 1 reply; 35+ messages in thread
From: Paolo Bonzini @ 2021-01-13 14:39 UTC (permalink / raw)
  To: Mark Cave-Ayland, qemu-devel, fam, laurent

On 30/12/20 16:37, Mark Cave-Ayland wrote:
> This patch series comes from an experimental branch that I've been working on
> to try and boot a MacOS toolbox ROM under the QEMU q800 machine. The effort is
> far from complete, but it seems worth submitting these patches separately since
> they are limited to the ESP device and form a substantial part of the work to
> date.
> 
> As part of Laurent's recent q800 work so-called PDMA (pseudo-DMA) support was
> added to the ESP device. This is whereby the DREQ (DMA request) line is used
> to signal to the host CPU that it can transfer data to/from the device over
> the SCSI bus.
> 
> The existing PDMA tracks 4 separate transfer data sources as indicated by the
> ESP pdma_origin variable: PDMA, TI, CMD and ASYNC with an independent variable
> pdma_len to store the transfer length. This works well with Linux which uses a
> single PDMA request to transfer a number of sectors in a single request.
> 
> Unfortunately the MacOS toolbox ROM has other ideas here: it sends data to the
> ESP as a mixture of FIFO and PDMA transfers and then uses a mixture of the FIFO
> and DMA counters to confirm that the correct number of bytes have been
> transferred. For this to work correctly the PDMA buffers and separate pdma_len
> transfer counter must be consolidated into the FIFO to allow mixing of both
> types of transfer within a single request.

This is all esp.c, so if Laurent and you are fine just send a pull request.

Thanks!

Paolo



> The patchset is split into several sections:
> 
> - Patches 1-4 are minor patches which make esp.c checkpatch friendly whilst also
>    fixing up some trace events ready for later patches in the series
>    
> - Patches 5-11 unify the DMA transfer count. In particular there are 2 synthetic
>    variables dma_counter and dma_left within ESPState which do not need to exist.
>    DMA transfer lengths are programmed into the TC (transfer count) register which is
>    decremented for each byte transferred, generating an interrupt when it reaches zero.
>    These patches add helper functions to read the TC and STC registers directly and
>    remove these synthetic variables so that the DMA transfer length is now tracked in
>    a single place.
> 
> - Now that the TC register represents the authoritative DMA transfer length, patches
>    12-20 work to eliminate the separate PDMA variables pdma_start, pdma_cur, pdma_len
>    and separate PDMA buffers PDMA and CMD. The PDMA position variables can be replaced
>    by the existing ESP cmdlen and ti_wptr/ti_rptr, whilst the FIFO (TI) buffer is used
>    for incoming data with commands being accumulated in cmdbuf as per standard DMA
>    requests.
> 
> - Patches 21 and 22 fix the detection of missing SCSI targets by the MacOS toolbox ROM
>    on startup at which point it will attempt to start reading information from a CDROM
>    attached to the q800 machine.
> 
> - Patch 23 is the main rework of the PDMA buffer transfers: instead of tracking the
>    SCSI transfers using a separate ASYNC pdma_origin, the contents of the ESPState
>    async_buf are copied to the FIFO buffer in 16-byte chunks with the transfer status
>    and IRQs being set accordingly.
> 
> - Patch 24 removes the last separate PDMA variable pdma_origin, including the separate
>    PDMA migration subsection which is no longer required (see note below about migration
>    compatibility).
>    
> - Finally patch 25 enables 4 byte PDMA reads/writes over the SCSI bus which are used
>    by MacOS when reading the next stage bootloader from CDROM (this is an increase from
>    2 bytes currently implemented and used by Linux).
> 
> 
> Testing
> =======
> 
> I've tested this on my SPARC32 OpenBIOS images which include Linux, OpenBSD, NetBSD,
> and Solaris and all of these continue to boot as before.
> 
> Similarly the q800 m68k Linux test image still boots as before with these patches
> applied. It is possible with lots of hacks to load Laurent's EMILE bootloader using
> a MacOS toolbox ROM - the hope is to try and start upstreaming more of these changes
> as time allows.
> 
> 
> Migration
> =========
> 
> The patchset ensures that ESP devices without PDMA (i.e. everything except the q800
> machine) will migrate successfully. This is fairly simple: the only change required
> here is to copy the old synthetic dma_left value over into the TC.
> 
> Unfortunately migrating the PDMA subsection is a lot harder due to the change in the
> way that the DMA TC and changes to the point at which transfer counters are updated.
> For this reason the patchset will not migrate from older q800 snapshots: I don't
> believe this to be a problem since some devices are still missing VMStateDescription
> plus there are likely to be more breaking changes as the q800 machine matures.
> 
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> 
> 
> Mark Cave-Ayland (25):
>    esp: checkpatch fixes
>    esp: add trace event when receiving a TI command
>    esp: fix esp_reg_read() trace event
>    esp: add PDMA trace events
>    esp: determine transfer direction directly from SCSI phase
>    esp: introduce esp_get_tc() and esp_set_tc()
>    esp: introduce esp_get_stc()
>    esp: apply transfer length adjustment when STC is zero at TC load time
>    esp: remove dma_counter from ESPState
>    esp: remove dma_left from ESPState
>    esp: remove minlen restriction in handle_ti
>    esp: introduce esp_pdma_read() and esp_pdma_write() functions
>    esp: use pdma_origin directly in esp_pdma_read()/esp_pdma_write()
>    esp: move pdma_len and TC logic into esp_pdma_read()/esp_pdma_write()
>    esp: accumulate SCSI commands for PDMA transfers in cmdbuf instead of
>      pdma_buf
>    esp: remove redundant pdma_start from ESPState
>    esp: move PDMA length adjustments into
>      esp_pdma_read()/esp_pdma_write()
>    esp: use ti_wptr/ti_rptr to manage the current FIFO position for PDMA
>    esp: use in-built TC to determine PDMA transfer length
>    esp: remove CMD pdma_origin
>    esp: rename get_cmd_cb() to esp_select()
>    esp: fix PDMA target selection
>    esp: use FIFO for PDMA transfers between initiator and device
>    esp: remove pdma_origin from ESPState
>    esp: add 4 byte PDMA read and write transfers
> 
>   hw/scsi/esp.c         | 461 +++++++++++++++++++++++++-----------------
>   hw/scsi/trace-events  |   5 +
>   include/hw/scsi/esp.h |  20 +-
>   3 files changed, 279 insertions(+), 207 deletions(-)
> 



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/25] esp: consolidate PDMA transfer buffers
  2021-01-13 14:39 ` Paolo Bonzini
@ 2021-01-13 19:29   ` Mark Cave-Ayland
  0 siblings, 0 replies; 35+ messages in thread
From: Mark Cave-Ayland @ 2021-01-13 19:29 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel, fam, laurent

On 13/01/2021 14:39, Paolo Bonzini wrote:

> On 30/12/20 16:37, Mark Cave-Ayland wrote:
>> This patch series comes from an experimental branch that I've been working on
>> to try and boot a MacOS toolbox ROM under the QEMU q800 machine. The effort is
>> far from complete, but it seems worth submitting these patches separately since
>> they are limited to the ESP device and form a substantial part of the work to
>> date.
>>
>> As part of Laurent's recent q800 work so-called PDMA (pseudo-DMA) support was
>> added to the ESP device. This is whereby the DREQ (DMA request) line is used
>> to signal to the host CPU that it can transfer data to/from the device over
>> the SCSI bus.
>>
>> The existing PDMA tracks 4 separate transfer data sources as indicated by the
>> ESP pdma_origin variable: PDMA, TI, CMD and ASYNC with an independent variable
>> pdma_len to store the transfer length. This works well with Linux which uses a
>> single PDMA request to transfer a number of sectors in a single request.
>>
>> Unfortunately the MacOS toolbox ROM has other ideas here: it sends data to the
>> ESP as a mixture of FIFO and PDMA transfers and then uses a mixture of the FIFO
>> and DMA counters to confirm that the correct number of bytes have been
>> transferred. For this to work correctly the PDMA buffers and separate pdma_len
>> transfer counter must be consolidated into the FIFO to allow mixing of both
>> types of transfer within a single request.
> 
> This is all esp.c, so if Laurent and you are fine just send a pull request.
> 
> Thanks!
> 
> Paolo

I sent a self-nak a little while back because I found an issue with address alignment 
in some requests coming from the MacOS toolbox ROM. I think I now understand what the 
issue is, so I hope to post a v2 with this fixed soon.


ATB,

Mark.


^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2021-01-13 19:37 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-30 15:37 [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 01/25] esp: checkpatch fixes Mark Cave-Ayland
2021-01-01 16:53   ` Philippe Mathieu-Daudé
2020-12-30 15:37 ` [PATCH 02/25] esp: add trace event when receiving a TI command Mark Cave-Ayland
2021-01-01 16:54   ` Philippe Mathieu-Daudé
2020-12-30 15:37 ` [PATCH 03/25] esp: fix esp_reg_read() trace event Mark Cave-Ayland
2021-01-01 16:54   ` Philippe Mathieu-Daudé
2020-12-30 15:37 ` [PATCH 04/25] esp: add PDMA trace events Mark Cave-Ayland
2021-01-01 16:55   ` Philippe Mathieu-Daudé
2020-12-30 15:37 ` [PATCH 05/25] esp: determine transfer direction directly from SCSI phase Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 06/25] esp: introduce esp_get_tc() and esp_set_tc() Mark Cave-Ayland
2021-01-01 16:56   ` Philippe Mathieu-Daudé
2020-12-30 15:37 ` [PATCH 07/25] esp: introduce esp_get_stc() Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 08/25] esp: apply transfer length adjustment when STC is zero at TC load time Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 09/25] esp: remove dma_counter from ESPState Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 10/25] esp: remove dma_left " Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 11/25] esp: remove minlen restriction in handle_ti Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 12/25] esp: introduce esp_pdma_read() and esp_pdma_write() functions Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 13/25] esp: use pdma_origin directly in esp_pdma_read()/esp_pdma_write() Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 14/25] esp: move pdma_len and TC logic into esp_pdma_read()/esp_pdma_write() Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 15/25] esp: accumulate SCSI commands for PDMA transfers in cmdbuf instead of pdma_buf Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 16/25] esp: remove redundant pdma_start from ESPState Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 17/25] esp: move PDMA length adjustments into esp_pdma_read()/esp_pdma_write() Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 18/25] esp: use ti_wptr/ti_rptr to manage the current FIFO position for PDMA Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 19/25] esp: use in-built TC to determine PDMA transfer length Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 20/25] esp: remove CMD pdma_origin Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 21/25] esp: rename get_cmd_cb() to esp_select() Mark Cave-Ayland
2021-01-01 16:57   ` Philippe Mathieu-Daudé
2020-12-30 15:37 ` [PATCH 22/25] esp: fix PDMA target selection Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 23/25] esp: use FIFO for PDMA transfers between initiator and device Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 24/25] esp: remove pdma_origin from ESPState Mark Cave-Ayland
2020-12-30 15:37 ` [PATCH 25/25] esp: add 4 byte PDMA read and write transfers Mark Cave-Ayland
2021-01-06 15:18 ` [PATCH 00/25] esp: consolidate PDMA transfer buffers Mark Cave-Ayland
2021-01-13 14:39 ` Paolo Bonzini
2021-01-13 19:29   ` Mark Cave-Ayland

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).