Patchwork qdev: add return value to init() callbacks.

login
register
mail settings
Submitter Gerd Hoffmann
Date Aug. 12, 2009, 3:59 p.m.
Message ID <1250092766-23986-1-git-send-email-kraxel@redhat.com>
Download mbox | patch
Permalink /patch/31199/
State Superseded
Headers show

Comments

Gerd Hoffmann - Aug. 12, 2009, 3:59 p.m.
Sorry folks, but it has to be.  One more of these invasive qdev patches.

We have a serious design bug in the qdev interface:  device init
callbacks can't signal failure because the init() callback has no
return value.  This patch fixes it.

We have already one case in-tree where this is needed:
Try -device virtio-blk-pci (without drive= specified) and watch qemu
segfault.  This patch fixes it.

With usb+scsi being converted to qdev we'll get more devices where the
init callback can fail for various reasons.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/ac97.c             |    3 ++-
 hw/ads7846.c          |    3 ++-
 hw/apb_pci.c          |    6 ++++--
 hw/arm_sysctl.c       |    3 ++-
 hw/arm_timer.c        |    6 ++++--
 hw/armv7m.c           |    3 ++-
 hw/armv7m_nvic.c      |    3 ++-
 hw/cirrus_vga.c       |    3 ++-
 hw/cs4231.c           |    3 ++-
 hw/e1000.c            |    3 ++-
 hw/eccmemctl.c        |    3 ++-
 hw/eepro100.c         |   15 ++++++++-------
 hw/es1370.c           |    3 ++-
 hw/escc.c             |    3 ++-
 hw/esp.c              |    3 ++-
 hw/etraxfs_pic.c      |    3 ++-
 hw/etraxfs_ser.c      |    3 ++-
 hw/etraxfs_timer.c    |    3 ++-
 hw/fdc.c              |   15 ++++++++-------
 hw/grackle_pci.c      |   12 ++++++++----
 hw/i2c.c              |    4 ++--
 hw/i2c.h              |    2 +-
 hw/integratorcp.c     |    6 ++++--
 hw/iommu.c            |    3 ++-
 hw/isa-bus.c          |    4 ++--
 hw/isa.h              |    2 +-
 hw/lm832x.c           |    3 ++-
 hw/lsi53c895a.c       |    3 ++-
 hw/m48t59.c           |    3 ++-
 hw/max111x.c          |   11 ++++++-----
 hw/max7310.c          |    3 ++-
 hw/mpcore.c           |    6 ++++--
 hw/musicpal.c         |   18 ++++++++++++------
 hw/ne2000.c           |    3 ++-
 hw/pci.c              |    4 ++--
 hw/pci.h              |    2 +-
 hw/pckbd.c            |    3 ++-
 hw/pcnet.c            |   11 ++++++-----
 hw/piix_pci.c         |   12 ++++++++----
 hw/pl011.c            |   11 ++++++-----
 hw/pl022.c            |    3 ++-
 hw/pl031.c            |    3 ++-
 hw/pl050.c            |   11 ++++++-----
 hw/pl061.c            |    3 ++-
 hw/pl080.c            |   11 ++++++-----
 hw/pl110.c            |    7 ++++---
 hw/pl181.c            |    3 ++-
 hw/pl190.c            |    3 ++-
 hw/pxa2xx.c           |    6 ++++--
 hw/qdev.c             |    9 ++++++---
 hw/qdev.h             |    4 ++--
 hw/realview_gic.c     |    3 ++-
 hw/rtl8139.c          |    3 ++-
 hw/sbi.c              |    3 ++-
 hw/slavio_intctl.c    |    3 ++-
 hw/slavio_misc.c      |    6 ++++--
 hw/slavio_timer.c     |    3 ++-
 hw/smbus.c            |    4 ++--
 hw/smbus.h            |    2 +-
 hw/smbus_eeprom.c     |    3 ++-
 hw/smc91c111.c        |    3 ++-
 hw/sparc32_dma.c      |    3 ++-
 hw/spitz.c            |    6 ++++--
 hw/ssd0303.c          |    3 ++-
 hw/ssd0323.c          |    3 ++-
 hw/ssi-sd.c           |    3 ++-
 hw/ssi.c              |    4 ++--
 hw/ssi.h              |    2 +-
 hw/stellaris.c        |   19 ++++++++++++-------
 hw/stellaris_enet.c   |    3 ++-
 hw/sun4c_intctl.c     |    3 ++-
 hw/sun4m.c            |    9 ++++++---
 hw/sun4u.c            |    9 ++++++---
 hw/syborg_fb.c        |    3 ++-
 hw/syborg_interrupt.c |    3 ++-
 hw/syborg_keyboard.c  |    3 ++-
 hw/syborg_pointer.c   |    3 ++-
 hw/syborg_rtc.c       |    3 ++-
 hw/syborg_serial.c    |    3 ++-
 hw/syborg_timer.c     |    3 ++-
 hw/syborg_virtio.c    |    7 ++++---
 hw/sysbus.c           |    4 ++--
 hw/sysbus.h           |    2 +-
 hw/tcx.c              |    3 ++-
 hw/tmp105.c           |    3 ++-
 hw/tosa.c             |    6 ++++--
 hw/twl92230.c         |    3 ++-
 hw/unin_pci.c         |   24 ++++++++++++++++--------
 hw/versatile_pci.c    |   10 ++++++----
 hw/versatilepb.c      |    3 ++-
 hw/vga.c              |    5 +++--
 hw/virtio-pci.c       |   13 +++++++++----
 hw/vmware_vga.c       |    3 ++-
 hw/wm8750.c           |    3 ++-
 hw/xilinx_ethlite.c   |    3 ++-
 hw/xilinx_intc.c      |    3 ++-
 hw/xilinx_timer.c     |    3 ++-
 hw/xilinx_uartlite.c  |    3 ++-
 98 files changed, 312 insertions(+), 186 deletions(-)
Markus Armbruster - Aug. 12, 2009, 5 p.m.
Gerd Hoffmann <kraxel@redhat.com> writes:

> Sorry folks, but it has to be.  One more of these invasive qdev patches.
>
> We have a serious design bug in the qdev interface:  device init
> callbacks can't signal failure because the init() callback has no
> return value.  This patch fixes it.

Yupp.

> We have already one case in-tree where this is needed:
> Try -device virtio-blk-pci (without drive= specified) and watch qemu
> segfault.  This patch fixes it.
>
> With usb+scsi being converted to qdev we'll get more devices where the
> init callback can fail for various reasons.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

I verified that we either

* change a function returning void to return int instead, or

* insert return 0 at the end of a function, or

* change F() to return F(), for some F() that now returns int, or

* insert return -1 instead of continuing to a crash, in
  virtio_blk_init_pci(), or

* handle a failed device init(), in qdev_device_add().

[...]
> diff --git a/hw/vga.c b/hw/vga.c
> index 4a0f197..12c0424 100644
> --- a/hw/vga.c
> +++ b/hw/vga.c
> @@ -2480,7 +2480,7 @@ static void pci_vga_write_config(PCIDevice *d,
>          s->map_addr = 0;
>  }
>  
> -static void pci_vga_initfn(PCIDevice *dev)
> +static int pci_vga_initfn(PCIDevice *dev)
>  {
>       PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
>       VGAState *s = &d->vga_state;
> @@ -2511,7 +2511,8 @@ static void pci_vga_initfn(PCIDevice *dev)
>              bios_total_size <<= 1;
>          pci_register_bar(&d->dev, PCI_ROM_SLOT, bios_total_size,
>                           PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
> -    }
> +     }
> +     return 0;
>  }
>  
>  int pci_vga_init(PCIBus *bus,

Looks like slight white-space damage, but isn't; the whole function is
indented weirdly.

[...]

Acked-by: Markus Armbruster <armbru@redhat.com>
Paul Brook - Aug. 12, 2009, 7:28 p.m.
> We have already one case in-tree where this is needed:
> Try -device virtio-blk-pci (without drive= specified) and watch qemu
> segfault.

No. Failure of the init routine should be fatal. i.e. virtio_blk_init_pci 
should call hw_error.

If you want to allow graceful failure (which is pointless for commandline 
options, but may be desirable for hotplug devices) they you need to also add 
some way of reporting why device creation failure. fprintf(stderr) is just 
plain wrong.

Paul
Gerd Hoffmann - Aug. 12, 2009, 7:47 p.m.
On 08/12/09 21:28, Paul Brook wrote:
>> We have already one case in-tree where this is needed:
>> Try -device virtio-blk-pci (without drive= specified) and watch qemu
>> segfault.
>
> No. Failure of the init routine should be fatal. i.e. virtio_blk_init_pci
> should call hw_error.

No.  That policy doesn't belong there.

> If you want to allow graceful failure  (which is pointless for commandline
> options, but may be desirable for hotplug devices)

Exactly.  And for that reason we must pass up the error to the caller. 
The caller can then decide what to do with it.  For devices added via 
command line options we probably want to exit(1).  For hotplugging we 
probably would not.

> they you need to also add
> some way of reporting why device creation failure. fprintf(stderr) is just
> plain wrong.

Indeed.  When hotplugging via monitor the error message should appear on 
the monitor, not stderr.  It is already an item on my todo list.

I'd prefer to address that in a separate patch though, the patch is 
already big and invasive enough as-is.

cheers,
   Gerd
Markus Armbruster - Aug. 13, 2009, 6:17 a.m.
Gerd Hoffmann <kraxel@redhat.com> writes:

> On 08/12/09 21:28, Paul Brook wrote:
>>> We have already one case in-tree where this is needed:
>>> Try -device virtio-blk-pci (without drive= specified) and watch qemu
>>> segfault.
>>
>> No. Failure of the init routine should be fatal. i.e. virtio_blk_init_pci
>> should call hw_error.
>
> No.  That policy doesn't belong there.
>
>> If you want to allow graceful failure  (which is pointless for commandline
>> options, but may be desirable for hotplug devices)
>
> Exactly.  And for that reason we must pass up the error to the
> caller. The caller can then decide what to do with it.  For devices
> added via command line options we probably want to exit(1).  For
> hotplugging we probably would not.

exit(1) on typo in the monitor is not nice.

One problem with passing up error codes is diagnostics: when we reach
the point where we can decide on policy, we've lost the context for
precise diagnostics.  net.c tackles that problem by passing the
destination for diagnostics down, to let code report errors with
config_error() while remaining unaware of policy.

>> they you need to also add
>> some way of reporting why device creation failure. fprintf(stderr) is just
>> plain wrong.
>
> Indeed.  When hotplugging via monitor the error message should appear
> on the monitor, not stderr.  It is already an item on my todo list.

Issue also exists elsewhere.  Try monitor command "pci_add auto
model=?".

> I'd prefer to address that in a separate patch though, the patch is
> already big and invasive enough as-is.

It's easy to review for its size precisely because it does just one
simple thing.  Let's keep it that way.
Gerd Hoffmann - Aug. 13, 2009, 7:48 a.m.
On 08/13/09 08:17, Markus Armbruster wrote:

> One problem with passing up error codes is diagnostics: when we reach
> the point where we can decide on policy, we've lost the context for
> precise diagnostics.  net.c tackles that problem by passing the
> destination for diagnostics down, to let code report errors with
> config_error() while remaining unaware of policy.

I don't want pass additional arguments all the way down just for error 
reporting.  One thing we can do is storing the error message in a global 
or thread-local variable (much like errno).  We could also add a errmsg 
field to DeviceState and use that.

> Issue also exists elsewhere.  Try monitor command "pci_add auto
> model=?".

Thats why I'd tend to use a global variable.  It also works in case 
don't have a DeviceState.

cheers,
   Gerd
Markus Armbruster - Aug. 13, 2009, 9:06 a.m.
Gerd Hoffmann <kraxel@redhat.com> writes:

> On 08/13/09 08:17, Markus Armbruster wrote:
>
>> One problem with passing up error codes is diagnostics: when we reach
>> the point where we can decide on policy, we've lost the context for
>> precise diagnostics.  net.c tackles that problem by passing the
>> destination for diagnostics down, to let code report errors with
>> config_error() while remaining unaware of policy.
>
> I don't want pass additional arguments all the way down just for error
> reporting.

It sure is tedious and ugly.

>             One thing we can do is storing the error message in a
> global or thread-local variable (much like errno).  We could also add
> a errmsg field to DeviceState and use that.
>
>> Issue also exists elsewhere.  Try monitor command "pci_add auto
>> model=?".
>
> Thats why I'd tend to use a global variable.  It also works in case
> don't have a DeviceState.

I find stashing error messages for later printing rather awkward.  Do
you provide space for one fixed-sized message?  Or arbitrary length?
Arbitrary number of messages?  Once you start to malloc(), you get to
worry about free()...  Meh.

I'd rather use the global or thread-local state to hold the sink for the
messages, then send the messages there as we make them.  No memory
management worries.

Patch

diff --git a/hw/ac97.c b/hw/ac97.c
index 6c818c9..fe3b7b2 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -1308,7 +1308,7 @@  static void ac97_on_reset (void *opaque)
     mixer_reset (s);
 }
 
-static void ac97_initfn (PCIDevice *dev)
+static int ac97_initfn (PCIDevice *dev)
 {
     PCIAC97LinkState *d = DO_UPCAST (PCIAC97LinkState, dev, dev);
     AC97LinkState *s = &d->ac97;
@@ -1356,6 +1356,7 @@  static void ac97_initfn (PCIDevice *dev)
     qemu_register_reset (ac97_on_reset, s);
     AUD_register_card ("ac97", &s->card);
     ac97_on_reset (s);
+    return 0;
 }
 
 int ac97_init (PCIBus *bus)
