qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 03/12] isa: Use realizefn for ISADevice


From: Andreas Färber
Subject: [Qemu-devel] [PATCH v2 03/12] isa: Use realizefn for ISADevice
Date: Fri, 7 Jun 2013 14:58:11 +0200

Drop ISADeviceClass::init and the resulting no-op initfn and let
children implement their own realizefn. Adapt error handling.
Split off an instance_init where sensible.

Signed-off-by: Andreas Färber <address@hidden>
---
 hw/audio/adlib.c         | 23 +++++++++++------------
 hw/audio/cs4231a.c       | 21 ++++++++++++++-------
 hw/audio/gus.c           | 18 +++++++++---------
 hw/audio/pcspk.c         | 19 ++++++++++++-------
 hw/audio/sb16.c          | 21 ++++++++++++++-------
 hw/block/fdc.c           | 24 ++++++++++++++----------
 hw/char/debugcon.c       | 23 ++++++++++++++---------
 hw/char/parallel.c       | 29 +++++++++++++++++------------
 hw/char/serial-isa.c     | 20 +++++++++++---------
 hw/char/serial-pci.c     | 17 +++++++++++++++--
 hw/char/serial.c         | 22 +++++++++++++++++-----
 hw/display/cirrus_vga.c  | 12 ++++++------
 hw/display/vga-isa.c     | 17 ++++++++---------
 hw/dma/i82374.c          | 13 +++++--------
 hw/i386/pc.c             | 19 +++++++++++++------
 hw/ide/isa.c             | 16 ++++++++--------
 hw/input/pckbd.c         | 29 ++++++++++++++++++-----------
 hw/input/vmmouse.c       |  8 +++-----
 hw/intc/i8259_common.c   |  9 +++------
 hw/isa/isa-bus.c         | 13 -------------
 hw/isa/pc87312.c         | 12 +++++-------
 hw/misc/applesmc.c       | 10 ++++------
 hw/misc/debugexit.c      | 10 +++++-----
 hw/misc/pc-testdev.c     | 11 +++++------
 hw/misc/pvpanic.c        | 19 ++++++++++++-------
 hw/misc/sga.c            |  7 +++----
 hw/misc/vmport.c         | 10 +++++-----
 hw/net/ne2000-isa.c      | 15 +++++++--------
 hw/timer/i8254_common.c  | 15 +++++++--------
 hw/timer/m48t59.c        | 22 +++++++++++++---------
 hw/timer/mc146818rtc.c   | 18 +++++++++---------
 hw/watchdog/wdt_ib700.c  |  8 +++-----
 include/hw/char/serial.h |  2 +-
 include/hw/isa/isa.h     |  1 -
 34 files changed, 291 insertions(+), 242 deletions(-)

diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c
index fc20857..6a7d377 100644
--- a/hw/audio/adlib.c
+++ b/hw/audio/adlib.c
@@ -283,21 +283,21 @@ static void Adlib_fini (AdlibState *s)
     AUD_remove_card (&s->card);
 }
 
