diff --git a/hw/ide.h b/hw/ide.h
index 7e23cda..9b357c0 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -19,10 +19,6 @@ PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
 
-/* ide-macio.c */
-MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
-		   void *dbdma, int channel, qemu_irq dma_irq);
-
 /* ide-mmio.c */
 void mmio_ide_init (hwaddr membase, hwaddr membase2,
                     MemoryRegion *address_space,
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index e0f04dc..375c46f 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -33,12 +33,6 @@
 /***********************************************************/
 /* MacIO based PowerPC IDE */
 
-typedef struct MACIOIDEState {
-    MemoryRegion mem;
-    IDEBus bus;
-    BlockDriverAIOCB *aiocb;
-} MACIOIDEState;
-
 #define MACIO_PAGE_SIZE 4096
 
 static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
@@ -321,30 +315,70 @@ static const VMStateDescription vmstate_pmac = {
     }
 };
 
-static void pmac_ide_reset(void *opaque)
+static void macio_ide_reset(DeviceState *dev)
 {
-    MACIOIDEState *d = opaque;
+    MACIOIDEState *d = MACIO_IDE(dev);
 
     ide_bus_reset(&d->bus);
 }
 
-/* hd_table must contain 4 block drivers */
-/* PowerMac uses memory mapped registers, not I/O. Return the memory
-   I/O index to access the ide. */
-MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
-                             void *dbdma, int channel, qemu_irq dma_irq)
+static void macio_ide_realizefn(DeviceState *dev, Error **errp)
 {
-    MACIOIDEState *d;
+    MACIOIDEState *s = MACIO_IDE(dev);
+
+    ide_init2(&s->bus, s->irq);
+}
+
+static void macio_ide_initfn(Object *obj)
+{
+    SysBusDevice *d = SYS_BUS_DEVICE(obj);
+    MACIOIDEState *s = MACIO_IDE(obj);
+
+    ide_bus_new(&s->bus, DEVICE(obj), 0);
+    memory_region_init_io(&s->mem, &pmac_ide_ops, s, "pmac-ide", 0x1000);
+    sysbus_init_mmio(d, &s->mem);
+    sysbus_init_irq(d, &s->irq);
+    sysbus_init_irq(d, &s->dma_irq);
+}
+
+static void macio_ide_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = macio_ide_realizefn;
+    dc->reset = macio_ide_reset;
+    dc->vmsd = &vmstate_pmac;
+}
 
-    d = g_malloc0(sizeof(MACIOIDEState));
-    ide_init2_with_non_qdev_drives(&d->bus, hd_table[0], hd_table[1], irq);
+static const TypeInfo macio_ide_type_info = {
+    .name = TYPE_MACIO_IDE,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MACIOIDEState),
+    .instance_init = macio_ide_initfn,
+    .class_init = macio_ide_class_init,
+};
 
-    if (dbdma)
-        DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, pmac_ide_flush, d);
+static void macio_ide_register_types(void)
+{
+    type_register_static(&macio_ide_type_info);
+}
 
-    memory_region_init_io(&d->mem, &pmac_ide_ops, d, "pmac-ide", 0x1000);
-    vmstate_register(NULL, 0, &vmstate_pmac, d);
-    qemu_register_reset(pmac_ide_reset, d);
+/* hd_table must contain 4 block drivers */
+void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table)
+{
+    int i;
 
-    return &d->mem;
+    for (i = 0; i < 2; i++) {
+        if (hd_table[i]) {
+            ide_create_drive(&s->bus, i, hd_table[i]);
+        }
+    }
 }
+
+void macio_ide_register_dma(MACIOIDEState *s, void *dbdma, int channel)
+{
+    DBDMA_register_channel(dbdma, channel, s->dma_irq,
+                           pmac_ide_transfer, pmac_ide_flush, s);
+}
+
+type_init(macio_ide_register_types)
diff --git a/hw/macio.c b/hw/macio.c
index 32f359c..36c00e3 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -25,6 +25,7 @@
 #include "hw.h"
 #include "ppc/mac.h"
 #include "pci/pci.h"
+#include "mac_dbdma.h"
 #include "escc.h"
 
 #define TYPE_MACIO "macio"
@@ -37,12 +38,10 @@ typedef struct MacIOState
     /*< public >*/
 
     MemoryRegion bar;
+    void *dbdma;
     MemoryRegion *pic_mem;
-    MemoryRegion *dbdma_mem;
     MemoryRegion *cuda_mem;
     MemoryRegion *escc_mem;
-    int nb_ide;
-    MemoryRegion *ide_mem[4];
 } MacIOState;
 
 #define OLDWORLD_MACIO(obj) \