diff --git a/hw/ads7846.c b/hw/ads7846.c
index 7d1cbc7..184b3dd 100644
--- a/hw/ads7846.c
+++ b/hw/ads7846.c
@@ -134,7 +134,7 @@  static int ads7846_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void ads7846_init(SSISlave *dev)
+static int ads7846_init(SSISlave *dev)
 {
     ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
 
@@ -152,6 +152,7 @@  static void ads7846_init(SSISlave *dev)
     ads7846_int_update(s);
 
     register_savevm("ads7846", -1, 0, ads7846_save, ads7846_load, s);
+    return 0;
 }
 
 static SSISlaveInfo ads7846_info = {
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 8b42fa8..6a6ea8f 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -260,7 +260,7 @@  PCIBus *pci_apb_init(target_phys_addr_t special_base,
     return d->host_state.bus;
 }
 
-static void pci_pbm_init_device(SysBusDevice *dev)
+static int pci_pbm_init_device(SysBusDevice *dev)
 {
 
     APBState *s;
@@ -283,9 +283,10 @@  static void pci_pbm_init_device(SysBusDevice *dev)
     pci_mem_data = cpu_register_io_memory(pci_apb_read,
                                           pci_apb_write, &s->host_state);
     sysbus_init_mmio(dev, 0x10000000ULL, pci_mem_data);
+    return 0;
 }
 
-static void pbm_pci_host_init(PCIDevice *d)
+static int pbm_pci_host_init(PCIDevice *d)
 {
     pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_SUN);
     pci_config_set_device_id(d->config, PCI_DEVICE_ID_SUN_SABRE);
@@ -298,6 +299,7 @@  static void pbm_pci_host_init(PCIDevice *d)
     pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
     d->config[0x0D] = 0x10; // latency_timer
     d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
+    return 0;
 }
 
 static PCIDeviceInfo pbm_pci_host_info = {
diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index 11b3787..02e5156 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -189,7 +189,7 @@  static CPUWriteMemoryFunc *arm_sysctl_writefn[] = {
    arm_sysctl_write
 };
 
-static void arm_sysctl_init1(SysBusDevice *dev)
+static int arm_sysctl_init1(SysBusDevice *dev)
 {
     arm_sysctl_state *s = FROM_SYSBUS(arm_sysctl_state, dev);
     int iomemtype;
@@ -201,6 +201,7 @@  static void arm_sysctl_init1(SysBusDevice *dev)
                                        arm_sysctl_writefn, s);
     sysbus_init_mmio(dev, 0x1000, iomemtype);
     /* ??? Save/restore.  */
+    return 0;
 }
 
 /* Legacy helper function.  */
diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index 572804f..91191dc 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -254,7 +254,7 @@  static int sp804_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void sp804_init(SysBusDevice *dev)
+static int sp804_init(SysBusDevice *dev)
 {
     int iomemtype;
     sp804_state *s = FROM_SYSBUS(sp804_state, dev);
@@ -272,6 +272,7 @@  static void sp804_init(SysBusDevice *dev)
                                        sp804_writefn, s);
     sysbus_init_mmio(dev, 0x1000, iomemtype);
     register_savevm("sp804", -1, 1, sp804_save, sp804_load, s);
+    return 0;
 }
 
 
@@ -323,7 +324,7 @@  static CPUWriteMemoryFunc *icp_pit_writefn[] = {
    icp_pit_write
 };
 
-static void icp_pit_init(SysBusDevice *dev)
+static int icp_pit_init(SysBusDevice *dev)
 {
     int iomemtype;
     icp_pit_state *s = FROM_SYSBUS(icp_pit_state, dev);
@@ -343,6 +344,7 @@  static void icp_pit_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, 0x1000, iomemtype);
     /* This device has no state to save/restore.  The component timers will
        save themselves.  */
+    return 0;
 }
 
 static void arm_timer_register_devices(void)
diff --git a/hw/armv7m.c b/hw/armv7m.c
index 2e4f0ed..38bee57 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -122,7 +122,7 @@  typedef struct {
     uint32_t base;
 } BitBandState;
 
-static void bitband_init(SysBusDevice *dev)
+static int bitband_init(SysBusDevice *dev)
 {
     BitBandState *s = FROM_SYSBUS(BitBandState, dev);
     int iomemtype;
@@ -130,6 +130,7 @@  static void bitband_init(SysBusDevice *dev)
     iomemtype = cpu_register_io_memory(bitband_readfn, bitband_writefn,
                                        &s->base);
     sysbus_init_mmio(dev, 0x02000000, iomemtype);
+    return 0;
 }
 
 static void armv7m_bitband_init(void)
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index f789c78..3360808 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -390,7 +390,7 @@  static int nvic_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void armv7m_nvic_init(SysBusDevice *dev)
+static int armv7m_nvic_init(SysBusDevice *dev)
 {
     nvic_state *s= FROM_SYSBUSGIC(nvic_state, dev);
 
@@ -398,6 +398,7 @@  static void armv7m_nvic_init(SysBusDevice *dev)
     cpu_register_physical_memory(0xe000e000, 0x1000, s->gic.iomemtype);
     s->systick.timer = qemu_new_timer(vm_clock, systick_timer_tick, s);
     register_savevm("armv7m_nvic", -1, 1, nvic_save, nvic_load, s);
+    return 0;
 }
 
 static void armv7m_nvic_register_devices(void)
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 95d822a..d5092ce 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -3302,7 +3302,7 @@  static void pci_cirrus_write_config(PCIDevice *d,
     cirrus_update_memory_access(s);
 }
 
-static void pci_cirrus_vga_initfn(PCIDevice *dev)
+static int pci_cirrus_vga_initfn(PCIDevice *dev)
 {
      PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
      CirrusVGAState *s = &d->cirrus_vga;
@@ -3335,6 +3335,7 @@  static void pci_cirrus_vga_initfn(PCIDevice *dev)
                           PCI_ADDRESS_SPACE_MEM, cirrus_pci_mmio_map);
      }
      /* XXX: ROM BIOS */
+     return 0;
 }
 
 void pci_cirrus_vga_init(PCIBus *bus)
diff --git a/hw/cs4231.c b/hw/cs4231.c
index f13815b..6fce78d 100644
--- a/hw/cs4231.c
+++ b/hw/cs4231.c
@@ -167,7 +167,7 @@  static int cs_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void cs4231_init1(SysBusDevice *dev)
+static int cs4231_init1(SysBusDevice *dev)
 {
     int io;
     CSState *s = FROM_SYSBUS(CSState, dev);
@@ -179,6 +179,7 @@  static void cs4231_init1(SysBusDevice *dev)
     register_savevm("cs4231", -1, 1, cs_save, cs_load, s);
     qemu_register_reset(cs_reset, s);
     cs_reset(s);
+    return 0;
 }
 
 static SysBusDeviceInfo cs4231_info = {
diff --git a/hw/e1000.c b/hw/e1000.c
index b0542d7..a845822 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1081,7 +1081,7 @@  static void e1000_reset(void *opaque)
     memset(&d->tx, 0, sizeof d->tx);
 }
 
-static void pci_e1000_init(PCIDevice *pci_dev)
+static int pci_e1000_init(PCIDevice *pci_dev)
 {
     E1000State *d = (E1000State *)pci_dev;
     uint8_t *pci_conf;
@@ -1132,6 +1132,7 @@  static void pci_e1000_init(PCIDevice *pci_dev)
     d->dev.unregister = pci_e1000_uninit;
     qemu_register_reset(e1000_reset, d);
     e1000_reset(d);
+    return 0;
 }
 
 static PCIDeviceInfo e1000_info = {
diff --git a/hw/eccmemctl.c b/hw/eccmemctl.c
index a19a112..f1dbcbd 100644
--- a/hw/eccmemctl.c
+++ b/hw/eccmemctl.c
@@ -315,7 +315,7 @@  static void ecc_reset(void *opaque)
     s->regs[ECC_ECR1] = 0;
 }
 
-static void ecc_init1(SysBusDevice *dev)
+static int ecc_init1(SysBusDevice *dev)
 {
     int ecc_io_memory;
     ECCState *s = FROM_SYSBUS(ECCState, dev);
@@ -333,6 +333,7 @@  static void ecc_init1(SysBusDevice *dev)
     register_savevm("ECC", -1, 3, ecc_save, ecc_load, s);
     qemu_register_reset(ecc_reset, s);
     ecc_reset(s);
+    return 0;
 }
 
 static SysBusDeviceInfo ecc_info = {
diff --git a/hw/eepro100.c b/hw/eepro100.c
index ec31a6a..f4cb59f 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1728,7 +1728,7 @@  static int pci_nic_uninit(PCIDevice *dev)
     return 0;
 }
 
-static void nic_init(PCIDevice *pci_dev, uint32_t device)
+static int nic_init(PCIDevice *pci_dev, uint32_t device)
 {
     PCIEEPRO100State *d = (PCIEEPRO100State *)pci_dev;
     EEPRO100State *s;
@@ -1774,21 +1774,22 @@  static void nic_init(PCIDevice *pci_dev, uint32_t device)
     qemu_register_reset(nic_reset, s);
 
     register_savevm(s->vc->model, -1, 3, nic_save, nic_load, s);
+    return 0;
 }
 
-static void pci_i82551_init(PCIDevice *dev)
+static int pci_i82551_init(PCIDevice *dev)
 {
-    nic_init(dev, i82551);
+    return nic_init(dev, i82551);
 }
 
-static void pci_i82557b_init(PCIDevice *dev)
+static int pci_i82557b_init(PCIDevice *dev)
 {
-    nic_init(dev, i82557B);
+    return nic_init(dev, i82557B);
 }
 
-static void pci_i82559er_init(PCIDevice *dev)
+static int pci_i82559er_init(PCIDevice *dev)
 {
-    nic_init(dev, i82559ER);
+    return nic_init(dev, i82559ER);
 }
 
 static PCIDeviceInfo eepro100_info[] = {
diff --git a/hw/es1370.c b/hw/es1370.c
index 5c9af0e..b206655 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -1005,7 +1005,7 @@  static void es1370_on_reset (void *opaque)
     es1370_reset (s);
 }
 
-static void es1370_initfn(PCIDevice *dev)
+static int es1370_initfn(PCIDevice *dev)
 {
     PCIES1370State *d = DO_UPCAST(PCIES1370State, dev, dev);
     ES1370State *s = &d->es1370;
@@ -1044,6 +1044,7 @@  static void es1370_initfn(PCIDevice *dev)
 
     AUD_register_card ("es1370", &s->card);
     es1370_reset (s);
+    return 0;
 }
 
 int es1370_init (PCIBus *bus)
diff --git a/hw/escc.c b/hw/escc.c
index 74a96cd..26ba34d 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -911,7 +911,7 @@  void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
     sysbus_mmio_map(s, 0, base);
 }
 
-static void escc_init1(SysBusDevice *dev)
+static int escc_init1(SysBusDevice *dev)
 {
     SerialState *s = FROM_SYSBUS(SerialState, dev);
     int io;
@@ -945,6 +945,7 @@  static void escc_init1(SysBusDevice *dev)
     register_savevm("escc", -1, 2, escc_save, escc_load, s);
     qemu_register_reset(escc_reset, s);
     escc_reset(s);
+    return 0;
 }
 
 static SysBusDeviceInfo escc_info = {
diff --git a/hw/esp.c b/hw/esp.c
index 146a73a..850b6a7 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -670,7 +670,7 @@  void esp_init(target_phys_addr_t espaddr, int it_shift,
     *reset = qdev_get_gpio_in(dev, 0);
 }
 
-static void esp_init1(SysBusDevice *dev)
+static int esp_init1(SysBusDevice *dev)
 {
     ESPState *s = FROM_SYSBUS(ESPState, dev);
     int esp_io_memory;
@@ -689,6 +689,7 @@  static void esp_init1(SysBusDevice *dev)
     qdev_init_gpio_in(&dev->qdev, parent_esp_reset, 1);
 
     scsi_bus_new(&dev->qdev, esp_scsi_attach);
+    return 0;
 }
 
 static void esp_register_devices(void)
diff --git a/hw/etraxfs_pic.c b/hw/etraxfs_pic.c
index 4527d98..7f99e64 100644
--- a/hw/etraxfs_pic.c
+++ b/hw/etraxfs_pic.c
@@ -136,7 +136,7 @@  static void irq_handler(void *opaque, int irq, int level)
     pic_update(fs);
 }
 
-static void etraxfs_pic_init(SysBusDevice *dev)
+static int etraxfs_pic_init(SysBusDevice *dev)
 {
     struct etrax_pic *s = FROM_SYSBUS(typeof (*s), dev);
     int intr_vect_regs;
@@ -147,6 +147,7 @@  static void etraxfs_pic_init(SysBusDevice *dev)
 
     intr_vect_regs = cpu_register_io_memory(pic_read, pic_write, s);
     sysbus_init_mmio(dev, R_MAX * 4, intr_vect_regs);
+    return 0;
 }
 
 static SysBusDeviceInfo etraxfs_pic_info = {
diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
index 7cb5e71..022a2f5 100644
--- a/hw/etraxfs_ser.c
+++ b/hw/etraxfs_ser.c
@@ -161,7 +161,7 @@  static void serial_event(void *opaque, int event)
 
 }
 
-static void etraxfs_ser_init(SysBusDevice *dev)
+static int etraxfs_ser_init(SysBusDevice *dev)
 {
     struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev);
     int ser_regs;
@@ -178,6 +178,7 @@  static void etraxfs_ser_init(SysBusDevice *dev)
         qemu_chr_add_handlers(s->chr,
                       serial_can_receive, serial_receive,
                       serial_event, s);
+    return 0;
 }
 
 static void etraxfs_serial_register(void)
diff --git a/hw/etraxfs_timer.c b/hw/etraxfs_timer.c
index 450e7d1..639c0d1 100644
--- a/hw/etraxfs_timer.c
+++ b/hw/etraxfs_timer.c
@@ -308,7 +308,7 @@  static void etraxfs_timer_reset(void *opaque)
     qemu_irq_lower(t->irq);
 }
 
-static void etraxfs_timer_init(SysBusDevice *dev)
+static int etraxfs_timer_init(SysBusDevice *dev)
 {
     struct etrax_timer *t = FROM_SYSBUS(typeof (*t), dev);
     int timer_regs;
@@ -327,6 +327,7 @@  static void etraxfs_timer_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, 0x5c, timer_regs);
 
     qemu_register_reset(etraxfs_timer_reset, t);
+    return 0;
 }
 
 static void etraxfs_timer_register(void)
diff --git a/hw/fdc.c b/hw/fdc.c
index c55560f..e25644c 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1925,7 +1925,7 @@  fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base,
     return fdctrl;
 }
 
-static void fdctrl_init_common(fdctrl_t *fdctrl)
+static int fdctrl_init_common(fdctrl_t *fdctrl)
 {
     int i, j;
     static int command_tables_inited = 0;
@@ -1953,9 +1953,10 @@  static void fdctrl_init_common(fdctrl_t *fdctrl)
     fdctrl_external_reset(fdctrl);
     register_savevm("fdc", -1, 2, fdc_save, fdc_load, fdctrl);
     qemu_register_reset(fdctrl_external_reset, fdctrl);
+    return 0;
 }
 
