Patchwork [19/22] PPC: dbdma: Wait for DMA until we have data

login
register
mail settings
Submitter Alexander Graf
Date July 11, 2013, 5:01 p.m.
Message ID <1373562085-29728-20-git-send-email-agraf@suse.de>
Download mbox | patch
Permalink /patch/258590/
State New
Headers show

Comments

Alexander Graf - July 11, 2013, 5:01 p.m.
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>
---
 hw/ide/macio.c | 19 +++++++++++++++++++
 hw/ppc/mac.h   |  1 +
 2 files changed, 20 insertions(+)

Patch

diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 126549d..2b1e51d 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 27c4ca3..1e578dd 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);