@@ -53,29 +52,33 @@ typedef struct OldWorldMacIOState {
     MacIOState parent_obj;
     /*< public >*/
 
+    qemu_irq irqs[2];
+
     MacIONVRAMState nvram;
+    MACIOIDEState ide;
 } OldWorldMacIOState;
 
+#define NEWWORLD_MACIO(obj) \
+    OBJECT_CHECK(NewWorldMacIOState, (obj), TYPE_NEWWORLD_MACIO)
+
+typedef struct NewWorldMacIOState {
+    /*< private >*/
+    MacIOState parent_obj;
+    /*< public >*/
+    qemu_irq irqs[4];
+    MACIOIDEState ide[2];
+} NewWorldMacIOState;
+
 static void macio_bar_setup(MacIOState *macio_state)
 {
-    int i;
     MemoryRegion *bar = &macio_state->bar;
 
-    if (macio_state->dbdma_mem) {
-        memory_region_add_subregion(bar, 0x08000, macio_state->dbdma_mem);
-    }
     if (macio_state->escc_mem) {
         memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem);
     }
     if (macio_state->cuda_mem) {
         memory_region_add_subregion(bar, 0x16000, macio_state->cuda_mem);
     }
-    for (i = 0; i < macio_state->nb_ide; i++) {
-        if (macio_state->ide_mem[i]) {
-            memory_region_add_subregion(bar, 0x1f000 + (i * 0x1000),
-                                        macio_state->ide_mem[i]);
-        }
-    }
 }
 
 static int macio_common_initfn(PCIDevice *d)
@@ -114,23 +117,42 @@ static int macio_oldworld_initfn(PCIDevice *d)
         memory_region_add_subregion(&s->bar, 0x00000, s->pic_mem);
     }
 
+    sysbus_dev = SYS_BUS_DEVICE(&os->ide);
+    sysbus_connect_irq(sysbus_dev, 0, os->irqs[0]);
+    sysbus_connect_irq(sysbus_dev, 1, os->irqs[1]);
+    macio_ide_register_dma(&os->ide, s->dbdma, 0x16);
+    ret = qdev_init(DEVICE(&os->ide));
+    if (ret < 0) {
+        return ret;
+    }
+
     return 0;
 }
 
 static void macio_oldworld_init(Object *obj)
 {
+    MacIOState *s = MACIO(obj);
     OldWorldMacIOState *os = OLDWORLD_MACIO(obj);
     DeviceState *dev;
 
+    qdev_init_gpio_out(DEVICE(obj), os->irqs, ARRAY_SIZE(os->irqs));
+
     object_initialize(&os->nvram, TYPE_MACIO_NVRAM);
     dev = DEVICE(&os->nvram);
     qdev_prop_set_uint32(dev, "size", 0x2000);
     qdev_prop_set_uint32(dev, "it_shift", 4);
+
+    object_initialize(&os->ide, TYPE_MACIO_IDE);
+    qdev_set_parent_bus(DEVICE(&os->ide), sysbus_get_default());
+    memory_region_add_subregion(&s->bar, 0x1f000 + (1 * 0x1000), &os->ide.mem);
+    object_property_add_child(obj, "ide", OBJECT(&os->ide), NULL);
 }
 
 static int macio_newworld_initfn(PCIDevice *d)
 {
     MacIOState *s = MACIO(d);
+    NewWorldMacIOState *ns = NEWWORLD_MACIO(d);
+    SysBusDevice *sysbus_dev;
     int ret = macio_common_initfn(d);
     if (ret < 0) {
         return ret;
@@ -141,14 +163,56 @@ static int macio_newworld_initfn(PCIDevice *d)
         memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem);
     }
 
+    sysbus_dev = SYS_BUS_DEVICE(&ns->ide[0]);
+    sysbus_connect_irq(sysbus_dev, 0, ns->irqs[0]);
+    sysbus_connect_irq(sysbus_dev, 1, ns->irqs[1]);
+    macio_ide_register_dma(&ns->ide[0], s->dbdma, 0x16);
+    ret = qdev_init(DEVICE(&ns->ide[0]));
+    if (ret < 0) {
+        return ret;
+    }
+
+    sysbus_dev = SYS_BUS_DEVICE(&ns->ide[1]);
+    sysbus_connect_irq(sysbus_dev, 0, ns->irqs[2]);
+    sysbus_connect_irq(sysbus_dev, 1, ns->irqs[3]);
+    macio_ide_register_dma(&ns->ide[0], s->dbdma, 0x1a);
+    ret = qdev_init(DEVICE(&ns->ide[1]));
+    if (ret < 0) {
+        return ret;
+    }
+
     return 0;
 }
 