-static void isabus_fdc_init1(ISADevice *dev)
+static int isabus_fdc_init1(ISADevice *dev)
 {
     fdctrl_isabus_t *isa = DO_UPCAST(fdctrl_isabus_t, busdev, dev);
     fdctrl_t *fdctrl = &isa->state;
@@ -1970,10 +1971,10 @@  static void isabus_fdc_init1(ISADevice *dev)
                           &fdctrl_write_port, fdctrl);
     isa_init_irq(&isa->busdev, &fdctrl->irq);
 
-    fdctrl_init_common(fdctrl);
+    return fdctrl_init_common(fdctrl);
 }
 
-static void sysbus_fdc_init1(SysBusDevice *dev)
+static int sysbus_fdc_init1(SysBusDevice *dev)
 {
     fdctrl_t *fdctrl = &(FROM_SYSBUS(fdctrl_sysbus_t, dev)->state);
     int io;
@@ -1983,10 +1984,10 @@  static void sysbus_fdc_init1(SysBusDevice *dev)
     sysbus_init_irq(dev, &fdctrl->irq);
     qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1);
 
-    fdctrl_init_common(fdctrl);
+    return fdctrl_init_common(fdctrl);
 }
 
-static void sun4m_fdc_init1(SysBusDevice *dev)
+static int sun4m_fdc_init1(SysBusDevice *dev)
 {
     fdctrl_t *fdctrl = &(FROM_SYSBUS(fdctrl_sysbus_t, dev)->state);
     int io;
@@ -1998,7 +1999,7 @@  static void sun4m_fdc_init1(SysBusDevice *dev)
     qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1);
 
     fdctrl->sun4m = 1;
-    fdctrl_init_common(fdctrl);
+    return fdctrl_init_common(fdctrl);
 }
 
 static ISADeviceInfo isa_fdc_info = {
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index b893ebe..38780f9 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -152,7 +152,7 @@  PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
     return d->host_state.bus;
 }
 
-static void pci_grackle_init_device(SysBusDevice *dev)
+static int pci_grackle_init_device(SysBusDevice *dev)
 {
     GrackleState *s;
     int pci_mem_config, pci_mem_data;
@@ -171,9 +171,10 @@  static void pci_grackle_init_device(SysBusDevice *dev)
                     &s->host_state);
     qemu_register_reset(pci_grackle_reset, &s->host_state);
     pci_grackle_reset(&s->host_state);
+    return 0;
 }
 
-static void pci_dec_21154_init_device(SysBusDevice *dev)
+static int pci_dec_21154_init_device(SysBusDevice *dev)
 {
     GrackleState *s;
     int pci_mem_config, pci_mem_data;
@@ -187,9 +188,10 @@  static void pci_dec_21154_init_device(SysBusDevice *dev)
                                           &s->host_state);
     sysbus_init_mmio(dev, 0x1000, pci_mem_config);
     sysbus_init_mmio(dev, 0x1000, pci_mem_data);
+    return 0;
 }
 
-static void grackle_pci_host_init(PCIDevice *d)
+static int grackle_pci_host_init(PCIDevice *d)
 {
     pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_MOTOROLA);
     pci_config_set_device_id(d->config, PCI_DEVICE_ID_MOTOROLA_MPC106);
@@ -197,9 +199,10 @@  static void grackle_pci_host_init(PCIDevice *d)
     d->config[0x09] = 0x01;
     pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
     d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
+    return 0;
 }
 
-static void dec_21154_pci_host_init(PCIDevice *d)
+static int dec_21154_pci_host_init(PCIDevice *d)
 {
     /* PCI2PCI bridge same values as PearPC - check this */
     pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_DEC);
@@ -223,6 +226,7 @@  static void dec_21154_pci_host_init(PCIDevice *d)
     d->config[0x25] = 0x84;
     d->config[0x26] = 0x00; // prefetchable_memory_limit
     d->config[0x27] = 0x85;
+    return 0;
 }
 
 static PCIDeviceInfo grackle_pci_host_info = {
diff --git a/hw/i2c.c b/hw/i2c.c
index 7a1b358..5473772 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -149,14 +149,14 @@  void i2c_slave_load(QEMUFile *f, i2c_slave *dev)
     }
 }
 
-static void i2c_slave_qdev_init(DeviceState *dev, DeviceInfo *base)
+static int i2c_slave_qdev_init(DeviceState *dev, DeviceInfo *base)
 {
     I2CSlaveInfo *info = container_of(base, I2CSlaveInfo, qdev);
     i2c_slave *s = I2C_SLAVE_FROM_QDEV(dev);
 
     s->info = info;
 
-    info->init(s);
+    return info->init(s);
 }
 
 void i2c_register_slave(I2CSlaveInfo *info)
diff --git a/hw/i2c.h b/hw/i2c.h
index 479ff4b..238f256 100644
--- a/hw/i2c.h
+++ b/hw/i2c.h
@@ -22,7 +22,7 @@  typedef int (*i2c_recv_cb)(i2c_slave *s);
 /* Notify the slave of a bus state change.  */
 typedef void (*i2c_event_cb)(i2c_slave *s, enum i2c_event event);
 
-typedef void (*i2c_slave_initfn)(i2c_slave *dev);
+typedef int (*i2c_slave_initfn)(i2c_slave *dev);
 
 typedef struct {
     DeviceInfo qdev;
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index 2d83004..3ec4eec 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -227,7 +227,7 @@  static CPUWriteMemoryFunc *integratorcm_writefn[] = {
    integratorcm_write
 };
 
-static void integratorcm_init(SysBusDevice *dev)
+static int integratorcm_init(SysBusDevice *dev)
 {
     int iomemtype;
     integratorcm_state *s = FROM_SYSBUS(integratorcm_state, dev);
@@ -260,6 +260,7 @@  static void integratorcm_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, 0x00800000, iomemtype);
     integratorcm_do_remap(s, 1);
     /* ??? Save/restore.  */
+    return 0;
 }
 
 /* Integrator/CP hardware emulation.  */
@@ -372,7 +373,7 @@  static CPUWriteMemoryFunc *icp_pic_writefn[] = {
    icp_pic_write
 };
 
-static void icp_pic_init(SysBusDevice *dev)
+static int icp_pic_init(SysBusDevice *dev)
 {
     icp_pic_state *s = FROM_SYSBUS(icp_pic_state, dev);
     int iomemtype;
@@ -383,6 +384,7 @@  static void icp_pic_init(SysBusDevice *dev)
     iomemtype = cpu_register_io_memory(icp_pic_readfn,
                                        icp_pic_writefn, s);
     sysbus_init_mmio(dev, 0x00800000, iomemtype);
+    return 0;
 }
 
 /* CP control registers.  */
diff --git a/hw/iommu.c b/hw/iommu.c
index 52385f7..60c955f 100644
--- a/hw/iommu.c
+++ b/hw/iommu.c
@@ -366,7 +366,7 @@  static void iommu_reset(void *opaque)
     s->regs[IOMMU_MASK_ID] = IOMMU_TS_MASK;
 }
 
-static void iommu_init1(SysBusDevice *dev)
+static int iommu_init1(SysBusDevice *dev)
 {
     IOMMUState *s = FROM_SYSBUS(IOMMUState, dev);
     int io;
@@ -379,6 +379,7 @@  static void iommu_init1(SysBusDevice *dev)
     register_savevm("iommu", -1, 2, iommu_save, iommu_load, s);
     qemu_register_reset(iommu_reset, s);
     iommu_reset(s);
+    return 0;
 }
 
 static SysBusDeviceInfo iommu_info = {
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 8c14b1d..b373427 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -69,12 +69,12 @@  void isa_init_irq(ISADevice *dev, qemu_irq *p)
     dev->nirqs++;
 }
 
-static void isa_qdev_init(DeviceState *qdev, DeviceInfo *base)
+static int isa_qdev_init(DeviceState *qdev, DeviceInfo *base)
 {
     ISADevice *dev = DO_UPCAST(ISADevice, qdev, qdev);
     ISADeviceInfo *info = DO_UPCAST(ISADeviceInfo, qdev, base);
 
-    info->init(dev);
+    return info->init(dev);
 }
 
 void isa_qdev_register(ISADeviceInfo *info)
diff --git a/hw/isa.h b/hw/isa.h
index 49c58f8..1ad93bf 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -17,7 +17,7 @@  struct ISADevice {
     int nirqs;
 };
 
-typedef void (*isa_qdev_initfn)(ISADevice *dev);
+typedef int (*isa_qdev_initfn)(ISADevice *dev);
 struct ISADeviceInfo {
     DeviceInfo qdev;
     isa_qdev_initfn init;
diff --git a/hw/lm832x.c b/hw/lm832x.c
index 197fe7d..32bfcb0 100644
--- a/hw/lm832x.c
+++ b/hw/lm832x.c
@@ -488,7 +488,7 @@  static int lm_kbd_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void lm8323_init(i2c_slave *i2c)
+static int lm8323_init(i2c_slave *i2c)
 {
     LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
 
@@ -502,6 +502,7 @@  static void lm8323_init(i2c_slave *i2c)
 
     qemu_register_reset((void *) lm_kbd_reset, s);
     register_savevm("LM8323", -1, 0, lm_kbd_save, lm_kbd_load, s);
+    return 0;
 }
 
 void lm832x_key_event(struct i2c_slave *i2c, int key, int state)
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index f749a45..938245b 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -2163,7 +2163,7 @@  static int lsi_scsi_uninit(PCIDevice *d)
     return 0;
 }
 
-static void lsi_scsi_init(PCIDevice *dev)
+static int lsi_scsi_init(PCIDevice *dev)
 {
     LSIState *s = (LSIState *)dev;
     uint8_t *pci_conf;
@@ -2205,6 +2205,7 @@  static void lsi_scsi_init(PCIDevice *dev)
     scsi_bus_new(&dev->qdev, lsi_scsi_attach);
 
     register_savevm("lsiscsi", -1, 0, lsi_scsi_save, lsi_scsi_load, s);
+    return 0;
 }
 
 static PCIDeviceInfo lsi_info = {
diff --git a/hw/m48t59.c b/hw/m48t59.c
index 6541cbe..c6d27bb 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -642,7 +642,7 @@  m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base,
     return d;
 }
 
-static void m48t59_init1(SysBusDevice *dev)
+static int m48t59_init1(SysBusDevice *dev)
 {
     m48t59_t *s = FROM_SYSBUS(m48t59_t, dev);
     int mem_index;
@@ -661,6 +661,7 @@  static void m48t59_init1(SysBusDevice *dev)
 
     qemu_register_reset(m48t59_reset, s);
     register_savevm("m48t59", -1, 1, m48t59_save, m48t59_load, s);
+    return 0;
 }
 
 static SysBusDeviceInfo m48t59_info = {
diff --git a/hw/max111x.c b/hw/max111x.c
index f7023a8..bd656bb 100644
--- a/hw/max111x.c
+++ b/hw/max111x.c
@@ -125,7 +125,7 @@  static int max111x_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void max111x_init(SSISlave *dev, int inputs)
+static int max111x_init(SSISlave *dev, int inputs)
 {
     MAX111xState *s = FROM_SSI_SLAVE(MAX111xState, dev);
 
@@ -144,16 +144,17 @@  static void max111x_init(SSISlave *dev, int inputs)
     s->com = 0;
 
     register_savevm("max111x", -1, 0, max111x_save, max111x_load, s);
+    return 0;
 }
 
-static void max1110_init(SSISlave *dev)
+static int max1110_init(SSISlave *dev)
 {
-    max111x_init(dev, 8);
+    return max111x_init(dev, 8);
 }
 
-static void max1111_init(SSISlave *dev)
+static int max1111_init(SSISlave *dev)
 {
-    max111x_init(dev, 4);
+    return max111x_init(dev, 4);
 }
 
 void max111x_set_input(DeviceState *dev, int line, uint8_t value)
diff --git a/hw/max7310.c b/hw/max7310.c
index a571e57..e737133 100644
--- a/hw/max7310.c
+++ b/hw/max7310.c
@@ -190,7 +190,7 @@  static void max7310_gpio_set(void *opaque, int line, int level)
 
 /* MAX7310 is SMBus-compatible (can be used with only SMBus protocols),
  * but also accepts sequences that are not SMBus so return an I2C device.  */
-static void max7310_init(i2c_slave *i2c)
+static int max7310_init(i2c_slave *i2c)
 {
     MAX7310State *s = FROM_I2C_SLAVE(MAX7310State, i2c);
 
@@ -200,6 +200,7 @@  static void max7310_init(i2c_slave *i2c)
     max7310_reset(&s->i2c);
 
     register_savevm("max7310", -1, 0, max7310_save, max7310_load, s);
+    return 0;
 }
 
 qemu_irq *max7310_gpio_in_get(i2c_slave *i2c)
diff --git a/hw/mpcore.c b/hw/mpcore.c
index 907bd99..01c5446 100644
--- a/hw/mpcore.c
+++ b/hw/mpcore.c
@@ -262,7 +262,7 @@  static void mpcore_priv_map(SysBusDevice *dev, target_phys_addr_t base)
     cpu_register_physical_memory(base + 0x1000, 0x1000, s->gic.iomemtype);
 }
 
-static void mpcore_priv_init(SysBusDevice *dev)
+static int mpcore_priv_init(SysBusDevice *dev)
 {
     mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev);
     int i;
@@ -274,6 +274,7 @@  static void mpcore_priv_init(SysBusDevice *dev)
     for (i = 0; i < 8; i++) {
         mpcore_timer_init(s, &s->timer[i], i);
     }