-static int Adlib_initfn (ISADevice *dev)
+static void adlib_realizefn (DeviceState *dev, Error **errp)
 {
     AdlibState *s = ADLIB(dev);
     struct audsettings as;
 
     if (glob_adlib) {
-        dolog ("Cannot create more than 1 adlib device\n");
-        return -1;
+        error_setg (errp, "Cannot create more than 1 adlib device");
+        return;
     }
     glob_adlib = s;
 
 #ifdef HAS_YMF262
     if (YMF262Init (1, 14318180, s->freq)) {
-        dolog ("YMF262Init %d failed\n", s->freq);
-        return -1;
+        error_setg (errp, "YMF262Init %d failed", s->freq);
+        return;
     }
     else {
         YMF262SetTimerHandler (0, timer_handler, 0);
@@ -306,8 +306,8 @@ static int Adlib_initfn (ISADevice *dev)
 #else
     s->opl = OPLCreate (OPL_TYPE_YM3812, 3579545, s->freq);
     if (!s->opl) {
-        dolog ("OPLCreate %d failed\n", s->freq);
-        return -1;
+        error_setg (errp, "OPLCreate %d failed", s->freq);
+        return;
     }
     else {
         OPLSetTimerHandler (s->opl, timer_handler, 0);
@@ -332,7 +332,8 @@ static int Adlib_initfn (ISADevice *dev)
         );
     if (!s->voice) {
         Adlib_fini (s);
-        return -1;
+        error_setg (errp, "Initializing audio voice failed");
+        return;
     }
 
     s->samples = AUD_get_buffer_size_out (s->voice) >> SHIFT;
@@ -346,8 +347,6 @@ static int Adlib_initfn (ISADevice *dev)
 
     register_ioport_read (s->port + 8, 2, 1, adlib_read, s);
     register_ioport_write (s->port + 8, 2, 1, adlib_write, s);
-
-    return 0;
 }
 
 static Property adlib_properties[] = {
@@ -359,8 +358,8 @@ static Property adlib_properties[] = {
 static void adlib_class_initfn (ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS (klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS (klass);
-    ic->init = Adlib_initfn;
+
+    dc->realize = adlib_realizefn;
     dc->desc = ADLIB_DESC;
     dc->props = adlib_properties;
 }
diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c
index d3ce739..605dad4 100644
--- a/hw/audio/cs4231a.c
+++ b/hw/audio/cs4231a.c
@@ -644,19 +644,25 @@ static const MemoryRegionOps cs_ioport_ops = {
     }
 };
 
-static int cs4231a_initfn (ISADevice *dev)
+static void cs4231a_initfn (Object *obj)
 {
+    CSState *s = CS4231A (obj);
+
+    memory_region_init_io (&s->ioports, &cs_ioport_ops, s, "cs4231a", 4);
+}
+
+static void cs4231a_realizefn (DeviceState *dev, Error **errp)
+{
+    ISADevice *d = ISA_DEVICE (dev);
     CSState *s = CS4231A (dev);
 
-    isa_init_irq (dev, &s->pic, s->irq);
+    isa_init_irq (d, &s->pic, s->irq);
 
-    memory_region_init_io (&s->ioports, &cs_ioport_ops, s, "cs4231a", 4);
-    isa_register_ioport (dev, &s->ioports, s->port);
+    isa_register_ioport (d, &s->ioports, s->port);
 
     DMA_register_channel (s->dma, cs_dma_read, s);
 
     AUD_register_card ("cs4231a", &s->card);
-    return 0;
 }
 
 static int cs4231a_init (ISABus *bus)
@@ -675,8 +681,8 @@ static Property cs4231a_properties[] = {
 static void cs4231a_class_initfn (ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS (klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS (klass);
-    ic->init = cs4231a_initfn;
+
+    dc->realize = cs4231a_realizefn;
     dc->reset = cs4231a_reset;
     dc->desc = "Crystal Semiconductor CS4231A";
     dc->vmsd = &vmstate_cs4231a;
@@ -687,6 +693,7 @@ static const TypeInfo cs4231a_info = {
     .name          = TYPE_CS4231A,
     .parent        = TYPE_ISA_DEVICE,
     .instance_size = sizeof (CSState),
+    .instance_init = cs4231a_initfn,
     .class_init    = cs4231a_class_initfn,
 };
 
diff --git a/hw/audio/gus.c b/hw/audio/gus.c
index e0aea26..f45ed0b 100644
--- a/hw/audio/gus.c
+++ b/hw/audio/gus.c
@@ -251,8 +251,9 @@ static const MemoryRegionPortio gus_portio_list2[] = {
     PORTIO_END_OF_LIST (),
 };
 
-static int gus_initfn (ISADevice *dev)
+static void gus_realizefn (DeviceState *dev, Error **errp)
 {
+    ISADevice *d = ISA_DEVICE(dev);
     GUSState *s = GUS (dev);
     struct audsettings as;
 
@@ -274,26 +275,25 @@ static int gus_initfn (ISADevice *dev)
 
     if (!s->voice) {
         AUD_remove_card (&s->card);
-        return -1;
+        error_setg(errp, "No voice");
+        return;
     }
 
     s->shift = 2;
     s->samples = AUD_get_buffer_size_out (s->voice) >> s->shift;
     s->mixbuf = g_malloc0 (s->samples << s->shift);
 
-    isa_register_portio_list (dev, s->port, gus_portio_list1, s, "gus");
-    isa_register_portio_list (dev, (s->port + 0x100) & 0xf00,
+    isa_register_portio_list (d, s->port, gus_portio_list1, s, "gus");
+    isa_register_portio_list (d, (s->port + 0x100) & 0xf00,
                               gus_portio_list2, s, "gus");
 
     DMA_register_channel (s->emu.gusdma, GUS_read_DMA, s);
     s->emu.himemaddr = s->himem;
     s->emu.gusdatapos = s->emu.himemaddr + 1024 * 1024 + 32;
     s->emu.opaque = s;
-    isa_init_irq (dev, &s->pic, s->emu.gusirq);
+    isa_init_irq (d, &s->pic, s->emu.gusirq);
 
     AUD_set_active_out (s->voice, 1);
-
-    return 0;
 }
 
 static int GUS_init (ISABus *bus)
@@ -313,8 +313,8 @@ static Property gus_properties[] = {
 static void gus_class_initfn (ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS (klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS (klass);
-    ic->init = gus_initfn;
+
+    dc->realize = gus_realizefn;
     dc->desc = "Gravis Ultrasound GF1";
     dc->vmsd = &vmstate_gus;
     dc->props = gus_properties;
diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c
index 3a7285f..5dde0e7 100644
--- a/hw/audio/pcspk.c
+++ b/hw/audio/pcspk.c
@@ -163,16 +163,21 @@ static const MemoryRegionOps pcspk_io_ops = {
     },
 };
 
-static int pcspk_initfn(ISADevice *dev)
+static void pcspk_initfn(Object *obj)
 {
-    PCSpkState *s = PC_SPEAKER(dev);
+    PCSpkState *s = PC_SPEAKER(obj);
 
     memory_region_init_io(&s->ioport, &pcspk_io_ops, s, "elcr", 1);
-    isa_register_ioport(dev, &s->ioport, s->iobase);
+}
 
-    pcspk_state = s;
+static void pcspk_realizefn(DeviceState *dev, Error **errp)
+{
+    ISADevice *isadev = ISA_DEVICE(dev);
+    PCSpkState *s = PC_SPEAKER(dev);
 
-    return 0;
+    isa_register_ioport(isadev, &s->ioport, s->iobase);
+
+    pcspk_state = s;
 }
 
 static Property pcspk_properties[] = {
@@ -184,9 +189,8 @@ static Property pcspk_properties[] = {
 static void pcspk_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
 
-    ic->init = pcspk_initfn;
+    dc->realize = pcspk_realizefn;
     dc->no_user = 1;
     dc->props = pcspk_properties;
 }
@@ -195,6 +199,7 @@ static const TypeInfo pcspk_info = {
     .name           = TYPE_PC_SPEAKER,
     .parent         = TYPE_ISA_DEVICE,
     .instance_size  = sizeof(PCSpkState),
+    .instance_init  = pcspk_initfn,
     .class_init     = pcspk_class_initfn,
 };
 
diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c
index 6ddc0ac..e697bc1 100644
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -1356,12 +1356,19 @@ static const MemoryRegionPortio sb16_ioport_list[] = {
 };
 
 
-static int sb16_initfn (ISADevice *dev)
+static void sb16_initfn (Object *obj)
 {
-    SB16State *s = SB16 (dev);
+    SB16State *s = SB16 (obj);
 
     s->cmd = -1;
-    isa_init_irq (dev, &s->pic, s->irq);
+}
+
+static void sb16_realizefn (DeviceState *dev, Error **errp)
+{
+    ISADevice *isadev = ISA_DEVICE (dev);
+    SB16State *s = SB16 (dev);
+
+    isa_init_irq (isadev, &s->pic, s->irq);
 
     s->mixer_regs[0x80] = magic_of_irq (s->irq);
     s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
@@ -1376,14 +1383,13 @@ static int sb16_initfn (ISADevice *dev)
         dolog ("warning: Could not create auxiliary timer\n");
     }
 
-    isa_register_portio_list (dev, s->port, sb16_ioport_list, s, "sb16");
+    isa_register_portio_list (isadev, s->port, sb16_ioport_list, s, "sb16");
 
     DMA_register_channel (s->hdma, SB_read_DMA, s);
     DMA_register_channel (s->dma, SB_read_DMA, s);
     s->can_write = 1;
 
     AUD_register_card ("sb16", &s->card);
-    return 0;
 }
 
 static int SB16_init (ISABus *bus)
@@ -1404,8 +1410,8 @@ static Property sb16_properties[] = {
 static void sb16_class_initfn (ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS (klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS (klass);
-    ic->init = sb16_initfn;
+
+    dc->realize = sb16_realizefn;
     dc->desc = "Creative Sound Blaster 16";
     dc->vmsd = &vmstate_sb16;
     dc->props = sb16_properties;
@@ -1415,6 +1421,7 @@ static const TypeInfo sb16_info = {
     .name          = TYPE_SB16,
     .parent        = TYPE_ISA_DEVICE,
     .instance_size = sizeof (SB16State),
+    .instance_init = sb16_initfn,
     .class_init    = sb16_class_initfn,
 };
 
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 0888652..79ea625 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -2117,24 +2117,28 @@ static const MemoryRegionPortio fdc_portio_list[] = {
     PORTIO_END_OF_LIST(),
 };
 
-static int isabus_fdc_init1(ISADevice *dev)
+static void isabus_fdc_realize(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     FDCtrlISABus *isa = ISA_FDC(dev);
     FDCtrl *fdctrl = &isa->state;
     int ret;
 
-    isa_register_portio_list(dev, isa->iobase, fdc_portio_list, fdctrl, "fdc");
+    isa_register_portio_list(isadev, isa->iobase, fdc_portio_list, fdctrl,
+                             "fdc");
 
-    isa_init_irq(dev, &fdctrl->irq, isa->irq);
+    isa_init_irq(isadev, &fdctrl->irq, isa->irq);
     fdctrl->dma_chann = isa->dma;
 
-    qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 2);
+    qdev_set_legacy_instance_id(dev, isa->iobase, 2);
     ret = fdctrl_init_common(fdctrl);
+    if (ret < 0) {
+        error_setg(errp, "Floppy init failed.");
+        return;
+    }
 
-    add_boot_device_path(isa->bootindexA, &dev->qdev, "/address@hidden");
-    add_boot_device_path(isa->bootindexB, &dev->qdev, "/address@hidden");
-
-    return ret;
+    add_boot_device_path(isa->bootindexA, dev, "/address@hidden");
+    add_boot_device_path(isa->bootindexB, dev, "/address@hidden");
 }
 
 static int sysbus_fdc_init1(SysBusDevice *dev)
@@ -2203,8 +2207,8 @@ static Property isa_fdc_properties[] = {
 static void isabus_fdc_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = isabus_fdc_init1;
+
+    dc->realize = isabus_fdc_realize;
     dc->fw_name = "fdc";
     dc->no_user = 1;
     dc->reset = fdctrl_external_reset_isa;
diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c
index 3b0637d..f254841 100644
--- a/hw/char/debugcon.c
+++ b/hw/char/debugcon.c
@@ -81,27 +81,32 @@ static const MemoryRegionOps debugcon_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static void debugcon_init_core(DebugconState *s)
+static void debugcon_realize_core(DebugconState *s, Error **errp)
 {
     if (!s->chr) {
-        fprintf(stderr, "Can't create debugcon device, empty char device\n");
-        exit(1);
+        error_setg(errp, "Can't create debugcon device, empty char device");
+        return;
     }
 
     qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, s);
 }
 
-static int debugcon_isa_initfn(ISADevice *dev)
+static void debugcon_isa_realizefn(DeviceState *dev, Error **errp)
 {
+    ISADevice *d = ISA_DEVICE(dev);
     ISADebugconState *isa = ISA_DEBUGCON_DEVICE(dev);
     DebugconState *s = &isa->state;
+    Error *err = NULL;
 
-    debugcon_init_core(s);
+    debugcon_realize_core(s, &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
     memory_region_init_io(&s->io, &debugcon_ops, s,
                           TYPE_ISA_DEBUGCON_DEVICE, 1);
-    memory_region_add_subregion(isa_address_space_io(dev),
+    memory_region_add_subregion(isa_address_space_io(d),
                                 isa->iobase, &s->io);
-    return 0;
 }
 
 static Property debugcon_isa_properties[] = {
@@ -114,8 +119,8 @@ static Property debugcon_isa_properties[] = {
 static void debugcon_isa_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = debugcon_isa_initfn;
+
+    dc->realize = debugcon_isa_realizefn;
     dc->props = debugcon_isa_properties;
 }
 
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index 8e48284..caa9eb4 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -477,29 +477,35 @@ static const MemoryRegionPortio 
isa_parallel_portio_sw_list[] = {
     PORTIO_END_OF_LIST(),
 };
 
-static int parallel_isa_initfn(ISADevice *dev)
+static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
 {
     static int index;
+    ISADevice *isadev = ISA_DEVICE(dev);
     ISAParallelState *isa = ISA_PARALLEL(dev);
     ParallelState *s = &isa->state;
     int base;
     uint8_t dummy;
 
     if (!s->chr) {
-        fprintf(stderr, "Can't create parallel device, empty char device\n");
-        exit(1);
+        error_setg(errp, "Can't create parallel device, empty char device");
+        return;
     }
 
-    if (isa->index == -1)
+    if (isa->index == -1) {
         isa->index = index;
-    if (isa->index >= MAX_PARALLEL_PORTS)
-        return -1;
-    if (isa->iobase == -1)
+    }
+    if (isa->index >= MAX_PARALLEL_PORTS) {
+        error_setg(errp, "Max. supported number of parallel ports is %d.",
+                   MAX_PARALLEL_PORTS);
+        return;
+    }
+    if (isa->iobase == -1) {
         isa->iobase = isa_parallel_io[isa->index];
+    }
     index++;
 
     base = isa->iobase;
-    isa_init_irq(dev, &s->irq, isa->isairq);
+    isa_init_irq(isadev, &s->irq, isa->isairq);
     qemu_register_reset(parallel_reset, s);
 
     if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
@@ -507,12 +513,11 @@ static int parallel_isa_initfn(ISADevice *dev)
         s->status = dummy;
     }
 
-    isa_register_portio_list(dev, base,
+    isa_register_portio_list(isadev, base,
                              (s->hw_driver
                               ? &isa_parallel_portio_hw_list[0]
                               : &isa_parallel_portio_sw_list[0]),
                              s, "parallel");
-    return 0;
 }
 
 /* Memory mapped interface */
@@ -599,8 +604,8 @@ static Property parallel_isa_properties[] = {
 static void parallel_isa_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = parallel_isa_initfn;
+
+    dc->realize = parallel_isa_realizefn;
     dc->props = parallel_isa_properties;
 }
 
diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c
index 342b4cc..6e7e0dd 100644
--- a/hw/char/serial-isa.c
+++ b/hw/char/serial-isa.c
@@ -44,9 +44,10 @@ static const int isa_serial_irq[MAX_SERIAL_PORTS] = {
     4, 3, 4, 3
 };
 
-static int serial_isa_initfn(ISADevice *dev)
+static void serial_isa_realizefn(DeviceState *dev, Error **errp)
 {
     static int index;
+    ISADevice *isadev = ISA_DEVICE(dev);
     ISASerialState *isa = ISA_SERIAL(dev);
     SerialState *s = &isa->state;
 
@@ -54,7 +55,9 @@ static int serial_isa_initfn(ISADevice *dev)
         isa->index = index;
     }
     if (isa->index >= MAX_SERIAL_PORTS) {
-        return -1;
+        error_setg(errp, "Max. supported number of ISA serial ports is %d.",
+                   MAX_SERIAL_PORTS);
+        return;
     }
     if (isa->iobase == -1) {
         isa->iobase = isa_serial_io[isa->index];
@@ -65,13 +68,12 @@ static int serial_isa_initfn(ISADevice *dev)
     index++;
 
     s->baudbase = 115200;
-    isa_init_irq(dev, &s->irq, isa->isairq);
-    serial_init_core(s);
-    qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 3);
+    isa_init_irq(isadev, &s->irq, isa->isairq);
+    serial_realize_core(s, errp);
+    qdev_set_legacy_instance_id(dev, isa->iobase, 3);
 
     memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8);
-    isa_register_ioport(dev, &s->io, isa->iobase);
-    return 0;
+    isa_register_ioport(isadev, &s->io, isa->iobase);
 }
 
 static const VMStateDescription vmstate_isa_serial = {
@@ -96,8 +98,8 @@ static Property serial_isa_properties[] = {
 static void serial_isa_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = serial_isa_initfn;
+
+    dc->realize = serial_isa_realizefn;
     dc->vmsd = &vmstate_isa_serial;
     dc->props = serial_isa_properties;
 }
diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c
index 2138e35..3bec8eb 100644
--- a/hw/char/serial-pci.c
+++ b/hw/char/serial-pci.c
@@ -27,6 +27,7 @@
 
 #include "hw/char/serial.h"
 #include "hw/pci/pci.h"
+#include "qapi/qmp/qerror.h"
 
 #define PCI_SERIAL_MAX_PORTS 4
 
@@ -49,9 +50,15 @@ static int serial_pci_init(PCIDevice *dev)
 {
     PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
     SerialState *s = &pci->state;
+    Error *err = NULL;
 
     s->baudbase = 115200;
-    serial_init_core(s);
+    serial_realize_core(s, &err);
+    if (err != NULL) {
+        qerror_report_err(err);
+        error_free(err);
+        return -1;
+    }
 
     pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
     s->irq = pci->dev.irq[0];
@@ -80,6 +87,7 @@ static int multi_serial_pci_init(PCIDevice *dev)
     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
     PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
     SerialState *s;
+    Error *err = NULL;
     int i;
 
     switch (pc->device_id) {
@@ -102,7 +110,12 @@ static int multi_serial_pci_init(PCIDevice *dev)
     for (i = 0; i < pci->ports; i++) {
         s = pci->state + i;
         s->baudbase = 115200;
-        serial_init_core(s);
+        serial_realize_core(s, &err);
+        if (err != NULL) {
+            qerror_report_err(err);
+            error_free(err);
+            return -1;
+        }
         s->irq = pci->irqs[i];
         pci->name[i] = g_strdup_printf("uart #%d", i+1);
         memory_region_init_io(&s->io, &serial_io_ops, s, pci->name[i], 8);
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 66b6348..f2701e8 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -670,11 +670,11 @@ static void serial_reset(void *opaque)
     qemu_irq_lower(s->irq);
 }
 
-void serial_init_core(SerialState *s)
+void serial_realize_core(SerialState *s, Error **errp)
 {
     if (!s->chr) {
-        fprintf(stderr, "Can't create serial device, empty char device\n");
-       exit(1);
+        error_setg(errp, "Can't create serial device, empty char device");
+        return;
     }
 
     s->modem_status_poll = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) 
serial_update_msl, s);
@@ -713,13 +713,19 @@ SerialState *serial_init(int base, qemu_irq irq, int 
baudbase,
                          CharDriverState *chr, MemoryRegion *system_io)
 {
     SerialState *s;
+    Error *err = NULL;
 
     s = g_malloc0(sizeof(SerialState));
 
     s->irq = irq;
     s->baudbase = baudbase;
     s->chr = chr;
-    serial_init_core(s);
+    serial_realize_core(s, &err);
+    if (err != NULL) {
+        fprintf(stderr, "%s\n", error_get_pretty(err));
+        error_free(err);
+        exit(1);
+    }
 
     vmstate_register(NULL, base, &vmstate_serial, s);
 
@@ -769,6 +775,7 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
                             CharDriverState *chr, enum device_endian end)
 {
     SerialState *s;
+    Error *err = NULL;
 
     s = g_malloc0(sizeof(SerialState));
 
@@ -777,7 +784,12 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
     s->baudbase = baudbase;
     s->chr = chr;
 
-    serial_init_core(s);
+    serial_realize_core(s, &err);
+    if (err != NULL) {
+        fprintf(stderr, "%s\n", error_get_pretty(err));
+        error_free(err);
+        exit(1);
+    }
     vmstate_register(NULL, base, &vmstate_serial, s);
 
     memory_region_init_io(&s->io, &serial_mm_ops[end], s,
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index a5dbc39..0d9eee8 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -2906,19 +2906,20 @@ static void cirrus_init_common(CirrusVGAState * s, int 
device_id, int is_pci,
  *
  ***************************************/
 
-static int vga_initfn(ISADevice *dev)
+static void isa_cirrus_vga_realizefn(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     ISACirrusVGAState *d = ISA_CIRRUS_VGA(dev);
     VGACommonState *s = &d->cirrus_vga.vga;
 
     vga_common_init(s);
     cirrus_init_common(&d->cirrus_vga, CIRRUS_ID_CLGD5430, 0,
-                       isa_address_space(dev), isa_address_space_io(dev));
-    s->con = graphic_console_init(DEVICE(dev), s->hw_ops, s);
+                       isa_address_space(isadev),
+                       isa_address_space_io(isadev));
+    s->con = graphic_console_init(dev, s->hw_ops, s);
     rom_add_vga(VGABIOS_CIRRUS_FILENAME);
     /* XXX ISA-LFB support */
     /* FIXME not qdev yet */
-    return 0;
 }
 
 static Property isa_cirrus_vga_properties[] = {
@@ -2929,11 +2930,10 @@ static Property isa_cirrus_vga_properties[] = {
 
 static void isa_cirrus_vga_class_init(ObjectClass *klass, void *data)
 {
-    ISADeviceClass *k = ISA_DEVICE_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->vmsd  = &vmstate_cirrus_vga;
-    k->init   = vga_initfn;
+    dc->realize = isa_cirrus_vga_realizefn;
     dc->props = isa_cirrus_vga_properties;
 }
 
diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c
index 9e63b69..d1691a9 100644
--- a/hw/display/vga-isa.c
+++ b/hw/display/vga-isa.c
@@ -48,30 +48,30 @@ static void vga_isa_reset(DeviceState *dev)
     vga_common_reset(s);
 }
 
-static int vga_initfn(ISADevice *dev)
+static void vga_isa_realizefn(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     ISAVGAState *d = ISA_VGA(dev);
     VGACommonState *s = &d->state;
     MemoryRegion *vga_io_memory;
     const MemoryRegionPortio *vga_ports, *vbe_ports;
 
     vga_common_init(s);
-    s->legacy_address_space = isa_address_space(dev);
+    s->legacy_address_space = isa_address_space(isadev);
     vga_io_memory = vga_init_io(s, &vga_ports, &vbe_ports);
-    isa_register_portio_list(dev, 0x3b0, vga_ports, s, "vga");
+    isa_register_portio_list(isadev, 0x3b0, vga_ports, s, "vga");
     if (vbe_ports) {
-        isa_register_portio_list(dev, 0x1ce, vbe_ports, s, "vbe");
+        isa_register_portio_list(isadev, 0x1ce, vbe_ports, s, "vbe");
     }
-    memory_region_add_subregion_overlap(isa_address_space(dev),
+    memory_region_add_subregion_overlap(isa_address_space(isadev),
                                         isa_mem_base + 0x000a0000,
                                         vga_io_memory, 1);
     memory_region_set_coalescing(vga_io_memory);
     s->con = graphic_console_init(DEVICE(dev), s->hw_ops, s);
 
-    vga_init_vbe(s, isa_address_space(dev));
+    vga_init_vbe(s, isa_address_space(isadev));
     /* ROM BIOS */
     rom_add_vga(VGABIOS_FILENAME);
-    return 0;
 }
 
 static Property vga_isa_properties[] = {
@@ -82,9 +82,8 @@ static Property vga_isa_properties[] = {
 static void vga_isa_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
 
-    ic->init = vga_initfn;
+    dc->realize = vga_isa_realizefn;
     dc->reset = vga_isa_reset;
     dc->vmsd = &vmstate_vga_common;
     dc->props = vga_isa_properties;
diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c
index f3d1924..6192780 100644
--- a/hw/dma/i82374.c
+++ b/hw/dma/i82374.c
@@ -98,7 +98,7 @@ static uint32_t i82374_read_descriptor(void *opaque, uint32_t 
nport)
     return val;
 }
 
-static void i82374_init(I82374State *s)
+static void i82374_realize(I82374State *s, Error **errp)
 {
     DMA_init(1, &s->out);
     memset(s->commands, 0, sizeof(s->commands));
@@ -124,7 +124,7 @@ static const VMStateDescription vmstate_isa_i82374 = {
     },
 };
 
-static int i82374_isa_init(ISADevice *dev)
+static void i82374_isa_realize(DeviceState *dev, Error **errp)
 {
     ISAi82374State *isa = I82374(dev);
     I82374State *s = &isa->state;
@@ -135,11 +135,9 @@ static int i82374_isa_init(ISADevice *dev)
     register_ioport_write(isa->iobase + 0x20, 0x20, 1, 
i82374_write_descriptor, s);
     register_ioport_read(isa->iobase + 0x20, 0x20, 1, i82374_read_descriptor, 
s);
 
-    i82374_init(s);
+    i82374_realize(s, errp);
 
-    qdev_init_gpio_out(&dev->qdev, &s->out, 1);
-
-    return 0;
+    qdev_init_gpio_out(dev, &s->out, 1);
 }
 
 static Property i82374_properties[] = {
@@ -149,10 +147,9 @@ static Property i82374_properties[] = {
 
 static void i82374_class_init(ObjectClass *klass, void *data)
 {
-    ISADeviceClass *k = ISA_DEVICE_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
     
-    k->init  = i82374_isa_init;
+    dc->realize = i82374_isa_realize;
     dc->vmsd = &vmstate_isa_i82374;
     dc->props = i82374_properties;
 }
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 4844a6b..e9c91e4 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -522,23 +522,29 @@ static const MemoryRegionOps port92_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static int port92_initfn(ISADevice *dev)
+static void port92_initfn(Object *obj)
 {
-    Port92State *s = PORT92(dev);
+    Port92State *s = PORT92(obj);
 
     memory_region_init_io(&s->io, &port92_ops, s, "port92", 1);
-    isa_register_ioport(dev, &s->io, 0x92);
 
     s->outport = 0;
-    return 0;
+}
+
+static void port92_realizefn(DeviceState *dev, Error **errp)
+{
+    ISADevice *isadev = ISA_DEVICE(dev);
+    Port92State *s = PORT92(dev);
+
+    isa_register_ioport(isadev, &s->io, 0x92);
 }
 
 static void port92_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = port92_initfn;
+
     dc->no_user = 1;
+    dc->realize = port92_realizefn;
     dc->reset = port92_reset;
     dc->vmsd = &vmstate_port92_isa;
 }
@@ -547,6 +553,7 @@ static const TypeInfo port92_info = {
     .name          = TYPE_PORT92,
     .parent        = TYPE_ISA_DEVICE,
     .instance_size = sizeof(Port92State),
+    .instance_init = port92_initfn,
     .class_init    = port92_class_initfn,
 };
 
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 369a7fa..7243c82 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -65,16 +65,16 @@ static const VMStateDescription vmstate_ide_isa = {
     }
 };
 
-static int isa_ide_initfn(ISADevice *dev)
+static void isa_ide_realizefn(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     ISAIDEState *s = ISA_IDE(dev);
 
-    ide_bus_new(&s->bus, DEVICE(dev), 0, 2);
-    ide_init_ioport(&s->bus, dev, s->iobase, s->iobase2);
-    isa_init_irq(dev, &s->irq, s->isairq);
+    ide_bus_new(&s->bus, dev, 0, 2);
+    ide_init_ioport(&s->bus, isadev, s->iobase, s->iobase2);
+    isa_init_irq(isadev, &s->irq, s->isairq);
     ide_init2(&s->bus, s->irq);
-    vmstate_register(&dev->qdev, 0, &vmstate_ide_isa, s);
-    return 0;
+    vmstate_register(dev, 0, &vmstate_ide_isa, s);
 };
 
 ISADevice *isa_ide_init(ISABus *bus, int iobase, int iobase2, int isairq,
@@ -113,8 +113,8 @@ static Property isa_ide_properties[] = {
 static void isa_ide_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = isa_ide_initfn;
+
+    dc->realize = isa_ide_realizefn;
     dc->fw_name = "ide";
     dc->reset = isa_ide_reset;
     dc->props = isa_ide_properties;
diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
index 17a5614..fff0a4d 100644
--- a/hw/input/pckbd.c
+++ b/hw/input/pckbd.c
@@ -489,31 +489,37 @@ static const MemoryRegionOps i8042_cmd_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static int i8042_initfn(ISADevice *dev)
+static void i8042_initfn(Object *obj)
 {
-    ISAKBDState *isa_s = I8042(dev);
+    ISAKBDState *isa_s = I8042(obj);
     KBDState *s = &isa_s->kbd;
 
-    isa_init_irq(dev, &s->irq_kbd, 1);
-    isa_init_irq(dev, &s->irq_mouse, 12);
-
     memory_region_init_io(isa_s->io + 0, &i8042_data_ops, s, "i8042-data", 1);
-    isa_register_ioport(dev, isa_s->io + 0, 0x60);
-
     memory_region_init_io(isa_s->io + 1, &i8042_cmd_ops, s, "i8042-cmd", 1);
-    isa_register_ioport(dev, isa_s->io + 1, 0x64);
+}
+
+static void i8042_realizefn(DeviceState *dev, Error **errp)
+{
+    ISADevice *isadev = ISA_DEVICE(dev);
+    ISAKBDState *isa_s = I8042(dev);
+    KBDState *s = &isa_s->kbd;
+
+    isa_init_irq(isadev, &s->irq_kbd, 1);
+    isa_init_irq(isadev, &s->irq_mouse, 12);
+
+    isa_register_ioport(isadev, isa_s->io + 0, 0x60);
+    isa_register_ioport(isadev, isa_s->io + 1, 0x64);
 
     s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s);
     s->mouse = ps2_mouse_init(kbd_update_aux_irq, s);
     qemu_register_reset(kbd_reset, s);
-    return 0;
 }
 
 static void i8042_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = i8042_initfn;
+
+    dc->realize = i8042_realizefn;
     dc->no_user = 1;
     dc->vmsd = &vmstate_kbd_isa;
 }
@@ -522,6 +528,7 @@ static const TypeInfo i8042_info = {
     .name          = TYPE_I8042,
     .parent        = TYPE_ISA_DEVICE,
     .instance_size = sizeof(ISAKBDState),
+    .instance_init = i8042_initfn,
     .class_init    = i8042_class_initfn,
 };
 
diff --git a/hw/input/vmmouse.c b/hw/input/vmmouse.c
index a610738..abd032b 100644
--- a/hw/input/vmmouse.c
+++ b/hw/input/vmmouse.c
@@ -261,7 +261,7 @@ static void vmmouse_reset(DeviceState *d)
     vmmouse_disable(s);
 }
 
-static int vmmouse_initfn(ISADevice *dev)
+static void vmmouse_realizefn(DeviceState *dev, Error **errp)
 {
     VMMouseState *s = VMMOUSE(dev);
 
@@ -270,8 +270,6 @@ static int vmmouse_initfn(ISADevice *dev)
     vmport_register(VMMOUSE_STATUS, vmmouse_ioport_read, s);
     vmport_register(VMMOUSE_COMMAND, vmmouse_ioport_read, s);
     vmport_register(VMMOUSE_DATA, vmmouse_ioport_read, s);
-
-    return 0;
 }
 
 static Property vmmouse_properties[] = {
@@ -282,8 +280,8 @@ static Property vmmouse_properties[] = {
 static void vmmouse_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = vmmouse_initfn;
+
+    dc->realize = vmmouse_realizefn;
     dc->no_user = 1;
     dc->reset = vmmouse_reset;
     dc->vmsd = &vmstate_vmmouse;
diff --git a/hw/intc/i8259_common.c b/hw/intc/i8259_common.c
index c2ba6a5..a3dee38 100644
--- a/hw/intc/i8259_common.c
+++ b/hw/intc/i8259_common.c
@@ -66,7 +66,7 @@ static int pic_dispatch_post_load(void *opaque, int 
version_id)
     return 0;
 }
 
-static int pic_init_common(ISADevice *dev)
+static void pic_common_realize(DeviceState *dev, Error **errp)
 {
     PICCommonState *s = PIC_COMMON(dev);
     PICCommonClass *info = PIC_COMMON_GET_CLASS(s);
@@ -78,9 +78,7 @@ static int pic_init_common(ISADevice *dev)
         isa_register_ioport(NULL, &s->elcr_io, s->elcr_addr);
     }
 
-    qdev_set_legacy_instance_id(DEVICE(dev), s->iobase, 1);
-
-    return 0;
+    qdev_set_legacy_instance_id(dev, s->iobase, 1);
 }
 
 ISADevice *i8259_init_chip(const char *name, ISABus *bus, bool master)
@@ -135,13 +133,12 @@ static Property pic_properties_common[] = {
 
 static void pic_common_class_init(ObjectClass *klass, void *data)
 {
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->vmsd = &vmstate_pic_common;
     dc->no_user = 1;
     dc->props = pic_properties_common;
-    ic->init = pic_init_common;
+    dc->realize = pic_common_realize;
 }
 
 static const TypeInfo pic_common_type = {
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index 7860b17..f12b15d 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -119,18 +119,6 @@ void isa_register_portio_list(ISADevice *dev, uint16_t 
start,
     portio_list_add(piolist, isabus->address_space_io, start);
 }
 
-static int isa_qdev_init(DeviceState *qdev)
-{
-    ISADevice *dev = ISA_DEVICE(qdev);
-    ISADeviceClass *klass = ISA_DEVICE_GET_CLASS(dev);
-
-    if (klass->init) {
-        return klass->init(dev);
-    }
-
-    return 0;
-}
-
 static void isa_device_init(Object *obj)
 {
     ISADevice *dev = ISA_DEVICE(obj);
@@ -230,7 +218,6 @@ static const TypeInfo isabus_bridge_info = {
 static void isa_device_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *k = DEVICE_CLASS(klass);
-    k->init = isa_qdev_init;
     k->bus_type = TYPE_ISA_BUS;
 }
 
diff --git a/hw/isa/pc87312.c b/hw/isa/pc87312.c
index 82f7c80..cc426df 100644
--- a/hw/isa/pc87312.c
+++ b/hw/isa/pc87312.c
@@ -264,7 +264,7 @@ static void pc87312_reset(DeviceState *d)
     pc87312_soft_reset(s);
 }
 
-static int pc87312_init(ISADevice *dev)
+static void pc87312_realize(DeviceState *dev, Error **errp)
 {
     PC87312State *s;
     DeviceState *d;
@@ -276,9 +276,10 @@ static int pc87312_init(ISADevice *dev)
     int i;
 
     s = PC87312(dev);
-    bus = isa_bus_from_device(dev);
+    isa = ISA_DEVICE(dev);
+    bus = isa_bus_from_device(isa);
+    isa_register_ioport(isa, &s->io, s->iobase);
     pc87312_hard_reset(s);
-    isa_register_ioport(dev, &s->io, s->iobase);
 
     if (is_parallel_enabled(s)) {
         chr = parallel_hds[0];
@@ -345,8 +346,6 @@ static int pc87312_init(ISADevice *dev)
         s->ide.dev = isa;
         trace_pc87312_info_ide(get_ide_iobase(s));
     }
-
-    return 0;
 }
 
 static void pc87312_initfn(Object *obj)
@@ -378,9 +377,8 @@ static Property pc87312_properties[] = {
 static void pc87312_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
 
-    ic->init = pc87312_init;
+    dc->realize = pc87312_realize;
     dc->reset = pc87312_reset;
     dc->vmsd = &vmstate_pc87312;
     dc->props = pc87312_properties;
diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 78904a8..46f4fbd 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -201,7 +201,7 @@ static void qdev_applesmc_isa_reset(DeviceState *dev)
     applesmc_add_key(s, "MSSD", 1, "\0x3");
 }
 
-static int applesmc_isa_init(ISADevice *dev)
+static void applesmc_isa_realize(DeviceState *dev, Error **errp)
 {
     AppleSMCState *s = APPLE_SMC(dev);
 
@@ -220,9 +220,7 @@ static int applesmc_isa_init(ISADevice *dev)
     }
 
     QLIST_INIT(&s->data_def);
-    qdev_applesmc_isa_reset(&dev->qdev);
-
-    return 0;
+    qdev_applesmc_isa_reset(dev);
 }
 
 static Property applesmc_isa_properties[] = {
@@ -235,8 +233,8 @@ static Property applesmc_isa_properties[] = {
 static void qdev_applesmc_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = applesmc_isa_init;
+
+    dc->realize = applesmc_isa_realize;
     dc->reset = qdev_applesmc_isa_reset;
     dc->props = applesmc_isa_properties;
 }
diff --git a/hw/misc/debugexit.c b/hw/misc/debugexit.c
index 59bed5b..ee254e4 100644
--- a/hw/misc/debugexit.c
+++ b/hw/misc/debugexit.c
@@ -35,15 +35,15 @@ static const MemoryRegionOps debug_exit_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static int debug_exit_initfn(ISADevice *dev)
+static void debug_exit_realizefn(DeviceState *d, Error **errp)
 {
-    ISADebugExitState *isa = ISA_DEBUG_EXIT_DEVICE(dev);
+    ISADevice *dev = ISA_DEVICE(d);
+    ISADebugExitState *isa = ISA_DEBUG_EXIT_DEVICE(d);
 
     memory_region_init_io(&isa->io, &debug_exit_ops, isa,
                           TYPE_ISA_DEBUG_EXIT_DEVICE, isa->iosize);
     memory_region_add_subregion(isa_address_space_io(dev),
                                 isa->iobase, &isa->io);
-    return 0;
 }
 
 static Property debug_exit_properties[] = {
@@ -55,8 +55,8 @@ static Property debug_exit_properties[] = {
 static void debug_exit_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = debug_exit_initfn;
+
+    dc->realize = debug_exit_realizefn;
     dc->props = debug_exit_properties;
 }
 
diff --git a/hw/misc/pc-testdev.c b/hw/misc/pc-testdev.c
index 32df175..e6707d6 100644
--- a/hw/misc/pc-testdev.c
+++ b/hw/misc/pc-testdev.c
@@ -142,9 +142,10 @@ static const MemoryRegionOps test_iomem_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static int init_test_device(ISADevice *isa)
+static void testdev_realizefn(DeviceState *d, Error **errp)
 {
-    PCTestdev *dev = TESTDEV(isa);
+    ISADevice *isa = ISA_DEVICE(d);
+    PCTestdev *dev = TESTDEV(d);
     MemoryRegion *mem = isa_address_space(isa);
     MemoryRegion *io = isa_address_space_io(isa);
 
@@ -161,15 +162,13 @@ static int init_test_device(ISADevice *isa)
     memory_region_add_subregion(io,  0xe4,       &dev->flush);
     memory_region_add_subregion(io,  0x2000,     &dev->irq);
     memory_region_add_subregion(mem, 0xff000000, &dev->iomem);
-
-    return 0;
 }
 
 static void testdev_class_init(ObjectClass *klass, void *data)
 {
-    ISADeviceClass *k = ISA_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
-    k->init = init_test_device;
+    dc->realize = testdev_realizefn;
 }
 
 static const TypeInfo testdev_info = {
diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 910e44f..060099b 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -86,14 +86,21 @@ static const MemoryRegionOps pvpanic_ops = {
     },
 };
 
-static int pvpanic_isa_initfn(ISADevice *dev)
+static void pvpanic_isa_initfn(Object *obj)
 {
+    PVPanicState *s = ISA_PVPANIC_DEVICE(obj);
+
+    memory_region_init_io(&s->io, &pvpanic_ops, s, "pvpanic", 1);
+}
+
+static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
+{
+    ISADevice *d = ISA_DEVICE(dev);
     PVPanicState *s = ISA_PVPANIC_DEVICE(dev);
     static bool port_configured;
     FWCfgState *fw_cfg;
 
-    memory_region_init_io(&s->io, &pvpanic_ops, s, "pvpanic", 1);
-    isa_register_ioport(dev, &s->io, s->ioport);
+    isa_register_ioport(d, &s->io, s->ioport);
 
     if (!port_configured) {
         fw_cfg = fw_cfg_find();
@@ -104,8 +111,6 @@ static int pvpanic_isa_initfn(ISADevice *dev)
             port_configured = true;
         }
     }
-
-    return 0;
 }
 
 int pvpanic_init(ISABus *bus)
@@ -122,9 +127,8 @@ static Property pvpanic_isa_properties[] = {
 static void pvpanic_isa_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
 
-    ic->init = pvpanic_isa_initfn;
+    dc->realize = pvpanic_isa_realizefn;
     dc->no_user = 1;
     dc->props = pvpanic_isa_properties;
 }
@@ -133,6 +137,7 @@ static TypeInfo pvpanic_isa_info = {
     .name          = TYPE_ISA_PVPANIC_DEVICE,
     .parent        = TYPE_ISA_DEVICE,
     .instance_size = sizeof(PVPanicState),
+    .instance_init = pvpanic_isa_initfn,
     .class_init    = pvpanic_isa_class_init,
 };
 
diff --git a/hw/misc/sga.c b/hw/misc/sga.c
index c842190..08803e7 100644
--- a/hw/misc/sga.c
+++ b/hw/misc/sga.c
@@ -38,17 +38,16 @@ typedef struct ISASGAState {
     ISADevice parent_obj;
 } ISASGAState;
 
-static int sga_initfn(ISADevice *dev)
+static void sga_realizefn(DeviceState *dev, Error **errp)
 {
     rom_add_vga(SGABIOS_FILENAME);
-    return 0;
 }
 
 static void sga_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = sga_initfn;
+
+    dc->realize = sga_realizefn;
     dc->desc = "Serial Graphics Adapter";
 }
 
diff --git a/hw/misc/vmport.c b/hw/misc/vmport.c
index c146129..57b71f5 100644
--- a/hw/misc/vmport.c
+++ b/hw/misc/vmport.c
@@ -137,25 +137,25 @@ static const MemoryRegionOps vmport_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static int vmport_initfn(ISADevice *dev)
+static void vmport_realizefn(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     VMPortState *s = VMPORT(dev);
 
     memory_region_init_io(&s->io, &vmport_ops, s, "vmport", 1);
-    isa_register_ioport(dev, &s->io, 0x5658);
+    isa_register_ioport(isadev, &s->io, 0x5658);
 
     port_state = s;
     /* Register some generic port commands */
     vmport_register(VMPORT_CMD_GETVERSION, vmport_cmd_get_version, NULL);
     vmport_register(VMPORT_CMD_GETRAMSIZE, vmport_cmd_ram_size, NULL);
-    return 0;
 }
 
 static void vmport_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = vmport_initfn;
+
+    dc->realize = vmport_realizefn;
     dc->no_user = 1;
 }
 
diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c
index f8e610c..9232abd 100644
--- a/hw/net/ne2000-isa.c
+++ b/hw/net/ne2000-isa.c
@@ -66,24 +66,23 @@ static const VMStateDescription vmstate_isa_ne2000 = {
     }
 };
 
-static int isa_ne2000_initfn(ISADevice *dev)
+static void isa_ne2000_realizefn(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     ISANE2000State *isa = ISA_NE2000(dev);
     NE2000State *s = &isa->ne2000;
 
     ne2000_setup_io(s, 0x20);
-    isa_register_ioport(dev, &s->io, isa->iobase);
+    isa_register_ioport(isadev, &s->io, isa->iobase);
 
-    isa_init_irq(dev, &s->irq, isa->isairq);
+    isa_init_irq(isadev, &s->irq, isa->isairq);
 
     qemu_macaddr_default_if_unset(&s->c.macaddr);
     ne2000_reset(s);
 
     s->nic = qemu_new_nic(&net_ne2000_isa_info, &s->c,
-                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
+                          object_get_typename(OBJECT(dev)), dev->id, s);
     qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
-
-    return 0;
 }
 
 static Property ne2000_isa_properties[] = {
@@ -96,8 +95,8 @@ static Property ne2000_isa_properties[] = {
 static void isa_ne2000_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = isa_ne2000_initfn;
+
+    dc->realize = isa_ne2000_realizefn;
     dc->props = ne2000_isa_properties;
 }
 
diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c
index 5342df4..36eed80 100644
--- a/hw/timer/i8254_common.c
+++ b/hw/timer/i8254_common.c
@@ -166,22 +166,22 @@ void pit_reset_common(PITCommonState *pit)
     }
 }
 
-static int pit_init_common(ISADevice *dev)
+static void pit_common_realize(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     PITCommonState *pit = PIT_COMMON(dev);
     PITCommonClass *c = PIT_COMMON_GET_CLASS(pit);
     int ret;
 
     ret = c->init(pit);
     if (ret < 0) {
-        return ret;
+        error_setg(errp, "PIT init failed.");
+        return;
     }
 
-    isa_register_ioport(dev, &pit->ioports, pit->iobase);
+    isa_register_ioport(isadev, &pit->ioports, pit->iobase);
 
-    qdev_set_legacy_instance_id(&dev->qdev, pit->iobase, 2);
-
-    return 0;
+    qdev_set_legacy_instance_id(dev, pit->iobase, 2);
 }
 
 static const VMStateDescription vmstate_pit_channel = {
@@ -286,10 +286,9 @@ static const VMStateDescription vmstate_pit_common = {
 
 static void pit_common_class_init(ObjectClass *klass, void *data)
 {
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
-    ic->init = pit_init_common;
+    dc->realize = pit_common_realize;
     dc->vmsd = &vmstate_pit_common;
     dc->no_user = 1;
 }
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
index 45753d8..bf6c4c8 100644
--- a/hw/timer/m48t59.c
+++ b/hw/timer/m48t59.c
@@ -691,7 +691,7 @@ M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, 
uint16_t size,
     return s;
 }
 
-static void m48t59_init_common(M48t59State *s)
+static void m48t59_realize_common(M48t59State *s, Error **errp)
 {
     s->buffer = g_malloc0(s->size);
     if (s->model == 59) {
@@ -703,27 +703,31 @@ static void m48t59_init_common(M48t59State *s)
     vmstate_register(NULL, -1, &vmstate_m48t59, s);
 }
 
-static int m48t59_init_isa1(ISADevice *dev)
+static void m48t59_isa_realize(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     M48t59ISAState *d = ISA_M48T59(dev);
     M48t59State *s = &d->state;
 
-    isa_init_irq(dev, &s->IRQ, 8);
-    m48t59_init_common(s);
-
-    return 0;
+    isa_init_irq(isadev, &s->IRQ, 8);
+    m48t59_realize_common(s, errp);
 }
 
 static int m48t59_init1(SysBusDevice *dev)
 {
     M48t59SysBusState *d = FROM_SYSBUS(M48t59SysBusState, dev);
     M48t59State *s = &d->state;
+    Error *err = NULL;
 
     sysbus_init_irq(dev, &s->IRQ);
 
     memory_region_init_io(&s->iomem, &nvram_ops, s, "m48t59.nvram", s->size);
     sysbus_init_mmio(dev, &s->iomem);
-    m48t59_init_common(s);
+    m48t59_realize_common(s, &err);
+    if (err != NULL) {
+        error_free(err);
+        return -1;
+    }
 
     return 0;
 }
@@ -738,8 +742,8 @@ static Property m48t59_isa_properties[] = {
 static void m48t59_isa_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = m48t59_init_isa1;
+
+    dc->realize = m48t59_isa_realize;
     dc->no_user = 1;
     dc->reset = m48t59_reset_isa;
     dc->props = m48t59_isa_properties;
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 481604d..9c4a7bd 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -814,8 +814,9 @@ static void rtc_get_date(Object *obj, Visitor *v, void 
*opaque,
     visit_end_struct(v, errp);
 }
 
-static int rtc_initfn(ISADevice *dev)
+static void rtc_realizefn(DeviceState *dev, Error **errp)
 {
+    ISADevice *isadev = ISA_DEVICE(dev);
     RTCState *s = MC146818_RTC(dev);
     int base = 0x70;
 
@@ -836,7 +837,7 @@ static int rtc_initfn(ISADevice *dev)
         s->base_year = 0;
     }
 
-    rtc_set_date_from_host(dev);
+    rtc_set_date_from_host(isadev);
 
 #ifdef TARGET_I386
     switch (s->lost_tick_policy) {
@@ -847,7 +848,8 @@ static int rtc_initfn(ISADevice *dev)
     case LOST_TICK_DISCARD:
         break;
     default:
-        return -EINVAL;
+        error_setg(errp, "Invalid lost tick policy.");
+        return;
     }
 #endif
 
@@ -862,15 +864,13 @@ static int rtc_initfn(ISADevice *dev)
     qemu_register_suspend_notifier(&s->suspend_notifier);
 
     memory_region_init_io(&s->io, &cmos_ops, s, "rtc", 2);
-    isa_register_ioport(dev, &s->io, base);
+    isa_register_ioport(isadev, &s->io, base);
 
-    qdev_set_legacy_instance_id(&dev->qdev, base, 3);
+    qdev_set_legacy_instance_id(dev, base, 3);
     qemu_register_reset(rtc_reset, s);
 
     object_property_add(OBJECT(s), "date", "struct tm",
                         rtc_get_date, NULL, NULL, s, NULL);
-
-    return 0;
 }
 
 ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
@@ -902,8 +902,8 @@ static Property mc146818rtc_properties[] = {
 static void rtc_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = rtc_initfn;
+
+    dc->realize = rtc_realizefn;
     dc->no_user = 1;
     dc->vmsd = &vmstate_rtc;
     dc->props = mc146818rtc_properties;
diff --git a/hw/watchdog/wdt_ib700.c b/hw/watchdog/wdt_ib700.c
index 6b8e33a..d85c894 100644
--- a/hw/watchdog/wdt_ib700.c
+++ b/hw/watchdog/wdt_ib700.c
@@ -97,7 +97,7 @@ static const VMStateDescription vmstate_ib700 = {
     }
 };
 
-static int wdt_ib700_init(ISADevice *dev)
+static void wdt_ib700_realize(DeviceState *dev, Error **errp)
 {
     IB700State *s = IB700(dev);
 
@@ -106,8 +106,6 @@ static int wdt_ib700_init(ISADevice *dev)
     s->timer = qemu_new_timer_ns(vm_clock, ib700_timer_expired, s);
     register_ioport_write(0x441, 2, 1, ib700_write_disable_reg, s);
     register_ioport_write(0x443, 2, 1, ib700_write_enable_reg, s);
-
-    return 0;
 }
 
 static void wdt_ib700_reset(DeviceState *dev)
@@ -127,8 +125,8 @@ static WatchdogTimerModel model = {
 static void wdt_ib700_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
-    ic->init = wdt_ib700_init;
+
+    dc->realize = wdt_ib700_realize;
     dc->reset = wdt_ib700_reset;
     dc->vmsd = &vmstate_ib700;
 }
diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
index bca79f1..c15354a 100644
--- a/include/hw/char/serial.h
+++ b/include/hw/char/serial.h
@@ -83,7 +83,7 @@ struct SerialState {
 extern const VMStateDescription vmstate_serial;
 extern const MemoryRegionOps serial_io_ops;
 
-void serial_init_core(SerialState *s);
+void serial_realize_core(SerialState *s, Error **errp);
 void serial_exit_core(SerialState *s);
 void serial_set_frequency(SerialState *s, uint32_t frequency);
 
diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index 82da37c..1f6ff55 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -22,7 +22,6 @@
 
 typedef struct ISADeviceClass {
     DeviceClass parent_class;
-    int (*init)(ISADevice *dev);
 } ISADeviceClass;
 
 struct ISABus {
-- 
1.8.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]