+static void macio_newworld_init(Object *obj)
+{
+    MacIOState *s = MACIO(obj);
+    NewWorldMacIOState *ns = NEWWORLD_MACIO(obj);
+    int i;
+    gchar *name;
+
+    qdev_init_gpio_out(DEVICE(obj), ns->irqs, ARRAY_SIZE(ns->irqs));
+
+    for (i = 0; i < 2; i++) {
+        object_initialize(&ns->ide[i], TYPE_MACIO_IDE);
+        qdev_set_parent_bus(DEVICE(&ns->ide[i]), sysbus_get_default());
+        memory_region_add_subregion(&s->bar, 0x1f000 + ((i + 1) * 0x1000),
+                                    &ns->ide[i].mem);
+        name = g_strdup_printf("ide[%i]", i);
+        object_property_add_child(obj, name, OBJECT(&ns->ide[i]), NULL);
+        g_free(name);
+    }
+}
+
 static void macio_instance_init(Object *obj)
 {
     MacIOState *s = MACIO(obj);
+    MemoryRegion *dbdma_mem;
 
     memory_region_init(&s->bar, "macio", 0x80000);
+
+    s->dbdma = DBDMA_init(&dbdma_mem);
+    memory_region_add_subregion(&s->bar, 0x08000, dbdma_mem);
 }
 
 static void macio_oldworld_class_init(ObjectClass *oc, void *data)
@@ -186,6 +250,8 @@ static const TypeInfo macio_oldworld_type_info = {
 static const TypeInfo macio_newworld_type_info = {
     .name          = TYPE_NEWWORLD_MACIO,
     .parent        = TYPE_MACIO,
+    .instance_size = sizeof(NewWorldMacIOState),
+    .instance_init = macio_newworld_init,
     .class_init    = macio_newworld_class_init,
 };
 
@@ -208,23 +274,15 @@ static void macio_register_types(void)
 type_init(macio_register_types)
 
 void macio_init(PCIDevice *d,
-                MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+                MemoryRegion *pic_mem,
                 MemoryRegion *cuda_mem,
-                int nb_ide, MemoryRegion **ide_mem,
                 MemoryRegion *escc_mem)
 {
     MacIOState *macio_state = MACIO(d);
-    int i;
 
     macio_state->pic_mem = pic_mem;
-    macio_state->dbdma_mem = dbdma_mem;
     macio_state->cuda_mem = cuda_mem;
     macio_state->escc_mem = escc_mem;
-    if (nb_ide > 4)
-        nb_ide = 4;
-    macio_state->nb_ide = nb_ide;
-    for (i = 0; i < nb_ide; i++)
-        macio_state->ide_mem[i] = ide_mem[i];
     /* Note: this code is strongly inspirated from the corresponding code
        in PearPC */
 
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index 581e95c..3e390d3 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -27,6 +27,7 @@
 
 #include "exec/memory.h"
 #include "hw/sysbus.h"
+#include "hw/ide/internal.h"
 
 /* SMP is not enabled, for now */
 #define MAX_CPUS 1
@@ -48,10 +49,30 @@ void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq);
 /* MacIO */
 #define TYPE_OLDWORLD_MACIO "macio-oldworld"
 #define TYPE_NEWWORLD_MACIO "macio-newworld"
+
+#define TYPE_MACIO_IDE "macio-ide"
+#define MACIO_IDE(obj) OBJECT_CHECK(MACIOIDEState, (obj), TYPE_MACIO_IDE)
+
+typedef struct MACIOIDEState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    qemu_irq irq;
+    qemu_irq dma_irq;
+
+    MemoryRegion mem;
+    IDEBus bus;
+    BlockDriverAIOCB *aiocb;
+} MACIOIDEState;
+
+void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table);
+void macio_ide_register_dma(MACIOIDEState *ide, void *dbdma, int channel);
+
 void macio_init(PCIDevice *dev,
-                MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+                MemoryRegion *pic_mem,
                 MemoryRegion *cuda_mem,
-                int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem);
+                MemoryRegion *escc_mem);
 
 /* Heathrow PIC */
 qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index a4b38fb..4fd86b0 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -148,15 +148,14 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
     long kernel_size, initrd_size;
     PCIBus *pci_bus;
     PCIDevice *macio;
+    MACIOIDEState *macio_ide;
     MacIONVRAMState *nvr;
     int bios_size;
-    MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem, *escc_mem;
+    MemoryRegion *pic_mem, *cuda_mem, *escc_mem;
     MemoryRegion *escc_bar = g_new(MemoryRegion, 1);
