Patchwork [RFC,09/10] ide: Allow to reconfigure ISA I/O base

login
register
mail settings
Submitter Andreas Färber
Date June 6, 2011, 4:20 p.m.
Message ID <1307377259-41434-10-git-send-email-andreas.faerber@web.de>
Download mbox | patch
Permalink /patch/99007/
State New
Headers show

Comments

Andreas Färber - June 6, 2011, 4:20 p.m.
Signed-off-by: Andreas Färber <andreas.faerber@web.de>
---
 hw/ide.h          |    1 +
 hw/ide/core.c     |    8 ++++++++
 hw/ide/internal.h |    1 +
 hw/ide/isa.c      |   28 +++++++++++++++++++++++++---
 4 files changed, 35 insertions(+), 3 deletions(-)

Patch

diff --git a/hw/ide.h b/hw/ide.h
index 34d9394..25b46a7 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -9,6 +9,7 @@ 
 /* ide-isa.c */
 ISADevice *isa_ide_init(int iobase, int iobase2, int isairq,
                         DriveInfo *hd0, DriveInfo *hd1);
+void isa_ide_reconfigure_iobase(ISADevice *dev, uint32_t iobase, uint32_t iobase2);
 
 /* ide-pci.c */
 void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 45410e8..c3b82de 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1760,6 +1760,14 @@  void ide_init_ioport(IDEBus *bus, int iobase, int iobase2)
     register_ioport_read(iobase, 4, 4, ide_data_readl, bus);
 }
 
+void ide_discard_ioport(int iobase, int iobase2)
+{
+    isa_unassign_ioport(iobase, 8);
+    if (iobase2 != 0) {
+        isa_unassign_ioport(iobase2, 1);
+    }
+}
+
 static bool is_identify_set(void *opaque, int version_id)
 {
     IDEState *s = opaque;
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index c2b35ec..dc0a2c9 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -564,6 +564,7 @@  void ide_init2(IDEBus *bus, qemu_irq irq);
 void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
                                     DriveInfo *hd1, qemu_irq irq);
 void ide_init_ioport(IDEBus *bus, int iobase, int iobase2);
+void ide_discard_ioport(int iobase, int iobase2);
 
 void ide_exec_cmd(IDEBus *bus, uint32_t val);
 void ide_dma_cb(void *opaque, int ret);
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 4ac7453..d1f81d7 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -62,15 +62,37 @@  static const VMStateDescription vmstate_ide_isa = {
     }
 };
 
+static void isa_ide_init_iobase(ISAIDEState *s)
+{
+    ide_init_ioport(&s->bus, s->iobase, s->iobase2);
+
+    isa_init_ioport_range(&s->dev, s->iobase, 8);
+    isa_init_ioport(&s->dev, s->iobase2);
+}
+
+void isa_ide_reconfigure_iobase(ISADevice *dev, uint32_t iobase, uint32_t iobase2)
+{
+    ISAIDEState *s = DO_UPCAST(ISAIDEState, dev, dev);
+
+    if (iobase != s->iobase || iobase2 != s->iobase2) {
+        ide_discard_ioport(s->iobase, s->iobase2);
+
+        isa_discard_ioport_range(dev, s->iobase2, 1);
+        isa_discard_ioport_range(dev, s->iobase, 8);
+
+        s->iobase = iobase;
+        s->iobase2 = iobase2;
+        isa_ide_init_iobase(s);
+    }
+}
+
 static int isa_ide_initfn(ISADevice *dev)
 {
     ISAIDEState *s = DO_UPCAST(ISAIDEState, dev, dev);
 
     ide_bus_new(&s->bus, &s->dev.qdev, 0);
-    ide_init_ioport(&s->bus, s->iobase, s->iobase2);
+    isa_ide_init_iobase(s);
     isa_init_irq(dev, &s->irq, s->isairq);
-    isa_init_ioport_range(dev, s->iobase, 8);
-    isa_init_ioport(dev, s->iobase2);
     ide_init2(&s->bus, s->irq);
     vmstate_register(&dev->qdev, 0, &vmstate_ide_isa, s);
     return 0;