Patchwork [04/13] bmdma: split out irq setting

login
register
mail settings
Submitter Alexander Graf
Date Dec. 8, 2010, 12:13 p.m.
Message ID <1291810400-11309-5-git-send-email-agraf@suse.de>
Download mbox | patch
Permalink /patch/74695/
State New
Headers show

Comments

Alexander Graf - Dec. 8, 2010, 12:13 p.m.
The IDE core doesn't care about BMDMA blocking IRQs from getting submitted,
so let's reflect that in the code and make IRQ blocking fully transparent.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ide/core.c     |    6 ------
 hw/ide/internal.h |    4 ++--
 hw/ide/pci.c      |   44 +++++++++++++++++++++++++++-----------------
 3 files changed, 29 insertions(+), 25 deletions(-)

Patch

diff --git a/hw/ide/core.c b/hw/ide/core.c
index fce994f..6284539 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2586,18 +2586,12 @@  static void ide_init1(IDEBus *bus, int unit)
                                            ide_sector_write_timer_cb, s);
 }
 
-static int ide_nop_start_irq(void *opaque)
-{
-    return 1;
-}
-
 static int ide_nop(void *opaque)
 {
     return 0;
 }
 
 static const IDEDMAOps ide_dma_nop = {
-    .start_irq      = ide_nop_start_irq,
     .start_dma      = (void*)ide_nop,
     .start_transfer = (void*)ide_nop,
     .prepare_buf    = (void*)ide_nop,
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 15ab119..af7e741 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -457,7 +457,6 @@  struct IDEState {
 };
 
 struct IDEDMAOps {
-    DMAFunc *start_irq;
     DMAStartFunc *start_dma;
     DMAFunc *start_transfer;
     DMAIntFunc *prepare_buf;
@@ -530,6 +529,7 @@  struct BMDMAState {
     uint32_t nsector;
     IORange addr_ioport;
     QEMUBH *bh;
+    qemu_irq irq;
 };
 
 static inline IDEState *idebus_active_if(IDEBus *bus)
@@ -545,7 +545,7 @@  static inline IDEState *bmdma_active_if(BMDMAState *bmdma)
 
 static inline void ide_set_irq(IDEBus *bus)
 {
-    if (bus->dma.ops->start_irq(bus->dma.opaque)) {
+    if (!(bus->cmd & IDE_CMD_DISABLE_IRQ)) {
         qemu_irq_raise(bus->irq);
     }
 }
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 2506cc5..270c13a 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -35,22 +35,6 @@ 
 
 #define BMDMA_PAGE_SIZE 4096
 
-static int bmdma_start_irq(void *opaque)
-{
-    BMDMAState *bm = opaque;
-    IDEBus *bus = bm->bus;
-
-    if (!(bus->cmd & IDE_CMD_DISABLE_IRQ)) {
-        if (bm) {
-            bm->status |= BM_STATUS_INT;
-        }
-        return 1;
-    }
-
-    /* IRQ forbidden */
-    return 0;
-}
-
 static void bmdma_start_dma(void *opaque, IDEState *s,
                             BlockDriverCompletionFunc *dma_cb)
 {
@@ -286,6 +270,24 @@  static int bmdma_start_transfer(void *opaque)
     return 0;
 }
 
+static void bmdma_irq(void *opaque, int n, int level)
+{
+    BMDMAState *bm = opaque;
+
+    if (!level) {
+        /* pass through lower */
+        qemu_set_irq(bm->irq, level);
+        return;
+    }
+
+    if (bm) {
+        bm->status |= BM_STATUS_INT;
+    }
+
+    /* trigger the real irq */
+    qemu_set_irq(bm->irq, level);
+}
+
 void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
 {
     BMDMAState *bm = opaque;
@@ -453,7 +455,6 @@  void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table)
 }
 
 static const struct IDEDMAOps bmdma_ops = {
-    .start_irq = bmdma_start_irq,
     .start_dma = bmdma_start_dma,
     .start_transfer = bmdma_start_transfer,
     .prepare_buf = bmdma_prepare_buf,
@@ -467,6 +468,15 @@  static const struct IDEDMAOps bmdma_ops = {
 
 void bmdma_init(IDEBus *bus, BMDMAState *bm)
 {
+    qemu_irq *irq;
+
+    if (bus->dma.ops == &bmdma_ops) {
+        return;
+    }
+
     bus->dma.ops = &bmdma_ops;
     bus->dma.opaque = bm;
+    bm->irq = bus->irq;
+    irq = qemu_allocate_irqs(bmdma_irq, bm, 1);
+    bus->irq = *irq;
 }