diff mbox

macio: handle non-block ATAPI DMA transfers

Message ID 1400415655-8066-1-git-send-email-mark.cave-ayland@ilande.co.uk
State New
Headers show

Commit Message

Mark Cave-Ayland May 18, 2014, 12:20 p.m. UTC
Currently the macio DMA routines assume that all DMA requests are for read/write
block transfers. This is not always the case for ATAPI, for example when
requesting a TOC where the response is generated directly in the IDE buffer.

Detect these non-block ATAPI DMA transfers (where no lba is specified in the
command) and copy the results directly into RAM as indicated by the DBDMA
descriptor. This fixes CDROM access under MorphOS.

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

Comments

Alexander Graf May 19, 2014, 9:18 a.m. UTC | #1
On 18.05.14 14:20, Mark Cave-Ayland wrote:
> Currently the macio DMA routines assume that all DMA requests are for read/write
> block transfers. This is not always the case for ATAPI, for example when
> requesting a TOC where the response is generated directly in the IDE buffer.
>
> Detect these non-block ATAPI DMA transfers (where no lba is specified in the
> command) and copy the results directly into RAM as indicated by the DBDMA
> descriptor. This fixes CDROM access under MorphOS.
>
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

Thanks, applied to ppc-next.


Alex
diff mbox

Patch

diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 1c20616..af57168 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -337,6 +337,27 @@  static void pmac_ide_transfer(DBDMA_io *io)
 
     s->io_buffer_size = 0;
     if (s->drive_kind == IDE_CD) {
+
+        /* Handle non-block ATAPI DMA transfers */
+        if (s->lba == -1) {
+            s->io_buffer_size = MIN(io->len, s->packet_transfer_size);
+            bdrv_acct_start(s->bs, &s->acct, s->io_buffer_size,
+                            BDRV_ACCT_READ);
+            MACIO_DPRINTF("non-block ATAPI DMA transfer size: %d\n",
+                          s->io_buffer_size);
+
+            /* Copy ATAPI buffer directly to RAM and finish */
+            cpu_physical_memory_write(io->addr, s->io_buffer,
+                                      s->io_buffer_size);
+            ide_atapi_cmd_ok(s);
+            m->dma_active = false;
+
+            MACIO_DPRINTF("end of non-block ATAPI DMA transfer\n");
+            bdrv_acct_done(s->bs, &s->acct);
+            io->dma_end(io);
+            return;
+        }
+
         bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ);
         pmac_ide_atapi_transfer_cb(io, 0);
         return;