+    return 0;
 }
 
 /* Dummy PIC to route IRQ lines.  The baseboard has 4 independent IRQ
@@ -309,7 +310,7 @@  static void mpcore_rirq_set_irq(void *opaque, int irq, int level)
     }
 }
 
-static void realview_mpcore_init(SysBusDevice *dev)
+static int realview_mpcore_init(SysBusDevice *dev)
 {
     mpcore_rirq_state *s = FROM_SYSBUS(mpcore_rirq_state, dev);
     DeviceState *gic;
@@ -331,6 +332,7 @@  static void realview_mpcore_init(SysBusDevice *dev)
         }
     }
     qdev_init_gpio_in(&dev->qdev, mpcore_rirq_set_irq, 64);
+    return 0;
 }
 
 static void mpcore_register_devices(void)
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 2d26b33..db8d52c 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -748,7 +748,7 @@  static void eth_cleanup(VLANClientState *vc)
     qemu_free(s);
 }
 
-static void mv88w8618_eth_init(SysBusDevice *dev)
+static int mv88w8618_eth_init(SysBusDevice *dev)
 {
     mv88w8618_eth_state *s = FROM_SYSBUS(mv88w8618_eth_state, dev);
 
@@ -759,6 +759,7 @@  static void mv88w8618_eth_init(SysBusDevice *dev)
     s->mmio_index = cpu_register_io_memory(mv88w8618_eth_readfn,
                                            mv88w8618_eth_writefn, s);
     sysbus_init_mmio(dev, MP_ETH_SIZE, s->mmio_index);
+    return 0;
 }
 
 /* LCD register offsets */
@@ -941,7 +942,7 @@  static CPUWriteMemoryFunc *musicpal_lcd_writefn[] = {
     musicpal_lcd_write
 };
 
-static void musicpal_lcd_init(SysBusDevice *dev)
+static int musicpal_lcd_init(SysBusDevice *dev)
 {
     musicpal_lcd_state *s = FROM_SYSBUS(musicpal_lcd_state, dev);
     int iomemtype;
@@ -954,6 +955,7 @@  static void musicpal_lcd_init(SysBusDevice *dev)
     s->ds = graphic_console_init(lcd_refresh, lcd_invalidate,
                                  NULL, NULL, s);
     qemu_console_resize(s->ds, 128*3, 64*3);
+    return 0;
 }
 
 /* PIC register offsets */
@@ -1036,7 +1038,7 @@  static CPUWriteMemoryFunc *mv88w8618_pic_writefn[] = {
     mv88w8618_pic_write
 };
 
-static void mv88w8618_pic_init(SysBusDevice *dev)
+static int mv88w8618_pic_init(SysBusDevice *dev)
 {
     mv88w8618_pic_state *s = FROM_SYSBUS(mv88w8618_pic_state, dev);
     int iomemtype;
@@ -1048,6 +1050,7 @@  static void mv88w8618_pic_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, MP_PIC_SIZE, iomemtype);
 
     qemu_register_reset(mv88w8618_pic_reset, s);
+    return 0;
 }
 
 /* PIT register offsets */
@@ -1155,7 +1158,7 @@  static CPUWriteMemoryFunc *mv88w8618_pit_writefn[] = {
     mv88w8618_pit_write
 };
 
-static void mv88w8618_pit_init(SysBusDevice *dev)
+static int mv88w8618_pit_init(SysBusDevice *dev)
 {
     int iomemtype;
     mv88w8618_pit_state *s = FROM_SYSBUS(mv88w8618_pit_state, dev);
@@ -1170,6 +1173,7 @@  static void mv88w8618_pit_init(SysBusDevice *dev)
     iomemtype = cpu_register_io_memory(mv88w8618_pit_readfn,
                                        mv88w8618_pit_writefn, s);
     sysbus_init_mmio(dev, MP_PIT_SIZE, iomemtype);
+    return 0;
 }
 
 /* Flash config register offsets */
@@ -1218,7 +1222,7 @@  static CPUWriteMemoryFunc *mv88w8618_flashcfg_writefn[] = {
     mv88w8618_flashcfg_write
 };
 
-static void mv88w8618_flashcfg_init(SysBusDevice *dev)
+static int mv88w8618_flashcfg_init(SysBusDevice *dev)
 {
     int iomemtype;
     mv88w8618_flashcfg_state *s = FROM_SYSBUS(mv88w8618_flashcfg_state, dev);
@@ -1227,6 +1231,7 @@  static void mv88w8618_flashcfg_init(SysBusDevice *dev)
     iomemtype = cpu_register_io_memory(mv88w8618_flashcfg_readfn,
                        mv88w8618_flashcfg_writefn, s);
     sysbus_init_mmio(dev, MP_FLASHCFG_SIZE, iomemtype);
+    return 0;
 }
 
 /* Misc register offsets */
@@ -1307,13 +1312,14 @@  static CPUWriteMemoryFunc *mv88w8618_wlan_writefn[] = {
     mv88w8618_wlan_write,
 };
 
-static void mv88w8618_wlan_init(SysBusDevice *dev)
+static int mv88w8618_wlan_init(SysBusDevice *dev)
 {
     int iomemtype;
 
     iomemtype = cpu_register_io_memory(mv88w8618_wlan_readfn,
                                        mv88w8618_wlan_writefn, NULL);
     sysbus_init_mmio(dev, MP_WLAN_SIZE, iomemtype);
+    return 0;
 }
 
 /* GPIO register offsets */
diff --git a/hw/ne2000.c b/hw/ne2000.c
index b9c018a..9f685b4 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -803,7 +803,7 @@  static void ne2000_cleanup(VLANClientState *vc)
     unregister_savevm("ne2000", s);
 }
 
-static void pci_ne2000_init(PCIDevice *pci_dev)
+static int pci_ne2000_init(PCIDevice *pci_dev)
 {
     PCINE2000State *d = (PCINE2000State *)pci_dev;
     NE2000State *s;
@@ -830,6 +830,7 @@  static void pci_ne2000_init(PCIDevice *pci_dev)
     qemu_format_nic_info_str(s->vc, s->macaddr);
 
     register_savevm("ne2000", -1, 3, ne2000_save, ne2000_load, s);
+    return 0;
 }
 
 static PCIDeviceInfo ne2000_info = {
diff --git a/hw/pci.c b/hw/pci.c
index 27eac04..73a7f6e 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -892,7 +892,7 @@  PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did,
     return s->bus;
 }
 
-static void pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
+static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
 {
     PCIDevice *pci_dev = (PCIDevice *)qdev;
     PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
@@ -904,7 +904,7 @@  static void pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
     pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn,
                                      info->config_read, info->config_write);
     assert(pci_dev);
-    info->init(pci_dev);
+    return info->init(pci_dev);
 }
 
 void pci_qdev_register(PCIDeviceInfo *info)
diff --git a/hw/pci.h b/hw/pci.h
index a2ec16a..87b4665 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -313,7 +313,7 @@  pci_config_set_class(uint8_t *pci_config, uint16_t val)
     pci_set_word(&pci_config[PCI_CLASS_DEVICE], val);
 }
 
-typedef void (*pci_qdev_initfn)(PCIDevice *dev);
+typedef int (*pci_qdev_initfn)(PCIDevice *dev);
 typedef struct {
     DeviceInfo qdev;
     pci_qdev_initfn init;
diff --git a/hw/pckbd.c b/hw/pckbd.c
index bb4cc0e..b1ffaa3 100644
--- a/hw/pckbd.c
+++ b/hw/pckbd.c
@@ -446,7 +446,7 @@  typedef struct ISAKBDState {
     KBDState  kbd;
 } ISAKBDState;
 
-static void i8042_initfn(ISADevice *dev)
+static int i8042_initfn(ISADevice *dev)
 {
     KBDState *s = &(DO_UPCAST(ISAKBDState, dev, dev)->kbd);
 
@@ -466,6 +466,7 @@  static void i8042_initfn(ISADevice *dev)
     vmmouse_init(s->mouse);
 #endif
     qemu_register_reset(kbd_reset, s);
+    return 0;
 }
 
 static ISADeviceInfo i8042_info = {
diff --git a/hw/pcnet.c b/hw/pcnet.c
index 637dcfb..fc983ff 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -1948,7 +1948,7 @@  static void pcnet_common_cleanup(PCNetState *d)
     qemu_free_timer(d->poll_timer);
 }
 
-static void pcnet_common_init(DeviceState *dev, PCNetState *s,
+static int pcnet_common_init(DeviceState *dev, PCNetState *s,
                               NetCleanup *cleanup)
 {
     s->poll_timer = qemu_new_timer(vm_clock, pcnet_poll_timer, s);
@@ -1959,6 +1959,7 @@  static void pcnet_common_init(DeviceState *dev, PCNetState *s,
                                  cleanup, s);
     pcnet_h_reset(s);
     register_savevm("pcnet", -1, 2, pcnet_save, pcnet_load, s);
+    return 0;
 }
 
 /* PCI interface */
@@ -2015,7 +2016,7 @@  static int pci_pcnet_uninit(PCIDevice *dev)
     return 0;
 }
 
-static void pci_pcnet_init(PCIDevice *pci_dev)
+static int pci_pcnet_init(PCIDevice *pci_dev)
 {
     PCIPCNetState *d = (PCIPCNetState *)pci_dev;
     PCNetState *s = &d->state;
@@ -2061,7 +2062,7 @@  static void pci_pcnet_init(PCIDevice *pci_dev)
     s->phys_mem_write = pci_physical_memory_write;
     s->pci_dev = pci_dev;
 
-    pcnet_common_init(&pci_dev->qdev, s, pci_pcnet_cleanup);
+    return pcnet_common_init(&pci_dev->qdev, s, pci_pcnet_cleanup);
 }
 
 /* SPARC32 interface */
@@ -2120,7 +2121,7 @@  static void lance_cleanup(VLANClientState *vc)
     pcnet_common_cleanup(d);
 }
 
-static void lance_init(SysBusDevice *dev)
+static int lance_init(SysBusDevice *dev)
 {
     SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev);
     PCNetState *s = &d->state;
@@ -2137,7 +2138,7 @@  static void lance_init(SysBusDevice *dev)
     s->phys_mem_read = ledma_memory_read;
     s->phys_mem_write = ledma_memory_write;
 
-    pcnet_common_init(&dev->qdev, s, lance_cleanup);
+    return pcnet_common_init(&dev->qdev, s, lance_cleanup);
 }
 
 static SysBusDeviceInfo lance_info = {
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index e2ddf4b..c9fef92 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -171,7 +171,7 @@  static int i440fx_load(QEMUFile* f, void *opaque, int version_id)
     return 0;
 }
 
-static void i440fx_pcihost_initfn(SysBusDevice *dev)
+static int i440fx_pcihost_initfn(SysBusDevice *dev)
 {
     I440FXState *s = FROM_SYSBUS(I440FXState, dev);
 
@@ -184,9 +184,10 @@  static void i440fx_pcihost_initfn(SysBusDevice *dev)
     register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s);
     register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);
     register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);
+    return 0;
 }
 
-static void i440fx_initfn(PCIDevice *d)
+static int i440fx_initfn(PCIDevice *d)
 {
     pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_INTEL);
     pci_config_set_device_id(d->config, PCI_DEVICE_ID_INTEL_82441);
@@ -197,6 +198,7 @@  static void i440fx_initfn(PCIDevice *d)
     d->config[0x72] = 0x02; /* SMRAM */
 
     register_savevm("I440FX", 0, 2, i440fx_save, i440fx_load, d);
+    return 0;
 }
 
 PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic)
@@ -339,7 +341,7 @@  static int piix_load(QEMUFile* f, void *opaque, int version_id)
     return pci_device_load(d, f);
 }
 
-static void piix3_initfn(PCIDevice *d)
+static int piix3_initfn(PCIDevice *d)
 {
     uint8_t *pci_conf;
 
@@ -356,9 +358,10 @@  static void piix3_initfn(PCIDevice *d)
     piix3_dev = d;
     piix3_reset(d);
     qemu_register_reset(piix3_reset, d);
+    return 0;
 }
 
-static void piix4_initfn(PCIDevice *d)
+static int piix4_initfn(PCIDevice *d)
 {
     uint8_t *pci_conf;
 
@@ -374,6 +377,7 @@  static void piix4_initfn(PCIDevice *d)
     piix4_dev = d;
     piix4_reset(d);
     qemu_register_reset(piix4_reset, d);
+    return 0;
 }
 
 int piix3_init(PCIBus *bus, int devfn)
diff --git a/hw/pl011.c b/hw/pl011.c
index 0528bfe..19da7af 100644
--- a/hw/pl011.c
+++ b/hw/pl011.c
@@ -286,7 +286,7 @@  static int pl011_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void pl011_init(SysBusDevice *dev, const unsigned char *id)
+static int pl011_init(SysBusDevice *dev, const unsigned char *id)
 {
     int iomemtype;
     pl011_state *s = FROM_SYSBUS(pl011_state, dev);
@@ -307,16 +307,17 @@  static void pl011_init(SysBusDevice *dev, const unsigned char *id)
                               pl011_event, s);
     }
     register_savevm("pl011_uart", -1, 1, pl011_save, pl011_load, s);
+    return 0;
 }
 
-static void pl011_init_arm(SysBusDevice *dev)
+static int pl011_init_arm(SysBusDevice *dev)
 {
-    pl011_init(dev, pl011_id_arm);
+    return pl011_init(dev, pl011_id_arm);
 }
 
-static void pl011_init_luminary(SysBusDevice *dev)
+static int pl011_init_luminary(SysBusDevice *dev)
 {
-    pl011_init(dev, pl011_id_luminary);
+    return pl011_init(dev, pl011_id_luminary);
 }
 
 static void pl011_register_devices(void)
diff --git a/hw/pl022.c b/hw/pl022.c
index 78076e0..ef7c61e 100644
--- a/hw/pl022.c
+++ b/hw/pl022.c
@@ -288,7 +288,7 @@  static int pl022_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void pl022_init(SysBusDevice *dev)
+static int pl022_init(SysBusDevice *dev)
 {
     pl022_state *s = FROM_SYSBUS(pl022_state, dev);
     int iomemtype;
@@ -300,6 +300,7 @@  static void pl022_init(SysBusDevice *dev)
     s->ssi = ssi_create_bus(&dev->qdev, "ssi");
     pl022_reset(s);
     register_savevm("pl022_ssp", -1, 1, pl022_save, pl022_load, s);
+    return 0;
 }
 
 static void pl022_register_devices(void)
diff --git a/hw/pl031.c b/hw/pl031.c
index 5c9992e..fe4c52a 100644
--- a/hw/pl031.c
+++ b/hw/pl031.c
@@ -183,7 +183,7 @@  static CPUReadMemoryFunc * pl031_readfn[] = {
     pl031_read
 };
 