-    MemoryRegion *ide_mem[3];
     int ppc_boot_device;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     void *fw_cfg;
-    void *dbdma;
     int machine_arch;
     SysBusDevice *s;
     DeviceState *dev;
@@ -363,12 +362,6 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
         pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
 
     ide_drive_get(hd, MAX_IDE_BUS);
-    dbdma = DBDMA_init(&dbdma_mem);
-
-    /* We only emulate 2 out of 3 IDE controllers for now */
-    ide_mem[0] = NULL;
-    ide_mem[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]);
-    ide_mem[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]);
 
     cuda_init(&cuda_mem, pic[0x19]);
 
@@ -376,8 +369,21 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
     adb_mouse_init(&adb_bus);
 
     macio = pci_create(pci_bus, -1, TYPE_NEWWORLD_MACIO);
-    macio_init(macio, pic_mem,
-               dbdma_mem, cuda_mem, 3, ide_mem, escc_bar);
+    dev = DEVICE(macio);
+    qdev_connect_gpio_out(dev, 0, pic[0x0d]); /* IDE */
+    qdev_connect_gpio_out(dev, 1, pic[0x02]); /* IDE DMA */
+    qdev_connect_gpio_out(dev, 2, pic[0x0e]); /* IDE */
+    qdev_connect_gpio_out(dev, 3, pic[0x02]); /* IDE DMA */
+    macio_init(macio, pic_mem, cuda_mem, escc_bar);
+
+    /* We only emulate 2 out of 3 IDE controllers for now */
+    macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
+                                                        "ide[0]"));
+    macio_ide_init_drives(macio_ide, hd);
+
+    macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
+                                                        "ide[1]"));
+    macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]);
 
     if (usb_enabled(machine_arch == ARCH_MAC99_U3)) {
         pci_create_simple(pci_bus, -1, "pci-ohci");
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 29b3277..6039ea6 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -27,7 +27,6 @@
 #include "hw/ppc.h"
 #include "mac.h"
 #include "hw/adb.h"
-#include "hw/mac_dbdma.h"
 #include "hw/nvram.h"
 #include "sysemu/sysemu.h"
 #include "net/net.h"
@@ -91,13 +90,14 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
     int32_t kernel_size, initrd_size;
     PCIBus *pci_bus;
     PCIDevice *macio;
+    MACIOIDEState *macio_ide;
+    DeviceState *dev;
     int bios_size;
-    MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem;
-    MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1), *ide_mem[2];
+    MemoryRegion *pic_mem, *cuda_mem;
+    MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1);
     uint16_t ppc_boot_device;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     void *fw_cfg;
-    void *dbdma;
 
     linux_boot = (kernel_filename != NULL);
 
@@ -263,17 +263,6 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
 
     ide_drive_get(hd, MAX_IDE_BUS);
 
-    /* First IDE channel is a MAC IDE on the MacIO bus */
-    dbdma = DBDMA_init(&dbdma_mem);
-    ide_mem[0] = NULL;
-    ide_mem[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
-
-    /* Second IDE channel is a CMD646 on the PCI bus */
-    hd[0] = hd[MAX_IDE_DEVS];
-    hd[1] = hd[MAX_IDE_DEVS + 1];
-    hd[3] = hd[2] = NULL;
-    pci_cmd646_ide_init(pci_bus, hd, 0);
-
     /* cuda also initialize ADB */
     cuda_init(&cuda_mem, pic[0x12]);
 
@@ -281,8 +270,21 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
     adb_mouse_init(&adb_bus);
 
     macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO);
-    macio_init(macio, pic_mem,
-               dbdma_mem, cuda_mem, 2, ide_mem, escc_bar);
+    dev = DEVICE(macio);
+    qdev_connect_gpio_out(dev, 0, pic[0x0D]); /* IDE */
+    qdev_connect_gpio_out(dev, 1, pic[0x02]); /* IDE DMA */
+    macio_init(macio, pic_mem, cuda_mem, escc_bar);
+
+    /* First IDE channel is a MAC IDE on the MacIO bus */
+    macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
+                                                        "ide"));
+    macio_ide_init_drives(macio_ide, hd);
+
+    /* Second IDE channel is a CMD646 on the PCI bus */
+    hd[0] = hd[MAX_IDE_DEVS];
+    hd[1] = hd[MAX_IDE_DEVS + 1];
+    hd[3] = hd[2] = NULL;
+    pci_cmd646_ide_init(pci_bus, hd, 0);
 
     if (usb_enabled(false)) {
         pci_create_simple(pci_bus, -1, "pci-ohci");
