diff mbox

macio: handle non-block ATAPI DMA transfers the same as block DMA transfers

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

Commit Message

Mark Cave-Ayland Aug. 1, 2015, 4:11 p.m. UTC
The existing code incorrectly changes the dma_active flag when a non-block
transfer has completed leading to a hang on newer versions of Linux because the
IDE and DMA engines deadlock waiting for each other.

Instead copy the buffer directly to RAM, set the remaining transfer size to 0 and
then invoke the ATAPI callback manually once again to correctly finish the
transfer in an identical manner to a block transfer.

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

Patch

diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index a55a479..2384533 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -247,9 +247,12 @@  static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
         /* Non-block ATAPI transfer - just copy to RAM */
         s->io_buffer_size = MIN(s->io_buffer_size, io->len);
         cpu_physical_memory_write(io->addr, s->io_buffer, s->io_buffer_size);
-        ide_atapi_cmd_ok(s);
-        m->dma_active = false;
-        goto done;
+
+        /* Invoke callback as we would at the end of a standard block 
+           transfer */
+        s->io_buffer_size = 0;
+        io->len = 0;
+        pmac_ide_atapi_transfer_cb(io, 0);
     }
 
     /* Calculate current offset */