-static void pl031_init(SysBusDevice *dev)
+static int pl031_init(SysBusDevice *dev)
 {
     int iomemtype;
     pl031_state *s = FROM_SYSBUS(pl031_state, dev);
@@ -202,6 +202,7 @@  static void pl031_init(SysBusDevice *dev)
     s->tick_offset = mktimegm(&tm);
 
     s->timer = qemu_new_timer(vm_clock, pl031_interrupt, s);
+    return 0;
 }
 
 static void pl031_register_devices(void)
diff --git a/hw/pl050.c b/hw/pl050.c
index c8818e0..499b5c1 100644
--- a/hw/pl050.c
+++ b/hw/pl050.c
@@ -122,7 +122,7 @@  static CPUWriteMemoryFunc *pl050_writefn[] = {
    pl050_write
 };
 
-static void pl050_init(SysBusDevice *dev, int is_mouse)
+static int pl050_init(SysBusDevice *dev, int is_mouse)
 {
     pl050_state *s = FROM_SYSBUS(pl050_state, dev);
     int iomemtype;
@@ -137,16 +137,17 @@  static void pl050_init(SysBusDevice *dev, int is_mouse)
     else
         s->dev = ps2_kbd_init(pl050_update, s);
     /* ??? Save/restore.  */
+    return 0;
 }
 
-static void pl050_init_keyboard(SysBusDevice *dev)
+static int pl050_init_keyboard(SysBusDevice *dev)
 {
-    pl050_init(dev, 0);
+    return pl050_init(dev, 0);
 }
 
-static void pl050_init_mouse(SysBusDevice *dev)
+static int pl050_init_mouse(SysBusDevice *dev)
 {
-    pl050_init(dev, 1);
+    return pl050_init(dev, 1);
 }
 
 static void pl050_register_devices(void)
diff --git a/hw/pl061.c b/hw/pl061.c
index a003b97..1c53d14 100644
--- a/hw/pl061.c
+++ b/hw/pl061.c
@@ -291,7 +291,7 @@  static int pl061_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void pl061_init(SysBusDevice *dev)
+static int pl061_init(SysBusDevice *dev)
 {
     int iomemtype;
     pl061_state *s = FROM_SYSBUS(pl061_state, dev);
@@ -304,6 +304,7 @@  static void pl061_init(SysBusDevice *dev)
     qdev_init_gpio_out(&dev->qdev, s->out, 8);
     pl061_reset(s);
     register_savevm("pl061_gpio", -1, 1, pl061_save, pl061_load, s);
+    return 0;
 }
 
 static void pl061_register_devices(void)
diff --git a/hw/pl080.c b/hw/pl080.c
index 9c17be6..a6da3fb 100644
--- a/hw/pl080.c
+++ b/hw/pl080.c
@@ -319,7 +319,7 @@  static CPUWriteMemoryFunc *pl080_writefn[] = {
    pl080_write
 };
 
-static void pl08x_init(SysBusDevice *dev, int nchannels)
+static int pl08x_init(SysBusDevice *dev, int nchannels)
 {
     int iomemtype;
     pl080_state *s = FROM_SYSBUS(pl080_state, dev);
@@ -330,16 +330,17 @@  static void pl08x_init(SysBusDevice *dev, int nchannels)
     sysbus_init_irq(dev, &s->irq);
     s->nchannels = nchannels;
     /* ??? Save/restore.  */
+    return 0;
 }
 
-static void pl080_init(SysBusDevice *dev)
+static int pl080_init(SysBusDevice *dev)
 {
-    pl08x_init(dev, 8);
+    return pl08x_init(dev, 8);
 }
 
-static void pl081_init(SysBusDevice *dev)
+static int pl081_init(SysBusDevice *dev)
 {
-    pl08x_init(dev, 2);
+    return pl08x_init(dev, 2);
 }
 
 /* The PL080 and PL081 are the same except for the number of channels
diff --git a/hw/pl110.c b/hw/pl110.c
index 2797f83..91e0480 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -352,7 +352,7 @@  static CPUWriteMemoryFunc *pl110_writefn[] = {
    pl110_write
 };
 
-static void pl110_init(SysBusDevice *dev)
+static int pl110_init(SysBusDevice *dev)
 {
     pl110_state *s = FROM_SYSBUS(pl110_state, dev);
     int iomemtype;
@@ -365,13 +365,14 @@  static void pl110_init(SysBusDevice *dev)
                                  pl110_invalidate_display,
                                  NULL, NULL, s);
     /* ??? Save/restore.  */
+    return 0;
 }
 
-static void pl110_versatile_init(SysBusDevice *dev)
+static int pl110_versatile_init(SysBusDevice *dev)
 {
     pl110_state *s = FROM_SYSBUS(pl110_state, dev);
     s->versatile = 1;
-    pl110_init(dev);
+    return pl110_init(dev);
 }
 
 static void pl110_register_devices(void)
diff --git a/hw/pl181.c b/hw/pl181.c
index 3075c9e..d269543 100644
--- a/hw/pl181.c
+++ b/hw/pl181.c
@@ -445,7 +445,7 @@  static void pl181_reset(void *opaque)
     s->mask[1] = 0;
 }
 
-static void pl181_init(SysBusDevice *dev)
+static int pl181_init(SysBusDevice *dev)
 {
     int iomemtype;
     pl181_state *s = FROM_SYSBUS(pl181_state, dev);
@@ -461,6 +461,7 @@  static void pl181_init(SysBusDevice *dev)
     qemu_register_reset(pl181_reset, s);
     pl181_reset(s);
     /* ??? Save/restore.  */
+    return 0;
 }
 
 static void pl181_register_devices(void)
diff --git a/hw/pl190.c b/hw/pl190.c
index f68fb42..296ed7a 100644
--- a/hw/pl190.c
+++ b/hw/pl190.c
@@ -227,7 +227,7 @@  static void pl190_reset(pl190_state *s)
   pl190_update_vectors(s);
 }
 
-static void pl190_init(SysBusDevice *dev)
+static int pl190_init(SysBusDevice *dev)
 {
     pl190_state *s = FROM_SYSBUS(pl190_state, dev);
     int iomemtype;
@@ -240,6 +240,7 @@  static void pl190_init(SysBusDevice *dev)
     sysbus_init_irq(dev, &s->fiq);
     pl190_reset(s);
     /* ??? Save/restore.  */
+    return 0;
 }
 
 static void pl190_register_devices(void)
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 28e9610..0a1129c 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -850,7 +850,7 @@  static int pxa2xx_ssp_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void pxa2xx_ssp_init(SysBusDevice *dev)
+static int pxa2xx_ssp_init(SysBusDevice *dev)
 {
     int iomemtype;
     PXA2xxSSPState *s = FROM_SYSBUS(PXA2xxSSPState, dev);
@@ -864,6 +864,7 @@  static void pxa2xx_ssp_init(SysBusDevice *dev)
                     pxa2xx_ssp_save, pxa2xx_ssp_load, s);
 
     s->bus = ssi_create_bus(&dev->qdev, "ssi");
+    return 0;
 }
 
 /* Real-Time Clock */
@@ -1479,9 +1480,10 @@  static int pxa2xx_i2c_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void pxa2xx_i2c_slave_init(i2c_slave *i2c)
+static int pxa2xx_i2c_slave_init(i2c_slave *i2c)
 {
     /* Nothing to do.  */
+    return 0;
 }
 
 static I2CSlaveInfo pxa2xx_i2c_slave_info = {
diff --git a/hw/qdev.c b/hw/qdev.c
index c1a7779..1b7d963 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -199,16 +199,19 @@  DeviceState *qdev_device_add(QemuOpts *opts)
         qdev_free(qdev);
         return NULL;
     }
-    qdev_init(qdev);
+    if (qdev_init(qdev) != 0) {
+        qdev_free(qdev);
+        return NULL;
+    }
     return qdev;
 }
 
 /* Initialize a device.  Device properties should be set before calling
    this function.  IRQs and MMIO regions should be connected/mapped after
    calling this function.  */
-void qdev_init(DeviceState *dev)
+int qdev_init(DeviceState *dev)
 {
-    dev->info->init(dev, dev->info);
+    return dev->info->init(dev, dev->info);
 }
 
 /* Unlink device from bus and free the structure.  */
diff --git a/hw/qdev.h b/hw/qdev.h
index 204c4e5..cefb681 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -88,7 +88,7 @@  struct CompatProperty {
 
 DeviceState *qdev_create(BusState *bus, const char *name);
 DeviceState *qdev_device_add(QemuOpts *opts);
-void qdev_init(DeviceState *dev);
+int qdev_init(DeviceState *dev);
 void qdev_free(DeviceState *dev);
 
 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n);
@@ -98,7 +98,7 @@  BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
 
 /*** Device API.  ***/
 
-typedef void (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
+typedef int (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
 typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv,
               int unit);
 
diff --git a/hw/realview_gic.c b/hw/realview_gic.c
index 089d94c..107def1 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -58,7 +58,7 @@  static void realview_gic_map(SysBusDevice *dev, target_phys_addr_t base)
     cpu_register_physical_memory(base + 0x1000, 0x1000, s->gic.iomemtype);
 }
 
-static void realview_gic_init(SysBusDevice *dev)
+static int realview_gic_init(SysBusDevice *dev)
 {
     RealViewGICState *s = FROM_SYSBUSGIC(RealViewGICState, dev);
 
@@ -66,6 +66,7 @@  static void realview_gic_init(SysBusDevice *dev)
     s->iomemtype = cpu_register_io_memory(realview_gic_cpu_readfn,
                                           realview_gic_cpu_writefn, s);
     sysbus_init_mmio_cb(dev, 0x2000, realview_gic_map);
+    return 0;
 }
 
 static void realview_gic_register_devices(void)
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index fcd6d95..9e54de3 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3445,7 +3445,7 @@  static int pci_rtl8139_uninit(PCIDevice *dev)
     return 0;
 }
 
-static void pci_rtl8139_init(PCIDevice *dev)
+static int pci_rtl8139_init(PCIDevice *dev)
 {
     PCIRTL8139State *d = (PCIRTL8139State *)dev;
     RTL8139State *s;
@@ -3497,6 +3497,7 @@  static void pci_rtl8139_init(PCIDevice *dev)
     qemu_mod_timer(s->timer,
         rtl8139_get_next_tctr_time(s,qemu_get_clock(vm_clock)));
 #endif /* RTL8139_ONBOARD_TIMER */
+    return 0;
 }
 
 static PCIDeviceInfo rtl8139_info = {
diff --git a/hw/sbi.c b/hw/sbi.c
index 3c8e95a..c885c28 100644
--- a/hw/sbi.c
+++ b/hw/sbi.c
@@ -131,7 +131,7 @@  static void sbi_reset(void *opaque)
     }
 }
 
-static void sbi_init1(SysBusDevice *dev)
+static int sbi_init1(SysBusDevice *dev)
 {
     SBIState *s = FROM_SYSBUS(SBIState, dev);
     int sbi_io_memory;
@@ -148,6 +148,7 @@  static void sbi_init1(SysBusDevice *dev)
     register_savevm("sbi", -1, 1, sbi_save, sbi_load, s);
     qemu_register_reset(sbi_reset, s);
     sbi_reset(s);
+    return 0;
 }
 
 static SysBusDeviceInfo sbi_info = {
diff --git a/hw/slavio_intctl.c b/hw/slavio_intctl.c
index dbea1f9..22af25b 100644
--- a/hw/slavio_intctl.c
+++ b/hw/slavio_intctl.c
@@ -390,7 +390,7 @@  static void slavio_intctl_reset(void *opaque)
     slavio_check_interrupts(s, 0);
 }
 
-static void slavio_intctl_init1(SysBusDevice *dev)
+static int slavio_intctl_init1(SysBusDevice *dev)
 {
     SLAVIO_INTCTLState *s = FROM_SYSBUS(SLAVIO_INTCTLState, dev);
     int io_memory;
@@ -418,6 +418,7 @@  static void slavio_intctl_init1(SysBusDevice *dev)
                     slavio_intctl_load, s);
     qemu_register_reset(slavio_intctl_reset, s);
     slavio_intctl_reset(s);
+    return 0;
 }
 
 static SysBusDeviceInfo slavio_intctl_info = {
diff --git a/hw/slavio_misc.c b/hw/slavio_misc.c
index c8dcd33..f754a4a 100644
--- a/hw/slavio_misc.c
+++ b/hw/slavio_misc.c
@@ -434,7 +434,7 @@  static int slavio_misc_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void apc_init1(SysBusDevice *dev)
+static int apc_init1(SysBusDevice *dev)
 {
     APCState *s = FROM_SYSBUS(APCState, dev);
     int io;
@@ -444,9 +444,10 @@  static void apc_init1(SysBusDevice *dev)
     /* Power management (APC) XXX: not a Slavio device */
     io = cpu_register_io_memory(apc_mem_read, apc_mem_write, s);
     sysbus_init_mmio(dev, MISC_SIZE, io);
+    return 0;
 }
 
-static void slavio_misc_init1(SysBusDevice *dev)
+static int slavio_misc_init1(SysBusDevice *dev)
 {
     MiscState *s = FROM_SYSBUS(MiscState, dev);
     int io;
@@ -498,6 +499,7 @@  static void slavio_misc_init1(SysBusDevice *dev)
                     s);
     qemu_register_reset(slavio_misc_reset, s);
     slavio_misc_reset(s);
+    return 0;
 }
 
 static SysBusDeviceInfo slavio_misc_info = {
diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c
index 531d6db..6665d54 100644
--- a/hw/slavio_timer.c
+++ b/hw/slavio_timer.c
@@ -412,7 +412,7 @@  static void slavio_timer_reset(void *opaque)
     s->cputimer_mode = 0;
 }
 
-static void slavio_timer_init1(SysBusDevice *dev)
+static int slavio_timer_init1(SysBusDevice *dev)
 {
     int io;
     SLAVIO_TIMERState *s = FROM_SYSBUS(SLAVIO_TIMERState, dev);
@@ -444,6 +444,7 @@  static void slavio_timer_init1(SysBusDevice *dev)
                     slavio_timer_load, s);
     qemu_register_reset(slavio_timer_reset, s);
     slavio_timer_reset(s);
