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-ayl...@ilande.co.uk> --- v2: add missing goto hw/ide/macio.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/ide/macio.c b/hw/ide/macio.c index a55a479..bd245e9 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -247,8 +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; + + /* 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); goto done; } -- 1.7.10.4