summaryrefslogtreecommitdiff
path: root/hw/ide/macio.c
diff options
context:
space:
mode:
authorMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>2014-05-18 13:20:55 +0100
committerAlexander Graf <agraf@suse.de>2014-06-16 13:24:36 +0200
commit85720d36676ef0b765a69f1e312b4c9d4ff6fa16 (patch)
tree2417d66867d722d96ec7e5f9dfc4b3a5161cd44e /hw/ide/macio.c
parent10582ff832798813ba3a17f13f3ab46250388b47 (diff)
downloadqemu-85720d36676ef0b765a69f1e312b4c9d4ff6fa16.tar.gz
qemu-85720d36676ef0b765a69f1e312b4c9d4ff6fa16.tar.bz2
qemu-85720d36676ef0b765a69f1e312b4c9d4ff6fa16.zip
macio: handle non-block ATAPI DMA transfers
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> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'hw/ide/macio.c')
-rw-r--r--hw/ide/macio.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 1c20616f5a..af57168db3 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;