+    return 0;
 }
 
 static SysBusDeviceInfo slavio_timer_info = {
diff --git a/hw/smbus.c b/hw/smbus.c
index 5618902..6c1149b 100644
--- a/hw/smbus.c
+++ b/hw/smbus.c
@@ -198,12 +198,12 @@  static int smbus_i2c_send(i2c_slave *s, uint8_t data)
     return 0;
 }
 
-static void smbus_device_init(i2c_slave *i2c)
+static int smbus_device_init(i2c_slave *i2c)
 {
     SMBusDeviceInfo *t = container_of(i2c->info, SMBusDeviceInfo, i2c);
     SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, i2c);
 
-    t->init(dev);
+    return t->init(dev);
 }
 
 void smbus_register_device(SMBusDeviceInfo *info)
diff --git a/hw/smbus.h b/hw/smbus.h
index d8c8059..d582e6d 100644
--- a/hw/smbus.h
+++ b/hw/smbus.h
@@ -37,7 +37,7 @@  struct SMBusDevice {
 
 typedef struct {
     I2CSlaveInfo i2c;
-    void (*init)(SMBusDevice *dev);
+    int (*init)(SMBusDevice *dev);
     void (*quick_cmd)(SMBusDevice *dev, uint8_t read);
     void (*send_byte)(SMBusDevice *dev, uint8_t val);
     uint8_t (*receive_byte)(SMBusDevice *dev);
diff --git a/hw/smbus_eeprom.c b/hw/smbus_eeprom.c
index 9785cc2..52463e0 100644
--- a/hw/smbus_eeprom.c
+++ b/hw/smbus_eeprom.c
@@ -96,11 +96,12 @@  static uint8_t eeprom_read_data(SMBusDevice *dev, uint8_t cmd, int n)
     return eeprom_receive_byte(dev);
 }
 
-static void smbus_eeprom_init(SMBusDevice *dev)
+static int smbus_eeprom_init(SMBusDevice *dev)
 {
     SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *)dev;
 
     eeprom->offset = 0;
+    return 0;
 }
 
 static SMBusDeviceInfo smbus_eeprom_info = {
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index 5f6956a..68224c1 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -700,7 +700,7 @@  static void smc91c111_cleanup(VLANClientState *vc)
     qemu_free(s);
 }
 
-static void smc91c111_init1(SysBusDevice *dev)
+static int smc91c111_init1(SysBusDevice *dev)
 {
     smc91c111_state *s = FROM_SYSBUS(smc91c111_state, dev);
 
@@ -717,6 +717,7 @@  static void smc91c111_init1(SysBusDevice *dev)
                                  smc91c111_cleanup, s);
     qemu_format_nic_info_str(s->vc, s->macaddr);
     /* ??? Save/restore.  */
+    return 0;
 }
 
 static void smc91c111_register_devices(void)
diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
index 7045453..06a291a 100644
--- a/hw/sparc32_dma.c
+++ b/hw/sparc32_dma.c
@@ -244,7 +244,7 @@  static int dma_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void sparc32_dma_init1(SysBusDevice *dev)
+static int sparc32_dma_init1(SysBusDevice *dev)
 {
     DMAState *s = FROM_SYSBUS(DMAState, dev);
     int dma_io_memory;
@@ -259,6 +259,7 @@  static void sparc32_dma_init1(SysBusDevice *dev)
 
     qdev_init_gpio_in(&dev->qdev, dma_set_irq, 1);
     qdev_init_gpio_out(&dev->qdev, &s->dev_reset, 1);
+    return 0;
 }
 
 static SysBusDeviceInfo sparc32_dma_info = {
diff --git a/hw/spitz.c b/hw/spitz.c
index 36bf534..aadaa09 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -604,7 +604,7 @@  static int spitz_lcdtg_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void spitz_lcdtg_init(SSISlave *dev)
+static int spitz_lcdtg_init(SSISlave *dev)
 {
     SpitzLCDTG *s = FROM_SSI_SLAVE(SpitzLCDTG, dev);
 
@@ -614,6 +614,7 @@  static void spitz_lcdtg_init(SSISlave *dev)
 
     register_savevm("spitz-lcdtg", -1, 1,
                     spitz_lcdtg_save, spitz_lcdtg_load, s);
+    return 0;
 }
 
 /* SSP devices */
@@ -697,7 +698,7 @@  static int spitz_ssp_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void corgi_ssp_init(SSISlave *dev)
+static int corgi_ssp_init(SSISlave *dev)
 {
     CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, dev);
 
@@ -707,6 +708,7 @@  static void corgi_ssp_init(SSISlave *dev)
     s->bus[2] = ssi_create_bus(&dev->qdev, "ssi2");
 
     register_savevm("spitz_ssp", -1, 1, spitz_ssp_save, spitz_ssp_load, s);
+    return 0;
 }
 
 static void spitz_ssp_attach(PXA2xxState *cpu)
diff --git a/hw/ssd0303.c b/hw/ssd0303.c
index 6872ef5..16aed58 100644
--- a/hw/ssd0303.c
+++ b/hw/ssd0303.c
@@ -304,7 +304,7 @@  static int ssd0303_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void ssd0303_init(i2c_slave *i2c)
+static int ssd0303_init(i2c_slave *i2c)
 {
     ssd0303_state *s = FROM_I2C_SLAVE(ssd0303_state, i2c);
 
@@ -313,6 +313,7 @@  static void ssd0303_init(i2c_slave *i2c)
                                  NULL, NULL, s);
     qemu_console_resize(s->ds, 96 * MAGNIFY, 16 * MAGNIFY);
     register_savevm("ssd0303_oled", -1, 1, ssd0303_save, ssd0303_load, s);
+    return 0;
 }
 
 static I2CSlaveInfo ssd0303_info = {
diff --git a/hw/ssd0323.c b/hw/ssd0323.c
index 319ab87..b632825 100644
--- a/hw/ssd0323.c
+++ b/hw/ssd0323.c
@@ -322,7 +322,7 @@  static int ssd0323_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void ssd0323_init(SSISlave *dev)
+static int ssd0323_init(SSISlave *dev)
 {
     ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, dev);
 
@@ -336,6 +336,7 @@  static void ssd0323_init(SSISlave *dev)
     qdev_init_gpio_in(&dev->qdev, ssd0323_cd, 1);
 
     register_savevm("ssd0323_oled", -1, 1, ssd0323_save, ssd0323_load, s);
+    return 0;
 }
 
 static SSISlaveInfo ssd0323_info = {
diff --git a/hw/ssi-sd.c b/hw/ssi-sd.c
index 4e67f14..5e74e5d 100644
--- a/hw/ssi-sd.c
+++ b/hw/ssi-sd.c
@@ -229,7 +229,7 @@  static int ssi_sd_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void ssi_sd_init(SSISlave *dev)
+static int ssi_sd_init(SSISlave *dev)
 {
     ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, dev);
     BlockDriverState *bs;
@@ -238,6 +238,7 @@  static void ssi_sd_init(SSISlave *dev)
     bs = qdev_init_bdrv(&dev->qdev, IF_SD);
     s->sd = sd_init(bs, 1);
     register_savevm("ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s);
+    return 0;
 }
 
 static SSISlaveInfo ssi_sd_info = {
diff --git a/hw/ssi.c b/hw/ssi.c
index a5133be..54ad1a1 100644
--- a/hw/ssi.c
+++ b/hw/ssi.c
@@ -18,7 +18,7 @@  static struct BusInfo ssi_bus_info = {
     .size = sizeof(SSIBus),
 };
 
-static void ssi_slave_init(DeviceState *dev, DeviceInfo *base_info)
+static int ssi_slave_init(DeviceState *dev, DeviceInfo *base_info)
 {
     SSISlaveInfo *info = container_of(base_info, SSISlaveInfo, qdev);
     SSISlave *s = SSI_SLAVE_FROM_QDEV(dev);
@@ -31,7 +31,7 @@  static void ssi_slave_init(DeviceState *dev, DeviceInfo *base_info)
     }
 
     s->info = info;
-    info->init(s);
+    return info->init(s);
 }
 
 void ssi_register_slave(SSISlaveInfo *info)
diff --git a/hw/ssi.h b/hw/ssi.h
index 6ff71e9..24610a8 100644
--- a/hw/ssi.h
+++ b/hw/ssi.h
@@ -18,7 +18,7 @@  typedef struct SSISlave SSISlave;
 /* Slave devices.  */
 typedef struct {
     DeviceInfo qdev;
-    void (*init)(SSISlave *dev);
+    int (*init)(SSISlave *dev);
     uint32_t (*transfer)(SSISlave *dev, uint32_t val);
 } SSISlaveInfo;
 
diff --git a/hw/stellaris.c b/hw/stellaris.c
index d9434ca..74f36d4 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -339,7 +339,7 @@  static int gptm_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void stellaris_gptm_init(SysBusDevice *dev)
+static int stellaris_gptm_init(SysBusDevice *dev)
 {
     int iomemtype;
     gptm_state *s = FROM_SYSBUS(gptm_state, dev);
@@ -355,6 +355,7 @@  static void stellaris_gptm_init(SysBusDevice *dev)
     s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]);
     s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]);
     register_savevm("stellaris_gptm", -1, 1, gptm_save, gptm_load, s);
+    return 0;
 }
 
 
@@ -654,9 +655,9 @@  static int ssys_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void stellaris_sys_init(uint32_t base, qemu_irq irq,
-                               stellaris_board_info * board,
-                               uint8_t *macaddr)
+static int stellaris_sys_init(uint32_t base, qemu_irq irq,
+                              stellaris_board_info * board,
+                              uint8_t *macaddr)
 {
     int iomemtype;
     ssys_state *s;
@@ -673,6 +674,7 @@  static void stellaris_sys_init(uint32_t base, qemu_irq irq,
     cpu_register_physical_memory(base, 0x00001000, iomemtype);
     ssys_reset(s);
     register_savevm("stellaris_sys", -1, 1, ssys_save, ssys_load, s);
+    return 0;
 }
 
 
@@ -870,7 +872,7 @@  static int stellaris_i2c_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void stellaris_i2c_init(SysBusDevice * dev)
+static int stellaris_i2c_init(SysBusDevice * dev)
 {
     stellaris_i2c_state *s = FROM_SYSBUS(stellaris_i2c_state, dev);
     i2c_bus *bus;
@@ -887,6 +889,7 @@  static void stellaris_i2c_init(SysBusDevice * dev)
     stellaris_i2c_reset(s);
     register_savevm("stellaris_i2c", -1, 1,
                     stellaris_i2c_save, stellaris_i2c_load, s);
+    return 0;
 }
 
 /* Analogue to Digital Converter.  This is only partially implemented,
@@ -1178,7 +1181,7 @@  static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void stellaris_adc_init(SysBusDevice *dev)
+static int stellaris_adc_init(SysBusDevice *dev)
 {
     stellaris_adc_state *s = FROM_SYSBUS(stellaris_adc_state, dev);
     int iomemtype;
@@ -1195,6 +1198,7 @@  static void stellaris_adc_init(SysBusDevice *dev)
     qdev_init_gpio_in(&dev->qdev, stellaris_adc_trigger, 1);
     register_savevm("stellaris_adc", -1, 1,
                     stellaris_adc_save, stellaris_adc_load, s);
+    return 0;
 }
 
 /* Some boards have both an OLED controller and SD card connected to
@@ -1244,7 +1248,7 @@  static int stellaris_ssi_bus_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void stellaris_ssi_bus_init(SSISlave *dev)
+static int stellaris_ssi_bus_init(SSISlave *dev)
 {
     stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev);
 
@@ -1254,6 +1258,7 @@  static void stellaris_ssi_bus_init(SSISlave *dev)
 
     register_savevm("stellaris_ssi_bus", -1, 1,
                     stellaris_ssi_bus_save, stellaris_ssi_bus_load, s);
+    return 0;
 }
 
 /* Board init.  */
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index 43fa305..92d5033 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -396,7 +396,7 @@  static void stellaris_enet_cleanup(VLANClientState *vc)
     qemu_free(s);
 }
 
-static void stellaris_enet_init(SysBusDevice *dev)
+static int stellaris_enet_init(SysBusDevice *dev)
 {
     stellaris_enet_state *s = FROM_SYSBUS(stellaris_enet_state, dev);
 
@@ -415,6 +415,7 @@  static void stellaris_enet_init(SysBusDevice *dev)
     stellaris_enet_reset(s);
     register_savevm("stellaris_enet", -1, 1,
                     stellaris_enet_save, stellaris_enet_load, s);
+    return 0;
 }
 
 static void stellaris_enet_register_devices(void)
diff --git a/hw/sun4c_intctl.c b/hw/sun4c_intctl.c
index 76b739c..85c2e25 100644
--- a/hw/sun4c_intctl.c
+++ b/hw/sun4c_intctl.c
@@ -198,7 +198,7 @@  static void sun4c_intctl_reset(void *opaque)
     s->pending = 0;
 }
 
-static void sun4c_intctl_init1(SysBusDevice *dev)
+static int sun4c_intctl_init1(SysBusDevice *dev)
 {
     Sun4c_INTCTLState *s = FROM_SYSBUS(Sun4c_INTCTLState, dev);
     int io_memory;
@@ -216,6 +216,7 @@  static void sun4c_intctl_init1(SysBusDevice *dev)
                     sun4c_intctl_load, s);
     qemu_register_reset(sun4c_intctl_reset, s);
     sun4c_intctl_reset(s);
+    return 0;
 }
 
 static SysBusDeviceInfo sun4c_intctl_info = {
diff --git a/hw/sun4m.c b/hw/sun4m.c
index ddc295a..fc04885 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -568,12 +568,13 @@  static void idreg_init(target_phys_addr_t addr)
     cpu_physical_memory_write_rom(addr, idreg_data, sizeof(idreg_data));
 }
 
-static void idreg_init1(SysBusDevice *dev)
+static int idreg_init1(SysBusDevice *dev)
 {
     ram_addr_t idreg_offset;
 
     idreg_offset = qemu_ram_alloc(sizeof(idreg_data));
     sysbus_init_mmio(dev, sizeof(idreg_data), idreg_offset | IO_MEM_ROM);
+    return 0;
 }
 
 static SysBusDeviceInfo idreg_info = {
@@ -623,12 +624,13 @@  static void prom_init(target_phys_addr_t addr, const char *bios_name)
     }
 }
 
