summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2013-06-30 02:54:35 +0200
committerAlexander Graf <agraf@suse.de>2013-07-11 18:51:25 +0200
commitcae323572eddc1a45e2f6ef98c006d98fed23b1e (patch)
treec433a66f0b4b9acd23d3ce3c08d5980795c4eed3
parent03ee3b1e58266c7e5b155d58f443d94b23d2bd05 (diff)
downloadqemu-cae323572eddc1a45e2f6ef98c006d98fed23b1e.zip
PPC: dbdma: Wait for DMA until we have data
We should only start processing DMA requests when we have data to process. Hold off working through the DMA shuffling until the IDE core told us that it's ready. This is required because the guest can program the DMA engine or the IDE transfer first. Both are legal. Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r--hw/ide/macio.c19
-rw-r--r--hw/ppc/mac.h1
2 files changed, 20 insertions, 0 deletions
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 126549dcdc..2b1e51d49e 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -64,6 +64,14 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
goto done;
}
+ if (!m->dma_active) {
+ MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n",
+ s->nsector, io->len, s->status);
+ /* data not ready yet, wait for the channel to get restarted */
+ io->processing = false;
+ return;
+ }
+
MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size);
if (s->io_buffer_size > 0) {
@@ -80,6 +88,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
if (s->packet_transfer_size <= 0) {
MACIO_DPRINTF("end of transfer\n");
ide_atapi_cmd_ok(s);
+ m->dma_active = false;
}
if (io->len == 0) {
@@ -130,6 +139,14 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
goto done;
}
+ if (!m->dma_active) {
+ MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n",
+ s->nsector, io->len, s->status);
+ /* data not ready yet, wait for the channel to get restarted */
+ io->processing = false;
+ return;
+ }
+
sector_num = ide_get_sector(s);
MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size);
if (s->io_buffer_size > 0) {
@@ -145,6 +162,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
MACIO_DPRINTF("end of transfer\n");
s->status = READY_STAT | SEEK_STAT;
ide_set_irq(s->bus);
+ m->dma_active = false;
}
if (io->len == 0) {
@@ -379,6 +397,7 @@ static void ide_dbdma_start(IDEDMA *dma, IDEState *s,
MACIOIDEState *m = container_of(dma, MACIOIDEState, dma);
MACIO_DPRINTF("\n");
+ m->dma_active = true;
DBDMA_kick(m->dbdma);
}
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index 27c4ca39be..1e578dd59d 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -133,6 +133,7 @@ typedef struct MACIOIDEState {
BlockDriverAIOCB *aiocb;
IDEDMA dma;
void *dbdma;
+ bool dma_active;
} MACIOIDEState;
void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table);