-static void prom_init1(SysBusDevice *dev)
+static int prom_init1(SysBusDevice *dev)
 {
     ram_addr_t prom_offset;
 
     prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
     sysbus_init_mmio(dev, PROM_SIZE_MAX, prom_offset | IO_MEM_ROM);
+    return 0;
 }
 
 static SysBusDeviceInfo prom_info = {
@@ -654,7 +656,7 @@  typedef struct RamDevice
 } RamDevice;
 
 /* System RAM */
-static void ram_init1(SysBusDevice *dev)
+static int ram_init1(SysBusDevice *dev)
 {
     ram_addr_t RAM_size, ram_offset;
     RamDevice *d = FROM_SYSBUS(RamDevice, dev);
@@ -663,6 +665,7 @@  static void ram_init1(SysBusDevice *dev)
 
     ram_offset = qemu_ram_alloc(RAM_size);
     sysbus_init_mmio(dev, RAM_size, ram_offset);
+    return 0;
 }
 
 static void ram_init(target_phys_addr_t addr, ram_addr_t RAM_size,
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 77164ca..6fce7c5 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -358,7 +358,7 @@  pci_ebus_init(PCIBus *bus, int devfn)
     pci_create_simple(bus, devfn, "ebus");
 }
 
-static void
+static int
 pci_ebus_init1(PCIDevice *s)
 {
     pci_config_set_vendor_id(s->config, PCI_VENDOR_ID_SUN);
@@ -377,6 +377,7 @@  pci_ebus_init1(PCIDevice *s)
                            ebus_mmio_mapfunc);
     pci_register_bar(s, 1, 0x800000,  PCI_ADDRESS_SPACE_MEM,
                            ebus_mmio_mapfunc);
+    return 0;
 }
 
 static PCIDeviceInfo ebus_info = {
@@ -426,12 +427,13 @@  static void prom_init(target_phys_addr_t addr, const char *bios_name)
     }
 }
 
-static void prom_init1(SysBusDevice *dev)
+static int prom_init1(SysBusDevice *dev)
 {
     ram_addr_t prom_offset;
 
     prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
     sysbus_init_mmio(dev, PROM_SIZE_MAX, prom_offset | IO_MEM_ROM);
+    return 0;
 }
 
 static SysBusDeviceInfo prom_info = {
@@ -458,7 +460,7 @@  typedef struct RamDevice
 } RamDevice;
 
 /* System RAM */
-static void ram_init1(SysBusDevice *dev)
+static int ram_init1(SysBusDevice *dev)
 {
     ram_addr_t RAM_size, ram_offset;
     RamDevice *d = FROM_SYSBUS(RamDevice, dev);
@@ -467,6 +469,7 @@  static void ram_init1(SysBusDevice *dev)
 
     ram_offset = qemu_ram_alloc(RAM_size);
     sysbus_init_mmio(dev, RAM_size, ram_offset);
+    return 0;
 }
 
 static void ram_init(target_phys_addr_t addr, ram_addr_t RAM_size)
diff --git a/hw/syborg_fb.c b/hw/syborg_fb.c
index efa5c0e..68cae17 100644
--- a/hw/syborg_fb.c
+++ b/hw/syborg_fb.c
@@ -503,7 +503,7 @@  static int syborg_fb_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void syborg_fb_init(SysBusDevice *dev)
+static int syborg_fb_init(SysBusDevice *dev)
 {
     SyborgFBState *s = FROM_SYSBUS(SyborgFBState, dev);
     int iomemtype;
@@ -528,6 +528,7 @@  static void syborg_fb_init(SysBusDevice *dev)
 
     register_savevm("syborg_framebuffer", -1, 1,
                     syborg_fb_save, syborg_fb_load, s);
+    return 0;
 }
 
 static SysBusDeviceInfo syborg_fb_info = {
diff --git a/hw/syborg_interrupt.c b/hw/syborg_interrupt.c
index 1b44989..306da5f 100644
--- a/hw/syborg_interrupt.c
+++ b/hw/syborg_interrupt.c
@@ -202,7 +202,7 @@  static int syborg_int_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void syborg_int_init(SysBusDevice *dev)
+static int syborg_int_init(SysBusDevice *dev)
 {
     SyborgIntState *s = FROM_SYSBUS(SyborgIntState, dev);
     int iomemtype;
@@ -215,6 +215,7 @@  static void syborg_int_init(SysBusDevice *dev)
     s->flags = qemu_mallocz(s->num_irqs * sizeof(syborg_int_flags));
 
     register_savevm("syborg_int", -1, 1, syborg_int_save, syborg_int_load, s);
+    return 0;
 }
 
 static SysBusDeviceInfo syborg_int_info = {
diff --git a/hw/syborg_keyboard.c b/hw/syborg_keyboard.c
index deece3c..356804b 100644
--- a/hw/syborg_keyboard.c
+++ b/hw/syborg_keyboard.c
@@ -203,7 +203,7 @@  static int syborg_keyboard_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void syborg_keyboard_init(SysBusDevice *dev)
+static int syborg_keyboard_init(SysBusDevice *dev)
 {
     SyborgKeyboardState *s = FROM_SYSBUS(SyborgKeyboardState, dev);
     int iomemtype;
@@ -222,6 +222,7 @@  static void syborg_keyboard_init(SysBusDevice *dev)
 
     register_savevm("syborg_keyboard", -1, 1,
                     syborg_keyboard_save, syborg_keyboard_load, s);
+    return 0;
 }
 
 static SysBusDeviceInfo syborg_keyboard_info = {
diff --git a/hw/syborg_pointer.c b/hw/syborg_pointer.c
index 152602a..d104801 100644
--- a/hw/syborg_pointer.c
+++ b/hw/syborg_pointer.c
@@ -199,7 +199,7 @@  static int syborg_pointer_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void syborg_pointer_init(SysBusDevice *dev)
+static int syborg_pointer_init(SysBusDevice *dev)
 {
     SyborgPointerState *s = FROM_SYSBUS(SyborgPointerState, dev);
     int iomemtype;
@@ -220,6 +220,7 @@  static void syborg_pointer_init(SysBusDevice *dev)
 
     register_savevm("syborg_pointer", -1, 1,
                     syborg_pointer_save, syborg_pointer_load, s);
+    return 0;
 }
 
 static SysBusDeviceInfo syborg_pointer_info = {
diff --git a/hw/syborg_rtc.c b/hw/syborg_rtc.c
index 48853f7..3426dcf 100644
--- a/hw/syborg_rtc.c
+++ b/hw/syborg_rtc.c
@@ -123,7 +123,7 @@  static int syborg_rtc_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void syborg_rtc_init(SysBusDevice *dev)
+static int syborg_rtc_init(SysBusDevice *dev)
 {
     SyborgRTCState *s = FROM_SYSBUS(SyborgRTCState, dev);
     struct tm tm;
@@ -137,6 +137,7 @@  static void syborg_rtc_init(SysBusDevice *dev)
     s->offset = (uint64_t)mktime(&tm) * 1000000000;
 
     register_savevm("syborg_rtc", -1, 1, syborg_rtc_save, syborg_rtc_load, s);
+    return 0;
 }
 
 static void syborg_rtc_register_devices(void)
diff --git a/hw/syborg_serial.c b/hw/syborg_serial.c
index f1c6c7e..04bfaa6 100644
--- a/hw/syborg_serial.c
+++ b/hw/syborg_serial.c
@@ -315,7 +315,7 @@  static int syborg_serial_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void syborg_serial_init(SysBusDevice *dev)
+static int syborg_serial_init(SysBusDevice *dev)
 {
     SyborgSerialState *s = FROM_SYSBUS(SyborgSerialState, dev);
     int iomemtype;
@@ -337,6 +337,7 @@  static void syborg_serial_init(SysBusDevice *dev)
 
     register_savevm("syborg_serial", -1, 1,
                     syborg_serial_save, syborg_serial_load, s);
+    return 0;
 }
 
 static SysBusDeviceInfo syborg_serial_info = {
diff --git a/hw/syborg_timer.c b/hw/syborg_timer.c
index f64b824..33a7914 100644
--- a/hw/syborg_timer.c
+++ b/hw/syborg_timer.c
@@ -203,7 +203,7 @@  static int syborg_timer_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void syborg_timer_init(SysBusDevice *dev)
+static int syborg_timer_init(SysBusDevice *dev)
 {
     SyborgTimerState *s = FROM_SYSBUS(SyborgTimerState, dev);
     QEMUBH *bh;
@@ -223,6 +223,7 @@  static void syborg_timer_init(SysBusDevice *dev)
     ptimer_set_freq(s->timer, s->freq);
     register_savevm("syborg_timer", -1, 1,
                     syborg_timer_save, syborg_timer_load, s);
+    return 0;
 }
 
 static SysBusDeviceInfo syborg_timer_info = {
diff --git a/hw/syborg_virtio.c b/hw/syborg_virtio.c
index aed1563..42e5011 100644
--- a/hw/syborg_virtio.c
+++ b/hw/syborg_virtio.c
@@ -245,7 +245,7 @@  static VirtIOBindings syborg_virtio_bindings = {
     .notify = syborg_virtio_update_irq
 };
 
-static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev)
+static int syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev)
 {
     int iomemtype;
 
@@ -263,17 +263,18 @@  static void syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev)
     qemu_register_reset(virtio_reset, vdev);
 
     virtio_bind_device(vdev, &syborg_virtio_bindings, proxy);
+    return 0;
 }
 
 /* Device specific bindings.  */
 
-static void syborg_virtio_net_init(SysBusDevice *dev)
+static int syborg_virtio_net_init(SysBusDevice *dev)
 {
     VirtIODevice *vdev;
     SyborgVirtIOProxy *proxy = FROM_SYSBUS(SyborgVirtIOProxy, dev);
 
     vdev = virtio_net_init(&dev->qdev);
-    syborg_virtio_init(proxy, vdev);
+    return syborg_virtio_init(proxy, vdev);
 }
 
 static void syborg_virtio_register_devices(void)
diff --git a/hw/sysbus.c b/hw/sysbus.c
index 269be77..f6516fd 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -105,11 +105,11 @@  void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
     dev->mmio[n].cb = cb;
 }
 
-static void sysbus_device_init(DeviceState *dev, DeviceInfo *base)
+static int sysbus_device_init(DeviceState *dev, DeviceInfo *base)
 {
     SysBusDeviceInfo *info = container_of(base, SysBusDeviceInfo, qdev);
 
-    info->init(sysbus_from_qdev(dev));
+    return info->init(sysbus_from_qdev(dev));
 }
 
 void sysbus_register_withprop(SysBusDeviceInfo *info)
diff --git a/hw/sysbus.h b/hw/sysbus.h
index d48ca8c..1a8f289 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -25,7 +25,7 @@  struct SysBusDevice {
     } mmio[QDEV_MAX_MMIO];
 };
 
-typedef void (*sysbus_initfn)(SysBusDevice *dev);
+typedef int (*sysbus_initfn)(SysBusDevice *dev);
 
 /* Macros to compensate for lack of type inheritance in C.  */
 #define sysbus_from_qdev(dev) ((SysBusDevice *)(dev))
diff --git a/hw/tcx.c b/hw/tcx.c
index 68dbf02..1279976 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -515,7 +515,7 @@  static CPUWriteMemoryFunc *tcx_dummy_write[3] = {
     tcx_dummy_writel,
 };
 
-static void tcx_init1(SysBusDevice *dev)
+static int tcx_init1(SysBusDevice *dev)
 {
     TCXState *s = FROM_SYSBUS(TCXState, dev);
     int io_memory, dummy_memory;
@@ -576,6 +576,7 @@  static void tcx_init1(SysBusDevice *dev)
     qemu_register_reset(tcx_reset, s);
     tcx_reset(s);
     qemu_console_resize(s->ds, s->width, s->height);
+    return 0;
 }
 
 static void tcx_screen_dump(void *opaque, const char *filename)
diff --git a/hw/tmp105.c b/hw/tmp105.c
index c9756c5..0113f8d 100644
--- a/hw/tmp105.c
+++ b/hw/tmp105.c
@@ -226,7 +226,7 @@  static void tmp105_reset(i2c_slave *i2c)
     tmp105_interrupt_update(s);
 }
 
-static void tmp105_init(i2c_slave *i2c)
+static int tmp105_init(i2c_slave *i2c)
 {
     TMP105State *s = FROM_I2C_SLAVE(TMP105State, i2c);
 
@@ -235,6 +235,7 @@  static void tmp105_init(i2c_slave *i2c)
     tmp105_reset(&s->i2c);
 
     register_savevm("TMP105", -1, 0, tmp105_save, tmp105_load, s);
+    return 0;
 }
 
 static I2CSlaveInfo tmp105_info = {
diff --git a/hw/tosa.c b/hw/tosa.c
index b932efc..4c463e6 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -121,9 +121,10 @@  static uint32_t tosa_ssp_tansfer(SSISlave *dev, uint32_t value)
     return 0;
 }
 
-static void tosa_ssp_init(SSISlave *dev)
+static int tosa_ssp_init(SSISlave *dev)
 {
     /* Nothing to do.  */
+    return 0;
 }
 
 typedef struct {
@@ -180,9 +181,10 @@  static int tosa_dac_recv(i2c_slave *s)
     return -1;
 }
 
-static void tosa_dac_init(i2c_slave *i2c)
+static int tosa_dac_init(i2c_slave *i2c)
 {
     /* Nothing to do.  */
+    return 0;
 }
 
 static void tosa_tg_init(PXA2xxState *cpu)
diff --git a/hw/twl92230.c b/hw/twl92230.c
index 519a583..b15a8bf 100644
--- a/hw/twl92230.c
+++ b/hw/twl92230.c
@@ -875,7 +875,7 @@  static int menelaus_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void twl92230_init(i2c_slave *i2c)
+static int twl92230_init(i2c_slave *i2c)
 {
     MenelausState *s = FROM_I2C_SLAVE(MenelausState, i2c);
 
@@ -888,6 +888,7 @@  static void twl92230_init(i2c_slave *i2c)
     menelaus_reset(&s->i2c);
 
     register_savevm("menelaus", -1, 0, menelaus_save, menelaus_load, s);
+    return 0;
 }
 
 static I2CSlaveInfo twl92230_info = {
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 73944af..3257f06 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -167,7 +167,7 @@  static void pci_unin_reset(void *opaque)
 {
 }
 
-static void pci_unin_main_init_device(SysBusDevice *dev)
+static int pci_unin_main_init_device(SysBusDevice *dev)
 {
     UNINState *s;
     int pci_mem_config, pci_mem_data;
@@ -187,9 +187,10 @@  static void pci_unin_main_init_device(SysBusDevice *dev)
     register_savevm("uninorth", 0, 1, pci_unin_save, pci_unin_load, &s->host_state);
     qemu_register_reset(pci_unin_reset, &s->host_state);
     pci_unin_reset(&s->host_state);
+    return 0;
 }
 
-static void pci_dec_21154_init_device(SysBusDevice *dev)
+static int pci_dec_21154_init_device(SysBusDevice *dev)
 {
     UNINState *s;
     int pci_mem_config, pci_mem_data;
@@ -204,9 +205,10 @@  static void pci_dec_21154_init_device(SysBusDevice *dev)
                                           pci_unin_main_write, &s->host_state);
     sysbus_init_mmio(dev, 0x1000, pci_mem_config);
     sysbus_init_mmio(dev, 0x1000, pci_mem_data);
+    return 0;
 }
 
-static void pci_unin_agp_init_device(SysBusDevice *dev)
+static int pci_unin_agp_init_device(SysBusDevice *dev)
 {
     UNINState *s;
     int pci_mem_config, pci_mem_data;
@@ -220,9 +222,10 @@  static void pci_unin_agp_init_device(SysBusDevice *dev)
                                           pci_unin_main_write, &s->host_state);
     sysbus_init_mmio(dev, 0x1000, pci_mem_config);
     sysbus_init_mmio(dev, 0x1000, pci_mem_data);
+    return 0;
 }
 
-static void pci_unin_internal_init_device(SysBusDevice *dev)
+static int pci_unin_internal_init_device(SysBusDevice *dev)
 {
     UNINState *s;
     int pci_mem_config, pci_mem_data;
@@ -236,6 +239,7 @@  static void pci_unin_internal_init_device(SysBusDevice *dev)
                                           pci_unin_write, s);
     sysbus_init_mmio(dev, 0x1000, pci_mem_config);
     sysbus_init_mmio(dev, 0x1000, pci_mem_data);
+    return 0;
 }
 
 PCIBus *pci_pmac_init(qemu_irq *pic)
@@ -277,7 +281,7 @@  PCIBus *pci_pmac_init(qemu_irq *pic)
     return d->host_state.bus;
 }
 
-static void unin_main_pci_host_init(PCIDevice *d)
+static int unin_main_pci_host_init(PCIDevice *d)
 {
     pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);
     pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_PCI);
@@ -287,9 +291,10 @@  static void unin_main_pci_host_init(PCIDevice *d)
     d->config[0x0D] = 0x10; // latency_timer
     d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
     d->config[0x34] = 0x00; // capabilities_pointer
+    return 0;
 }
 
-static void dec_21154_pci_host_init(PCIDevice *d)
+static int dec_21154_pci_host_init(PCIDevice *d)
 {
     /* pci-to-pci bridge */
     pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_DEC);
@@ -315,9 +320,10 @@  static void dec_21154_pci_host_init(PCIDevice *d)
     d->config[0x26] = 0xF1; // prefectchable_memory_limit
     d->config[0x27] = 0x7F;
     // d->config[0x34] = 0xdc // capabilities_pointer
+    return 0;
 }
 
-static void unin_agp_pci_host_init(PCIDevice *d)
+static int unin_agp_pci_host_init(PCIDevice *d)
 {
     pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);
     pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_AGP);
@@ -327,9 +333,10 @@  static void unin_agp_pci_host_init(PCIDevice *d)
     d->config[0x0D] = 0x10; // latency_timer
     d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
     //    d->config[0x34] = 0x80; // capabilities_pointer
+    return 0;
 }
 
-static void unin_internal_pci_host_init(PCIDevice *d)
+static int unin_internal_pci_host_init(PCIDevice *d)
 {
     pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);
     pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_I_PCI);
@@ -339,6 +346,7 @@  static void unin_internal_pci_host_init(PCIDevice *d)
     d->config[0x0D] = 0x10; // latency_timer
     d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
     d->config[0x34] = 0x00; // capabilities_pointer
+    return 0;
 }
 
 static PCIDeviceInfo unin_main_pci_host_info = {
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index 5eb2625..3b14b07 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -109,7 +109,7 @@  static void pci_vpb_map(SysBusDevice *dev, target_phys_addr_t base)
     }
 }
 
-static void pci_vpb_init(SysBusDevice *dev)
+static int pci_vpb_init(SysBusDevice *dev)
 {
     PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev);
     PCIBus *bus;
@@ -129,16 +129,17 @@  static void pci_vpb_init(SysBusDevice *dev)
     sysbus_init_mmio_cb(dev, 0x04000000, pci_vpb_map);
 
     pci_create_simple(bus, -1, "versatile_pci_host");
+    return 0;
 }
 
-static void pci_realview_init(SysBusDevice *dev)
+static int pci_realview_init(SysBusDevice *dev)
 {
     PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev);
     s->realview = 1;
-    pci_vpb_init(dev);
+    return pci_vpb_init(dev);
 }
 
-static void versatile_pci_host_init(PCIDevice *d)
+static int versatile_pci_host_init(PCIDevice *d)
 {
     pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_XILINX);
     /* Both boards have the same device ID.  Oh well.  */
@@ -151,6 +152,7 @@  static void versatile_pci_host_init(PCIDevice *d)
     d->config[0x09] = 0x00; // programming i/f
     pci_config_set_class(d->config, PCI_CLASS_PROCESSOR_CO);
     d->config[0x0D] = 0x10; // latency_timer
+    return 0;
 }
 
 static PCIDeviceInfo versatile_pci_host_info = {
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 3371121..e1035a9 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -129,7 +129,7 @@  static CPUWriteMemoryFunc *vpb_sic_writefn[] = {
    vpb_sic_write
 };
 
-static void vpb_sic_init(SysBusDevice *dev)
+static int vpb_sic_init(SysBusDevice *dev)
 {
     vpb_sic_state *s = FROM_SYSBUS(vpb_sic_state, dev);
     int iomemtype;
@@ -144,6 +144,7 @@  static void vpb_sic_init(SysBusDevice *dev)
                                        vpb_sic_writefn, s);
     sysbus_init_mmio(dev, 0x1000, iomemtype);
     /* ??? Save/restore.  */
+    return 0;
 }
 
 /* Board init.  */
diff --git a/hw/vga.c b/hw/vga.c
index 4a0f197..12c0424 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2480,7 +2480,7 @@  static void pci_vga_write_config(PCIDevice *d,
         s->map_addr = 0;
 }
 
-static void pci_vga_initfn(PCIDevice *dev)
+static int pci_vga_initfn(PCIDevice *dev)
 {
      PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
      VGAState *s = &d->vga_state;
@@ -2511,7 +2511,8 @@  static void pci_vga_initfn(PCIDevice *dev)
             bios_total_size <<= 1;
         pci_register_bar(&d->dev, PCI_ROM_SLOT, bios_total_size,
                          PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
-    }
+     }
+     return 0;
 }
 
 int pci_vga_init(PCIBus *bus,
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 8b57dfc..71c3868 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -424,7 +424,7 @@  static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
     virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
 }
 
-static void virtio_blk_init_pci(PCIDevice *pci_dev)
+static int virtio_blk_init_pci(PCIDevice *pci_dev)
 {
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
     VirtIODevice *vdev;
@@ -435,15 +435,17 @@  static void virtio_blk_init_pci(PCIDevice *pci_dev)
 
     if (!proxy->dinfo) {
         fprintf(stderr, "drive property not set\n");
+        return -1;
     }
     vdev = virtio_blk_init(&pci_dev->qdev, proxy->dinfo);
     virtio_init_pci(proxy, vdev,
                     PCI_VENDOR_ID_REDHAT_QUMRANET,
                     PCI_DEVICE_ID_VIRTIO_BLOCK,
                     proxy->class_code, 0x00);
+    return 0;
 }
 
-static void virtio_console_init_pci(PCIDevice *pci_dev)
+static int virtio_console_init_pci(PCIDevice *pci_dev)
 {
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
     VirtIODevice *vdev;
@@ -458,9 +460,10 @@  static void virtio_console_init_pci(PCIDevice *pci_dev)
                     PCI_VENDOR_ID_REDHAT_QUMRANET,
                     PCI_DEVICE_ID_VIRTIO_CONSOLE,
                     proxy->class_code, 0x00);
+    return 0;
 }
 
-static void virtio_net_init_pci(PCIDevice *pci_dev)
+static int virtio_net_init_pci(PCIDevice *pci_dev)
 {
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
     VirtIODevice *vdev;
@@ -481,9 +484,10 @@  static void virtio_net_init_pci(PCIDevice *pci_dev)
 
     /* make the actual value visible */
     proxy->nvectors = vdev->nvectors;
+    return 0;
 }
 
-static void virtio_balloon_init_pci(PCIDevice *pci_dev)
+static int virtio_balloon_init_pci(PCIDevice *pci_dev)
 {
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
     VirtIODevice *vdev;
@@ -494,6 +498,7 @@  static void virtio_balloon_init_pci(PCIDevice *pci_dev)
                     PCI_DEVICE_ID_VIRTIO_BALLOON,
                     PCI_CLASS_MEMORY_RAM,
                     0x00);
+    return 0;
 }
 
 static PCIDeviceInfo virtio_info[] = {
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 5ceebf1..dcdc7ec 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1210,7 +1210,7 @@  static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num,
                     iomemtype);
 }
 
-static void pci_vmsvga_initfn(PCIDevice *dev)
+static int pci_vmsvga_initfn(PCIDevice *dev)
 {
     struct pci_vmsvga_state_s *s =
         DO_UPCAST(struct pci_vmsvga_state_s, card, dev);
@@ -1236,6 +1236,7 @@  static void pci_vmsvga_initfn(PCIDevice *dev)
     vmsvga_init(&s->chip, VGA_RAM_SIZE);
 
     register_savevm("vmware_vga", 0, 0, pci_vmsvga_save, pci_vmsvga_load, s);
+    return 0;
 }
 
 void pci_vmsvga_init(PCIBus *bus)
diff --git a/hw/wm8750.c b/hw/wm8750.c
index 0c0dbba..f55eae7 100644
--- a/hw/wm8750.c
+++ b/hw/wm8750.c
@@ -645,7 +645,7 @@  static int wm8750_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void wm8750_init(i2c_slave *i2c)
+static int wm8750_init(i2c_slave *i2c)
 {
     WM8750State *s = FROM_I2C_SLAVE(WM8750State, i2c);
 
@@ -653,6 +653,7 @@  static void wm8750_init(i2c_slave *i2c)
     wm8750_reset(&s->i2c);
 
     register_savevm(CODEC, -1, 0, wm8750_save, wm8750_load, s);
+    return 0;
 }
 
 #if 0
diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c
index f981d10..aec6d7b 100644
--- a/hw/xilinx_ethlite.c
+++ b/hw/xilinx_ethlite.c
@@ -207,7 +207,7 @@  static void eth_cleanup(VLANClientState *vc)
     qemu_free(s);
 }
 
-static void xilinx_ethlite_init(SysBusDevice *dev)
+static int xilinx_ethlite_init(SysBusDevice *dev)
 {
     struct xlx_ethlite *s = FROM_SYSBUS(typeof (*s), dev);
     int regs;
@@ -221,6 +221,7 @@  static void xilinx_ethlite_init(SysBusDevice *dev)
     qdev_get_macaddr(&dev->qdev, s->macaddr);
     s->vc = qdev_get_vlan_client(&dev->qdev,
                                  eth_can_rx, eth_rx, NULL, eth_cleanup, s);
+    return 0;
 }
 
 static SysBusDeviceInfo xilinx_ethlite_info = {
diff --git a/hw/xilinx_intc.c b/hw/xilinx_intc.c
index 7fadad5..9bca659 100644
--- a/hw/xilinx_intc.c
+++ b/hw/xilinx_intc.c
@@ -145,7 +145,7 @@  static void irq_handler(void *opaque, int irq, int level)
     update_irq(p);
 }
 
-static void xilinx_intc_init(SysBusDevice *dev)
+static int xilinx_intc_init(SysBusDevice *dev)
 {
     struct xlx_pic *p = FROM_SYSBUS(typeof (*p), dev);
     int pic_regs;
@@ -155,6 +155,7 @@  static void xilinx_intc_init(SysBusDevice *dev)
 
     pic_regs = cpu_register_io_memory(pic_read, pic_write, p);
     sysbus_init_mmio(dev, R_MAX * 4, pic_regs);
+    return 0;
 }
 
 static SysBusDeviceInfo xilinx_intc_info = {
diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c
index 196f011..a93c63a 100644
--- a/hw/xilinx_timer.c
+++ b/hw/xilinx_timer.c
@@ -189,7 +189,7 @@  static void timer_hit(void *opaque)
     timer_update_irq(t);
 }
 
-static void xilinx_timer_init(SysBusDevice *dev)
+static int xilinx_timer_init(SysBusDevice *dev)
 {
     struct timerblock *t = FROM_SYSBUS(typeof (*t), dev);
     unsigned int i;
@@ -212,6 +212,7 @@  static void xilinx_timer_init(SysBusDevice *dev)
 
     timer_regs = cpu_register_io_memory(timer_read, timer_write, t);
     sysbus_init_mmio(dev, R_MAX * 4 * t->nr_timers, timer_regs);
+    return 0;
 }
 
 static SysBusDeviceInfo xilinx_timer_info = {
diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c
index 9bf2e91..13a0108 100644
--- a/hw/xilinx_uartlite.c
+++ b/hw/xilinx_uartlite.c
@@ -193,7 +193,7 @@  static void uart_event(void *opaque, int event)
 
 }
 
-static void xilinx_uartlite_init(SysBusDevice *dev)
+static int xilinx_uartlite_init(SysBusDevice *dev)
 {
     struct xlx_uartlite *s = FROM_SYSBUS(typeof (*s), dev);
     int uart_regs;
@@ -207,6 +207,7 @@  static void xilinx_uartlite_init(SysBusDevice *dev)
     s->chr = qdev_init_chardev(&dev->qdev);
     if (s->chr)
         qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
+    return 0;
 }
 
 static void xilinx_uart_register(void)