All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev
@ 2012-01-24 19:32 Anthony Liguori
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 01/28] macio: convert " Anthony Liguori
                   ` (30 more replies)
  0 siblings, 31 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:32 UTC (permalink / raw)
  To: qemu-devel

This series makes qdev a proper Object and converts qdev's type inheritance to
QOM inheritance.

The first half of the series are manual cleanups/refactorings.  The second half
is mostly scripted conversion, separated out into reviewable and bisectable
chunks.

I've tested this series extensively for the pc target including bisectability.
I have not tested any other targets yet so your mileage may vary.

Since the original RFC, I've fixed any of the not-for-upstream issues.  This
also includes some uni-north patches that are in ppc-next.

Paolo and Andreas have asked that I declare a date when I'll merge this so that
people can be prepared for the rebase fall out.  I will merge this on Friday
unless there is a major problem found in review.

This is also available at:

https://github.com/aliguori/qemu/tree/qom-upstream.10

For full context, the whole tree is located at:

https://github.com/aliguori/qemu/commits/qom-rebase.7

git diffstat origin/master HEAD
 Makefile                   |    2 
 Makefile.hw                |    1 
 Makefile.objs              |    3 
 Makefile.target            |    2 
 configure                  |    2 
 hw/9pfs/virtio-9p-device.c |   44 ++--
 hw/a9mpcore.c              |   21 +
 hw/ac97.c                  |   39 ++-
 hw/acpi_piix4.c            |   59 +++--
 hw/ads7846.c               |   17 +
 hw/alpha_typhoon.c         |   17 +
 hw/apb_pci.c               |   71 ++++--
 hw/apic.c                  |   21 +
 hw/apic_common.c           |   88 +++++---
 hw/apic_internal.h         |   32 +-
 hw/applesmc.c              |   18 +
 hw/arm11mpcore.c           |   68 +++---
 hw/arm_l2x0.c              |   25 +-
 hw/arm_mptimer.c           |   23 +-
 hw/arm_sysctl.c            |   31 +-
 hw/arm_timer.c             |   46 +++-
 hw/armv7m.c                |   25 +-
 hw/armv7m_nvic.c           |   21 +
 hw/bitbang_i2c.c           |   17 +
 hw/bonito.c                |   47 ++--
 hw/ccid-card-emulated.c    |   27 +-
 hw/ccid-card-passthru.c    |   27 +-
 hw/ccid.h                  |   28 +-
 hw/cirrus_vga.c            |   50 ++--
 hw/container.c             |   17 +
 hw/cs4231.c                |   27 +-
 hw/cs4231a.c               |   20 +
 hw/debugcon.c              |   16 +
 hw/dec_pci.c               |   74 ++++--
 hw/ds1225y.c               |   29 +-
 hw/ds1338.c                |   31 +-
 hw/e1000.c                 |   45 ++--
 hw/eccmemctl.c             |   29 +-
 hw/eepro100.c              |  202 +++++++++++-------
 hw/empty_slot.c            |   15 +
 hw/es1370.c                |   36 +--
 hw/escc.c                  |   43 ++-
 hw/esp.c                   |   27 +-
 hw/etraxfs_eth.c           |   33 +--
 hw/etraxfs_pic.c           |   25 +-
 hw/etraxfs_ser.c           |   17 +
 hw/etraxfs_timer.c         |   16 +
 hw/fdc.c                   |   84 +++++--
 hw/fw_cfg.c                |   33 +--
 hw/g364fb.c                |   33 +--
 hw/grackle_pci.c           |   44 ++--
 hw/grlib_apbuart.c         |   25 +-
 hw/grlib_gptimer.c         |   31 +-
 hw/grlib_irqmp.c           |   29 +-
 hw/gt64xxx.c               |   39 ++-
 hw/gus.c                   |   20 +
 hw/hda-audio.c             |   60 +++--
 hw/hpet.c                  |   33 +--
 hw/i2c.c                   |  111 +++++++---
 hw/i2c.h                   |   52 ++--
 hw/i82374.c                |   19 +
 hw/i82378.c                |   31 +-
 hw/i8254.c                 |   22 +-
 hw/i8259.c                 |   15 +
 hw/i8259_common.c          |   45 ++--
 hw/i8259_internal.h        |   27 +-
 hw/ide/cmd646.c            |   41 ++-
 hw/ide/ich.c               |   37 +--
 hw/ide/internal.h          |   20 +
 hw/ide/isa.c               |   20 +
 hw/ide/piix.c              |   91 +++++---
 hw/ide/qdev.c              |  111 ++++++----
 hw/ide/via.c               |   27 +-
 hw/integratorcp.c          |   40 ++-
 hw/intel-hda.c             |   91 +++++---
 hw/intel-hda.h             |   26 +-
 hw/ioapic.c                |   17 +
 hw/ioapic_common.c         |   49 +++-
 hw/ioapic_internal.h       |   26 +-
 hw/ioh3420.c               |   59 +++--
 hw/isa-bus.c               |   57 +++--
 hw/isa.h                   |   23 +-
 hw/ivshmem.c               |   47 ++--
 hw/kvm/apic.c              |   19 +
 hw/kvm/clock.c             |   19 +
 hw/kvm/i8259.c             |   19 +
 hw/kvm/ioapic.c            |   23 +-
 hw/lan9118.c               |   31 +-
 hw/lance.c                 |   33 +--
 hw/lm32_juart.c            |   19 +
 hw/lm32_pic.c              |   19 +
 hw/lm32_sys.c              |   29 +-
 hw/lm32_timer.c            |   31 +-
 hw/lm32_uart.c             |   19 +
 hw/lm832x.c                |   33 +--
 hw/lsi53c895a.c            |   33 +--
 hw/m48t59.c                |   51 +++-
 hw/macio.c                 |   50 +++-
 hw/marvell_88w8618_audio.c |   35 +--
 hw/max111x.c               |   34 ++-
 hw/max7310.c               |   35 +--
 hw/mc146818rtc.c           |   22 +-
 hw/milkymist-ac97.c        |   19 +
 hw/milkymist-hpdmc.c       |   19 +
 hw/milkymist-memcard.c     |   19 +
 hw/milkymist-minimac2.c    |   37 ++-
 hw/milkymist-pfpu.c        |   19 +
 hw/milkymist-softusb.c     |   43 ++-
 hw/milkymist-sysctl.c      |   43 ++-
 hw/milkymist-tmu2.c        |   19 +
 hw/milkymist-uart.c        |   19 +
 hw/milkymist-vgafb.c       |   31 +-
 hw/mips_malta.c            |   19 +
 hw/mipsnet.c               |   33 +--
 hw/mpc8544_guts.c          |   15 +
 hw/mst_fpga.c              |   19 +
 hw/musicpal.c              |  153 ++++++++++----
 hw/nand.c                  |   33 +--
 hw/ne2000-isa.c            |   18 +
 hw/ne2000.c                |   37 ++-
 hw/omap_gpio.c             |   70 ++++--
 hw/omap_intc.c             |   62 +++--
 hw/onenand.c               |   35 ++-
 hw/opencores_eth.c         |   31 +-
 hw/openpic.c               |   30 --
 hw/openpic.h               |    2 
 hw/parallel.c              |   16 +
 hw/pc.c                    |   20 +
 hw/pci.c                   |  140 +++++-------
 hw/pci.h                   |   80 +++----
 hw/pci_bridge.c            |    2 
 hw/pcie.c                  |    2 
 hw/pckbd.c                 |   18 +
 hw/pcnet-pci.c             |   39 ++-
 hw/pcnet.c                 |    2 
 hw/piix4.c                 |   35 +--
 hw/piix_pci.c              |  126 +++++++----
 hw/pl011.c                 |   36 ++-
 hw/pl022.c                 |   15 +
 hw/pl031.c                 |   19 +
 hw/pl041.c                 |   34 +--
 hw/pl050.c                 |   34 ++-
 hw/pl061.c                 |   34 ++-
 hw/pl080.c                 |   38 ++-
 hw/pl110.c                 |   57 +++--
 hw/pl181.c                 |   23 +-
 hw/pl190.c                 |   21 +
 hw/ppc4xx_pci.c            |   38 ++-
 hw/ppc_newworld.c          |    2 
 hw/ppce500_pci.c           |   38 ++-
 hw/ppce500_spin.c          |   15 +
 hw/prep_pci.c              |   52 ++--
 hw/pxa2xx.c                |   96 ++++++--
 hw/pxa2xx_dma.c            |   29 +-
 hw/pxa2xx_gpio.c           |   29 +-
 hw/pxa2xx_pic.c            |   19 +
 hw/pxa2xx_timer.c          |   66 +++---
 hw/qdev-properties.c       |   20 -
 hw/qdev.c                  |  123 ++++++++---
 hw/qdev.h                  |   40 +++
 hw/qxl.c                   |   66 +++---
 hw/realview.c              |   15 +
 hw/realview_gic.c          |   16 +
 hw/rtl8139.c               |   43 ++-
 hw/s390-virtio-bus.c       |  110 +++++++---
 hw/sb16.c                  |   20 +
 hw/sbi.c                   |   19 +
 hw/scsi-bus.c              |   95 ++++++--
 hw/scsi-disk.c             |  159 ++++++++------
 hw/scsi-generic.c          |   29 +-
 hw/scsi.h                  |   31 +-
 hw/serial.c                |   18 +
 hw/sga.c                   |   15 -
 hw/sh_pci.c                |   37 ++-
 hw/slavio_intctl.c         |   19 +
 hw/slavio_misc.c           |   34 ++-
 hw/slavio_timer.c          |   29 +-
 hw/smbus.c                 |   85 +++++--
 hw/smbus.h                 |   42 ++-
 hw/smbus_eeprom.c          |   27 +-
 hw/smc91c111.c             |   31 +-
 hw/spapr_llan.c            |   41 ++-
 hw/spapr_pci.c             |   31 ++
 hw/spapr_vio.c             |   72 ++++--
 hw/spapr_vio.h             |   35 ++-
 hw/spapr_vscsi.c           |   37 ++-
 hw/spapr_vty.c             |   37 ++-
 hw/sparc32_dma.c           |   31 +-
 hw/spitz.c                 |   94 +++++---
 hw/ssd0303.c               |   33 +--
 hw/ssd0323.c               |   17 +
 hw/ssi-sd.c                |   17 +
 hw/ssi.c                   |   23 +-
 hw/ssi.h                   |   18 +
 hw/stellaris.c             |   65 +++++-
 hw/stellaris_enet.c        |   27 +-
 hw/strongarm.c             |  124 +++++++----
 hw/sun4c_intctl.c          |   19 +
 hw/sun4m.c                 |   78 +++++--
 hw/sun4m_iommu.c           |   29 +-
 hw/sun4u.c                 |   71 ++++--
 hw/sysbus.c                |   40 ++-
 hw/sysbus.h                |   25 +-
 hw/tcx.c                   |   37 ++-
 hw/tmp105.c                |   37 ++-
 hw/tosa.c                  |   50 ++--
 hw/tusb6010.c              |   17 +
 hw/twl92230.c              |   35 +--
 hw/unin_pci.c              |  204 +++++++++++++-----
 hw/usb-audio.c             |   38 ++-
 hw/usb-bt.c                |   33 +--
 hw/usb-bus.c               |  190 +++++++++++++----
 hw/usb-ccid.c              |  114 +++++++---
 hw/usb-desc.c              |   22 +-
 hw/usb-ehci.c              |   63 +++--
 hw/usb-hid.c               |  108 +++++-----
 hw/usb-hub.c               |   35 +--
 hw/usb-msd.c               |   41 ++-
 hw/usb-net.c               |   43 ++-
 hw/usb-ohci.c              |   58 +++--
 hw/usb-serial.c            |   74 +++---
 hw/usb-uhci.c              |  189 +++++++++++------
 hw/usb-wacom.c             |   36 +--
 hw/usb-xhci.c              |   37 ++-
 hw/usb.c                   |   24 --
 hw/usb.h                   |   50 +++-
 hw/versatile_pci.c         |   53 +++-
 hw/versatilepb.c           |   19 +
 hw/vga-isa.c               |   18 +
 hw/vga-pci.c               |   27 +-
 hw/virtio-console.c        |   69 +++---
 hw/virtio-net.c            |    2 
 hw/virtio-pci.c            |  210 +++++++++++--------
 hw/virtio-serial-bus.c     |   68 +++---
 hw/virtio-serial.h         |   81 ++++---
 hw/vmmouse.c               |   22 +-
 hw/vmport.c                |   16 +
 hw/vmware_vga.c            |   34 +--
 hw/vt82c686.c              |  120 ++++++-----
 hw/wdt_i6300esb.c          |   33 +--
 hw/wdt_ib700.c             |   18 +
 hw/wm8750.c                |   37 ++-
 hw/xen_platform.c          |   34 +--
 hw/xilinx_axidma.c         |   27 +-
 hw/xilinx_axienet.c        |   35 ++-
 hw/xilinx_ethlite.c        |   31 +-
 hw/xilinx_intc.c           |   25 +-
 hw/xilinx_timer.c          |   27 +-
 hw/xilinx_uartlite.c       |   16 +
 hw/xio3130_downstream.c    |   59 +++--
 hw/xio3130_upstream.c      |   53 ++--
 hw/z2.c                    |   52 +++-
 hw/zaurus.c                |   27 +-
 include/qemu/object.h      |  436 ++++++++++++++++++++++++++++++++++++++++
 qom/Makefile               |    1 
 qom/object.c               |  485 +++++++++++++++++++++++++++++++++++++++++++++
 usb-bsd.c                  |   29 +-
 usb-linux.c                |   37 +--
 usb-redir.c                |   33 +--
 259 files changed, 7764 insertions(+), 3755 deletions(-)

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 01/28] macio: convert to qdev
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
@ 2012-01-24 19:32 ` Anthony Liguori
  2012-01-26 23:17   ` [Qemu-devel] [PATCH] macio: Convert " Andreas Färber
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 02/28] openpic: remove dead code to make a PCI device version Anthony Liguori
                   ` (29 subsequent siblings)
  30 siblings, 1 reply; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori

This is a "shallow", half hearted, and untested conversion.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/macio.c |   43 ++++++++++++++++++++++++++++++-------------
 1 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/hw/macio.c b/hw/macio.c
index cc6ae40..357e0ea 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -27,8 +27,9 @@
 #include "pci.h"
 #include "escc.h"
 
-typedef struct macio_state_t macio_state_t;
-struct macio_state_t {
+typedef struct MacIOState
+{
+    PCIDevice parent;
     int is_oldworld;
     MemoryRegion bar;
     MemoryRegion *pic_mem;
@@ -38,9 +39,9 @@ struct macio_state_t {
     void *nvram;
     int nb_ide;
     MemoryRegion *ide_mem[4];
-};
+} MacIOState;
 
-static void macio_bar_setup(macio_state_t *macio_state)
+static void macio_bar_setup(MacIOState *macio_state)
 {
     int i;
     MemoryRegion *bar = &macio_state->bar;
@@ -74,6 +75,27 @@ static void macio_bar_setup(macio_state_t *macio_state)
         macio_nvram_setup_bar(macio_state->nvram, bar, 0x60000);
 }
 
+static int macio_initfn(PCIDevice *d)
+{
+    d->config[0x3d] = 0x01; // interrupt on pin 1
+    return 0;
+}
+
+static PCIDeviceInfo macio_info = {
+    .qdev.name = "macio",
+    .qdev.size = sizeof(MacIOState),
+    .init = macio_initfn,
+    .vendor_id = PCI_VENDOR_ID_APPLE,
+    .class_id = PCI_CLASS_OTHERS << 8,
+};
+
+static void macio_register(void)
+{
+    pci_qdev_register(&macio_info);
+}
+
+device_init(macio_register);
+
 void macio_init (PCIBus *bus, int device_id, int is_oldworld,
                  MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
                  MemoryRegion *cuda_mem, void *nvram,
@@ -81,13 +103,12 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld,
                  MemoryRegion *escc_mem)
 {
     PCIDevice *d;
-    macio_state_t *macio_state;
+    MacIOState *macio_state;
     int i;
 
-    d = pci_register_device(bus, "macio",
-                            sizeof(PCIDevice) + sizeof(macio_state_t),
-                            -1, NULL, NULL);
-    macio_state = (macio_state_t *)(d + 1);
+    d = pci_create_simple(bus, -1, "macio");
+
+    macio_state = DO_UPCAST(MacIOState, parent, d);
     macio_state->is_oldworld = is_oldworld;
     macio_state->pic_mem = pic_mem;
     macio_state->dbdma_mem = dbdma_mem;
@@ -104,11 +125,7 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld,
     /* Note: this code is strongly inspirated from the corresponding code
        in PearPC */
 
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);
     pci_config_set_device_id(d->config, device_id);
-    pci_config_set_class(d->config, PCI_CLASS_OTHERS << 8);
-
-    d->config[0x3d] = 0x01; // interrupt on pin 1
 
     macio_bar_setup(macio_state);
     pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &macio_state->bar);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 02/28] openpic: remove dead code to make a PCI device version
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 01/28] macio: convert " Anthony Liguori
@ 2012-01-24 19:32 ` Anthony Liguori
  2012-01-26 23:57   ` Andreas Färber
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 03/28] pci: call reset unconditionally Anthony Liguori
                   ` (28 subsequent siblings)
  30 siblings, 1 reply; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, qemu-ppc, Alexander Graf

bus is always NULL so the code in this if clause is dead (and therefore
untested).

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/openpic.c      |   30 +++---------------------------
 hw/openpic.h      |    2 +-
 hw/ppc_newworld.c |    2 +-
 3 files changed, 5 insertions(+), 29 deletions(-)

diff --git a/hw/openpic.c b/hw/openpic.c
index 22fc275..280b7a9 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -1181,41 +1181,17 @@ static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src)
     qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
 }
 
-qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus,
+qemu_irq *openpic_init (MemoryRegion **pmem, int nb_cpus,
                         qemu_irq **irqs, qemu_irq irq_out)
 {
     openpic_t *opp;
-    uint8_t *pci_conf;
     int i, m;
 
     /* XXX: for now, only one CPU is supported */
     if (nb_cpus != 1)
         return NULL;
-    if (bus) {
-        opp = (openpic_t *)pci_register_device(bus, "OpenPIC", sizeof(openpic_t),
-                                               -1, NULL, NULL);
-        pci_conf = opp->pci_dev.config;
-        pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_IBM);
-        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_IBM_OPENPIC2);
-        pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER); // FIXME?
-        pci_conf[0x3d] = 0x00; // no interrupt pin
-
-        memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000);
-#if 0 // Don't implement ISU for now
-        opp_io_memory = cpu_register_io_memory(openpic_src_read,
-                                               openpic_src_write, NULL
-                                               DEVICE_NATIVE_ENDIAN);
-        cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2),
-                                     opp_io_memory);
-#endif
-
-        /* Register I/O spaces */
-        pci_register_bar(&opp->pci_dev, 0,
-                         PCI_BASE_ADDRESS_SPACE_MEMORY, &opp->mem);
-    } else {
-        opp = g_malloc0(sizeof(openpic_t));
-        memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000);
-    }
+    opp = g_malloc0(sizeof(openpic_t));
+    memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000);
 
     //    isu_base &= 0xFFFC0000;
     opp->nb_cpus = nb_cpus;
diff --git a/hw/openpic.h b/hw/openpic.h
index 715f084..8556030 100644
--- a/hw/openpic.h
+++ b/hw/openpic.h
@@ -11,7 +11,7 @@ enum {
     OPENPIC_OUTPUT_NB,
 };
 
-qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus,
+qemu_irq *openpic_init (MemoryRegion **pmem, int nb_cpus,
                         qemu_irq **irqs, qemu_irq irq_out);
 qemu_irq *mpic_init (MemoryRegion *address_space, target_phys_addr_t base,
                      int nb_cpus, qemu_irq **irqs, qemu_irq irq_out);
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index a746c9c..506187b 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -311,7 +311,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
             exit(1);
         }
     }
-    pic = openpic_init(NULL, &pic_mem, smp_cpus, openpic_irqs, NULL);
+    pic = openpic_init(&pic_mem, smp_cpus, openpic_irqs, NULL);
     if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
         /* 970 gets a U3 bus */
         pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io());
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 03/28] pci: call reset unconditionally
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 01/28] macio: convert " Anthony Liguori
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 02/28] openpic: remove dead code to make a PCI device version Anthony Liguori
@ 2012-01-24 19:32 ` Anthony Liguori
  2012-01-25 12:42   ` Michael S. Tsirkin
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 04/28] qom: add the base Object class (v2) Anthony Liguori
                   ` (27 subsequent siblings)
  30 siblings, 1 reply; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Michael S. Tsirkin

Because now all PCI devices are converted to qdev.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/pci.c |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 54400ac..ab3b53d 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -159,11 +159,8 @@ void pci_device_deassert_intx(PCIDevice *dev)
 void pci_device_reset(PCIDevice *dev)
 {
     int r;
-    /* TODO: call the below unconditionally once all pci devices
-     * are qdevified */
-    if (dev->qdev.info) {
-        qdev_reset_all(&dev->qdev);
-    }
+
+    qdev_reset_all(&dev->qdev);
 
     dev->irq_state = 0;
     pci_update_irq_status(dev);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 04/28] qom: add the base Object class (v2)
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (2 preceding siblings ...)
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 03/28] pci: call reset unconditionally Anthony Liguori
@ 2012-01-24 19:32 ` Anthony Liguori
  2012-01-25 21:30   ` Andreas Färber
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 05/28] qdev: integrate with QEMU Object Model (v2) Anthony Liguori
                   ` (26 subsequent siblings)
  30 siblings, 1 reply; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori

This class provides the main building block for QEMU Object Model and is
extensively documented in the header file.  It is largely inspired by GObject.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
v1 -> v2
 - remove printf() in type registration
 - fix typo in comment (Paolo)
 - make Interface private
 - move object into a new directory and move header into include/qemu/
 - don't make object.h depend on qemu-common.h
 - remove Type and replace it with TypeImpl * (Paolo)
 - use hash table to store types (Paolo)
 - aggressively cache parent type (Paolo)
 - make a type_register and use it with interfaces (Paolo)
 - fix interface cast comment (Paolo)
 - add a few more functions required in later series
---
 Makefile              |    2 +
 Makefile.hw           |    1 +
 Makefile.objs         |    3 +
 Makefile.target       |    2 +
 configure             |    2 +-
 include/qemu/object.h |  436 ++++++++++++++++++++++++++++++++++++++++++++
 qom/Makefile          |    1 +
 qom/object.c          |  485 +++++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 931 insertions(+), 1 deletions(-)
 create mode 100644 include/qemu/object.h
 create mode 100644 qom/Makefile
 create mode 100644 qom/object.c

diff --git a/Makefile b/Makefile
index 917fb9b..d172cbf 100644
--- a/Makefile
+++ b/Makefile
@@ -114,6 +114,8 @@ QEMU_CFLAGS+=$(CURL_CFLAGS)
 
 QEMU_CFLAGS+=$(GLIB_CFLAGS)
 
+QEMU_CFLAGS += -I$(SRC_PATH)/include
+
 ui/cocoa.o: ui/cocoa.m
 
 ui/sdl.o audio/sdlaudio.o ui/sdl_zoom.o baum.o: QEMU_CFLAGS += $(SDL_CFLAGS)
diff --git a/Makefile.hw b/Makefile.hw
index 63eb7e4..7b8d068 100644
--- a/Makefile.hw
+++ b/Makefile.hw
@@ -11,6 +11,7 @@ $(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw)
 
 QEMU_CFLAGS+=-I..
 QEMU_CFLAGS += $(GLIB_CFLAGS)
+QEMU_CFLAGS += -I$(SRC_PATH)/include
 
 include $(SRC_PATH)/Makefile.objs
 
diff --git a/Makefile.objs b/Makefile.objs
index 04a1d1b..a7bd3d9 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -122,6 +122,9 @@ common-obj-$(CONFIG_WIN32) += version.o
 
 common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o ui/spice-display.o spice-qemu-char.o
 
+include $(SRC_PATH)/qom/Makefile
+common-obj-y += $(addprefix qom/, $(qom-y))
+
 audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
 audio-obj-$(CONFIG_SDL) += sdlaudio.o
 audio-obj-$(CONFIG_OSS) += ossaudio.o
diff --git a/Makefile.target b/Makefile.target
index 092565a..2c763a1 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -22,6 +22,8 @@ QEMU_CFLAGS += -I.. -I$(TARGET_PATH) -DNEED_CPU_H
 
 include $(SRC_PATH)/Makefile.objs
 
+QEMU_CFLAGS+=-I$(SRC_PATH)/include
+
 ifdef CONFIG_USER_ONLY
 # user emulator name
 QEMU_PROG=qemu-$(TARGET_ARCH2)
diff --git a/configure b/configure
index 9d5175b..8f4eda0 100755
--- a/configure
+++ b/configure
@@ -3781,7 +3781,7 @@ DIRS="$DIRS pc-bios/spapr-rtas"
 DIRS="$DIRS roms/seabios roms/vgabios"
 DIRS="$DIRS fsdev ui"
 DIRS="$DIRS qapi qapi-generated"
-DIRS="$DIRS qga trace"
+DIRS="$DIRS qga trace qom"
 FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
 FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
diff --git a/include/qemu/object.h b/include/qemu/object.h
new file mode 100644
index 0000000..ba37850
--- /dev/null
+++ b/include/qemu/object.h
@@ -0,0 +1,436 @@
+/*
+ * QEMU Object Model
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_OBJECT_H
+#define QEMU_OBJECT_H
+
+#include <glib.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+struct TypeImpl;
+typedef struct TypeImpl *Type;
+
+typedef struct ObjectClass ObjectClass;
+typedef struct Object Object;
+
+typedef struct TypeInfo TypeInfo;
+
+typedef struct InterfaceClass InterfaceClass;
+typedef struct InterfaceInfo InterfaceInfo;
+
+#define TYPE_OBJECT NULL
+
+/**
+ * SECTION:object.h
+ * @title:Base Object Type System
+ * @short_description: interfaces for creating new types and objects
+ *
+ * The QEMU Object Model provides a framework for registering user creatable
+ * types and instantiating objects from those types.  QOM provides the following
+ * features:
+ *
+ *  - System for dynamically registering types
+ *  - Support for single-inheritance of types
+ *  - Multiple inheritance of stateless interfaces
+ *
+ * <example>
+ *   <title>Creating a minimal type</title>
+ *   <programlisting>
+ * #include "qdev.h"
+ *
+ * #define TYPE_MY_DEVICE "my-device"
+ *
+ * typedef struct MyDevice
+ * {
+ *     DeviceState parent;
+ *
+ *     int reg0, reg1, reg2;
+ * } MyDevice;
+ *
+ * static TypeInfo my_device_info = {
+ *     .name = TYPE_MY_DEVICE,
+ *     .parent = TYPE_DEVICE,
+ *     .instance_size = sizeof(MyDevice),
+ * };
+ *
+ * static void my_device_module_init(void)
+ * {
+ *     type_register_static(&my_device_info);
+ * }
+ *
+ * device_init(my_device_module_init);
+ *   </programlisting>
+ * </example>
+ *
+ * In the above example, we create a simple type that is described by #TypeInfo.
+ * #TypeInfo describes information about the type including what it inherits
+ * from, the instance and class size, and constructor/destructor hooks.
+ *
+ * Every type has an #ObjectClass associated with it.  #ObjectClass derivatives
+ * are instantiated dynamically but there is only ever one instance for any
+ * given type.  The #ObjectClass typically holds a table of function pointers
+ * for the virtual methods implemented by this type.
+ *
+ * Using object_new(), a new #Object derivative will be instantiated.  You can
+ * cast an #Object to a subclass (or base-class) type using
+ * object_dynamic_cast().  You typically want to define a macro wrapper around
+ * object_dynamic_cast_assert() to make it easier to convert to a specific type.
+ *
+ * # Class Initialization #
+ *
+ * Before an object is initialized, the class for the object must be
+ * initialized.  There is only one class object for all instance objects
+ * that is created lazily.
+ *
+ * Classes are initialized by first initializing any parent classes (if
+ * necessary).  After the parent class object has initialized, it will be
+ * copied into the current class object and any additional storage in the
+ * class object is zero filled.
+ *
+ * The effect of this is that classes automatically inherit any virtual
+ * function pointers that the parent class has already initialized.  All
+ * other fields will be zero filled.
+ *
+ * Once all of the parent classes have been initialized, #TypeInfo::class_init
+ * is called to let the class being instantiated provide default initialize for
+ * it's virtual functions.
+ *
+ * # Interfaces #
+ *
+ * Interfaces allow a limited form of multiple inheritance.  Instances are
+ * similar to normal types except for the fact that are only defined by
+ * their classes and never carry any state.  You can dynamically cast an object
+ * to one of its #Interface types and vice versa.
+ */
+
+/**
+ * ObjectClass:
+ *
+ * The base for all classes.  The only thing that #ObjectClass contains is an
+ * integer type handle.
+ */
+struct ObjectClass
+{
+    /*< private >*/
+    Type type;
+};
+
+/**
+ * Object:
+ *
+ * The base for all objects.  The first member of this object is a pointer to
+ * a #ObjectClass.  Since C guarantees that the first member of a structure
+ * always begins at byte 0 of that structure, as long as any sub-object places
+ * its parent as the first member, we can cast directly to a #Object.
+ *
+ * As a result, #Object contains a reference to the objects type as its
+ * first member.  This allows identification of the real type of the object at
+ * run time.
+ *
+ * #Object also contains a list of #Interfaces that this object
+ * implements.
+ */
+struct Object
+{
+    /*< private >*/
+    ObjectClass *class;
+
+    GSList *interfaces;
+};
+
+/**
+ * TypeInfo:
+ * @name: The name of the type.
+ * @parent: The name of the parent type.
+ * @instance_size: The size of the object (derivative of #Object).  If
+ *   @instance_size is 0, then the size of the object will be the size of the
+ *   parent object.
+ * @instance_init: This function is called to initialize an object.  The parent
+ *   class will have already been initialized so the type is only responsible
+ *   for initializing its own members.
+ * @instance_finalize: This function is called during object destruction.  This
+ *   is called before the parent @instance_finalize function has been called.
+ *   An object should only free the members that are unique to its type in this
+ *   function.
+ * @abstract: If this field is true, then the class is considered abstract and
+ *   cannot be directly instantiated.
+ * @class_size: The size of the class object (derivative of #ObjectClass)
+ *   for this object.  If @class_size is 0, then the size of the class will be
+ *   assumed to be the size of the parent class.  This allows a type to avoid
+ *   implementing an explicit class type if they are not adding additional
+ *   virtual functions.
+ * @class_init: This function is called after all parent class initialization
+ *   has occured to allow a class to set its default virtual method pointers.  
+ *   This is also the function to use to override virtual methods from a parent
+ *   class.
+ * @class_finalize: This function is called during class destruction and is
+ *   meant to release and dynamic parameters allocated by @class_init.
+ * @class_data: Data to pass to the @class_init and @class_finalize functions.
+ *   This can be useful when building dynamic classes.
+ * @interfaces: The list of interfaces associated with this type.  This
+ *   should point to a static array that's terminated with a zero filled
+ *   element.
+ */
+struct TypeInfo
+{
+    const char *name;
+    const char *parent;
+
+    size_t instance_size;
+    void (*instance_init)(Object *obj);
+    void (*instance_finalize)(Object *obj);
+
+    bool abstract;
+    size_t class_size;
+
+    void (*class_init)(ObjectClass *klass, void *data);
+    void (*class_finalize)(ObjectClass *klass, void *data);
+    void *class_data;
+
+    InterfaceInfo *interfaces;
+};
+
+/**
+ * OBJECT:
+ * @obj: A derivative of #Object
+ *
+ * Converts an object to a #Object.  Since all objects are #Objects,
+ * this function will always succeed.
+ */
+#define OBJECT(obj) \
+    ((Object *)(obj))
+
+/**
+ * OBJECT_CHECK:
+ * @type: The C type to use for the return value.
+ * @obj: A derivative of @type to cast.
+ * @name: The QOM typename of @type
+ *
+ * A type safe version of @object_dynamic_cast_assert.  Typically each class
+ * will define a macro based on this type to perform type safe dynamic_casts to
+ * this object type.
+ *
+ * If an invalid object is passed to this function, a run time assert will be
+ * generated.
+ */
+#define OBJECT_CHECK(type, obj, name) \
+    ((type *)object_dynamic_cast_assert((Object *)(obj), (name)))
+
+/**
+ * OBJECT_CLASS_CHECK:
+ * @class: The C type to use for the return value.
+ * @obj: A derivative of @type to cast.
+ * @name: the QOM typename of @class.
+ *
+ * A type safe version of @object_check_class.  This macro is typically wrapped
+ * by each type to perform type safe casts of a class to a specific class type.
+ */
+#define OBJECT_CLASS_CHECK(class, obj, name) \
+    ((class *)object_class_dynamic_cast_assert((ObjectClass *)(obj), (name)))
+
+/**
+ * OBJECT_GET_CLASS:
+ * @class: The C type to use for the return value.
+ * @obj: The object to obtain the class for.
+ * @name: The QOM typename of @obj.
+ *
+ * This function will return a specific class for a given object.  Its generally
+ * used by each type to provide a type safe macro to get a specific class type
+ * from an object.
+ */
+#define OBJECT_GET_CLASS(class, obj, name) \
+    OBJECT_CLASS_CHECK(class, object_get_class(OBJECT(obj)), name)
+
+#define OBJECT_CLASS(class) \
+    ((ObjectClass *)(class))
+
+/**
+ * InterfaceClass:
+ * @parent_class: the base class
+ *
+ * The class for all interfaces.  Subclasses of this class should only add
+ * virtual methods.
+ */
+struct InterfaceClass
+{
+    ObjectClass parent_class;
+};
+
+/**
+ * InterfaceInfo:
+ * @type: The name of the interface.
+ * @interface_initfn: This method is called during class initialization and is
+ *   used to initialize an interface associated with a class.  This function
+ *   should initialize any default virtual functions for a class and/or override
+ *   virtual functions in a parent class.
+ *
+ * The information associated with an interface.
+ */
+struct InterfaceInfo
+{
+    const char *type;
+
+    void (*interface_initfn)(ObjectClass *class, void *data);
+};
+
+#define TYPE_INTERFACE "interface"
+
+/**
+ * object_new:
+ * @typename: The name of the type of the object to instantiate.
+ *
+ * This function will initialize a new object using heap allocated memory.  This
+ * function should be paired with object_delete() to free the resources
+ * associated with the object.
+ *
+ * Returns: The newly allocated and instantiated object.
+ */
+Object *object_new(const char *typename);
+
+/**
+ * object_new_with_type:
+ * @type: The type of the object to instantiate.
+ *
+ * This function will initialize a new object using heap allocated memory.  This
+ * function should be paired with object_delete() to free the resources
+ * associated with the object.
+ *
+ * Returns: The newly allocated and instantiated object.
+ */
+Object *object_new_with_type(Type type);
+
+/**
+ * object_delete:
+ * @obj: The object to free.
+ *
+ * Finalize an object and then free the memory associated with it.  This should
+ * be paired with object_new() to free the resources associated with an object.
+ */
+void object_delete(Object *obj);
+
+/**
+ * object_initialize_with_type:
+ * @obj: A pointer to the memory to be used for the object.
+ * @type: The type of the object to instantiate.
+ *
+ * This function will initialize an object.  The memory for the object should
+ * have already been allocated.
+ */
+void object_initialize_with_type(void *data, Type type);
+
+/**
+ * object_initialize:
+ * @obj: A pointer to the memory to be used for the object.
+ * @typename: The name of the type of the object to instantiate.
+ *
+ * This function will initialize an object.  The memory for the object should
+ * have already been allocated.
+ */
+void object_initialize(void *obj, const char *typename);
+
+/**
+ * object_finalize:
+ * @obj: The object to finalize.
+ *
+ * This function destroys and object without freeing the memory associated with
+ * it.
+ */
+void object_finalize(void *obj);
+
+/**
+ * object_dynamic_cast:
+ * @obj: The object to cast.
+ * @typename: The @typename to cast to.
+ *
+ * This function will determine if @obj is-a @typename.  @obj can refer to an
+ * object or an interface associated with an object.
+ *
+ * Returns: This function returns @obj on success or #NULL on failure.
+ */
+Object *object_dynamic_cast(Object *obj, const char *typename);
+
+/**
+ * @object_dynamic_cast_assert:
+ *
+ * See object_dynamic_cast() for a description of the parameters of this
+ * function.  The only difference in behavior is that this function asserts
+ * instead of returning #NULL on failure.
+ */
+Object *object_dynamic_cast_assert(Object *obj, const char *typename);
+
+/**
+ * object_get_class:
+ * @obj: A derivative of #Object
+ *
+ * Returns: The #ObjectClass of the type associated with @obj.
+ */
+ObjectClass *object_get_class(Object *obj);
+
+/**
+ * object_get_typename:
+ * @obj: A derivative of #Object.
+ *
+ * Returns: The QOM typename of @obj.
+ */
+const char *object_get_typename(Object *obj);
+
+/**
+ * type_register_static:
+ * @info: The #TypeInfo of the new type.
+ *
+ * @info and all of the strings it points to should exist for the life time
+ * that the type is registered.
+ *
+ * Returns: 0 on failure, the new #Type on success.
+ */
+Type type_register_static(const TypeInfo *info);
+
+/**
+ * type_register:
+ * @info: The #TypeInfo of the new type
+ *
+ * Unlike type_register_static(), this call does not require @info or it's
+ * string members to continue to exist after the call returns.
+ *
+ * Returns: 0 on failure, the new #Type on success.
+ */
+Type type_register(const TypeInfo *info);
+
+/**
+ * object_class_dynamic_cast_assert:
+ * @klass: The #ObjectClass to attempt to cast.
+ * @typename: The QOM typename of the class to cast to.
+ *
+ * Returns: This function always returns @klass and asserts on failure.
+ */
+ObjectClass *object_class_dynamic_cast_assert(ObjectClass *klass,
+                                              const char *typename);
+
+ObjectClass *object_class_dynamic_cast(ObjectClass *klass,
+                                       const char *typename);
+
+/**
+ * object_class_get_name:
+ * @klass: The class to obtain the QOM typename for.
+ *
+ * Returns: The QOM typename for @klass.
+ */
+const char *object_class_get_name(ObjectClass *klass);
+
+ObjectClass *object_class_by_name(const char *typename);
+
+void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
+                          void *opaque);
+
+#endif
diff --git a/qom/Makefile b/qom/Makefile
new file mode 100644
index 0000000..a3c7892
--- /dev/null
+++ b/qom/Makefile
@@ -0,0 +1 @@
+qom-y = object.o
diff --git a/qom/object.c b/qom/object.c
new file mode 100644
index 0000000..ef37e08
--- /dev/null
+++ b/qom/object.c
@@ -0,0 +1,485 @@
+/*
+ * QEMU Object Model
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/object.h"
+#include "qemu-common.h"
+
+#define MAX_INTERFACES 32
+
+typedef struct InterfaceImpl InterfaceImpl;
+typedef struct TypeImpl TypeImpl;
+
+struct InterfaceImpl
+{
+    const char *parent;
+    void (*interface_initfn)(ObjectClass *class, void *data);
+    TypeImpl *type;
+};
+
+struct TypeImpl
+{
+    const char *name;
+
+    size_t class_size;
+
+    size_t instance_size;
+
+    void (*class_init)(ObjectClass *klass, void *data);
+    void (*class_finalize)(ObjectClass *klass, void *data);
+
+    void *class_data;
+
+    void (*instance_init)(Object *obj);
+    void (*instance_finalize)(Object *obj);
+
+    bool abstract;
+
+    const char *parent;
+    TypeImpl *parent_type;
+
+    ObjectClass *class;
+
+    int num_interfaces;
+    InterfaceImpl interfaces[MAX_INTERFACES];
+};
+
+typedef struct Interface
+{
+    Object parent;
+    Object *obj;
+} Interface;
+
+#define INTERFACE(obj) OBJECT_CHECK(Interface, obj, TYPE_INTERFACE)
+
+static GHashTable *type_table_get(void)
+{
+    static GHashTable *type_table;
+
+    if (type_table == NULL) {
+        type_table = g_hash_table_new(g_str_hash, g_str_equal);
+    }
+
+    return type_table;
+}
+
+static void type_table_add(TypeImpl *ti)
+{
+    g_hash_table_insert(type_table_get(), (void *)ti->name, ti);
+}
+
+static TypeImpl *type_table_lookup(const char *name)
+{
+    return g_hash_table_lookup(type_table_get(), name);
+}
+
+TypeImpl *type_register(const TypeInfo *info)
+{
+    TypeImpl *ti = g_malloc0(sizeof(*ti));
+
+    g_assert(info->name != NULL);
+
+    ti->name = g_strdup(info->name);
+    ti->parent = g_strdup(info->parent);
+
+    ti->class_size = info->class_size;
+    ti->instance_size = info->instance_size;
+
+    ti->class_init = info->class_init;
+    ti->class_finalize = info->class_finalize;
+    ti->class_data = info->class_data;
+
+    ti->instance_init = info->instance_init;
+    ti->instance_finalize = info->instance_finalize;
+
+    ti->abstract = info->abstract;
+
+    if (info->interfaces) {
+        int i;
+
+        for (i = 0; info->interfaces[i].type; i++) {
+            ti->interfaces[i].parent = info->interfaces[i].type;
+            ti->interfaces[i].interface_initfn = info->interfaces[i].interface_initfn;
+            ti->num_interfaces++;
+        }
+    }
+
+    type_table_add(ti);
+
+    return ti;
+}
+
+TypeImpl *type_register_static(const TypeInfo *info)
+{
+    return type_register(info);
+}
+
+static TypeImpl *type_get_by_name(const char *name)
+{
+    if (name == NULL) {
+        return NULL;
+    }
+
+    return type_table_lookup(name);
+}
+
+static TypeImpl *type_get_parent(TypeImpl *type)
+{
+    if (!type->parent_type && type->parent) {
+        type->parent_type = type_get_by_name(type->parent);
+        g_assert(type->parent_type != NULL);
+    }
+
+    return type->parent_type;
+}
+
+static bool type_has_parent(TypeImpl *type)
+{
+    return (type->parent != NULL);
+}
+
+static size_t type_class_get_size(TypeImpl *ti)
+{
+    if (ti->class_size) {
+        return ti->class_size;
+    }
+
+    if (type_has_parent(ti)) {
+        return type_class_get_size(type_get_parent(ti));
+    }
+
+    return sizeof(ObjectClass);
+}
+
+static void type_class_interface_init(TypeImpl *ti, InterfaceImpl *iface)
+{
+    TypeInfo info = {
+        .instance_size = sizeof(Interface),
+        .parent = iface->parent,
+        .class_size = sizeof(InterfaceClass),
+        .class_init = iface->interface_initfn,
+        .abstract = true,
+    };
+    char *name = g_strdup_printf("<%s::%s>", ti->name, iface->parent);
+
+    info.name = name;
+    iface->type = type_register(&info);
+    g_free(name);
+}
+
+static void type_class_init(TypeImpl *ti)
+{
+    size_t class_size = sizeof(ObjectClass);
+    int i;
+
+    if (ti->class) {
+        return;
+    }
+
+    ti->class_size = type_class_get_size(ti);
+
+    ti->class = g_malloc0(ti->class_size);
+    ti->class->type = ti;
+
+    if (type_has_parent(ti)) {
+        TypeImpl *parent = type_get_parent(ti);
+
+        type_class_init(parent);
+
+        class_size = parent->class_size;
+        g_assert(parent->class_size <= ti->class_size);
+
+        memcpy((void *)ti->class + sizeof(ObjectClass),
+               (void *)parent->class + sizeof(ObjectClass),
+               parent->class_size - sizeof(ObjectClass));
+    }
+
+    memset((void *)ti->class + class_size, 0, ti->class_size - class_size);
+
+    for (i = 0; i < ti->num_interfaces; i++) {
+        type_class_interface_init(ti, &ti->interfaces[i]);
+    }
+
+    if (ti->class_init) {
+        ti->class_init(ti->class, ti->class_data);
+    }
+}
+
+static void object_interface_init(Object *obj, InterfaceImpl *iface)
+{
+    TypeImpl *ti = iface->type;
+    Interface *iface_obj;
+
+    iface_obj = INTERFACE(object_new(ti->name));
+    iface_obj->obj = obj;
+
+    obj->interfaces = g_slist_prepend(obj->interfaces, iface_obj);
+}
+
+static void object_init_with_type(Object *obj, TypeImpl *ti)
+{
+    int i;
+
+    if (type_has_parent(ti)) {
+        object_init_with_type(obj, type_get_parent(ti));
+    }
+
+    for (i = 0; i < ti->num_interfaces; i++) {
+        object_interface_init(obj, &ti->interfaces[i]);
+    }
+
+    if (ti->instance_init) {
+        ti->instance_init(obj);
+    }
+}
+
+void object_initialize_with_type(void *data, TypeImpl *type)
+{
+    Object *obj = data;
+
+    g_assert(type != NULL);
+    g_assert(type->instance_size >= sizeof(ObjectClass));
+
+    type_class_init(type);
+    g_assert(type->abstract == false);
+
+    memset(obj, 0, type->instance_size);
+    obj->class = type->class;
+    object_init_with_type(obj, type);
+}
+
+void object_initialize(void *data, const char *typename)
+{
+    TypeImpl *type = type_get_by_name(typename);
+
+    object_initialize_with_type(data, type);
+}
+
+static void object_deinit(Object *obj, TypeImpl *type)
+{
+    if (type->instance_finalize) {
+        type->instance_finalize(obj);
+    }
+
+    while (obj->interfaces) {
+        Interface *iface_obj = obj->interfaces->data;
+        obj->interfaces = g_slist_delete_link(obj->interfaces, obj->interfaces);
+        object_delete(OBJECT(iface_obj));
+    }
+
+    if (type_has_parent(type)) {
+        object_deinit(obj, type_get_parent(type));
+    }
+}
+
+void object_finalize(void *data)
+{
+    Object *obj = data;
+    TypeImpl *ti = obj->class->type;
+
+    object_deinit(obj, ti);
+}
+
+Object *object_new_with_type(Type type)
+{
+    Object *obj;
+
+    g_assert(type != NULL);
+
+    obj = g_malloc(type->instance_size);
+    object_initialize_with_type(obj, type);
+
+    return obj;
+}
+
+Object *object_new(const char *typename)
+{
+    TypeImpl *ti = type_get_by_name(typename);
+
+    return object_new_with_type(ti);
+}
+
+void object_delete(Object *obj)
+{
+    object_finalize(obj);
+    g_free(obj);
+}
+
+static bool object_is_type(Object *obj, const char *typename)
+{
+    TypeImpl *target_type = type_get_by_name(typename);
+    TypeImpl *type = obj->class->type;
+    GSList *i;
+
+    /* Check if typename is a direct ancestor of type */
+    while (type) {
+        if (type == target_type) {
+            return true;
+        }
+
+        type = type_get_parent(type);
+    }
+
+    /* Check if obj has an interface of typename */
+    for (i = obj->interfaces; i; i = i->next) {
+        Interface *iface = i->data;
+
+        if (object_is_type(OBJECT(iface), typename)) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+Object *object_dynamic_cast(Object *obj, const char *typename)
+{
+    GSList *i;
+
+    /* Check if typename is a direct ancestor */
+    if (object_is_type(obj, typename)) {
+        return obj;
+    }
+
+    /* Check if obj has an interface of typename */
+    for (i = obj->interfaces; i; i = i->next) {
+        Interface *iface = i->data;
+
+        if (object_is_type(OBJECT(iface), typename)) {
+            return OBJECT(iface);
+        }
+    }
+
+    /* Check if obj is an interface and its containing object is a direct
+     * ancestor of typename */
+    if (object_is_type(obj, TYPE_INTERFACE)) {
+        Interface *iface = INTERFACE(obj);
+
+        if (object_is_type(iface->obj, typename)) {
+            return iface->obj;
+        }
+    }
+
+    return NULL;
+}
+
+
+static void register_interface(void)
+{
+    static TypeInfo interface_info = {
+        .name = TYPE_INTERFACE,
+        .instance_size = sizeof(Interface),
+        .abstract = true,
+    };
+
+    type_register_static(&interface_info);
+}
+
+device_init(register_interface);
+
+Object *object_dynamic_cast_assert(Object *obj, const char *typename)
+{
+    Object *inst;
+
+    inst = object_dynamic_cast(obj, typename);
+
+    if (!inst) {
+        fprintf(stderr, "Object %p is not an instance of type %s\n",
+                obj, typename);
+        abort();
+    }
+
+    return inst;
+}
+
+ObjectClass *object_class_dynamic_cast(ObjectClass *class,
+                                       const char *typename)
+{
+    TypeImpl *target_type = type_get_by_name(typename);
+    TypeImpl *type = class->type;
+
+    while (type) {
+        if (type == target_type) {
+            return class;
+        }
+
+        type = type_get_parent(type);
+    }
+
+    return NULL;
+}
+
+ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
+                                              const char *typename)
+{
+    ObjectClass *ret = object_class_dynamic_cast(class, typename);
+
+    if (!ret) {
+        fprintf(stderr, "Object %p is not an instance of type %s\n",
+                class, typename);
+        abort();
+    }
+
+    return ret;
+}
+
+const char *object_get_typename(Object *obj)
+{
+    return obj->class->type->name;
+}
+
+ObjectClass *object_get_class(Object *obj)
+{
+    return obj->class;
+}
+
+const char *object_class_get_name(ObjectClass *klass)
+{
+    return klass->type->name;
+}
+
+ObjectClass *object_class_by_name(const char *typename)
+{
+    TypeImpl *type = type_get_by_name(typename);
+
+    if (!type) {
+        return NULL;
+    }
+
+    type_class_init(type);
+
+    return type->class;
+}
+
+typedef struct OCFData
+{
+    void (*fn)(ObjectClass *klass, void *opaque);
+    void *opaque;
+} OCFData;
+
+static void object_class_foreach_tramp(gpointer key, gpointer value,
+                                       gpointer opaque)
+{
+    OCFData *data = opaque;
+    TypeImpl *type = value;
+
+    type_class_init(type);
+
+    data->fn(value, type->class);
+}
+
+void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
+                          void *opaque)
+{
+    OCFData data = { fn, opaque };
+
+    g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
+}
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 05/28] qdev: integrate with QEMU Object Model (v2)
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (3 preceding siblings ...)
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 04/28] qom: add the base Object class (v2) Anthony Liguori
@ 2012-01-24 19:32 ` Anthony Liguori
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 06/28] qdev: move qdev->info to class Anthony Liguori
                   ` (25 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori

This is a very shallow integration.  We register a TYPE_DEVICE but only use
QOM as basically a memory allocator.  This will make all devices show up as
QOM objects but they will all carry the TYPE_DEVICE.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
v1 -> v2
 - update for new location of object.h
---
 hw/qdev.c |   27 +++++++++++++++++++++++++--
 hw/qdev.h |   10 ++++++++++
 2 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 5a75668..3bc9166 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -47,9 +47,17 @@ static BusState *qbus_find(const char *path);
 /* Register a new device type.  */
 void qdev_register(DeviceInfo *info)
 {
+    TypeInfo type_info = {};
+
     assert(info->size >= sizeof(DeviceState));
     assert(!info->next);
 
+    type_info.name = info->name;
+    type_info.parent = TYPE_DEVICE;
+    type_info.instance_size = info->size;
+
+    type_register_static(&type_info);
+
     info->next = device_info_list;
     device_info_list = info;
 }
@@ -93,7 +101,7 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
     Property *prop;
 
     assert(bus->info == info->bus_info);
-    dev = g_malloc0(info->size);
+    dev = DEVICE(object_new(info->name));
     dev->info = info;
     dev->parent_bus = bus;
     qdev_prop_set_defaults(dev, dev->info->props);
@@ -519,7 +527,7 @@ void qdev_free(DeviceState *dev)
     if (dev->ref != 0) {
         qerror_report(QERR_DEVICE_IN_USE, dev->id?:"");
     }
-    g_free(dev);
+    object_delete(OBJECT(dev));
 }
 
 void qdev_machine_creation_done(void)
@@ -1572,3 +1580,18 @@ void qdev_machine_init(void)
     qdev_get_peripheral_anon();
     qdev_get_peripheral();
 }
+
+static TypeInfo device_type_info = {
+    .name = TYPE_DEVICE,
+    .parent = TYPE_OBJECT,
+    .instance_size = sizeof(DeviceState),
+    .abstract = true,
+    .class_size = sizeof(DeviceClass),
+};
+
+static void init_qdev(void)
+{
+    type_register_static(&device_type_info);
+}
+
+device_init(init_qdev);
diff --git a/hw/qdev.h b/hw/qdev.h
index 6b58dd8..1e01a04 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -6,6 +6,7 @@
 #include "qemu-char.h"
 #include "qemu-option.h"
 #include "qapi/qapi-visit-core.h"
+#include "qemu/object.h"
 
 typedef struct Property Property;
 
@@ -66,9 +67,18 @@ typedef struct DeviceProperty
     QTAILQ_ENTRY(DeviceProperty) node;
 } DeviceProperty;
 
+#define TYPE_DEVICE "device"
+#define DEVICE(obj) OBJECT_CHECK(DeviceState, (obj), TYPE_DEVICE)
+
+typedef struct DeviceClass {
+    ObjectClass parent_class;
+} DeviceClass;
+
 /* This structure should not be accessed directly.  We declare it here
    so that it can be embedded in individual device state structures.  */
 struct DeviceState {
+    Object parent_obj;
+
     const char *id;
     enum DevState state;
     QemuOpts *opts;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 06/28] qdev: move qdev->info to class
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (4 preceding siblings ...)
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 05/28] qdev: integrate with QEMU Object Model (v2) Anthony Liguori
@ 2012-01-24 19:32 ` Anthony Liguori
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 07/28] qdev: don't access name through info Anthony Liguori
                   ` (24 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Anthony Liguori, Michael S. Tsirkin, Gerd Hoffmann,
	Amit Shah, Paul Brook

Right now, DeviceInfo acts as the class for qdev.  In order to switch to a
proper ObjectClass derivative, we need to ween all of the callers off of
interacting directly with the info pointer.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/acpi_piix4.c        |    4 +-
 hw/apic_common.c       |   10 +++---
 hw/cirrus_vga.c        |    2 +-
 hw/e1000.c             |    2 +-
 hw/eepro100.c          |    4 +-
 hw/hda-audio.c         |    2 +-
 hw/i8259_common.c      |    6 ++--
 hw/ide/piix.c          |    2 +-
 hw/intel-hda.c         |    6 ++--
 hw/ioapic_common.c     |    6 ++--
 hw/lan9118.c           |    2 +-
 hw/lsi53c895a.c        |    2 +-
 hw/mipsnet.c           |    2 +-
 hw/ne2000-isa.c        |    2 +-
 hw/ne2000.c            |    2 +-
 hw/opencores_eth.c     |    2 +-
 hw/pci.c               |   16 ++++++-----
 hw/pcnet.c             |    2 +-
 hw/qdev-properties.c   |   20 +++++++-------
 hw/qdev.c              |   70 ++++++++++++++++++++++++++++--------------------
 hw/qdev.h              |   16 +++++++++-
 hw/rtl8139.c           |    2 +-
 hw/smc91c111.c         |    2 +-
 hw/spapr_vio.c         |    6 ++--
 hw/spapr_vty.c         |    2 +-
 hw/usb-bus.c           |    2 +-
 hw/usb-ccid.c          |    2 +-
 hw/usb-net.c           |    2 +-
 hw/usb-ohci.c          |    2 +-
 hw/virtio-console.c    |    2 +-
 hw/virtio-net.c        |    2 +-
 hw/virtio-serial-bus.c |    6 ++--
 32 files changed, 118 insertions(+), 92 deletions(-)

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index bdc55a1..4d0b390 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -280,7 +280,7 @@ static void piix4_update_hotplug(PIIX4PMState *s)
     s->pci0_hotplug_enable = ~0;
 
     QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
-        PCIDeviceInfo *info = container_of(qdev->info, PCIDeviceInfo, qdev);
+        PCIDeviceInfo *info = container_of(qdev_get_info(qdev), PCIDeviceInfo, qdev);
         PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, qdev);
         int slot = PCI_SLOT(pdev->devfn);
 
@@ -491,7 +491,7 @@ static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
 
     QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
         dev = DO_UPCAST(PCIDevice, qdev, qdev);
-        info = container_of(qdev->info, PCIDeviceInfo, qdev);
+        info = container_of(qdev_get_info(qdev), PCIDeviceInfo, qdev);
         if (PCI_SLOT(dev->devfn) == slot && !info->no_hotplug) {
             qdev_free(qdev);
         }
diff --git a/hw/apic_common.c b/hw/apic_common.c
index e05369c..ac06147 100644
--- a/hw/apic_common.c
+++ b/hw/apic_common.c
@@ -31,7 +31,7 @@ void cpu_set_apic_base(DeviceState *d, uint64_t val)
     trace_cpu_set_apic_base(val);
 
     if (s) {
-        info = DO_UPCAST(APICCommonInfo, busdev.qdev, s->busdev.qdev.info);
+        info = DO_UPCAST(APICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
         info->set_base(s, val);
     }
 }
@@ -51,7 +51,7 @@ void cpu_set_apic_tpr(DeviceState *d, uint8_t val)
     APICCommonInfo *info;
 
     if (s) {
-        info = DO_UPCAST(APICCommonInfo, busdev.qdev, s->busdev.qdev.info);
+        info = DO_UPCAST(APICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
         info->set_tpr(s, val);
     }
 }
@@ -89,7 +89,7 @@ void apic_deliver_nmi(DeviceState *d)
     APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
     APICCommonInfo *info;
 
-    info = DO_UPCAST(APICCommonInfo, busdev.qdev, s->busdev.qdev.info);
+    info = DO_UPCAST(APICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
     info->external_nmi(s);
 }
 
@@ -232,7 +232,7 @@ static int apic_init_common(SysBusDevice *dev)
     }
     s->idx = apic_no++;
 
-    info = DO_UPCAST(APICCommonInfo, busdev.qdev, s->busdev.qdev.info);
+    info = DO_UPCAST(APICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
     info->init(s);
 
     sysbus_init_mmio(&s->busdev, &s->io_memory);
@@ -243,7 +243,7 @@ static int apic_dispatch_post_load(void *opaque, int version_id)
 {
     APICCommonState *s = opaque;
     APICCommonInfo *info =
-        DO_UPCAST(APICCommonInfo, busdev.qdev, s->busdev.qdev.info);
+        DO_UPCAST(APICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
 
     if (info->post_load) {
         info->post_load(s);
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 8506bb5..5594bde 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2928,7 +2928,7 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
 {
      PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
      CirrusVGAState *s = &d->cirrus_vga;
-     PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, dev->qdev.info);
+     PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, qdev_get_info(&dev->qdev));
      int16_t device_id = info->device_id;
 
      /* setup VGA */
diff --git a/hw/e1000.c b/hw/e1000.c
index 86c5416..f7f72ac 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1177,7 +1177,7 @@ static int pci_e1000_init(PCIDevice *pci_dev)
     d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum;
 
     d->nic = qemu_new_nic(&net_e1000_info, &d->conf,
-                          d->dev.qdev.info->name, d->dev.qdev.id, d);
+                          qdev_get_info(&d->dev.qdev)->name, d->dev.qdev.id, d);
 
     qemu_format_nic_info_str(&d->nic->nc, macaddr);
 
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 6a162f6..81a32b8 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1848,7 +1848,7 @@ static int e100_nic_init(PCIDevice *pci_dev)
 {
     EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
     E100PCIDeviceInfo *e100_device = DO_UPCAST(E100PCIDeviceInfo, pci.qdev,
-                                               pci_dev->qdev.info);
+                                               qdev_get_info(&pci_dev->qdev));
 
     TRACE(OTHER, logout("\n"));
 
@@ -1878,7 +1878,7 @@ static int e100_nic_init(PCIDevice *pci_dev)
     nic_reset(s);
 
     s->nic = qemu_new_nic(&net_eepro100_info, &s->conf,
-                          pci_dev->qdev.info->name, pci_dev->qdev.id, s);
+                          qdev_get_info(&pci_dev->qdev)->name, pci_dev->qdev.id, s);
 
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
     TRACE(OTHER, logout("%s\n", s->nic->nc.info_str));
diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index 9b089e6..0bc0a25 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -777,7 +777,7 @@ static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
     uint32_t i, type;
 
     a->desc = desc;
-    a->name = a->hda.qdev.info->name;
+    a->name = qdev_get_info(&a->hda.qdev)->name;
     dprint(a, 1, "%s: cad %d\n", __FUNCTION__, a->hda.cad);
 
     AUD_register_card("hda", &a->card);
diff --git a/hw/i8259_common.c b/hw/i8259_common.c
index e515876..7536897 100644
--- a/hw/i8259_common.c
+++ b/hw/i8259_common.c
@@ -49,7 +49,7 @@ static void pic_dispatch_pre_save(void *opaque)
 {
     PICCommonState *s = opaque;
     PICCommonInfo *info =
-        DO_UPCAST(PICCommonInfo, isadev.qdev, s->dev.qdev.info);
+        DO_UPCAST(PICCommonInfo, isadev.qdev, qdev_get_info(&s->dev.qdev));
 
     if (info->pre_save) {
         info->pre_save(s);
@@ -60,7 +60,7 @@ static int pic_dispatch_post_load(void *opaque, int version_id)
 {
     PICCommonState *s = opaque;
     PICCommonInfo *info =
-        DO_UPCAST(PICCommonInfo, isadev.qdev, s->dev.qdev.info);
+        DO_UPCAST(PICCommonInfo, isadev.qdev, qdev_get_info(&s->dev.qdev));
 
     if (info->post_load) {
         info->post_load(s);
@@ -72,7 +72,7 @@ static int pic_init_common(ISADevice *dev)
 {
     PICCommonState *s = DO_UPCAST(PICCommonState, dev, dev);
     PICCommonInfo *info =
-        DO_UPCAST(PICCommonInfo, isadev.qdev, dev->qdev.info);
+        DO_UPCAST(PICCommonInfo, isadev.qdev, qdev_get_info(&dev->qdev));
 
     info->init(s);
 
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 3473345..c0e3450 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -195,7 +195,6 @@ PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
     PCIDevice *dev;
 
     dev = pci_create_simple(bus, devfn, "piix3-ide-xen");
-    dev->qdev.info->unplug = pci_piix3_xen_ide_unplug;
     pci_ide_create_devs(dev, hd_table);
     return dev;
 }
@@ -253,6 +252,7 @@ static PCIDeviceInfo piix_ide_info[] = {
         .qdev.name    = "piix3-ide-xen",
         .qdev.size    = sizeof(PCIIDEState),
         .qdev.no_user = 1,
+        .qdev.unplug  = pci_piix3_xen_ide_unplug,
         .init         = pci_piix_ide_initfn,
         .vendor_id    = PCI_VENDOR_ID_INTEL,
         .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 10769e0..12dcc84 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -1116,8 +1116,8 @@ static void intel_hda_reset(DeviceState *dev)
     /* reset codecs */
     QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
         cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
-        if (qdev->info->reset) {
-            qdev->info->reset(qdev);
+        if (qdev_get_info(qdev)->reset) {
+            qdev_get_info(qdev)->reset(qdev);
         }
         d->state_sts |= (1 << cdev->cad);
     }
@@ -1129,7 +1129,7 @@ static int intel_hda_init(PCIDevice *pci)
     IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci);
     uint8_t *conf = d->pci.config;
 
-    d->name = d->pci.qdev.info->name;
+    d->name = qdev_get_info(&d->pci.qdev)->name;
 
     pci_config_set_interrupt_pin(conf, 1);
 
diff --git a/hw/ioapic_common.c b/hw/ioapic_common.c
index 3aa9a1c..4a7624c 100644
--- a/hw/ioapic_common.c
+++ b/hw/ioapic_common.c
@@ -40,7 +40,7 @@ static void ioapic_dispatch_pre_save(void *opaque)
 {
     IOAPICCommonState *s = opaque;
     IOAPICCommonInfo *info =
-        DO_UPCAST(IOAPICCommonInfo, busdev.qdev, s->busdev.qdev.info);
+        DO_UPCAST(IOAPICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
 
     if (info->pre_save) {
         info->pre_save(s);
@@ -51,7 +51,7 @@ static int ioapic_dispatch_post_load(void *opaque, int version_id)
 {
     IOAPICCommonState *s = opaque;
     IOAPICCommonInfo *info =
-        DO_UPCAST(IOAPICCommonInfo, busdev.qdev, s->busdev.qdev.info);
+        DO_UPCAST(IOAPICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
 
     if (info->post_load) {
         info->post_load(s);
@@ -69,7 +69,7 @@ static int ioapic_init_common(SysBusDevice *dev)
         return -1;
     }
 
-    info = DO_UPCAST(IOAPICCommonInfo, busdev.qdev, s->busdev.qdev.info);
+    info = DO_UPCAST(IOAPICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
     info->init(s, ioapic_no);
 
     sysbus_init_mmio(&s->busdev, &s->io_memory);
diff --git a/hw/lan9118.c b/hw/lan9118.c
index 9b199d0..d1b244e 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -1221,7 +1221,7 @@ static int lan9118_init1(SysBusDevice *dev)
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
     s->nic = qemu_new_nic(&net_lan9118_info, &s->conf,
-                          dev->qdev.info->name, dev->qdev.id, s);
+                          qdev_get_info(&dev->qdev)->name, dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
     s->eeprom[0] = 0xa5;
     for (i = 0; i < 6; i++) {
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 0d3a101..9f475e0 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -1681,7 +1681,7 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
                 DeviceState *dev;
 
                 QTAILQ_FOREACH(dev, &s->bus.qbus.children, sibling) {
-                    dev->info->reset(dev);
+                    qdev_get_info(dev)->reset(dev);
                 }
                 s->sstat0 |= LSI_SSTAT0_RST;
                 lsi_script_scsi_interrupt(s, LSI_SIST0_RST, 0);
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index b1234b8..1486833 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -240,7 +240,7 @@ static int mipsnet_sysbus_init(SysBusDevice *dev)
     sysbus_init_irq(dev, &s->irq);
 
     s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf,
-                          dev->qdev.info->name, dev->qdev.id, s);
+                          qdev_get_info(&dev->qdev)->name, dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
 
     return 0;
diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c
index 11ffee7..60dc333 100644
--- a/hw/ne2000-isa.c
+++ b/hw/ne2000-isa.c
@@ -76,7 +76,7 @@ static int isa_ne2000_initfn(ISADevice *dev)
     ne2000_reset(s);
 
     s->nic = qemu_new_nic(&net_ne2000_isa_info, &s->c,
-                          dev->qdev.info->name, dev->qdev.id, s);
+                          qdev_get_info(&dev->qdev)->name, dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->c.macaddr.a);
 
     return 0;
diff --git a/hw/ne2000.c b/hw/ne2000.c
index 62e082f..d016b8e 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -760,7 +760,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
     ne2000_reset(s);
 
     s->nic = qemu_new_nic(&net_ne2000_info, &s->c,
-                          pci_dev->qdev.info->name, pci_dev->qdev.id, s);
+                          qdev_get_info(&pci_dev->qdev)->name, pci_dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->c.macaddr.a);
 
     if (!pci_dev->qdev.hotplugged) {
diff --git a/hw/opencores_eth.c b/hw/opencores_eth.c
index f7cc1b4..d4d3529 100644
--- a/hw/opencores_eth.c
+++ b/hw/opencores_eth.c
@@ -717,7 +717,7 @@ static int sysbus_open_eth_init(SysBusDevice *dev)
     sysbus_init_irq(dev, &s->irq);
 
     s->nic = qemu_new_nic(&net_open_eth_info, &s->conf,
-                          s->dev.qdev.info->name, s->dev.qdev.id, s);
+                          qdev_get_info(&s->dev.qdev)->name, s->dev.qdev.id, s);
     return 0;
 }
 
diff --git a/hw/pci.c b/hw/pci.c
index ab3b53d..5345079 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -841,7 +841,7 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
 static int pci_unregister_device(DeviceState *dev)
 {
     PCIDevice *pci_dev = DO_UPCAST(PCIDevice, qdev, dev);
-    PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, dev->info);
+    PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, qdev_get_info(dev));
     int ret = 0;
 
     if (info->exit)
@@ -1531,7 +1531,7 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
 static int pci_unplug_device(DeviceState *qdev)
 {
     PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);
-    PCIDeviceInfo *info = container_of(qdev->info, PCIDeviceInfo, qdev);
+    PCIDeviceInfo *info = container_of(qdev_get_info(qdev), PCIDeviceInfo, qdev);
 
     if (info->no_hotplug) {
         qerror_report(QERR_DEVICE_NO_HOTPLUG, info->qdev.name);
@@ -1544,7 +1544,9 @@ static int pci_unplug_device(DeviceState *qdev)
 void pci_qdev_register(PCIDeviceInfo *info)
 {
     info->qdev.init = pci_qdev_init;
-    info->qdev.unplug = pci_unplug_device;
+    if (!info->qdev.unplug) {
+        info->qdev.unplug = pci_unplug_device;
+    }
     info->qdev.exit = pci_unregister_device;
     info->qdev.bus_info = &pci_bus_info;
     qdev_register(&info->qdev);
@@ -1737,10 +1739,10 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
         size = 1 << qemu_fls(size);
     }
 
-    if (pdev->qdev.info->vmsd)
-        snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->vmsd->name);
+    if (qdev_get_info(&pdev->qdev)->vmsd)
+        snprintf(name, sizeof(name), "%s.rom", qdev_get_info(&pdev->qdev)->vmsd->name);
     else
-        snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->name);
+        snprintf(name, sizeof(name), "%s.rom", qdev_get_info(&pdev->qdev)->name);
     pdev->has_rom = true;
     memory_region_init_ram(&pdev->rom, name, size);
     vmstate_register_ram(&pdev->rom, &pdev->qdev);
@@ -1981,7 +1983,7 @@ static int pci_qdev_find_recursive(PCIBus *bus,
     }
 
     /* roughly check if given qdev is pci device */
-    if (qdev->info->init == &pci_qdev_init &&
+    if (qdev_get_info(qdev)->init == &pci_qdev_init &&
         qdev->parent_bus->info == &pci_bus_info) {
         *pdev = DO_UPCAST(PCIDevice, qdev, qdev);
         return 0;
diff --git a/hw/pcnet.c b/hw/pcnet.c
index 306dc6e..1b5d678 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -1719,7 +1719,7 @@ int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
     s->poll_timer = qemu_new_timer_ns(vm_clock, pcnet_poll_timer, s);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
-    s->nic = qemu_new_nic(info, &s->conf, dev->info->name, dev->id, s);
+    s->nic = qemu_new_nic(info, &s->conf, qdev_get_info(dev)->name, dev->id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
 
     add_boot_device_path(s->conf.bootindex, dev, "/ethernet-phy@0");
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 02f0dae..4610c3d 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -966,7 +966,7 @@ static Property *qdev_prop_find(DeviceState *dev, const char *name)
     Property *prop;
 
     /* device properties */
-    prop = qdev_prop_walk(dev->info->props, name);
+    prop = qdev_prop_walk(qdev_get_info(dev)->props, name);
     if (prop)
         return prop;
 
@@ -989,16 +989,16 @@ void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
     switch (ret) {
     case -EEXIST:
         error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
-                  dev->info->name, prop->name, value);
+                  qdev_get_info(dev)->name, prop->name, value);
         break;
     default:
     case -EINVAL:
         error_set(errp, QERR_PROPERTY_VALUE_BAD,
-                  dev->info->name, prop->name, value);
+                  qdev_get_info(dev)->name, prop->name, value);
         break;
     case -ENOENT:
         error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
-                  dev->info->name, prop->name, value);
+                  qdev_get_info(dev)->name, prop->name, value);
         break;
     case 0:
         break;
@@ -1018,7 +1018,7 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
      * removed along with it.
      */
     if (!prop || !prop->info->parse) {
-        qerror_report(QERR_PROPERTY_NOT_FOUND, dev->info->name, name);
+        qerror_report(QERR_PROPERTY_NOT_FOUND, qdev_get_info(dev)->name, name);
         return -1;
     }
     ret = prop->info->parse(dev, prop, value);
@@ -1039,12 +1039,12 @@ void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyT
     prop = qdev_prop_find(dev, name);
     if (!prop) {
         fprintf(stderr, "%s: property \"%s.%s\" not found\n",
-                __FUNCTION__, dev->info->name, name);
+                __FUNCTION__, qdev_get_info(dev)->name, name);
         abort();
     }
     if (prop->info->type != type) {
         fprintf(stderr, "%s: property \"%s.%s\" type mismatch\n",
-                __FUNCTION__, dev->info->name, name);
+                __FUNCTION__, qdev_get_info(dev)->name, name);
         abort();
     }
     qdev_prop_cpy(dev, prop, src);
@@ -1093,7 +1093,7 @@ int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *va
     if (res < 0) {
         error_report("Can't attach drive %s to %s.%s: %s",
                      bdrv_get_device_name(value),
-                     dev->id ? dev->id : dev->info->name,
+                     dev->id ? dev->id : qdev_get_info(dev)->name,
                      name, strerror(-res));
         return -1;
     }
@@ -1165,8 +1165,8 @@ void qdev_prop_set_globals(DeviceState *dev)
     GlobalProperty *prop;
 
     QTAILQ_FOREACH(prop, &global_props, next) {
-        if (strcmp(dev->info->name, prop->driver) != 0 &&
-            strcmp(dev->info->bus_info->name, prop->driver) != 0) {
+        if (strcmp(qdev_get_info(dev)->name, prop->driver) != 0 &&
+            strcmp(qdev_get_info(dev)->bus_info->name, prop->driver) != 0) {
             continue;
         }
         if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
diff --git a/hw/qdev.c b/hw/qdev.c
index 3bc9166..49d26a2 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -45,6 +45,17 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name,
 static BusState *qbus_find(const char *path);
 
 /* Register a new device type.  */
+static void qdev_subclass_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    dc->info = data;
+}
+
+DeviceInfo *qdev_get_info(DeviceState *dev)
+{
+    return DEVICE_GET_CLASS(dev)->info;
+}
+
 void qdev_register(DeviceInfo *info)
 {
     TypeInfo type_info = {};
@@ -55,6 +66,8 @@ void qdev_register(DeviceInfo *info)
     type_info.name = info->name;
     type_info.parent = TYPE_DEVICE;
     type_info.instance_size = info->size;
+    type_info.class_init = qdev_subclass_init;
+    type_info.class_data = info;
 
     type_register_static(&type_info);
 
@@ -102,9 +115,8 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
 
     assert(bus->info == info->bus_info);
     dev = DEVICE(object_new(info->name));
-    dev->info = info;
     dev->parent_bus = bus;
-    qdev_prop_set_defaults(dev, dev->info->props);
+    qdev_prop_set_defaults(dev, qdev_get_info(dev)->props);
     qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
     qdev_prop_set_globals(dev);
     QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
@@ -117,12 +129,12 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
     QTAILQ_INIT(&dev->properties);
     dev->state = DEV_STATE_CREATED;
 
-    for (prop = dev->info->props; prop && prop->name; prop++) {
+    for (prop = qdev_get_info(dev)->props; prop && prop->name; prop++) {
         qdev_property_add_legacy(dev, prop, NULL);
         qdev_property_add_static(dev, prop, NULL);
     }
 
-    for (prop = dev->info->bus_info->props; prop && prop->name; prop++) {
+    for (prop = qdev_get_info(dev)->bus_info->props; prop && prop->name; prop++) {
         qdev_property_add_legacy(dev, prop, NULL);
         qdev_property_add_static(dev, prop, NULL);
     }
@@ -355,19 +367,19 @@ int qdev_init(DeviceState *dev)
     int rc;
 
     assert(dev->state == DEV_STATE_CREATED);
-    rc = dev->info->init(dev, dev->info);
+    rc = qdev_get_info(dev)->init(dev, qdev_get_info(dev));
     if (rc < 0) {
         qdev_free(dev);
         return rc;
     }
-    if (dev->info->vmsd) {
-        vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,
+    if (qdev_get_info(dev)->vmsd) {
+        vmstate_register_with_alias_id(dev, -1, qdev_get_info(dev)->vmsd, dev,
                                        dev->instance_id_alias,
                                        dev->alias_required_for_version);
     }
     dev->state = DEV_STATE_INITIALIZED;
-    if (dev->hotplugged && dev->info->reset) {
-        dev->info->reset(dev);
+    if (dev->hotplugged && qdev_get_info(dev)->reset) {
+        qdev_get_info(dev)->reset(dev);
     }
     return 0;
 }
@@ -386,17 +398,17 @@ int qdev_unplug(DeviceState *dev)
         qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
         return -1;
     }
-    assert(dev->info->unplug != NULL);
+    assert(qdev_get_info(dev)->unplug != NULL);
 
     qdev_hot_removed = true;
 
-    return dev->info->unplug(dev);
+    return qdev_get_info(dev)->unplug(dev);
 }
 
 static int qdev_reset_one(DeviceState *dev, void *opaque)
 {
-    if (dev->info->reset) {
-        dev->info->reset(dev);
+    if (qdev_get_info(dev)->reset) {
+        qdev_get_info(dev)->reset(dev);
     }
 
     return 0;
@@ -447,7 +459,7 @@ int qdev_simple_unplug_cb(DeviceState *dev)
    way is somewhat unclean, and best avoided.  */
 void qdev_init_nofail(DeviceState *dev)
 {
-    DeviceInfo *info = dev->info;
+    DeviceInfo *info = qdev_get_info(dev);
 
     if (qdev_init(dev) < 0) {
         error_report("Initialization of device %s failed", info->name);
@@ -508,15 +520,15 @@ void qdev_free(DeviceState *dev)
             bus = QLIST_FIRST(&dev->child_bus);
             qbus_free(bus);
         }
-        if (dev->info->vmsd)
-            vmstate_unregister(dev, dev->info->vmsd, dev);
-        if (dev->info->exit)
-            dev->info->exit(dev);
+        if (qdev_get_info(dev)->vmsd)
+            vmstate_unregister(dev, qdev_get_info(dev)->vmsd, dev);
+        if (qdev_get_info(dev)->exit)
+            qdev_get_info(dev)->exit(dev);
         if (dev->opts)
             qemu_opts_del(dev->opts);
     }
     QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
-    for (prop = dev->info->props; prop && prop->name; prop++) {
+    for (prop = qdev_get_info(dev)->props; prop && prop->name; prop++) {
         if (prop->info->free) {
             prop->info->free(dev, prop);
         }
@@ -708,7 +720,7 @@ static void qbus_list_bus(DeviceState *dev)
     const char *sep = " ";
 
     error_printf("child busses at \"%s\":",
-                 dev->id ? dev->id : dev->info->name);
+                 dev->id ? dev->id : qdev_get_info(dev)->name);
     QLIST_FOREACH(child, &dev->child_bus, sibling) {
         error_printf("%s\"%s\"", sep, child->name);
         sep = ", ";
@@ -723,7 +735,7 @@ static void qbus_list_dev(BusState *bus)
 
     error_printf("devices at \"%s\":", bus->name);
     QTAILQ_FOREACH(dev, &bus->children, sibling) {
-        error_printf("%s\"%s\"", sep, dev->info->name);
+        error_printf("%s\"%s\"", sep, qdev_get_info(dev)->name);
         if (dev->id)
             error_printf("/\"%s\"", dev->id);
         sep = ", ";
@@ -759,12 +771,12 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
         }
     }
     QTAILQ_FOREACH(dev, &bus->children, sibling) {
-        if (strcmp(dev->info->name, elem) == 0) {
+        if (strcmp(qdev_get_info(dev)->name, elem) == 0) {
             return dev;
         }
     }
     QTAILQ_FOREACH(dev, &bus->children, sibling) {
-        if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
+        if (qdev_get_info(dev)->alias && strcmp(qdev_get_info(dev)->alias, elem) == 0) {
             return dev;
         }
     }
@@ -966,7 +978,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
 {
     BusState *child;
-    qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
+    qdev_printf("dev: %s, id \"%s\"\n", qdev_get_info(dev)->name,
                 dev->id ? dev->id : "");
     indent += 2;
     if (dev->num_gpio_in) {
@@ -975,7 +987,7 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
     if (dev->num_gpio_out) {
         qdev_printf("gpio-out %d\n", dev->num_gpio_out);
     }
-    qdev_print_props(mon, dev, dev->info->props, "dev", indent);
+    qdev_print_props(mon, dev, qdev_get_info(dev)->props, "dev", indent);
     qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
     if (dev->parent_bus->info->print_dev)
         dev->parent_bus->info->print_dev(mon, dev, indent);
@@ -1056,7 +1068,7 @@ static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
             l += snprintf(p + l, size - l, "%s", d);
             g_free(d);
         } else {
-            l += snprintf(p + l, size - l, "%s", dev->info->name);
+            l += snprintf(p + l, size - l, "%s", qdev_get_info(dev)->name);
         }
     }
     l += snprintf(p + l , size - l, "/");
@@ -1078,7 +1090,7 @@ char* qdev_get_fw_dev_path(DeviceState *dev)
 
 char *qdev_get_type(DeviceState *dev, Error **errp)
 {
-    return g_strdup(dev->info->name);
+    return g_strdup(qdev_get_info(dev)->name);
 }
 
 void qdev_ref(DeviceState *dev)
@@ -1288,7 +1300,7 @@ void qdev_property_add_child(DeviceState *dev, const char *name,
 {
     gchar *type;
 
-    type = g_strdup_printf("child<%s>", child->info->name);
+    type = g_strdup_printf("child<%s>", qdev_get_info(child)->name);
 
     qdev_property_add(dev, name, type, qdev_get_child_property,
                       NULL, qdev_release_child_property,
@@ -1340,7 +1352,7 @@ static void qdev_set_link_property(DeviceState *dev, Visitor *v, void *opaque,
         if (target) {
             gchar *target_type;
 
-            target_type = g_strdup_printf("link<%s>", target->info->name);
+            target_type = g_strdup_printf("link<%s>", qdev_get_info(target)->name);
             if (strcmp(target_type, type) == 0) {
                 *child = target;
                 qdev_ref(target);
diff --git a/hw/qdev.h b/hw/qdev.h
index 1e01a04..e13111f 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -69,9 +69,12 @@ typedef struct DeviceProperty
 
 #define TYPE_DEVICE "device"
 #define DEVICE(obj) OBJECT_CHECK(DeviceState, (obj), TYPE_DEVICE)
+#define DEVICE_CLASS(klass) OBJECT_CLASS_CHECK(DeviceClass, (klass), TYPE_DEVICE)
+#define DEVICE_GET_CLASS(obj) OBJECT_GET_CLASS(DeviceClass, (obj), TYPE_DEVICE)
 
 typedef struct DeviceClass {
     ObjectClass parent_class;
+    DeviceInfo *info;
 } DeviceClass;
 
 /* This structure should not be accessed directly.  We declare it here
@@ -83,7 +86,6 @@ struct DeviceState {
     enum DevState state;
     QemuOpts *opts;
     int hotplugged;
-    DeviceInfo *info;
     BusState *parent_bus;
     int num_gpio_out;
     qemu_irq *gpio_out;
@@ -389,9 +391,19 @@ void qdev_prop_set_globals(DeviceState *dev);
 void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
                                     Property *prop, const char *value);
 
+DeviceInfo *qdev_get_info(DeviceState *dev);
+
 static inline const char *qdev_fw_name(DeviceState *dev)
 {
-    return dev->info->fw_name ? : dev->info->alias ? : dev->info->name;
+    DeviceInfo *info = qdev_get_info(dev);
+
+    if (info->fw_name) {
+        return info->fw_name;
+    } else if (info->alias) {
+        return info->alias;
+    }
+
+    return info->name;
 }
 
 char *qdev_get_fw_dev_path(DeviceState *dev);
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 0ae9f57..16d948e 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3478,7 +3478,7 @@ static int pci_rtl8139_init(PCIDevice *dev)
     s->eeprom.contents[9] = s->conf.macaddr.a[4] | s->conf.macaddr.a[5] << 8;
 
     s->nic = qemu_new_nic(&net_rtl8139_info, &s->conf,
-                          dev->qdev.info->name, dev->qdev.id, s);
+                          qdev_get_info(&dev->qdev)->name, dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
 
     s->cplus_txbuffer = NULL;
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index 82b8811..b83a893 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -752,7 +752,7 @@ static int smc91c111_init1(SysBusDevice *dev)
     sysbus_init_irq(dev, &s->irq);
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_smc91c111_info, &s->conf,
-                          dev->qdev.info->name, dev->qdev.id, s);
+                          qdev_get_info(&dev->qdev)->name, dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
     /* ??? Save/restore.  */
     return 0;
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 7a86dc8..0159413 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -75,7 +75,7 @@ VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
 
 static char *vio_format_dev_name(VIOsPAPRDevice *dev)
 {
-    VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)dev->qdev.info;
+    VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qdev_get_info(&dev->qdev);
     char *name;
 
     /* Device tree style name device@reg */
@@ -90,7 +90,7 @@ static char *vio_format_dev_name(VIOsPAPRDevice *dev)
 static int vio_make_devnode(VIOsPAPRDevice *dev,
                             void *fdt)
 {
-    VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)dev->qdev.info;
+    VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qdev_get_info(&dev->qdev);
     int vdevice_off, node_off, ret;
     char *dt_name;
 
@@ -700,7 +700,7 @@ static target_ulong h_vio_signal(CPUState *env, sPAPREnvironment *spapr,
         return H_PARAMETER;
     }
 
-    info = (VIOsPAPRDeviceInfo *)dev->qdev.info;
+    info = (VIOsPAPRDeviceInfo *)qdev_get_info(&dev->qdev);
 
     if (mode & ~info->signal_mask) {
         return H_PARAMETER;
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index c5fb096..181dd0e 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -163,7 +163,7 @@ VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
     selected = NULL;
     QTAILQ_FOREACH(iter, &bus->bus.children, sibling) {
         /* Only look at VTY devices */
-        if (iter->info != &spapr_vty.qdev) {
+        if (qdev_get_info(iter) != &spapr_vty.qdev) {
             continue;
         }
 
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 016a3f2..3b80d5e 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -250,7 +250,7 @@ int usb_claim_port(USBDevice *dev)
             return -1;
         }
     } else {
-        if (bus->nfree == 1 && strcmp(dev->qdev.info->name, "usb-hub") != 0) {
+        if (bus->nfree == 1 && strcmp(qdev_get_info(&dev->qdev)->name, "usb-hub") != 0) {
             /* Create a new hub and chain it on */
             usb_create_simple(bus, "usb-hub");
         }
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index e9935ad..3b7f95d 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -1114,7 +1114,7 @@ static int ccid_card_exit(DeviceState *qdev)
 {
     int ret = 0;
     CCIDCardState *card = DO_UPCAST(CCIDCardState, qdev, qdev);
-    CCIDCardInfo *info = DO_UPCAST(CCIDCardInfo, qdev, qdev->info);
+    CCIDCardInfo *info = DO_UPCAST(CCIDCardInfo, qdev, qdev_get_info(qdev));
     USBCCIDState *s =
         DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent);
 
diff --git a/hw/usb-net.c b/hw/usb-net.c
index 2f527a8..086aa7e 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1337,7 +1337,7 @@ static int usb_net_initfn(USBDevice *dev)
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_usbnet_info, &s->conf,
-                          s->dev.qdev.info->name, s->dev.qdev.id, s);
+                          qdev_get_info(&s->dev.qdev)->name, s->dev.qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
     snprintf(s->usbstring_mac, sizeof(s->usbstring_mac),
              "%02x%02x%02x%02x%02x%02x",
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 69463d2..afa3274 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1777,7 +1777,7 @@ static int usb_ohci_init(OHCIState *ohci, DeviceState *dev,
     memory_region_init_io(&ohci->mem, &ohci_mem_ops, ohci, "ohci", 256);
     ohci->localmem_base = localmem_base;
 
-    ohci->name = dev->info->name;
+    ohci->name = qdev_get_info(dev)->name;
     usb_packet_init(&ohci->usb_packet);
 
     ohci->async_td = 0;
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 0b28a30..f25adc4 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -110,7 +110,7 @@ static int virtconsole_initfn(VirtIOSerialPort *port)
 {
     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
     VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev,
-                                           vcon->port.dev.info);
+                                           qdev_get_info(&vcon->port.dev));
 
     if (port->id == 0 && !info->is_console) {
         error_report("Port number 0 on virtio-serial devices reserved for virtconsole devices for backward compatibility.");
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 8c2f460..6c785d0 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -1030,7 +1030,7 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
     memcpy(&n->mac[0], &conf->macaddr, sizeof(n->mac));
     n->status = VIRTIO_NET_S_LINK_UP;
 
-    n->nic = qemu_new_nic(&net_virtio_info, conf, dev->info->name, dev->id, n);
+    n->nic = qemu_new_nic(&net_virtio_info, conf, qdev_get_info(dev)->name, dev->id, n);
 
     qemu_format_nic_info_str(&n->nic->nc, conf->macaddr.a);
 
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 32e46e9..982ffbf 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -138,7 +138,7 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
     assert(port);
     assert(virtio_queue_ready(vq));
 
-    info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info);
+    info = DO_UPCAST(VirtIOSerialPortInfo, qdev, qdev_get_info(&port->dev));
 
     while (!port->throttled) {
         unsigned int i;
@@ -373,7 +373,7 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
 
     trace_virtio_serial_handle_control_message_port(port->id);
 
-    info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info);
+    info = DO_UPCAST(VirtIOSerialPortInfo, qdev, qdev_get_info(&port->dev));
 
     switch(cpkt.event) {
     case VIRTIO_CONSOLE_PORT_READY:
@@ -824,7 +824,7 @@ static int virtser_port_qdev_exit(DeviceState *qdev)
 {
     VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
     VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev,
-                                           port->dev.info);
+                                           qdev_get_info(&port->dev));
     VirtIOSerial *vser = port->vser;
 
     qemu_bh_delete(port->bh);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 07/28] qdev: don't access name through info
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (5 preceding siblings ...)
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 06/28] qdev: move qdev->info to class Anthony Liguori
@ 2012-01-24 19:32 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 08/28] qdev: use a wrapper to access reset and promote reset to a class method Anthony Liguori
                   ` (23 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Jan Kiszka, Gerd Hoffmann, Michael S. Tsirkin

We already have a QOM interface for this so let's use it.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/e1000.c              |    2 +-
 hw/eepro100.c           |    2 +-
 hw/etraxfs_eth.c        |    2 +-
 hw/hda-audio.c          |    2 +-
 hw/intel-hda.c          |    2 +-
 hw/lan9118.c            |    2 +-
 hw/milkymist-minimac2.c |    2 +-
 hw/mipsnet.c            |    2 +-
 hw/musicpal.c           |    2 +-
 hw/ne2000-isa.c         |    2 +-
 hw/ne2000.c             |    2 +-
 hw/opencores_eth.c      |    2 +-
 hw/pci.c                |    6 +++---
 hw/pcnet.c              |    2 +-
 hw/qdev-properties.c    |   16 ++++++++--------
 hw/qdev.c               |   16 ++++++++--------
 hw/qdev.h               |    2 +-
 hw/rtl8139.c            |    2 +-
 hw/smc91c111.c          |    2 +-
 hw/spapr_llan.c         |    2 +-
 hw/stellaris_enet.c     |    2 +-
 hw/usb-bus.c            |    2 +-
 hw/usb-net.c            |    2 +-
 hw/usb-ohci.c           |    2 +-
 hw/virtio-net.c         |    2 +-
 hw/xilinx_axienet.c     |    2 +-
 hw/xilinx_ethlite.c     |    2 +-
 27 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/hw/e1000.c b/hw/e1000.c
index f7f72ac..6bab54e 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1177,7 +1177,7 @@ static int pci_e1000_init(PCIDevice *pci_dev)
     d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum;
 
     d->nic = qemu_new_nic(&net_e1000_info, &d->conf,
-                          qdev_get_info(&d->dev.qdev)->name, d->dev.qdev.id, d);
+                          object_get_typename(OBJECT(d)), d->dev.qdev.id, d);
 
     qemu_format_nic_info_str(&d->nic->nc, macaddr);
 
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 81a32b8..f0059c6 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1878,7 +1878,7 @@ static int e100_nic_init(PCIDevice *pci_dev)
     nic_reset(s);
 
     s->nic = qemu_new_nic(&net_eepro100_info, &s->conf,
-                          qdev_get_info(&pci_dev->qdev)->name, pci_dev->qdev.id, s);
+                          object_get_typename(OBJECT(pci_dev)), pci_dev->qdev.id, s);
 
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
     TRACE(OTHER, logout("%s\n", s->nic->nc.info_str));
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 5afa55f..1b6b71d 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -605,7 +605,7 @@ static int fs_eth_init(SysBusDevice *dev)
 
 	qemu_macaddr_default_if_unset(&s->conf.macaddr);
 	s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf,
-			      dev->qdev.info->name, dev->qdev.id, s);
+			      object_get_typename(OBJECT(s)), dev->qdev.id, s);
 	qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
 
 	tdk_init(&s->phy);
diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index 0bc0a25..8053c74 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -777,7 +777,7 @@ static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
     uint32_t i, type;
 
     a->desc = desc;
-    a->name = qdev_get_info(&a->hda.qdev)->name;
+    a->name = object_get_typename(OBJECT(a));
     dprint(a, 1, "%s: cad %d\n", __FUNCTION__, a->hda.cad);
 
     AUD_register_card("hda", &a->card);
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 12dcc84..8cb92d3 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -1129,7 +1129,7 @@ static int intel_hda_init(PCIDevice *pci)
     IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci);
     uint8_t *conf = d->pci.config;
 
-    d->name = qdev_get_info(&d->pci.qdev)->name;
+    d->name = object_get_typename(OBJECT(d));
 
     pci_config_set_interrupt_pin(conf, 1);
 
diff --git a/hw/lan9118.c b/hw/lan9118.c
index d1b244e..93e1896 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -1221,7 +1221,7 @@ static int lan9118_init1(SysBusDevice *dev)
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
     s->nic = qemu_new_nic(&net_lan9118_info, &s->conf,
-                          qdev_get_info(&dev->qdev)->name, dev->qdev.id, s);
+                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
     s->eeprom[0] = 0xa5;
     for (i = 0; i < 6; i++) {
diff --git a/hw/milkymist-minimac2.c b/hw/milkymist-minimac2.c
index 7006d29..107ba65 100644
--- a/hw/milkymist-minimac2.c
+++ b/hw/milkymist-minimac2.c
@@ -479,7 +479,7 @@ static int milkymist_minimac2_init(SysBusDevice *dev)
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf,
-                          dev->qdev.info->name, dev->qdev.id, s);
+                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
 
     return 0;
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index 1486833..0f80cfe 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -240,7 +240,7 @@ static int mipsnet_sysbus_init(SysBusDevice *dev)
     sysbus_init_irq(dev, &s->irq);
 
     s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf,
-                          qdev_get_info(&dev->qdev)->name, dev->qdev.id, s);
+                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
 
     return 0;
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 977ffb6..bca5ee9 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -387,7 +387,7 @@ static int mv88w8618_eth_init(SysBusDevice *dev)
 
     sysbus_init_irq(dev, &s->irq);
     s->nic = qemu_new_nic(&net_mv88w8618_info, &s->conf,
-                          dev->qdev.info->name, dev->qdev.id, s);
+                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
     memory_region_init_io(&s->iomem, &mv88w8618_eth_ops, s, "mv88w8618-eth",
                           MP_ETH_SIZE);
     sysbus_init_mmio(dev, &s->iomem);
diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c
index 60dc333..5bc5f2a 100644
--- a/hw/ne2000-isa.c
+++ b/hw/ne2000-isa.c
@@ -76,7 +76,7 @@ static int isa_ne2000_initfn(ISADevice *dev)
     ne2000_reset(s);
 
     s->nic = qemu_new_nic(&net_ne2000_isa_info, &s->c,
-                          qdev_get_info(&dev->qdev)->name, dev->qdev.id, s);
+                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->c.macaddr.a);
 
     return 0;
diff --git a/hw/ne2000.c b/hw/ne2000.c
index d016b8e..b44eab1 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -760,7 +760,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
     ne2000_reset(s);
 
     s->nic = qemu_new_nic(&net_ne2000_info, &s->c,
-                          qdev_get_info(&pci_dev->qdev)->name, pci_dev->qdev.id, s);
+                          object_get_typename(OBJECT(pci_dev)), pci_dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->c.macaddr.a);
 
     if (!pci_dev->qdev.hotplugged) {
diff --git a/hw/opencores_eth.c b/hw/opencores_eth.c
index d4d3529..5161b0c 100644
--- a/hw/opencores_eth.c
+++ b/hw/opencores_eth.c
@@ -717,7 +717,7 @@ static int sysbus_open_eth_init(SysBusDevice *dev)
     sysbus_init_irq(dev, &s->irq);
 
     s->nic = qemu_new_nic(&net_open_eth_info, &s->conf,
-                          qdev_get_info(&s->dev.qdev)->name, s->dev.qdev.id, s);
+                          object_get_typename(OBJECT(s)), s->dev.qdev.id, s);
     return 0;
 }
 
diff --git a/hw/pci.c b/hw/pci.c
index 5345079..516da08 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1493,7 +1493,7 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
     if (pci_dev == NULL)
         return -1;
     if (qdev->hotplugged && info->no_hotplug) {
-        qerror_report(QERR_DEVICE_NO_HOTPLUG, info->qdev.name);
+        qerror_report(QERR_DEVICE_NO_HOTPLUG, object_get_typename(OBJECT(pci_dev)));
         do_pci_unregister_device(pci_dev);
         return -1;
     }
@@ -1534,7 +1534,7 @@ static int pci_unplug_device(DeviceState *qdev)
     PCIDeviceInfo *info = container_of(qdev_get_info(qdev), PCIDeviceInfo, qdev);
 
     if (info->no_hotplug) {
-        qerror_report(QERR_DEVICE_NO_HOTPLUG, info->qdev.name);
+        qerror_report(QERR_DEVICE_NO_HOTPLUG, object_get_typename(OBJECT(dev)));
         return -1;
     }
     return dev->bus->hotplug(dev->bus->hotplug_qdev, dev,
@@ -1742,7 +1742,7 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
     if (qdev_get_info(&pdev->qdev)->vmsd)
         snprintf(name, sizeof(name), "%s.rom", qdev_get_info(&pdev->qdev)->vmsd->name);
     else
-        snprintf(name, sizeof(name), "%s.rom", qdev_get_info(&pdev->qdev)->name);
+        snprintf(name, sizeof(name), "%s.rom", object_get_typename(OBJECT(pdev)));
     pdev->has_rom = true;
     memory_region_init_ram(&pdev->rom, name, size);
     vmstate_register_ram(&pdev->rom, &pdev->qdev);
diff --git a/hw/pcnet.c b/hw/pcnet.c
index 1b5d678..41d1ae48 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -1719,7 +1719,7 @@ int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
     s->poll_timer = qemu_new_timer_ns(vm_clock, pcnet_poll_timer, s);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
-    s->nic = qemu_new_nic(info, &s->conf, qdev_get_info(dev)->name, dev->id, s);
+    s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
 
     add_boot_device_path(s->conf.bootindex, dev, "/ethernet-phy@0");
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 4610c3d..89a3e97 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -989,16 +989,16 @@ void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
     switch (ret) {
     case -EEXIST:
         error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
-                  qdev_get_info(dev)->name, prop->name, value);
+                  object_get_typename(OBJECT(dev)), prop->name, value);
         break;
     default:
     case -EINVAL:
         error_set(errp, QERR_PROPERTY_VALUE_BAD,
-                  qdev_get_info(dev)->name, prop->name, value);
+                  object_get_typename(OBJECT(dev)), prop->name, value);
         break;
     case -ENOENT:
         error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
-                  qdev_get_info(dev)->name, prop->name, value);
+                  object_get_typename(OBJECT(dev)), prop->name, value);
         break;
     case 0:
         break;
@@ -1018,7 +1018,7 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
      * removed along with it.
      */
     if (!prop || !prop->info->parse) {
-        qerror_report(QERR_PROPERTY_NOT_FOUND, qdev_get_info(dev)->name, name);
+        qerror_report(QERR_PROPERTY_NOT_FOUND, object_get_typename(OBJECT(dev)), name);
         return -1;
     }
     ret = prop->info->parse(dev, prop, value);
@@ -1039,12 +1039,12 @@ void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyT
     prop = qdev_prop_find(dev, name);
     if (!prop) {
         fprintf(stderr, "%s: property \"%s.%s\" not found\n",
-                __FUNCTION__, qdev_get_info(dev)->name, name);
+                __FUNCTION__, object_get_typename(OBJECT(dev)), name);
         abort();
     }
     if (prop->info->type != type) {
         fprintf(stderr, "%s: property \"%s.%s\" type mismatch\n",
-                __FUNCTION__, qdev_get_info(dev)->name, name);
+                __FUNCTION__, object_get_typename(OBJECT(dev)), name);
         abort();
     }
     qdev_prop_cpy(dev, prop, src);
@@ -1093,7 +1093,7 @@ int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *va
     if (res < 0) {
         error_report("Can't attach drive %s to %s.%s: %s",
                      bdrv_get_device_name(value),
-                     dev->id ? dev->id : qdev_get_info(dev)->name,
+                     dev->id ? dev->id : object_get_typename(OBJECT(dev)),
                      name, strerror(-res));
         return -1;
     }
@@ -1165,7 +1165,7 @@ void qdev_prop_set_globals(DeviceState *dev)
     GlobalProperty *prop;
 
     QTAILQ_FOREACH(prop, &global_props, next) {
-        if (strcmp(qdev_get_info(dev)->name, prop->driver) != 0 &&
+        if (strcmp(object_get_typename(OBJECT(dev)), prop->driver) != 0 &&
             strcmp(qdev_get_info(dev)->bus_info->name, prop->driver) != 0) {
             continue;
         }
diff --git a/hw/qdev.c b/hw/qdev.c
index 49d26a2..5da94a8 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -720,7 +720,7 @@ static void qbus_list_bus(DeviceState *dev)
     const char *sep = " ";
 
     error_printf("child busses at \"%s\":",
-                 dev->id ? dev->id : qdev_get_info(dev)->name);
+                 dev->id ? dev->id : object_get_typename(OBJECT(dev)));
     QLIST_FOREACH(child, &dev->child_bus, sibling) {
         error_printf("%s\"%s\"", sep, child->name);
         sep = ", ";
@@ -735,7 +735,7 @@ static void qbus_list_dev(BusState *bus)
 
     error_printf("devices at \"%s\":", bus->name);
     QTAILQ_FOREACH(dev, &bus->children, sibling) {
-        error_printf("%s\"%s\"", sep, qdev_get_info(dev)->name);
+        error_printf("%s\"%s\"", sep, object_get_typename(OBJECT(dev)));
         if (dev->id)
             error_printf("/\"%s\"", dev->id);
         sep = ", ";
@@ -771,7 +771,7 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
         }
     }
     QTAILQ_FOREACH(dev, &bus->children, sibling) {
-        if (strcmp(qdev_get_info(dev)->name, elem) == 0) {
+        if (strcmp(object_get_typename(OBJECT(dev)), elem) == 0) {
             return dev;
         }
     }
@@ -978,7 +978,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
 {
     BusState *child;
-    qdev_printf("dev: %s, id \"%s\"\n", qdev_get_info(dev)->name,
+    qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
                 dev->id ? dev->id : "");
     indent += 2;
     if (dev->num_gpio_in) {
@@ -1068,7 +1068,7 @@ static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
             l += snprintf(p + l, size - l, "%s", d);
             g_free(d);
         } else {
-            l += snprintf(p + l, size - l, "%s", qdev_get_info(dev)->name);
+            l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
         }
     }
     l += snprintf(p + l , size - l, "/");
@@ -1090,7 +1090,7 @@ char* qdev_get_fw_dev_path(DeviceState *dev)
 
 char *qdev_get_type(DeviceState *dev, Error **errp)
 {
-    return g_strdup(qdev_get_info(dev)->name);
+    return g_strdup(object_get_typename(OBJECT(dev)));
 }
 
 void qdev_ref(DeviceState *dev)
@@ -1300,7 +1300,7 @@ void qdev_property_add_child(DeviceState *dev, const char *name,
 {
     gchar *type;
 
-    type = g_strdup_printf("child<%s>", qdev_get_info(child)->name);
+    type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
 
     qdev_property_add(dev, name, type, qdev_get_child_property,
                       NULL, qdev_release_child_property,
@@ -1352,7 +1352,7 @@ static void qdev_set_link_property(DeviceState *dev, Visitor *v, void *opaque,
         if (target) {
             gchar *target_type;
 
-            target_type = g_strdup_printf("link<%s>", qdev_get_info(target)->name);
+            target_type = g_strdup_printf("link<%s>", object_get_typename(OBJECT(target)));
             if (strcmp(target_type, type) == 0) {
                 *child = target;
                 qdev_ref(target);
diff --git a/hw/qdev.h b/hw/qdev.h
index e13111f..a6af632 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -403,7 +403,7 @@ static inline const char *qdev_fw_name(DeviceState *dev)
         return info->alias;
     }
 
-    return info->name;
+    return object_get_typename(OBJECT(dev));
 }
 
 char *qdev_get_fw_dev_path(DeviceState *dev);
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 16d948e..2b55c7f 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3478,7 +3478,7 @@ static int pci_rtl8139_init(PCIDevice *dev)
     s->eeprom.contents[9] = s->conf.macaddr.a[4] | s->conf.macaddr.a[5] << 8;
 
     s->nic = qemu_new_nic(&net_rtl8139_info, &s->conf,
-                          qdev_get_info(&dev->qdev)->name, dev->qdev.id, s);
+                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
 
     s->cplus_txbuffer = NULL;
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index b83a893..4a68f6b 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -752,7 +752,7 @@ static int smc91c111_init1(SysBusDevice *dev)
     sysbus_init_irq(dev, &s->irq);
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_smc91c111_info, &s->conf,
-                          qdev_get_info(&dev->qdev)->name, dev->qdev.id, s);
+                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
     /* ??? Save/restore.  */
     return 0;
diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c
index 45674c4..91003cc 100644
--- a/hw/spapr_llan.c
+++ b/hw/spapr_llan.c
@@ -189,7 +189,7 @@ static int spapr_vlan_init(VIOsPAPRDevice *sdev)
     qemu_macaddr_default_if_unset(&dev->nicconf.macaddr);
 
     dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf,
-                            sdev->qdev.info->name, sdev->qdev.id, dev);
+                            object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
     qemu_format_nic_info_str(&dev->nic->nc, dev->nicconf.macaddr.a);
 
     return 0;
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index 866c9a2..ecd750c 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -411,7 +411,7 @@ static int stellaris_enet_init(SysBusDevice *dev)
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
     s->nic = qemu_new_nic(&net_stellaris_enet_info, &s->conf,
-                          dev->qdev.info->name, dev->qdev.id, s);
+                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
 
     stellaris_enet_reset(s);
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 3b80d5e..9b67f18 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -250,7 +250,7 @@ int usb_claim_port(USBDevice *dev)
             return -1;
         }
     } else {
-        if (bus->nfree == 1 && strcmp(qdev_get_info(&dev->qdev)->name, "usb-hub") != 0) {
+        if (bus->nfree == 1 && strcmp(object_get_typename(OBJECT(dev)), "usb-hub") != 0) {
             /* Create a new hub and chain it on */
             usb_create_simple(bus, "usb-hub");
         }
diff --git a/hw/usb-net.c b/hw/usb-net.c
index 086aa7e..fd4106b 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1337,7 +1337,7 @@ static int usb_net_initfn(USBDevice *dev)
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_usbnet_info, &s->conf,
-                          qdev_get_info(&s->dev.qdev)->name, s->dev.qdev.id, s);
+                          object_get_typename(OBJECT(s)), s->dev.qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
     snprintf(s->usbstring_mac, sizeof(s->usbstring_mac),
              "%02x%02x%02x%02x%02x%02x",
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index afa3274..2df6a6e 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1777,7 +1777,7 @@ static int usb_ohci_init(OHCIState *ohci, DeviceState *dev,
     memory_region_init_io(&ohci->mem, &ohci_mem_ops, ohci, "ohci", 256);
     ohci->localmem_base = localmem_base;
 
-    ohci->name = qdev_get_info(dev)->name;
+    ohci->name = object_get_typename(OBJECT(dev));
     usb_packet_init(&ohci->usb_packet);
 
     ohci->async_td = 0;
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 6c785d0..bc5e3a8 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -1030,7 +1030,7 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
     memcpy(&n->mac[0], &conf->macaddr, sizeof(n->mac));
     n->status = VIRTIO_NET_S_LINK_UP;
 
-    n->nic = qemu_new_nic(&net_virtio_info, conf, qdev_get_info(dev)->name, dev->id, n);
+    n->nic = qemu_new_nic(&net_virtio_info, conf, object_get_typename(OBJECT(dev)), dev->id, n);
 
     qemu_format_nic_info_str(&n->nic->nc, conf->macaddr.a);
 
diff --git a/hw/xilinx_axienet.c b/hw/xilinx_axienet.c
index a2eb3e6..e713248 100644
--- a/hw/xilinx_axienet.c
+++ b/hw/xilinx_axienet.c
@@ -856,7 +856,7 @@ static int xilinx_enet_init(SysBusDevice *dev)
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_xilinx_enet_info, &s->conf,
-                          dev->qdev.info->name, dev->qdev.id, s);
+                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
 
     tdk_init(&s->TEMAC.phy);
diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c
index 6777254..de595f4 100644
--- a/hw/xilinx_ethlite.c
+++ b/hw/xilinx_ethlite.c
@@ -221,7 +221,7 @@ static int xilinx_ethlite_init(SysBusDevice *dev)
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf,
-                          dev->qdev.info->name, dev->qdev.id, s);
+                          object_get_typename(OBJECT(dev)), dev->qdev.id, s);
     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
     return 0;
 }
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 08/28] qdev: use a wrapper to access reset and promote reset to a class method
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (6 preceding siblings ...)
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 07/28] qdev: don't access name through info Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 09/28] qdev: add a interface to register subclasses Anthony Liguori
                   ` (22 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Anthony Liguori, Paul Brook

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/intel-hda.c  |    4 +---
 hw/lsi53c895a.c |    2 +-
 hw/qdev.c       |   22 +++++++++++++++++-----
 hw/qdev.h       |    8 ++++++++
 4 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 8cb92d3..6e1c5de 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -1116,9 +1116,7 @@ static void intel_hda_reset(DeviceState *dev)
     /* reset codecs */
     QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
         cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
-        if (qdev_get_info(qdev)->reset) {
-            qdev_get_info(qdev)->reset(qdev);
-        }
+        device_reset(DEVICE(cdev));
         d->state_sts |= (1 << cdev->cad);
     }
     intel_hda_update_irq(d);
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 9f475e0..3a87171 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -1681,7 +1681,7 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
                 DeviceState *dev;
 
                 QTAILQ_FOREACH(dev, &s->bus.qbus.children, sibling) {
-                    qdev_get_info(dev)->reset(dev);
+                    device_reset(dev);
                 }
                 s->sstat0 |= LSI_SSTAT0_RST;
                 lsi_script_scsi_interrupt(s, LSI_SIST0_RST, 0);
diff --git a/hw/qdev.c b/hw/qdev.c
index 5da94a8..a80ca7c 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -48,7 +48,12 @@ static BusState *qbus_find(const char *path);
 static void qdev_subclass_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+
     dc->info = data;
+    dc->reset = dc->info->reset;
+
+    /* Poison to try to detect future uses */
+    dc->info->reset = NULL;
 }
 
 DeviceInfo *qdev_get_info(DeviceState *dev)
@@ -378,8 +383,8 @@ int qdev_init(DeviceState *dev)
                                        dev->alias_required_for_version);
     }
     dev->state = DEV_STATE_INITIALIZED;
-    if (dev->hotplugged && qdev_get_info(dev)->reset) {
-        qdev_get_info(dev)->reset(dev);
+    if (dev->hotplugged) {
+        device_reset(dev);
     }
     return 0;
 }
@@ -407,9 +412,7 @@ int qdev_unplug(DeviceState *dev)
 
 static int qdev_reset_one(DeviceState *dev, void *opaque)
 {
-    if (qdev_get_info(dev)->reset) {
-        qdev_get_info(dev)->reset(dev);
-    }
+    device_reset(dev);
 
     return 0;
 }
@@ -1593,6 +1596,15 @@ void qdev_machine_init(void)
     qdev_get_peripheral();
 }
 
+void device_reset(DeviceState *dev)
+{
+    DeviceClass *klass = DEVICE_GET_CLASS(dev);
+
+    if (klass->reset) {
+        klass->reset(dev);
+    }
+}
+
 static TypeInfo device_type_info = {
     .name = TYPE_DEVICE,
     .parent = TYPE_OBJECT,
diff --git a/hw/qdev.h b/hw/qdev.h
index a6af632..f3c9219 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -75,6 +75,7 @@ typedef struct DeviceProperty
 typedef struct DeviceClass {
     ObjectClass parent_class;
     DeviceInfo *info;
+    void (*reset)(DeviceState *dev);
 } DeviceClass;
 
 /* This structure should not be accessed directly.  We declare it here
@@ -647,4 +648,11 @@ char *qdev_get_type(DeviceState *dev, Error **errp);
  */
 void qdev_machine_init(void);
 
+/**
+ * @device_reset
+ *
+ * Reset a single device (by calling the reset method).
+ */
+void device_reset(DeviceState *dev);
+
 #endif
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 09/28] qdev: add a interface to register subclasses
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (7 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 08/28] qdev: use a wrapper to access reset and promote reset to a class method Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 10/28] qdev: add class_init to DeviceInfo Anthony Liguori
                   ` (21 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori

In order to introduce inheritance while still using the qdev registration
interfaces, we need to be able to use a parent other than TYPE_DEVICE.  Add a
new interface that allows this.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/qdev.c |    9 +++++++--
 hw/qdev.h |    1 +
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index a80ca7c..c4b5284 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -61,7 +61,7 @@ DeviceInfo *qdev_get_info(DeviceState *dev)
     return DEVICE_GET_CLASS(dev)->info;
 }
 
-void qdev_register(DeviceInfo *info)
+void qdev_register_subclass(DeviceInfo *info, const char *parent)
 {
     TypeInfo type_info = {};
 
@@ -69,7 +69,7 @@ void qdev_register(DeviceInfo *info)
     assert(!info->next);
 
     type_info.name = info->name;
-    type_info.parent = TYPE_DEVICE;
+    type_info.parent = parent;
     type_info.instance_size = info->size;
     type_info.class_init = qdev_subclass_init;
     type_info.class_data = info;
@@ -80,6 +80,11 @@ void qdev_register(DeviceInfo *info)
     device_info_list = info;
 }
 
+void qdev_register(DeviceInfo *info)
+{
+    qdev_register_subclass(info, TYPE_DEVICE);
+}
+
 static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
 {
     DeviceInfo *info;
diff --git a/hw/qdev.h b/hw/qdev.h
index f3c9219..48f80a5 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -241,6 +241,7 @@ struct DeviceInfo {
 extern DeviceInfo *device_info_list;
 
 void qdev_register(DeviceInfo *info);
+void qdev_register_subclass(DeviceInfo *info, const char *parent);
 
 /* Register device properties.  */
 /* GPIO inputs also double as IRQ sinks.  */
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 10/28] qdev: add class_init to DeviceInfo
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (8 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 09/28] qdev: add a interface to register subclasses Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 11/28] qdev: prepare source tree for code conversion Anthony Liguori
                   ` (20 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori

Since we are still dynamically creating TypeInfo, we need to chain the
class_init function in order to be able to make use of it within subclasses of
TYPE_DEVICE.

This will disappear once we register TypeInfos directly.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/qdev.c |    4 ++++
 hw/qdev.h |    5 +++++
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index c4b5284..81996bb 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -54,6 +54,10 @@ static void qdev_subclass_init(ObjectClass *klass, void *data)
 
     /* Poison to try to detect future uses */
     dc->info->reset = NULL;
+
+    if (dc->info->class_init) {
+        dc->info->class_init(klass, data);
+    }
 }
 
 DeviceInfo *qdev_get_info(DeviceState *dev)
diff --git a/hw/qdev.h b/hw/qdev.h
index 48f80a5..c9572a5 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -231,6 +231,11 @@ struct DeviceInfo {
     /* device state */
     const VMStateDescription *vmsd;
 
+    /**
+     * See #TypeInfo::class_init()
+     */
+    void (*class_init)(ObjectClass *klass, void *data);
+
     /* Private to qdev / bus.  */
     qdev_initfn init;
     qdev_event unplug;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 11/28] qdev: prepare source tree for code conversion
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (9 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 10/28] qdev: add class_init to DeviceInfo Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-26 17:35   ` [Qemu-devel] [PATCH 1/3] es1370: Drop dead code Andreas Färber
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 12/28] isa: pic: convert to QEMU Object Model Anthony Liguori
                   ` (19 subsequent siblings)
  30 siblings, 1 reply; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Anthony Liguori, Gerd Hoffmann, Michael S. Tsirkin

These are various small stylistic changes which help make things more
consistent such that the automated conversion script can be simpler.

It's not necessary to agree or disagree with these style changes because all
of this code is going to be rewritten by the patch monkey script anyway.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/9pfs/virtio-9p-device.c |    3 +-
 hw/es1370.c                |    5 -
 hw/ide/cmd646.c            |   33 ++++-----
 hw/ide/ich.c               |   30 +++----
 hw/ide/piix.c              |   70 +++++++++---------
 hw/marvell_88w8618_audio.c |    8 +--
 hw/piix4.c                 |   29 +++----
 hw/piix_pci.c              |   86 +++++++++++-----------
 hw/qxl.c                   |    8 +-
 hw/spapr_llan.c            |    4 +-
 hw/spapr_vscsi.c           |    4 +-
 hw/spapr_vty.c             |    6 +-
 hw/usb-ehci.c              |   49 ++++++------
 hw/usb-uhci.c              |  107 +++++++++++++++------------
 hw/virtio-pci.c            |  174 ++++++++++++++++++++++----------------------
 15 files changed, 304 insertions(+), 312 deletions(-)

diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 642d5e2..1325f2f 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -172,8 +172,7 @@ static PCIDeviceInfo virtio_9p_info = {
     .revision  = VIRTIO_PCI_ABI_VERSION,
     .class_id  = 0x2,
     .qdev.props = (Property[]) {
-        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
-                        VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
         DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
         DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
         DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
diff --git a/hw/es1370.c b/hw/es1370.c
index 6a3ba55..3527eb6 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -1041,13 +1041,8 @@ static PCIDeviceInfo es1370_info = {
     .vendor_id    = PCI_VENDOR_ID_ENSONIQ,
     .device_id    = PCI_DEVICE_ID_ENSONIQ_ES1370,
     .class_id     = PCI_CLASS_MULTIMEDIA_AUDIO,
-#if 1
     .subsystem_vendor_id = 0x4942,
     .subsystem_id = 0x4c4c,
-#else
-    .subsystem_vendor_id = 0x1274,
-    .subsystem_id = 0x1371,
-#endif
 };
 
 static void es1370_register (void)
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 5fe98b1..99e7e6f 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -325,27 +325,24 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
     pci_ide_create_devs(dev, hd_table);
 }
 
-static PCIDeviceInfo cmd646_ide_info[] = {
-    {
-        .qdev.name    = "cmd646-ide",
-        .qdev.size    = sizeof(PCIIDEState),
-        .init         = pci_cmd646_ide_initfn,
-        .exit         = pci_cmd646_ide_exitfn,
-        .vendor_id    = PCI_VENDOR_ID_CMD,
-        .device_id    = PCI_DEVICE_ID_CMD_646,
-        .revision     = 0x07, // IDE controller revision
-        .class_id     = PCI_CLASS_STORAGE_IDE,
-        .qdev.props   = (Property[]) {
-            DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
-            DEFINE_PROP_END_OF_LIST(),
-        },
-    },{
-        /* end of list */
-    }
+static PCIDeviceInfo cmd646_ide_info = {
+    .qdev.name    = "cmd646-ide",
+    .qdev.size    = sizeof(PCIIDEState),
+    .init         = pci_cmd646_ide_initfn,
+    .exit         = pci_cmd646_ide_exitfn,
+    .vendor_id    = PCI_VENDOR_ID_CMD,
+    .device_id    = PCI_DEVICE_ID_CMD_646,
+    /* IDE controller revision */
+    .revision     = 0x07,
+    .class_id     = PCI_CLASS_STORAGE_IDE,
+    .qdev.props   = (Property[]) {
+        DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
+        DEFINE_PROP_END_OF_LIST(),
+    },
 };
 
 static void cmd646_ide_register(void)
 {
-    pci_qdev_register_many(cmd646_ide_info);
+    pci_qdev_register(&cmd646_ide_info);
 }
 device_init(cmd646_ide_register);
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 3f7510f..e6421e2 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -146,26 +146,22 @@ static void pci_ich9_write_config(PCIDevice *pci, uint32_t addr,
     msi_write_config(pci, addr, val, len);
 }
 
-static PCIDeviceInfo ich_ahci_info[] = {
-    {
-        .qdev.name    = "ich9-ahci",
-        .qdev.alias   = "ahci",
-        .qdev.size    = sizeof(AHCIPCIState),
-        .qdev.vmsd    = &vmstate_ahci,
-        .init         = pci_ich9_ahci_init,
-        .exit         = pci_ich9_uninit,
-        .config_write = pci_ich9_write_config,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82801IR,
-        .revision     = 0x02,
-        .class_id     = PCI_CLASS_STORAGE_SATA,
-    },{
-        /* end of list */
-    }
+static PCIDeviceInfo ich_ahci_info = {
+    .qdev.name    = "ich9-ahci",
+    .qdev.alias   = "ahci",
+    .qdev.size    = sizeof(AHCIPCIState),
+    .qdev.vmsd    = &vmstate_ahci,
+    .init         = pci_ich9_ahci_init,
+    .exit         = pci_ich9_uninit,
+    .config_write = pci_ich9_write_config,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82801IR,
+    .revision     = 0x02,
+    .class_id     = PCI_CLASS_STORAGE_SATA,
 };
 
 static void ich_ahci_register(void)
 {
-    pci_qdev_register_many(ich_ahci_info);
+    pci_qdev_register(&ich_ahci_info);
 }
 device_init(ich_ahci_register);
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index c0e3450..91b77a2 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -237,43 +237,45 @@ PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
     return dev;
 }
 
-static PCIDeviceInfo piix_ide_info[] = {
-    {
-        .qdev.name    = "piix3-ide",
-        .qdev.size    = sizeof(PCIIDEState),
-        .qdev.no_user = 1,
-        .no_hotplug   = 1,
-        .init         = pci_piix_ide_initfn,
-        .exit         = pci_piix_ide_exitfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
-        .class_id     = PCI_CLASS_STORAGE_IDE,
-    },{
-        .qdev.name    = "piix3-ide-xen",
-        .qdev.size    = sizeof(PCIIDEState),
-        .qdev.no_user = 1,
-        .qdev.unplug  = pci_piix3_xen_ide_unplug,
-        .init         = pci_piix_ide_initfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
-        .class_id     = PCI_CLASS_STORAGE_IDE,
-    },{
-        .qdev.name    = "piix4-ide",
-        .qdev.size    = sizeof(PCIIDEState),
-        .qdev.no_user = 1,
-        .no_hotplug   = 1,
-        .init         = pci_piix_ide_initfn,
-        .exit         = pci_piix_ide_exitfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371AB,
-        .class_id     = PCI_CLASS_STORAGE_IDE,
-    },{
-        /* end of list */
-    }
+static PCIDeviceInfo piix3_ide_info = {
+    .qdev.name    = "piix3-ide",
+    .qdev.size    = sizeof(PCIIDEState),
+    .qdev.no_user = 1,
+    .no_hotplug   = 1,
+    .init         = pci_piix_ide_initfn,
+    .exit         = pci_piix_ide_exitfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
+    .class_id     = PCI_CLASS_STORAGE_IDE,
+};
+
+static PCIDeviceInfo piix3_ide_xen_info = {
+    .qdev.name    = "piix3-ide-xen",
+    .qdev.size    = sizeof(PCIIDEState),
+    .qdev.no_user = 1,
+    .qdev.unplug  = pci_piix3_xen_ide_unplug,
+    .init         = pci_piix_ide_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
+    .class_id     = PCI_CLASS_STORAGE_IDE,
+};
+
+static PCIDeviceInfo piix4_ide_info = {
+    .qdev.name    = "piix4-ide",
+    .qdev.size    = sizeof(PCIIDEState),
+    .qdev.no_user = 1,
+    .no_hotplug   = 1,
+    .init         = pci_piix_ide_initfn,
+    .exit         = pci_piix_ide_exitfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82371AB,
+    .class_id     = PCI_CLASS_STORAGE_IDE,
 };
 
 static void piix_ide_register(void)
 {
-    pci_qdev_register_many(piix_ide_info);
+    pci_qdev_register(&piix3_ide_info);
+    pci_qdev_register(&piix3_ide_xen_info);
+    pci_qdev_register(&piix4_ide_info);
 }
 device_init(piix_ide_register);
diff --git a/hw/marvell_88w8618_audio.c b/hw/marvell_88w8618_audio.c
index 0cd8410..409b1eb 100644
--- a/hw/marvell_88w8618_audio.c
+++ b/hw/marvell_88w8618_audio.c
@@ -50,7 +50,7 @@ typedef struct mv88w8618_audio_state {
     uint32_t play_pos;
     uint32_t last_free;
     uint32_t clock_div;
-    DeviceState *wm;
+    void *wm;
 } mv88w8618_audio_state;
 
 static void mv88w8618_audio_callback(void *opaque, int free_out, int free_in)
@@ -279,11 +279,7 @@ static SysBusDeviceInfo mv88w8618_audio_info = {
     .qdev.reset = mv88w8618_audio_reset,
     .qdev.vmsd  = &mv88w8618_audio_vmsd,
     .qdev.props = (Property[]) {
-        {
-            .name   = "wm8750",
-            .info   = &qdev_prop_ptr,
-            .offset = offsetof(mv88w8618_audio_state, wm),
-        },
+        DEFINE_PROP_PTR("wm8750", mv88w8618_audio_state, wm),
         {/* end of list */}
     }
 };
diff --git a/hw/piix4.c b/hw/piix4.c
index 51af459..130dfd1 100644
--- a/hw/piix4.c
+++ b/hw/piix4.c
@@ -102,25 +102,22 @@ int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn)
     return d->devfn;
 }
 
-static PCIDeviceInfo piix4_info[] = {
-    {
-        .qdev.name    = "PIIX4",
-        .qdev.desc    = "ISA bridge",
-        .qdev.size    = sizeof(PIIX4State),
-        .qdev.vmsd    = &vmstate_piix4,
-        .qdev.no_user = 1,
-        .no_hotplug   = 1,
-        .init         = piix4_initfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371AB_0, // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge
-        .class_id     = PCI_CLASS_BRIDGE_ISA,
-    },{
-        /* end of list */
-    }
+static PCIDeviceInfo piix4_info = {
+    .qdev.name    = "PIIX4",
+    .qdev.desc    = "ISA bridge",
+    .qdev.size    = sizeof(PIIX4State),
+    .qdev.vmsd    = &vmstate_piix4,
+    .qdev.no_user = 1,
+    .no_hotplug   = 1,
+    .init         = piix4_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    /* 82371AB/EB/MB PIIX4 PCI-to-ISA bridge */
+    .device_id    = PCI_DEVICE_ID_INTEL_82371AB_0,
+    .class_id     = PCI_CLASS_BRIDGE_ISA,
 };
 
 static void piix4_register(void)
 {
-    pci_qdev_register_many(piix4_info);
+    pci_qdev_register(&piix4_info);
 }
 device_init(piix4_register);
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 3652522..5cbeed5 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -502,47 +502,47 @@ static int piix3_initfn(PCIDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo i440fx_info[] = {
-    {
-        .qdev.name    = "i440FX",
-        .qdev.desc    = "Host bridge",
-        .qdev.size    = sizeof(PCII440FXState),
-        .qdev.vmsd    = &vmstate_i440fx,
-        .qdev.no_user = 1,
-        .no_hotplug   = 1,
-        .init         = i440fx_initfn,
-        .config_write = i440fx_write_config,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82441,
-        .revision     = 0x02,
-        .class_id     = PCI_CLASS_BRIDGE_HOST,
-    },{
-        .qdev.name    = "PIIX3",
-        .qdev.desc    = "ISA bridge",
-        .qdev.size    = sizeof(PIIX3State),
-        .qdev.vmsd    = &vmstate_piix3,
-        .qdev.no_user = 1,
-        .no_hotplug   = 1,
-        .init         = piix3_initfn,
-        .config_write = piix3_write_config,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
-        .class_id     = PCI_CLASS_BRIDGE_ISA,
-    },{
-        .qdev.name    = "PIIX3-xen",
-        .qdev.desc    = "ISA bridge",
-        .qdev.size    = sizeof(PIIX3State),
-        .qdev.vmsd    = &vmstate_piix3,
-        .qdev.no_user = 1,
-        .no_hotplug   = 1,
-        .init         = piix3_initfn,
-        .config_write = piix3_write_config_xen,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
-        .class_id     = PCI_CLASS_BRIDGE_ISA,
-    },{
-        /* end of list */
-    }
+static PCIDeviceInfo i440fx_info = {
+    .qdev.name    = "i440FX",
+    .qdev.desc    = "Host bridge",
+    .qdev.size    = sizeof(PCII440FXState),
+    .qdev.vmsd    = &vmstate_i440fx,
+    .qdev.no_user = 1,
+    .no_hotplug   = 1,
+    .init         = i440fx_initfn,
+    .config_write = i440fx_write_config,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82441,
+    .revision     = 0x02,
+    .class_id     = PCI_CLASS_BRIDGE_HOST,
+};
+
+static PCIDeviceInfo piix3_info = {
+    .qdev.name    = "PIIX3",
+    .qdev.desc    = "ISA bridge",
+    .qdev.size    = sizeof(PIIX3State),
+    .qdev.vmsd    = &vmstate_piix3,
+    .qdev.no_user = 1,
+    .no_hotplug   = 1,
+    .init         = piix3_initfn,
+    .config_write = piix3_write_config,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
+    .class_id     = PCI_CLASS_BRIDGE_ISA,
+};
+
+static PCIDeviceInfo piix3_xen_info = {
+    .qdev.name    = "PIIX3-xen",
+    .qdev.desc    = "ISA bridge",
+    .qdev.size    = sizeof(PIIX3State),
+    .qdev.vmsd    = &vmstate_piix3,
+    .qdev.no_user = 1,
+    .no_hotplug   = 1,
+    .init         = piix3_initfn,
+    .config_write = piix3_write_config_xen,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
+    .class_id     = PCI_CLASS_BRIDGE_ISA,
 };
 
 static SysBusDeviceInfo i440fx_pcihost_info = {
@@ -555,7 +555,9 @@ static SysBusDeviceInfo i440fx_pcihost_info = {
 
 static void i440fx_register(void)
 {
+    pci_qdev_register(&i440fx_info);
+    pci_qdev_register(&piix3_info);
+    pci_qdev_register(&piix3_xen_info);
     sysbus_register_withprop(&i440fx_pcihost_info);
-    pci_qdev_register_many(i440fx_info);
 }
 device_init(i440fx_register);
diff --git a/hw/qxl.c b/hw/qxl.c
index bdd36f9..2a716bf 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1827,7 +1827,7 @@ static Property qxl_properties[] = {
         DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo qxl_info_primary = {
+static PCIDeviceInfo qxl_primary_info = {
     .qdev.name    = "qxl-vga",
     .qdev.desc    = "Spice QXL GPU (primary, vga compatible)",
     .qdev.size    = sizeof(PCIQXLDevice),
@@ -1842,7 +1842,7 @@ static PCIDeviceInfo qxl_info_primary = {
     .qdev.props   = qxl_properties,
 };
 
-static PCIDeviceInfo qxl_info_secondary = {
+static PCIDeviceInfo qxl_secondary_info = {
     .qdev.name    = "qxl",
     .qdev.desc    = "Spice QXL GPU (secondary)",
     .qdev.size    = sizeof(PCIQXLDevice),
@@ -1857,8 +1857,8 @@ static PCIDeviceInfo qxl_info_secondary = {
 
 static void qxl_register(void)
 {
-    pci_qdev_register(&qxl_info_primary);
-    pci_qdev_register(&qxl_info_secondary);
+    pci_qdev_register(&qxl_primary_info);
+    pci_qdev_register(&qxl_secondary_info);
 }
 
 device_init(qxl_register);
diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c
index 91003cc..b9a5afc 100644
--- a/hw/spapr_llan.c
+++ b/hw/spapr_llan.c
@@ -474,7 +474,7 @@ static target_ulong h_multicast_ctrl(CPUState *env, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static VIOsPAPRDeviceInfo spapr_vlan = {
+static VIOsPAPRDeviceInfo spapr_vlan_info = {
     .init = spapr_vlan_init,
     .devnode = spapr_vlan_devnode,
     .dt_name = "l-lan",
@@ -492,12 +492,12 @@ static VIOsPAPRDeviceInfo spapr_vlan = {
 
 static void spapr_vlan_register(void)
 {
-    spapr_vio_bus_register_withprop(&spapr_vlan);
     spapr_register_hypercall(H_REGISTER_LOGICAL_LAN, h_register_logical_lan);
     spapr_register_hypercall(H_FREE_LOGICAL_LAN, h_free_logical_lan);
     spapr_register_hypercall(H_SEND_LOGICAL_LAN, h_send_logical_lan);
     spapr_register_hypercall(H_ADD_LOGICAL_LAN_BUFFER,
                              h_add_logical_lan_buffer);
     spapr_register_hypercall(H_MULTICAST_CTRL, h_multicast_ctrl);
+    spapr_vio_bus_register_withprop(&spapr_vlan_info);
 }
 device_init(spapr_vlan_register);
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index 00e2d2d..21d946e 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -947,7 +947,7 @@ static int spapr_vscsi_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
     return 0;
 }
 
-static VIOsPAPRDeviceInfo spapr_vscsi = {
+static VIOsPAPRDeviceInfo spapr_vscsi_info = {
     .init = spapr_vscsi_init,
     .devnode = spapr_vscsi_devnode,
     .dt_name = "v-scsi",
@@ -964,6 +964,6 @@ static VIOsPAPRDeviceInfo spapr_vscsi = {
 
 static void spapr_vscsi_register(void)
 {
-    spapr_vio_bus_register_withprop(&spapr_vscsi);
+    spapr_vio_bus_register_withprop(&spapr_vscsi_info);
 }
 device_init(spapr_vscsi_register);
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index 181dd0e..3d5c579 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -135,7 +135,7 @@ void spapr_vty_create(VIOsPAPRBus *bus, uint32_t reg, CharDriverState *chardev)
     qdev_init_nofail(dev);
 }
 
-static VIOsPAPRDeviceInfo spapr_vty = {
+static VIOsPAPRDeviceInfo spapr_vty_info = {
     .init = spapr_vty_init,
     .dt_name = "vty",
     .dt_type = "serial",
@@ -163,7 +163,7 @@ VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
     selected = NULL;
     QTAILQ_FOREACH(iter, &bus->bus.children, sibling) {
         /* Only look at VTY devices */
-        if (qdev_get_info(iter) != &spapr_vty.qdev) {
+        if (qdev_get_info(iter) != &spapr_vty_info.qdev) {
             continue;
         }
 
@@ -203,8 +203,8 @@ static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg)
 
 static void spapr_vty_register(void)
 {
-    spapr_vio_bus_register_withprop(&spapr_vty);
     spapr_register_hypercall(H_PUT_TERM_CHAR, h_put_term_char);
     spapr_register_hypercall(H_GET_TERM_CHAR, h_get_term_char);
+    spapr_vio_bus_register_withprop(&spapr_vty_info);
 }
 device_init(spapr_vty_register);
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index a305661..63fc3c7 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -2263,30 +2263,28 @@ static Property ehci_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo ehci_info[] = {
-    {
-        .qdev.name    = "usb-ehci",
-        .qdev.size    = sizeof(EHCIState),
-        .qdev.vmsd    = &vmstate_ehci,
-        .init         = usb_ehci_initfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82801D, /* ich4 */
-        .revision     = 0x10,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = ehci_properties,
-    },{
-        .qdev.name    = "ich9-usb-ehci1",
-        .qdev.size    = sizeof(EHCIState),
-        .qdev.vmsd    = &vmstate_ehci,
-        .init         = usb_ehci_initfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82801I_EHCI1,
-        .revision     = 0x03,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = ehci_properties,
-    },{
-        /* end of list */
-    }
+static PCIDeviceInfo ehci_info = {
+    .qdev.name    = "usb-ehci",
+    .qdev.size    = sizeof(EHCIState),
+    .qdev.vmsd    = &vmstate_ehci,
+    .init         = usb_ehci_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82801D, /* ich4 */
+    .revision     = 0x10,
+    .class_id     = PCI_CLASS_SERIAL_USB,
+    .qdev.props   = ehci_properties,
+};
+
+static PCIDeviceInfo ich9_ehci_info = {
+    .qdev.name    = "ich9-usb-ehci1",
+    .qdev.size    = sizeof(EHCIState),
+    .qdev.vmsd    = &vmstate_ehci,
+    .init         = usb_ehci_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82801I_EHCI1,
+    .revision     = 0x03,
+    .class_id     = PCI_CLASS_SERIAL_USB,
+    .qdev.props   = ehci_properties,
 };
 
 static int usb_ehci_initfn(PCIDevice *dev)
@@ -2362,7 +2360,8 @@ static int usb_ehci_initfn(PCIDevice *dev)
 
 static void ehci_register(void)
 {
-    pci_qdev_register_many(ehci_info);
+    pci_qdev_register(&ehci_info);
+    pci_qdev_register(&ich9_ehci_info);
 }
 device_init(ehci_register);
 
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 25d4e8c..1821063 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1192,8 +1192,7 @@ static Property uhci_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo uhci_info[] = {
-    {
+static PCIDeviceInfo piix3_uhci_info = {
         .qdev.name    = "piix3-usb-uhci",
         .qdev.size    = sizeof(UHCIState),
         .qdev.vmsd    = &vmstate_uhci,
@@ -1204,7 +1203,9 @@ static PCIDeviceInfo uhci_info[] = {
         .revision     = 0x01,
         .class_id     = PCI_CLASS_SERIAL_USB,
         .qdev.props   = uhci_properties,
-    },{
+};
+
+static PCIDeviceInfo piix4_uhci_info = {
         .qdev.name    = "piix4-usb-uhci",
         .qdev.size    = sizeof(UHCIState),
         .qdev.vmsd    = &vmstate_uhci,
@@ -1215,55 +1216,65 @@ static PCIDeviceInfo uhci_info[] = {
         .revision     = 0x01,
         .class_id     = PCI_CLASS_SERIAL_USB,
         .qdev.props   = uhci_properties,
-    },{
-        .qdev.name    = "vt82c686b-usb-uhci",
-        .qdev.size    = sizeof(UHCIState),
-        .qdev.vmsd    = &vmstate_uhci,
-        .init         = usb_uhci_vt82c686b_initfn,
-        .exit         = usb_uhci_exit,
-        .vendor_id    = PCI_VENDOR_ID_VIA,
-        .device_id    = PCI_DEVICE_ID_VIA_UHCI,
-        .revision     = 0x01,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = uhci_properties,
-    },{
-        .qdev.name    = "ich9-usb-uhci1",
-        .qdev.size    = sizeof(UHCIState),
-        .qdev.vmsd    = &vmstate_uhci,
-        .init         = usb_uhci_common_initfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI1,
-        .revision     = 0x03,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = uhci_properties,
-    },{
-        .qdev.name    = "ich9-usb-uhci2",
-        .qdev.size    = sizeof(UHCIState),
-        .qdev.vmsd    = &vmstate_uhci,
-        .init         = usb_uhci_common_initfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI2,
-        .revision     = 0x03,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = uhci_properties,
-    },{
-        .qdev.name    = "ich9-usb-uhci3",
-        .qdev.size    = sizeof(UHCIState),
-        .qdev.vmsd    = &vmstate_uhci,
-        .init         = usb_uhci_common_initfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI3,
-        .revision     = 0x03,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = uhci_properties,
-    },{
-        /* end of list */
-    }
+};
+
+static PCIDeviceInfo vt82c686b_uhci_info = {
+    .qdev.name    = "vt82c686b-usb-uhci",
+    .qdev.size    = sizeof(UHCIState),
+    .qdev.vmsd    = &vmstate_uhci,
+    .init         = usb_uhci_vt82c686b_initfn,
+    .exit         = usb_uhci_exit,
+    .vendor_id    = PCI_VENDOR_ID_VIA,
+    .device_id    = PCI_DEVICE_ID_VIA_UHCI,
+    .revision     = 0x01,
+    .class_id     = PCI_CLASS_SERIAL_USB,
+    .qdev.props   = uhci_properties,
+};
+
+static PCIDeviceInfo ich9_uhci1_info = {
+    .qdev.name    = "ich9-usb-uhci1",
+    .qdev.size    = sizeof(UHCIState),
+    .qdev.vmsd    = &vmstate_uhci,
+    .init         = usb_uhci_common_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI1,
+    .revision     = 0x03,
+    .class_id     = PCI_CLASS_SERIAL_USB,
+    .qdev.props   = uhci_properties,
+};
+
+static PCIDeviceInfo ich9_uhci2_info = {
+    .qdev.name    = "ich9-usb-uhci2",
+    .qdev.size    = sizeof(UHCIState),
+    .qdev.vmsd    = &vmstate_uhci,
+    .init         = usb_uhci_common_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI2,
+    .revision     = 0x03,
+    .class_id     = PCI_CLASS_SERIAL_USB,
+    .qdev.props   = uhci_properties,
+};
+
+static PCIDeviceInfo ich9_uhci3_info = {
+    .qdev.name    = "ich9-usb-uhci3",
+    .qdev.size    = sizeof(UHCIState),
+    .qdev.vmsd    = &vmstate_uhci,
+    .init         = usb_uhci_common_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI3,
+    .revision     = 0x03,
+    .class_id     = PCI_CLASS_SERIAL_USB,
+    .qdev.props   = uhci_properties,
 };
 
 static void uhci_register(void)
 {
-    pci_qdev_register_many(uhci_info);
+    pci_qdev_register(&piix3_uhci_info);
+    pci_qdev_register(&piix4_uhci_info);
+    pci_qdev_register(&vt82c686b_uhci_info);
+    pci_qdev_register(&ich9_uhci1_info);
+    pci_qdev_register(&ich9_uhci2_info);
+    pci_qdev_register(&ich9_uhci3_info);
 }
 device_init(uhci_register);
 
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index c93889a..72b53af 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -806,98 +806,96 @@ static int virtio_balloon_exit_pci(PCIDevice *pci_dev)
     return virtio_exit_pci(pci_dev);
 }
 
-static PCIDeviceInfo virtio_info[] = {
-    {
-        .qdev.name = "virtio-blk-pci",
-        .qdev.alias = "virtio-blk",
-        .qdev.size = sizeof(VirtIOPCIProxy),
-        .init      = virtio_blk_init_pci,
-        .exit      = virtio_blk_exit_pci,
-        .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
-        .device_id = PCI_DEVICE_ID_VIRTIO_BLOCK,
-        .revision  = VIRTIO_PCI_ABI_VERSION,
-        .class_id  = PCI_CLASS_STORAGE_SCSI,
-        .qdev.props = (Property[]) {
-            DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
-            DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
-            DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial),
-            DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
-                            VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
-            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
-            DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
-            DEFINE_PROP_END_OF_LIST(),
-        },
-        .qdev.reset = virtio_pci_reset,
-    },{
-        .qdev.name  = "virtio-net-pci",
-        .qdev.alias = "virtio-net",
-        .qdev.size  = sizeof(VirtIOPCIProxy),
-        .init       = virtio_net_init_pci,
-        .exit       = virtio_net_exit_pci,
-        .romfile    = "pxe-virtio.rom",
-        .vendor_id  = PCI_VENDOR_ID_REDHAT_QUMRANET,
-        .device_id  = PCI_DEVICE_ID_VIRTIO_NET,
-        .revision   = VIRTIO_PCI_ABI_VERSION,
-        .class_id   = PCI_CLASS_NETWORK_ETHERNET,
-        .qdev.props = (Property[]) {
-            DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
-                            VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
-            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
-            DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
-            DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
-            DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy,
-                               net.txtimer, TX_TIMER_INTERVAL),
-            DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy,
-                              net.txburst, TX_BURST),
-            DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx),
-            DEFINE_PROP_END_OF_LIST(),
-        },
-        .qdev.reset = virtio_pci_reset,
-    },{
-        .qdev.name = "virtio-serial-pci",
-        .qdev.alias = "virtio-serial",
-        .qdev.size = sizeof(VirtIOPCIProxy),
-        .init      = virtio_serial_init_pci,
-        .exit      = virtio_serial_exit_pci,
-        .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
-        .device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE,
-        .revision  = VIRTIO_PCI_ABI_VERSION,
-        .class_id  = PCI_CLASS_COMMUNICATION_OTHER,
-        .qdev.props = (Property[]) {
-            DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
-                            VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
-            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
-                               DEV_NVECTORS_UNSPECIFIED),
-            DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
-            DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-            DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy,
-                               serial.max_virtserial_ports, 31),
-            DEFINE_PROP_END_OF_LIST(),
-        },
-        .qdev.reset = virtio_pci_reset,
-    },{
-        .qdev.name = "virtio-balloon-pci",
-        .qdev.alias = "virtio-balloon",
-        .qdev.size = sizeof(VirtIOPCIProxy),
-        .init      = virtio_balloon_init_pci,
-        .exit      = virtio_balloon_exit_pci,
-        .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
-        .device_id = PCI_DEVICE_ID_VIRTIO_BALLOON,
-        .revision  = VIRTIO_PCI_ABI_VERSION,
-        .class_id  = PCI_CLASS_MEMORY_RAM,
-        .qdev.props = (Property[]) {
-            DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-            DEFINE_PROP_END_OF_LIST(),
-        },
-        .qdev.reset = virtio_pci_reset,
-    },{
-        /* end of list */
-    }
+static PCIDeviceInfo virtio_blk_info = {
+    .qdev.name = "virtio-blk-pci",
+    .qdev.alias = "virtio-blk",
+    .qdev.size = sizeof(VirtIOPCIProxy),
+    .init      = virtio_blk_init_pci,
+    .exit      = virtio_blk_exit_pci,
+    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+    .device_id = PCI_DEVICE_ID_VIRTIO_BLOCK,
+    .revision  = VIRTIO_PCI_ABI_VERSION,
+    .class_id  = PCI_CLASS_STORAGE_SCSI,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
+        DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
+        DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial),
+        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+        DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
+        DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+    .qdev.reset = virtio_pci_reset,
+};
+
+static PCIDeviceInfo virtio_net_info = {
+    .qdev.name  = "virtio-net-pci",
+    .qdev.alias = "virtio-net",
+    .qdev.size  = sizeof(VirtIOPCIProxy),
+    .init       = virtio_net_init_pci,
+    .exit       = virtio_net_exit_pci,
+    .romfile    = "pxe-virtio.rom",
+    .vendor_id  = PCI_VENDOR_ID_REDHAT_QUMRANET,
+    .device_id  = PCI_DEVICE_ID_VIRTIO_NET,
+    .revision   = VIRTIO_PCI_ABI_VERSION,
+    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
+        DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
+        DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
+        DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
+        DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy, net.txtimer, TX_TIMER_INTERVAL),
+        DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy, net.txburst, TX_BURST),
+        DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+    .qdev.reset = virtio_pci_reset,
+};
+
+static PCIDeviceInfo virtio_serial_info = {
+    .qdev.name = "virtio-serial-pci",
+    .qdev.alias = "virtio-serial",
+    .qdev.size = sizeof(VirtIOPCIProxy),
+    .init      = virtio_serial_init_pci,
+    .exit      = virtio_serial_exit_pci,
+    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+    .device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE,
+    .revision  = VIRTIO_PCI_ABI_VERSION,
+    .class_id  = PCI_CLASS_COMMUNICATION_OTHER,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+        DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, DEV_NVECTORS_UNSPECIFIED),
+        DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
+        DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+        DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, serial.max_virtserial_ports, 31),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+    .qdev.reset = virtio_pci_reset,
+};
+
+static PCIDeviceInfo virtio_balloon_info = {
+    .qdev.name = "virtio-balloon-pci",
+    .qdev.alias = "virtio-balloon",
+    .qdev.size = sizeof(VirtIOPCIProxy),
+    .init      = virtio_balloon_init_pci,
+    .exit      = virtio_balloon_exit_pci,
+    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+    .device_id = PCI_DEVICE_ID_VIRTIO_BALLOON,
+    .revision  = VIRTIO_PCI_ABI_VERSION,
+    .class_id  = PCI_CLASS_MEMORY_RAM,
+    .qdev.props = (Property[]) {
+        DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+    .qdev.reset = virtio_pci_reset,
 };
 
 static void virtio_pci_register_devices(void)
 {
-    pci_qdev_register_many(virtio_info);
+    pci_qdev_register(&virtio_blk_info);
+    pci_qdev_register(&virtio_net_info);
+    pci_qdev_register(&virtio_serial_info);
+    pci_qdev_register(&virtio_balloon_info);
 }
 
 device_init(virtio_pci_register_devices)
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 12/28] isa: pic: convert to QEMU Object Model
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (10 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 11/28] qdev: prepare source tree for code conversion Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 13/28] usb: " Anthony Liguori
                   ` (18 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Anthony Liguori

This converts two devices at once because PIC subclasses ISA and converting
subclasses independently is extremely hard.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/applesmc.c       |   18 ++++++++++++------
 hw/cirrus_vga.c     |   17 ++++++++++++-----
 hw/cs4231a.c        |   20 +++++++++++++-------
 hw/debugcon.c       |   16 +++++++++++-----
 hw/fdc.c            |   24 +++++++++++++++---------
 hw/gus.c            |   20 +++++++++++++-------
 hw/i82374.c         |   19 +++++++++++++------
 hw/i8254.c          |   22 ++++++++++++++--------
 hw/i8259.c          |   15 +++++++++++----
 hw/i8259_common.c   |   45 ++++++++++++++++++++++++++++++++-------------
 hw/i8259_internal.h |   27 +++++++++++++++++----------
 hw/ide/isa.c        |   20 +++++++++++++-------
 hw/isa-bus.c        |   38 ++++++++++++++++++++++++++++----------
 hw/isa.h            |   23 +++++++++++++++--------
 hw/kvm/i8259.c      |   19 +++++++++++++------
 hw/m48t59.c         |   20 +++++++++++++-------
 hw/mc146818rtc.c    |   22 ++++++++++++++--------
 hw/ne2000-isa.c     |   16 +++++++++++-----
 hw/parallel.c       |   16 +++++++++++-----
 hw/pc.c             |   20 +++++++++++++-------
 hw/pckbd.c          |   18 ++++++++++++------
 hw/sb16.c           |   20 +++++++++++++-------
 hw/serial.c         |   18 ++++++++++++------
 hw/sga.c            |   15 ++++++++++-----
 hw/vga-isa.c        |   18 ++++++++++++------
 hw/vmmouse.c        |   22 ++++++++++++++--------
 hw/vmport.c         |   16 +++++++++++-----
 hw/wdt_ib700.c      |   18 ++++++++++++------
 28 files changed, 390 insertions(+), 192 deletions(-)

diff --git a/hw/applesmc.c b/hw/applesmc.c
index c47b592..a6e88bc 100644
--- a/hw/applesmc.c
+++ b/hw/applesmc.c
@@ -220,12 +220,18 @@ static int applesmc_isa_init(ISADevice *dev)
     return 0;
 }
 
-static ISADeviceInfo applesmc_isa_info = {
-    .qdev.name  = "isa-applesmc",
-    .qdev.size  = sizeof(struct AppleSMCStatus),
-    .qdev.reset = qdev_applesmc_isa_reset,
-    .init       = applesmc_isa_init,
-    .qdev.props = (Property[]) {
+static void qdev_applesmc_class_init(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = applesmc_isa_init;
+}
+
+static DeviceInfo applesmc_isa_info = {
+    .name  = "isa-applesmc",
+    .size  = sizeof(struct AppleSMCStatus),
+    .reset = qdev_applesmc_isa_reset,
+    .class_init = qdev_applesmc_class_init,
+    .props = (Property[]) {
         DEFINE_PROP_HEX32("iobase", struct AppleSMCStatus, iobase,
                           APPLESMC_DEFAULT_IOBASE),
         DEFINE_PROP_STRING("osk", struct AppleSMCStatus, osk),
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 5594bde..1d0aadf 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2905,11 +2905,18 @@ static int vga_initfn(ISADevice *dev)
     return 0;
 }
 
-static ISADeviceInfo isa_cirrus_vga_info = {
-    .qdev.name     = "isa-cirrus-vga",
-    .qdev.size     = sizeof(ISACirrusVGAState),
-    .qdev.vmsd     = &vmstate_cirrus_vga,
-    .init          = vga_initfn,
+static void isa_cirrus_vga_class_init(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *k = ISA_DEVICE_CLASS(klass);
+
+    k->init          = vga_initfn;
+}
+
+static DeviceInfo isa_cirrus_vga_info = {
+    .name     = "isa-cirrus-vga",
+    .size     = sizeof(ISACirrusVGAState),
+    .vmsd     = &vmstate_cirrus_vga,
+    .class_init = isa_cirrus_vga_class_init,
 };
 
 static void isa_cirrus_vga_register(void)
diff --git a/hw/cs4231a.c b/hw/cs4231a.c
index dc77a3a..811c76b 100644
--- a/hw/cs4231a.c
+++ b/hw/cs4231a.c
@@ -665,13 +665,19 @@ int cs4231a_init (ISABus *bus)
     return 0;
 }
 
-static ISADeviceInfo cs4231a_info = {
-    .qdev.name     = "cs4231a",
-    .qdev.desc     = "Crystal Semiconductor CS4231A",
-    .qdev.size     = sizeof (CSState),
-    .qdev.vmsd     = &vmstate_cs4231a,
-    .init          = cs4231a_initfn,
-    .qdev.props    = (Property[]) {
+static void cs4231a_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = cs4231a_initfn;
+}
+
+static DeviceInfo cs4231a_info = {
+    .name     = "cs4231a",
+    .desc     = "Crystal Semiconductor CS4231A",
+    .size     = sizeof (CSState),
+    .vmsd     = &vmstate_cs4231a,
+    .class_init = cs4231a_class_initfn,
+    .props    = (Property[]) {
         DEFINE_PROP_HEX32  ("iobase",  CSState, port, 0x534),
         DEFINE_PROP_UINT32 ("irq",     CSState, irq,  9),
         DEFINE_PROP_UINT32 ("dma",     CSState, dma,  3),
diff --git a/hw/debugcon.c b/hw/debugcon.c
index c9ee6d9..f290122 100644
--- a/hw/debugcon.c
+++ b/hw/debugcon.c
@@ -87,11 +87,17 @@ static int debugcon_isa_initfn(ISADevice *dev)
     return 0;
 }
 
-static ISADeviceInfo debugcon_isa_info = {
-    .qdev.name  = "isa-debugcon",
-    .qdev.size  = sizeof(ISADebugconState),
-    .init       = debugcon_isa_initfn,
-    .qdev.props = (Property[]) {
+static void debugcon_isa_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = debugcon_isa_initfn;
+}
+
+static DeviceInfo debugcon_isa_info = {
+    .name  = "isa-debugcon",
+    .size  = sizeof(ISADebugconState),
+    .class_init = debugcon_isa_class_initfn,
+    .props = (Property[]) {
         DEFINE_PROP_HEX32("iobase", ISADebugconState, iobase, 0xe9),
         DEFINE_PROP_CHR("chardev",  ISADebugconState, state.chr),
         DEFINE_PROP_HEX32("readback", ISADebugconState, state.readback, 0xe9),
diff --git a/hw/fdc.c b/hw/fdc.c
index 70aa5c7..f761221 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1959,15 +1959,21 @@ static const VMStateDescription vmstate_isa_fdc ={
     }
 };
 
-static ISADeviceInfo isa_fdc_info = {
-    .init = isabus_fdc_init1,
-    .qdev.name  = "isa-fdc",
-    .qdev.fw_name  = "fdc",
-    .qdev.size  = sizeof(FDCtrlISABus),
-    .qdev.no_user = 1,
-    .qdev.vmsd  = &vmstate_isa_fdc,
-    .qdev.reset = fdctrl_external_reset_isa,
-    .qdev.props = (Property[]) {
+static void isabus_fdc_class_init1(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = isabus_fdc_init1;
+}
+
+static DeviceInfo isa_fdc_info = {
+    .class_init = isabus_fdc_class_init1,
+    .name  = "isa-fdc",
+    .fw_name  = "fdc",
+    .size  = sizeof(FDCtrlISABus),
+    .no_user = 1,
+    .vmsd  = &vmstate_isa_fdc,
+    .reset = fdctrl_external_reset_isa,
+    .props = (Property[]) {
         DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].bs),
         DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].bs),
         DEFINE_PROP_INT32("bootindexA", FDCtrlISABus, bootindexA, -1),
diff --git a/hw/gus.c b/hw/gus.c
index ab872d8..6603aab 100644
--- a/hw/gus.c
+++ b/hw/gus.c
@@ -299,13 +299,19 @@ int GUS_init (ISABus *bus)
     return 0;
 }
 
-static ISADeviceInfo gus_info = {
-    .qdev.name     = "gus",
-    .qdev.desc     = "Gravis Ultrasound GF1",
-    .qdev.size     = sizeof (GUSState),
-    .qdev.vmsd     = &vmstate_gus,
-    .init          = gus_initfn,
-    .qdev.props    = (Property[]) {
+static void gus_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = gus_initfn;
+}
+
+static DeviceInfo gus_info = {
+    .name     = "gus",
+    .desc     = "Gravis Ultrasound GF1",
+    .size     = sizeof (GUSState),
+    .vmsd     = &vmstate_gus,
+    .class_init          = gus_class_initfn,
+    .props    = (Property[]) {
         DEFINE_PROP_UINT32 ("freq",    GUSState, freq,        44100),
         DEFINE_PROP_HEX32  ("iobase",  GUSState, port,        0x240),
         DEFINE_PROP_UINT32 ("irq",     GUSState, emu.gusirq,  7),
diff --git a/hw/i82374.c b/hw/i82374.c
index 616d1fc..2814379 100644
--- a/hw/i82374.c
+++ b/hw/i82374.c
@@ -135,12 +135,19 @@ static int i82374_isa_init(ISADevice *dev)
     return 0;
 }
 
-static ISADeviceInfo i82374_isa_info = {
-    .qdev.name  = "i82374",
-    .qdev.size  = sizeof(ISAi82374State),
-    .qdev.vmsd  = &vmstate_isa_i82374,
-    .init       = i82374_isa_init,
-    .qdev.props = (Property[]) {
+static void i82374_class_init(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *k = ISA_DEVICE_CLASS(klass);
+    
+    k->init       = i82374_isa_init;
+}
+
+static DeviceInfo i82374_isa_info = {
+    .name  = "i82374",
+    .size  = sizeof(ISAi82374State),
+    .vmsd  = &vmstate_isa_i82374,
+    .class_init = i82374_class_init,
+    .props = (Property[]) {
         DEFINE_PROP_HEX32("iobase", ISAi82374State, iobase, 0x400),
         DEFINE_PROP_END_OF_LIST()
     },
diff --git a/hw/i8254.c b/hw/i8254.c
index cf9ed2f..add1fab 100644
--- a/hw/i8254.c
+++ b/hw/i8254.c
@@ -535,14 +535,20 @@ static int pit_initfn(ISADevice *dev)
     return 0;
 }
 
-static ISADeviceInfo pit_info = {
-    .qdev.name     = "isa-pit",
-    .qdev.size     = sizeof(PITState),
-    .qdev.vmsd     = &vmstate_pit,
-    .qdev.reset    = pit_reset,
-    .qdev.no_user  = 1,
-    .init          = pit_initfn,
-    .qdev.props = (Property[]) {
+static void pit_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = pit_initfn;
+}
+
+static DeviceInfo pit_info = {
+    .name     = "isa-pit",
+    .size     = sizeof(PITState),
+    .vmsd     = &vmstate_pit,
+    .reset    = pit_reset,
+    .no_user  = 1,
+    .class_init          = pit_class_initfn,
+    .props = (Property[]) {
         DEFINE_PROP_UINT32("irq", PITState, irq,  -1),
         DEFINE_PROP_HEX32("iobase", PITState, iobase,  -1),
         DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/i8259.c b/hw/i8259.c
index 3005ce2..e083bb6 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -472,10 +472,17 @@ qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq)
     return irq_set;
 }
 
-static PICCommonInfo i8259_info = {
-    .isadev.qdev.name  = "isa-i8259",
-    .isadev.qdev.reset = pic_reset,
-    .init              = pic_init,
+static void i8259_class_init(ObjectClass *klass, void *data)
+{
+    PICCommonClass *k = PIC_COMMON_CLASS(klass);
+
+    k->init = pic_init;
+}
+
+static DeviceInfo i8259_info = {
+    .name  = "isa-i8259",
+    .reset = pic_reset,
+    .class_init = i8259_class_init,
 };
 
 static void pic_register(void)
diff --git a/hw/i8259_common.c b/hw/i8259_common.c
index 7536897..24b1076 100644
--- a/hw/i8259_common.c
+++ b/hw/i8259_common.c
@@ -48,8 +48,7 @@ void pic_reset_common(PICCommonState *s)
 static void pic_dispatch_pre_save(void *opaque)
 {
     PICCommonState *s = opaque;
-    PICCommonInfo *info =
-        DO_UPCAST(PICCommonInfo, isadev.qdev, qdev_get_info(&s->dev.qdev));
+    PICCommonClass *info = PIC_COMMON_GET_CLASS(s);
 
     if (info->pre_save) {
         info->pre_save(s);
@@ -59,8 +58,7 @@ static void pic_dispatch_pre_save(void *opaque)
 static int pic_dispatch_post_load(void *opaque, int version_id)
 {
     PICCommonState *s = opaque;
-    PICCommonInfo *info =
-        DO_UPCAST(PICCommonInfo, isadev.qdev, qdev_get_info(&s->dev.qdev));
+    PICCommonClass *info = PIC_COMMON_GET_CLASS(s);
 
     if (info->post_load) {
         info->post_load(s);
@@ -71,8 +69,7 @@ static int pic_dispatch_post_load(void *opaque, int version_id)
 static int pic_init_common(ISADevice *dev)
 {
     PICCommonState *s = DO_UPCAST(PICCommonState, dev, dev);
-    PICCommonInfo *info =
-        DO_UPCAST(PICCommonInfo, isadev.qdev, qdev_get_info(&dev->qdev));
+    PICCommonClass *info = PIC_COMMON_GET_CLASS(s);
 
     info->init(s);
 
@@ -136,12 +133,34 @@ static Property pic_properties_common[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-void pic_qdev_register(PICCommonInfo *info)
+void pic_qdev_register(DeviceInfo *info)
 {
-    info->isadev.init = pic_init_common;
-    info->isadev.qdev.size = sizeof(PICCommonState);
-    info->isadev.qdev.vmsd = &vmstate_pic_common;
-    info->isadev.qdev.no_user = 1;
-    info->isadev.qdev.props = pic_properties_common;
-    isa_qdev_register(&info->isadev);
+    info->size = sizeof(PICCommonState);
+    info->vmsd = &vmstate_pic_common;
+    info->no_user = 1;
+    info->props = pic_properties_common;
+    isa_qdev_register_subclass(info, TYPE_PIC_COMMON);
 }
+
+static void pic_common_class_init(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+
+    ic->init = pic_init_common;
+}
+
+static TypeInfo pic_common_type = {
+    .name = TYPE_PIC_COMMON,
+    .parent = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(PICCommonState),
+    .class_size = sizeof(PICCommonClass),
+    .class_init = pic_common_class_init,
+    .abstract = true,
+};
+
+static void register_devices(void)
+{
+    type_register_static(&pic_common_type);
+}
+
+device_init(register_devices);
diff --git a/hw/i8259_internal.h b/hw/i8259_internal.h
index 13deb14..e9d1732 100644
--- a/hw/i8259_internal.h
+++ b/hw/i8259_internal.h
@@ -31,6 +31,22 @@
 
 typedef struct PICCommonState PICCommonState;
 
+#define TYPE_PIC_COMMON "pic-common"
+#define PIC_COMMON(obj) \
+     OBJECT_CHECK(PICCommon, (obj), TYPE_PIC_COMMON)
+#define PIC_COMMON_CLASS(klass) \
+     OBJECT_CLASS_CHECK(PICCommonClass, (klass), TYPE_PIC_COMMON)
+#define PIC_COMMON_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(PICCommonClass, (obj), TYPE_PIC_COMMON)
+
+typedef struct PICCommonClass
+{
+    ISADeviceClass parent_class;
+    void (*init)(PICCommonState *s);
+    void (*pre_save)(PICCommonState *s);
+    void (*post_load)(PICCommonState *s);
+} PICCommonClass;
+
 struct PICCommonState {
     ISADevice dev;
     uint8_t last_irr; /* edge detection */
@@ -58,19 +74,10 @@ struct PICCommonState {
     MemoryRegion elcr_io;
 };
 
-typedef struct PICCommonInfo PICCommonInfo;
-
-struct PICCommonInfo {
-    ISADeviceInfo isadev;
-    void (*init)(PICCommonState *s);
-    void (*pre_save)(PICCommonState *s);
-    void (*post_load)(PICCommonState *s);
-};
-
 void pic_reset_common(PICCommonState *s);
 
 ISADevice *i8259_init_chip(const char *name, ISABus *bus, bool master);
 
-void pic_qdev_register(PICCommonInfo *info);
+void pic_qdev_register(DeviceInfo *info);
 
 #endif /* !QEMU_I8259_INTERNAL_H */
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 219f3a4..464473a 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -94,13 +94,19 @@ ISADevice *isa_ide_init(ISABus *bus, int iobase, int iobase2, int isairq,
     return dev;
 }
 
-static ISADeviceInfo isa_ide_info = {
-    .qdev.name  = "isa-ide",
-    .qdev.fw_name  = "ide",
-    .qdev.size  = sizeof(ISAIDEState),
-    .init       = isa_ide_initfn,
-    .qdev.reset = isa_ide_reset,
-    .qdev.props = (Property[]) {
+static void isa_ide_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = isa_ide_initfn;
+}
+
+static DeviceInfo isa_ide_info = {
+    .name  = "isa-ide",
+    .fw_name  = "ide",
+    .size  = sizeof(ISAIDEState),
+    .class_init       = isa_ide_class_initfn,
+    .reset = isa_ide_reset,
+    .props = (Property[]) {
         DEFINE_PROP_HEX32("iobase",  ISAIDEState, iobase,  0x1f0),
         DEFINE_PROP_HEX32("iobase2", ISAIDEState, iobase2, 0x3f6),
         DEFINE_PROP_UINT32("irq",    ISAIDEState, isairq,  14),
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 5af790b..6943194 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -112,20 +112,29 @@ void isa_register_portio_list(ISADevice *dev, uint16_t start,
 
 static int isa_qdev_init(DeviceState *qdev, DeviceInfo *base)
 {
-    ISADevice *dev = DO_UPCAST(ISADevice, qdev, qdev);
-    ISADeviceInfo *info = DO_UPCAST(ISADeviceInfo, qdev, base);
+    ISADevice *dev = ISA_DEVICE(qdev);
+    ISADeviceClass *klass = ISA_DEVICE_GET_CLASS(dev);
 
     dev->isairq[0] = -1;
     dev->isairq[1] = -1;
 
-    return info->init(dev);
+    if (klass->init) {
+        return klass->init(dev);
+    }
+
+    return 0;
+}
+
+void isa_qdev_register_subclass(DeviceInfo *info, const char *parent)
+{
+    info->init = isa_qdev_init;
+    info->bus_info = &isa_bus_info;
+    qdev_register_subclass(info, parent);
 }
 
-void isa_qdev_register(ISADeviceInfo *info)
+void isa_qdev_register(DeviceInfo *info)
 {
-    info->qdev.init = isa_qdev_init;
-    info->qdev.bus_info = &isa_bus_info;
-    qdev_register(&info->qdev);
+    isa_qdev_register_subclass(info, TYPE_ISA_DEVICE);
 }
 
 ISADevice *isa_create(ISABus *bus, const char *name)
@@ -137,7 +146,7 @@ ISADevice *isa_create(ISABus *bus, const char *name)
                  name);
     }
     dev = qdev_create(&bus->qbus, name);
-    return DO_UPCAST(ISADevice, qdev, dev);
+    return ISA_DEVICE(dev);
 }
 
 ISADevice *isa_try_create(ISABus *bus, const char *name)
@@ -149,7 +158,7 @@ ISADevice *isa_try_create(ISABus *bus, const char *name)
                  name);
     }
     dev = qdev_try_create(&bus->qbus, name);
-    return DO_UPCAST(ISADevice, qdev, dev);
+    return ISA_DEVICE(dev);
 }
 
 ISADevice *isa_create_simple(ISABus *bus, const char *name)
@@ -163,7 +172,7 @@ ISADevice *isa_create_simple(ISABus *bus, const char *name)
 
 static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent)
 {
-    ISADevice *d = DO_UPCAST(ISADevice, qdev, dev);
+    ISADevice *d = ISA_DEVICE(dev);
 
     if (d->isairq[1] != -1) {
         monitor_printf(mon, "%*sisa irqs %d,%d\n", indent, "",
@@ -188,9 +197,18 @@ static SysBusDeviceInfo isabus_bridge_info = {
     .qdev.no_user = 1,
 };
 
+static TypeInfo isa_device_type_info = {
+    .name = TYPE_ISA_DEVICE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(ISADevice),
+    .abstract = true,
+    .class_size = sizeof(ISADeviceClass),
+};
+
 static void isabus_register_devices(void)
 {
     sysbus_register_withprop(&isabus_bridge_info);
+    type_register_static(&isa_device_type_info);
 }
 
 static char *isabus_get_fw_dev_path(DeviceState *dev)
diff --git a/hw/isa.h b/hw/isa.h
index b11a0be..9f5d158 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -10,7 +10,19 @@
 #define ISA_NUM_IRQS 16
 
 typedef struct ISADevice ISADevice;
-typedef struct ISADeviceInfo ISADeviceInfo;
+
+#define TYPE_ISA_DEVICE "isa-device"
+#define ISA_DEVICE(obj) \
+     OBJECT_CHECK(ISADevice, (obj), TYPE_ISA_DEVICE)
+#define ISA_DEVICE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(ISADeviceClass, (klass), TYPE_ISA_DEVICE)
+#define ISA_DEVICE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(ISADeviceClass, (obj), TYPE_ISA_DEVICE)
+
+typedef struct ISADeviceClass {
+    DeviceClass parent_class;
+    int (*init)(ISADevice *dev);
+} ISADeviceClass;
 
 struct ISABus {
     BusState qbus;
@@ -25,17 +37,12 @@ struct ISADevice {
     int ioport_id;
 };
 
-typedef int (*isa_qdev_initfn)(ISADevice *dev);
-struct ISADeviceInfo {
-    DeviceInfo qdev;
-    isa_qdev_initfn init;
-};
-
 ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io);
 void isa_bus_irqs(ISABus *bus, qemu_irq *irqs);
 qemu_irq isa_get_irq(ISADevice *dev, int isairq);
 void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq);
-void isa_qdev_register(ISADeviceInfo *info);
+void isa_qdev_register(DeviceInfo *info);
+void isa_qdev_register_subclass(DeviceInfo *info, const char *parent);
 MemoryRegion *isa_address_space(ISADevice *dev);
 ISADevice *isa_create(ISABus *bus, const char *name);
 ISADevice *isa_try_create(ISABus *bus, const char *name);
diff --git a/hw/kvm/i8259.c b/hw/kvm/i8259.c
index 64bb5c2..b34901c 100644
--- a/hw/kvm/i8259.c
+++ b/hw/kvm/i8259.c
@@ -112,12 +112,19 @@ qemu_irq *kvm_i8259_init(ISABus *bus)
     return qemu_allocate_irqs(kvm_pic_set_irq, NULL, ISA_NUM_IRQS);
 }
 
-static PICCommonInfo kvm_i8259_info = {
-    .isadev.qdev.name  = "kvm-i8259",
-    .isadev.qdev.reset = kvm_pic_reset,
-    .init       = kvm_pic_init,
-    .pre_save   = kvm_pic_get,
-    .post_load  = kvm_pic_put,
+static void kvm_i8259_class_init(ObjectClass *klass, void *data)
+{
+    PICCommonClass *k = PIC_COMMON_CLASS(klass);
+
+    k->init       = kvm_pic_init;
+    k->pre_save   = kvm_pic_get;
+    k->post_load  = kvm_pic_put;
+}
+
+static DeviceInfo kvm_i8259_info = {
+    .name  = "kvm-i8259",
+    .reset = kvm_pic_reset,
+    .class_init = kvm_i8259_class_init,
 };
 
 static void kvm_pic_register(void)
diff --git a/hw/m48t59.c b/hw/m48t59.c
index c043996..5912cd6 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -720,13 +720,19 @@ static int m48t59_init1(SysBusDevice *dev)
     return 0;
 }
 
-static ISADeviceInfo m48t59_isa_info = {
-    .init = m48t59_init_isa1,
-    .qdev.name = "m48t59_isa",
-    .qdev.size = sizeof(M48t59ISAState),
-    .qdev.reset = m48t59_reset_isa,
-    .qdev.no_user = 1,
-    .qdev.props = (Property[]) {
+static void m48t59_init_class_isa1(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = m48t59_init_isa1;
+}
+
+static DeviceInfo m48t59_isa_info = {
+    .class_init = m48t59_init_class_isa1,
+    .name = "m48t59_isa",
+    .size = sizeof(M48t59ISAState),
+    .reset = m48t59_reset_isa,
+    .no_user = 1,
+    .props = (Property[]) {
         DEFINE_PROP_UINT32("size",    M48t59ISAState, state.size,    -1),
         DEFINE_PROP_UINT32("type",    M48t59ISAState, state.type,    -1),
         DEFINE_PROP_HEX32( "io_base", M48t59ISAState, state.io_base,  0),
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index 657fa10..685eb89 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -629,7 +629,7 @@ static void visit_type_int32(Visitor *v, int *value, const char *name, Error **e
 static void rtc_get_date(DeviceState *dev, Visitor *v, void *opaque,
                          const char *name, Error **errp)
 {
-    ISADevice *isa = DO_UPCAST(ISADevice, qdev, dev);
+    ISADevice *isa = ISA_DEVICE(dev);
     RTCState *s = DO_UPCAST(RTCState, dev, isa);
 
     visit_start_struct(v, NULL, "struct tm", name, 0, errp);
@@ -699,13 +699,19 @@ ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
     return dev;
 }
 
-static ISADeviceInfo mc146818rtc_info = {
-    .qdev.name     = "mc146818rtc",
-    .qdev.size     = sizeof(RTCState),
-    .qdev.no_user  = 1,
-    .qdev.vmsd     = &vmstate_rtc,
-    .init          = rtc_initfn,
-    .qdev.props    = (Property[]) {
+static void rtc_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = rtc_initfn;
+}
+
+static DeviceInfo mc146818rtc_info = {
+    .name     = "mc146818rtc",
+    .size     = sizeof(RTCState),
+    .no_user  = 1,
+    .vmsd     = &vmstate_rtc,
+    .class_init          = rtc_class_initfn,
+    .props    = (Property[]) {
         DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980),
         DEFINE_PROP_END_OF_LIST(),
     }
diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c
index 5bc5f2a..25a7a31 100644
--- a/hw/ne2000-isa.c
+++ b/hw/ne2000-isa.c
@@ -82,11 +82,17 @@ static int isa_ne2000_initfn(ISADevice *dev)
     return 0;
 }
 
-static ISADeviceInfo ne2000_isa_info = {
-    .qdev.name  = "ne2k_isa",
-    .qdev.size  = sizeof(ISANE2000State),
-    .init       = isa_ne2000_initfn,
-    .qdev.props = (Property[]) {
+static void isa_ne2000_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = isa_ne2000_initfn;
+}
+
+static DeviceInfo ne2000_isa_info = {
+    .name  = "ne2k_isa",
+    .size  = sizeof(ISANE2000State),
+    .class_init       = isa_ne2000_class_initfn,
+    .props = (Property[]) {
         DEFINE_PROP_HEX32("iobase", ISANE2000State, iobase, 0x300),
         DEFINE_PROP_UINT32("irq",   ISANE2000State, isairq, 9),
         DEFINE_NIC_PROPERTIES(ISANE2000State, ne2000.c),
diff --git a/hw/parallel.c b/hw/parallel.c
index c4c5dbe..cadcffb 100644
--- a/hw/parallel.c
+++ b/hw/parallel.c
@@ -583,11 +583,17 @@ bool parallel_mm_init(MemoryRegion *address_space,
     return true;
 }
 
-static ISADeviceInfo parallel_isa_info = {
-    .qdev.name  = "isa-parallel",
-    .qdev.size  = sizeof(ISAParallelState),
-    .init       = parallel_isa_initfn,
-    .qdev.props = (Property[]) {
+static void parallel_isa_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = parallel_isa_initfn;
+}
+
+static DeviceInfo parallel_isa_info = {
+    .name  = "isa-parallel",
+    .size  = sizeof(ISAParallelState),
+    .class_init       = parallel_isa_class_initfn,
+    .props = (Property[]) {
         DEFINE_PROP_UINT32("index", ISAParallelState, index,   -1),
         DEFINE_PROP_HEX32("iobase", ISAParallelState, iobase,  -1),
         DEFINE_PROP_UINT32("irq",   ISAParallelState, isairq,  7),
diff --git a/hw/pc.c b/hw/pc.c
index f3124d3..31608d3 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -497,13 +497,19 @@ static int port92_initfn(ISADevice *dev)
     return 0;
 }
 
-static ISADeviceInfo port92_info = {
-    .qdev.name     = "port92",
-    .qdev.size     = sizeof(Port92State),
-    .qdev.vmsd     = &vmstate_port92_isa,
-    .qdev.no_user  = 1,
-    .qdev.reset    = port92_reset,
-    .init          = port92_initfn,
+static void port92_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = port92_initfn;
+}
+
+static DeviceInfo port92_info = {
+    .name     = "port92",
+    .size     = sizeof(Port92State),
+    .vmsd     = &vmstate_port92_isa,
+    .no_user  = 1,
+    .reset    = port92_reset,
+    .class_init          = port92_class_initfn,
 };
 
 static void port92_register(void)
diff --git a/hw/pckbd.c b/hw/pckbd.c
index 06b40c5..2ebe1c5 100644
--- a/hw/pckbd.c
+++ b/hw/pckbd.c
@@ -497,12 +497,18 @@ static int i8042_initfn(ISADevice *dev)
     return 0;
 }
 
-static ISADeviceInfo i8042_info = {
-    .qdev.name     = "i8042",
-    .qdev.size     = sizeof(ISAKBDState),
-    .qdev.vmsd     = &vmstate_kbd_isa,
-    .qdev.no_user  = 1,
-    .init          = i8042_initfn,
+static void i8042_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = i8042_initfn;
+}
+
+static DeviceInfo i8042_info = {
+    .name     = "i8042",
+    .size     = sizeof(ISAKBDState),
+    .vmsd     = &vmstate_kbd_isa,
+    .no_user  = 1,
+    .class_init          = i8042_class_initfn,
 };
 
 static void i8042_register(void)
diff --git a/hw/sb16.c b/hw/sb16.c
index 887b32e..67357ce 100644
--- a/hw/sb16.c
+++ b/hw/sb16.c
@@ -1391,13 +1391,19 @@ int SB16_init (ISABus *bus)
     return 0;
 }
 
-static ISADeviceInfo sb16_info = {
-    .qdev.name     = "sb16",
-    .qdev.desc     = "Creative Sound Blaster 16",
-    .qdev.size     = sizeof (SB16State),
-    .qdev.vmsd     = &vmstate_sb16,
-    .init          = sb16_initfn,
-    .qdev.props    = (Property[]) {
+static void sb16_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = sb16_initfn;
+}
+
+static DeviceInfo sb16_info = {
+    .name     = "sb16",
+    .desc     = "Creative Sound Blaster 16",
+    .size     = sizeof (SB16State),
+    .vmsd     = &vmstate_sb16,
+    .class_init          = sb16_class_initfn,
+    .props    = (Property[]) {
         DEFINE_PROP_HEX32  ("version", SB16State, ver,  0x0405), /* 4.5 */
         DEFINE_PROP_HEX32  ("iobase",  SB16State, port, 0x220),
         DEFINE_PROP_UINT32 ("irq",     SB16State, irq,  5),
diff --git a/hw/serial.c b/hw/serial.c
index d35c7a9..2644b13 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -879,12 +879,18 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
     return s;
 }
 
-static ISADeviceInfo serial_isa_info = {
-    .qdev.name  = "isa-serial",
-    .qdev.size  = sizeof(ISASerialState),
-    .qdev.vmsd  = &vmstate_isa_serial,
-    .init       = serial_isa_initfn,
-    .qdev.props = (Property[]) {
+static void serial_isa_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = serial_isa_initfn;
+}
+
+static DeviceInfo serial_isa_info = {
+    .name  = "isa-serial",
+    .size  = sizeof(ISASerialState),
+    .vmsd  = &vmstate_isa_serial,
+    .class_init       = serial_isa_class_initfn,
+    .props = (Property[]) {
         DEFINE_PROP_UINT32("index", ISASerialState, index,   -1),
         DEFINE_PROP_HEX32("iobase", ISASerialState, iobase,  -1),
         DEFINE_PROP_UINT32("irq",   ISASerialState, isairq,  -1),
diff --git a/hw/sga.c b/hw/sga.c
index ea11937..d612cb6 100644
--- a/hw/sga.c
+++ b/hw/sga.c
@@ -40,12 +40,17 @@ static int sga_initfn(ISADevice *dev)
     rom_add_vga(SGABIOS_FILENAME);
     return 0;
 }
+static void sga_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = sga_initfn;
+}
 
-static ISADeviceInfo sga_info = {
-    .qdev.name    = "sga",
-    .qdev.desc    = "Serial Graphics Adapter",
-    .qdev.size    = sizeof(ISASGAState),
-    .init         = sga_initfn,
+static DeviceInfo sga_info = {
+    .name    = "sga",
+    .desc    = "Serial Graphics Adapter",
+    .size    = sizeof(ISASGAState),
+    .class_init         = sga_class_initfn,
 };
 
 static void sga_register(void)
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index 4825313..cb6af91 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -69,12 +69,18 @@ static int vga_initfn(ISADevice *dev)
     return 0;
 }
 
-static ISADeviceInfo vga_info = {
-    .qdev.name     = "isa-vga",
-    .qdev.size     = sizeof(ISAVGAState),
-    .qdev.vmsd     = &vmstate_vga_common,
-    .qdev.reset     = vga_reset_isa,
-    .init          = vga_initfn,
+static void vga_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = vga_initfn;
+}
+
+static DeviceInfo vga_info = {
+    .name     = "isa-vga",
+    .size     = sizeof(ISAVGAState),
+    .vmsd     = &vmstate_vga_common,
+    .reset     = vga_reset_isa,
+    .class_init          = vga_class_initfn,
 };
 
 static void vga_register(void)
diff --git a/hw/vmmouse.c b/hw/vmmouse.c
index 1113f33..da2ea32 100644
--- a/hw/vmmouse.c
+++ b/hw/vmmouse.c
@@ -269,14 +269,20 @@ static int vmmouse_initfn(ISADevice *dev)
     return 0;
 }
 
-static ISADeviceInfo vmmouse_info = {
-    .init          = vmmouse_initfn,
-    .qdev.name     = "vmmouse",
-    .qdev.size     = sizeof(VMMouseState),
-    .qdev.vmsd     = &vmstate_vmmouse,
-    .qdev.no_user  = 1,
-    .qdev.reset    = vmmouse_reset,
-    .qdev.props = (Property[]) {
+static void vmmouse_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = vmmouse_initfn;
+}
+
+static DeviceInfo vmmouse_info = {
+    .class_init          = vmmouse_class_initfn,
+    .name     = "vmmouse",
+    .size     = sizeof(VMMouseState),
+    .vmsd     = &vmstate_vmmouse,
+    .no_user  = 1,
+    .reset    = vmmouse_reset,
+    .props = (Property[]) {
         DEFINE_PROP_PTR("ps2_mouse", VMMouseState, ps2_mouse),
         DEFINE_PROP_END_OF_LIST(),
     }
diff --git a/hw/vmport.c b/hw/vmport.c
index 0a3dbc5..c4582d6 100644
--- a/hw/vmport.c
+++ b/hw/vmport.c
@@ -144,11 +144,17 @@ static int vmport_initfn(ISADevice *dev)
     return 0;
 }
 
-static ISADeviceInfo vmport_info = {
-    .qdev.name     = "vmport",
-    .qdev.size     = sizeof(VMPortState),
-    .qdev.no_user  = 1,
-    .init          = vmport_initfn,
+static void vmport_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = vmport_initfn;
+}
+
+static DeviceInfo vmport_info = {
+    .name     = "vmport",
+    .size     = sizeof(VMPortState),
+    .no_user  = 1,
+    .class_init          = vmport_class_initfn,
 };
 
 static void vmport_dev_register(void)
diff --git a/hw/wdt_ib700.c b/hw/wdt_ib700.c
index ba1d92d..6deb0de 100644
--- a/hw/wdt_ib700.c
+++ b/hw/wdt_ib700.c
@@ -120,12 +120,18 @@ static WatchdogTimerModel model = {
     .wdt_description = "iBASE 700",
 };
 
-static ISADeviceInfo wdt_ib700_info = {
-    .qdev.name  = "ib700",
-    .qdev.size  = sizeof(IB700State),
-    .qdev.vmsd  = &vmstate_ib700,
-    .qdev.reset = wdt_ib700_reset,
-    .init       = wdt_ib700_init,
+static void wdt_ib700_class_init(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = wdt_ib700_init;
+}
+
+static DeviceInfo wdt_ib700_info = {
+    .name  = "ib700",
+    .size  = sizeof(IB700State),
+    .vmsd  = &vmstate_ib700,
+    .reset = wdt_ib700_reset,
+    .class_init       = wdt_ib700_class_init,
 };
 
 static void wdt_ib700_register_devices(void)
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 13/28] usb: convert to QEMU Object Model
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (11 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 12/28] isa: pic: convert to QEMU Object Model Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 14/28] ccid: " Anthony Liguori
                   ` (17 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/usb-audio.c  |   38 +++++++-----
 hw/usb-bt.c     |   33 ++++++----
 hw/usb-bus.c    |  188 +++++++++++++++++++++++++++++++++++++++++++-----------
 hw/usb-ccid.c   |   38 +++++++-----
 hw/usb-desc.c   |   22 +++---
 hw/usb-hid.c    |  108 +++++++++++++++++++-------------
 hw/usb-hub.c    |   35 ++++++----
 hw/usb-msd.c    |   41 +++++++-----
 hw/usb-net.c    |   41 +++++++-----
 hw/usb-serial.c |   74 ++++++++++++---------
 hw/usb-wacom.c  |   36 ++++++-----
 hw/usb-xhci.c   |    4 +-
 hw/usb.c        |   24 +++----
 hw/usb.h        |   50 +++++++++++---
 usb-bsd.c       |   29 +++++---
 usb-linux.c     |   37 ++++++-----
 usb-redir.c     |   33 ++++++----
 17 files changed, 528 insertions(+), 303 deletions(-)

diff --git a/hw/usb-audio.c b/hw/usb-audio.c
index b22d578..561ae31 100644
--- a/hw/usb-audio.c
+++ b/hw/usb-audio.c
@@ -674,21 +674,27 @@ static const VMStateDescription vmstate_usb_audio = {
     .unmigratable = 1,
 };
 
-static struct USBDeviceInfo usb_audio_info = {
-    .product_desc   = "QEMU USB Audio Interface",
-    .usbdevice_name = "audio",
-    .qdev.name      = "usb-audio",
-    .qdev.size      = sizeof(USBAudioState),
-    .qdev.vmsd      = &vmstate_usb_audio,
-    .usb_desc       = &desc_audio,
-    .init           = usb_audio_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = usb_audio_handle_reset,
-    .handle_control = usb_audio_handle_control,
-    .handle_data    = usb_audio_handle_data,
-    .handle_destroy = usb_audio_handle_destroy,
-    .set_interface  = usb_audio_set_interface,
-    .qdev.props = (Property[]) {
+static void usb_audio_class_init(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *k = USB_DEVICE_CLASS(klass);
+
+    k->product_desc   = "QEMU USB Audio Interface";
+    k->usb_desc       = &desc_audio;
+    k->init           = usb_audio_initfn;
+    k->handle_packet  = usb_generic_handle_packet;
+    k->handle_reset   = usb_audio_handle_reset;
+    k->handle_control = usb_audio_handle_control;
+    k->handle_data    = usb_audio_handle_data;
+    k->handle_destroy = usb_audio_handle_destroy;
+    k->set_interface  = usb_audio_set_interface;
+}
+
+static struct DeviceInfo usb_audio_info = {
+    .name      = "usb-audio",
+    .size      = sizeof(USBAudioState),
+    .vmsd      = &vmstate_usb_audio,
+    .class_init = usb_audio_class_init,
+    .props = (Property[]) {
         DEFINE_PROP_UINT32("debug", USBAudioState, debug, 0),
         DEFINE_PROP_UINT32("buffer", USBAudioState, buffer,
                            8 * USBAUDIO_PACKET_SIZE),
@@ -698,7 +704,7 @@ static struct USBDeviceInfo usb_audio_info = {
 
 static void usb_audio_register_devices(void)
 {
-    usb_qdev_register(&usb_audio_info);
+    usb_qdev_register(&usb_audio_info, "audio", NULL);
 }
 
 device_init(usb_audio_register_devices)
diff --git a/hw/usb-bt.c b/hw/usb-bt.c
index 0c1270b..bf8c470 100644
--- a/hw/usb-bt.c
+++ b/hw/usb-bt.c
@@ -527,22 +527,29 @@ static const VMStateDescription vmstate_usb_bt = {
     .unmigratable = 1,
 };
 
-static struct USBDeviceInfo bt_info = {
-    .product_desc   = "QEMU BT dongle",
-    .qdev.name      = "usb-bt-dongle",
-    .qdev.size      = sizeof(struct USBBtState),
-    .qdev.vmsd      = &vmstate_usb_bt,
-    .usb_desc       = &desc_bluetooth,
-    .init           = usb_bt_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = usb_bt_handle_reset,
-    .handle_control = usb_bt_handle_control,
-    .handle_data    = usb_bt_handle_data,
-    .handle_destroy = usb_bt_handle_destroy,
+static void usb_bt_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_bt_initfn;
+    uc->product_desc   = "QEMU BT dongle";
+    uc->usb_desc       = &desc_bluetooth;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_bt_handle_reset;
+    uc->handle_control = usb_bt_handle_control;
+    uc->handle_data    = usb_bt_handle_data;
+    uc->handle_destroy = usb_bt_handle_destroy;
+}
+
+static struct DeviceInfo bt_info = {
+    .name      = "usb-bt-dongle",
+    .size      = sizeof(struct USBBtState),
+    .vmsd      = &vmstate_usb_bt,
+    .class_init= usb_bt_class_initfn,
 };
 
 static void usb_bt_register_devices(void)
 {
-    usb_qdev_register(&bt_info);
+    usb_qdev_register(&bt_info, NULL, NULL);
 }
 device_init(usb_bt_register_devices)
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 9b67f18..aeef908 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -65,14 +65,104 @@ USBBus *usb_bus_find(int busnr)
     return NULL;
 }
 
+static int usb_device_init(USBDevice *dev)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->init) {
+        return klass->init(dev);
+    }
+    return 0;
+}
+
+static void usb_device_handle_destroy(USBDevice *dev)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->handle_destroy) {
+        klass->handle_destroy(dev);
+    }
+}
+
+int usb_device_handle_packet(USBDevice *dev, USBPacket *p)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->handle_packet) {
+        return klass->handle_packet(dev, p);
+    }
+    return -ENOSYS;
+}
+
+void usb_device_cancel_packet(USBDevice *dev, USBPacket *p)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->cancel_packet) {
+        klass->cancel_packet(dev, p);
+    }
+}
+
+void usb_device_handle_attach(USBDevice *dev)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->handle_attach) {
+        klass->handle_attach(dev);
+    }
+}
+
+void usb_device_handle_reset(USBDevice *dev)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->handle_reset) {
+        klass->handle_reset(dev);
+    }
+}
+
+int usb_device_handle_control(USBDevice *dev, USBPacket *p, int request,
+                              int value, int index, int length, uint8_t *data)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->handle_control) {
+        return klass->handle_control(dev, p, request, value, index, length,
+                                         data);
+    }
+    return -ENOSYS;
+}
+
+int usb_device_handle_data(USBDevice *dev, USBPacket *p)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->handle_data) {
+        return klass->handle_data(dev, p);
+    }
+    return -ENOSYS;
+}
+
+const char *usb_device_get_product_desc(USBDevice *dev)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    return klass->product_desc;
+}
+
+const USBDesc *usb_device_get_usb_desc(USBDevice *dev)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    return klass->usb_desc;
+}
+
+void usb_device_set_interface(USBDevice *dev, int interface,
+                              int alt_old, int alt_new)
+{
+    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+    if (klass->set_interface) {
+        klass->set_interface(dev, interface, alt_old, alt_new);
+    }
+}
+
 static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
 {
-    USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
-    USBDeviceInfo *info = DO_UPCAST(USBDeviceInfo, qdev, base);
+    USBDevice *dev = USB_DEVICE(qdev);
     int rc;
 
-    pstrcpy(dev->product_desc, sizeof(dev->product_desc), info->product_desc);
-    dev->info = info;
+    pstrcpy(dev->product_desc, sizeof(dev->product_desc),
+            usb_device_get_product_desc(dev));
     dev->auto_attach = 1;
     QLIST_INIT(&dev->strings);
     usb_ep_init(dev);
@@ -80,7 +170,7 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
     if (rc != 0) {
         return rc;
     }
-    rc = dev->info->init(dev);
+    rc = usb_device_init(dev);
     if (rc != 0) {
         usb_release_port(dev);
         return rc;
@@ -97,34 +187,43 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
 
 static int usb_qdev_exit(DeviceState *qdev)
 {
-    USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+    USBDevice *dev = USB_DEVICE(qdev);
 
     if (dev->attached) {
         usb_device_detach(dev);
     }
-    if (dev->info->handle_destroy) {
-        dev->info->handle_destroy(dev);
-    }
+    usb_device_handle_destroy(dev);
     if (dev->port) {
         usb_release_port(dev);
     }
     return 0;
 }
 
-void usb_qdev_register(USBDeviceInfo *info)
+typedef struct LegacyUSBFactory
 {
-    info->qdev.bus_info = &usb_bus_info;
-    info->qdev.init     = usb_qdev_init;
-    info->qdev.unplug   = qdev_simple_unplug_cb;
-    info->qdev.exit     = usb_qdev_exit;
-    qdev_register(&info->qdev);
-}
+    const char *name;
+    const char *usbdevice_name;
+    USBDevice *(*usbdevice_init)(const char *params);
+} LegacyUSBFactory;
 
-void usb_qdev_register_many(USBDeviceInfo *info)
+static GSList *legacy_usb_factory;
+
+void usb_qdev_register(DeviceInfo *info,
+                       const char *usbdevice_name,
+                       USBDevice *(*usbdevice_init)(const char *params))
 {
-    while (info->qdev.name) {
-        usb_qdev_register(info);
-        info++;
+    info->bus_info = &usb_bus_info;
+    info->init     = usb_qdev_init;
+    info->unplug   = qdev_simple_unplug_cb;
+    info->exit     = usb_qdev_exit;
+    qdev_register_subclass(info, TYPE_USB_DEVICE);
+
+    if (usbdevice_name) {
+        LegacyUSBFactory *f = g_malloc0(sizeof(*f));
+        f->name = info->name;
+        f->usbdevice_name = usbdevice_name;
+        f->usbdevice_init = usbdevice_init;
+        legacy_usb_factory = g_slist_append(legacy_usb_factory, f);
     }
 }
 
@@ -144,7 +243,7 @@ USBDevice *usb_create(USBBus *bus, const char *name)
 #endif
 
     dev = qdev_create(&bus->qbus, name);
-    return DO_UPCAST(USBDevice, qdev, dev);
+    return USB_DEVICE(dev);
 }
 
 USBDevice *usb_create_simple(USBBus *bus, const char *name)
@@ -365,7 +464,7 @@ static const char *usb_speed(unsigned int speed)
 
 static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
 {
-    USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+    USBDevice *dev = USB_DEVICE(qdev);
     USBBus *bus = usb_bus_from_device(dev);
 
     monitor_printf(mon, "%*saddr %d.%d, port %s, speed %s, name %s%s\n",
@@ -377,13 +476,13 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
 
 static char *usb_get_dev_path(DeviceState *qdev)
 {
-    USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+    USBDevice *dev = USB_DEVICE(qdev);
     return g_strdup(dev->port->path);
 }
 
 static char *usb_get_fw_dev_path(DeviceState *qdev)
 {
-    USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+    USBDevice *dev = USB_DEVICE(qdev);
     char *fw_path, *in;
     ssize_t pos = 0, fw_len;
     long nr;
@@ -434,8 +533,8 @@ void usb_info(Monitor *mon)
 USBDevice *usbdevice_create(const char *cmdline)
 {
     USBBus *bus = usb_bus_find(-1 /* any */);
-    DeviceInfo *info;
-    USBDeviceInfo *usb;
+    LegacyUSBFactory *f = NULL;
+    GSList *i;
     char driver[32];
     const char *params;
     int len;
@@ -452,17 +551,13 @@ USBDevice *usbdevice_create(const char *cmdline)
         pstrcpy(driver, sizeof(driver), cmdline);
     }
 
-    for (info = device_info_list; info != NULL; info = info->next) {
-        if (info->bus_info != &usb_bus_info)
-            continue;
-        usb = DO_UPCAST(USBDeviceInfo, qdev, info);
-        if (usb->usbdevice_name == NULL)
-            continue;
-        if (strcmp(usb->usbdevice_name, driver) != 0)
-            continue;
-        break;
+    for (i = legacy_usb_factory; i; i = i->next) {
+        f = i->data;
+        if (strcmp(f->usbdevice_name, driver) == 0) {
+            break;
+        }
     }
-    if (info == NULL) {
+    if (i == NULL) {
 #if 0
         /* no error because some drivers are not converted (yet) */
         error_report("usbdevice %s not found", driver);
@@ -470,12 +565,27 @@ USBDevice *usbdevice_create(const char *cmdline)
         return NULL;
     }
 
-    if (!usb->usbdevice_init) {
+    if (!f->usbdevice_init) {
         if (*params) {
             error_report("usbdevice %s accepts no params", driver);
             return NULL;
         }
-        return usb_create_simple(bus, usb->qdev.name);
+        return usb_create_simple(bus, f->name);
     }
-    return usb->usbdevice_init(params);
+    return f->usbdevice_init(params);
 }
+
+static TypeInfo usb_device_type_info = {
+    .name = TYPE_USB_DEVICE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(USBDevice),
+    .abstract = true,
+    .class_size = sizeof(USBDeviceClass),
+};
+
+static void usb_register_devices(void)
+{
+    type_register_static(&usb_device_type_info);
+}
+
+device_init(usb_register_devices);
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index 3b7f95d..eb63dfc 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -1286,28 +1286,34 @@ static VMStateDescription ccid_vmstate = {
     }
 };
 
-static struct USBDeviceInfo ccid_info = {
-    .product_desc   = "QEMU USB CCID",
-    .qdev.name      = CCID_DEV_NAME,
-    .qdev.desc      = "CCID Rev 1.1 smartcard reader",
-    .qdev.size      = sizeof(USBCCIDState),
-    .init           = ccid_initfn,
-    .usb_desc       = &desc_ccid,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = ccid_handle_reset,
-    .handle_control = ccid_handle_control,
-    .handle_data    = ccid_handle_data,
-    .handle_destroy = ccid_handle_destroy,
-    .usbdevice_name = "ccid",
-    .qdev.props     = (Property[]) {
+static void ccid_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = ccid_initfn;
+    uc->product_desc   = "QEMU USB CCID";
+    uc->usb_desc       = &desc_ccid;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = ccid_handle_reset;
+    uc->handle_control = ccid_handle_control;
+    uc->handle_data    = ccid_handle_data;
+    uc->handle_destroy = ccid_handle_destroy;
+}
+
+static struct DeviceInfo ccid_info = {
+    .name      = CCID_DEV_NAME,
+    .desc      = "CCID Rev 1.1 smartcard reader",
+    .size      = sizeof(USBCCIDState),
+    .class_init= ccid_class_initfn,
+    .vmsd      = &ccid_vmstate,
+    .props     = (Property[]) {
         DEFINE_PROP_UINT8("debug", USBCCIDState, debug, 0),
         DEFINE_PROP_END_OF_LIST(),
     },
-    .qdev.vmsd      = &ccid_vmstate,
 };
 
 static void ccid_register_devices(void)
 {
-    usb_qdev_register(&ccid_info);
+    usb_qdev_register(&ccid_info, "ccid", NULL);
 }
 device_init(ccid_register_devices)
diff --git a/hw/usb-desc.c b/hw/usb-desc.c
index b3eb97b..3c3ed6a 100644
--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -297,8 +297,8 @@ static int usb_desc_set_interface(USBDevice *dev, int index, int value)
     dev->ifaces[index] = iface;
     usb_desc_ep_init(dev);
 
-    if (dev->info->set_interface && old != value) {
-        dev->info->set_interface(dev, index, old, value);
+    if (old != value) {
+        usb_device_set_interface(dev, index, old, value);
     }
     return 0;
 }
@@ -338,7 +338,7 @@ static int usb_desc_set_config(USBDevice *dev, int value)
 
 static void usb_desc_setdefaults(USBDevice *dev)
 {
-    const USBDesc *desc = dev->info->usb_desc;
+    const USBDesc *desc = usb_device_get_usb_desc(dev);
 
     assert(desc != NULL);
     switch (dev->speed) {
@@ -355,7 +355,7 @@ static void usb_desc_setdefaults(USBDevice *dev)
 
 void usb_desc_init(USBDevice *dev)
 {
-    const USBDesc *desc = dev->info->usb_desc;
+    const USBDesc *desc = usb_device_get_usb_desc(dev);
 
     assert(desc != NULL);
     dev->speed = USB_SPEED_FULL;
@@ -371,7 +371,7 @@ void usb_desc_init(USBDevice *dev)
 
 void usb_desc_attach(USBDevice *dev)
 {
-    const USBDesc *desc = dev->info->usb_desc;
+    const USBDesc *desc = usb_device_get_usb_desc(dev);
 
     assert(desc != NULL);
     if (desc->high && (dev->port->speedmask & USB_SPEED_MASK_HIGH)) {
@@ -380,7 +380,7 @@ void usb_desc_attach(USBDevice *dev)
         dev->speed = USB_SPEED_FULL;
     } else {
         fprintf(stderr, "usb: port/device speed mismatch for \"%s\"\n",
-                dev->info->product_desc);
+                usb_device_get_product_desc(dev));
         return;
     }
     usb_desc_setdefaults(dev);
@@ -436,7 +436,7 @@ int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len)
 
     str = usb_desc_get_string(dev, index);
     if (str == NULL) {
-        str = dev->info->usb_desc->str[index];
+        str = usb_device_get_usb_desc(dev)->str[index];
         if (str == NULL) {
             return 0;
         }
@@ -455,7 +455,7 @@ int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len)
 
 int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len)
 {
-    const USBDesc *desc = dev->info->usb_desc;
+    const USBDesc *desc = usb_device_get_usb_desc(dev);
     const USBDescDevice *other_dev;
     uint8_t buf[256];
     uint8_t type = value >> 8;
@@ -463,9 +463,9 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len
     int ret = -1;
 
     if (dev->speed == USB_SPEED_HIGH) {
-        other_dev = dev->info->usb_desc->full;
+        other_dev = usb_device_get_usb_desc(dev)->full;
     } else {
-        other_dev = dev->info->usb_desc->high;
+        other_dev = usb_device_get_usb_desc(dev)->high;
     }
 
     switch(type) {
@@ -520,7 +520,7 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len
 int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
         int request, int value, int index, int length, uint8_t *data)
 {
-    const USBDesc *desc = dev->info->usb_desc;
+    const USBDesc *desc = usb_device_get_usb_desc(dev);
     int ret = -1;
 
     assert(desc != NULL);
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 997f828..88fdd35 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -553,53 +553,73 @@ static const VMStateDescription vmstate_usb_kbd = {
     }
 };
 
-static struct USBDeviceInfo hid_info[] = {
-    {
-        .product_desc   = "QEMU USB Tablet",
-        .qdev.name      = "usb-tablet",
-        .usbdevice_name = "tablet",
-        .qdev.size      = sizeof(USBHIDState),
-        .qdev.vmsd      = &vmstate_usb_ptr,
-        .usb_desc       = &desc_tablet,
-        .init           = usb_tablet_initfn,
-        .handle_packet  = usb_generic_handle_packet,
-        .handle_reset   = usb_hid_handle_reset,
-        .handle_control = usb_hid_handle_control,
-        .handle_data    = usb_hid_handle_data,
-        .handle_destroy = usb_hid_handle_destroy,
-    },{
-        .product_desc   = "QEMU USB Mouse",
-        .qdev.name      = "usb-mouse",
-        .usbdevice_name = "mouse",
-        .qdev.size      = sizeof(USBHIDState),
-        .qdev.vmsd      = &vmstate_usb_ptr,
-        .usb_desc       = &desc_mouse,
-        .init           = usb_mouse_initfn,
-        .handle_packet  = usb_generic_handle_packet,
-        .handle_reset   = usb_hid_handle_reset,
-        .handle_control = usb_hid_handle_control,
-        .handle_data    = usb_hid_handle_data,
-        .handle_destroy = usb_hid_handle_destroy,
-    },{
-        .product_desc   = "QEMU USB Keyboard",
-        .qdev.name      = "usb-kbd",
-        .usbdevice_name = "keyboard",
-        .qdev.size      = sizeof(USBHIDState),
-        .qdev.vmsd      = &vmstate_usb_kbd,
-        .usb_desc       = &desc_keyboard,
-        .init           = usb_keyboard_initfn,
-        .handle_packet  = usb_generic_handle_packet,
-        .handle_reset   = usb_hid_handle_reset,
-        .handle_control = usb_hid_handle_control,
-        .handle_data    = usb_hid_handle_data,
-        .handle_destroy = usb_hid_handle_destroy,
-    },{
-        /* end of list */
-    }
+static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_tablet_initfn;
+    uc->product_desc   = "QEMU USB Tablet";
+    uc->usb_desc       = &desc_tablet;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_hid_handle_reset;
+    uc->handle_control = usb_hid_handle_control;
+    uc->handle_data    = usb_hid_handle_data;
+    uc->handle_destroy = usb_hid_handle_destroy;
+}
+
+static struct DeviceInfo usb_tablet_info = {
+    .name      = "usb-tablet",
+    .size      = sizeof(USBHIDState),
+    .vmsd      = &vmstate_usb_ptr,
+    .class_init= usb_tablet_class_initfn,
+};
+
+static void usb_mouse_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_mouse_initfn;
+    uc->product_desc   = "QEMU USB Mouse";
+    uc->usb_desc       = &desc_mouse;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_hid_handle_reset;
+    uc->handle_control = usb_hid_handle_control;
+    uc->handle_data    = usb_hid_handle_data;
+    uc->handle_destroy = usb_hid_handle_destroy;
+}
+
+static struct DeviceInfo usb_mouse_info = {
+    .name      = "usb-mouse",
+    .size      = sizeof(USBHIDState),
+    .vmsd      = &vmstate_usb_ptr,
+    .class_init= usb_mouse_class_initfn,
+};
+
+static void usb_keyboard_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_keyboard_initfn;
+    uc->product_desc   = "QEMU USB Keyboard";
+    uc->usb_desc       = &desc_keyboard;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_hid_handle_reset;
+    uc->handle_control = usb_hid_handle_control;
+    uc->handle_data    = usb_hid_handle_data;
+    uc->handle_destroy = usb_hid_handle_destroy;
+}
+
+static struct DeviceInfo usb_keyboard_info = {
+    .name      = "usb-kbd",
+    .size      = sizeof(USBHIDState),
+    .vmsd      = &vmstate_usb_kbd,
+    .class_init= usb_keyboard_class_initfn,
 };
 
 static void usb_hid_register_devices(void)
 {
-    usb_qdev_register_many(hid_info);
+    usb_qdev_register(&usb_tablet_info, "tablet", NULL);
+    usb_qdev_register(&usb_mouse_info, "mouse", NULL);
+    usb_qdev_register(&usb_keyboard_info, "keyboard", NULL);
 }
 device_init(usb_hid_register_devices)
diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index 069611b..ee4e6a6 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -533,23 +533,30 @@ static const VMStateDescription vmstate_usb_hub = {
     }
 };
 
-static struct USBDeviceInfo hub_info = {
-    .product_desc   = "QEMU USB Hub",
-    .qdev.name      = "usb-hub",
-    .qdev.fw_name    = "hub",
-    .qdev.size      = sizeof(USBHubState),
-    .qdev.vmsd      = &vmstate_usb_hub,
-    .usb_desc       = &desc_hub,
-    .init           = usb_hub_initfn,
-    .handle_packet  = usb_hub_handle_packet,
-    .handle_reset   = usb_hub_handle_reset,
-    .handle_control = usb_hub_handle_control,
-    .handle_data    = usb_hub_handle_data,
-    .handle_destroy = usb_hub_handle_destroy,
+static void  usb_hub_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_hub_initfn;
+    uc->product_desc   = "QEMU USB Hub";
+    uc->usb_desc       = &desc_hub;
+    uc->handle_packet  = usb_hub_handle_packet;
+    uc->handle_reset   = usb_hub_handle_reset;
+    uc->handle_control = usb_hub_handle_control;
+    uc->handle_data    = usb_hub_handle_data;
+    uc->handle_destroy = usb_hub_handle_destroy;
+}
+
+static struct DeviceInfo hub_info = {
+    .name      = "usb-hub",
+    .fw_name   = "hub",
+    .size      = sizeof(USBHubState),
+    .vmsd      = &vmstate_usb_hub,
+    .class_init= usb_hub_class_initfn,
 };
 
 static void usb_hub_register_devices(void)
 {
-    usb_qdev_register(&hub_info);
+    usb_qdev_register(&hub_info, NULL, NULL);
 }
 device_init(usb_hub_register_devices)
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index 186831d..ceb01e0 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -636,23 +636,28 @@ static const VMStateDescription vmstate_usb_msd = {
     }
 };
 
-static struct USBDeviceInfo msd_info = {
-    .product_desc   = "QEMU USB MSD",
-    .qdev.name      = "usb-storage",
-    .qdev.fw_name      = "storage",
-    .qdev.size      = sizeof(MSDState),
-    .qdev.vmsd      = &vmstate_usb_msd,
-    .usb_desc       = &desc,
-    .init           = usb_msd_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .cancel_packet  = usb_msd_cancel_io,
-    .handle_attach  = usb_desc_attach,
-    .handle_reset   = usb_msd_handle_reset,
-    .handle_control = usb_msd_handle_control,
-    .handle_data    = usb_msd_handle_data,
-    .usbdevice_name = "disk",
-    .usbdevice_init = usb_msd_init,
-    .qdev.props     = (Property[]) {
+static void usb_msd_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_msd_initfn;
+    uc->product_desc   = "QEMU USB MSD";
+    uc->usb_desc       = &desc;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->cancel_packet  = usb_msd_cancel_io;
+    uc->handle_attach  = usb_desc_attach;
+    uc->handle_reset   = usb_msd_handle_reset;
+    uc->handle_control = usb_msd_handle_control;
+    uc->handle_data    = usb_msd_handle_data;
+}
+
+static struct DeviceInfo msd_info = {
+    .name      = "usb-storage",
+    .fw_name   = "storage",
+    .size      = sizeof(MSDState),
+    .vmsd      = &vmstate_usb_msd,
+    .class_init= usb_msd_class_initfn,
+    .props     = (Property[]) {
         DEFINE_BLOCK_PROPERTIES(MSDState, conf),
         DEFINE_PROP_STRING("serial", MSDState, serial),
         DEFINE_PROP_BIT("removable", MSDState, removable, 0, false),
@@ -662,6 +667,6 @@ static struct USBDeviceInfo msd_info = {
 
 static void usb_msd_register_devices(void)
 {
-    usb_qdev_register(&msd_info);
+    usb_qdev_register(&msd_info, "disk", usb_msd_init);
 }
 device_init(usb_msd_register_devices)
diff --git a/hw/usb-net.c b/hw/usb-net.c
index fd4106b..57b58ac 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1385,29 +1385,34 @@ static const VMStateDescription vmstate_usb_net = {
     .unmigratable = 1,
 };
 
-static struct USBDeviceInfo net_info = {
-    .product_desc   = "QEMU USB Network Interface",
-    .qdev.name      = "usb-net",
-    .qdev.fw_name    = "network",
-    .qdev.size      = sizeof(USBNetState),
-    .qdev.vmsd      = &vmstate_usb_net,
-    .usb_desc       = &desc_net,
-    .init           = usb_net_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = usb_net_handle_reset,
-    .handle_control = usb_net_handle_control,
-    .handle_data    = usb_net_handle_data,
-    .handle_destroy = usb_net_handle_destroy,
-    .usbdevice_name = "net",
-    .usbdevice_init = usb_net_init,
-    .qdev.props     = (Property[]) {
+static void usb_net_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_net_initfn;
+    uc->product_desc   = "QEMU USB Network Interface";
+    uc->usb_desc       = &desc_net;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_net_handle_reset;
+    uc->handle_control = usb_net_handle_control;
+    uc->handle_data    = usb_net_handle_data;
+    uc->handle_destroy = usb_net_handle_destroy;
+}
+
+static struct DeviceInfo net_info = {
+    .name      = "usb-net",
+    .fw_name   = "network",
+    .size      = sizeof(USBNetState),
+    .vmsd      = &vmstate_usb_net,
+    .class_init= usb_net_class_initfn,
+    .props     = (Property[]) {
         DEFINE_NIC_PROPERTIES(USBNetState, conf),
         DEFINE_PROP_END_OF_LIST(),
-    }
+    },
 };
 
 static void usb_net_register_devices(void)
 {
-    usb_qdev_register(&net_info);
+    usb_qdev_register(&net_info, "net", usb_net_init);
 }
 device_init(usb_net_register_devices)
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
index e3c8238..de49607 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -570,41 +570,51 @@ static const VMStateDescription vmstate_usb_serial = {
     .unmigratable = 1,
 };
 
-static struct USBDeviceInfo serial_info = {
-    .product_desc   = "QEMU USB Serial",
-    .qdev.name      = "usb-serial",
-    .qdev.size      = sizeof(USBSerialState),
-    .qdev.vmsd      = &vmstate_usb_serial,
-    .usb_desc       = &desc_serial,
-    .init           = usb_serial_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = usb_serial_handle_reset,
-    .handle_control = usb_serial_handle_control,
-    .handle_data    = usb_serial_handle_data,
-    .handle_destroy = usb_serial_handle_destroy,
-    .usbdevice_name = "serial",
-    .usbdevice_init = usb_serial_init,
-    .qdev.props     = (Property[]) {
+static void usb_serial_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init = usb_serial_initfn;
+    uc->product_desc   = "QEMU USB Serial";
+    uc->usb_desc       = &desc_serial;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_serial_handle_reset;
+    uc->handle_control = usb_serial_handle_control;
+    uc->handle_data    = usb_serial_handle_data;
+    uc->handle_destroy = usb_serial_handle_destroy;
+}
+
+static struct DeviceInfo serial_info = {
+    .name      = "usb-serial",
+    .size      = sizeof(USBSerialState),
+    .vmsd      = &vmstate_usb_serial,
+    .class_init= usb_serial_class_initfn,
+    .props     = (Property[]) {
         DEFINE_PROP_CHR("chardev", USBSerialState, cs),
         DEFINE_PROP_END_OF_LIST(),
     },
 };
 
-static struct USBDeviceInfo braille_info = {
-    .product_desc   = "QEMU USB Braille",
-    .qdev.name      = "usb-braille",
-    .qdev.size      = sizeof(USBSerialState),
-    .qdev.vmsd      = &vmstate_usb_serial,
-    .usb_desc       = &desc_braille,
-    .init           = usb_serial_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = usb_serial_handle_reset,
-    .handle_control = usb_serial_handle_control,
-    .handle_data    = usb_serial_handle_data,
-    .handle_destroy = usb_serial_handle_destroy,
-    .usbdevice_name = "braille",
-    .usbdevice_init = usb_braille_init,
-    .qdev.props     = (Property[]) {
+static void usb_braille_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_serial_initfn;
+    uc->product_desc   = "QEMU USB Braille";
+    uc->usb_desc       = &desc_braille;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_serial_handle_reset;
+    uc->handle_control = usb_serial_handle_control;
+    uc->handle_data    = usb_serial_handle_data;
+    uc->handle_destroy = usb_serial_handle_destroy;
+}
+
+static struct DeviceInfo braille_info = {
+    .name      = "usb-braille",
+    .size      = sizeof(USBSerialState),
+    .vmsd      = &vmstate_usb_serial,
+    .class_init= usb_braille_class_initfn,
+    .props     = (Property[]) {
         DEFINE_PROP_CHR("chardev", USBSerialState, cs),
         DEFINE_PROP_END_OF_LIST(),
     },
@@ -612,7 +622,7 @@ static struct USBDeviceInfo braille_info = {
 
 static void usb_serial_register_devices(void)
 {
-    usb_qdev_register(&serial_info);
-    usb_qdev_register(&braille_info);
+    usb_qdev_register(&serial_info, "serial", usb_serial_init);
+    usb_qdev_register(&braille_info, "braille", usb_braille_init);
 }
 device_init(usb_serial_register_devices)
diff --git a/hw/usb-wacom.c b/hw/usb-wacom.c
index 61d5b18..9b20a31 100644
--- a/hw/usb-wacom.c
+++ b/hw/usb-wacom.c
@@ -349,24 +349,30 @@ static const VMStateDescription vmstate_usb_wacom = {
     .unmigratable = 1,
 };
 
-static struct USBDeviceInfo wacom_info = {
-    .product_desc   = "QEMU PenPartner Tablet",
-    .qdev.name      = "usb-wacom-tablet",
-    .qdev.desc      = "QEMU PenPartner Tablet",
-    .usbdevice_name = "wacom-tablet",
-    .usb_desc       = &desc_wacom,
-    .qdev.size      = sizeof(USBWacomState),
-    .qdev.vmsd      = &vmstate_usb_wacom,
-    .init           = usb_wacom_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = usb_wacom_handle_reset,
-    .handle_control = usb_wacom_handle_control,
-    .handle_data    = usb_wacom_handle_data,
-    .handle_destroy = usb_wacom_handle_destroy,
+static void usb_wacom_class_init(ObjectClass *class, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(class);
+
+    uc->product_desc   = "QEMU PenPartner Tablet";
+    uc->usb_desc       = &desc_wacom;
+    uc->init           = usb_wacom_initfn;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_wacom_handle_reset;
+    uc->handle_control = usb_wacom_handle_control;
+    uc->handle_data    = usb_wacom_handle_data;
+    uc->handle_destroy = usb_wacom_handle_destroy;
+}
+
+static struct DeviceInfo wacom_info = {
+    .name      = "usb-wacom-tablet",
+    .desc      = "QEMU PenPartner Tablet",
+    .size      = sizeof(USBWacomState),
+    .vmsd      = &vmstate_usb_wacom,
+    .class_init= usb_wacom_class_init,
 };
 
 static void usb_wacom_register_devices(void)
 {
-    usb_qdev_register(&wacom_info);
+    usb_qdev_register(&wacom_info, "wacom-tablet", NULL);
 }
 device_init(usb_wacom_register_devices)
diff --git a/hw/usb-xhci.c b/hw/usb-xhci.c
index 28fe9de..95bf010 100644
--- a/hw/usb-xhci.c
+++ b/hw/usb-xhci.c
@@ -1458,7 +1458,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
     if (!xfer->in_xfer) {
         xhci_xfer_data(xfer, xfer->data, wLength, 0, 1, 0);
     }
-    ret = dev->info->handle_control(dev, &xfer->packet,
+    ret = usb_device_handle_control(dev, &xfer->packet,
                                     (bmRequestType << 8) | bRequest,
                                     wValue, wIndex, wLength, xfer->data);
 
@@ -1767,7 +1767,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
         slot->devaddr = xhci->devaddr++;
         slot_ctx[3] = (SLOT_ADDRESSED << SLOT_STATE_SHIFT) | slot->devaddr;
         DPRINTF("xhci: device address is %d\n", slot->devaddr);
-        dev->info->handle_control(dev, NULL,
+        usb_device_handle_control(dev, NULL,
                                   DeviceOutRequest | USB_REQ_SET_ADDRESS,
                                   slot->devaddr, 0, 0, NULL);
     }
diff --git a/hw/usb.c b/hw/usb.c
index 860538a..c3ff5b7 100644
--- a/hw/usb.c
+++ b/hw/usb.c
@@ -95,8 +95,8 @@ static int do_token_setup(USBDevice *s, USBPacket *p)
     index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
 
     if (s->setup_buf[0] & USB_DIR_IN) {
-        ret = s->info->handle_control(s, p, request, value, index,
-                                      s->setup_len, s->data_buf);
+        ret = usb_device_handle_control(s, p, request, value, index,
+                                        s->setup_len, s->data_buf);
         if (ret == USB_RET_ASYNC) {
              s->setup_state = SETUP_STATE_SETUP;
              return USB_RET_ASYNC;
@@ -129,7 +129,7 @@ static int do_token_in(USBDevice *s, USBPacket *p)
     int ret = 0;
 
     if (p->devep != 0)
-        return s->info->handle_data(s, p);
+        return usb_device_handle_data(s, p);
 
     request = (s->setup_buf[0] << 8) | s->setup_buf[1];
     value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
@@ -138,8 +138,8 @@ static int do_token_in(USBDevice *s, USBPacket *p)
     switch(s->setup_state) {
     case SETUP_STATE_ACK:
         if (!(s->setup_buf[0] & USB_DIR_IN)) {
-            ret = s->info->handle_control(s, p, request, value, index,
-                                          s->setup_len, s->data_buf);
+            ret = usb_device_handle_control(s, p, request, value, index,
+                                            s->setup_len, s->data_buf);
             if (ret == USB_RET_ASYNC) {
                 return USB_RET_ASYNC;
             }
@@ -176,7 +176,7 @@ static int do_token_in(USBDevice *s, USBPacket *p)
 static int do_token_out(USBDevice *s, USBPacket *p)
 {
     if (p->devep != 0)
-        return s->info->handle_data(s, p);
+        return usb_device_handle_data(s, p);
 
     switch(s->setup_state) {
     case SETUP_STATE_ACK:
@@ -220,9 +220,7 @@ int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
     switch(p->pid) {
     case USB_MSG_ATTACH:
         s->state = USB_STATE_ATTACHED;
-        if (s->info->handle_attach) {
-            s->info->handle_attach(s);
-        }
+        usb_device_handle_attach(s);
         return 0;
 
     case USB_MSG_DETACH:
@@ -233,9 +231,7 @@ int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
         s->remote_wakeup = 0;
         s->addr = 0;
         s->state = USB_STATE_DEFAULT;
-        if (s->info->handle_reset) {
-            s->info->handle_reset(s);
-        }
+        usb_device_handle_reset(s);
         return 0;
     }
 
@@ -326,7 +322,7 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
     int ret;
 
     assert(p->owner == NULL);
-    ret = dev->info->handle_packet(dev, p);
+    ret = usb_device_handle_packet(dev, p);
     if (ret == USB_RET_ASYNC) {
         if (p->owner == NULL) {
             p->owner = usb_ep_get(dev, p->pid, p->devep);
@@ -357,7 +353,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
 void usb_cancel_packet(USBPacket * p)
 {
     assert(p->owner != NULL);
-    p->owner->dev->info->cancel_packet(p->owner->dev, p);
+    usb_device_cancel_packet(p->owner->dev, p);
     p->owner = NULL;
 }
 
diff --git a/hw/usb.h b/hw/usb.h
index 37f7d96..5b9badb 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -1,3 +1,6 @@
+#ifndef QEMU_USB_H
+#define QEMU_USB_H
+
 /*
  * QEMU USB API
  *
@@ -150,7 +153,6 @@ typedef struct USBBus USBBus;
 typedef struct USBBusOps USBBusOps;
 typedef struct USBPort USBPort;
 typedef struct USBDevice USBDevice;
-typedef struct USBDeviceInfo USBDeviceInfo;
 typedef struct USBPacket USBPacket;
 typedef struct USBEndpoint USBEndpoint;
 
@@ -183,7 +185,6 @@ struct USBEndpoint {
 /* definition of a USB device */
 struct USBDevice {
     DeviceState qdev;
-    USBDeviceInfo *info;
     USBPort *port;
     char *port_path;
     void *opaque;
@@ -219,8 +220,17 @@ struct USBDevice {
     const USBDescIface  *ifaces[USB_MAX_INTERFACES];
 };
 
-struct USBDeviceInfo {
-    DeviceInfo qdev;
+#define TYPE_USB_DEVICE "usb-device"
+#define USB_DEVICE(obj) \
+     OBJECT_CHECK(USBDevice, (obj), TYPE_USB_DEVICE)
+#define USB_DEVICE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(USBDeviceClass, (klass), TYPE_USB_DEVICE)
+#define USB_DEVICE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(USBDeviceClass, (obj), TYPE_USB_DEVICE)
+
+typedef struct USBDeviceClass {
+    DeviceClass parent_class;
+
     int (*init)(USBDevice *dev);
 
     /*
@@ -274,11 +284,7 @@ struct USBDeviceInfo {
 
     const char *product_desc;
     const USBDesc *usb_desc;
-
-    /* handle legacy -usbdevice command line options */
-    const char *usbdevice_name;
-    USBDevice *(*usbdevice_init)(const char *params);
-};
+} USBDeviceClass;
 
 typedef struct USBPortOps {
     void (*attach)(USBPort *port);
@@ -412,8 +418,9 @@ struct USBBusOps {
 
 void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host);
 USBBus *usb_bus_find(int busnr);
-void usb_qdev_register(USBDeviceInfo *info);
-void usb_qdev_register_many(USBDeviceInfo *info);
+void usb_qdev_register(DeviceInfo *info,
+                       const char *usbdevice_name,
+                       USBDevice *(*usbdevice_init)(const char *params));
 USBDevice *usb_create(USBBus *bus, const char *name);
 USBDevice *usb_create_simple(USBBus *bus, const char *name);
 USBDevice *usbdevice_create(const char *cmdline);
@@ -445,4 +452,25 @@ extern const VMStateDescription vmstate_usb_device;
     .offset     = vmstate_offset_value(_state, _field, USBDevice),   \
 }
 
+int usb_device_handle_packet(USBDevice *dev, USBPacket *p);
+
+void usb_device_cancel_packet(USBDevice *dev, USBPacket *p);
+
+void usb_device_handle_attach(USBDevice *dev);
+
+void usb_device_handle_reset(USBDevice *dev);
+
+int usb_device_handle_control(USBDevice *dev, USBPacket *p, int request, int value,
+                              int index, int length, uint8_t *data);
+
+int usb_device_handle_data(USBDevice *dev, USBPacket *p);
+
+void usb_device_set_interface(USBDevice *dev, int interface,
+                              int alt_old, int alt_new);
+
+const char *usb_device_get_product_desc(USBDevice *dev);
+
+const USBDesc *usb_device_get_usb_desc(USBDevice *dev);
+
+#endif
 
diff --git a/usb-bsd.c b/usb-bsd.c
index 1187552..2c6afc8 100644
--- a/usb-bsd.c
+++ b/usb-bsd.c
@@ -397,21 +397,28 @@ fail:
     return ret;
 }
 
-static struct USBDeviceInfo usb_host_dev_info = {
-    .product_desc   = "USB Host Device",
-    .qdev.name      = "usb-host",
-    .qdev.size      = sizeof(USBHostDevice),
-    .init           = usb_host_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .handle_reset   = usb_host_handle_reset,
-    .handle_control = usb_host_handle_control,
-    .handle_data    = usb_host_handle_data,
-    .handle_destroy = usb_host_handle_destroy,
+static void usb_host_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->product_desc   = "USB Host Device";
+    uc->init           = usb_host_initfn;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->handle_reset   = usb_host_handle_reset;
+    uc->handle_control = usb_host_handle_control;
+    uc->handle_data    = usb_host_handle_data;
+    uc->handle_destroy = usb_host_handle_destroy;
+}
+
+static struct DeviceInfo usb_host_dev_info = {
+    .name      = "usb-host",
+    .size      = sizeof(USBHostDevice),
+    .class_init= usb_host_initfn,
 };
 
 static void usb_host_register_devices(void)
 {
-    usb_qdev_register(&usb_host_dev_info);
+    usb_qdev_register(&usb_host_dev_info, NULL, NULL);
 }
 device_init(usb_host_register_devices)
 
diff --git a/usb-linux.c b/usb-linux.c
index 56898dd..31810f6 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -1402,21 +1402,26 @@ static const VMStateDescription vmstate_usb_host = {
     .unmigratable = 1,
 };
 
-static struct USBDeviceInfo usb_host_dev_info = {
-    .product_desc   = "USB Host Device",
-    .qdev.name      = "usb-host",
-    .qdev.size      = sizeof(USBHostDevice),
-    .qdev.vmsd      = &vmstate_usb_host,
-    .init           = usb_host_initfn,
-    .handle_packet  = usb_generic_handle_packet,
-    .cancel_packet  = usb_host_async_cancel,
-    .handle_data    = usb_host_handle_data,
-    .handle_control = usb_host_handle_control,
-    .handle_reset   = usb_host_handle_reset,
-    .handle_destroy = usb_host_handle_destroy,
-    .usbdevice_name = "host",
-    .usbdevice_init = usb_host_device_open,
-    .qdev.props     = (Property[]) {
+static void usb_host_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usb_host_initfn;
+    uc->product_desc   = "USB Host Device";
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->cancel_packet  = usb_host_async_cancel;
+    uc->handle_data    = usb_host_handle_data;
+    uc->handle_control = usb_host_handle_control;
+    uc->handle_reset   = usb_host_handle_reset;
+    uc->handle_destroy = usb_host_handle_destroy;
+}
+
+static struct DeviceInfo usb_host_dev_info = {
+    .name      = "usb-host",
+    .size      = sizeof(USBHostDevice),
+    .vmsd      = &vmstate_usb_host,
+    .class_init= usb_host_class_initfn,
+    .props     = (Property[]) {
         DEFINE_PROP_UINT32("hostbus",  USBHostDevice, match.bus_num,    0),
         DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr,       0),
         DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
@@ -1429,7 +1434,7 @@ static struct USBDeviceInfo usb_host_dev_info = {
 
 static void usb_host_register_devices(void)
 {
-    usb_qdev_register(&usb_host_dev_info);
+    usb_qdev_register(&usb_host_dev_info, "host", usb_host_device_open);
 }
 device_init(usb_host_register_devices)
 
diff --git a/usb-redir.c b/usb-redir.c
index 79d29ec..8f4a29a 100644
--- a/usb-redir.c
+++ b/usb-redir.c
@@ -1315,18 +1315,25 @@ static void usbredir_interrupt_packet(void *priv, uint32_t id,
     }
 }
 
-static struct USBDeviceInfo usbredir_dev_info = {
-    .product_desc   = "USB Redirection Device",
-    .qdev.name      = "usb-redir",
-    .qdev.size      = sizeof(USBRedirDevice),
-    .init           = usbredir_initfn,
-    .handle_destroy = usbredir_handle_destroy,
-    .handle_packet  = usb_generic_handle_packet,
-    .cancel_packet  = usbredir_cancel_packet,
-    .handle_reset   = usbredir_handle_reset,
-    .handle_data    = usbredir_handle_data,
-    .handle_control = usbredir_handle_control,
-    .qdev.props     = (Property[]) {
+static void usbredir_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->init           = usbredir_initfn;
+    uc->product_desc   = "USB Redirection Device";
+    uc->handle_destroy = usbredir_handle_destroy;
+    uc->handle_packet  = usb_generic_handle_packet;
+    uc->cancel_packet  = usbredir_cancel_packet;
+    uc->handle_reset   = usbredir_handle_reset;
+    uc->handle_data    = usbredir_handle_data;
+    uc->handle_control = usbredir_handle_control;
+}
+
+static struct DeviceInfo usbredir_dev_info = {
+    .name      = "usb-redir",
+    .size      = sizeof(USBRedirDevice),
+    .class_init= usbredir_class_initfn,
+    .props     = (Property[]) {
         DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
         DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
         DEFINE_PROP_END_OF_LIST(),
@@ -1335,6 +1342,6 @@ static struct USBDeviceInfo usbredir_dev_info = {
 
 static void usbredir_register_devices(void)
 {
-    usb_qdev_register(&usbredir_dev_info);
+    usb_qdev_register(&usbredir_dev_info, NULL, NULL);
 }
 device_init(usbredir_register_devices);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 14/28] ccid: convert to QEMU Object Model
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (12 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 13/28] usb: " Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 15/28] ssi: " Anthony Liguori
                   ` (16 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/ccid-card-emulated.c |   27 ++++++++++------
 hw/ccid-card-passthru.c |   27 ++++++++++------
 hw/ccid.h               |   28 +++++++++++------
 hw/usb-ccid.c           |   76 +++++++++++++++++++++++++++++++++++------------
 4 files changed, 109 insertions(+), 49 deletions(-)

diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c
index 2d2ebce..6dabe7a 100644
--- a/hw/ccid-card-emulated.c
+++ b/hw/ccid-card-emulated.c
@@ -564,16 +564,23 @@ static int emulated_exitfn(CCIDCardState *base)
     return 0;
 }
 
-static CCIDCardInfo emulated_card_info = {
-    .qdev.name = EMULATED_DEV_NAME,
-    .qdev.desc = "emulated smartcard",
-    .qdev.size = sizeof(EmulatedState),
-    .initfn = emulated_initfn,
-    .exitfn = emulated_exitfn,
-    .get_atr = emulated_get_atr,
-    .apdu_from_guest = emulated_apdu_from_guest,
-    .qdev.unplug    = qdev_simple_unplug_cb,
-    .qdev.props     = (Property[]) {
+static void emulated_class_initfn(ObjectClass *klass, void *data)
+{
+    CCIDCardClass *cc = CCID_CARD_CLASS(klass);
+
+    cc->initfn = emulated_initfn;
+    cc->exitfn = emulated_exitfn;
+    cc->get_atr = emulated_get_atr;
+    cc->apdu_from_guest = emulated_apdu_from_guest;
+}
+
+static DeviceInfo emulated_card_info = {
+    .name = EMULATED_DEV_NAME,
+    .desc = "emulated smartcard",
+    .size = sizeof(EmulatedState),
+    .unplug    = qdev_simple_unplug_cb,
+    .class_init = emulated_class_initfn,
+    .props     = (Property[]) {
         DEFINE_PROP_STRING("backend", EmulatedState, backend_str),
         DEFINE_PROP_STRING("cert1", EmulatedState, cert1),
         DEFINE_PROP_STRING("cert2", EmulatedState, cert2),
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
index 9f51c6c..f563d97 100644
--- a/hw/ccid-card-passthru.c
+++ b/hw/ccid-card-passthru.c
@@ -316,16 +316,23 @@ static VMStateDescription passthru_vmstate = {
     }
 };
 
-static CCIDCardInfo passthru_card_info = {
-    .qdev.name = PASSTHRU_DEV_NAME,
-    .qdev.desc = "passthrough smartcard",
-    .qdev.size = sizeof(PassthruState),
-    .qdev.vmsd = &passthru_vmstate,
-    .initfn = passthru_initfn,
-    .exitfn = passthru_exitfn,
-    .get_atr = passthru_get_atr,
-    .apdu_from_guest = passthru_apdu_from_guest,
-    .qdev.props     = (Property[]) {
+static void passthru_class_initfn(ObjectClass *klass, void *data)
+{
+    CCIDCardClass *cc = CCID_CARD_CLASS(klass);
+
+    cc->initfn = passthru_initfn;
+    cc->exitfn = passthru_exitfn;
+    cc->get_atr = passthru_get_atr;
+    cc->apdu_from_guest = passthru_apdu_from_guest;
+}
+
+static DeviceInfo passthru_card_info = {
+    .name = PASSTHRU_DEV_NAME,
+    .desc = "passthrough smartcard",
+    .size = sizeof(PassthruState),
+    .vmsd = &passthru_vmstate,
+    .class_init = passthru_class_initfn,
+    .props     = (Property[]) {
         DEFINE_PROP_CHR("chardev", PassthruState, cs),
         DEFINE_PROP_UINT8("debug", PassthruState, debug, 0),
         DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/ccid.h b/hw/ccid.h
index 9e3abe1..9e4979c 100644
--- a/hw/ccid.h
+++ b/hw/ccid.h
@@ -15,26 +15,34 @@
 typedef struct CCIDCardState CCIDCardState;
 typedef struct CCIDCardInfo CCIDCardInfo;
 
-/*
- * state of the CCID Card device (i.e. hw/ccid-card-*.c)
- */
-struct CCIDCardState {
-    DeviceState qdev;
-    uint32_t    slot; /* For future use with multiple slot reader. */
-};
+#define TYPE_CCID_CARD "ccid-card"
+#define CCID_CARD(obj) \
+     OBJECT_CHECK(CCIDCardState, (obj), TYPE_CCID_CARD)
+#define CCID_CARD_CLASS(klass) \
+     OBJECT_CLASS_CHECK(CCIDCardClass, (klass), TYPE_CCID_CARD)
+#define CCID_CARD_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(CCIDCardClass, (obj), TYPE_CCID_CARD)
 
 /*
  * callbacks to be used by the CCID device (hw/usb-ccid.c) to call
  * into the smartcard device (hw/ccid-card-*.c)
  */
-struct CCIDCardInfo {
-    DeviceInfo qdev;
+typedef struct CCIDCardClass {
+    DeviceClass parent_class;
     const uint8_t *(*get_atr)(CCIDCardState *card, uint32_t *len);
     void (*apdu_from_guest)(CCIDCardState *card,
                             const uint8_t *apdu,
                             uint32_t len);
     int (*exitfn)(CCIDCardState *card);
     int (*initfn)(CCIDCardState *card);
+} CCIDCardClass;
+
+/*
+ * state of the CCID Card device (i.e. hw/ccid-card-*.c)
+ */
+struct CCIDCardState {
+    DeviceState qdev;
+    uint32_t    slot; /* For future use with multiple slot reader. */
 };
 
 /*
@@ -46,7 +54,7 @@ void ccid_card_send_apdu_to_guest(CCIDCardState *card,
 void ccid_card_card_removed(CCIDCardState *card);
 void ccid_card_card_inserted(CCIDCardState *card);
 void ccid_card_card_error(CCIDCardState *card, uint64_t error);
-void ccid_card_qdev_register(CCIDCardInfo *card);
+void ccid_card_qdev_register(DeviceInfo *card);
 
 /*
  * support guest visible insertion/removal of ccid devices based on actual
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index eb63dfc..aff81fa 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -269,7 +269,6 @@ typedef struct USBCCIDState {
     USBDevice dev;
     CCIDBus bus;
     CCIDCardState *card;
-    CCIDCardInfo *cardinfo; /* caching the info pointer */
     BulkIn bulk_in_pending[BULK_IN_PENDING_NUM]; /* circular */
     uint32_t bulk_in_pending_start;
     uint32_t bulk_in_pending_end; /* first free */
@@ -468,6 +467,43 @@ static const USBDesc desc_ccid = {
     .str  = desc_strings,
 };
 
+static const uint8_t *ccid_card_get_atr(CCIDCardState *card, uint32_t *len)
+{
+    CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
+    if (cc->get_atr) {
+        return cc->get_atr(card, len);
+    }
+    return NULL;
+}
+
+static void ccid_card_apdu_from_guest(CCIDCardState *card,
+                                      const uint8_t *apdu,
+                                      uint32_t len)
+{
+    CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
+    if (cc->apdu_from_guest) {
+        cc->apdu_from_guest(card, apdu, len);
+    }
+}
+
+static int ccid_card_exitfn(CCIDCardState *card)
+{
+    CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
+    if (cc->exitfn) {
+        return cc->exitfn(card);
+    }
+    return 0;
+}
+
+static int ccid_card_initfn(CCIDCardState *card)
+{
+    CCIDCardClass *cc = CCID_CARD_GET_CLASS(card);
+    if (cc->initfn) {
+        return cc->initfn(card);
+    }
+    return 0;
+}
+
 static bool ccid_has_pending_answers(USBCCIDState *s)
 {
     return s->pending_answers_num > 0;
@@ -741,7 +777,7 @@ static void ccid_write_data_block_atr(USBCCIDState *s, CCID_Header *recv)
     uint32_t len = 0;
 
     if (s->card) {
-        atr = s->cardinfo->get_atr(s->card, &len);
+        atr = ccid_card_get_atr(s->card, &len);
     }
     ccid_write_data_block(s, recv->bSlot, recv->bSeq, atr, len);
 }
@@ -827,7 +863,7 @@ static void ccid_on_apdu_from_guest(USBCCIDState *s, CCID_XferBlock *recv)
                 recv->hdr.bSeq, len);
     ccid_add_pending_answer(s, (CCID_Header *)recv);
     if (s->card) {
-        s->cardinfo->apdu_from_guest(s->card, recv->abData, len);
+        ccid_card_apdu_from_guest(s->card, recv->abData, len);
     } else {
         DPRINTF(s, D_WARN, "warning: discarded apdu\n");
     }
@@ -1113,26 +1149,21 @@ void ccid_card_card_inserted(CCIDCardState *card)
 static int ccid_card_exit(DeviceState *qdev)
 {
     int ret = 0;
-    CCIDCardState *card = DO_UPCAST(CCIDCardState, qdev, qdev);
-    CCIDCardInfo *info = DO_UPCAST(CCIDCardInfo, qdev, qdev_get_info(qdev));
+    CCIDCardState *card = CCID_CARD(qdev);
     USBCCIDState *s =
         DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent);
 
     if (ccid_card_inserted(s)) {
         ccid_card_card_removed(card);
     }
-    if (info->exitfn) {
-        ret = info->exitfn(card);
-    }
+    ret = ccid_card_exitfn(card);
     s->card = NULL;
-    s->cardinfo = NULL;
     return ret;
 }
 
 static int ccid_card_init(DeviceState *qdev, DeviceInfo *base)
 {
-    CCIDCardState *card = DO_UPCAST(CCIDCardState, qdev, qdev);
-    CCIDCardInfo *info = DO_UPCAST(CCIDCardInfo, qdev, base);
+    CCIDCardState *card = CCID_CARD(qdev);
     USBCCIDState *s =
         DO_UPCAST(USBCCIDState, dev.qdev, card->qdev.parent_bus->parent);
     int ret = 0;
@@ -1146,20 +1177,19 @@ static int ccid_card_init(DeviceState *qdev, DeviceInfo *base)
         error_report("Warning: usb-ccid card already full, not adding");
         return -1;
     }
-    ret = info->initfn ? info->initfn(card) : ret;
+    ret = ccid_card_initfn(card);
     if (ret == 0) {
         s->card = card;
-        s->cardinfo = info;
     }
     return ret;
 }
 
-void ccid_card_qdev_register(CCIDCardInfo *card)
+void ccid_card_qdev_register(DeviceInfo *info)
 {
-    card->qdev.bus_info = &ccid_bus_info;
-    card->qdev.init = ccid_card_init;
-    card->qdev.exit = ccid_card_exit;
-    qdev_register(&card->qdev);
+    info->bus_info = &ccid_bus_info;
+    info->init = ccid_card_init;
+    info->exit = ccid_card_exit;
+    qdev_register_subclass(info, TYPE_CCID_CARD);
 }
 
 static int ccid_initfn(USBDevice *dev)
@@ -1170,7 +1200,6 @@ static int ccid_initfn(USBDevice *dev)
     qbus_create_inplace(&s->bus.qbus, &ccid_bus_info, &dev->qdev, NULL);
     s->bus.qbus.allow_hotplug = 1;
     s->card = NULL;
-    s->cardinfo = NULL;
     s->migration_state = MIGRATION_NONE;
     s->migration_target_ip = 0;
     s->migration_target_port = 0;
@@ -1312,8 +1341,17 @@ static struct DeviceInfo ccid_info = {
     },
 };
 
+static TypeInfo ccid_card_type_info = {
+    .name = TYPE_CCID_CARD,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(CCIDCardState),
+    .abstract = true,
+    .class_size = sizeof(CCIDCardClass),
+};
+
 static void ccid_register_devices(void)
 {
+    type_register_static(&ccid_card_type_info);
     usb_qdev_register(&ccid_info, "ccid", NULL);
 }
 device_init(ccid_register_devices)
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 15/28] ssi: convert to QEMU Object Model
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (13 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 14/28] ccid: " Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 16/28] i2c: rename i2c_slave -> I2CSlave Anthony Liguori
                   ` (15 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Anthony Liguori, Paul Brook

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/ads7846.c   |   17 ++++++++++++-----
 hw/max111x.c   |   34 ++++++++++++++++++++++++----------
 hw/spitz.c     |   39 +++++++++++++++++++++++++++------------
 hw/ssd0323.c   |   17 ++++++++++++-----
 hw/ssi-sd.c    |   17 ++++++++++++-----
 hw/ssi.c       |   23 ++++++++++++-----------
 hw/ssi.h       |   18 +++++++++++++-----
 hw/stellaris.c |   17 ++++++++++++-----
 hw/tosa.c      |   19 +++++++++++++------
 hw/z2.c        |   19 +++++++++++++------
 10 files changed, 150 insertions(+), 70 deletions(-)

diff --git a/hw/ads7846.c b/hw/ads7846.c
index de3f7af..c1b894e 100644
--- a/hw/ads7846.c
+++ b/hw/ads7846.c
@@ -153,11 +153,18 @@ static int ads7846_init(SSISlave *dev)
     return 0;
 }
 
-static SSISlaveInfo ads7846_info = {
-    .qdev.name ="ads7846",
-    .qdev.size = sizeof(ADS7846State),
-    .init = ads7846_init,
-    .transfer = ads7846_transfer
+static void ads7846_class_init(ObjectClass *klass, void *data)
+{
+    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+
+    k->init = ads7846_init;
+    k->transfer = ads7846_transfer;
+}
+
+static DeviceInfo ads7846_info = {
+    .name = "ads7846",
+    .size = sizeof(ADS7846State),
+    .class_init = ads7846_class_init,
 };
 
 static void ads7846_register_devices(void)
diff --git a/hw/max111x.c b/hw/max111x.c
index fc79814..db17842 100644
--- a/hw/max111x.c
+++ b/hw/max111x.c
@@ -153,18 +153,32 @@ void max111x_set_input(DeviceState *dev, int line, uint8_t value)
     s->input[line] = value;
 }
 
-static SSISlaveInfo max1110_info = {
-    .qdev.name = "max1110",
-    .qdev.size = sizeof(MAX111xState),
-    .init = max1110_init,
-    .transfer = max111x_transfer
+static void max1110_class_init(ObjectClass *klass, void *data)
+{
+    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+
+    k->init = max1110_init;
+    k->transfer = max111x_transfer;
+}
+
+static DeviceInfo max1110_info = {
+    .name = "max1110",
+    .size = sizeof(MAX111xState),
+    .class_init = max1110_class_init,
 };
 
-static SSISlaveInfo max1111_info = {
-    .qdev.name = "max1111",
-    .qdev.size = sizeof(MAX111xState),
-    .init = max1111_init,
-    .transfer = max111x_transfer
+static void max1111_class_init(ObjectClass *klass, void *data)
+{
+    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+
+    k->init = max1111_init;
+    k->transfer = max111x_transfer;
+}
+
+static DeviceInfo max1111_info = {
+    .name = "max1111",
+    .size = sizeof(MAX111xState),
+    .class_init = max1111_class_init,
 };
 
 static void max111x_register_devices(void)
diff --git a/hw/spitz.c b/hw/spitz.c
index 9d129c2..0f63139 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -1070,12 +1070,20 @@ static const VMStateDescription vmstate_corgi_ssp_regs = {
     }
 };
 
-static SSISlaveInfo corgi_ssp_info = {
-    .qdev.name = "corgi-ssp",
-    .qdev.size = sizeof(CorgiSSPState),
-    .qdev.vmsd = &vmstate_corgi_ssp_regs,
-    .init = corgi_ssp_init,
-    .transfer = corgi_ssp_transfer
+static void corgi_ssp_class_init(ObjectClass *klass, void *data)
+{
+    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+
+    k->init = corgi_ssp_init;
+    k->transfer = corgi_ssp_transfer;
+}
+
+
+static DeviceInfo corgi_ssp_info = {
+    .name = "corgi-ssp",
+    .size = sizeof(CorgiSSPState),
+    .vmsd = &vmstate_corgi_ssp_regs,
+    .class_init = corgi_ssp_class_init,
 };
 
 static const VMStateDescription vmstate_spitz_lcdtg_regs = {
@@ -1090,12 +1098,19 @@ static const VMStateDescription vmstate_spitz_lcdtg_regs = {
     }
 };
 
-static SSISlaveInfo spitz_lcdtg_info = {
-    .qdev.name = "spitz-lcdtg",
-    .qdev.size = sizeof(SpitzLCDTG),
-    .qdev.vmsd = &vmstate_spitz_lcdtg_regs,
-    .init = spitz_lcdtg_init,
-    .transfer = spitz_lcdtg_transfer
+static void spitz_lcdtg_class_init(ObjectClass *klass, void *data)
+{
+    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+
+    k->init = spitz_lcdtg_init;
+    k->transfer = spitz_lcdtg_transfer;
+}
+
+static DeviceInfo spitz_lcdtg_info = {
+    .name = "spitz-lcdtg",
+    .size = sizeof(SpitzLCDTG),
+    .vmsd = &vmstate_spitz_lcdtg_regs,
+    .class_init = spitz_lcdtg_class_init,
 };
 
 static void spitz_register_devices(void)
diff --git a/hw/ssd0323.c b/hw/ssd0323.c
index 1eb3823..8e2fac8 100644
--- a/hw/ssd0323.c
+++ b/hw/ssd0323.c
@@ -340,11 +340,18 @@ static int ssd0323_init(SSISlave *dev)
     return 0;
 }
 
-static SSISlaveInfo ssd0323_info = {
-    .qdev.name = "ssd0323",
-    .qdev.size = sizeof(ssd0323_state),
-    .init = ssd0323_init,
-    .transfer = ssd0323_transfer
+static void ssd0323_class_init(ObjectClass *klass, void *data)
+{
+    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+
+    k->init = ssd0323_init;
+    k->transfer = ssd0323_transfer;
+}
+
+static DeviceInfo ssd0323_info = {
+    .name = "ssd0323",
+    .size = sizeof(ssd0323_state),
+    .class_init = ssd0323_class_init,
 };
 
 static void ssd03232_register_devices(void)
diff --git a/hw/ssi-sd.c b/hw/ssi-sd.c
index 2d89cfe..2738cf9 100644
--- a/hw/ssi-sd.c
+++ b/hw/ssi-sd.c
@@ -244,11 +244,18 @@ static int ssi_sd_init(SSISlave *dev)
     return 0;
 }
 
-static SSISlaveInfo ssi_sd_info = {
-    .qdev.name = "ssi-sd",
-    .qdev.size = sizeof(ssi_sd_state),
-    .init = ssi_sd_init,
-    .transfer = ssi_sd_transfer
+static void ssi_sd_class_init(ObjectClass *klass, void *data)
+{
+    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+
+    k->init = ssi_sd_init;
+    k->transfer = ssi_sd_transfer;
+}
+
+static DeviceInfo ssi_sd_info = {
+    .name = "ssi-sd",
+    .size = sizeof(ssi_sd_state),
+    .class_init = ssi_sd_class_init,
 };
 
 static void ssi_sd_register_devices(void)
diff --git a/hw/ssi.c b/hw/ssi.c
index b47953a..99a0616 100644
--- a/hw/ssi.c
+++ b/hw/ssi.c
@@ -23,8 +23,8 @@ static struct BusInfo ssi_bus_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);
+    SSISlave *s = SSI_SLAVE(dev);
+    SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(s);
     SSIBus *bus;
 
     bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev));
@@ -33,16 +33,15 @@ static int ssi_slave_init(DeviceState *dev, DeviceInfo *base_info)
         hw_error("Too many devices on SSI bus");
     }
 
-    s->info = info;
-    return info->init(s);
+    return ssc->init(s);
 }
 
-void ssi_register_slave(SSISlaveInfo *info)
+void ssi_register_slave(DeviceInfo *info)
 {
-    assert(info->qdev.size >= sizeof(SSISlave));
-    info->qdev.init = ssi_slave_init;
-    info->qdev.bus_info = &ssi_bus_info;
-    qdev_register(&info->qdev);
+    assert(info->size >= sizeof(SSISlave));
+    info->init = ssi_slave_init;
+    info->bus_info = &ssi_bus_info;
+    qdev_register(info);
 }
 
 DeviceState *ssi_create_slave(SSIBus *bus, const char *name)
@@ -64,10 +63,12 @@ uint32_t ssi_transfer(SSIBus *bus, uint32_t val)
 {
     DeviceState *dev;
     SSISlave *slave;
+    SSISlaveClass *ssc;
     dev = QTAILQ_FIRST(&bus->qbus.children);
     if (!dev) {
         return 0;
     }
-    slave = SSI_SLAVE_FROM_QDEV(dev);
-    return slave->info->transfer(slave, val);
+    slave = SSI_SLAVE(dev);
+    ssc = SSI_SLAVE_GET_CLASS(slave);
+    return ssc->transfer(slave, val);
 }
diff --git a/hw/ssi.h b/hw/ssi.h
index 24610a8..97aefa7 100644
--- a/hw/ssi.h
+++ b/hw/ssi.h
@@ -15,22 +15,30 @@
 
 typedef struct SSISlave SSISlave;
 
+#define TYPE_SSI_SLAVE "ssi-slave"
+#define SSI_SLAVE(obj) \
+     OBJECT_CHECK(SSISlave, (obj), TYPE_SSI_SLAVE)
+#define SSI_SLAVE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(SSISlaveClass, (klass), TYPE_SSI_SLAVE)
+#define SSI_SLAVE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(SSISlaveClass, (obj), TYPE_SSI_SLAVE)
+
 /* Slave devices.  */
-typedef struct {
-    DeviceInfo qdev;
+typedef struct SSISlaveClass {
+    DeviceClass parent_class;
+
     int (*init)(SSISlave *dev);
     uint32_t (*transfer)(SSISlave *dev, uint32_t val);
-} SSISlaveInfo;
+} SSISlaveClass;
 
 struct SSISlave {
     DeviceState qdev;
-    SSISlaveInfo *info;
 };
 
 #define SSI_SLAVE_FROM_QDEV(dev) DO_UPCAST(SSISlave, qdev, dev)
 #define FROM_SSI_SLAVE(type, dev) DO_UPCAST(type, ssidev, dev)
 
-void ssi_register_slave(SSISlaveInfo *info);
+void ssi_register_slave(DeviceInfo *info);
 
 DeviceState *ssi_create_slave(SSIBus *bus, const char *name);
 
diff --git a/hw/stellaris.c b/hw/stellaris.c
index 7a73074..a1620cb 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -1394,11 +1394,18 @@ static void stellaris_machine_init(void)
 
 machine_init(stellaris_machine_init);
 
-static SSISlaveInfo stellaris_ssi_bus_info = {
-    .qdev.name = "evb6965-ssi",
-    .qdev.size = sizeof(stellaris_ssi_bus_state),
-    .init = stellaris_ssi_bus_init,
-    .transfer = stellaris_ssi_bus_transfer
+static void stellaris_ssi_bus_class_init(ObjectClass *klass, void *data)
+{
+    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+
+    k->init = stellaris_ssi_bus_init;
+    k->transfer = stellaris_ssi_bus_transfer;
+}
+
+static DeviceInfo stellaris_ssi_bus_info = {
+    .name = "evb6965-ssi",
+    .size = sizeof(stellaris_ssi_bus_state),
+    .class_init = stellaris_ssi_bus_class_init,
 };
 
 static void stellaris_register_devices(void)
diff --git a/hw/tosa.c b/hw/tosa.c
index 0caba79..ade4cf6 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -266,13 +266,20 @@ static I2CSlaveInfo tosa_dac_info = {
     .event = tosa_dac_event,
     .recv = tosa_dac_recv,
     .send = tosa_dac_send
-};
+ };
+
+static void tosa_ssp_class_init(ObjectClass *klass, void *data)
+{
+    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+
+    k->init = tosa_ssp_init;
+    k->transfer = tosa_ssp_tansfer;
+}
 
-static SSISlaveInfo tosa_ssp_info = {
-    .qdev.name = "tosa-ssp",
-    .qdev.size = sizeof(SSISlave),
-    .init = tosa_ssp_init,
-    .transfer = tosa_ssp_tansfer
+static DeviceInfo tosa_ssp_info = {
+    .name = "tosa-ssp",
+    .size = sizeof(SSISlave),
+    .class_init = tosa_ssp_class_init,
 };
 
 static void tosa_register_devices(void)
diff --git a/hw/z2.c b/hw/z2.c
index 8d48488..f895892 100644
--- a/hw/z2.c
+++ b/hw/z2.c
@@ -174,12 +174,19 @@ static VMStateDescription vmstate_zipit_lcd_state = {
     }
 };
 
-static SSISlaveInfo zipit_lcd_info = {
-    .qdev.name = "zipit-lcd",
-    .qdev.size = sizeof(ZipitLCD),
-    .qdev.vmsd = &vmstate_zipit_lcd_state,
-    .init = zipit_lcd_init,
-    .transfer = zipit_lcd_transfer
+static void zipit_lcd_class_init(ObjectClass *klass, void *data)
+{
+    SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+
+    k->init = zipit_lcd_init;
+    k->transfer = zipit_lcd_transfer;
+}
+
+static DeviceInfo zipit_lcd_info = {
+    .name = "zipit-lcd",
+    .size = sizeof(ZipitLCD),
+    .vmsd = &vmstate_zipit_lcd_state,
+    .class_init = zipit_lcd_class_init,
 };
 
 typedef struct {
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 16/28] i2c: rename i2c_slave -> I2CSlave
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (14 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 15/28] ssi: " Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 17/28] i2c: smbus: convert to QEMU Object Model Anthony Liguori
                   ` (14 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/ds1338.c   |   10 +++++-----
 hw/i2c.c      |   30 +++++++++++++++---------------
 hw/i2c.h      |   22 ++++++++++++----------
 hw/lm832x.c   |   10 +++++-----
 hw/max7310.c  |   10 +++++-----
 hw/pxa2xx.c   |   10 +++++-----
 hw/smbus.c    |    8 ++++----
 hw/smbus.h    |    2 +-
 hw/spitz.c    |    2 +-
 hw/ssd0303.c  |   10 +++++-----
 hw/tmp105.c   |   14 +++++++-------
 hw/tosa.c     |   10 +++++-----
 hw/twl92230.c |   12 ++++++------
 hw/wm8750.c   |   14 +++++++-------
 hw/z2.c       |   10 +++++-----
 15 files changed, 88 insertions(+), 86 deletions(-)

diff --git a/hw/ds1338.c b/hw/ds1338.c
index f754cb7..1c4ba9f 100644
--- a/hw/ds1338.c
+++ b/hw/ds1338.c
@@ -13,7 +13,7 @@
 #include "i2c.h"
 
 typedef struct {
-    i2c_slave i2c;
+    I2CSlave i2c;
     time_t offset;
     struct tm now;
     uint8_t nvram[56];
@@ -21,7 +21,7 @@ typedef struct {
     int addr_byte;
 } DS1338State;
 
-static void ds1338_event(i2c_slave *i2c, enum i2c_event event)
+static void ds1338_event(I2CSlave *i2c, enum i2c_event event)
 {
     DS1338State *s = FROM_I2C_SLAVE(DS1338State, i2c);
 
@@ -51,7 +51,7 @@ static void ds1338_event(i2c_slave *i2c, enum i2c_event event)
     }
 }
 
-static int ds1338_recv(i2c_slave *i2c)
+static int ds1338_recv(I2CSlave *i2c)
 {
     DS1338State *s = FROM_I2C_SLAVE(DS1338State, i2c);
     uint8_t res;
@@ -61,7 +61,7 @@ static int ds1338_recv(i2c_slave *i2c)
     return res;
 }
 
-static int ds1338_send(i2c_slave *i2c, uint8_t data)
+static int ds1338_send(I2CSlave *i2c, uint8_t data)
 {
     DS1338State *s = FROM_I2C_SLAVE(DS1338State, i2c);
     if (s->addr_byte) {
@@ -113,7 +113,7 @@ static int ds1338_send(i2c_slave *i2c, uint8_t data)
     return 0;
 }
 
-static int ds1338_init(i2c_slave *i2c)
+static int ds1338_init(I2CSlave *i2c)
 {
     return 0;
 }
diff --git a/hw/i2c.c b/hw/i2c.c
index 9bcf3e1..9efe70c 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -12,8 +12,8 @@
 struct i2c_bus
 {
     BusState qbus;
-    i2c_slave *current_dev;
-    i2c_slave *dev;
+    I2CSlave *current_dev;
+    I2CSlave *dev;
     uint8_t saved_address;
 };
 
@@ -21,7 +21,7 @@ static struct BusInfo i2c_bus_info = {
     .name = "I2C",
     .size = sizeof(i2c_bus),
     .props = (Property[]) {
-        DEFINE_PROP_UINT8("address", struct i2c_slave, address, 0),
+        DEFINE_PROP_UINT8("address", struct I2CSlave, address, 0),
         DEFINE_PROP_END_OF_LIST(),
     }
 };
@@ -66,7 +66,7 @@ i2c_bus *i2c_init_bus(DeviceState *parent, const char *name)
     return bus;
 }
 
-void i2c_set_slave_address(i2c_slave *dev, uint8_t address)
+void i2c_set_slave_address(I2CSlave *dev, uint8_t address)
 {
     dev->address = address;
 }
@@ -82,10 +82,10 @@ int i2c_bus_busy(i2c_bus *bus)
 int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv)
 {
     DeviceState *qdev;
-    i2c_slave *slave = NULL;
+    I2CSlave *slave = NULL;
 
     QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) {
-        i2c_slave *candidate = I2C_SLAVE_FROM_QDEV(qdev);
+        I2CSlave *candidate = I2C_SLAVE_FROM_QDEV(qdev);
         if (candidate->address == address) {
             slave = candidate;
             break;
@@ -104,7 +104,7 @@ int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv)
 
 void i2c_end_transfer(i2c_bus *bus)
 {
-    i2c_slave *dev = bus->current_dev;
+    I2CSlave *dev = bus->current_dev;
 
     if (!dev)
         return;
@@ -116,7 +116,7 @@ void i2c_end_transfer(i2c_bus *bus)
 
 int i2c_send(i2c_bus *bus, uint8_t data)
 {
-    i2c_slave *dev = bus->current_dev;
+    I2CSlave *dev = bus->current_dev;
 
     if (!dev)
         return -1;
@@ -126,7 +126,7 @@ int i2c_send(i2c_bus *bus, uint8_t data)
 
 int i2c_recv(i2c_bus *bus)
 {
-    i2c_slave *dev = bus->current_dev;
+    I2CSlave *dev = bus->current_dev;
 
     if (!dev)
         return -1;
@@ -136,7 +136,7 @@ int i2c_recv(i2c_bus *bus)
 
 void i2c_nack(i2c_bus *bus)
 {
-    i2c_slave *dev = bus->current_dev;
+    I2CSlave *dev = bus->current_dev;
 
     if (!dev)
         return;
@@ -146,7 +146,7 @@ void i2c_nack(i2c_bus *bus)
 
 static int i2c_slave_post_load(void *opaque, int version_id)
 {
-    i2c_slave *dev = opaque;
+    I2CSlave *dev = opaque;
     i2c_bus *bus;
     bus = FROM_QBUS(i2c_bus, qdev_get_parent_bus(&dev->qdev));
     if (bus->saved_address == dev->address) {
@@ -156,13 +156,13 @@ static int i2c_slave_post_load(void *opaque, int version_id)
 }
 
 const VMStateDescription vmstate_i2c_slave = {
-    .name = "i2c_slave",
+    .name = "I2CSlave",
     .version_id = 1,
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .post_load = i2c_slave_post_load,
     .fields      = (VMStateField []) {
-        VMSTATE_UINT8(address, i2c_slave),
+        VMSTATE_UINT8(address, I2CSlave),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -170,7 +170,7 @@ const VMStateDescription vmstate_i2c_slave = {
 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);
+    I2CSlave *s = I2C_SLAVE_FROM_QDEV(dev);
 
     s->info = info;
 
@@ -179,7 +179,7 @@ static int i2c_slave_qdev_init(DeviceState *dev, DeviceInfo *base)
 
 void i2c_register_slave(I2CSlaveInfo *info)
 {
-    assert(info->qdev.size >= sizeof(i2c_slave));
+    assert(info->qdev.size >= sizeof(I2CSlave));
     info->qdev.init = i2c_slave_qdev_init;
     info->qdev.bus_info = &i2c_bus_info;
     qdev_register(&info->qdev);
diff --git a/hw/i2c.h b/hw/i2c.h
index a3383ff..d45cdad 100644
--- a/hw/i2c.h
+++ b/hw/i2c.h
@@ -15,14 +15,16 @@ enum i2c_event {
     I2C_NACK /* Masker NACKed a receive byte.  */
 };
 
+typedef struct I2CSlave I2CSlave;
+
 /* Master to slave.  */
-typedef int (*i2c_send_cb)(i2c_slave *s, uint8_t data);
+typedef int (*i2c_send_cb)(I2CSlave *s, uint8_t data);
 /* Slave to master.  */
-typedef int (*i2c_recv_cb)(i2c_slave *s);
+typedef int (*i2c_recv_cb)(I2CSlave *s);
 /* Notify the slave of a bus state change.  */
-typedef void (*i2c_event_cb)(i2c_slave *s, enum i2c_event event);
+typedef void (*i2c_event_cb)(I2CSlave *s, enum i2c_event event);
 
-typedef int (*i2c_slave_initfn)(i2c_slave *dev);
+typedef int (*i2c_slave_initfn)(I2CSlave *dev);
 
 typedef struct {
     DeviceInfo qdev;
@@ -34,7 +36,7 @@ typedef struct {
     i2c_send_cb send;
 } I2CSlaveInfo;
 
-struct i2c_slave
+struct I2CSlave
 {
     DeviceState qdev;
     I2CSlaveInfo *info;
@@ -44,7 +46,7 @@ struct i2c_slave
 };
 
 i2c_bus *i2c_init_bus(DeviceState *parent, const char *name);
-void i2c_set_slave_address(i2c_slave *dev, uint8_t address);
+void i2c_set_slave_address(I2CSlave *dev, uint8_t address);
 int i2c_bus_busy(i2c_bus *bus);
 int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv);
 void i2c_end_transfer(i2c_bus *bus);
@@ -52,7 +54,7 @@ void i2c_nack(i2c_bus *bus);
 int i2c_send(i2c_bus *bus, uint8_t data);
 int i2c_recv(i2c_bus *bus);
 
-#define I2C_SLAVE_FROM_QDEV(dev) DO_UPCAST(i2c_slave, qdev, dev)
+#define I2C_SLAVE_FROM_QDEV(dev) DO_UPCAST(I2CSlave, qdev, dev)
 #define FROM_I2C_SLAVE(type, dev) DO_UPCAST(type, i2c, dev)
 
 void i2c_register_slave(I2CSlaveInfo *type);
@@ -69,7 +71,7 @@ void wm8750_dac_commit(void *opaque);
 void wm8750_set_bclk_in(void *opaque, int new_hz);
 
 /* tmp105.c */
-void tmp105_set(i2c_slave *i2c, int temp);
+void tmp105_set(I2CSlave *i2c, int temp);
 
 /* lm832x.c */
 void lm832x_key_event(DeviceState *dev, int key, int state);
@@ -78,10 +80,10 @@ extern const VMStateDescription vmstate_i2c_slave;
 
 #define VMSTATE_I2C_SLAVE(_field, _state) {                          \
     .name       = (stringify(_field)),                               \
-    .size       = sizeof(i2c_slave),                                 \
+    .size       = sizeof(I2CSlave),                                  \
     .vmsd       = &vmstate_i2c_slave,                                \
     .flags      = VMS_STRUCT,                                        \
-    .offset     = vmstate_offset_value(_state, _field, i2c_slave),   \
+    .offset     = vmstate_offset_value(_state, _field, I2CSlave),    \
 }
 
 #endif
diff --git a/hw/lm832x.c b/hw/lm832x.c
index 992ce49..9e53cb3 100644
--- a/hw/lm832x.c
+++ b/hw/lm832x.c
@@ -24,7 +24,7 @@
 #include "console.h"
 
 typedef struct {
-    i2c_slave i2c;
+    I2CSlave i2c;
     uint8_t i2c_dir;
     uint8_t i2c_cycle;
     uint8_t reg;
@@ -378,7 +378,7 @@ static void lm_kbd_write(LM823KbdState *s, int reg, int byte, uint8_t value)
     }
 }
 
-static void lm_i2c_event(i2c_slave *i2c, enum i2c_event event)
+static void lm_i2c_event(I2CSlave *i2c, enum i2c_event event)
 {
     LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
 
@@ -394,14 +394,14 @@ static void lm_i2c_event(i2c_slave *i2c, enum i2c_event event)
     }
 }
 
-static int lm_i2c_rx(i2c_slave *i2c)
+static int lm_i2c_rx(I2CSlave *i2c)
 {
     LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
 
     return lm_kbd_read(s, s->reg, s->i2c_cycle ++);
 }
 
-static int lm_i2c_tx(i2c_slave *i2c, uint8_t data)
+static int lm_i2c_tx(I2CSlave *i2c, uint8_t data)
 {
     LM823KbdState *s = (LM823KbdState *) i2c;
 
@@ -458,7 +458,7 @@ static const VMStateDescription vmstate_lm_kbd = {
 };
 
 
-static int lm8323_init(i2c_slave *i2c)
+static int lm8323_init(I2CSlave *i2c)
 {
     LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
 
diff --git a/hw/max7310.c b/hw/max7310.c
index c1bdb2e..a955236 100644
--- a/hw/max7310.c
+++ b/hw/max7310.c
@@ -10,7 +10,7 @@
 #include "i2c.h"
 
 typedef struct {
-    i2c_slave i2c;
+    I2CSlave i2c;
     int i2c_command_byte;
     int len;
 
@@ -33,7 +33,7 @@ static void max7310_reset(DeviceState *dev)
     s->command = 0x00;
 }
 
-static int max7310_rx(i2c_slave *i2c)
+static int max7310_rx(I2CSlave *i2c)
 {
     MAX7310State *s = (MAX7310State *) i2c;
 
@@ -68,7 +68,7 @@ static int max7310_rx(i2c_slave *i2c)
     return 0xff;
 }
 
-static int max7310_tx(i2c_slave *i2c, uint8_t data)
+static int max7310_tx(I2CSlave *i2c, uint8_t data)
 {
     MAX7310State *s = (MAX7310State *) i2c;
     uint8_t diff;
@@ -123,7 +123,7 @@ static int max7310_tx(i2c_slave *i2c, uint8_t data)
     return 0;
 }
 
-static void max7310_event(i2c_slave *i2c, enum i2c_event event)
+static void max7310_event(I2CSlave *i2c, enum i2c_event event)
 {
     MAX7310State *s = (MAX7310State *) i2c;
     s->len = 0;
@@ -175,7 +175,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 int max7310_init(i2c_slave *i2c)
+static int max7310_init(I2CSlave *i2c)
 {
     MAX7310State *s = FROM_I2C_SLAVE(MAX7310State, i2c);
 
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 6ddd500..895fb3f 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -1243,7 +1243,7 @@ static SysBusDeviceInfo pxa2xx_rtc_sysbus_info = {
 
 /* I2C Interface */
 typedef struct {
-    i2c_slave i2c;
+    I2CSlave i2c;
     PXA2xxI2CState *host;
 } PXA2xxI2CSlaveState;
 
@@ -1279,7 +1279,7 @@ static void pxa2xx_i2c_update(PXA2xxI2CState *s)
 }
 
 /* These are only stubs now.  */
-static void pxa2xx_i2c_event(i2c_slave *i2c, enum i2c_event event)
+static void pxa2xx_i2c_event(I2CSlave *i2c, enum i2c_event event)
 {
     PXA2xxI2CSlaveState *slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, i2c);
     PXA2xxI2CState *s = slave->host;
@@ -1303,7 +1303,7 @@ static void pxa2xx_i2c_event(i2c_slave *i2c, enum i2c_event event)
     pxa2xx_i2c_update(s);
 }
 
-static int pxa2xx_i2c_rx(i2c_slave *i2c)
+static int pxa2xx_i2c_rx(I2CSlave *i2c)
 {
     PXA2xxI2CSlaveState *slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, i2c);
     PXA2xxI2CState *s = slave->host;
@@ -1318,7 +1318,7 @@ static int pxa2xx_i2c_rx(i2c_slave *i2c)
     return s->data;
 }
 
-static int pxa2xx_i2c_tx(i2c_slave *i2c, uint8_t data)
+static int pxa2xx_i2c_tx(I2CSlave *i2c, uint8_t data)
 {
     PXA2xxI2CSlaveState *slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, i2c);
     PXA2xxI2CState *s = slave->host;
@@ -1466,7 +1466,7 @@ static const VMStateDescription vmstate_pxa2xx_i2c = {
     }
 };
 
-static int pxa2xx_i2c_slave_init(i2c_slave *i2c)
+static int pxa2xx_i2c_slave_init(I2CSlave *i2c)
 {
     /* Nothing to do.  */
     return 0;
diff --git a/hw/smbus.c b/hw/smbus.c
index ff027c8..0cb3566 100644
--- a/hw/smbus.c
+++ b/hw/smbus.c
@@ -65,7 +65,7 @@ static void smbus_do_write(SMBusDevice *dev)
     }
 }
 
-static void smbus_i2c_event(i2c_slave *s, enum i2c_event event)
+static void smbus_i2c_event(I2CSlave *s, enum i2c_event event)
 {
     SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
 
@@ -148,7 +148,7 @@ static void smbus_i2c_event(i2c_slave *s, enum i2c_event event)
     }
 }
 
-static int smbus_i2c_recv(i2c_slave *s)
+static int smbus_i2c_recv(I2CSlave *s)
 {
     SMBusDeviceInfo *t = container_of(s->info, SMBusDeviceInfo, i2c);
     SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
@@ -182,7 +182,7 @@ static int smbus_i2c_recv(i2c_slave *s)
     return ret;
 }
 
-static int smbus_i2c_send(i2c_slave *s, uint8_t data)
+static int smbus_i2c_send(I2CSlave *s, uint8_t data)
 {
     SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
 
@@ -198,7 +198,7 @@ static int smbus_i2c_send(i2c_slave *s, uint8_t data)
     return 0;
 }
 
-static int smbus_device_init(i2c_slave *i2c)
+static int smbus_device_init(I2CSlave *i2c)
 {
     SMBusDeviceInfo *t = container_of(i2c->info, SMBusDeviceInfo, i2c);
     SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, i2c);
diff --git a/hw/smbus.h b/hw/smbus.h
index a398715..2f2d49e 100644
--- a/hw/smbus.h
+++ b/hw/smbus.h
@@ -26,7 +26,7 @@
 
 struct SMBusDevice {
     /* The SMBus protocol is implemented on top of I2C.  */
-    i2c_slave i2c;
+    I2CSlave i2c;
 
     /* Remaining fields for internal use only.  */
     int mode;
diff --git a/hw/spitz.c b/hw/spitz.c
index 0f63139..a2a778f 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -717,7 +717,7 @@ static void spitz_microdrive_attach(PXA2xxState *cpu, int slot)
 
 static void spitz_wm8750_addr(void *opaque, int line, int level)
 {
-    i2c_slave *wm = (i2c_slave *) opaque;
+    I2CSlave *wm = (I2CSlave *) opaque;
     if (level)
         i2c_set_slave_address(wm, SPITZ_WM_ADDRH);
     else
diff --git a/hw/ssd0303.c b/hw/ssd0303.c
index bcad7bf..6a9a8a7 100644
--- a/hw/ssd0303.c
+++ b/hw/ssd0303.c
@@ -42,7 +42,7 @@ enum ssd0303_cmd {
 };
 
 typedef struct {
-    i2c_slave i2c;
+    I2CSlave i2c;
     DisplayState *ds;
     int row;
     int col;
@@ -57,13 +57,13 @@ typedef struct {
     uint8_t framebuffer[132*8];
 } ssd0303_state;
 
-static int ssd0303_recv(i2c_slave *i2c)
+static int ssd0303_recv(I2CSlave *i2c)
 {
     BADF("Reads not implemented\n");
     return -1;
 }
 
-static int ssd0303_send(i2c_slave *i2c, uint8_t data)
+static int ssd0303_send(I2CSlave *i2c, uint8_t data)
 {
     ssd0303_state *s = (ssd0303_state *)i2c;
     enum ssd0303_cmd old_cmd_state;
@@ -173,7 +173,7 @@ static int ssd0303_send(i2c_slave *i2c, uint8_t data)
     return 0;
 }
 
-static void ssd0303_event(i2c_slave *i2c, enum i2c_event event)
+static void ssd0303_event(I2CSlave *i2c, enum i2c_event event)
 {
     ssd0303_state *s = (ssd0303_state *)i2c;
     switch (event) {
@@ -283,7 +283,7 @@ static const VMStateDescription vmstate_ssd0303 = {
     }
 };
 
-static int ssd0303_init(i2c_slave *i2c)
+static int ssd0303_init(I2CSlave *i2c)
 {
     ssd0303_state *s = FROM_I2C_SLAVE(ssd0303_state, i2c);
 
diff --git a/hw/tmp105.c b/hw/tmp105.c
index f7e6f2b..ed8a0f3 100644
--- a/hw/tmp105.c
+++ b/hw/tmp105.c
@@ -22,7 +22,7 @@
 #include "i2c.h"
 
 typedef struct {
-    i2c_slave i2c;
+    I2CSlave i2c;
     uint8_t len;
     uint8_t buf[2];
     qemu_irq pin;
@@ -65,7 +65,7 @@ static void tmp105_alarm_update(TMP105State *s)
 }
 
 /* Units are 0.001 centigrades relative to 0 C.  */
-void tmp105_set(i2c_slave *i2c, int temp)
+void tmp105_set(I2CSlave *i2c, int temp)
 {
     TMP105State *s = (TMP105State *) i2c;
 
@@ -138,7 +138,7 @@ static void tmp105_write(TMP105State *s)
     }
 }
 
-static int tmp105_rx(i2c_slave *i2c)
+static int tmp105_rx(I2CSlave *i2c)
 {
     TMP105State *s = (TMP105State *) i2c;
 
@@ -148,7 +148,7 @@ static int tmp105_rx(i2c_slave *i2c)
         return 0xff;
 }
 
-static int tmp105_tx(i2c_slave *i2c, uint8_t data)
+static int tmp105_tx(I2CSlave *i2c, uint8_t data)
 {
     TMP105State *s = (TMP105State *) i2c;
 
@@ -163,7 +163,7 @@ static int tmp105_tx(i2c_slave *i2c, uint8_t data)
     return 0;
 }
 
-static void tmp105_event(i2c_slave *i2c, enum i2c_event event)
+static void tmp105_event(I2CSlave *i2c, enum i2c_event event)
 {
     TMP105State *s = (TMP105State *) i2c;
 
@@ -202,7 +202,7 @@ static const VMStateDescription vmstate_tmp105 = {
     }
 };
 
-static void tmp105_reset(i2c_slave *i2c)
+static void tmp105_reset(I2CSlave *i2c)
 {
     TMP105State *s = (TMP105State *) i2c;
 
@@ -215,7 +215,7 @@ static void tmp105_reset(i2c_slave *i2c)
     tmp105_interrupt_update(s);
 }
 
-static int tmp105_init(i2c_slave *i2c)
+static int tmp105_init(I2CSlave *i2c)
 {
     TMP105State *s = FROM_I2C_SLAVE(TMP105State, i2c);
 
diff --git a/hw/tosa.c b/hw/tosa.c
index ade4cf6..5f4968d 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -133,12 +133,12 @@ static int tosa_ssp_init(SSISlave *dev)
 }
 
 typedef struct {
-    i2c_slave i2c;
+    I2CSlave i2c;
     int len;
     char buf[3];
 } TosaDACState;
 
-static int tosa_dac_send(i2c_slave *i2c, uint8_t data)
+static int tosa_dac_send(I2CSlave *i2c, uint8_t data)
 {
     TosaDACState *s = FROM_I2C_SLAVE(TosaDACState, i2c);
     s->buf[s->len] = data;
@@ -157,7 +157,7 @@ static int tosa_dac_send(i2c_slave *i2c, uint8_t data)
     return 0;
 }
 
-static void tosa_dac_event(i2c_slave *i2c, enum i2c_event event)
+static void tosa_dac_event(I2CSlave *i2c, enum i2c_event event)
 {
     TosaDACState *s = FROM_I2C_SLAVE(TosaDACState, i2c);
     s->len = 0;
@@ -180,13 +180,13 @@ static void tosa_dac_event(i2c_slave *i2c, enum i2c_event event)
     }
 }
 
-static int tosa_dac_recv(i2c_slave *s)
+static int tosa_dac_recv(I2CSlave *s)
 {
     printf("%s: recv not supported!!!\n", __FUNCTION__);
     return -1;
 }
 
-static int tosa_dac_init(i2c_slave *i2c)
+static int tosa_dac_init(I2CSlave *i2c)
 {
     /* Nothing to do.  */
     return 0;
diff --git a/hw/twl92230.c b/hw/twl92230.c
index a75448f..ced705c 100644
--- a/hw/twl92230.c
+++ b/hw/twl92230.c
@@ -27,7 +27,7 @@
 #define VERBOSE 1
 
 typedef struct {
-    i2c_slave i2c;
+    I2CSlave i2c;
 
     int firstbyte;
     uint8_t reg;
@@ -126,7 +126,7 @@ static void menelaus_rtc_hz(void *opaque)
     menelaus_update(s);
 }
 
-static void menelaus_reset(i2c_slave *i2c)
+static void menelaus_reset(I2CSlave *i2c)
 {
     MenelausState *s = (MenelausState *) i2c;
     s->reg = 0x00;
@@ -709,7 +709,7 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value)
     }
 }
 
-static void menelaus_event(i2c_slave *i2c, enum i2c_event event)
+static void menelaus_event(I2CSlave *i2c, enum i2c_event event)
 {
     MenelausState *s = (MenelausState *) i2c;
 
@@ -717,7 +717,7 @@ static void menelaus_event(i2c_slave *i2c, enum i2c_event event)
         s->firstbyte = 1;
 }
 
-static int menelaus_tx(i2c_slave *i2c, uint8_t data)
+static int menelaus_tx(I2CSlave *i2c, uint8_t data)
 {
     MenelausState *s = (MenelausState *) i2c;
     /* Interpret register address byte */
@@ -730,7 +730,7 @@ static int menelaus_tx(i2c_slave *i2c, uint8_t data)
     return 0;
 }
 
-static int menelaus_rx(i2c_slave *i2c)
+static int menelaus_rx(I2CSlave *i2c)
 {
     MenelausState *s = (MenelausState *) i2c;
 
@@ -842,7 +842,7 @@ static const VMStateDescription vmstate_menelaus = {
     }
 };
 
-static int twl92230_init(i2c_slave *i2c)
+static int twl92230_init(I2CSlave *i2c)
 {
     MenelausState *s = FROM_I2C_SLAVE(MenelausState, i2c);
 
diff --git a/hw/wm8750.c b/hw/wm8750.c
index 9fbdf3d..5526bc4 100644
--- a/hw/wm8750.c
+++ b/hw/wm8750.c
@@ -24,7 +24,7 @@ typedef struct {
 } WMRate;
 
 typedef struct {
-    i2c_slave i2c;
+    I2CSlave i2c;
     uint8_t i2c_data[2];
     int i2c_len;
     QEMUSoundCard card;
@@ -254,7 +254,7 @@ static void wm8750_clk_update(WM8750State *s, int ext)
     }
 }
 
-static void wm8750_reset(i2c_slave *i2c)
+static void wm8750_reset(I2CSlave *i2c)
 {
     WM8750State *s = (WM8750State *) i2c;
     s->rate = &wm_rate_table[0];
@@ -297,7 +297,7 @@ static void wm8750_reset(i2c_slave *i2c)
     s->i2c_len = 0;
 }
 
-static void wm8750_event(i2c_slave *i2c, enum i2c_event event)
+static void wm8750_event(I2CSlave *i2c, enum i2c_event event)
 {
     WM8750State *s = (WM8750State *) i2c;
 
@@ -354,7 +354,7 @@ static void wm8750_event(i2c_slave *i2c, enum i2c_event event)
 #define WM8750_ROUT2V	0x29
 #define WM8750_MOUTV	0x2a
 
-static int wm8750_tx(i2c_slave *i2c, uint8_t data)
+static int wm8750_tx(I2CSlave *i2c, uint8_t data)
 {
     WM8750State *s = (WM8750State *) i2c;
     uint8_t cmd;
@@ -554,7 +554,7 @@ static int wm8750_tx(i2c_slave *i2c, uint8_t data)
     return 0;
 }
 
-static int wm8750_rx(i2c_slave *i2c)
+static int wm8750_rx(I2CSlave *i2c)
 {
     return 0x00;
 }
@@ -609,7 +609,7 @@ static const VMStateDescription vmstate_wm8750 = {
     }
 };
 
-static int wm8750_init(i2c_slave *i2c)
+static int wm8750_init(I2CSlave *i2c)
 {
     WM8750State *s = FROM_I2C_SLAVE(WM8750State, i2c);
 
@@ -620,7 +620,7 @@ static int wm8750_init(i2c_slave *i2c)
 }
 
 #if 0
-static void wm8750_fini(i2c_slave *i2c)
+static void wm8750_fini(I2CSlave *i2c)
 {
     WM8750State *s = (WM8750State *) i2c;
     wm8750_reset(&s->i2c);
diff --git a/hw/z2.c b/hw/z2.c
index f895892..2984a60 100644
--- a/hw/z2.c
+++ b/hw/z2.c
@@ -190,12 +190,12 @@ static DeviceInfo zipit_lcd_info = {
 };
 
 typedef struct {
-    i2c_slave i2c;
+    I2CSlave i2c;
     int len;
     uint8_t buf[3];
 } AER915State;
 
-static int aer915_send(i2c_slave *i2c, uint8_t data)
+static int aer915_send(I2CSlave *i2c, uint8_t data)
 {
     AER915State *s = FROM_I2C_SLAVE(AER915State, i2c);
     s->buf[s->len] = data;
@@ -213,7 +213,7 @@ static int aer915_send(i2c_slave *i2c, uint8_t data)
     return 0;
 }
 
-static void aer915_event(i2c_slave *i2c, enum i2c_event event)
+static void aer915_event(I2CSlave *i2c, enum i2c_event event)
 {
     AER915State *s = FROM_I2C_SLAVE(AER915State, i2c);
     switch (event) {
@@ -232,7 +232,7 @@ static void aer915_event(i2c_slave *i2c, enum i2c_event event)
     }
 }
 
-static int aer915_recv(i2c_slave *slave)
+static int aer915_recv(I2CSlave *slave)
 {
     int retval = 0x00;
     AER915State *s = FROM_I2C_SLAVE(AER915State, slave);
@@ -255,7 +255,7 @@ static int aer915_recv(i2c_slave *slave)
     return retval;
 }
 
-static int aer915_init(i2c_slave *i2c)
+static int aer915_init(I2CSlave *i2c)
 {
     /* Nothing to do.  */
     return 0;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 17/28] i2c: smbus: convert to QEMU Object Model
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (15 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 16/28] i2c: rename i2c_slave -> I2CSlave Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 18/28] hda-codec: " Anthony Liguori
                   ` (13 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori

This converts two types because smbus is implemented as a subclass of i2c.  It's
extremely difficult to convert these two independently.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/ds1338.c       |   21 +++++++++----
 hw/i2c.c          |   83 +++++++++++++++++++++++++++++++++++++++++-----------
 hw/i2c.h          |   40 ++++++++++++++-----------
 hw/lm832x.c       |   23 +++++++++-----
 hw/max7310.c      |   25 ++++++++++------
 hw/pxa2xx.c       |   21 +++++++++----
 hw/smbus.c        |   77 ++++++++++++++++++++++++++++++++-----------------
 hw/smbus.h        |   42 ++++++++++++++++++---------
 hw/smbus_eeprom.c |   27 +++++++++++------
 hw/ssd0303.c      |   23 +++++++++-----
 hw/tmp105.c       |   23 +++++++++-----
 hw/tosa.c         |   21 +++++++++----
 hw/twl92230.c     |   23 +++++++++-----
 hw/wm8750.c       |   23 +++++++++-----
 hw/z2.c           |   23 +++++++++-----
 15 files changed, 331 insertions(+), 164 deletions(-)

diff --git a/hw/ds1338.c b/hw/ds1338.c
index 1c4ba9f..4e09efe 100644
--- a/hw/ds1338.c
+++ b/hw/ds1338.c
@@ -118,13 +118,20 @@ static int ds1338_init(I2CSlave *i2c)
     return 0;
 }
 
-static I2CSlaveInfo ds1338_info = {
-    .qdev.name = "ds1338",
-    .qdev.size = sizeof(DS1338State),
-    .init = ds1338_init,
-    .event = ds1338_event,
-    .recv = ds1338_recv,
-    .send = ds1338_send,
+static void ds1338_class_init(ObjectClass *klass, void *data)
+{
+    I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
+
+    k->init = ds1338_init;
+    k->event = ds1338_event;
+    k->recv = ds1338_recv;
+    k->send = ds1338_send;
+}
+
+static DeviceInfo ds1338_info = {
+    .name = "ds1338",
+    .size = sizeof(DS1338State),
+    .class_init = ds1338_class_init,
 };
 
 static void ds1338_register_devices(void)
diff --git a/hw/i2c.c b/hw/i2c.c
index 9efe70c..9e5d3df 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -83,6 +83,7 @@ int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv)
 {
     DeviceState *qdev;
     I2CSlave *slave = NULL;
+    I2CSlaveClass *sc;
 
     QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) {
         I2CSlave *candidate = I2C_SLAVE_FROM_QDEV(qdev);
@@ -92,24 +93,33 @@ int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv)
         }
     }
 
-    if (!slave)
+    if (!slave) {
         return 1;
+    }
 
+    sc = I2C_SLAVE_GET_CLASS(slave);
     /* If the bus is already busy, assume this is a repeated
        start condition.  */
     bus->current_dev = slave;
-    slave->info->event(slave, recv ? I2C_START_RECV : I2C_START_SEND);
+    if (sc->event) {
+        sc->event(slave, recv ? I2C_START_RECV : I2C_START_SEND);
+    }
     return 0;
 }
 
 void i2c_end_transfer(i2c_bus *bus)
 {
     I2CSlave *dev = bus->current_dev;
+    I2CSlaveClass *sc;
 
-    if (!dev)
+    if (!dev) {
         return;
+    }
 
-    dev->info->event(dev, I2C_FINISH);
+    sc = I2C_SLAVE_GET_CLASS(dev);
+    if (sc->event) {
+        sc->event(dev, I2C_FINISH);
+    }
 
     bus->current_dev = NULL;
 }
@@ -117,31 +127,50 @@ void i2c_end_transfer(i2c_bus *bus)
 int i2c_send(i2c_bus *bus, uint8_t data)
 {
     I2CSlave *dev = bus->current_dev;
+    I2CSlaveClass *sc;
 
-    if (!dev)
+    if (!dev) {
         return -1;
+    }
 
-    return dev->info->send(dev, data);
+    sc = I2C_SLAVE_GET_CLASS(dev);
+    if (sc->send) {
+        return sc->send(dev, data);
+    }
+
+    return -1;
 }
 
 int i2c_recv(i2c_bus *bus)
 {
     I2CSlave *dev = bus->current_dev;
+    I2CSlaveClass *sc;
 
-    if (!dev)
+    if (!dev) {
         return -1;
+    }
+
+    sc = I2C_SLAVE_GET_CLASS(dev);
+    if (sc->recv) {
+        return sc->recv(dev);
+    }
 
-    return dev->info->recv(dev);
+    return -1;
 }
 
 void i2c_nack(i2c_bus *bus)
 {
     I2CSlave *dev = bus->current_dev;
+    I2CSlaveClass *sc;
 
-    if (!dev)
+    if (!dev) {
         return;
+    }
 
-    dev->info->event(dev, I2C_NACK);
+    sc = I2C_SLAVE_GET_CLASS(dev);
+    if (sc->event) {
+        sc->event(dev, I2C_NACK);
+    }
 }
 
 static int i2c_slave_post_load(void *opaque, int version_id)
@@ -169,20 +198,23 @@ const VMStateDescription vmstate_i2c_slave = {
 
 static int i2c_slave_qdev_init(DeviceState *dev, DeviceInfo *base)
 {
-    I2CSlaveInfo *info = container_of(base, I2CSlaveInfo, qdev);
     I2CSlave *s = I2C_SLAVE_FROM_QDEV(dev);
+    I2CSlaveClass *sc = I2C_SLAVE_GET_CLASS(s);
 
-    s->info = info;
+    return sc->init(s);
+}
 
-    return info->init(s);
+void i2c_register_slave_subclass(DeviceInfo *info, const char *parent)
+{
+    assert(info->size >= sizeof(I2CSlave));
+    info->init = i2c_slave_qdev_init;
+    info->bus_info = &i2c_bus_info;
+    qdev_register_subclass(info, parent);
 }
 
-void i2c_register_slave(I2CSlaveInfo *info)
+void i2c_register_slave(DeviceInfo *info)
 {
-    assert(info->qdev.size >= sizeof(I2CSlave));
-    info->qdev.init = i2c_slave_qdev_init;
-    info->qdev.bus_info = &i2c_bus_info;
-    qdev_register(&info->qdev);
+    i2c_register_slave_subclass(info, TYPE_I2C_SLAVE);
 }
 
 DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr)
@@ -194,3 +226,18 @@ DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr)
     qdev_init_nofail(dev);
     return dev;
 }
+
+static TypeInfo i2c_slave_type_info = {
+    .name = TYPE_I2C_SLAVE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(I2CSlave),
+    .abstract = true,
+    .class_size = sizeof(I2CSlaveClass),
+};
+
+static void i2c_slave_register_devices(void)
+{
+    type_register_static(&i2c_slave_type_info);
+}
+
+device_init(i2c_slave_register_devices);
diff --git a/hw/i2c.h b/hw/i2c.h
index d45cdad..31fd59c 100644
--- a/hw/i2c.h
+++ b/hw/i2c.h
@@ -17,29 +17,34 @@ enum i2c_event {
 
 typedef struct I2CSlave I2CSlave;
 
-/* Master to slave.  */
-typedef int (*i2c_send_cb)(I2CSlave *s, uint8_t data);
-/* Slave to master.  */
-typedef int (*i2c_recv_cb)(I2CSlave *s);
-/* Notify the slave of a bus state change.  */
-typedef void (*i2c_event_cb)(I2CSlave *s, enum i2c_event event);
+#define TYPE_I2C_SLAVE "i2c-slave"
+#define I2C_SLAVE(obj) \
+     OBJECT_CHECK(I2CSlave, (obj), TYPE_I2C_SLAVE)
+#define I2C_SLAVE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(I2CSlaveClass, (klass), TYPE_I2C_SLAVE)
+#define I2C_SLAVE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(I2CSlaveClass, (obj), TYPE_I2C_SLAVE)
+
+typedef struct I2CSlaveClass
+{
+    DeviceClass parent_class;
+
+    /* Callbacks provided by the device.  */
+    int (*init)(I2CSlave *dev);
 
-typedef int (*i2c_slave_initfn)(I2CSlave *dev);
+    /* Master to slave.  */
+    int (*send)(I2CSlave *s, uint8_t data);
 
-typedef struct {
-    DeviceInfo qdev;
+    /* Slave to master.  */
+    int (*recv)(I2CSlave *s);
 
-    /* Callbacks provided by the device.  */
-    i2c_slave_initfn init;
-    i2c_event_cb event;
-    i2c_recv_cb recv;
-    i2c_send_cb send;
-} I2CSlaveInfo;
+    /* Notify the slave of a bus state change.  */
+    void (*event)(I2CSlave *s, enum i2c_event event);
+} I2CSlaveClass;
 
 struct I2CSlave
 {
     DeviceState qdev;
-    I2CSlaveInfo *info;
 
     /* Remaining fields for internal use by the I2C code.  */
     uint8_t address;
@@ -57,7 +62,8 @@ int i2c_recv(i2c_bus *bus);
 #define I2C_SLAVE_FROM_QDEV(dev) DO_UPCAST(I2CSlave, qdev, dev)
 #define FROM_I2C_SLAVE(type, dev) DO_UPCAST(type, i2c, dev)
 
-void i2c_register_slave(I2CSlaveInfo *type);
+void i2c_register_slave(DeviceInfo *type);
+void i2c_register_slave_subclass(DeviceInfo *info, const char *parent);
 
 DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr);
 
diff --git a/hw/lm832x.c b/hw/lm832x.c
index 9e53cb3..84f81fe 100644
--- a/hw/lm832x.c
+++ b/hw/lm832x.c
@@ -494,14 +494,21 @@ void lm832x_key_event(DeviceState *dev, int key, int state)
     lm_kbd_irq_update(s);
 }
 
-static I2CSlaveInfo lm8323_info = {
-    .qdev.name = "lm8323",
-    .qdev.size = sizeof(LM823KbdState),
-    .qdev.vmsd = &vmstate_lm_kbd,
-    .init = lm8323_init,
-    .event = lm_i2c_event,
-    .recv = lm_i2c_rx,
-    .send = lm_i2c_tx
+static void lm8323_class_init(ObjectClass *klass, void *data)
+{
+    I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
+
+    k->init = lm8323_init;
+    k->event = lm_i2c_event;
+    k->recv = lm_i2c_rx;
+    k->send = lm_i2c_tx;
+}
+
+static DeviceInfo lm8323_info = {
+    .name = "lm8323",
+    .size = sizeof(LM823KbdState),
+    .vmsd = &vmstate_lm_kbd,
+    .class_init = lm8323_class_init,
 };
 
 static void lm832x_register_devices(void)
diff --git a/hw/max7310.c b/hw/max7310.c
index a955236..0cc3219 100644
--- a/hw/max7310.c
+++ b/hw/max7310.c
@@ -185,15 +185,22 @@ static int max7310_init(I2CSlave *i2c)
     return 0;
 }
 
-static I2CSlaveInfo max7310_info = {
-    .qdev.name = "max7310",
-    .qdev.size = sizeof(MAX7310State),
-    .qdev.vmsd = &vmstate_max7310,
-    .qdev.reset = max7310_reset,
-    .init = max7310_init,
-    .event = max7310_event,
-    .recv = max7310_rx,
-    .send = max7310_tx
+static void max7310_class_init(ObjectClass *klass, void *data)
+{
+    I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
+
+    k->init = max7310_init;
+    k->event = max7310_event;
+    k->recv = max7310_rx;
+    k->send = max7310_tx;
+}
+
+static DeviceInfo max7310_info = {
+    .name = "max7310",
+    .size = sizeof(MAX7310State),
+    .vmsd = &vmstate_max7310,
+    .reset = max7310_reset,
+    .class_init = max7310_class_init,
 };
 
 static void max7310_register_devices(void)
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 895fb3f..2ebb739 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -1472,13 +1472,20 @@ static int pxa2xx_i2c_slave_init(I2CSlave *i2c)
     return 0;
 }
 
-static I2CSlaveInfo pxa2xx_i2c_slave_info = {
-    .qdev.name = "pxa2xx-i2c-slave",
-    .qdev.size = sizeof(PXA2xxI2CSlaveState),
-    .init = pxa2xx_i2c_slave_init,
-    .event = pxa2xx_i2c_event,
-    .recv = pxa2xx_i2c_rx,
-    .send = pxa2xx_i2c_tx
+static void pxapxa2xx_i2c_slave_class_init(ObjectClass *klass, void *data)
+{
+    I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
+
+    k->init = pxa2xx_i2c_slave_init;
+    k->event = pxa2xx_i2c_event;
+    k->recv = pxa2xx_i2c_rx;
+    k->send = pxa2xx_i2c_tx;
+}
+
+static DeviceInfo pxa2xx_i2c_slave_info = {
+    .name = "pxa2xx-i2c-slave",
+    .size = sizeof(PXA2xxI2CSlaveState),
+    .class_init = pxapxa2xx_i2c_slave_class_init,
 };
 
 PXA2xxI2CState *pxa2xx_i2c_init(target_phys_addr_t base,
diff --git a/hw/smbus.c b/hw/smbus.c
index 0cb3566..ed31a59 100644
--- a/hw/smbus.c
+++ b/hw/smbus.c
@@ -37,37 +37,38 @@ enum {
 
 static void smbus_do_quick_cmd(SMBusDevice *dev, int recv)
 {
-    SMBusDeviceInfo *t = container_of(dev->i2c.info, SMBusDeviceInfo, i2c);
+    SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
 
     DPRINTF("Quick Command %d\n", recv);
-    if (t->quick_cmd)
-        t->quick_cmd(dev, recv);
+    if (sc->quick_cmd) {
+        sc->quick_cmd(dev, recv);
+    }
 }
 
 static void smbus_do_write(SMBusDevice *dev)
 {
-    SMBusDeviceInfo *t = container_of(dev->i2c.info, SMBusDeviceInfo, i2c);
+    SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
 
     if (dev->data_len == 0) {
         smbus_do_quick_cmd(dev, 0);
     } else if (dev->data_len == 1) {
         DPRINTF("Send Byte\n");
-        if (t->send_byte) {
-            t->send_byte(dev, dev->data_buf[0]);
+        if (sc->send_byte) {
+            sc->send_byte(dev, dev->data_buf[0]);
         }
     } else {
         dev->command = dev->data_buf[0];
         DPRINTF("Command %d len %d\n", dev->command, dev->data_len - 1);
-        if (t->write_data) {
-            t->write_data(dev, dev->command, dev->data_buf + 1,
-                          dev->data_len - 1);
+        if (sc->write_data) {
+            sc->write_data(dev, dev->command, dev->data_buf + 1,
+                           dev->data_len - 1);
         }
     }
 }
 
 static void smbus_i2c_event(I2CSlave *s, enum i2c_event event)
 {
-    SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
+    SMBusDevice *dev = SMBUS_DEVICE(s);
 
     switch (event) {
     case I2C_START_SEND:
@@ -150,14 +151,14 @@ static void smbus_i2c_event(I2CSlave *s, enum i2c_event event)
 
 static int smbus_i2c_recv(I2CSlave *s)
 {
-    SMBusDeviceInfo *t = container_of(s->info, SMBusDeviceInfo, i2c);
-    SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
+    SMBusDevice *dev = SMBUS_DEVICE(s);
+    SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
     int ret;
 
     switch (dev->mode) {
     case SMBUS_RECV_BYTE:
-        if (t->receive_byte) {
-            ret = t->receive_byte(dev);
+        if (sc->receive_byte) {
+            ret = sc->receive_byte(dev);
         } else {
             ret = 0;
         }
@@ -165,8 +166,8 @@ static int smbus_i2c_recv(I2CSlave *s)
         dev->mode = SMBUS_DONE;
         break;
     case SMBUS_READ_DATA:
-        if (t->read_data) {
-            ret = t->read_data(dev, dev->command, dev->data_len);
+        if (sc->read_data) {
+            ret = sc->read_data(dev, dev->command, dev->data_len);
             dev->data_len++;
         } else {
             ret = 0;
@@ -184,7 +185,7 @@ static int smbus_i2c_recv(I2CSlave *s)
 
 static int smbus_i2c_send(I2CSlave *s, uint8_t data)
 {
-    SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
+    SMBusDevice *dev = SMBUS_DEVICE(s);
 
     switch (dev->mode) {
     case SMBUS_WRITE_DATA:
@@ -200,20 +201,16 @@ static int smbus_i2c_send(I2CSlave *s, uint8_t data)
 
 static int smbus_device_init(I2CSlave *i2c)
 {
-    SMBusDeviceInfo *t = container_of(i2c->info, SMBusDeviceInfo, i2c);
-    SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, i2c);
+    SMBusDevice *dev = SMBUS_DEVICE(i2c);
+    SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
 
-    return t->init(dev);
+    return sc->init(dev);
 }
 
-void smbus_register_device(SMBusDeviceInfo *info)
+void smbus_register_device(DeviceInfo *info)
 {
-    assert(info->i2c.qdev.size >= sizeof(SMBusDevice));
-    info->i2c.init = smbus_device_init;
-    info->i2c.event = smbus_i2c_event;
-    info->i2c.recv = smbus_i2c_recv;
-    info->i2c.send = smbus_i2c_send;
-    i2c_register_slave(&info->i2c);
+    assert(info->size >= sizeof(SMBusDevice));
+    i2c_register_slave_subclass(info, TYPE_SMBUS_DEVICE);
 }
 
 /* Master device commands.  */
@@ -316,3 +313,29 @@ void smbus_write_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *dat
         i2c_send(bus, data[i]);
     i2c_end_transfer(bus);
 }
+
+static void smbus_device_class_init(ObjectClass *klass, void *data)
+{
+    I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
+
+    sc->init = smbus_device_init;
+    sc->event = smbus_i2c_event;
+    sc->recv = smbus_i2c_recv;
+    sc->send = smbus_i2c_send;
+}
+
+static TypeInfo smbus_device_type_info = {
+    .name = TYPE_SMBUS_DEVICE,
+    .parent = TYPE_I2C_SLAVE,
+    .instance_size = sizeof(SMBusDevice),
+    .abstract = true,
+    .class_size = sizeof(SMBusDeviceClass),
+    .class_init = smbus_device_class_init,
+};
+
+static void smbus_device_register_devices(void)
+{
+    type_register_static(&smbus_device_type_info);
+}
+
+device_init(smbus_device_register_devices);
diff --git a/hw/smbus.h b/hw/smbus.h
index 2f2d49e..90fadee 100644
--- a/hw/smbus.h
+++ b/hw/smbus.h
@@ -1,3 +1,6 @@
+#ifndef QEMU_SMBUS_H
+#define QEMU_SMBUS_H
+
 /*
  * QEMU SMBus API
  *
@@ -24,19 +27,17 @@
 
 #include "i2c.h"
 
-struct SMBusDevice {
-    /* The SMBus protocol is implemented on top of I2C.  */
-    I2CSlave i2c;
-
-    /* Remaining fields for internal use only.  */
-    int mode;
-    int data_len;
-    uint8_t data_buf[34]; /* command + len + 32 bytes of data.  */
-    uint8_t command;
-};
+#define TYPE_SMBUS_DEVICE "smbus-device"
+#define SMBUS_DEVICE(obj) \
+     OBJECT_CHECK(SMBusDevice, (obj), TYPE_SMBUS_DEVICE)
+#define SMBUS_DEVICE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(SMBusDeviceClass, (klass), TYPE_SMBUS_DEVICE)
+#define SMBUS_DEVICE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(SMBusDeviceClass, (obj), TYPE_SMBUS_DEVICE)
 
-typedef struct {
-    I2CSlaveInfo i2c;
+typedef struct SMBusDeviceClass
+{
+    I2CSlaveClass parent_class;
     int (*init)(SMBusDevice *dev);
     void (*quick_cmd)(SMBusDevice *dev, uint8_t read);
     void (*send_byte)(SMBusDevice *dev, uint8_t val);
@@ -51,9 +52,20 @@ typedef struct {
        byte at a time.  The device is responsible for adding the length
        byte on block reads.  */
     uint8_t (*read_data)(SMBusDevice *dev, uint8_t cmd, int n);
-} SMBusDeviceInfo;
+} SMBusDeviceClass;
 
-void smbus_register_device(SMBusDeviceInfo *info);
+struct SMBusDevice {
+    /* The SMBus protocol is implemented on top of I2C.  */
+    I2CSlave i2c;
+
+    /* Remaining fields for internal use only.  */
+    int mode;
+    int data_len;
+    uint8_t data_buf[34]; /* command + len + 32 bytes of data.  */
+    uint8_t command;
+};
+
+void smbus_register_device(DeviceInfo *info);
 
 /* Master device commands.  */
 void smbus_quick_command(i2c_bus *bus, uint8_t addr, int read);
@@ -69,3 +81,5 @@ void smbus_write_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *dat
 
 void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom,
                        const uint8_t *eeprom_spd, int size);
+
+#endif
diff --git a/hw/smbus_eeprom.c b/hw/smbus_eeprom.c
index 5d080ab..401dff5 100644
--- a/hw/smbus_eeprom.c
+++ b/hw/smbus_eeprom.c
@@ -104,19 +104,26 @@ static int smbus_eeprom_initfn(SMBusDevice *dev)
     return 0;
 }
 
-static SMBusDeviceInfo smbus_eeprom_info = {
-    .i2c.qdev.name = "smbus-eeprom",
-    .i2c.qdev.size = sizeof(SMBusEEPROMDevice),
-    .i2c.qdev.props = (Property[]) {
+static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
+{
+    SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(klass);
+
+    sc->init = smbus_eeprom_initfn;
+    sc->quick_cmd = eeprom_quick_cmd;
+    sc->send_byte = eeprom_send_byte;
+    sc->receive_byte = eeprom_receive_byte;
+    sc->write_data = eeprom_write_data;
+    sc->read_data = eeprom_read_data;
+}
+
+static DeviceInfo smbus_eeprom_info = {
+    .name = "smbus-eeprom",
+    .size = sizeof(SMBusEEPROMDevice),
+    .class_init = smbus_eeprom_class_initfn,
+    .props = (Property[]) {
         DEFINE_PROP_PTR("data", SMBusEEPROMDevice, data),
         DEFINE_PROP_END_OF_LIST(),
     },
-    .init = smbus_eeprom_initfn,
-    .quick_cmd = eeprom_quick_cmd,
-    .send_byte = eeprom_send_byte,
-    .receive_byte = eeprom_receive_byte,
-    .write_data = eeprom_write_data,
-    .read_data = eeprom_read_data
 };
 
 static void smbus_eeprom_register_devices(void)
diff --git a/hw/ssd0303.c b/hw/ssd0303.c
index 6a9a8a7..acf027f 100644
--- a/hw/ssd0303.c
+++ b/hw/ssd0303.c
@@ -294,14 +294,21 @@ static int ssd0303_init(I2CSlave *i2c)
     return 0;
 }
 
-static I2CSlaveInfo ssd0303_info = {
-    .qdev.name = "ssd0303",
-    .qdev.size = sizeof(ssd0303_state),
-    .qdev.vmsd = &vmstate_ssd0303,
-    .init = ssd0303_init,
-    .event = ssd0303_event,
-    .recv = ssd0303_recv,
-    .send = ssd0303_send
+static void ssd0303_class_init(ObjectClass *klass, void *data)
+{
+    I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
+
+    k->init = ssd0303_init;
+    k->event = ssd0303_event;
+    k->recv = ssd0303_recv;
+    k->send = ssd0303_send;
+}
+
+static DeviceInfo ssd0303_info = {
+    .name = "ssd0303",
+    .size = sizeof(ssd0303_state),
+    .vmsd = &vmstate_ssd0303,
+    .class_init = ssd0303_class_init,
 };
 
 static void ssd0303_register_devices(void)
diff --git a/hw/tmp105.c b/hw/tmp105.c
index ed8a0f3..12fe60d 100644
--- a/hw/tmp105.c
+++ b/hw/tmp105.c
@@ -226,14 +226,21 @@ static int tmp105_init(I2CSlave *i2c)
     return 0;
 }
 
-static I2CSlaveInfo tmp105_info = {
-    .qdev.name = "tmp105",
-    .qdev.size = sizeof(TMP105State),
-    .qdev.vmsd = &vmstate_tmp105,
-    .init = tmp105_init,
-    .event = tmp105_event,
-    .recv = tmp105_rx,
-    .send = tmp105_tx
+static void tmp105_class_init(ObjectClass *klass, void *data)
+{
+    I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
+
+    k->init = tmp105_init;
+    k->event = tmp105_event;
+    k->recv = tmp105_rx;
+    k->send = tmp105_tx;
+}
+
+static DeviceInfo tmp105_info = {
+    .name = "tmp105",
+    .size = sizeof(TMP105State),
+    .vmsd = &vmstate_tmp105,
+    .class_init = tmp105_class_init,
 };
 
 static void tmp105_register_devices(void)
diff --git a/hw/tosa.c b/hw/tosa.c
index 5f4968d..9f112b1 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -259,13 +259,20 @@ static void tosapda_machine_init(void)
 
 machine_init(tosapda_machine_init);
 
-static I2CSlaveInfo tosa_dac_info = {
-    .qdev.name = "tosa_dac",
-    .qdev.size = sizeof(TosaDACState),
-    .init = tosa_dac_init,
-    .event = tosa_dac_event,
-    .recv = tosa_dac_recv,
-    .send = tosa_dac_send
+static void tosa_dac_class_init(ObjectClass *klass, void *data)
+{
+    I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
+
+    k->init = tosa_dac_init;
+    k->event = tosa_dac_event;
+    k->recv = tosa_dac_recv;
+    k->send = tosa_dac_send;
+}
+
+static DeviceInfo tosa_dac_info = {
+    .name = "tosa_dac",
+    .size = sizeof(TosaDACState),
+    .class_init = tosa_dac_class_init,
  };
 
 static void tosa_ssp_class_init(ObjectClass *klass, void *data)
diff --git a/hw/twl92230.c b/hw/twl92230.c
index ced705c..ba4f8aa 100644
--- a/hw/twl92230.c
+++ b/hw/twl92230.c
@@ -857,14 +857,21 @@ static int twl92230_init(I2CSlave *i2c)
     return 0;
 }
 
-static I2CSlaveInfo twl92230_info = {
-    .qdev.name ="twl92230",
-    .qdev.size = sizeof(MenelausState),
-    .qdev.vmsd = &vmstate_menelaus,
-    .init = twl92230_init,
-    .event = menelaus_event,
-    .recv = menelaus_rx,
-    .send = menelaus_tx
+static void twl92230_class_init(ObjectClass *klass, void *data)
+{
+    I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
+
+    sc->init = twl92230_init;
+    sc->event = menelaus_event;
+    sc->recv = menelaus_rx;
+    sc->send = menelaus_tx;
+}
+
+static DeviceInfo twl92230_info = {
+    .name ="twl92230",
+    .size = sizeof(MenelausState),
+    .vmsd = &vmstate_menelaus,
+    .class_init = twl92230_class_init,
 };
 
 static void twl92230_register_devices(void)
diff --git a/hw/wm8750.c b/hw/wm8750.c
index 5526bc4..33bce0d 100644
--- a/hw/wm8750.c
+++ b/hw/wm8750.c
@@ -689,14 +689,21 @@ void wm8750_set_bclk_in(void *opaque, int new_hz)
     wm8750_clk_update(s, 1);
 }
 
-static I2CSlaveInfo wm8750_info = {
-    .qdev.name = "wm8750",
-    .qdev.size = sizeof(WM8750State),
-    .qdev.vmsd = &vmstate_wm8750,
-    .init = wm8750_init,
-    .event = wm8750_event,
-    .recv = wm8750_rx,
-    .send = wm8750_tx
+static void wm8750_class_init(ObjectClass *klass, void *data)
+{
+    I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
+
+    sc->init = wm8750_init;
+    sc->event = wm8750_event;
+    sc->recv = wm8750_rx;
+    sc->send = wm8750_tx;
+}
+
+static DeviceInfo wm8750_info = {
+    .name = "wm8750",
+    .size = sizeof(WM8750State),
+    .vmsd = &vmstate_wm8750,
+    .class_init = wm8750_class_init,
 };
 
 static void wm8750_register_devices(void)
diff --git a/hw/z2.c b/hw/z2.c
index 2984a60..b12f974 100644
--- a/hw/z2.c
+++ b/hw/z2.c
@@ -273,14 +273,21 @@ static VMStateDescription vmstate_aer915_state = {
     }
 };
 
-static I2CSlaveInfo aer915_info = {
-    .qdev.name = "aer915",
-    .qdev.size = sizeof(AER915State),
-    .qdev.vmsd = &vmstate_aer915_state,
-    .init = aer915_init,
-    .event = aer915_event,
-    .recv = aer915_recv,
-    .send = aer915_send
+static void aer915_class_init(ObjectClass *klass, void *data)
+{
+    I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
+
+    k->init = aer915_init;
+    k->event = aer915_event;
+    k->recv = aer915_recv;
+    k->send = aer915_send;
+}
+
+static DeviceInfo aer915_info = {
+    .name = "aer915",
+    .size = sizeof(AER915State),
+    .vmsd = &vmstate_aer915_state,
+    .class_init = aer915_class_init,
 };
 
 static void z2_init(ram_addr_t ram_size,
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 18/28] hda-codec: convert to QEMU Object Model
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (16 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 17/28] i2c: smbus: convert to QEMU Object Model Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 19/28] ide: " Anthony Liguori
                   ` (12 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/hda-audio.c |   58 ++++++++++++++++++++++++++++++++++---------------------
 hw/intel-hda.c |   31 +++++++++++++++++------------
 hw/intel-hda.h |   26 ++++++++++++++++--------
 3 files changed, 71 insertions(+), 44 deletions(-)

diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index 8053c74..2b3ce2f 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -906,33 +906,47 @@ static int hda_audio_init_duplex(HDACodecDevice *hda)
     return hda_audio_init(hda, &duplex);
 }
 
-static HDACodecDeviceInfo hda_audio_info_output = {
-    .qdev.name    = "hda-output",
-    .qdev.desc    = "HDA Audio Codec, output-only",
-    .qdev.size    = sizeof(HDAAudioState),
-    .qdev.vmsd    = &vmstate_hda_audio,
-    .qdev.props   = hda_audio_properties,
-    .init         = hda_audio_init_output,
-    .exit         = hda_audio_exit,
-    .command      = hda_audio_command,
-    .stream       = hda_audio_stream,
+static void hda_audio_output_class_init(ObjectClass *klass, void *data)
+{
+    HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
+
+    k->init = hda_audio_init_output;
+    k->exit = hda_audio_exit;
+    k->command = hda_audio_command;
+    k->stream = hda_audio_stream;
+}
+
+static DeviceInfo hda_audio_output_info = {
+    .name = "hda-output",
+    .desc = "HDA Audio Codec, output-only",
+    .size = sizeof(HDAAudioState),
+    .vmsd = &vmstate_hda_audio,
+    .props = hda_audio_properties,
+    .class_init = hda_audio_output_class_init,
 };
 
-static HDACodecDeviceInfo hda_audio_info_duplex = {
-    .qdev.name    = "hda-duplex",
-    .qdev.desc    = "HDA Audio Codec, duplex",
-    .qdev.size    = sizeof(HDAAudioState),
-    .qdev.vmsd    = &vmstate_hda_audio,
-    .qdev.props   = hda_audio_properties,
-    .init         = hda_audio_init_duplex,
-    .exit         = hda_audio_exit,
-    .command      = hda_audio_command,
-    .stream       = hda_audio_stream,
+static void hda_audio_duplex_class_init(ObjectClass *klass, void *data)
+{
+    HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
+
+    k->init = hda_audio_init_duplex;
+    k->exit = hda_audio_exit;
+    k->command = hda_audio_command;
+    k->stream = hda_audio_stream;
+}
+
+static DeviceInfo hda_audio_duplex_info = {
+    .name = "hda-duplex",
+    .desc = "HDA Audio Codec, duplex",
+    .size = sizeof(HDAAudioState),
+    .vmsd = &vmstate_hda_audio,
+    .props = hda_audio_properties,
+    .class_init = hda_audio_duplex_class_init,
 };
 
 static void hda_audio_register(void)
 {
-    hda_codec_register(&hda_audio_info_output);
-    hda_codec_register(&hda_audio_info_duplex);
+    hda_codec_register(&hda_audio_output_info);
+    hda_codec_register(&hda_audio_duplex_info);
 }
 device_init(hda_audio_register);
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 6e1c5de..f727c22 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -51,9 +51,8 @@ static int hda_codec_dev_init(DeviceState *qdev, DeviceInfo *base)
 {
     HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, qdev->parent_bus);
     HDACodecDevice *dev = DO_UPCAST(HDACodecDevice, qdev, qdev);
-    HDACodecDeviceInfo *info = DO_UPCAST(HDACodecDeviceInfo, qdev, base);
+    HDACodecDeviceClass *cdc = HDA_CODEC_DEVICE_GET_CLASS(dev);
 
-    dev->info = info;
     if (dev->cad == -1) {
         dev->cad = bus->next_cad;
     }
@@ -61,25 +60,26 @@ static int hda_codec_dev_init(DeviceState *qdev, DeviceInfo *base)
         return -1;
     }
     bus->next_cad = dev->cad + 1;
-    return info->init(dev);
+    return cdc->init(dev);
 }
 
 static int hda_codec_dev_exit(DeviceState *qdev)
 {
     HDACodecDevice *dev = DO_UPCAST(HDACodecDevice, qdev, qdev);
+    HDACodecDeviceClass *cdc = HDA_CODEC_DEVICE_GET_CLASS(dev);
 
-    if (dev->info->exit) {
-        dev->info->exit(dev);
+    if (cdc->exit) {
+        cdc->exit(dev);
     }
     return 0;
 }
 
-void hda_codec_register(HDACodecDeviceInfo *info)
+void hda_codec_register(DeviceInfo *info)
 {
-    info->qdev.init = hda_codec_dev_init;
-    info->qdev.exit = hda_codec_dev_exit;
-    info->qdev.bus_info = &hda_codec_bus_info;
-    qdev_register(&info->qdev);
+    info->init = hda_codec_dev_init;
+    info->exit = hda_codec_dev_exit;
+    info->bus_info = &hda_codec_bus_info;
+    qdev_register(info);
 }
 
 HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad)
@@ -283,6 +283,7 @@ static int intel_hda_send_command(IntelHDAState *d, uint32_t verb)
 {
     uint32_t cad, nid, data;
     HDACodecDevice *codec;
+    HDACodecDeviceClass *cdc;
 
     cad = (verb >> 28) & 0x0f;
     if (verb & (1 << 27)) {
@@ -298,7 +299,8 @@ static int intel_hda_send_command(IntelHDAState *d, uint32_t verb)
         dprint(d, 1, "%s: addressed non-existing codec\n", __FUNCTION__);
         return -1;
     }
-    codec->info->command(codec, nid, data);
+    cdc = HDA_CODEC_DEVICE_GET_CLASS(codec);
+    cdc->command(codec, nid, data);
     return 0;
 }
 
@@ -491,9 +493,12 @@ static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool runn
     HDACodecDevice *cdev;
 
     QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
+        HDACodecDeviceClass *cdc;
+
         cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
-        if (cdev->info->stream) {
-            cdev->info->stream(cdev, stream, running, output);
+        cdc = HDA_CODEC_DEVICE_GET_CLASS(cdev);
+        if (cdc->stream) {
+            cdc->stream(cdev, stream, running, output);
         }
     }
 }
diff --git a/hw/intel-hda.h b/hw/intel-hda.h
index 65fd2a8..f523587 100644
--- a/hw/intel-hda.h
+++ b/hw/intel-hda.h
@@ -6,9 +6,16 @@
 /* --------------------------------------------------------------------- */
 /* hda bus                                                               */
 
+#define TYPE_HDA_CODEC_DEVICE "hda-codec"
+#define HDA_CODEC_DEVICE(obj) \
+     OBJECT_CHECK(HDACodecDevice, (obj), TYPE_HDA_CODEC_DEVICE)
+#define HDA_CODEC_DEVICE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(HDACodecDeviceClass, (klass), TYPE_HDA_CODEC_DEVICE)
+#define HDA_CODEC_DEVICE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(HDACodecDeviceClass, (obj), TYPE_HDA_CODEC_DEVICE)
+
 typedef struct HDACodecBus HDACodecBus;
 typedef struct HDACodecDevice HDACodecDevice;
-typedef struct HDACodecDeviceInfo HDACodecDeviceInfo;
 
 typedef void (*hda_codec_response_func)(HDACodecDevice *dev,
                                         bool solicited, uint32_t response);
@@ -23,24 +30,25 @@ struct HDACodecBus {
     hda_codec_xfer_func xfer;
 };
 
-struct HDACodecDevice {
-    DeviceState         qdev;
-    HDACodecDeviceInfo  *info;
-    uint32_t            cad;    /* codec address */
-};
+typedef struct HDACodecDeviceClass
+{
+    DeviceClass parent_class;
 
-struct HDACodecDeviceInfo {
-    DeviceInfo qdev;
     int (*init)(HDACodecDevice *dev);
     int (*exit)(HDACodecDevice *dev);
     void (*command)(HDACodecDevice *dev, uint32_t nid, uint32_t data);
     void (*stream)(HDACodecDevice *dev, uint32_t stnr, bool running, bool output);
+} HDACodecDeviceClass;
+
+struct HDACodecDevice {
+    DeviceState         qdev;
+    uint32_t            cad;    /* codec address */
 };
 
 void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus,
                         hda_codec_response_func response,
                         hda_codec_xfer_func xfer);
-void hda_codec_register(HDACodecDeviceInfo *info);
+void hda_codec_register(DeviceInfo *info);
 HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad);
 
 void hda_codec_response(HDACodecDevice *dev, bool solicited, uint32_t response);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 19/28] ide: convert to QEMU Object Model
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (17 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 18/28] hda-codec: " Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 20/28] scsi: " Anthony Liguori
                   ` (11 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Anthony Liguori

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/ide/internal.h |   20 ++++++---
 hw/ide/qdev.c     |  111 +++++++++++++++++++++++++++++++++--------------------
 2 files changed, 82 insertions(+), 49 deletions(-)

diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 00b28df..c808a0d 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -21,7 +21,6 @@
 
 typedef struct IDEBus IDEBus;
 typedef struct IDEDevice IDEDevice;
-typedef struct IDEDeviceInfo IDEDeviceInfo;
 typedef struct IDEState IDEState;
 typedef struct IDEDMA IDEDMA;
 typedef struct IDEDMAOps IDEDMAOps;
@@ -450,6 +449,19 @@ struct IDEBus {
     int error_status;
 };
 
+#define TYPE_IDE_DEVICE "ide-device"
+#define IDE_DEVICE(obj) \
+     OBJECT_CHECK(IDEDevice, (obj), TYPE_IDE_DEVICE)
+#define IDE_DEVICE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(IDEDeviceClass, (klass), TYPE_IDE_DEVICE)
+#define IDE_DEVICE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(IDEDeviceClass, (obj), TYPE_IDE_DEVICE)
+
+typedef struct IDEDeviceClass {
+    DeviceClass parent_class;
+    int (*init)(IDEDevice *dev);
+} IDEDeviceClass;
+
 struct IDEDevice {
     DeviceState qdev;
     uint32_t unit;
@@ -458,12 +470,6 @@ struct IDEDevice {
     char *serial;
 };
 
-typedef int (*ide_qdev_initfn)(IDEDevice *dev);
-struct IDEDeviceInfo {
-    DeviceInfo qdev;
-    ide_qdev_initfn init;
-};
-
 #define BM_STATUS_DMAING 0x01
 #define BM_STATUS_ERROR  0x02
 #define BM_STATUS_INT    0x04
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 4207127..b507e34 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -55,8 +55,8 @@ static char *idebus_get_fw_dev_path(DeviceState *dev)
 
 static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base)
 {
-    IDEDevice *dev = DO_UPCAST(IDEDevice, qdev, qdev);
-    IDEDeviceInfo *info = DO_UPCAST(IDEDeviceInfo, qdev, base);
+    IDEDevice *dev = IDE_DEVICE(qdev);
+    IDEDeviceClass *dc = IDE_DEVICE_GET_CLASS(dev);
     IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev->parent_bus);
 
     if (!dev->conf.bs) {
@@ -85,17 +85,17 @@ static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base)
         error_report("Invalid IDE unit %d", dev->unit);
         goto err;
     }
-    return info->init(dev);
+    return dc->init(dev);
 
 err:
     return -1;
 }
 
-static void ide_qdev_register(IDEDeviceInfo *info)
+static void ide_qdev_register(DeviceInfo *info)
 {
-    info->qdev.init = ide_qdev_init;
-    info->qdev.bus_info = &ide_bus_info;
-    qdev_register(&info->qdev);
+    info->init = ide_qdev_init;
+    info->bus_info = &ide_bus_info;
+    qdev_register_subclass(info, TYPE_IDE_DEVICE);
 }
 
 IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive)
@@ -182,46 +182,73 @@ static int ide_drive_initfn(IDEDevice *dev)
     DEFINE_PROP_STRING("ver",  IDEDrive, dev.version),  \
     DEFINE_PROP_STRING("serial",  IDEDrive, dev.serial)
 
-static IDEDeviceInfo ide_dev_info[] = {
-    {
-        .qdev.name    = "ide-hd",
-        .qdev.fw_name = "drive",
-        .qdev.desc    = "virtual IDE disk",
-        .qdev.size    = sizeof(IDEDrive),
-        .init         = ide_hd_initfn,
-        .qdev.props   = (Property[]) {
-            DEFINE_IDE_DEV_PROPERTIES(),
-            DEFINE_PROP_END_OF_LIST(),
-        }
-    },{
-        .qdev.name    = "ide-cd",
-        .qdev.fw_name = "drive",
-        .qdev.desc    = "virtual IDE CD-ROM",
-        .qdev.size    = sizeof(IDEDrive),
-        .init         = ide_cd_initfn,
-        .qdev.props   = (Property[]) {
-            DEFINE_IDE_DEV_PROPERTIES(),
-            DEFINE_PROP_END_OF_LIST(),
-        }
-    },{
-        .qdev.name    = "ide-drive", /* legacy -device ide-drive */
-        .qdev.fw_name = "drive",
-        .qdev.desc    = "virtual IDE disk or CD-ROM (legacy)",
-        .qdev.size    = sizeof(IDEDrive),
-        .init         = ide_drive_initfn,
-        .qdev.props   = (Property[]) {
-            DEFINE_IDE_DEV_PROPERTIES(),
-            DEFINE_PROP_END_OF_LIST(),
-        }
+static void ide_hd_class_init(ObjectClass *klass, void *data)
+{
+    IDEDeviceClass *k = IDE_DEVICE_CLASS(klass);
+    k->init = ide_hd_initfn;
+}
+
+static DeviceInfo ide_hd_info = {
+    .name    = "ide-hd",
+    .fw_name = "drive",
+    .desc    = "virtual IDE disk",
+    .size    = sizeof(IDEDrive),
+    .class_init = ide_hd_class_init,
+    .props   = (Property[]) {
+        DEFINE_IDE_DEV_PROPERTIES(),
+        DEFINE_PROP_END_OF_LIST(),
     }
 };
 
-static void ide_dev_register(void)
+static void ide_cd_class_init(ObjectClass *klass, void *data)
 {
-    int i;
+    IDEDeviceClass *k = IDE_DEVICE_CLASS(klass);
+    k->init = ide_cd_initfn;
+}
 
-    for (i = 0; i < ARRAY_SIZE(ide_dev_info); i++) {
-        ide_qdev_register(&ide_dev_info[i]);
+static DeviceInfo ide_cd_info = {
+    .name    = "ide-cd",
+    .fw_name = "drive",
+    .desc    = "virtual IDE CD-ROM",
+    .size    = sizeof(IDEDrive),
+    .class_init = ide_cd_class_init,
+    .props   = (Property[]) {
+        DEFINE_IDE_DEV_PROPERTIES(),
+        DEFINE_PROP_END_OF_LIST(),
     }
+};
+
+static void ide_drive_class_init(ObjectClass *klass, void *data)
+{
+    IDEDeviceClass *k = IDE_DEVICE_CLASS(klass);
+    k->init = ide_drive_initfn;
+}
+
+static DeviceInfo ide_drive_info = {
+    .name    = "ide-drive", /* legacy -device ide-drive */
+    .fw_name = "drive",
+    .desc    = "virtual IDE disk or CD-ROM (legacy)",
+    .size    = sizeof(IDEDrive),
+    .class_init = ide_drive_class_init,
+    .props   = (Property[]) {
+        DEFINE_IDE_DEV_PROPERTIES(),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+static TypeInfo ide_device_type_info = {
+    .name = TYPE_IDE_DEVICE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(IDEDevice),
+    .abstract = true,
+    .class_size = sizeof(IDEDeviceClass),
+};
+
+static void ide_dev_register(void)
+{
+    ide_qdev_register(&ide_hd_info);
+    ide_qdev_register(&ide_cd_info);
+    ide_qdev_register(&ide_drive_info);
+    type_register_static(&ide_device_type_info);
 }
 device_init(ide_dev_register);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 20/28] scsi: convert to QEMU Object Model
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (18 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 19/28] ide: " Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 21/28] spapr: convert to QEMU Object Model (v2) Anthony Liguori
                   ` (10 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Anthony Liguori, Paul Brook

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/scsi-bus.c     |   95 +++++++++++++++++++++++---------
 hw/scsi-disk.c    |  159 ++++++++++++++++++++++++++++++++---------------------
 hw/scsi-generic.c |   29 ++++++----
 hw/scsi.h         |   31 ++++++----
 4 files changed, 201 insertions(+), 113 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 64e709e..d017ece 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -23,6 +23,42 @@ static struct BusInfo scsi_bus_info = {
 };
 static int next_scsi_bus;
 
+static int scsi_device_init(SCSIDevice *s)
+{
+    SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s);
+    if (sc->init) {
+        return sc->init(s);
+    }
+    return 0;
+}
+
+static void scsi_device_destroy(SCSIDevice *s)
+{
+    SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s);
+    if (sc->destroy) {
+        sc->destroy(s);
+    }
+}
+
+static SCSIRequest *scsi_device_alloc_req(SCSIDevice *s, uint32_t tag, uint32_t lun,
+                                          uint8_t *buf, void *hba_private)
+{
+    SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s);
+    if (sc->alloc_req) {
+        return sc->alloc_req(s, tag, lun, buf, hba_private);
+    }
+
+    return NULL;
+}
+
+static void scsi_device_unit_attention_reported(SCSIDevice *s)
+{
+    SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s);
+    if (sc->unit_attention_reported) {
+        sc->unit_attention_reported(s);
+    }
+}
+
 /* Create a scsi bus, and attach devices to it.  */
 void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info)
 {
@@ -81,8 +117,7 @@ static void scsi_dma_restart_cb(void *opaque, int running, RunState state)
 
 static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
 {
-    SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
-    SCSIDeviceInfo *info = DO_UPCAST(SCSIDeviceInfo, qdev, base);
+    SCSIDevice *dev = SCSI_DEVICE(qdev);
     SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
     SCSIDevice *d;
     int rc = -1;
@@ -126,9 +161,8 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
         }
     }
 
-    dev->info = info;
     QTAILQ_INIT(&dev->requests);
-    rc = dev->info->init(dev);
+    rc = scsi_device_init(dev);
     if (rc == 0) {
         dev->vmsentry = qemu_add_vm_change_state_handler(scsi_dma_restart_cb,
                                                          dev);
@@ -140,24 +174,22 @@ err:
 
 static int scsi_qdev_exit(DeviceState *qdev)
 {
-    SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
+    SCSIDevice *dev = SCSI_DEVICE(qdev);
 
     if (dev->vmsentry) {
         qemu_del_vm_change_state_handler(dev->vmsentry);
     }
-    if (dev->info->destroy) {
-        dev->info->destroy(dev);
-    }
+    scsi_device_destroy(dev);
     return 0;
 }
 
-void scsi_qdev_register(SCSIDeviceInfo *info)
+void scsi_qdev_register(DeviceInfo *info)
 {
-    info->qdev.bus_info = &scsi_bus_info;
-    info->qdev.init     = scsi_qdev_init;
-    info->qdev.unplug   = qdev_simple_unplug_cb;
-    info->qdev.exit     = scsi_qdev_exit;
-    qdev_register(&info->qdev);
+    info->bus_info = &scsi_bus_info;
+    info->init     = scsi_qdev_init;
+    info->unplug   = qdev_simple_unplug_cb;
+    info->exit     = scsi_qdev_exit;
+    qdev_register_subclass(info, TYPE_SCSI_DEVICE);
 }
 
 /* handle legacy '-drive if=scsi,...' cmd line args */
@@ -182,7 +214,7 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
     }
     if (qdev_init(dev) < 0)
         return NULL;
-    return DO_UPCAST(SCSIDevice, qdev, dev);
+    return SCSI_DEVICE(dev);
 }
 
 int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
@@ -278,7 +310,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
     found_lun0 = false;
     n = 0;
     QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) {
-        SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
+        SCSIDevice *dev = SCSI_DEVICE(qdev);
 
         if (dev->channel == channel && dev->id == id) {
             if (dev->lun == 0) {
@@ -300,7 +332,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
     stl_be_p(&r->buf, n);
     i = found_lun0 ? 8 : 16;
     QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) {
-        SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
+        SCSIDevice *dev = SCSI_DEVICE(qdev);
 
         if (dev->channel == channel && dev->id == id) {
             store_lun(&r->buf[i], dev->lun);
@@ -398,9 +430,7 @@ static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)
                                        MIN(req->cmd.xfer, sizeof r->buf),
                                        (req->cmd.buf[1] & 1) == 0);
         if (r->req.dev->sense_is_ua) {
-            if (r->req.dev->info->unit_attention_reported) {
-                r->req.dev->info->unit_attention_reported(req->dev);
-            }
+            scsi_device_unit_attention_reported(req->dev);
             r->req.dev->sense_len = 0;
             r->req.dev->sense_is_ua = false;
         }
@@ -507,7 +537,7 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
             req = scsi_req_alloc(&reqops_target_command, d, tag, lun,
                                  hba_private);
         } else {
-            req = d->info->alloc_req(d, tag, lun, buf, hba_private);
+            req = scsi_device_alloc_req(d, tag, lun, buf, hba_private);
         }
     }
 
@@ -597,9 +627,7 @@ int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len)
      * Here we handle unit attention clearing for UA_INTLCK_CTRL == 00b.
      */
     if (req->dev->sense_is_ua) {
-        if (req->dev->info->unit_attention_reported) {
-            req->dev->info->unit_attention_reported(req->dev);
-        }
+        scsi_device_unit_attention_reported(req->dev);
         req->dev->sense_len = 0;
         req->dev->sense_is_ua = false;
     }
@@ -1367,7 +1395,7 @@ void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense)
 
 static char *scsibus_get_fw_dev_path(DeviceState *dev)
 {
-    SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev);
+    SCSIDevice *d = SCSI_DEVICE(dev);
     char path[100];
 
     snprintf(path, sizeof(path), "channel@%x/%s@%x,%x", d->channel,
@@ -1382,7 +1410,7 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun)
     SCSIDevice *target_dev = NULL;
 
     QTAILQ_FOREACH_REVERSE(qdev, &bus->qbus.children, ChildrenHead, sibling) {
-        SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
+        SCSIDevice *dev = SCSI_DEVICE(qdev);
 
         if (dev->channel == channel && dev->id == id) {
             if (dev->lun == lun) {
@@ -1393,3 +1421,18 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun)
     }
     return target_dev;
 }
+
+static TypeInfo scsi_device_type_info = {
+    .name = TYPE_SCSI_DEVICE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(SCSIDevice),
+    .abstract = true,
+    .class_size = sizeof(SCSIDeviceClass),
+};
+
+static void scsi_register_devices(void)
+{
+    type_register_static(&scsi_device_type_info);
+}
+
+device_init(scsi_register_devices);
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 5d8bf53..cb61d82 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1720,75 +1720,108 @@ static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
     DEFINE_PROP_STRING("ver",  SCSIDiskState, version),         \
     DEFINE_PROP_STRING("serial",  SCSIDiskState, serial)
 
-static SCSIDeviceInfo scsi_disk_info[] = {
-    {
-        .qdev.name    = "scsi-hd",
-        .qdev.fw_name = "disk",
-        .qdev.desc    = "virtual SCSI disk",
-        .qdev.size    = sizeof(SCSIDiskState),
-        .qdev.reset   = scsi_disk_reset,
-        .init         = scsi_hd_initfn,
-        .destroy      = scsi_destroy,
-        .alloc_req    = scsi_new_request,
-        .unit_attention_reported = scsi_disk_unit_attention_reported,
-        .qdev.props   = (Property[]) {
-            DEFINE_SCSI_DISK_PROPERTIES(),
-            DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
-            DEFINE_PROP_END_OF_LIST(),
-        }
-    },{
-        .qdev.name    = "scsi-cd",
-        .qdev.fw_name = "disk",
-        .qdev.desc    = "virtual SCSI CD-ROM",
-        .qdev.size    = sizeof(SCSIDiskState),
-        .qdev.reset   = scsi_disk_reset,
-        .init         = scsi_cd_initfn,
-        .destroy      = scsi_destroy,
-        .alloc_req    = scsi_new_request,
-        .unit_attention_reported = scsi_disk_unit_attention_reported,
-        .qdev.props   = (Property[]) {
-            DEFINE_SCSI_DISK_PROPERTIES(),
-            DEFINE_PROP_END_OF_LIST(),
-        },
+static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
+{
+    SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
+
+    sc->init         = scsi_hd_initfn;
+    sc->destroy      = scsi_destroy;
+    sc->alloc_req    = scsi_new_request;
+    sc->unit_attention_reported = scsi_disk_unit_attention_reported;
+}
+
+static DeviceInfo scsi_hd_info = {
+    .name    = "scsi-hd",
+    .fw_name = "disk",
+    .desc    = "virtual SCSI disk",
+    .size    = sizeof(SCSIDiskState),
+    .reset   = scsi_disk_reset,
+    .class_init = scsi_hd_class_initfn,
+    .props   = (Property[]) {
+        DEFINE_SCSI_DISK_PROPERTIES(),
+        DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
+
+static void scsi_cd_class_initfn(ObjectClass *klass, void *data)
+{
+    SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
+
+    sc->init         = scsi_cd_initfn;
+    sc->destroy      = scsi_destroy;
+    sc->alloc_req    = scsi_new_request;
+    sc->unit_attention_reported = scsi_disk_unit_attention_reported;
+}
+
+static DeviceInfo scsi_cd_info = {
+    .name    = "scsi-cd",
+    .fw_name = "disk",
+    .desc    = "virtual SCSI CD-ROM",
+    .size    = sizeof(SCSIDiskState),
+    .reset   = scsi_disk_reset,
+    .class_init = scsi_cd_class_initfn,
+    .props   = (Property[]) {
+        DEFINE_SCSI_DISK_PROPERTIES(),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
+
 #ifdef __linux__
-    },{
-        .qdev.name    = "scsi-block",
-        .qdev.fw_name = "disk",
-        .qdev.desc    = "SCSI block device passthrough",
-        .qdev.size    = sizeof(SCSIDiskState),
-        .qdev.reset   = scsi_disk_reset,
-        .init         = scsi_block_initfn,
-        .destroy      = scsi_destroy,
-        .alloc_req    = scsi_block_new_request,
-        .qdev.props   = (Property[]) {
-            DEFINE_SCSI_DISK_PROPERTIES(),
-            DEFINE_PROP_END_OF_LIST(),
-        },
+static void scsi_block_class_initfn(ObjectClass *klass, void *data)
+{
+    SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
+
+    sc->init         = scsi_block_initfn;
+    sc->destroy      = scsi_destroy;
+    sc->alloc_req    = scsi_block_new_request;
+}
+
+static DeviceInfo scsi_block_info = {
+    .name    = "scsi-block",
+    .fw_name = "disk",
+    .desc    = "SCSI block device passthrough",
+    .size    = sizeof(SCSIDiskState),
+    .reset   = scsi_disk_reset,
+    .class_init = scsi_block_class_initfn,
+    .props   = (Property[]) {
+        DEFINE_SCSI_DISK_PROPERTIES(),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
 #endif
-    },{
-        .qdev.name    = "scsi-disk", /* legacy -device scsi-disk */
-        .qdev.fw_name = "disk",
-        .qdev.desc    = "virtual SCSI disk or CD-ROM (legacy)",
-        .qdev.size    = sizeof(SCSIDiskState),
-        .qdev.reset   = scsi_disk_reset,
-        .init         = scsi_disk_initfn,
-        .destroy      = scsi_destroy,
-        .alloc_req    = scsi_new_request,
-        .unit_attention_reported = scsi_disk_unit_attention_reported,
-        .qdev.props   = (Property[]) {
-            DEFINE_SCSI_DISK_PROPERTIES(),
-            DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
-            DEFINE_PROP_END_OF_LIST(),
-        }
+
+static void scsi_disk_class_initfn(ObjectClass *klass, void *data)
+{
+    SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
+
+    sc->init         = scsi_disk_initfn;
+    sc->destroy      = scsi_destroy;
+    sc->alloc_req    = scsi_new_request;
+    sc->unit_attention_reported = scsi_disk_unit_attention_reported;
+}
+
+static DeviceInfo scsi_disk_info = {
+    .name    = "scsi-disk", /* legacy -device scsi-disk */
+    .fw_name = "disk",
+    .desc    = "virtual SCSI disk or CD-ROM (legacy)",
+    .size    = sizeof(SCSIDiskState),
+    .reset   = scsi_disk_reset,
+    .class_init = scsi_disk_class_initfn,
+    .props   = (Property[]) {
+        DEFINE_SCSI_DISK_PROPERTIES(),
+        DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
+        DEFINE_PROP_END_OF_LIST(),
     }
 };
 
 static void scsi_disk_register_devices(void)
 {
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(scsi_disk_info); i++) {
-        scsi_qdev_register(&scsi_disk_info[i]);
-    }
+    scsi_qdev_register(&scsi_hd_info);
+    scsi_qdev_register(&scsi_cd_info);
+#ifdef __linux__
+    scsi_qdev_register(&scsi_block_info);
+#endif
+    scsi_qdev_register(&scsi_disk_info);
 }
 device_init(scsi_disk_register_devices)
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 0aebcdd..5cf4005 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -357,7 +357,7 @@ static int get_stream_blocksize(BlockDriverState *bdrv)
 
 static void scsi_generic_reset(DeviceState *dev)
 {
-    SCSIDevice *s = DO_UPCAST(SCSIDevice, qdev, dev);
+    SCSIDevice *s = SCSI_DEVICE(dev);
 
     scsi_device_purge_requests(s, SENSE_CODE(RESET));
 }
@@ -457,16 +457,23 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
     return req;
 }
 
-static SCSIDeviceInfo scsi_generic_info = {
-    .qdev.name    = "scsi-generic",
-    .qdev.fw_name = "disk",
-    .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
-    .qdev.size    = sizeof(SCSIDevice),
-    .qdev.reset   = scsi_generic_reset,
-    .init         = scsi_generic_initfn,
-    .destroy      = scsi_destroy,
-    .alloc_req    = scsi_new_request,
-    .qdev.props   = (Property[]) {
+static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
+{
+    SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
+
+    sc->init         = scsi_generic_initfn;
+    sc->destroy      = scsi_destroy;
+    sc->alloc_req    = scsi_new_request;
+}
+
+static DeviceInfo scsi_generic_info = {
+    .name    = "scsi-generic",
+    .fw_name = "disk",
+    .desc    = "pass through generic scsi device (/dev/sg*)",
+    .size    = sizeof(SCSIDevice),
+    .reset   = scsi_generic_reset,
+    .class_init = scsi_generic_class_initfn,
+    .props   = (Property[]) {
         DEFINE_BLOCK_PROPERTIES(SCSIDevice, conf),
         DEFINE_PROP_END_OF_LIST(),
     },
diff --git a/hw/scsi.h b/hw/scsi.h
index ab6e952..4290b20 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -13,7 +13,6 @@ typedef struct SCSIBus SCSIBus;
 typedef struct SCSIBusInfo SCSIBusInfo;
 typedef struct SCSICommand SCSICommand;
 typedef struct SCSIDevice SCSIDevice;
-typedef struct SCSIDeviceInfo SCSIDeviceInfo;
 typedef struct SCSIRequest SCSIRequest;
 typedef struct SCSIReqOps SCSIReqOps;
 
@@ -58,6 +57,23 @@ struct SCSIRequest {
     QTAILQ_ENTRY(SCSIRequest) next;
 };
 
+#define TYPE_SCSI_DEVICE "scsi-device"
+#define SCSI_DEVICE(obj) \
+     OBJECT_CHECK(SCSIDevice, (obj), TYPE_SCSI_DEVICE)
+#define SCSI_DEVICE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(SCSIDeviceClass, (klass), TYPE_SCSI_DEVICE)
+#define SCSI_DEVICE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(SCSIDeviceClass, (obj), TYPE_SCSI_DEVICE)
+
+typedef struct SCSIDeviceClass {
+    DeviceClass parent_class;
+    int (*init)(SCSIDevice *dev);
+    void (*destroy)(SCSIDevice *s);
+    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
+                              uint8_t *buf, void *hba_private);
+    void (*unit_attention_reported)(SCSIDevice *s);
+} SCSIDeviceClass;
+
 struct SCSIDevice
 {
     DeviceState qdev;
@@ -65,7 +81,6 @@ struct SCSIDevice
     QEMUBH *bh;
     uint32_t id;
     BlockConf conf;
-    SCSIDeviceInfo *info;
     SCSISense unit_attention;
     bool sense_is_ua;
     uint8_t sense[SCSI_SENSE_BUF_SIZE];
@@ -93,16 +108,6 @@ struct SCSIReqOps {
     uint8_t *(*get_buf)(SCSIRequest *req);
 };
 
-typedef int (*scsi_qdev_initfn)(SCSIDevice *dev);
-struct SCSIDeviceInfo {
-    DeviceInfo qdev;
-    scsi_qdev_initfn init;
-    void (*destroy)(SCSIDevice *s);
-    SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
-                              uint8_t *buf, void *hba_private);
-    void (*unit_attention_reported)(SCSIDevice *s);
-};
-
 struct SCSIBusInfo {
     int tcq;
     int max_channel, max_target, max_lun;
@@ -120,7 +125,7 @@ struct SCSIBus {
 };
 
 void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info);
-void scsi_qdev_register(SCSIDeviceInfo *info);
+void scsi_qdev_register(DeviceInfo *info);
 
 static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
 {
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 21/28] spapr: convert to QEMU Object Model (v2)
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (19 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 20/28] scsi: " Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 22/28] virtio-serial: convert to QEMU Object Model Anthony Liguori
                   ` (9 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
v1 -> v2
 - use QOM to check for the default console
---
 hw/spapr_llan.c  |   37 ++++++++++++++++++++++-------------
 hw/spapr_vio.c   |   55 ++++++++++++++++++++++++++++++++---------------------
 hw/spapr_vio.h   |   35 +++++++++++++++++++++++++--------
 hw/spapr_vscsi.c |   35 +++++++++++++++++++++------------
 hw/spapr_vty.c   |   35 +++++++++++++++++++++------------
 5 files changed, 126 insertions(+), 71 deletions(-)

diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c
index b9a5afc..0fb176a 100644
--- a/hw/spapr_llan.c
+++ b/hw/spapr_llan.c
@@ -474,20 +474,29 @@ static target_ulong h_multicast_ctrl(CPUState *env, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static VIOsPAPRDeviceInfo spapr_vlan_info = {
-    .init = spapr_vlan_init,
-    .devnode = spapr_vlan_devnode,
-    .dt_name = "l-lan",
-    .dt_type = "network",
-    .dt_compatible = "IBM,l-lan",
-    .signal_mask = 0x1,
-    .qdev.name = "spapr-vlan",
-    .qdev.size = sizeof(VIOsPAPRVLANDevice),
-    .qdev.props = (Property[]) {
-        DEFINE_SPAPR_PROPERTIES(VIOsPAPRVLANDevice, sdev, 0x1000, 0x10000000),
-        DEFINE_NIC_PROPERTIES(VIOsPAPRVLANDevice, nicconf),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property spapr_vlan_properties[] = {
+    DEFINE_SPAPR_PROPERTIES(VIOsPAPRVLANDevice, sdev, 0x1000, 0x10000000),
+    DEFINE_NIC_PROPERTIES(VIOsPAPRVLANDevice, nicconf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void spapr_vlan_class_init(ObjectClass *klass, void *data)
+{
+    VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
+
+    k->init = spapr_vlan_init;
+    k->devnode = spapr_vlan_devnode;
+    k->dt_name = "l-lan";
+    k->dt_type = "network";
+    k->dt_compatible = "IBM,l-lan";
+    k->signal_mask = 0x1;
+}
+
+static DeviceInfo spapr_vlan_info = {
+    .name = "spapr-vlan",
+    .size = sizeof(VIOsPAPRVLANDevice),
+    .props = spapr_vlan_properties,
+    .class_init = spapr_vlan_class_init,
 };
 
 static void spapr_vlan_register(void)
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 0159413..bc586bf 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -75,11 +75,11 @@ VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
 
 static char *vio_format_dev_name(VIOsPAPRDevice *dev)
 {
-    VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qdev_get_info(&dev->qdev);
+    VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
     char *name;
 
     /* Device tree style name device@reg */
-    if (asprintf(&name, "%s@%x", info->dt_name, dev->reg) < 0) {
+    if (asprintf(&name, "%s@%x", pc->dt_name, dev->reg) < 0) {
         return NULL;
     }
 
@@ -90,7 +90,7 @@ static char *vio_format_dev_name(VIOsPAPRDevice *dev)
 static int vio_make_devnode(VIOsPAPRDevice *dev,
                             void *fdt)
 {
-    VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qdev_get_info(&dev->qdev);
+    VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
     int vdevice_off, node_off, ret;
     char *dt_name;
 
@@ -115,17 +115,17 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
         return ret;
     }
 
-    if (info->dt_type) {
+    if (pc->dt_type) {
         ret = fdt_setprop_string(fdt, node_off, "device_type",
-                                 info->dt_type);
+                                 pc->dt_type);
         if (ret < 0) {
             return ret;
         }
     }
 
-    if (info->dt_compatible) {
+    if (pc->dt_compatible) {
         ret = fdt_setprop_string(fdt, node_off, "compatible",
-                                 info->dt_compatible);
+                                 pc->dt_compatible);
         if (ret < 0) {
             return ret;
         }
@@ -163,8 +163,8 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
         }
     }
 
-    if (info->devnode) {
-        ret = (info->devnode)(dev, fdt, node_off);
+    if (pc->devnode) {
+        ret = (pc->devnode)(dev, fdt, node_off);
         if (ret < 0) {
             return ret;
         }
@@ -621,7 +621,7 @@ static void rtas_quiesce(sPAPREnvironment *spapr, uint32_t token,
     rtas_st(rets, 0, 0);
 }
 
-static int spapr_vio_check_reg(VIOsPAPRDevice *sdev, VIOsPAPRDeviceInfo *info)
+static int spapr_vio_check_reg(VIOsPAPRDevice *sdev)
 {
     VIOsPAPRDevice *other_sdev;
     DeviceState *qdev;
@@ -639,7 +639,9 @@ static int spapr_vio_check_reg(VIOsPAPRDevice *sdev, VIOsPAPRDeviceInfo *info)
 
         if (other_sdev != sdev && other_sdev->reg == sdev->reg) {
             fprintf(stderr, "vio: %s and %s devices conflict at address %#x\n",
-                    info->qdev.name, other_sdev->qdev.info->name, sdev->reg);
+                    object_get_typename(OBJECT(sdev)),
+                    object_get_typename(OBJECT(qdev)),
+                    sdev->reg);
             return -EEXIST;
         }
     }
@@ -649,12 +651,12 @@ static int spapr_vio_check_reg(VIOsPAPRDevice *sdev, VIOsPAPRDeviceInfo *info)
 
 static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo)
 {
-    VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
     VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
+    VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
     char *id;
     int ret;
 
-    ret = spapr_vio_check_reg(dev, info);
+    ret = spapr_vio_check_reg(dev);
     if (ret) {
         return ret;
     }
@@ -675,16 +677,16 @@ static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo)
 
     rtce_init(dev);
 
-    return info->init(dev);
+    return pc->init(dev);
 }
 
-void spapr_vio_bus_register_withprop(VIOsPAPRDeviceInfo *info)
+void spapr_vio_bus_register_withprop(DeviceInfo *info)
 {
-    info->qdev.init = spapr_vio_busdev_init;
-    info->qdev.bus_info = &spapr_vio_bus_info;
+    info->init = spapr_vio_busdev_init;
+    info->bus_info = &spapr_vio_bus_info;
 
-    assert(info->qdev.size >= sizeof(VIOsPAPRDevice));
-    qdev_register(&info->qdev);
+    assert(info->size >= sizeof(VIOsPAPRDevice));
+    qdev_register_subclass(info, TYPE_VIO_SPAPR_DEVICE);
 }
 
 static target_ulong h_vio_signal(CPUState *env, sPAPREnvironment *spapr,
@@ -694,15 +696,15 @@ static target_ulong h_vio_signal(CPUState *env, sPAPREnvironment *spapr,
     target_ulong reg = args[0];
     target_ulong mode = args[1];
     VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
-    VIOsPAPRDeviceInfo *info;
+    VIOsPAPRDeviceClass *pc;
 
     if (!dev) {
         return H_PARAMETER;
     }
 
-    info = (VIOsPAPRDeviceInfo *)qdev_get_info(&dev->qdev);
+    pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
 
-    if (mode & ~info->signal_mask) {
+    if (mode & ~pc->signal_mask) {
         return H_PARAMETER;
     }
 
@@ -760,9 +762,18 @@ static SysBusDeviceInfo spapr_vio_bridge_info = {
     .qdev.no_user = 1,
 };
 
+static TypeInfo spapr_vio_type_info = {
+    .name = TYPE_VIO_SPAPR_DEVICE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(VIOsPAPRDevice),
+    .abstract = true,
+    .class_size = sizeof(VIOsPAPRDeviceClass),
+};
+
 static void spapr_vio_register_devices(void)
 {
     sysbus_register_withprop(&spapr_vio_bridge_info);
+    type_register_static(&spapr_vio_type_info);
 }
 
 device_init(spapr_vio_register_devices)
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index 0984d55..7d1155a 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -34,6 +34,14 @@ enum VIOsPAPR_TCEAccess {
 
 #define SPAPR_VTY_BASE_ADDRESS     0x30000000
 
+#define TYPE_VIO_SPAPR_DEVICE "vio-spapr-device"
+#define VIO_SPAPR_DEVICE(obj) \
+     OBJECT_CHECK(VIOsPAPRDevice, (obj), TYPE_VIO_SPAPR_DEVICE)
+#define VIO_SPAPR_DEVICE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(VIOsPAPRDeviceClass, (klass), TYPE_VIO_SPAPR_DEVICE)
+#define VIO_SPAPR_DEVICE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(VIOsPAPRDeviceClass, (obj), TYPE_VIO_SPAPR_DEVICE)
+
 struct VIOsPAPRDevice;
 
 typedef struct VIOsPAPR_RTCE {
@@ -47,7 +55,20 @@ typedef struct VIOsPAPR_CRQ {
     int(*SendFunc)(struct VIOsPAPRDevice *vdev, uint8_t *crq);
 } VIOsPAPR_CRQ;
 
-typedef struct VIOsPAPRDevice {
+typedef struct VIOsPAPRDevice VIOsPAPRDevice;
+typedef struct VIOsPAPRBus VIOsPAPRBus;
+
+typedef struct VIOsPAPRDeviceClass {
+    DeviceClass parent_class;
+
+    const char *dt_name, *dt_type, *dt_compatible;
+    target_ulong signal_mask;
+    int (*init)(VIOsPAPRDevice *dev);
+    void (*hcalls)(VIOsPAPRBus *bus);
+    int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
+} VIOsPAPRDeviceClass;
+
+struct VIOsPAPRDevice {
     DeviceState qdev;
     uint32_t reg;
     uint32_t flags;
@@ -59,28 +80,24 @@ typedef struct VIOsPAPRDevice {
     VIOsPAPR_RTCE *rtce_table;
     int kvmtce_fd;
     VIOsPAPR_CRQ crq;
-} VIOsPAPRDevice;
+};
 
 #define DEFINE_SPAPR_PROPERTIES(type, field, default_reg, default_dma_window) \
         DEFINE_PROP_UINT32("reg", type, field.reg, default_reg), \
         DEFINE_PROP_UINT32("dma-window", type, field.rtce_window_size, \
                            default_dma_window)
 
-typedef struct VIOsPAPRBus {
+struct VIOsPAPRBus {
     BusState bus;
-} VIOsPAPRBus;
-
-typedef struct {
-    DeviceInfo qdev;
     const char *dt_name, *dt_type, *dt_compatible;
     target_ulong signal_mask;
     int (*init)(VIOsPAPRDevice *dev);
     int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
-} VIOsPAPRDeviceInfo;
+};
 
 extern VIOsPAPRBus *spapr_vio_bus_init(void);
 extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg);
-extern void spapr_vio_bus_register_withprop(VIOsPAPRDeviceInfo *info);
+extern void spapr_vio_bus_register_withprop(DeviceInfo *info);
 extern int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt);
 extern int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus);
 
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index 21d946e..b83bb7f 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -947,19 +947,28 @@ static int spapr_vscsi_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
     return 0;
 }
 
-static VIOsPAPRDeviceInfo spapr_vscsi_info = {
-    .init = spapr_vscsi_init,
-    .devnode = spapr_vscsi_devnode,
-    .dt_name = "v-scsi",
-    .dt_type = "vscsi",
-    .dt_compatible = "IBM,v-scsi",
-    .signal_mask = 0x00000001,
-    .qdev.name = "spapr-vscsi",
-    .qdev.size = sizeof(VSCSIState),
-    .qdev.props = (Property[]) {
-        DEFINE_SPAPR_PROPERTIES(VSCSIState, vdev, 0x2000, 0x10000000),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property spapr_vscsi_properties[] = {
+    DEFINE_SPAPR_PROPERTIES(VSCSIState, vdev, 0x2000, 0x10000000),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void spapr_vscsi_class_init(ObjectClass *klass, void *data)
+{
+    VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
+
+    k->init = spapr_vscsi_init;
+    k->devnode = spapr_vscsi_devnode;
+    k->dt_name = "v-scsi";
+    k->dt_type = "vscsi";
+    k->dt_compatible = "IBM,v-scsi";
+    k->signal_mask = 0x00000001;
+}
+
+static DeviceInfo spapr_vscsi_info = {
+    .name = "spapr-vscsi",
+    .size = sizeof(VSCSIState),
+    .props = spapr_vscsi_properties,
+    .class_init = spapr_vscsi_class_init,
 };
 
 static void spapr_vscsi_register(void)
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index 3d5c579..1780ffe 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -135,18 +135,27 @@ void spapr_vty_create(VIOsPAPRBus *bus, uint32_t reg, CharDriverState *chardev)
     qdev_init_nofail(dev);
 }
 
-static VIOsPAPRDeviceInfo spapr_vty_info = {
-    .init = spapr_vty_init,
-    .dt_name = "vty",
-    .dt_type = "serial",
-    .dt_compatible = "hvterm1",
-    .qdev.name = "spapr-vty",
-    .qdev.size = sizeof(VIOsPAPRVTYDevice),
-    .qdev.props = (Property[]) {
-        DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev, SPAPR_VTY_BASE_ADDRESS, 0),
-        DEFINE_PROP_CHR("chardev", VIOsPAPRVTYDevice, chardev),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property spapr_vty_properties[] = {
+    DEFINE_SPAPR_PROPERTIES(VIOsPAPRVTYDevice, sdev, SPAPR_VTY_BASE_ADDRESS, 0),
+    DEFINE_PROP_CHR("chardev", VIOsPAPRVTYDevice, chardev),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void spapr_vty_class_init(ObjectClass *klass, void *data)
+{
+    VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
+
+    k->init = spapr_vty_init;
+    k->dt_name = "vty";
+    k->dt_type = "serial";
+    k->dt_compatible = "hvterm1";
+}
+
+static DeviceInfo spapr_vty_info = {
+    .name = "spapr-vty",
+    .size = sizeof(VIOsPAPRVTYDevice),
+    .props = spapr_vty_properties,
+    .class_init = spapr_vty_class_init,
 };
 
 VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
@@ -163,7 +172,7 @@ VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
     selected = NULL;
     QTAILQ_FOREACH(iter, &bus->bus.children, sibling) {
         /* Only look at VTY devices */
-        if (qdev_get_info(iter) != &spapr_vty_info.qdev) {
+        if (!object_dynamic_cast(OBJECT(iter), "spapr-vty")) {
             continue;
         }
 
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 22/28] virtio-serial: convert to QEMU Object Model
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (20 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 21/28] spapr: convert to QEMU Object Model (v2) Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:59   ` Amit Shah
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 23/28] unin_pci: Clean up qdev names Anthony Liguori
                   ` (8 subsequent siblings)
  30 siblings, 1 reply; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Amit Shah, Anthony Liguori

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/virtio-console.c    |   69 +++++++++++++++++++++++++---------------
 hw/virtio-serial-bus.c |   68 ++++++++++++++++++++++++----------------
 hw/virtio-serial.h     |   81 ++++++++++++++++++++++++++----------------------
 3 files changed, 128 insertions(+), 90 deletions(-)

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index f25adc4..73c3935 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -109,10 +109,9 @@ static void chr_event(void *opaque, int event)
 static int virtconsole_initfn(VirtIOSerialPort *port)
 {
     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
-    VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev,
-                                           qdev_get_info(&vcon->port.dev));
+    VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);
 
-    if (port->id == 0 && !info->is_console) {
+    if (port->id == 0 && !k->is_console) {
         error_report("Port number 0 on virtio-serial devices reserved for virtconsole devices for backward compatibility.");
         return -1;
     }
@@ -125,18 +124,27 @@ static int virtconsole_initfn(VirtIOSerialPort *port)
     return 0;
 }
 
-static VirtIOSerialPortInfo virtconsole_info = {
-    .qdev.name     = "virtconsole",
-    .qdev.size     = sizeof(VirtConsole),
-    .is_console    = true,
-    .init          = virtconsole_initfn,
-    .have_data     = flush_buf,
-    .guest_open    = guest_open,
-    .guest_close   = guest_close,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_CHR("chardev", VirtConsole, chr),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property virtconsole_properties[] = {
+    DEFINE_PROP_CHR("chardev", VirtConsole, chr),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtconsole_class_init(ObjectClass *klass, void *data)
+{
+    VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
+
+    k->is_console = true;
+    k->init = virtconsole_initfn;
+    k->have_data = flush_buf;
+    k->guest_open = guest_open;
+    k->guest_close = guest_close;
+}
+
+static DeviceInfo virtconsole_info = {
+    .name = "virtconsole",
+    .size = sizeof(VirtConsole),
+    .props = virtconsole_properties,
+    .class_init = virtconsole_class_init,
 };
 
 static void virtconsole_register(void)
@@ -145,17 +153,26 @@ static void virtconsole_register(void)
 }
 device_init(virtconsole_register)
 
-static VirtIOSerialPortInfo virtserialport_info = {
-    .qdev.name     = "virtserialport",
-    .qdev.size     = sizeof(VirtConsole),
-    .init          = virtconsole_initfn,
-    .have_data     = flush_buf,
-    .guest_open    = guest_open,
-    .guest_close   = guest_close,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_CHR("chardev", VirtConsole, chr),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property virtserialport_properties[] = {
+    DEFINE_PROP_CHR("chardev", VirtConsole, chr),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtserialport_class_init(ObjectClass *klass, void *data)
+{
+    VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
+
+    k->init = virtconsole_initfn;
+    k->have_data = flush_buf;
+    k->guest_open = guest_open;
+    k->guest_close = guest_close;
+}
+
+static DeviceInfo virtserialport_info = {
+    .name = "virtserialport",
+    .size = sizeof(VirtConsole),
+    .props = virtserialport_properties,
+    .class_init = virtserialport_class_init,
 };
 
 static void virtserialport_register(void)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 982ffbf..edf54d7 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -133,12 +133,12 @@ static void discard_vq_data(VirtQueue *vq, VirtIODevice *vdev)
 static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
                                  VirtIODevice *vdev)
 {
-    VirtIOSerialPortInfo *info;
+    VirtIOSerialPortClass *vsc;
 
     assert(port);
     assert(virtio_queue_ready(vq));
 
-    info = DO_UPCAST(VirtIOSerialPortInfo, qdev, qdev_get_info(&port->dev));
+    vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
 
     while (!port->throttled) {
         unsigned int i;
@@ -157,7 +157,7 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
             ssize_t ret;
 
             buf_size = port->elem.out_sg[i].iov_len - port->iov_offset;
-            ret = info->have_data(port,
+            ret = vsc->have_data(port,
                                   port->elem.out_sg[i].iov_base
                                   + port->iov_offset,
                                   buf_size);
@@ -176,7 +176,7 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
                  * 1: chardevs can notify frondends
                  * 2: the guest driver does not spin in these cases
                  */
-                if (!info->is_console) {
+                if (vsc->is_console) {
                     virtio_serial_throttle_port(port, true);
                 }
                 port->iov_idx = i;
@@ -331,7 +331,7 @@ void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle)
 static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
 {
     struct VirtIOSerialPort *port;
-    struct VirtIOSerialPortInfo *info;
+    VirtIOSerialPortClass *vsc;
     struct virtio_console_control cpkt, *gcpkt;
     uint8_t *buffer;
     size_t buffer_len;
@@ -373,7 +373,7 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
 
     trace_virtio_serial_handle_control_message_port(port->id);
 
-    info = DO_UPCAST(VirtIOSerialPortInfo, qdev, qdev_get_info(&port->dev));
+    vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
 
     switch(cpkt.event) {
     case VIRTIO_CONSOLE_PORT_READY:
@@ -389,7 +389,7 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
          * this port is a console port so that the guest can hook it
          * up to hvc.
          */
-        if (info->is_console) {
+        if (vsc->is_console) {
             send_control_event(port, VIRTIO_CONSOLE_CONSOLE_PORT, 1);
         }
 
@@ -418,21 +418,21 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
          * initialised. If some app is interested in knowing about
          * this event, let it know.
          */
-        if (info->guest_ready) {
-            info->guest_ready(port);
+        if (vsc->guest_ready) {
+            vsc->guest_ready(port);
         }
         break;
 
     case VIRTIO_CONSOLE_PORT_OPEN:
         port->guest_connected = cpkt.value;
-        if (cpkt.value && info->guest_open) {
+        if (cpkt.value && vsc->guest_open) {
             /* Send the guest opened notification if an app is interested */
-            info->guest_open(port);
+            vsc->guest_open(port);
         }
 
-        if (!cpkt.value && info->guest_close) {
+        if (!cpkt.value && vsc->guest_close) {
             /* Send the guest closed notification if an app is interested */
-            info->guest_close(port);
+            vsc->guest_close(port);
         }
         break;
     }
@@ -751,7 +751,7 @@ static void remove_port(VirtIOSerial *vser, uint32_t port_id)
 static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
 {
     VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
-    VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev, base);
+    VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
     VirtIOSerialBus *bus = DO_UPCAST(VirtIOSerialBus, qbus, qdev->parent_bus);
     int ret, max_nr_ports;
     bool plugging_port0;
@@ -759,14 +759,14 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
     port->vser = bus->vser;
     port->bh = qemu_bh_new(flush_queued_data_bh, port);
 
-    assert(info->have_data);
+    assert(vsc->have_data);
 
     /*
      * Is the first console port we're seeing? If so, put it up at
      * location 0. This is done for backward compatibility (old
      * kernel, new qemu).
      */
-    plugging_port0 = info->is_console && !find_port_by_id(port->vser, 0);
+    plugging_port0 = vsc->is_console && !find_port_by_id(port->vser, 0);
 
     if (find_port_by_id(port->vser, port->id)) {
         error_report("virtio-serial-bus: A port already exists at id %u",
@@ -793,7 +793,7 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
         return -1;
     }
 
-    ret = info->init(port);
+    ret = vsc->init(port);
     if (ret) {
         return ret;
     }
@@ -823,8 +823,7 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
 static int virtser_port_qdev_exit(DeviceState *qdev)
 {
     VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
-    VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev,
-                                           qdev_get_info(&port->dev));
+    VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
     VirtIOSerial *vser = port->vser;
 
     qemu_bh_delete(port->bh);
@@ -832,19 +831,19 @@ static int virtser_port_qdev_exit(DeviceState *qdev)
 
     QTAILQ_REMOVE(&vser->ports, port, next);
 
-    if (info->exit) {
-        info->exit(port);
+    if (vsc->exit) {
+        vsc->exit(port);
     }
     return 0;
 }
 
-void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info)
+void virtio_serial_port_qdev_register(DeviceInfo *info)
 {
-    info->qdev.init = virtser_port_qdev_init;
-    info->qdev.bus_info = &virtser_bus_info;
-    info->qdev.exit = virtser_port_qdev_exit;
-    info->qdev.unplug = qdev_simple_unplug_cb;
-    qdev_register(&info->qdev);
+    info->init = virtser_port_qdev_init;
+    info->bus_info = &virtser_bus_info;
+    info->exit = virtser_port_qdev_exit;
+    info->unplug = qdev_simple_unplug_cb;
+    qdev_register_subclass(info, TYPE_VIRTIO_SERIAL_PORT);
 }
 
 VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
@@ -940,3 +939,18 @@ void virtio_serial_exit(VirtIODevice *vdev)
 
     virtio_cleanup(vdev);
 }
+
+static TypeInfo virtio_serial_port_type_info = {
+    .name = TYPE_VIRTIO_SERIAL_PORT,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(VirtIOSerialPort),
+    .abstract = true,
+    .class_size = sizeof(VirtIOSerialPortClass),
+};
+
+static void virtio_serial_register_devices(void)
+{
+    type_register_static(&virtio_serial_port_type_info);
+}
+
+device_init(virtio_serial_register_devices);
diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
index ab13803..6207c89 100644
--- a/hw/virtio-serial.h
+++ b/hw/virtio-serial.h
@@ -62,10 +62,52 @@ struct virtio_serial_conf {
 
 /* == In-qemu interface == */
 
+#define TYPE_VIRTIO_SERIAL_PORT "virtio-serial-port"
+#define VIRTIO_SERIAL_PORT(obj) \
+     OBJECT_CHECK(VirtIOSerialPort, (obj), TYPE_VIRTIO_SERIAL_PORT)
+#define VIRTIO_SERIAL_PORT_CLASS(klass) \
+     OBJECT_CLASS_CHECK(VirtIOSerialPortClass, (klass), TYPE_VIRTIO_SERIAL_PORT)
+#define VIRTIO_SERIAL_PORT_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(VirtIOSerialPortClass, (obj), TYPE_VIRTIO_SERIAL_PORT)
+
 typedef struct VirtIOSerial VirtIOSerial;
 typedef struct VirtIOSerialBus VirtIOSerialBus;
 typedef struct VirtIOSerialPort VirtIOSerialPort;
-typedef struct VirtIOSerialPortInfo VirtIOSerialPortInfo;
+
+typedef struct VirtIOSerialPortClass {
+    DeviceClass parent_class;
+
+    /* Is this a device that binds with hvc in the guest? */
+    bool is_console;
+
+    /*
+     * The per-port (or per-app) init function that's called when a
+     * new device is found on the bus.
+     */
+    int (*init)(VirtIOSerialPort *port);
+    /*
+     * Per-port exit function that's called when a port gets
+     * hot-unplugged or removed.
+     */
+    int (*exit)(VirtIOSerialPort *port);
+
+    /* Callbacks for guest events */
+        /* Guest opened device. */
+    void (*guest_open)(VirtIOSerialPort *port);
+        /* Guest closed device. */
+    void (*guest_close)(VirtIOSerialPort *port);
+
+        /* Guest is now ready to accept data (virtqueues set up). */
+    void (*guest_ready)(VirtIOSerialPort *port);
+
+    /*
+     * Guest wrote some data to the port. This data is handed over to
+     * the app via this callback.  The app can return a size less than
+     * 'len'.  In this case, throttling will be enabled for this port.
+     */
+    ssize_t (*have_data)(VirtIOSerialPort *port, const uint8_t *buf,
+                         size_t len);
+} VirtIOSerialPortClass;
 
 /*
  * This is the state that's shared between all the ports.  Some of the
@@ -131,48 +173,13 @@ struct VirtIOSerialPort {
     bool throttled;
 };
 
-struct VirtIOSerialPortInfo {
-    DeviceInfo qdev;
-
-    /* Is this a device that binds with hvc in the guest? */
-    bool is_console;
-
-    /*
-     * The per-port (or per-app) init function that's called when a
-     * new device is found on the bus.
-     */
-    int (*init)(VirtIOSerialPort *port);
-    /*
-     * Per-port exit function that's called when a port gets
-     * hot-unplugged or removed.
-     */
-    int (*exit)(VirtIOSerialPort *port);
-
-    /* Callbacks for guest events */
-        /* Guest opened device. */
-    void (*guest_open)(VirtIOSerialPort *port);
-        /* Guest closed device. */
-    void (*guest_close)(VirtIOSerialPort *port);
-
-        /* Guest is now ready to accept data (virtqueues set up). */
-    void (*guest_ready)(VirtIOSerialPort *port);
-
-    /*
-     * Guest wrote some data to the port. This data is handed over to
-     * the app via this callback.  The app can return a size less than
-     * 'len'.  In this case, throttling will be enabled for this port.
-     */
-    ssize_t (*have_data)(VirtIOSerialPort *port, const uint8_t *buf,
-                         size_t len);
-};
-
 /* Interface to the virtio-serial bus */
 
 /*
  * Individual ports/apps should call this function to register the port
  * with the virtio-serial bus
  */
-void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info);
+void virtio_serial_port_qdev_register(DeviceInfo *info);
 
 /*
  * Open a connection to the port
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 23/28] unin_pci: Clean up qdev names
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (21 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 22/28] virtio-serial: convert to QEMU Object Model Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 24/28] unin_pci: Drop duplicate busdev Anthony Liguori
                   ` (7 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, Andreas Färber, Alexander Graf

From: Andreas Färber <afaerber@suse.de>

Add -pcihost to SysBus devices to resolve name conflicts,
and clarify PCI vs. Internal PCI.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/unin_pci.c |   54 +++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 14d9914..be0e98c 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -213,7 +213,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
 
     /* Use values found on a real PowerMac */
     /* Uninorth main bus */
-    dev = qdev_create(NULL, "uni-north");
+    dev = qdev_create(NULL, "uni-north-pci-pcihost");
     qdev_init_nofail(dev);
     s = sysbus_from_qdev(dev);
     d = FROM_SYSBUS(UNINState, s);
@@ -245,7 +245,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
 
     /* Uninorth AGP bus */
     pci_create_simple(d->host_state.bus, PCI_DEVFN(11, 0), "uni-north-agp");
-    dev = qdev_create(NULL, "uni-north-agp");
+    dev = qdev_create(NULL, "uni-north-agp-pcihost");
     qdev_init_nofail(dev);
     s = sysbus_from_qdev(dev);
     sysbus_mmio_map(s, 0, 0xf0800000);
@@ -254,8 +254,9 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
     /* Uninorth internal bus */
 #if 0
     /* XXX: not needed for now */
-    pci_create_simple(d->host_state.bus, PCI_DEVFN(14, 0), "uni-north-pci");
-    dev = qdev_create(NULL, "uni-north-pci");
+    pci_create_simple(d->host_state.bus, PCI_DEVFN(14, 0),
+                      "uni-north-internal-pci");
+    dev = qdev_create(NULL, "uni-north-internal-pci-pcihost");
     qdev_init_nofail(dev);
     s = sysbus_from_qdev(dev);
     sysbus_mmio_map(s, 0, 0xf4800000);
@@ -275,7 +276,7 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
 
     /* Uninorth AGP bus */
 
-    dev = qdev_create(NULL, "u3-agp");
+    dev = qdev_create(NULL, "u3-agp-pcihost");
     qdev_init_nofail(dev);
     s = sysbus_from_qdev(dev);
     d = FROM_SYSBUS(UNINState, s);
@@ -335,7 +336,7 @@ static int unin_internal_pci_host_init(PCIDevice *d)
 }
 
 static PCIDeviceInfo unin_main_pci_host_info = {
-    .qdev.name = "uni-north",
+    .qdev.name = "uni-north-pci",
     .qdev.size = sizeof(PCIDevice),
     .init      = unin_main_pci_host_init,
     .vendor_id = PCI_VENDOR_ID_APPLE,
@@ -365,7 +366,7 @@ static PCIDeviceInfo unin_agp_pci_host_info = {
 };
 
 static PCIDeviceInfo unin_internal_pci_host_info = {
-    .qdev.name = "uni-north-pci",
+    .qdev.name = "uni-north-internal-pci",
     .qdev.size = sizeof(PCIDevice),
     .init      = unin_internal_pci_host_init,
     .vendor_id = PCI_VENDOR_ID_APPLE,
@@ -374,19 +375,42 @@ static PCIDeviceInfo unin_internal_pci_host_info = {
     .class_id  = PCI_CLASS_BRIDGE_HOST,
 };
 
+static SysBusDeviceInfo sysbus_unin_pci_host_info = {
+    .qdev.name = "uni-north-pci-pcihost",
+    .qdev.size = sizeof(UNINState),
+    .init      = pci_unin_main_init_device,
+};
+
+static SysBusDeviceInfo sysbus_u3_agp_pci_host_info = {
+    .qdev.name = "u3-agp-pcihost",
+    .qdev.size = sizeof(UNINState),
+    .init      = pci_u3_agp_init_device,
+};
+
+static SysBusDeviceInfo sysbus_unin_agp_pci_host_info = {
+    .qdev.name = "uni-north-agp-pcihost",
+    .qdev.size = sizeof(UNINState),
+    .init      = pci_unin_agp_init_device,
+};
+
+static SysBusDeviceInfo sysbus_unin_internal_pci_host_info = {
+    .qdev.name = "uni-north-internal-pci-pcihost",
+    .qdev.size = sizeof(UNINState),
+    .init      = pci_unin_internal_init_device,
+};
+
 static void unin_register_devices(void)
 {
-    sysbus_register_dev("uni-north", sizeof(UNINState),
-                        pci_unin_main_init_device);
+    sysbus_register_withprop(&sysbus_unin_pci_host_info);
     pci_qdev_register(&unin_main_pci_host_info);
-    sysbus_register_dev("u3-agp", sizeof(UNINState),
-                        pci_u3_agp_init_device);
+
+    sysbus_register_withprop(&sysbus_u3_agp_pci_host_info);
     pci_qdev_register(&u3_agp_pci_host_info);
-    sysbus_register_dev("uni-north-agp", sizeof(UNINState),
-                        pci_unin_agp_init_device);
+
+    sysbus_register_withprop(&sysbus_unin_agp_pci_host_info);
     pci_qdev_register(&unin_agp_pci_host_info);
-    sysbus_register_dev("uni-north-pci", sizeof(UNINState),
-                        pci_unin_internal_init_device);
+
+    sysbus_register_withprop(&sysbus_unin_internal_pci_host_info);
     pci_qdev_register(&unin_internal_pci_host_info);
 }
 
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 24/28] unin_pci: Drop duplicate busdev
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (22 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 23/28] unin_pci: Clean up qdev names Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 25/28] unin_pci: Drop unused reset handler Anthony Liguori
                   ` (6 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, Andreas Färber, Alexander Graf

From: Andreas Färber <afaerber@suse.de>

PCIHostState already has a busdev.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/unin_pci.c |   29 ++++++++++++++++++++---------
 1 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index be0e98c..8c03cb0 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -39,7 +39,6 @@
 static const int unin_irq_line[] = { 0x1b, 0x1c, 0x1d, 0x1e };
 
 typedef struct UNINState {
-    SysBusDevice busdev;
     PCIHostState host_state;
     MemoryRegion pci_mmio;
     MemoryRegion pci_hole;
@@ -134,11 +133,13 @@ static const MemoryRegionOps unin_data_ops = {
 
 static int pci_unin_main_init_device(SysBusDevice *dev)
 {
+    PCIHostState *h;
     UNINState *s;
 
     /* Use values found on a real PowerMac */
     /* Uninorth main bus */
-    s = FROM_SYSBUS(UNINState, dev);
+    h = FROM_SYSBUS(PCIHostState, dev);
+    s = DO_UPCAST(UNINState, host_state, h);
 
     memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
                           &s->host_state, "pci-conf-idx", 0x1000);
@@ -154,10 +155,12 @@ static int pci_unin_main_init_device(SysBusDevice *dev)
 
 static int pci_u3_agp_init_device(SysBusDevice *dev)
 {
+    PCIHostState *h;
     UNINState *s;
 
     /* Uninorth U3 AGP bus */
-    s = FROM_SYSBUS(UNINState, dev);
+    h = FROM_SYSBUS(PCIHostState, dev);
+    s = DO_UPCAST(UNINState, host_state, h);
 
     memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
                           &s->host_state, "pci-conf-idx", 0x1000);
@@ -173,10 +176,12 @@ static int pci_u3_agp_init_device(SysBusDevice *dev)
 
 static int pci_unin_agp_init_device(SysBusDevice *dev)
 {
+    PCIHostState *h;
     UNINState *s;
 
     /* Uninorth AGP bus */
-    s = FROM_SYSBUS(UNINState, dev);
+    h = FROM_SYSBUS(PCIHostState, dev);
+    s = DO_UPCAST(UNINState, host_state, h);
 
     memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
                           &s->host_state, "pci-conf-idx", 0x1000);
@@ -189,10 +194,12 @@ static int pci_unin_agp_init_device(SysBusDevice *dev)
 
 static int pci_unin_internal_init_device(SysBusDevice *dev)
 {
+    PCIHostState *h;
     UNINState *s;
 
     /* Uninorth internal bus */
-    s = FROM_SYSBUS(UNINState, dev);
+    h = FROM_SYSBUS(PCIHostState, dev);
+    s = DO_UPCAST(UNINState, host_state, h);
 
     memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
                           &s->host_state, "pci-conf-idx", 0x1000);
@@ -209,6 +216,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
 {
     DeviceState *dev;
     SysBusDevice *s;
+    PCIHostState *h;
     UNINState *d;
 
     /* Use values found on a real PowerMac */
@@ -216,14 +224,15 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
     dev = qdev_create(NULL, "uni-north-pci-pcihost");
     qdev_init_nofail(dev);
     s = sysbus_from_qdev(dev);
-    d = FROM_SYSBUS(UNINState, s);
+    h = FROM_SYSBUS(PCIHostState, s);
+    d = DO_UPCAST(UNINState, host_state, h);
     memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL);
     memory_region_init_alias(&d->pci_hole, "pci-hole", &d->pci_mmio,
                              0x80000000ULL, 0x70000000ULL);
     memory_region_add_subregion(address_space_mem, 0x80000000ULL,
                                 &d->pci_hole);
 
-    d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
+    d->host_state.bus = pci_register_bus(dev, "pci",
                                          pci_unin_set_irq, pci_unin_map_irq,
                                          pic,
                                          &d->pci_mmio,
@@ -272,6 +281,7 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
 {
     DeviceState *dev;
     SysBusDevice *s;
+    PCIHostState *h;
     UNINState *d;
 
     /* Uninorth AGP bus */
@@ -279,7 +289,8 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
     dev = qdev_create(NULL, "u3-agp-pcihost");
     qdev_init_nofail(dev);
     s = sysbus_from_qdev(dev);
-    d = FROM_SYSBUS(UNINState, s);
+    h = FROM_SYSBUS(PCIHostState, s);
+    d = DO_UPCAST(UNINState, host_state, h);
 
     memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL);
     memory_region_init_alias(&d->pci_hole, "pci-hole", &d->pci_mmio,
@@ -287,7 +298,7 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
     memory_region_add_subregion(address_space_mem, 0x80000000ULL,
                                 &d->pci_hole);
 
-    d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
+    d->host_state.bus = pci_register_bus(dev, "pci",
                                          pci_unin_set_irq, pci_unin_map_irq,
                                          pic,
                                          &d->pci_mmio,
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 25/28] unin_pci: Drop unused reset handler
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (23 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 24/28] unin_pci: Drop duplicate busdev Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 19:33   ` Anthony Liguori
                   ` (5 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, Andreas Färber, Alexander Graf

From: Andreas Färber <afaerber@suse.de>

Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/unin_pci.c |    7 -------
 1 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 8c03cb0..6a10013 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -63,10 +63,6 @@ static void pci_unin_set_irq(void *opaque, int irq_num, int level)
     qemu_set_irq(pic[unin_irq_line[irq_num]], level);
 }
 
-static void pci_unin_reset(void *opaque)
-{
-}
-
 static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr)
 {
     uint32_t retval;
@@ -148,7 +144,6 @@ static int pci_unin_main_init_device(SysBusDevice *dev)
     sysbus_init_mmio(dev, &s->host_state.conf_mem);
     sysbus_init_mmio(dev, &s->host_state.data_mem);
 
-    qemu_register_reset(pci_unin_reset, &s->host_state);
     return 0;
 }
 
@@ -169,8 +164,6 @@ static int pci_u3_agp_init_device(SysBusDevice *dev)
     sysbus_init_mmio(dev, &s->host_state.conf_mem);
     sysbus_init_mmio(dev, &s->host_state.data_mem);
 
-    qemu_register_reset(pci_unin_reset, &s->host_state);
-
     return 0;
 }
 
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 26/28] pci: convert to QEMU Object Model
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
@ 2012-01-24 19:33   ` Anthony Liguori
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 02/28] openpic: remove dead code to make a PCI device version Anthony Liguori
                     ` (29 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Anthony Liguori, xen-devel, Michael S. Tsirkin,
	Stefano Stabellini, Alexander Graf, Blue Swirl,
	Andreas Färber, qemu-ppc, Paul Brook, Gerd Hoffmann

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/9pfs/virtio-9p-device.c |   43 ++++++----
 hw/ac97.c                  |   39 +++++----
 hw/acpi_piix4.c            |   59 +++++++------
 hw/apb_pci.c               |   54 ++++++++-----
 hw/bonito.c                |   30 ++++---
 hw/cirrus_vga.c            |   33 +++++---
 hw/dec_pci.c               |   57 ++++++++-----
 hw/e1000.c                 |   43 ++++++----
 hw/eepro100.c              |  200 +++++++++++++++++++++++++++----------------
 hw/es1370.c                |   31 ++++---
 hw/grackle_pci.c           |   25 ++++--
 hw/gt64xxx.c               |   23 ++++--
 hw/i82378.c                |   31 ++++---
 hw/ide/cmd646.c            |   36 +++++---
 hw/ide/ich.c               |   31 ++++---
 hw/ide/piix.c              |   79 +++++++++++-------
 hw/ide/via.c               |   27 ++++--
 hw/intel-hda.c             |   56 ++++++++----
 hw/ioh3420.c               |   59 +++++++------
 hw/ivshmem.c               |   47 ++++++----
 hw/lsi53c895a.c            |   31 ++++---
 hw/macio.c                 |   19 +++--
 hw/ne2000.c                |   35 +++++---
 hw/pci.c                   |  123 ++++++++++++---------------
 hw/pci.h                   |   80 +++++++++---------
 hw/pci_bridge.c            |    2 +-
 hw/pcie.c                  |    2 +-
 hw/pcnet-pci.c             |   39 +++++----
 hw/piix4.c                 |   30 ++++---
 hw/piix_pci.c              |   95 +++++++++++++--------
 hw/ppc4xx_pci.c            |   21 +++--
 hw/ppce500_pci.c           |   21 +++--
 hw/prep_pci.c              |   33 ++++----
 hw/qdev.c                  |    1 +
 hw/qxl.c                   |   62 ++++++++-----
 hw/rtl8139.c               |   41 ++++++----
 hw/sh_pci.c                |   19 +++--
 hw/spapr_pci.c             |   15 +++-
 hw/sun4u.c                 |   23 ++++--
 hw/unin_pci.c              |   92 +++++++++++++-------
 hw/usb-ehci.c              |   54 ++++++++-----
 hw/usb-ohci.c              |   37 +++++---
 hw/usb-uhci.c              |  168 +++++++++++++++++++++++--------------
 hw/usb-xhci.c              |   33 +++++---
 hw/versatile_pci.c         |   22 +++--
 hw/vga-pci.c               |   27 ++++---
 hw/virtio-pci.c            |  188 ++++++++++++++++++++++++-----------------
 hw/vmware_vga.c            |   34 +++++---
 hw/vt82c686.c              |  120 ++++++++++++++++----------
 hw/wdt_i6300esb.c          |   33 +++++---
 hw/xen_platform.c          |   34 +++++---
 hw/xio3130_downstream.c    |   59 +++++++------
 hw/xio3130_upstream.c      |   53 +++++++-----
 53 files changed, 1599 insertions(+), 1050 deletions(-)

diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 1325f2f..aded048 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -163,23 +163,32 @@ static int virtio_9p_init_pci(PCIDevice *pci_dev)
     return 0;
 }
 
-static PCIDeviceInfo virtio_9p_info = {
-    .qdev.name = "virtio-9p-pci",
-    .qdev.size = sizeof(VirtIOPCIProxy),
-    .init      = virtio_9p_init_pci,
-    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
-    .device_id = 0x1009,
-    .revision  = VIRTIO_PCI_ABI_VERSION,
-    .class_id  = 0x2,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
-        DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
-        DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-        DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
-        DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id),
-        DEFINE_PROP_END_OF_LIST(),
-    },
-    .qdev.reset = virtio_pci_reset,
+static Property virtio_9p_properties[] = {
+    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
+    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+    DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
+    DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_9p_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_9p_init_pci;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = 0x1009;
+    k->revision = VIRTIO_PCI_ABI_VERSION;
+    k->class_id = 0x2;
+}
+
+static DeviceInfo virtio_9p_info = {
+    .name = "virtio-9p-pci",
+    .size = sizeof(VirtIOPCIProxy),
+    .props = virtio_9p_properties,
+    .class_init = virtio_9p_class_init,
+    .reset = virtio_pci_reset,
 };
 
 static void virtio_9p_register_devices(void)
diff --git a/hw/ac97.c b/hw/ac97.c
index 03be99b..33b85f5 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -1344,21 +1344,30 @@ int ac97_init (PCIBus *bus)
     return 0;
 }
 
-static PCIDeviceInfo ac97_info = {
-    .qdev.name    = "AC97",
-    .qdev.desc    = "Intel 82801AA AC97 Audio",
-    .qdev.size    = sizeof (AC97LinkState),
-    .qdev.vmsd    = &vmstate_ac97,
-    .init         = ac97_initfn,
-    .exit         = ac97_exitfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82801AA_5,
-    .revision     = 0x01,
-    .class_id     = PCI_CLASS_MULTIMEDIA_AUDIO,
-    .qdev.props   = (Property[]) {
-        DEFINE_PROP_UINT32("use_broken_id", AC97LinkState, use_broken_id, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property ac97_properties[] = {
+    DEFINE_PROP_UINT32("use_broken_id", AC97LinkState, use_broken_id, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ac97_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = ac97_initfn;
+    k->exit = ac97_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
+    k->revision = 0x01;
+    k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+}
+
+static DeviceInfo ac97_info = {
+    .name = "AC97",
+    .desc = "Intel 82801AA AC97 Audio",
+    .size = sizeof (AC97LinkState),
+    .vmsd = &vmstate_ac97,
+    .props = ac97_properties,
+    .class_init = ac97_class_init,
 };
 
 static void ac97_register (void)
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 4d0b390..9058a7c 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -280,11 +280,11 @@ static void piix4_update_hotplug(PIIX4PMState *s)
     s->pci0_hotplug_enable = ~0;
 
     QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
-        PCIDeviceInfo *info = container_of(qdev_get_info(qdev), PCIDeviceInfo, qdev);
-        PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, qdev);
+        PCIDevice *pdev = PCI_DEVICE(qdev);
+        PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pdev);
         int slot = PCI_SLOT(pdev->devfn);
 
-        if (info->no_hotplug) {
+        if (pc->no_hotplug) {
             s->pci0_hotplug_enable &= ~(1 << slot);
         }
     }
@@ -396,23 +396,32 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
     return s->smb.smbus;
 }
 
-static PCIDeviceInfo piix4_pm_info = {
-    .qdev.name          = "PIIX4_PM",
-    .qdev.desc          = "PM",
-    .qdev.size          = sizeof(PIIX4PMState),
-    .qdev.vmsd          = &vmstate_acpi,
-    .qdev.no_user       = 1,
-    .no_hotplug         = 1,
-    .init               = piix4_pm_initfn,
-    .config_write       = pm_write_config,
-    .vendor_id          = PCI_VENDOR_ID_INTEL,
-    .device_id          = PCI_DEVICE_ID_INTEL_82371AB_3,
-    .revision           = 0x03,
-    .class_id           = PCI_CLASS_BRIDGE_OTHER,
-    .qdev.props         = (Property[]) {
-        DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property piix4_pm_properties[] = {
+    DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void piix4_pm_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = piix4_pm_initfn;
+    k->config_write = pm_write_config;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82371AB_3;
+    k->revision = 0x03;
+    k->class_id = PCI_CLASS_BRIDGE_OTHER;
+}
+
+static DeviceInfo piix4_pm_info = {
+    .name = "PIIX4_PM",
+    .desc = "PM",
+    .size = sizeof(PIIX4PMState),
+    .vmsd = &vmstate_acpi,
+    .no_user = 1,
+    .props = piix4_pm_properties,
+    .class_init = piix4_pm_class_init,
 };
 
 static void piix4_pm_register(void)
@@ -485,14 +494,12 @@ static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
 {
     BusState *bus = opaque;
     DeviceState *qdev, *next;
-    PCIDevice *dev;
-    PCIDeviceInfo *info;
     int slot = ffs(val) - 1;
 
     QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
-        dev = DO_UPCAST(PCIDevice, qdev, qdev);
-        info = container_of(qdev_get_info(qdev), PCIDeviceInfo, qdev);
-        if (PCI_SLOT(dev->devfn) == slot && !info->no_hotplug) {
+        PCIDevice *dev = PCI_DEVICE(qdev);
+        PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
+        if (PCI_SLOT(dev->devfn) == slot && !pc->no_hotplug) {
             qdev_free(qdev);
         }
     }
@@ -553,7 +560,7 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
 {
     int slot = PCI_SLOT(dev->devfn);
     PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev,
-                                DO_UPCAST(PCIDevice, qdev, qdev));
+                                PCI_DEVICE(qdev));
 
     /* Don't send event when device is enabled during qemu machine creation:
      * it is present on boot, no hotplug event is necessary. We do send an
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 3a1b111..70cfc77 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -436,14 +436,21 @@ static int pbm_pci_host_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo pbm_pci_host_info = {
-    .qdev.name = "pbm",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = pbm_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_SUN,
-    .device_id = PCI_DEVICE_ID_SUN_SABRE,
-    .class_id  = PCI_CLASS_BRIDGE_HOST,
-    .is_bridge = 1,
+static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pbm_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_SUN;
+    k->device_id = PCI_DEVICE_ID_SUN_SABRE;
+    k->class_id = PCI_CLASS_BRIDGE_HOST;
+    k->is_bridge = 1;
+}
+
+static DeviceInfo pbm_pci_host_info = {
+    .name = "pbm",
+    .size = sizeof(PCIDevice),
+    .class_init = pbm_pci_host_class_init,
 };
 
 static SysBusDeviceInfo pbm_host_info = {
@@ -453,18 +460,25 @@ static SysBusDeviceInfo pbm_host_info = {
     .init = pci_pbm_init_device,
 };
 
-static PCIDeviceInfo pbm_pci_bridge_info = {
-    .qdev.name = "pbm-bridge",
-    .qdev.size = sizeof(PCIBridge),
-    .qdev.vmsd = &vmstate_pci_device,
-    .qdev.reset = pci_bridge_reset,
-    .init = apb_pci_bridge_initfn,
-    .exit = pci_bridge_exitfn,
-    .vendor_id = PCI_VENDOR_ID_SUN,
-    .device_id = PCI_DEVICE_ID_SUN_SIMBA,
-    .revision = 0x11,
-    .config_write = pci_bridge_write_config,
-    .is_bridge = 1,
+static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = apb_pci_bridge_initfn;
+    k->exit = pci_bridge_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_SUN;
+    k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
+    k->revision = 0x11;
+    k->config_write = pci_bridge_write_config;
+    k->is_bridge = 1;
+}
+
+static DeviceInfo pbm_pci_bridge_info = {
+    .name = "pbm-bridge",
+    .size = sizeof(PCIBridge),
+    .vmsd = &vmstate_pci_device,
+    .reset = pci_bridge_reset,
+    .class_init = pbm_pci_bridge_class_init,
 };
 
 static void pbm_register_devices(void)
diff --git a/hw/bonito.c b/hw/bonito.c
index f2c7837..23384ec 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -766,18 +766,24 @@ PCIBus *bonito_init(qemu_irq *pic)
     return b;
 }
 
-static PCIDeviceInfo bonito_info = {
-    .qdev.name    = "Bonito",
-    .qdev.desc    = "Host bridge",
-    .qdev.size    = sizeof(PCIBonitoState),
-    .qdev.vmsd    = &vmstate_bonito,
-    .qdev.no_user = 1,
-    .init         = bonito_initfn,
-    /*Bonito North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined"*/
-    .vendor_id    = 0xdf53,
-    .device_id    = 0x00d5,
-    .revision     = 0x01,
-    .class_id     = PCI_CLASS_BRIDGE_HOST,
+static void bonito_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = bonito_initfn;
+    k->vendor_id = 0xdf53;
+    k->device_id = 0x00d5;
+    k->revision = 0x01;
+    k->class_id = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo bonito_info = {
+    .name = "Bonito",
+    .desc = "Host bridge",
+    .size = sizeof(PCIBonitoState),
+    .vmsd = &vmstate_bonito,
+    .no_user = 1,
+    .class_init = bonito_class_init,
 };
 
 static SysBusDeviceInfo bonito_pcihost_info = {
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 1d0aadf..3fac2ee 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2935,8 +2935,8 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
 {
      PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
      CirrusVGAState *s = &d->cirrus_vga;
-     PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, qdev_get_info(&dev->qdev));
-     int16_t device_id = info->device_id;
+     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
+     int16_t device_id = pc->device_id;
 
      /* setup VGA */
      vga_common_init(&s->vga, VGA_RAM_SIZE);
@@ -2970,17 +2970,24 @@ DeviceState *pci_cirrus_vga_init(PCIBus *bus)
     return &pci_create_simple(bus, -1, "cirrus-vga")->qdev;
 }
 
-static PCIDeviceInfo cirrus_vga_info = {
-    .qdev.name    = "cirrus-vga",
-    .qdev.desc    = "Cirrus CLGD 54xx VGA",
-    .qdev.size    = sizeof(PCICirrusVGAState),
-    .qdev.vmsd    = &vmstate_pci_cirrus_vga,
-    .no_hotplug   = 1,
-    .init         = pci_cirrus_vga_initfn,
-    .romfile      = VGABIOS_CIRRUS_FILENAME,
-    .vendor_id    = PCI_VENDOR_ID_CIRRUS,
-    .device_id    = CIRRUS_ID_CLGD5446,
-    .class_id     = PCI_CLASS_DISPLAY_VGA,
+static void cirrus_vga_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = pci_cirrus_vga_initfn;
+    k->romfile = VGABIOS_CIRRUS_FILENAME;
+    k->vendor_id = PCI_VENDOR_ID_CIRRUS;
+    k->device_id = CIRRUS_ID_CLGD5446;
+    k->class_id = PCI_CLASS_DISPLAY_VGA;
+}
+
+static DeviceInfo cirrus_vga_info = {
+    .name = "cirrus-vga",
+    .desc = "Cirrus CLGD 54xx VGA",
+    .size = sizeof(PCICirrusVGAState),
+    .vmsd = &vmstate_pci_cirrus_vga,
+    .class_init = cirrus_vga_class_init,
 };
 
 static void cirrus_vga_register(void)
diff --git a/hw/dec_pci.c b/hw/dec_pci.c
index 08d4e06..7c3f50e 100644
--- a/hw/dec_pci.c
+++ b/hw/dec_pci.c
@@ -50,18 +50,25 @@ static int dec_map_irq(PCIDevice *pci_dev, int irq_num)
     return irq_num;
 }
 
-static PCIDeviceInfo dec_21154_pci_bridge_info = {
-    .qdev.name = "dec-21154-p2p-bridge",
-    .qdev.desc = "DEC 21154 PCI-PCI bridge",
-    .qdev.size = sizeof(PCIBridge),
-    .qdev.vmsd = &vmstate_pci_device,
-    .qdev.reset = pci_bridge_reset,
-    .init = pci_bridge_initfn,
-    .exit = pci_bridge_exitfn,
-    .vendor_id = PCI_VENDOR_ID_DEC,
-    .device_id = PCI_DEVICE_ID_DEC_21154,
-    .config_write = pci_bridge_write_config,
-    .is_bridge = 1,
+static void dec_21154_pci_bridge_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_bridge_initfn;
+    k->exit = pci_bridge_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_DEC;
+    k->device_id = PCI_DEVICE_ID_DEC_21154;
+    k->config_write = pci_bridge_write_config;
+    k->is_bridge = 1;
+}
+
+static DeviceInfo dec_21154_pci_bridge_info = {
+    .name = "dec-21154-p2p-bridge",
+    .desc = "DEC 21154 PCI-PCI bridge",
+    .size = sizeof(PCIBridge),
+    .vmsd = &vmstate_pci_device,
+    .reset = pci_bridge_reset,
+    .class_init = dec_21154_pci_bridge_class_init,
 };
 
 PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
@@ -98,21 +105,29 @@ static int dec_21154_pci_host_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo dec_21154_pci_host_info = {
-    .qdev.name = "dec-21154",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = dec_21154_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_DEC,
-    .device_id = PCI_DEVICE_ID_DEC_21154,
-    .revision = 0x02,
-    .class_id = PCI_CLASS_BRIDGE_PCI,
-    .is_bridge  = 1,
+static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = dec_21154_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_DEC;
+    k->device_id = PCI_DEVICE_ID_DEC_21154;
+    k->revision = 0x02;
+    k->class_id = PCI_CLASS_BRIDGE_PCI;
+    k->is_bridge = 1;
+}
+
+static DeviceInfo dec_21154_pci_host_info = {
+    .name = "dec-21154",
+    .size = sizeof(PCIDevice),
+    .class_init = dec_21154_pci_host_class_init,
 };
 
 static void dec_register_devices(void)
 {
     sysbus_register_dev("dec-21154", sizeof(DECState),
                         pci_dec_21154_init_device);
+
     pci_qdev_register(&dec_21154_pci_host_info);
     pci_qdev_register(&dec_21154_pci_bridge_info);
 }
diff --git a/hw/e1000.c b/hw/e1000.c
index 6bab54e..c5d3ecb 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1192,23 +1192,32 @@ static void qdev_e1000_reset(DeviceState *dev)
     e1000_reset(d);
 }
 
-static PCIDeviceInfo e1000_info = {
-    .qdev.name  = "e1000",
-    .qdev.desc  = "Intel Gigabit Ethernet",
-    .qdev.size  = sizeof(E1000State),
-    .qdev.reset = qdev_e1000_reset,
-    .qdev.vmsd  = &vmstate_e1000,
-    .init       = pci_e1000_init,
-    .exit       = pci_e1000_uninit,
-    .romfile    = "pxe-e1000.rom",
-    .vendor_id  = PCI_VENDOR_ID_INTEL,
-    .device_id  = E1000_DEVID,
-    .revision   = 0x03,
-    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(E1000State, conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property e1000_properties[] = {
+    DEFINE_NIC_PROPERTIES(E1000State, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void e1000_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_e1000_init;
+    k->exit = pci_e1000_uninit;
+    k->romfile = "pxe-e1000.rom";
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = E1000_DEVID;
+    k->revision = 0x03;
+    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+}
+
+static DeviceInfo e1000_info = {
+    .name = "e1000",
+    .desc = "Intel Gigabit Ethernet",
+    .size = sizeof(E1000State),
+    .reset = qdev_e1000_reset,
+    .vmsd = &vmstate_e1000,
+    .props = e1000_properties,
+    .class_init = e1000_class_init,
 };
 
 static void e1000_register_devices(void)
diff --git a/hw/eepro100.c b/hw/eepro100.c
index f0059c6..9f6d333 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -128,7 +128,13 @@
 #define DRVR_INT        0x0200  /* Driver generated interrupt. */
 
 typedef struct {
-    PCIDeviceInfo pci;
+    DeviceInfo qdev;
+
+    uint16_t device_id;
+    uint8_t revision;
+    uint16_t subsystem_vendor_id;
+    uint16_t subsystem_id;
+
     uint32_t device;
     uint8_t stats_size;
     bool has_extended_tcb_support;
@@ -318,6 +324,8 @@ static const uint16_t eepro100_mdi_mask[] = {
 
 #define POLYNOMIAL 0x04c11db6
 
+static E100PCIDeviceInfo *eepro100_get_class(EEPRO100State *s);
+
 /* From FreeBSD */
 /* XXX: optimize */
 static unsigned compute_mcast_idx(const uint8_t * ep)
@@ -487,8 +495,9 @@ static void eepro100_fcp_interrupt(EEPRO100State * s)
 }
 #endif
 
-static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
+static void e100_pci_reset(EEPRO100State * s)
 {
+    E100PCIDeviceInfo *info = eepro100_get_class(s);
     uint32_t device = s->device;
     uint8_t *pci_conf = s->dev.config;
 
@@ -508,8 +517,8 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
     /* Maximum Latency */
     pci_set_byte(pci_conf + PCI_MAX_LAT, 0x18);
 
-    s->stats_size = e100_device->stats_size;
-    s->has_extended_tcb_support = e100_device->has_extended_tcb_support;
+    s->stats_size = info->stats_size;
+    s->has_extended_tcb_support = info->has_extended_tcb_support;
 
     switch (device) {
     case i82550:
@@ -558,7 +567,7 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
     }
     assert(s->stats_size > 0 && s->stats_size <= sizeof(s->statistics));
 
-    if (e100_device->power_management) {
+    if (info->power_management) {
         /* Power Management Capabilities */
         int cfg_offset = 0xdc;
         int r = pci_add_capability(&s->dev, PCI_CAP_ID_PM,
@@ -1847,14 +1856,13 @@ static NetClientInfo net_eepro100_info = {
 static int e100_nic_init(PCIDevice *pci_dev)
 {
     EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
-    E100PCIDeviceInfo *e100_device = DO_UPCAST(E100PCIDeviceInfo, pci.qdev,
-                                               qdev_get_info(&pci_dev->qdev));
+    E100PCIDeviceInfo *info = eepro100_get_class(s);
 
     TRACE(OTHER, logout("\n"));
 
-    s->device = e100_device->device;
+    s->device = info->device;
 
-    e100_pci_reset(s, e100_device);
+    e100_pci_reset(s);
 
     /* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM,
      * i82559 and later support 64 or 256 word EEPROM. */
@@ -1897,136 +1905,182 @@ static int e100_nic_init(PCIDevice *pci_dev)
 
 static E100PCIDeviceInfo e100_devices[] = {
     {
-        .pci.qdev.name = "i82550",
-        .pci.qdev.desc = "Intel i82550 Ethernet",
+        .qdev.name = "i82550",
+        .qdev.desc = "Intel i82550 Ethernet",
         .device = i82550,
         /* TODO: check device id. */
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
         /* Revision ID: 0x0c, 0x0d, 0x0e. */
-        .pci.revision = 0x0e,
+        .revision = 0x0e,
         /* TODO: check size of statistical counters. */
         .stats_size = 80,
         /* TODO: check extended tcb support. */
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82551",
-        .pci.qdev.desc = "Intel i82551 Ethernet",
+        .qdev.name = "i82551",
+        .qdev.desc = "Intel i82551 Ethernet",
         .device = i82551,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
         /* Revision ID: 0x0f, 0x10. */
-        .pci.revision = 0x0f,
+        .revision = 0x0f,
         /* TODO: check size of statistical counters. */
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82557a",
-        .pci.qdev.desc = "Intel i82557A Ethernet",
+        .qdev.name = "i82557a",
+        .qdev.desc = "Intel i82557A Ethernet",
         .device = i82557A,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
-        .pci.revision = 0x01,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x01,
         .power_management = false,
     },{
-        .pci.qdev.name = "i82557b",
-        .pci.qdev.desc = "Intel i82557B Ethernet",
+        .qdev.name = "i82557b",
+        .qdev.desc = "Intel i82557B Ethernet",
         .device = i82557B,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
-        .pci.revision = 0x02,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x02,
         .power_management = false,
     },{
-        .pci.qdev.name = "i82557c",
-        .pci.qdev.desc = "Intel i82557C Ethernet",
+        .qdev.name = "i82557c",
+        .qdev.desc = "Intel i82557C Ethernet",
         .device = i82557C,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
-        .pci.revision = 0x03,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x03,
         .power_management = false,
     },{
-        .pci.qdev.name = "i82558a",
-        .pci.qdev.desc = "Intel i82558A Ethernet",
+        .qdev.name = "i82558a",
+        .qdev.desc = "Intel i82558A Ethernet",
         .device = i82558A,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
-        .pci.revision = 0x04,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x04,
         .stats_size = 76,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82558b",
-        .pci.qdev.desc = "Intel i82558B Ethernet",
+        .qdev.name = "i82558b",
+        .qdev.desc = "Intel i82558B Ethernet",
         .device = i82558B,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
-        .pci.revision = 0x05,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x05,
         .stats_size = 76,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82559a",
-        .pci.qdev.desc = "Intel i82559A Ethernet",
+        .qdev.name = "i82559a",
+        .qdev.desc = "Intel i82559A Ethernet",
         .device = i82559A,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
-        .pci.revision = 0x06,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x06,
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82559b",
-        .pci.qdev.desc = "Intel i82559B Ethernet",
+        .qdev.name = "i82559b",
+        .qdev.desc = "Intel i82559B Ethernet",
         .device = i82559B,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
-        .pci.revision = 0x07,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x07,
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82559c",
-        .pci.qdev.desc = "Intel i82559C Ethernet",
+        .qdev.name = "i82559c",
+        .qdev.desc = "Intel i82559C Ethernet",
         .device = i82559C,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
 #if 0
-        .pci.revision = 0x08,
+        .revision = 0x08,
 #endif
         /* TODO: Windows wants revision id 0x0c. */
-        .pci.revision = 0x0c,
+        .revision = 0x0c,
 #if EEPROM_SIZE > 0
-        .pci.subsystem_vendor_id = PCI_VENDOR_ID_INTEL,
-        .pci.subsystem_id = 0x0040,
+        .subsystem_vendor_id = PCI_VENDOR_ID_INTEL,
+        .subsystem_id = 0x0040,
 #endif
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82559er",
-        .pci.qdev.desc = "Intel i82559ER Ethernet",
+        .qdev.name = "i82559er",
+        .qdev.desc = "Intel i82559ER Ethernet",
         .device = i82559ER,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
-        .pci.revision = 0x09,
+        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        .revision = 0x09,
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82562",
-        .pci.qdev.desc = "Intel i82562 Ethernet",
+        .qdev.name = "i82562",
+        .qdev.desc = "Intel i82562 Ethernet",
         .device = i82562,
         /* TODO: check device id. */
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
         /* TODO: wrong revision id. */
-        .pci.revision = 0x0e,
+        .revision = 0x0e,
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
         /* Toshiba Tecra 8200. */
-        .pci.qdev.name = "i82801",
-        .pci.qdev.desc = "Intel i82801 Ethernet",
+        .qdev.name = "i82801",
+        .qdev.desc = "Intel i82801 Ethernet",
         .device = i82801,
-        .pci.device_id = 0x2449,
-        .pci.revision = 0x03,
+        .device_id = 0x2449,
+        .revision = 0x03,
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
     }
 };
 
+static E100PCIDeviceInfo *eepro100_get_class_by_name(const char *typename)
+{
+    E100PCIDeviceInfo *info = NULL;
+    int i;
+
+    /* This is admittedly awkward but also temporary.  QOM allows for
+     * parameterized typing and for subclassing both of which would suitable
+     * handle what's going on here.  But class_data is already being used as
+     * a stop-gap hack to allow incremental qdev conversion so we cannot use it
+     * right now.  Once we merge the final QOM series, we can come back here and
+     * do this in a much more elegant fashion.
+     */
+    for (i = 0; i < ARRAY_SIZE(e100_devices); i++) {
+        if (strcmp(e100_devices[i].qdev.name, typename) == 0) {
+            info = &e100_devices[i];
+            break;
+        }
+    }
+    assert(info != NULL);
+
+    return info;
+}
+
+static E100PCIDeviceInfo *eepro100_get_class(EEPRO100State *s)
+{
+    return eepro100_get_class_by_name(object_get_typename(OBJECT(s)));
+}
+
+static void eepro100_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+    E100PCIDeviceInfo *info;
+
+    info = eepro100_get_class_by_name(object_class_get_name(klass));
+
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+    k->romfile = "pxe-eepro100.rom";
+    k->init = e100_nic_init;
+    k->exit = pci_nic_uninit;
+    k->device_id = info->device_id;
+    k->revision = info->revision;
+    k->subsystem_vendor_id = info->subsystem_vendor_id;
+    k->subsystem_id = info->subsystem_id;
+}
+
 static Property e100_properties[] = {
     DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
     DEFINE_PROP_END_OF_LIST(),
@@ -2036,17 +2090,13 @@ static void eepro100_register_devices(void)
 {
     size_t i;
     for (i = 0; i < ARRAY_SIZE(e100_devices); i++) {
-        PCIDeviceInfo *pci_dev = &e100_devices[i].pci;
-        /* We use the same rom file for all device ids.
-           QEMU fixes the device id during rom load. */
-        pci_dev->vendor_id = PCI_VENDOR_ID_INTEL;
-        pci_dev->class_id = PCI_CLASS_NETWORK_ETHERNET;
-        pci_dev->romfile = "pxe-eepro100.rom";
-        pci_dev->init = e100_nic_init;
-        pci_dev->exit = pci_nic_uninit;
-        pci_dev->qdev.props = e100_properties;
-        pci_dev->qdev.size = sizeof(EEPRO100State);
-        pci_qdev_register(pci_dev);
+        DeviceInfo *info = &e100_devices[i].qdev;
+
+        info->class_init = eepro100_class_init;
+        info->size = sizeof(EEPRO100State);
+        info->props = e100_properties;
+        
+        pci_qdev_register(info);
     }
 }
 
diff --git a/hw/es1370.c b/hw/es1370.c
index 3527eb6..205bed7 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -1031,18 +1031,25 @@ int es1370_init (PCIBus *bus)
     return 0;
 }
 
-static PCIDeviceInfo es1370_info = {
-    .qdev.name    = "ES1370",
-    .qdev.desc    = "ENSONIQ AudioPCI ES1370",
-    .qdev.size    = sizeof (ES1370State),
-    .qdev.vmsd    = &vmstate_es1370,
-    .init         = es1370_initfn,
-    .exit         = es1370_exitfn,
-    .vendor_id    = PCI_VENDOR_ID_ENSONIQ,
-    .device_id    = PCI_DEVICE_ID_ENSONIQ_ES1370,
-    .class_id     = PCI_CLASS_MULTIMEDIA_AUDIO,
-    .subsystem_vendor_id = 0x4942,
-    .subsystem_id = 0x4c4c,
+static void es1370_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = es1370_initfn;
+    k->exit = es1370_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_ENSONIQ;
+    k->device_id = PCI_DEVICE_ID_ENSONIQ_ES1370;
+    k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+    k->subsystem_vendor_id = 0x4942;
+    k->subsystem_id = 0x4c4c;
+}
+
+static DeviceInfo es1370_info = {
+    .name = "ES1370",
+    .desc = "ENSONIQ AudioPCI ES1370",
+    .size = sizeof (ES1370State),
+    .vmsd = &vmstate_es1370,
+    .class_init = es1370_class_init,
 };
 
 static void es1370_register (void)
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index be10a6d..a790f97 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -121,15 +121,22 @@ static int grackle_pci_host_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo grackle_pci_info = {
-    .qdev.name = "grackle",
-    .qdev.size = sizeof(PCIDevice),
-    .qdev.no_user = 1,
-    .init      = grackle_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_MOTOROLA,
-    .device_id = PCI_DEVICE_ID_MOTOROLA_MPC106,
-    .revision  = 0x00,
-    .class_id  = PCI_CLASS_BRIDGE_HOST,
+static void grackle_pci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init      = grackle_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_MOTOROLA;
+    k->device_id = PCI_DEVICE_ID_MOTOROLA_MPC106;
+    k->revision  = 0x00;
+    k->class_id  = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo grackle_pci_info = {
+    .name = "grackle",
+    .size = sizeof(PCIDevice),
+    .no_user = 1,
+    .class_init = grackle_pci_class_init,
 };
 
 static SysBusDeviceInfo grackle_pci_host_info = {
diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index 432683a..9fc51f2 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -1136,14 +1136,21 @@ static int gt64120_pci_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo gt64120_pci_info = {
-    .qdev.name = "gt64120_pci",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = gt64120_pci_init,
-    .vendor_id = PCI_VENDOR_ID_MARVELL,
-    .device_id = PCI_DEVICE_ID_MARVELL_GT6412X,
-    .revision  = 0x10,
-    .class_id  = PCI_CLASS_BRIDGE_HOST,
+static void gt64120_pci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = gt64120_pci_init;
+    k->vendor_id = PCI_VENDOR_ID_MARVELL;
+    k->device_id = PCI_DEVICE_ID_MARVELL_GT6412X;
+    k->revision = 0x10;
+    k->class_id = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo gt64120_pci_info = {
+    .name = "gt64120_pci",
+    .size = sizeof(PCIDevice),
+    .class_init = gt64120_pci_class_init,
 };
 
 static void gt64120_pci_register_devices(void)
diff --git a/hw/i82378.c b/hw/i82378.c
index 95ae274..99b453a 100644
--- a/hw/i82378.c
+++ b/hw/i82378.c
@@ -238,18 +238,25 @@ static int pci_i82378_init(PCIDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo pci_i82378_info = {
-    .init = pci_i82378_init,
-    .qdev.name = "i82378",
-    .qdev.size = sizeof(PCIi82378State),
-    .qdev.vmsd = &vmstate_pci_i82378,
-    .vendor_id = PCI_VENDOR_ID_INTEL,
-    .device_id = PCI_DEVICE_ID_INTEL_82378,
-    .revision = 0x03,
-    .class_id = PCI_CLASS_BRIDGE_ISA,
-    .subsystem_vendor_id = 0x0,
-    .subsystem_id = 0x0,
-    .qdev.props = (Property[]) {
+static void pci_i82378_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_i82378_init;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82378;
+    k->revision = 0x03;
+    k->class_id = PCI_CLASS_BRIDGE_ISA;
+    k->subsystem_vendor_id = 0x0;
+    k->subsystem_id = 0x0;
+}
+
+static DeviceInfo pci_i82378_info = {
+    .name = "i82378",
+    .size = sizeof(PCIi82378State),
+    .vmsd = &vmstate_pci_i82378,
+    .class_init = pci_i82378_class_init,
+    .props = (Property[]) {
         DEFINE_PROP_HEX32("iobase", PCIi82378State, isa_io_base, 0x80000000),
         DEFINE_PROP_HEX32("membase", PCIi82378State, isa_mem_base, 0xc0000000),
         DEFINE_PROP_END_OF_LIST()
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 99e7e6f..9c673bb 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -325,20 +325,28 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
     pci_ide_create_devs(dev, hd_table);
 }
 
-static PCIDeviceInfo cmd646_ide_info = {
-    .qdev.name    = "cmd646-ide",
-    .qdev.size    = sizeof(PCIIDEState),
-    .init         = pci_cmd646_ide_initfn,
-    .exit         = pci_cmd646_ide_exitfn,
-    .vendor_id    = PCI_VENDOR_ID_CMD,
-    .device_id    = PCI_DEVICE_ID_CMD_646,
-    /* IDE controller revision */
-    .revision     = 0x07,
-    .class_id     = PCI_CLASS_STORAGE_IDE,
-    .qdev.props   = (Property[]) {
-        DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property cmd646_ide_properties[] = {
+    DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void cmd646_ide_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_cmd646_ide_initfn;
+    k->exit = pci_cmd646_ide_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_CMD;
+    k->device_id = PCI_DEVICE_ID_CMD_646;
+    k->revision = 0x07;
+    k->class_id = PCI_CLASS_STORAGE_IDE;
+}
+
+static DeviceInfo cmd646_ide_info = {
+    .name = "cmd646-ide",
+    .size = sizeof(PCIIDEState),
+    .props = cmd646_ide_properties,
+    .class_init = cmd646_ide_class_init,
 };
 
 static void cmd646_ide_register(void)
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index e6421e2..1cae9f1 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -146,18 +146,25 @@ static void pci_ich9_write_config(PCIDevice *pci, uint32_t addr,
     msi_write_config(pci, addr, val, len);
 }
 
-static PCIDeviceInfo ich_ahci_info = {
-    .qdev.name    = "ich9-ahci",
-    .qdev.alias   = "ahci",
-    .qdev.size    = sizeof(AHCIPCIState),
-    .qdev.vmsd    = &vmstate_ahci,
-    .init         = pci_ich9_ahci_init,
-    .exit         = pci_ich9_uninit,
-    .config_write = pci_ich9_write_config,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82801IR,
-    .revision     = 0x02,
-    .class_id     = PCI_CLASS_STORAGE_SATA,
+static void ich_ahci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_ich9_ahci_init;
+    k->exit = pci_ich9_uninit;
+    k->config_write = pci_ich9_write_config;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82801IR;
+    k->revision = 0x02;
+    k->class_id = PCI_CLASS_STORAGE_SATA;
+}
+
+static DeviceInfo ich_ahci_info = {
+    .name = "ich9-ahci",
+    .alias = "ahci",
+    .size = sizeof(AHCIPCIState),
+    .vmsd = &vmstate_ahci,
+    .class_init = ich_ahci_class_init,
 };
 
 static void ich_ahci_register(void)
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 91b77a2..832a507 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -237,39 +237,60 @@ PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
     return dev;
 }
 
-static PCIDeviceInfo piix3_ide_info = {
-    .qdev.name    = "piix3-ide",
-    .qdev.size    = sizeof(PCIIDEState),
-    .qdev.no_user = 1,
-    .no_hotplug   = 1,
-    .init         = pci_piix_ide_initfn,
-    .exit         = pci_piix_ide_exitfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
-    .class_id     = PCI_CLASS_STORAGE_IDE,
+static void piix3_ide_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = pci_piix_ide_initfn;
+    k->exit = pci_piix_ide_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
+    k->class_id = PCI_CLASS_STORAGE_IDE;
+}
+
+static DeviceInfo piix3_ide_info = {
+    .name = "piix3-ide",
+    .size = sizeof(PCIIDEState),
+    .no_user = 1,
+    .class_init = piix3_ide_class_init,
 };
 
-static PCIDeviceInfo piix3_ide_xen_info = {
-    .qdev.name    = "piix3-ide-xen",
-    .qdev.size    = sizeof(PCIIDEState),
-    .qdev.no_user = 1,
-    .qdev.unplug  = pci_piix3_xen_ide_unplug,
-    .init         = pci_piix_ide_initfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
-    .class_id     = PCI_CLASS_STORAGE_IDE,
+static void piix3_ide_xen_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_piix_ide_initfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
+    k->class_id = PCI_CLASS_STORAGE_IDE;
+}
+
+static DeviceInfo piix3_ide_xen_info = {
+    .name = "piix3-ide-xen",
+    .size = sizeof(PCIIDEState),
+    .no_user = 1,
+    .class_init = piix3_ide_xen_class_init,
+    .unplug = pci_piix3_xen_ide_unplug,
 };
 
-static PCIDeviceInfo piix4_ide_info = {
-    .qdev.name    = "piix4-ide",
-    .qdev.size    = sizeof(PCIIDEState),
-    .qdev.no_user = 1,
-    .no_hotplug   = 1,
-    .init         = pci_piix_ide_initfn,
-    .exit         = pci_piix_ide_exitfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82371AB,
-    .class_id     = PCI_CLASS_STORAGE_IDE,
+static void piix4_ide_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = pci_piix_ide_initfn;
+    k->exit = pci_piix_ide_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82371AB;
+    k->class_id = PCI_CLASS_STORAGE_IDE;
+}
+
+static DeviceInfo piix4_ide_info = {
+    .name = "piix4-ide",
+    .size = sizeof(PCIIDEState),
+    .no_user = 1,
+    .class_init = piix4_ide_class_init,
 };
 
 static void piix_ide_register(void)
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 4ea2064..ef70864 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -213,16 +213,23 @@ void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
     pci_ide_create_devs(dev, hd_table);
 }
 
-static PCIDeviceInfo via_ide_info = {
-    .qdev.name    = "via-ide",
-    .qdev.size    = sizeof(PCIIDEState),
-    .qdev.no_user = 1,
-    .init         = vt82c686b_ide_initfn,
-    .exit         = vt82c686b_ide_exitfn,
-    .vendor_id    = PCI_VENDOR_ID_VIA,
-    .device_id    = PCI_DEVICE_ID_VIA_IDE,
-    .revision     = 0x06,
-    .class_id     = PCI_CLASS_STORAGE_IDE,
+static void via_ide_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = vt82c686b_ide_initfn;
+    k->exit = vt82c686b_ide_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_VIA;
+    k->device_id = PCI_DEVICE_ID_VIA_IDE;
+    k->revision = 0x06;
+    k->class_id = PCI_CLASS_STORAGE_IDE;
+}
+
+static DeviceInfo via_ide_info = {
+    .name = "via-ide",
+    .size = sizeof(PCIIDEState),
+    .no_user = 1,
+    .class_init = via_ide_class_init,
 };
 
 static void via_ide_register(void)
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index f727c22..f062133 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -79,7 +79,7 @@ void hda_codec_register(DeviceInfo *info)
     info->init = hda_codec_dev_init;
     info->exit = hda_codec_dev_exit;
     info->bus_info = &hda_codec_bus_info;
-    qdev_register(info);
+    qdev_register_subclass(info, TYPE_HDA_CODEC_DEVICE);
 }
 
 HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad)
@@ -1247,29 +1247,47 @@ static const VMStateDescription vmstate_intel_hda = {
     }
 };
 
-static PCIDeviceInfo intel_hda_info = {
-    .qdev.name    = "intel-hda",
-    .qdev.desc    = "Intel HD Audio Controller",
-    .qdev.size    = sizeof(IntelHDAState),
-    .qdev.vmsd    = &vmstate_intel_hda,
-    .qdev.reset   = intel_hda_reset,
-    .init         = intel_hda_init,
-    .exit         = intel_hda_exit,
-    .config_write = intel_hda_write_config,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = 0x2668,
-    .revision     = 1,
-    .class_id     = PCI_CLASS_MULTIMEDIA_HD_AUDIO,
-    .qdev.props   = (Property[]) {
-        DEFINE_PROP_UINT32("debug", IntelHDAState, debug, 0),
-        DEFINE_PROP_UINT32("msi", IntelHDAState, msi, 1),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property intel_hda_properties[] = {
+    DEFINE_PROP_UINT32("debug", IntelHDAState, debug, 0),
+    DEFINE_PROP_UINT32("msi", IntelHDAState, msi, 1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void intel_hda_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = intel_hda_init;
+    k->exit = intel_hda_exit;
+    k->config_write = intel_hda_write_config;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = 0x2668;
+    k->revision = 1;
+    k->class_id = PCI_CLASS_MULTIMEDIA_HD_AUDIO;
+}
+
+static DeviceInfo intel_hda_info = {
+    .name = "intel-hda",
+    .desc = "Intel HD Audio Controller",
+    .size = sizeof(IntelHDAState),
+    .vmsd = &vmstate_intel_hda,
+    .reset = intel_hda_reset,
+    .props = intel_hda_properties,
+    .class_init = intel_hda_class_init,
+};
+
+static TypeInfo hda_codec_device_type_info = {
+    .name = TYPE_HDA_CODEC_DEVICE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(HDACodecDevice),
+    .abstract = true,
+    .class_size = sizeof(HDACodecDeviceClass),
 };
 
 static void intel_hda_register(void)
 {
     pci_qdev_register(&intel_hda_info);
+    type_register_static(&hda_codec_device_type_info);
 }
 device_init(intel_hda_register);
 
diff --git a/hw/ioh3420.c b/hw/ioh3420.c
index a6bfbb9..6cfafb3 100644
--- a/hw/ioh3420.c
+++ b/hw/ioh3420.c
@@ -80,7 +80,7 @@ static void ioh3420_write_config(PCIDevice *d,
 
 static void ioh3420_reset(DeviceState *qdev)
 {
-    PCIDevice *d = DO_UPCAST(PCIDevice, qdev, qdev);
+    PCIDevice *d = PCI_DEVICE(qdev);
     msi_reset(d);
     ioh3420_aer_vector_update(d);
     pcie_cap_root_reset(d);
@@ -201,31 +201,38 @@ static const VMStateDescription vmstate_ioh3420 = {
     }
 };
 
-static PCIDeviceInfo ioh3420_info = {
-    .qdev.name = "ioh3420",
-    .qdev.desc = "Intel IOH device id 3420 PCIE Root Port",
-    .qdev.size = sizeof(PCIESlot),
-    .qdev.reset = ioh3420_reset,
-    .qdev.vmsd = &vmstate_ioh3420,
-
-    .is_express = 1,
-    .is_bridge = 1,
-    .config_write = ioh3420_write_config,
-    .init = ioh3420_initfn,
-    .exit = ioh3420_exitfn,
-    .vendor_id = PCI_VENDOR_ID_INTEL,
-    .device_id = PCI_DEVICE_ID_IOH_EPORT,
-    .revision = PCI_DEVICE_ID_IOH_REV,
-
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT8("port", PCIESlot, port.port, 0),
-        DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
-        DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
-        DEFINE_PROP_UINT16("aer_log_max", PCIESlot,
-                           port.br.dev.exp.aer_log.log_max,
-                           PCIE_AER_LOG_MAX_DEFAULT),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property ioh3420_properties[] = {
+    DEFINE_PROP_UINT8("port", PCIESlot, port.port, 0),
+    DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
+    DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
+    DEFINE_PROP_UINT16("aer_log_max", PCIESlot,
+    port.br.dev.exp.aer_log.log_max,
+    PCIE_AER_LOG_MAX_DEFAULT),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ioh3420_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->is_express = 1;
+    k->is_bridge = 1;
+    k->config_write = ioh3420_write_config;
+    k->init = ioh3420_initfn;
+    k->exit = ioh3420_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_IOH_EPORT;
+    k->revision = PCI_DEVICE_ID_IOH_REV;
+}
+
+static DeviceInfo ioh3420_info = {
+    .name = "ioh3420",
+    .desc = "Intel IOH device id 3420 PCIE Root Port",
+    .size = sizeof(PCIESlot),
+    .reset = ioh3420_reset,
+    .vmsd = &vmstate_ioh3420,
+    .props = ioh3420_properties,
+    .class_init = ioh3420_class_init,
 };
 
 static void ioh3420_register(void)
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index bec2e0b..e2880be 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -766,25 +766,34 @@ static int pci_ivshmem_uninit(PCIDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo ivshmem_info = {
-    .qdev.name  = "ivshmem",
-    .qdev.size  = sizeof(IVShmemState),
-    .qdev.reset = ivshmem_reset,
-    .init       = pci_ivshmem_init,
-    .exit       = pci_ivshmem_uninit,
-    .vendor_id  = PCI_VENDOR_ID_REDHAT_QUMRANET,
-    .device_id  = 0x1110,
-    .class_id   = PCI_CLASS_MEMORY_RAM,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_CHR("chardev", IVShmemState, server_chr),
-        DEFINE_PROP_STRING("size", IVShmemState, sizearg),
-        DEFINE_PROP_UINT32("vectors", IVShmemState, vectors, 1),
-        DEFINE_PROP_BIT("ioeventfd", IVShmemState, features, IVSHMEM_IOEVENTFD, false),
-        DEFINE_PROP_BIT("msi", IVShmemState, features, IVSHMEM_MSI, true),
-        DEFINE_PROP_STRING("shm", IVShmemState, shmobj),
-        DEFINE_PROP_STRING("role", IVShmemState, role),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property ivshmem_properties[] = {
+    DEFINE_PROP_CHR("chardev", IVShmemState, server_chr),
+    DEFINE_PROP_STRING("size", IVShmemState, sizearg),
+    DEFINE_PROP_UINT32("vectors", IVShmemState, vectors, 1),
+    DEFINE_PROP_BIT("ioeventfd", IVShmemState, features, IVSHMEM_IOEVENTFD, false),
+    DEFINE_PROP_BIT("msi", IVShmemState, features, IVSHMEM_MSI, true),
+    DEFINE_PROP_STRING("shm", IVShmemState, shmobj),
+    DEFINE_PROP_STRING("role", IVShmemState, role),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ivshmem_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_ivshmem_init;
+    k->exit = pci_ivshmem_uninit;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = 0x1110;
+    k->class_id = PCI_CLASS_MEMORY_RAM;
+}
+
+static DeviceInfo ivshmem_info = {
+    .name = "ivshmem",
+    .size = sizeof(IVShmemState),
+    .reset = ivshmem_reset,
+    .props = ivshmem_properties,
+    .class_init = ivshmem_class_init,
 };
 
 static void ivshmem_register_devices(void)
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 3a87171..3571588 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -2120,18 +2120,25 @@ static int lsi_scsi_init(PCIDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo lsi_info = {
-    .qdev.name  = "lsi53c895a",
-    .qdev.alias = "lsi",
-    .qdev.size  = sizeof(LSIState),
-    .qdev.reset = lsi_scsi_reset,
-    .qdev.vmsd  = &vmstate_lsi_scsi,
-    .init       = lsi_scsi_init,
-    .exit       = lsi_scsi_uninit,
-    .vendor_id  = PCI_VENDOR_ID_LSI_LOGIC,
-    .device_id  = PCI_DEVICE_ID_LSI_53C895A,
-    .class_id   = PCI_CLASS_STORAGE_SCSI,
-    .subsystem_id = 0x1000,
+static void lsi_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = lsi_scsi_init;
+    k->exit = lsi_scsi_uninit;
+    k->vendor_id = PCI_VENDOR_ID_LSI_LOGIC;
+    k->device_id = PCI_DEVICE_ID_LSI_53C895A;
+    k->class_id = PCI_CLASS_STORAGE_SCSI;
+    k->subsystem_id = 0x1000;
+}
+
+static DeviceInfo lsi_info = {
+    .name = "lsi53c895a",
+    .alias = "lsi",
+    .size = sizeof(LSIState),
+    .reset = lsi_scsi_reset,
+    .vmsd = &vmstate_lsi_scsi,
+    .class_init = lsi_class_init,
 };
 
 static void lsi53c895a_register_devices(void)
diff --git a/hw/macio.c b/hw/macio.c
index 357e0ea..ae9db08 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -81,12 +81,19 @@ static int macio_initfn(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo macio_info = {
-    .qdev.name = "macio",
-    .qdev.size = sizeof(MacIOState),
-    .init = macio_initfn,
-    .vendor_id = PCI_VENDOR_ID_APPLE,
-    .class_id = PCI_CLASS_OTHERS << 8,
+static void macio_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = macio_initfn;
+    k->vendor_id = PCI_VENDOR_ID_APPLE;
+    k->class_id = PCI_CLASS_OTHERS << 8;
+}
+
+static DeviceInfo macio_info = {
+    .name = "macio",
+    .size = sizeof(MacIOState),
+    .class_init = macio_class_init,
 };
 
 static void macio_register(void)
diff --git a/hw/ne2000.c b/hw/ne2000.c
index b44eab1..138479a 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -786,19 +786,28 @@ static int pci_ne2000_exit(PCIDevice *pci_dev)
     return 0;
 }
 
-static PCIDeviceInfo ne2000_info = {
-    .qdev.name  = "ne2k_pci",
-    .qdev.size  = sizeof(PCINE2000State),
-    .qdev.vmsd  = &vmstate_pci_ne2000,
-    .init       = pci_ne2000_init,
-    .exit       = pci_ne2000_exit,
-    .vendor_id  = PCI_VENDOR_ID_REALTEK,
-    .device_id  = PCI_DEVICE_ID_REALTEK_8029,
-    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property ne2000_properties[] = {
+    DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ne2000_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_ne2000_init;
+    k->exit = pci_ne2000_exit;
+    k->vendor_id = PCI_VENDOR_ID_REALTEK;
+    k->device_id = PCI_DEVICE_ID_REALTEK_8029;
+    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+}
+
+static DeviceInfo ne2000_info = {
+    .name = "ne2k_pci",
+    .size = sizeof(PCINE2000State),
+    .vmsd = &vmstate_pci_ne2000,
+    .props = ne2000_properties,
+    .class_init = ne2000_class_init,
 };
 
 static void ne2000_register_devices(void)
diff --git a/hw/pci.c b/hw/pci.c
index 516da08..6a0b1f5 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -89,7 +89,6 @@ static const VMStateDescription vmstate_pcibus = {
         VMSTATE_END_OF_LIST()
     }
 };
-
 static int pci_bar(PCIDevice *d, int reg)
 {
     uint8_t type;
@@ -730,11 +729,11 @@ static void pci_config_free(PCIDevice *pci_dev)
 
 /* -1 for devfn means auto assign */
 static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
-                                         const char *name, int devfn,
-                                         const PCIDeviceInfo *info)
+                                         const char *name, int devfn)
 {
-    PCIConfigReadFunc *config_read = info->config_read;
-    PCIConfigWriteFunc *config_write = info->config_write;
+    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
+    PCIConfigReadFunc *config_read = pc->config_read;
+    PCIConfigWriteFunc *config_write = pc->config_write;
 
     if (devfn < 0) {
         for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
@@ -756,29 +755,29 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
     pci_dev->irq_state = 0;
     pci_config_alloc(pci_dev);
 
-    pci_config_set_vendor_id(pci_dev->config, info->vendor_id);
-    pci_config_set_device_id(pci_dev->config, info->device_id);
-    pci_config_set_revision(pci_dev->config, info->revision);
-    pci_config_set_class(pci_dev->config, info->class_id);
+    pci_config_set_vendor_id(pci_dev->config, pc->vendor_id);
+    pci_config_set_device_id(pci_dev->config, pc->device_id);
+    pci_config_set_revision(pci_dev->config, pc->revision);
+    pci_config_set_class(pci_dev->config, pc->class_id);
 
-    if (!info->is_bridge) {
-        if (info->subsystem_vendor_id || info->subsystem_id) {
+    if (!pc->is_bridge) {
+        if (pc->subsystem_vendor_id || pc->subsystem_id) {
             pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID,
-                         info->subsystem_vendor_id);
+                         pc->subsystem_vendor_id);
             pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID,
-                         info->subsystem_id);
+                         pc->subsystem_id);
         } else {
             pci_set_default_subsystem_id(pci_dev);
         }
     } else {
         /* subsystem_vendor_id/subsystem_id are only for header type 0 */
-        assert(!info->subsystem_vendor_id);
-        assert(!info->subsystem_id);
+        assert(!pc->subsystem_vendor_id);
+        assert(!pc->subsystem_id);
     }
     pci_init_cmask(pci_dev);
     pci_init_wmask(pci_dev);
     pci_init_w1cmask(pci_dev);
-    if (info->is_bridge) {
+    if (pc->is_bridge) {
         pci_init_wmask_bridge(pci_dev);
     }
     if (pci_init_multifunction(bus, pci_dev)) {
@@ -805,26 +804,6 @@ static void do_pci_unregister_device(PCIDevice *pci_dev)
     pci_config_free(pci_dev);
 }
 
-/* TODO: obsolete. eliminate this once all pci devices are qdevifed. */
-PCIDevice *pci_register_device(PCIBus *bus, const char *name,
-                               int instance_size, int devfn,
-                               PCIConfigReadFunc *config_read,
-                               PCIConfigWriteFunc *config_write)
-{
-    PCIDevice *pci_dev;
-    PCIDeviceInfo info = {
-        .config_read = config_read,
-        .config_write = config_write,
-    };
-
-    pci_dev = g_malloc0(instance_size);
-    pci_dev = do_pci_register_device(pci_dev, bus, name, devfn, &info);
-    if (pci_dev == NULL) {
-        hw_error("PCI: can't register device\n");
-    }
-    return pci_dev;
-}
-
 static void pci_unregister_io_regions(PCIDevice *pci_dev)
 {
     PCIIORegion *r;
@@ -840,12 +819,12 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
 
 static int pci_unregister_device(DeviceState *dev)
 {
-    PCIDevice *pci_dev = DO_UPCAST(PCIDevice, qdev, dev);
-    PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, qdev_get_info(dev));
+    PCIDevice *pci_dev = PCI_DEVICE(dev);
+    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
     int ret = 0;
 
-    if (info->exit)
-        ret = info->exit(pci_dev);
+    if (pc->exit)
+        ret = pc->exit(pci_dev);
     if (ret)
         return ret;
 
@@ -1477,28 +1456,27 @@ PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn)
 static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
 {
     PCIDevice *pci_dev = (PCIDevice *)qdev;
-    PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
+    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
     PCIBus *bus;
     int rc;
     bool is_default_rom;
 
     /* initialize cap_present for pci_is_express() and pci_config_size() */
-    if (info->is_express) {
+    if (pc->is_express) {
         pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
     }
 
     bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
-    pci_dev = do_pci_register_device(pci_dev, bus, base->name,
-                                     pci_dev->devfn, info);
+    pci_dev = do_pci_register_device(pci_dev, bus, base->name, pci_dev->devfn);
     if (pci_dev == NULL)
         return -1;
-    if (qdev->hotplugged && info->no_hotplug) {
+    if (qdev->hotplugged && pc->no_hotplug) {
         qerror_report(QERR_DEVICE_NO_HOTPLUG, object_get_typename(OBJECT(pci_dev)));
         do_pci_unregister_device(pci_dev);
         return -1;
     }
-    if (info->init) {
-        rc = info->init(pci_dev);
+    if (pc->init) {
+        rc = pc->init(pci_dev);
         if (rc != 0) {
             do_pci_unregister_device(pci_dev);
             return rc;
@@ -1507,8 +1485,8 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
 
     /* rom loading */
     is_default_rom = false;
-    if (pci_dev->romfile == NULL && info->romfile != NULL) {
-        pci_dev->romfile = g_strdup(info->romfile);
+    if (pci_dev->romfile == NULL && pc->romfile != NULL) {
+        pci_dev->romfile = g_strdup(pc->romfile);
         is_default_rom = true;
     }
     pci_add_option_rom(pci_dev, is_default_rom);
@@ -1530,10 +1508,10 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
 
 static int pci_unplug_device(DeviceState *qdev)
 {
-    PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);
-    PCIDeviceInfo *info = container_of(qdev_get_info(qdev), PCIDeviceInfo, qdev);
+    PCIDevice *dev = PCI_DEVICE(qdev);
+    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
 
-    if (info->no_hotplug) {
+    if (pc->no_hotplug) {
         qerror_report(QERR_DEVICE_NO_HOTPLUG, object_get_typename(OBJECT(dev)));
         return -1;
     }
@@ -1541,23 +1519,15 @@ static int pci_unplug_device(DeviceState *qdev)
                              PCI_HOTPLUG_DISABLED);
 }
 
-void pci_qdev_register(PCIDeviceInfo *info)
-{
-    info->qdev.init = pci_qdev_init;
-    if (!info->qdev.unplug) {
-        info->qdev.unplug = pci_unplug_device;
-    }
-    info->qdev.exit = pci_unregister_device;
-    info->qdev.bus_info = &pci_bus_info;
-    qdev_register(&info->qdev);
-}
-
-void pci_qdev_register_many(PCIDeviceInfo *info)
+void pci_qdev_register(DeviceInfo *info)
 {
-    while (info->qdev.name) {
-        pci_qdev_register(info);
-        info++;
+    info->init = pci_qdev_init;
+    if (!info->unplug) {
+        info->unplug = pci_unplug_device;
     }
+    info->exit = pci_unregister_device;
+    info->bus_info = &pci_bus_info;
+    qdev_register_subclass(info, TYPE_PCI_DEVICE);
 }
 
 PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction,
@@ -1568,7 +1538,7 @@ PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction,
     dev = qdev_create(&bus->qbus, name);
     qdev_prop_set_uint32(dev, "addr", devfn);
     qdev_prop_set_bit(dev, "multifunction", multifunction);
-    return DO_UPCAST(PCIDevice, qdev, dev);
+    return PCI_DEVICE(dev);
 }
 
 PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,
@@ -1985,7 +1955,7 @@ static int pci_qdev_find_recursive(PCIBus *bus,
     /* roughly check if given qdev is pci device */
     if (qdev_get_info(qdev)->init == &pci_qdev_init &&
         qdev->parent_bus->info == &pci_bus_info) {
-        *pdev = DO_UPCAST(PCIDevice, qdev, qdev);
+        *pdev = PCI_DEVICE(qdev);
         return 0;
     }
     return -EINVAL;
@@ -2019,3 +1989,18 @@ MemoryRegion *pci_address_space_io(PCIDevice *dev)
 {
     return dev->bus->address_space_io;
 }
+
+static TypeInfo pci_device_type_info = {
+    .name = TYPE_PCI_DEVICE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(PCIDevice),
+    .abstract = true,
+    .class_size = sizeof(PCIDeviceClass),
+};
+
+static void pci_register_devices(void)
+{
+    type_register_static(&pci_device_type_info);
+}
+
+device_init(pci_register_devices);
diff --git a/hw/pci.h b/hw/pci.h
index 5501d95..09b2324 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -127,6 +127,46 @@ enum {
     QEMU_PCI_CAP_SERR = (1 << QEMU_PCI_CAP_SERR_BITNR),
 };
 
+#define TYPE_PCI_DEVICE "pci-device"
+#define PCI_DEVICE(obj) \
+     OBJECT_CHECK(PCIDevice, (obj), TYPE_PCI_DEVICE)
+#define PCI_DEVICE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(PCIDeviceClass, (klass), TYPE_PCI_DEVICE)
+#define PCI_DEVICE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(PCIDeviceClass, (obj), TYPE_PCI_DEVICE)
+
+typedef struct PCIDeviceClass {
+    DeviceClass parent_class;
+
+    int (*init)(PCIDevice *dev);
+    PCIUnregisterFunc *exit;
+    PCIConfigReadFunc *config_read;
+    PCIConfigWriteFunc *config_write;
+
+    uint16_t vendor_id;
+    uint16_t device_id;
+    uint8_t revision;
+    uint16_t class_id;
+    uint16_t subsystem_vendor_id;       /* only for header type = 0 */
+    uint16_t subsystem_id;              /* only for header type = 0 */
+
+    /*
+     * pci-to-pci bridge or normal device.
+     * This doesn't mean pci host switch.
+     * When card bus bridge is supported, this would be enhanced.
+     */
+    int is_bridge;
+
+    /* pcie stuff */
+    int is_express;   /* is this device pci express? */
+
+    /* device isn't hot-pluggable */
+    int no_hotplug;
+
+    /* rom bar */
+    const char *romfile;
+} PCIDeviceClass;
+
 struct PCIDevice {
     DeviceState qdev;
     /* PCI config space */
@@ -196,11 +236,6 @@ struct PCIDevice {
     uint32_t rom_bar;
 };
 
-PCIDevice *pci_register_device(PCIBus *bus, const char *name,
-                               int instance_size, int devfn,
-                               PCIConfigReadFunc *config_read,
-                               PCIConfigWriteFunc *config_write);
-
 void pci_register_bar(PCIDevice *pci_dev, int region_num,
                       uint8_t attr, MemoryRegion *memory);
 pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num);
@@ -429,40 +464,7 @@ pci_quad_test_and_set_mask(uint8_t *config, uint64_t mask)
     return val & mask;
 }
 
-typedef int (*pci_qdev_initfn)(PCIDevice *dev);
-typedef struct {
-    DeviceInfo qdev;
-    pci_qdev_initfn init;
-    PCIUnregisterFunc *exit;
-    PCIConfigReadFunc *config_read;
-    PCIConfigWriteFunc *config_write;
-
-    uint16_t vendor_id;
-    uint16_t device_id;
-    uint8_t revision;
-    uint16_t class_id;
-    uint16_t subsystem_vendor_id;       /* only for header type = 0 */
-    uint16_t subsystem_id;              /* only for header type = 0 */
-
-    /*
-     * pci-to-pci bridge or normal device.
-     * This doesn't mean pci host switch.
-     * When card bus bridge is supported, this would be enhanced.
-     */
-    int is_bridge;
-
-    /* pcie stuff */
-    int is_express;   /* is this device pci express? */
-
-    /* device isn't hot-pluggable */
-    int no_hotplug;
-
-    /* rom bar */
-    const char *romfile;
-} PCIDeviceInfo;
-
-void pci_qdev_register(PCIDeviceInfo *info);
-void pci_qdev_register_many(PCIDeviceInfo *info);
+void pci_qdev_register(DeviceInfo *info);
 
 PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction,
                                     const char *name);
diff --git a/hw/pci_bridge.c b/hw/pci_bridge.c
index 650d165..1ed4339 100644
--- a/hw/pci_bridge.c
+++ b/hw/pci_bridge.c
@@ -294,7 +294,7 @@ void pci_bridge_reset_reg(PCIDevice *dev)
 /* default reset function for PCI-to-PCI bridge */
 void pci_bridge_reset(DeviceState *qdev)
 {
-    PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);
+    PCIDevice *dev = PCI_DEVICE(qdev);
     pci_bridge_reset_reg(dev);
 }
 
diff --git a/hw/pcie.c b/hw/pcie.c
index 5c9eb2f..7c92f19 100644
--- a/hw/pcie.c
+++ b/hw/pcie.c
@@ -203,7 +203,7 @@ static void pcie_cap_slot_event(PCIDevice *dev, PCIExpressHotPlugEvent event)
 static int pcie_cap_slot_hotplug(DeviceState *qdev,
                                  PCIDevice *pci_dev, PCIHotplugState state)
 {
-    PCIDevice *d = DO_UPCAST(PCIDevice, qdev, qdev);
+    PCIDevice *d = PCI_DEVICE(qdev);
     uint8_t *exp_cap = d->config + d->exp.exp_cap;
     uint16_t sltsta = pci_get_word(exp_cap + PCI_EXP_SLTSTA);
 
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 4e164da..be3bd79 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -348,21 +348,30 @@ static void pci_reset(DeviceState *dev)
     pcnet_h_reset(&d->state);
 }
 
-static PCIDeviceInfo pcnet_info = {
-    .qdev.name  = "pcnet",
-    .qdev.size  = sizeof(PCIPCNetState),
-    .qdev.reset = pci_reset,
-    .qdev.vmsd  = &vmstate_pci_pcnet,
-    .init       = pci_pcnet_init,
-    .exit       = pci_pcnet_uninit,
-    .vendor_id  = PCI_VENDOR_ID_AMD,
-    .device_id  = PCI_DEVICE_ID_AMD_LANCE,
-    .revision   = 0x10,
-    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property pcnet_properties[] = {
+    DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pcnet_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_pcnet_init;
+    k->exit = pci_pcnet_uninit;
+    k->vendor_id = PCI_VENDOR_ID_AMD;
+    k->device_id = PCI_DEVICE_ID_AMD_LANCE;
+    k->revision = 0x10;
+    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+}
+
+static DeviceInfo pcnet_info = {
+    .name = "pcnet",
+    .size = sizeof(PCIPCNetState),
+    .reset = pci_reset,
+    .vmsd = &vmstate_pci_pcnet,
+    .props = pcnet_properties,
+    .class_init = pcnet_class_init,
 };
 
 static void pci_pcnet_register_devices(void)
diff --git a/hw/piix4.c b/hw/piix4.c
index 130dfd1..88be535 100644
--- a/hw/piix4.c
+++ b/hw/piix4.c
@@ -102,18 +102,24 @@ int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn)
     return d->devfn;
 }
 
-static PCIDeviceInfo piix4_info = {
-    .qdev.name    = "PIIX4",
-    .qdev.desc    = "ISA bridge",
-    .qdev.size    = sizeof(PIIX4State),
-    .qdev.vmsd    = &vmstate_piix4,
-    .qdev.no_user = 1,
-    .no_hotplug   = 1,
-    .init         = piix4_initfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    /* 82371AB/EB/MB PIIX4 PCI-to-ISA bridge */
-    .device_id    = PCI_DEVICE_ID_INTEL_82371AB_0,
-    .class_id     = PCI_CLASS_BRIDGE_ISA,
+static void piix4_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = piix4_initfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82371AB_0;
+    k->class_id = PCI_CLASS_BRIDGE_ISA;
+}
+
+static DeviceInfo piix4_info = {
+    .name = "PIIX4",
+    .desc = "ISA bridge",
+    .size = sizeof(PIIX4State),
+    .vmsd = &vmstate_piix4,
+    .no_user = 1,
+    .class_init = piix4_class_init,
 };
 
 static void piix4_register(void)
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 5cbeed5..787db4e 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -502,47 +502,68 @@ static int piix3_initfn(PCIDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo i440fx_info = {
-    .qdev.name    = "i440FX",
-    .qdev.desc    = "Host bridge",
-    .qdev.size    = sizeof(PCII440FXState),
-    .qdev.vmsd    = &vmstate_i440fx,
-    .qdev.no_user = 1,
-    .no_hotplug   = 1,
-    .init         = i440fx_initfn,
-    .config_write = i440fx_write_config,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82441,
-    .revision     = 0x02,
-    .class_id     = PCI_CLASS_BRIDGE_HOST,
+static void piix3_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug   = 1;
+    k->init         = piix3_initfn;
+    k->config_write = piix3_write_config;
+    k->vendor_id    = PCI_VENDOR_ID_INTEL;
+    k->device_id    = PCI_DEVICE_ID_INTEL_82371SB_0; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
+    k->class_id     = PCI_CLASS_BRIDGE_ISA;
+}
+
+static DeviceInfo piix3_info = {
+    .name    = "PIIX3",
+    .desc    = "ISA bridge",
+    .size    = sizeof(PIIX3State),
+    .vmsd    = &vmstate_piix3,
+    .no_user = 1,
+    .class_init = piix3_class_init,
 };
 
-static PCIDeviceInfo piix3_info = {
-    .qdev.name    = "PIIX3",
-    .qdev.desc    = "ISA bridge",
-    .qdev.size    = sizeof(PIIX3State),
-    .qdev.vmsd    = &vmstate_piix3,
-    .qdev.no_user = 1,
-    .no_hotplug   = 1,
-    .init         = piix3_initfn,
-    .config_write = piix3_write_config,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
-    .class_id     = PCI_CLASS_BRIDGE_ISA,
+static void piix3_xen_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug   = 1;
+    k->init         = piix3_initfn;
+    k->config_write = piix3_write_config_xen;
+    k->vendor_id    = PCI_VENDOR_ID_INTEL;
+    k->device_id    = PCI_DEVICE_ID_INTEL_82371SB_0; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
+    k->class_id     = PCI_CLASS_BRIDGE_ISA;
 };
 
-static PCIDeviceInfo piix3_xen_info = {
-    .qdev.name    = "PIIX3-xen",
-    .qdev.desc    = "ISA bridge",
-    .qdev.size    = sizeof(PIIX3State),
-    .qdev.vmsd    = &vmstate_piix3,
-    .qdev.no_user = 1,
-    .no_hotplug   = 1,
-    .init         = piix3_initfn,
-    .config_write = piix3_write_config_xen,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
-    .class_id     = PCI_CLASS_BRIDGE_ISA,
+static DeviceInfo piix3_xen_info = {
+    .name    = "PIIX3-xen",
+    .desc    = "ISA bridge",
+    .size    = sizeof(PIIX3State),
+    .vmsd    = &vmstate_piix3,
+    .no_user = 1,
+    .class_init = piix3_xen_class_init,
+};
+
+static void i440fx_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = i440fx_initfn;
+    k->config_write = i440fx_write_config;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82441;
+    k->revision = 0x02;
+    k->class_id = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo i440fx_info = {
+    .name = "i440FX",
+    .desc = "Host bridge",
+    .size = sizeof(PCII440FXState),
+    .vmsd = &vmstate_i440fx,
+    .no_user = 1,
+    .class_init = i440fx_class_init,
 };
 
 static SysBusDeviceInfo i440fx_pcihost_info = {
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index 26de007..b38840e 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -366,13 +366,20 @@ static int ppc4xx_pcihost_initfn(SysBusDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo ppc4xx_host_bridge_info = {
-    .qdev.name    = "ppc4xx-host-bridge",
-    .qdev.desc    = "Host bridge",
-    .qdev.size    = sizeof(PCIDevice),
-    .vendor_id    = PCI_VENDOR_ID_IBM,
-    .device_id    = PCI_DEVICE_ID_IBM_440GX,
-    .class_id     = PCI_CLASS_BRIDGE_OTHER,
+static void ppc4xx_host_bridge_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->vendor_id    = PCI_VENDOR_ID_IBM;
+    k->device_id    = PCI_DEVICE_ID_IBM_440GX;
+    k->class_id     = PCI_CLASS_BRIDGE_OTHER;
+}
+
+static DeviceInfo ppc4xx_host_bridge_info = {
+    .name    = "ppc4xx-host-bridge",
+    .desc    = "Host bridge",
+    .size    = sizeof(PCIDevice),
+    .class_init = ppc4xx_host_bridge_class_init,
 };
 
 static SysBusDeviceInfo ppc4xx_pcihost_info = {
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index b606206..bc783bf 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -339,13 +339,20 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo e500_host_bridge_info = {
-    .qdev.name    = "e500-host-bridge",
-    .qdev.desc    = "Host bridge",
-    .qdev.size    = sizeof(PCIDevice),
-    .vendor_id    = PCI_VENDOR_ID_FREESCALE,
-    .device_id    = PCI_DEVICE_ID_MPC8533E,
-    .class_id     = PCI_CLASS_PROCESSOR_POWERPC,
+static void e500_host_bridge_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->vendor_id = PCI_VENDOR_ID_FREESCALE;
+    k->device_id = PCI_DEVICE_ID_MPC8533E;
+    k->class_id = PCI_CLASS_PROCESSOR_POWERPC;
+}
+
+static DeviceInfo e500_host_bridge_info = {
+    .name = "e500-host-bridge",
+    .desc = "Host bridge",
+    .size = sizeof(PCIDevice),
+    .class_init = e500_host_bridge_class_init,
 };
 
 static SysBusDeviceInfo e500_pcihost_info = {
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index 4961eed..4ff1049 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -134,21 +134,24 @@ static const VMStateDescription vmstate_raven = {
     },
 };
 
-static PCIDeviceInfo raven_info = {
-    .qdev.name = "raven",
-    .qdev.desc = "PReP Host Bridge - Motorola Raven",
-    .qdev.size = sizeof(RavenPCIState),
-    .qdev.vmsd = &vmstate_raven,
-    .qdev.no_user = 1,
-    .no_hotplug = 1,
-    .init = raven_init,
-    .vendor_id = PCI_VENDOR_ID_MOTOROLA,
-    .device_id = PCI_DEVICE_ID_MOTOROLA_RAVEN,
-    .revision = 0x00,
-    .class_id = PCI_CLASS_BRIDGE_HOST,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_END_OF_LIST()
-    },
+static void raven_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = raven_init;
+    k->vendor_id = PCI_VENDOR_ID_MOTOROLA;
+    k->device_id = PCI_DEVICE_ID_MOTOROLA_RAVEN;
+    k->revision = 0x00;
+    k->class_id = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo raven_info = {
+    .name = "raven",
+    .desc = "PReP Host Bridge - Motorola Raven",
+    .size = sizeof(RavenPCIState),
+    .vmsd = &vmstate_raven,
+    .no_user = 1,
+    .class_init = raven_class_init,
 };
 
 static SysBusDeviceInfo raven_pcihost_info = {
diff --git a/hw/qdev.c b/hw/qdev.c
index 81996bb..a8c24de 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -119,6 +119,7 @@ bool qdev_exists(const char *name)
 {
     return !!qdev_find_info(NULL, name);
 }
+
 static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
                                      Error **errp);
 
diff --git a/hw/qxl.c b/hw/qxl.c
index 2a716bf..7aa7d19 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1827,32 +1827,46 @@ static Property qxl_properties[] = {
         DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo qxl_primary_info = {
-    .qdev.name    = "qxl-vga",
-    .qdev.desc    = "Spice QXL GPU (primary, vga compatible)",
-    .qdev.size    = sizeof(PCIQXLDevice),
-    .qdev.reset   = qxl_reset_handler,
-    .qdev.vmsd    = &qxl_vmstate,
-    .no_hotplug   = 1,
-    .init         = qxl_init_primary,
-    .romfile      = "vgabios-qxl.bin",
-    .vendor_id    = REDHAT_PCI_VENDOR_ID,
-    .device_id    = QXL_DEVICE_ID_STABLE,
-    .class_id     = PCI_CLASS_DISPLAY_VGA,
-    .qdev.props   = qxl_properties,
+static void qxl_primary_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = qxl_init_primary;
+    k->romfile = "vgabios-qxl.bin";
+    k->vendor_id = REDHAT_PCI_VENDOR_ID;
+    k->device_id = QXL_DEVICE_ID_STABLE;
+    k->class_id = PCI_CLASS_DISPLAY_VGA;
+}
+
+static DeviceInfo qxl_primary_info = {
+    .name = "qxl-vga",
+    .desc = "Spice QXL GPU (primary, vga compatible)",
+    .size = sizeof(PCIQXLDevice),
+    .reset = qxl_reset_handler,
+    .vmsd = &qxl_vmstate,
+    .props = qxl_properties,
+    .class_init = qxl_primary_class_init,
 };
 
-static PCIDeviceInfo qxl_secondary_info = {
-    .qdev.name    = "qxl",
-    .qdev.desc    = "Spice QXL GPU (secondary)",
-    .qdev.size    = sizeof(PCIQXLDevice),
-    .qdev.reset   = qxl_reset_handler,
-    .qdev.vmsd    = &qxl_vmstate,
-    .init         = qxl_init_secondary,
-    .vendor_id    = REDHAT_PCI_VENDOR_ID,
-    .device_id    = QXL_DEVICE_ID_STABLE,
-    .class_id     = PCI_CLASS_DISPLAY_OTHER,
-    .qdev.props   = qxl_properties,
+static void qxl_secondary_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = qxl_init_secondary;
+    k->vendor_id = REDHAT_PCI_VENDOR_ID;
+    k->device_id = QXL_DEVICE_ID_STABLE;
+    k->class_id = PCI_CLASS_DISPLAY_OTHER;
+}
+
+static DeviceInfo qxl_secondary_info = {
+    .name = "qxl",
+    .desc = "Spice QXL GPU (secondary)",
+    .size = sizeof(PCIQXLDevice),
+    .reset = qxl_reset_handler,
+    .vmsd = &qxl_vmstate,
+    .props = qxl_properties,
+    .class_init = qxl_secondary_class_init,
 };
 
 static void qxl_register(void)
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 2b55c7f..15dec9b 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3494,22 +3494,31 @@ static int pci_rtl8139_init(PCIDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo rtl8139_info = {
-    .qdev.name  = "rtl8139",
-    .qdev.size  = sizeof(RTL8139State),
-    .qdev.reset = rtl8139_reset,
-    .qdev.vmsd  = &vmstate_rtl8139,
-    .init       = pci_rtl8139_init,
-    .exit       = pci_rtl8139_uninit,
-    .romfile    = "pxe-rtl8139.rom",
-    .vendor_id  = PCI_VENDOR_ID_REALTEK,
-    .device_id  = PCI_DEVICE_ID_REALTEK_8139,
-    .revision   = RTL8139_PCI_REVID, /* >=0x20 is for 8139C+ */
-    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(RTL8139State, conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property rtl8139_properties[] = {
+    DEFINE_NIC_PROPERTIES(RTL8139State, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void rtl8139_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_rtl8139_init;
+    k->exit = pci_rtl8139_uninit;
+    k->romfile = "pxe-rtl8139.rom";
+    k->vendor_id = PCI_VENDOR_ID_REALTEK;
+    k->device_id = PCI_DEVICE_ID_REALTEK_8139;
+    k->revision = RTL8139_PCI_REVID; /* >=0x20 is for 8139C+ */
+    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+}
+
+static DeviceInfo rtl8139_info = {
+    .name = "rtl8139",
+    .size = sizeof(RTL8139State),
+    .reset = rtl8139_reset,
+    .vmsd = &vmstate_rtl8139,
+    .props = rtl8139_properties,
+    .class_init = rtl8139_class_init,
 };
 
 static void rtl8139_register_devices(void)
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index d4d028d..baeab9e 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -147,12 +147,19 @@ static int sh_pci_host_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo sh_pci_host_info = {
-    .qdev.name = "sh_pci_host",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = sh_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_HITACHI,
-    .device_id = PCI_DEVICE_ID_HITACHI_SH7751R,
+static void sh_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = sh_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_HITACHI;
+    k->device_id = PCI_DEVICE_ID_HITACHI_SH7751R;
+}
+
+static DeviceInfo sh_pci_host_info = {
+    .name = "sh_pci_host",
+    .size = sizeof(PCIDevice),
+    .class_init = sh_pci_host_class_init,
 };
 
 static void sh_pci_register_devices(void)
diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c
index 2c95faa..8a39f8f 100644
--- a/hw/spapr_pci.c
+++ b/hw/spapr_pci.c
@@ -214,10 +214,17 @@ static int spapr_main_pci_host_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo spapr_main_pci_host_info = {
-    .qdev.name = "spapr-pci-host-bridge",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = spapr_main_pci_host_init,
+static void spapr_main_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = spapr_main_pci_host_init;
+}
+
+static DeviceInfo spapr_main_pci_host_info = {
+    .name = "spapr-pci-host-bridge",
+    .size = sizeof(PCIDevice),
+    .class_init = spapr_main_pci_host_class_init,
 };
 
 static void spapr_register_devices(void)
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 2dc3d04..6d9fdf6 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -562,14 +562,21 @@ pci_ebus_init1(PCIDevice *pci_dev)
     return 0;
 }
 
-static PCIDeviceInfo ebus_info = {
-    .qdev.name = "ebus",
-    .qdev.size = sizeof(EbusState),
-    .init = pci_ebus_init1,
-    .vendor_id = PCI_VENDOR_ID_SUN,
-    .device_id = PCI_DEVICE_ID_SUN_EBUS,
-    .revision = 0x01,
-    .class_id = PCI_CLASS_BRIDGE_OTHER,
+static void ebus_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_ebus_init1;
+    k->vendor_id = PCI_VENDOR_ID_SUN;
+    k->device_id = PCI_DEVICE_ID_SUN_EBUS;
+    k->revision = 0x01;
+    k->class_id = PCI_CLASS_BRIDGE_OTHER;
+}
+
+static DeviceInfo ebus_info = {
+    .name = "ebus",
+    .size = sizeof(EbusState),
+    .class_init = ebus_class_init,
 };
 
 static void pci_ebus_register(void)
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 6a10013..6a148e0 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -339,44 +339,72 @@ static int unin_internal_pci_host_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo unin_main_pci_host_info = {
-    .qdev.name = "uni-north-pci",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = unin_main_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_APPLE,
-    .device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI,
-    .revision  = 0x00,
-    .class_id  = PCI_CLASS_BRIDGE_HOST,
+static void unin_main_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init      = unin_main_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_APPLE;
+    k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI;
+    k->revision  = 0x00;
+    k->class_id  = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo unin_main_pci_host_info = {
+    .name = "uni-north-pci",
+    .size = sizeof(PCIDevice),
+    .class_init = unin_main_pci_host_class_init,
 };
 
-static PCIDeviceInfo u3_agp_pci_host_info = {
-    .qdev.name = "u3-agp",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = u3_agp_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_APPLE,
-    .device_id = PCI_DEVICE_ID_APPLE_U3_AGP,
-    .revision  = 0x00,
-    .class_id  = PCI_CLASS_BRIDGE_HOST,
+static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init      = u3_agp_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_APPLE;
+    k->device_id = PCI_DEVICE_ID_APPLE_U3_AGP;
+    k->revision  = 0x00;
+    k->class_id  = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo u3_agp_pci_host_info = {
+    .name = "u3-agp",
+    .size = sizeof(PCIDevice),
+    .class_init = u3_agp_pci_host_class_init,
 };
 
-static PCIDeviceInfo unin_agp_pci_host_info = {
-    .qdev.name = "uni-north-agp",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = unin_agp_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_APPLE,
-    .device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP,
-    .revision  = 0x00,
-    .class_id  = PCI_CLASS_BRIDGE_HOST,
+static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init      = unin_agp_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_APPLE;
+    k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP;
+    k->revision  = 0x00;
+    k->class_id  = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo unin_agp_pci_host_info = {
+    .name = "uni-north-agp",
+    .size = sizeof(PCIDevice),
+    .class_init = unin_agp_pci_host_class_init,
 };
 
-static PCIDeviceInfo unin_internal_pci_host_info = {
-    .qdev.name = "uni-north-internal-pci",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = unin_internal_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_APPLE,
-    .device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI,
-    .revision  = 0x00,
-    .class_id  = PCI_CLASS_BRIDGE_HOST,
+static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init      = unin_internal_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_APPLE;
+    k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI;
+    k->revision  = 0x00;
+    k->class_id  = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo unin_internal_pci_host_info = {
+    .name = "uni-north-internal-pci",
+    .size = sizeof(PCIDevice),
+    .class_init = unin_internal_pci_host_class_init,
 };
 
 static SysBusDeviceInfo sysbus_unin_pci_host_info = {
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 63fc3c7..8baff1d 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -2263,28 +2263,42 @@ static Property ehci_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo ehci_info = {
-    .qdev.name    = "usb-ehci",
-    .qdev.size    = sizeof(EHCIState),
-    .qdev.vmsd    = &vmstate_ehci,
-    .init         = usb_ehci_initfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82801D, /* ich4 */
-    .revision     = 0x10,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .qdev.props   = ehci_properties,
+static void ehci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_ehci_initfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82801D; /* ich4 */
+    k->revision = 0x10;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo ehci_info = {
+    .name = "usb-ehci",
+    .size = sizeof(EHCIState),
+    .vmsd = &vmstate_ehci,
+    .props = ehci_properties,
+    .class_init = ehci_class_init,
 };
 
-static PCIDeviceInfo ich9_ehci_info = {
-    .qdev.name    = "ich9-usb-ehci1",
-    .qdev.size    = sizeof(EHCIState),
-    .qdev.vmsd    = &vmstate_ehci,
-    .init         = usb_ehci_initfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82801I_EHCI1,
-    .revision     = 0x03,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .qdev.props   = ehci_properties,
+static void ich9_ehci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_ehci_initfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82801I_EHCI1;
+    k->revision = 0x03;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo ich9_ehci_info = {
+    .name = "ich9-usb-ehci1",
+    .size = sizeof(EHCIState),
+    .vmsd = &vmstate_ehci,
+    .props = ehci_properties,
+    .class_init = ich9_ehci_class_init,
 };
 
 static int usb_ehci_initfn(PCIDevice *dev)
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 2df6a6e..b9b37d5 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1836,20 +1836,29 @@ static int ohci_init_pxa(SysBusDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo ohci_pci_info = {
-    .qdev.name    = "pci-ohci",
-    .qdev.desc    = "Apple USB Controller",
-    .qdev.size    = sizeof(OHCIPCIState),
-    .init         = usb_ohci_initfn_pci,
-    .vendor_id    = PCI_VENDOR_ID_APPLE,
-    .device_id    = PCI_DEVICE_ID_APPLE_IPID_USB,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .qdev.props   = (Property[]) {
-        DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus),
-        DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3),
-        DEFINE_PROP_UINT32("firstport", OHCIPCIState, firstport, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property ohci_pci_properties[] = {
+    DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus),
+    DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3),
+    DEFINE_PROP_UINT32("firstport", OHCIPCIState, firstport, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ohci_pci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_ohci_initfn_pci;
+    k->vendor_id = PCI_VENDOR_ID_APPLE;
+    k->device_id = PCI_DEVICE_ID_APPLE_IPID_USB;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo ohci_pci_info = {
+    .name = "pci-ohci",
+    .desc = "Apple USB Controller",
+    .size = sizeof(OHCIPCIState),
+    .props = ohci_pci_properties,
+    .class_init = ohci_pci_class_init,
 };
 
 static SysBusDeviceInfo ohci_sysbus_info = {
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 1821063..e20d7c4 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1192,79 +1192,121 @@ static Property uhci_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo piix3_uhci_info = {
-        .qdev.name    = "piix3-usb-uhci",
-        .qdev.size    = sizeof(UHCIState),
-        .qdev.vmsd    = &vmstate_uhci,
-        .init         = usb_uhci_common_initfn,
-        .exit         = usb_uhci_exit,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371SB_2,
-        .revision     = 0x01,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = uhci_properties,
+static void piix3_uhci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_uhci_common_initfn;
+    k->exit = usb_uhci_exit;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82371SB_2;
+    k->revision = 0x01;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo piix3_uhci_info = {
+    .name = "piix3-usb-uhci",
+    .size = sizeof(UHCIState),
+    .vmsd = &vmstate_uhci,
+    .props = uhci_properties,
+    .class_init = piix3_uhci_class_init,
 };
 
-static PCIDeviceInfo piix4_uhci_info = {
-        .qdev.name    = "piix4-usb-uhci",
-        .qdev.size    = sizeof(UHCIState),
-        .qdev.vmsd    = &vmstate_uhci,
-        .init         = usb_uhci_common_initfn,
-        .exit         = usb_uhci_exit,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371AB_2,
-        .revision     = 0x01,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = uhci_properties,
+static void piix4_uhci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_uhci_common_initfn;
+    k->exit = usb_uhci_exit;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82371AB_2;
+    k->revision = 0x01;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo piix4_uhci_info = {
+    .name = "piix4-usb-uhci",
+    .size = sizeof(UHCIState),
+    .vmsd = &vmstate_uhci,
+    .props = uhci_properties,
+    .class_init = piix4_uhci_class_init,
 };
 
-static PCIDeviceInfo vt82c686b_uhci_info = {
-    .qdev.name    = "vt82c686b-usb-uhci",
-    .qdev.size    = sizeof(UHCIState),
-    .qdev.vmsd    = &vmstate_uhci,
-    .init         = usb_uhci_vt82c686b_initfn,
-    .exit         = usb_uhci_exit,
-    .vendor_id    = PCI_VENDOR_ID_VIA,
-    .device_id    = PCI_DEVICE_ID_VIA_UHCI,
-    .revision     = 0x01,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .qdev.props   = uhci_properties,
+static void vt82c686b_uhci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_uhci_vt82c686b_initfn;
+    k->exit = usb_uhci_exit;
+    k->vendor_id = PCI_VENDOR_ID_VIA;
+    k->device_id = PCI_DEVICE_ID_VIA_UHCI;
+    k->revision = 0x01;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo vt82c686b_uhci_info = {
+    .name = "vt82c686b-usb-uhci",
+    .size = sizeof(UHCIState),
+    .vmsd = &vmstate_uhci,
+    .props = uhci_properties,
+    .class_init = vt82c686b_uhci_class_init,
 };
 
-static PCIDeviceInfo ich9_uhci1_info = {
-    .qdev.name    = "ich9-usb-uhci1",
-    .qdev.size    = sizeof(UHCIState),
-    .qdev.vmsd    = &vmstate_uhci,
-    .init         = usb_uhci_common_initfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI1,
-    .revision     = 0x03,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .qdev.props   = uhci_properties,
+static void ich9_uhci1_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_uhci_common_initfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI1;
+    k->revision = 0x03;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo ich9_uhci1_info = {
+    .name = "ich9-usb-uhci1",
+    .size = sizeof(UHCIState),
+    .vmsd = &vmstate_uhci,
+    .props = uhci_properties,
+    .class_init = ich9_uhci1_class_init,
 };
 
-static PCIDeviceInfo ich9_uhci2_info = {
-    .qdev.name    = "ich9-usb-uhci2",
-    .qdev.size    = sizeof(UHCIState),
-    .qdev.vmsd    = &vmstate_uhci,
-    .init         = usb_uhci_common_initfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI2,
-    .revision     = 0x03,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .qdev.props   = uhci_properties,
+static void ich9_uhci2_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_uhci_common_initfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI2;
+    k->revision = 0x03;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo ich9_uhci2_info = {
+    .name = "ich9-usb-uhci2",
+    .size = sizeof(UHCIState),
+    .vmsd = &vmstate_uhci,
+    .props = uhci_properties,
+    .class_init = ich9_uhci2_class_init,
 };
 
-static PCIDeviceInfo ich9_uhci3_info = {
-    .qdev.name    = "ich9-usb-uhci3",
-    .qdev.size    = sizeof(UHCIState),
-    .qdev.vmsd    = &vmstate_uhci,
-    .init         = usb_uhci_common_initfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI3,
-    .revision     = 0x03,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .qdev.props   = uhci_properties,
+static void ich9_uhci3_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_uhci_common_initfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI3;
+    k->revision = 0x03;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo ich9_uhci3_info = {
+    .name = "ich9-usb-uhci3",
+    .size = sizeof(UHCIState),
+    .vmsd = &vmstate_uhci,
+    .props = uhci_properties,
+    .class_init = ich9_uhci3_class_init,
 };
 
 static void uhci_register(void)
diff --git a/hw/usb-xhci.c b/hw/usb-xhci.c
index 95bf010..fba2de3 100644
--- a/hw/usb-xhci.c
+++ b/hw/usb-xhci.c
@@ -2724,19 +2724,26 @@ static const VMStateDescription vmstate_xhci = {
     .unmigratable = 1,
 };
 
-static PCIDeviceInfo xhci_info = {
-    .qdev.name    = "nec-usb-xhci",
-    .qdev.alias   = "xhci",
-    .qdev.size    = sizeof(XHCIState),
-    .qdev.vmsd    = &vmstate_xhci,
-    .init         = usb_xhci_initfn,
-    .vendor_id    = PCI_VENDOR_ID_NEC,
-    .device_id    = PCI_DEVICE_ID_NEC_UPD720200,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .revision     = 0x03,
-    .is_express   = 1,
-    .config_write = xhci_write_config,
-    .qdev.props   = (Property[]) {
+static void xhci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init         = usb_xhci_initfn;
+    k->vendor_id    = PCI_VENDOR_ID_NEC;
+    k->device_id    = PCI_DEVICE_ID_NEC_UPD720200;
+    k->class_id     = PCI_CLASS_SERIAL_USB;
+    k->revision     = 0x03;
+    k->is_express   = 1;
+    k->config_write = xhci_write_config;
+}
+
+static DeviceInfo xhci_info = {
+    .name    = "nec-usb-xhci",
+    .alias   = "xhci",
+    .size    = sizeof(XHCIState),
+    .vmsd    = &vmstate_xhci,
+    .class_init   = xhci_class_init,
+    .props   = (Property[]) {
         DEFINE_PROP_UINT32("msi", XHCIState, msi, 0),
         DEFINE_PROP_END_OF_LIST(),
     }
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index a285f7f..0eb7d32 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -109,14 +109,20 @@ static int versatile_pci_host_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo versatile_pci_host_info = {
-    .qdev.name = "versatile_pci_host",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = versatile_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_XILINX,
-    /* Both boards have the same device ID.  Oh well.  */
-    .device_id = PCI_DEVICE_ID_XILINX_XC2VP30,
-    .class_id  = PCI_CLASS_PROCESSOR_CO,
+static void versatile_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = versatile_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_XILINX;
+    k->device_id = PCI_DEVICE_ID_XILINX_XC2VP30;
+    k->class_id = PCI_CLASS_PROCESSOR_CO;
+}
+
+static DeviceInfo versatile_pci_host_info = {
+    .name = "versatile_pci_host",
+    .size = sizeof(PCIDevice),
+    .class_init = versatile_pci_host_class_init,
 };
 
 static void versatile_pci_register_devices(void)
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index a75dbf3..ef9f8a5 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -75,18 +75,23 @@ DeviceState *pci_vga_init(PCIBus *bus)
     return &pci_create_simple(bus, -1, "VGA")->qdev;
 }
 
-static PCIDeviceInfo vga_info = {
-    .qdev.name    = "VGA",
-    .qdev.size    = sizeof(PCIVGAState),
-    .qdev.vmsd    = &vmstate_vga_pci,
-    .no_hotplug   = 1,
-    .init         = pci_vga_initfn,
-    .romfile      = "vgabios-stdvga.bin",
+static void vga_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = pci_vga_initfn;
+    k->romfile = "vgabios-stdvga.bin";
+    k->vendor_id = PCI_VENDOR_ID_QEMU;
+    k->device_id = PCI_DEVICE_ID_QEMU_VGA;
+    k->class_id = PCI_CLASS_DISPLAY_VGA;
+}
 
-    /* dummy VGA (same as Bochs ID) */
-    .vendor_id    = PCI_VENDOR_ID_QEMU,
-    .device_id    = PCI_DEVICE_ID_QEMU_VGA,
-    .class_id     = PCI_CLASS_DISPLAY_VGA,
+static DeviceInfo vga_info = {
+    .name = "VGA",
+    .size = sizeof(PCIVGAState),
+    .vmsd = &vmstate_vga_pci,
+    .class_init = vga_class_init,
 };
 
 static void vga_register(void)
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 72b53af..126fb08 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -806,88 +806,124 @@ static int virtio_balloon_exit_pci(PCIDevice *pci_dev)
     return virtio_exit_pci(pci_dev);
 }
 
-static PCIDeviceInfo virtio_blk_info = {
-    .qdev.name = "virtio-blk-pci",
-    .qdev.alias = "virtio-blk",
-    .qdev.size = sizeof(VirtIOPCIProxy),
-    .init      = virtio_blk_init_pci,
-    .exit      = virtio_blk_exit_pci,
-    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
-    .device_id = PCI_DEVICE_ID_VIRTIO_BLOCK,
-    .revision  = VIRTIO_PCI_ABI_VERSION,
-    .class_id  = PCI_CLASS_STORAGE_SCSI,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
-        DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
-        DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial),
-        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
-        DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
-        DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
-        DEFINE_PROP_END_OF_LIST(),
-    },
-    .qdev.reset = virtio_pci_reset,
+static Property virtio_blk_properties[] = {
+    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
+    DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
+    DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial),
+    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
+    DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo virtio_net_info = {
-    .qdev.name  = "virtio-net-pci",
-    .qdev.alias = "virtio-net",
-    .qdev.size  = sizeof(VirtIOPCIProxy),
-    .init       = virtio_net_init_pci,
-    .exit       = virtio_net_exit_pci,
-    .romfile    = "pxe-virtio.rom",
-    .vendor_id  = PCI_VENDOR_ID_REDHAT_QUMRANET,
-    .device_id  = PCI_DEVICE_ID_VIRTIO_NET,
-    .revision   = VIRTIO_PCI_ABI_VERSION,
-    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
-        DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
-        DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
-        DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
-        DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy, net.txtimer, TX_TIMER_INTERVAL),
-        DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy, net.txburst, TX_BURST),
-        DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx),
-        DEFINE_PROP_END_OF_LIST(),
-    },
-    .qdev.reset = virtio_pci_reset,
+static void virtio_blk_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_blk_init_pci;
+    k->exit = virtio_blk_exit_pci;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = PCI_DEVICE_ID_VIRTIO_BLOCK;
+    k->revision = VIRTIO_PCI_ABI_VERSION;
+    k->class_id = PCI_CLASS_STORAGE_SCSI;
+}
+
+static DeviceInfo virtio_blk_info = {
+    .name = "virtio-blk-pci",
+    .alias = "virtio-blk",
+    .size = sizeof(VirtIOPCIProxy),
+    .props = virtio_blk_properties,
+    .reset = virtio_pci_reset,
+    .class_init = virtio_blk_class_init,
+};
+
+static Property virtio_net_properties[] = {
+    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
+    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
+    DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
+    DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
+    DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy, net.txtimer, TX_TIMER_INTERVAL),
+    DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy, net.txburst, TX_BURST),
+    DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_net_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_net_init_pci;
+    k->exit = virtio_net_exit_pci;
+    k->romfile = "pxe-virtio.rom";
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = PCI_DEVICE_ID_VIRTIO_NET;
+    k->revision = VIRTIO_PCI_ABI_VERSION;
+    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+}
+
+static DeviceInfo virtio_net_info = {
+    .name = "virtio-net-pci",
+    .alias = "virtio-net",
+    .size = sizeof(VirtIOPCIProxy),
+    .props = virtio_net_properties,
+    .reset = virtio_pci_reset,
+    .class_init = virtio_net_class_init,
 };
 
-static PCIDeviceInfo virtio_serial_info = {
-    .qdev.name = "virtio-serial-pci",
-    .qdev.alias = "virtio-serial",
-    .qdev.size = sizeof(VirtIOPCIProxy),
-    .init      = virtio_serial_init_pci,
-    .exit      = virtio_serial_exit_pci,
-    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
-    .device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE,
-    .revision  = VIRTIO_PCI_ABI_VERSION,
-    .class_id  = PCI_CLASS_COMMUNICATION_OTHER,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
-        DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, DEV_NVECTORS_UNSPECIFIED),
-        DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
-        DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-        DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, serial.max_virtserial_ports, 31),
-        DEFINE_PROP_END_OF_LIST(),
-    },
-    .qdev.reset = virtio_pci_reset,
+static Property virtio_serial_properties[] = {
+    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, DEV_NVECTORS_UNSPECIFIED),
+    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
+    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+    DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, serial.max_virtserial_ports, 31),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo virtio_balloon_info = {
-    .qdev.name = "virtio-balloon-pci",
-    .qdev.alias = "virtio-balloon",
-    .qdev.size = sizeof(VirtIOPCIProxy),
-    .init      = virtio_balloon_init_pci,
-    .exit      = virtio_balloon_exit_pci,
-    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
-    .device_id = PCI_DEVICE_ID_VIRTIO_BALLOON,
-    .revision  = VIRTIO_PCI_ABI_VERSION,
-    .class_id  = PCI_CLASS_MEMORY_RAM,
-    .qdev.props = (Property[]) {
-        DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-        DEFINE_PROP_END_OF_LIST(),
-    },
-    .qdev.reset = virtio_pci_reset,
+static void virtio_serial_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_serial_init_pci;
+    k->exit = virtio_serial_exit_pci;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE;
+    k->revision = VIRTIO_PCI_ABI_VERSION;
+    k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
+}
+
+static DeviceInfo virtio_serial_info = {
+    .name = "virtio-serial-pci",
+    .alias = "virtio-serial",
+    .size = sizeof(VirtIOPCIProxy),
+    .props = virtio_serial_properties,
+    .reset = virtio_pci_reset,
+    .class_init = virtio_serial_class_init,
+};
+
+static Property virtio_balloon_properties[] = {
+    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_balloon_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_balloon_init_pci;
+    k->exit = virtio_balloon_exit_pci;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = PCI_DEVICE_ID_VIRTIO_BALLOON;
+    k->revision = VIRTIO_PCI_ABI_VERSION;
+    k->class_id = PCI_CLASS_MEMORY_RAM;
+}
+
+static DeviceInfo virtio_balloon_info = {
+    .name = "virtio-balloon-pci",
+    .alias = "virtio-balloon",
+    .size = sizeof(VirtIOPCIProxy),
+    .props = virtio_balloon_properties,
+    .reset = virtio_pci_reset,
+    .class_init = virtio_balloon_class_init,
 };
 
 static void virtio_pci_register_devices(void)
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index b1885c3..e7bbf7c 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1199,20 +1199,26 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo vmsvga_info = {
-    .qdev.name    = "vmware-svga",
-    .qdev.size    = sizeof(struct pci_vmsvga_state_s),
-    .qdev.vmsd    = &vmstate_vmware_vga,
-    .qdev.reset   = vmsvga_reset,
-    .no_hotplug   = 1,
-    .init         = pci_vmsvga_initfn,
-    .romfile      = "vgabios-vmware.bin",
-
-    .vendor_id    =  PCI_VENDOR_ID_VMWARE,
-    .device_id    = SVGA_PCI_DEVICE_ID,
-    .class_id     = PCI_CLASS_DISPLAY_VGA,
-    .subsystem_vendor_id = PCI_VENDOR_ID_VMWARE,
-    .subsystem_id = SVGA_PCI_DEVICE_ID,
+static void vmsvga_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = pci_vmsvga_initfn;
+    k->romfile = "vgabios-vmware.bin";
+    k->vendor_id = PCI_VENDOR_ID_VMWARE;
+    k->device_id = SVGA_PCI_DEVICE_ID;
+    k->class_id = PCI_CLASS_DISPLAY_VGA;
+    k->subsystem_vendor_id = PCI_VENDOR_ID_VMWARE;
+    k->subsystem_id = SVGA_PCI_DEVICE_ID;
+}
+
+static DeviceInfo vmsvga_info = {
+    .name = "vmware-svga",
+    .size = sizeof(struct pci_vmsvga_state_s),
+    .vmsd = &vmstate_vmware_vga,
+    .reset = vmsvga_reset,
+    .class_init = vmsvga_class_init,
 };
 
 static void vmsvga_register(void)
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 7fb88a5..72be4fd 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -346,15 +346,22 @@ void vt82c686b_ac97_init(PCIBus *bus, int devfn)
     qdev_init_nofail(&dev->qdev);
 }
 
-static PCIDeviceInfo via_ac97_info = {
-    .qdev.name          = "VT82C686B_AC97",
-    .qdev.desc          = "AC97",
-    .qdev.size          = sizeof(VT686AC97State),
-    .init               = vt82c686b_ac97_initfn,
-    .vendor_id          = PCI_VENDOR_ID_VIA,
-    .device_id          = PCI_DEVICE_ID_VIA_AC97,
-    .revision           = 0x50,
-    .class_id           = PCI_CLASS_MULTIMEDIA_AUDIO,
+static void via_ac97_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = vt82c686b_ac97_initfn;
+    k->vendor_id = PCI_VENDOR_ID_VIA;
+    k->device_id = PCI_DEVICE_ID_VIA_AC97;
+    k->revision = 0x50;
+    k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+}
+
+static DeviceInfo via_ac97_info = {
+    .name = "VT82C686B_AC97",
+    .desc = "AC97",
+    .size = sizeof(VT686AC97State),
+    .class_init = via_ac97_class_init,
 };
 
 static void vt82c686b_ac97_register(void)
@@ -385,15 +392,22 @@ void vt82c686b_mc97_init(PCIBus *bus, int devfn)
     qdev_init_nofail(&dev->qdev);
 }
 
-static PCIDeviceInfo via_mc97_info = {
-    .qdev.name          = "VT82C686B_MC97",
-    .qdev.desc          = "MC97",
-    .qdev.size          = sizeof(VT686MC97State),
-    .init               = vt82c686b_mc97_initfn,
-    .vendor_id          = PCI_VENDOR_ID_VIA,
-    .device_id          = PCI_DEVICE_ID_VIA_MC97,
-    .class_id           = PCI_CLASS_COMMUNICATION_OTHER,
-    .revision           = 0x30,
+static void via_mc97_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = vt82c686b_mc97_initfn;
+    k->vendor_id = PCI_VENDOR_ID_VIA;
+    k->device_id = PCI_DEVICE_ID_VIA_MC97;
+    k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
+    k->revision = 0x30;
+}
+
+static DeviceInfo via_mc97_info = {
+    .name = "VT82C686B_MC97",
+    .desc = "MC97",
+    .size = sizeof(VT686MC97State),
+    .class_init = via_mc97_class_init,
 };
 
 static void vt82c686b_mc97_register(void)
@@ -451,21 +465,30 @@ i2c_bus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
     return s->smb.smbus;
 }
 
-static PCIDeviceInfo via_pm_info = {
-    .qdev.name          = "VT82C686B_PM",
-    .qdev.desc          = "PM",
-    .qdev.size          = sizeof(VT686PMState),
-    .qdev.vmsd          = &vmstate_acpi,
-    .init               = vt82c686b_pm_initfn,
-    .config_write       = pm_write_config,
-    .vendor_id          = PCI_VENDOR_ID_VIA,
-    .device_id          = PCI_DEVICE_ID_VIA_ACPI,
-    .class_id           = PCI_CLASS_BRIDGE_OTHER,
-    .revision           = 0x40,
-    .qdev.props         = (Property[]) {
-        DEFINE_PROP_UINT32("smb_io_base", VT686PMState, smb_io_base, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property via_pm_properties[] = {
+    DEFINE_PROP_UINT32("smb_io_base", VT686PMState, smb_io_base, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void via_pm_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = vt82c686b_pm_initfn;
+    k->config_write = pm_write_config;
+    k->vendor_id = PCI_VENDOR_ID_VIA;
+    k->device_id = PCI_DEVICE_ID_VIA_ACPI;
+    k->class_id = PCI_CLASS_BRIDGE_OTHER;
+    k->revision = 0x40;
+}
+
+static DeviceInfo via_pm_info = {
+    .name = "VT82C686B_PM",
+    .desc = "PM",
+    .size = sizeof(VT686PMState),
+    .vmsd = &vmstate_acpi,
+    .props = via_pm_properties,
+    .class_init = via_pm_class_init,
 };
 
 static void vt82c686b_pm_register(void)
@@ -519,18 +542,25 @@ ISABus *vt82c686b_init(PCIBus *bus, int devfn)
     return DO_UPCAST(ISABus, qbus, qdev_get_child_bus(&d->qdev, "isa.0"));
 }
 
-static PCIDeviceInfo via_info = {
-    .qdev.name    = "VT82C686B",
-    .qdev.desc    = "ISA bridge",
-    .qdev.size    = sizeof(VT82C686BState),
-    .qdev.vmsd    = &vmstate_via,
-    .qdev.no_user = 1,
-    .init         = vt82c686b_initfn,
-    .config_write = vt82c686b_write_config,
-    .vendor_id    = PCI_VENDOR_ID_VIA,
-    .device_id    = PCI_DEVICE_ID_VIA_ISA_BRIDGE,
-    .class_id     = PCI_CLASS_BRIDGE_ISA,
-    .revision     = 0x40,
+static void via_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = vt82c686b_initfn;
+    k->config_write = vt82c686b_write_config;
+    k->vendor_id = PCI_VENDOR_ID_VIA;
+    k->device_id = PCI_DEVICE_ID_VIA_ISA_BRIDGE;
+    k->class_id = PCI_CLASS_BRIDGE_ISA;
+    k->revision = 0x40;
+}
+
+static DeviceInfo via_info = {
+    .name = "VT82C686B",
+    .desc = "ISA bridge",
+    .size = sizeof(VT82C686BState),
+    .vmsd = &vmstate_via,
+    .no_user = 1,
+    .class_init = via_class_init,
 };
 
 static void vt82c686b_register(void)
diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c
index 20d8673..a6ceff8 100644
--- a/hw/wdt_i6300esb.c
+++ b/hw/wdt_i6300esb.c
@@ -143,7 +143,7 @@ static void i6300esb_disable_timer(I6300State *d)
 
 static void i6300esb_reset(DeviceState *dev)
 {
-    PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, dev);
+    PCIDevice *pdev = PCI_DEVICE(dev);
     I6300State *d = DO_UPCAST(I6300State, dev, pdev);
 
     i6300esb_debug("I6300State = %p\n", d);
@@ -425,18 +425,25 @@ static WatchdogTimerModel model = {
     .wdt_description = "Intel 6300ESB",
 };
 
-static PCIDeviceInfo i6300esb_info = {
-    .qdev.name    = "i6300esb",
-    .qdev.size    = sizeof(I6300State),
-    .qdev.vmsd    = &vmstate_i6300esb,
-    .qdev.reset   = i6300esb_reset,
-    .config_read  = i6300esb_config_read,
-    .config_write = i6300esb_config_write,
-    .init         = i6300esb_init,
-    .exit         = i6300esb_exit,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_ESB_9,
-    .class_id     = PCI_CLASS_SYSTEM_OTHER,
+static void i6300esb_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->config_read = i6300esb_config_read;
+    k->config_write = i6300esb_config_write;
+    k->init = i6300esb_init;
+    k->exit = i6300esb_exit;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_ESB_9;
+    k->class_id = PCI_CLASS_SYSTEM_OTHER;
+}
+
+static DeviceInfo i6300esb_info = {
+    .name = "i6300esb",
+    .size = sizeof(I6300State),
+    .vmsd = &vmstate_i6300esb,
+    .reset = i6300esb_reset,
+    .class_init = i6300esb_class_init,
 };
 
 static void i6300esb_register_devices(void)
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index e62eaef..40687fb 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -372,20 +372,26 @@ static void platform_reset(DeviceState *dev)
     platform_fixed_ioport_reset(s);
 }
 
-static PCIDeviceInfo xen_platform_info = {
-    .init = xen_platform_initfn,
-    .qdev.name = "xen-platform",
-    .qdev.desc = "XEN platform pci device",
-    .qdev.size = sizeof(PCIXenPlatformState),
-    .qdev.vmsd = &vmstate_xen_platform,
-    .qdev.reset = platform_reset,
-
-    .vendor_id    =  PCI_VENDOR_ID_XEN,
-    .device_id    = PCI_DEVICE_ID_XEN_PLATFORM,
-    .class_id     = PCI_CLASS_OTHERS << 8 | 0x80,
-    .subsystem_vendor_id = PCI_VENDOR_ID_XEN,
-    .subsystem_id = PCI_DEVICE_ID_XEN_PLATFORM,
-    .revision = 1,
+static void xen_platform_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = xen_platform_initfn;
+    k->vendor_id = PCI_VENDOR_ID_XEN;
+    k->device_id = PCI_DEVICE_ID_XEN_PLATFORM;
+    k->class_id = PCI_CLASS_OTHERS << 8 | 0x80;
+    k->subsystem_vendor_id = PCI_VENDOR_ID_XEN;
+    k->subsystem_id = PCI_DEVICE_ID_XEN_PLATFORM;
+    k->revision = 1;
+}
+
+static DeviceInfo xen_platform_info = {
+    .name = "xen-platform",
+    .desc = "XEN platform pci device",
+    .size = sizeof(PCIXenPlatformState),
+    .vmsd = &vmstate_xen_platform,
+    .reset = platform_reset,
+    .class_init = xen_platform_class_init,
 };
 
 static void xen_platform_register(void)
diff --git a/hw/xio3130_downstream.c b/hw/xio3130_downstream.c
index d3c387d..6d625cb 100644
--- a/hw/xio3130_downstream.c
+++ b/hw/xio3130_downstream.c
@@ -47,7 +47,7 @@ static void xio3130_downstream_write_config(PCIDevice *d, uint32_t address,
 
 static void xio3130_downstream_reset(DeviceState *qdev)
 {
-    PCIDevice *d = DO_UPCAST(PCIDevice, qdev, qdev);
+    PCIDevice *d = PCI_DEVICE(qdev);
     msi_reset(d);
     pcie_cap_deverr_reset(d);
     pcie_cap_slot_reset(d);
@@ -167,31 +167,38 @@ static const VMStateDescription vmstate_xio3130_downstream = {
     }
 };
 
-static PCIDeviceInfo xio3130_downstream_info = {
-    .qdev.name = "xio3130-downstream",
-    .qdev.desc = "TI X3130 Downstream Port of PCI Express Switch",
-    .qdev.size = sizeof(PCIESlot),
-    .qdev.reset = xio3130_downstream_reset,
-    .qdev.vmsd = &vmstate_xio3130_downstream,
-
-    .is_express = 1,
-    .is_bridge = 1,
-    .config_write = xio3130_downstream_write_config,
-    .init = xio3130_downstream_initfn,
-    .exit = xio3130_downstream_exitfn,
-    .vendor_id = PCI_VENDOR_ID_TI,
-    .device_id = PCI_DEVICE_ID_TI_XIO3130D,
-    .revision = XIO3130_REVISION,
-
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT8("port", PCIESlot, port.port, 0),
-        DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
-        DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
-        DEFINE_PROP_UINT16("aer_log_max", PCIESlot,
-                           port.br.dev.exp.aer_log.log_max,
-                           PCIE_AER_LOG_MAX_DEFAULT),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property xio3130_downstream_properties[] = {
+    DEFINE_PROP_UINT8("port", PCIESlot, port.port, 0),
+    DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
+    DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
+    DEFINE_PROP_UINT16("aer_log_max", PCIESlot,
+    port.br.dev.exp.aer_log.log_max,
+    PCIE_AER_LOG_MAX_DEFAULT),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void xio3130_downstream_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->is_express = 1;
+    k->is_bridge = 1;
+    k->config_write = xio3130_downstream_write_config;
+    k->init = xio3130_downstream_initfn;
+    k->exit = xio3130_downstream_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_TI;
+    k->device_id = PCI_DEVICE_ID_TI_XIO3130D;
+    k->revision = XIO3130_REVISION;
+}
+
+static DeviceInfo xio3130_downstream_info = {
+    .name = "xio3130-downstream",
+    .desc = "TI X3130 Downstream Port of PCI Express Switch",
+    .size = sizeof(PCIESlot),
+    .reset = xio3130_downstream_reset,
+    .vmsd = &vmstate_xio3130_downstream,
+    .props = xio3130_downstream_properties,
+    .class_init = xio3130_downstream_class_init,
 };
 
 static void xio3130_downstream_register(void)
diff --git a/hw/xio3130_upstream.c b/hw/xio3130_upstream.c
index 8283695..ec4c5e3 100644
--- a/hw/xio3130_upstream.c
+++ b/hw/xio3130_upstream.c
@@ -46,7 +46,7 @@ static void xio3130_upstream_write_config(PCIDevice *d, uint32_t address,
 
 static void xio3130_upstream_reset(DeviceState *qdev)
 {
-    PCIDevice *d = DO_UPCAST(PCIDevice, qdev, qdev);
+    PCIDevice *d = PCI_DEVICE(qdev);
     msi_reset(d);
     pci_bridge_reset(qdev);
     pcie_cap_deverr_reset(d);
@@ -144,28 +144,35 @@ static const VMStateDescription vmstate_xio3130_upstream = {
     }
 };
 
-static PCIDeviceInfo xio3130_upstream_info = {
-    .qdev.name = "x3130-upstream",
-    .qdev.desc = "TI X3130 Upstream Port of PCI Express Switch",
-    .qdev.size = sizeof(PCIEPort),
-    .qdev.reset = xio3130_upstream_reset,
-    .qdev.vmsd = &vmstate_xio3130_upstream,
-
-    .is_express = 1,
-    .is_bridge = 1,
-    .config_write = xio3130_upstream_write_config,
-    .init = xio3130_upstream_initfn,
-    .exit = xio3130_upstream_exitfn,
-    .vendor_id = PCI_VENDOR_ID_TI,
-    .device_id = PCI_DEVICE_ID_TI_XIO3130U,
-    .revision = XIO3130_REVISION,
-
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT8("port", PCIEPort, port, 0),
-        DEFINE_PROP_UINT16("aer_log_max", PCIEPort, br.dev.exp.aer_log.log_max,
-                           PCIE_AER_LOG_MAX_DEFAULT),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property xio3130_upstream_properties[] = {
+    DEFINE_PROP_UINT8("port", PCIEPort, port, 0),
+    DEFINE_PROP_UINT16("aer_log_max", PCIEPort, br.dev.exp.aer_log.log_max,
+    PCIE_AER_LOG_MAX_DEFAULT),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void xio3130_upstream_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->is_express = 1;
+    k->is_bridge = 1;
+    k->config_write = xio3130_upstream_write_config;
+    k->init = xio3130_upstream_initfn;
+    k->exit = xio3130_upstream_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_TI;
+    k->device_id = PCI_DEVICE_ID_TI_XIO3130U;
+    k->revision = XIO3130_REVISION;
+}
+
+static DeviceInfo xio3130_upstream_info = {
+    .name = "x3130-upstream",
+    .desc = "TI X3130 Upstream Port of PCI Express Switch",
+    .size = sizeof(PCIEPort),
+    .reset = xio3130_upstream_reset,
+    .vmsd = &vmstate_xio3130_upstream,
+    .props = xio3130_upstream_properties,
+    .class_init = xio3130_upstream_class_init,
 };
 
 static void xio3130_upstream_register(void)
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [PATCH 26/28] pci: convert to QEMU Object Model
@ 2012-01-24 19:33   ` Anthony Liguori
  0 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Anthony Liguori, xen-devel, Michael S. Tsirkin,
	Stefano Stabellini, Alexander Graf, Blue Swirl,
	Andreas Färber, qemu-ppc, Paul Brook, Gerd Hoffmann

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/9pfs/virtio-9p-device.c |   43 ++++++----
 hw/ac97.c                  |   39 +++++----
 hw/acpi_piix4.c            |   59 +++++++------
 hw/apb_pci.c               |   54 ++++++++-----
 hw/bonito.c                |   30 ++++---
 hw/cirrus_vga.c            |   33 +++++---
 hw/dec_pci.c               |   57 ++++++++-----
 hw/e1000.c                 |   43 ++++++----
 hw/eepro100.c              |  200 +++++++++++++++++++++++++++----------------
 hw/es1370.c                |   31 ++++---
 hw/grackle_pci.c           |   25 ++++--
 hw/gt64xxx.c               |   23 ++++--
 hw/i82378.c                |   31 ++++---
 hw/ide/cmd646.c            |   36 +++++---
 hw/ide/ich.c               |   31 ++++---
 hw/ide/piix.c              |   79 +++++++++++-------
 hw/ide/via.c               |   27 ++++--
 hw/intel-hda.c             |   56 ++++++++----
 hw/ioh3420.c               |   59 +++++++------
 hw/ivshmem.c               |   47 ++++++----
 hw/lsi53c895a.c            |   31 ++++---
 hw/macio.c                 |   19 +++--
 hw/ne2000.c                |   35 +++++---
 hw/pci.c                   |  123 ++++++++++++---------------
 hw/pci.h                   |   80 +++++++++---------
 hw/pci_bridge.c            |    2 +-
 hw/pcie.c                  |    2 +-
 hw/pcnet-pci.c             |   39 +++++----
 hw/piix4.c                 |   30 ++++---
 hw/piix_pci.c              |   95 +++++++++++++--------
 hw/ppc4xx_pci.c            |   21 +++--
 hw/ppce500_pci.c           |   21 +++--
 hw/prep_pci.c              |   33 ++++----
 hw/qdev.c                  |    1 +
 hw/qxl.c                   |   62 ++++++++-----
 hw/rtl8139.c               |   41 ++++++----
 hw/sh_pci.c                |   19 +++--
 hw/spapr_pci.c             |   15 +++-
 hw/sun4u.c                 |   23 ++++--
 hw/unin_pci.c              |   92 +++++++++++++-------
 hw/usb-ehci.c              |   54 ++++++++-----
 hw/usb-ohci.c              |   37 +++++---
 hw/usb-uhci.c              |  168 +++++++++++++++++++++++--------------
 hw/usb-xhci.c              |   33 +++++---
 hw/versatile_pci.c         |   22 +++--
 hw/vga-pci.c               |   27 ++++---
 hw/virtio-pci.c            |  188 ++++++++++++++++++++++++-----------------
 hw/vmware_vga.c            |   34 +++++---
 hw/vt82c686.c              |  120 ++++++++++++++++----------
 hw/wdt_i6300esb.c          |   33 +++++---
 hw/xen_platform.c          |   34 +++++---
 hw/xio3130_downstream.c    |   59 +++++++------
 hw/xio3130_upstream.c      |   53 +++++++-----
 53 files changed, 1599 insertions(+), 1050 deletions(-)

diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 1325f2f..aded048 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -163,23 +163,32 @@ static int virtio_9p_init_pci(PCIDevice *pci_dev)
     return 0;
 }
 
-static PCIDeviceInfo virtio_9p_info = {
-    .qdev.name = "virtio-9p-pci",
-    .qdev.size = sizeof(VirtIOPCIProxy),
-    .init      = virtio_9p_init_pci,
-    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
-    .device_id = 0x1009,
-    .revision  = VIRTIO_PCI_ABI_VERSION,
-    .class_id  = 0x2,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
-        DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
-        DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-        DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
-        DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id),
-        DEFINE_PROP_END_OF_LIST(),
-    },
-    .qdev.reset = virtio_pci_reset,
+static Property virtio_9p_properties[] = {
+    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
+    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+    DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
+    DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_9p_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_9p_init_pci;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = 0x1009;
+    k->revision = VIRTIO_PCI_ABI_VERSION;
+    k->class_id = 0x2;
+}
+
+static DeviceInfo virtio_9p_info = {
+    .name = "virtio-9p-pci",
+    .size = sizeof(VirtIOPCIProxy),
+    .props = virtio_9p_properties,
+    .class_init = virtio_9p_class_init,
+    .reset = virtio_pci_reset,
 };
 
 static void virtio_9p_register_devices(void)
diff --git a/hw/ac97.c b/hw/ac97.c
index 03be99b..33b85f5 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -1344,21 +1344,30 @@ int ac97_init (PCIBus *bus)
     return 0;
 }
 
-static PCIDeviceInfo ac97_info = {
-    .qdev.name    = "AC97",
-    .qdev.desc    = "Intel 82801AA AC97 Audio",
-    .qdev.size    = sizeof (AC97LinkState),
-    .qdev.vmsd    = &vmstate_ac97,
-    .init         = ac97_initfn,
-    .exit         = ac97_exitfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82801AA_5,
-    .revision     = 0x01,
-    .class_id     = PCI_CLASS_MULTIMEDIA_AUDIO,
-    .qdev.props   = (Property[]) {
-        DEFINE_PROP_UINT32("use_broken_id", AC97LinkState, use_broken_id, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property ac97_properties[] = {
+    DEFINE_PROP_UINT32("use_broken_id", AC97LinkState, use_broken_id, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ac97_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = ac97_initfn;
+    k->exit = ac97_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
+    k->revision = 0x01;
+    k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+}
+
+static DeviceInfo ac97_info = {
+    .name = "AC97",
+    .desc = "Intel 82801AA AC97 Audio",
+    .size = sizeof (AC97LinkState),
+    .vmsd = &vmstate_ac97,
+    .props = ac97_properties,
+    .class_init = ac97_class_init,
 };
 
 static void ac97_register (void)
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 4d0b390..9058a7c 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -280,11 +280,11 @@ static void piix4_update_hotplug(PIIX4PMState *s)
     s->pci0_hotplug_enable = ~0;
 
     QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
-        PCIDeviceInfo *info = container_of(qdev_get_info(qdev), PCIDeviceInfo, qdev);
-        PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, qdev);
+        PCIDevice *pdev = PCI_DEVICE(qdev);
+        PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pdev);
         int slot = PCI_SLOT(pdev->devfn);
 
-        if (info->no_hotplug) {
+        if (pc->no_hotplug) {
             s->pci0_hotplug_enable &= ~(1 << slot);
         }
     }
@@ -396,23 +396,32 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
     return s->smb.smbus;
 }
 
-static PCIDeviceInfo piix4_pm_info = {
-    .qdev.name          = "PIIX4_PM",
-    .qdev.desc          = "PM",
-    .qdev.size          = sizeof(PIIX4PMState),
-    .qdev.vmsd          = &vmstate_acpi,
-    .qdev.no_user       = 1,
-    .no_hotplug         = 1,
-    .init               = piix4_pm_initfn,
-    .config_write       = pm_write_config,
-    .vendor_id          = PCI_VENDOR_ID_INTEL,
-    .device_id          = PCI_DEVICE_ID_INTEL_82371AB_3,
-    .revision           = 0x03,
-    .class_id           = PCI_CLASS_BRIDGE_OTHER,
-    .qdev.props         = (Property[]) {
-        DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property piix4_pm_properties[] = {
+    DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void piix4_pm_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = piix4_pm_initfn;
+    k->config_write = pm_write_config;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82371AB_3;
+    k->revision = 0x03;
+    k->class_id = PCI_CLASS_BRIDGE_OTHER;
+}
+
+static DeviceInfo piix4_pm_info = {
+    .name = "PIIX4_PM",
+    .desc = "PM",
+    .size = sizeof(PIIX4PMState),
+    .vmsd = &vmstate_acpi,
+    .no_user = 1,
+    .props = piix4_pm_properties,
+    .class_init = piix4_pm_class_init,
 };
 
 static void piix4_pm_register(void)
@@ -485,14 +494,12 @@ static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
 {
     BusState *bus = opaque;
     DeviceState *qdev, *next;
-    PCIDevice *dev;
-    PCIDeviceInfo *info;
     int slot = ffs(val) - 1;
 
     QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
-        dev = DO_UPCAST(PCIDevice, qdev, qdev);
-        info = container_of(qdev_get_info(qdev), PCIDeviceInfo, qdev);
-        if (PCI_SLOT(dev->devfn) == slot && !info->no_hotplug) {
+        PCIDevice *dev = PCI_DEVICE(qdev);
+        PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
+        if (PCI_SLOT(dev->devfn) == slot && !pc->no_hotplug) {
             qdev_free(qdev);
         }
     }
@@ -553,7 +560,7 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
 {
     int slot = PCI_SLOT(dev->devfn);
     PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev,
-                                DO_UPCAST(PCIDevice, qdev, qdev));
+                                PCI_DEVICE(qdev));
 
     /* Don't send event when device is enabled during qemu machine creation:
      * it is present on boot, no hotplug event is necessary. We do send an
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 3a1b111..70cfc77 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -436,14 +436,21 @@ static int pbm_pci_host_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo pbm_pci_host_info = {
-    .qdev.name = "pbm",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = pbm_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_SUN,
-    .device_id = PCI_DEVICE_ID_SUN_SABRE,
-    .class_id  = PCI_CLASS_BRIDGE_HOST,
-    .is_bridge = 1,
+static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pbm_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_SUN;
+    k->device_id = PCI_DEVICE_ID_SUN_SABRE;
+    k->class_id = PCI_CLASS_BRIDGE_HOST;
+    k->is_bridge = 1;
+}
+
+static DeviceInfo pbm_pci_host_info = {
+    .name = "pbm",
+    .size = sizeof(PCIDevice),
+    .class_init = pbm_pci_host_class_init,
 };
 
 static SysBusDeviceInfo pbm_host_info = {
@@ -453,18 +460,25 @@ static SysBusDeviceInfo pbm_host_info = {
     .init = pci_pbm_init_device,
 };
 
-static PCIDeviceInfo pbm_pci_bridge_info = {
-    .qdev.name = "pbm-bridge",
-    .qdev.size = sizeof(PCIBridge),
-    .qdev.vmsd = &vmstate_pci_device,
-    .qdev.reset = pci_bridge_reset,
-    .init = apb_pci_bridge_initfn,
-    .exit = pci_bridge_exitfn,
-    .vendor_id = PCI_VENDOR_ID_SUN,
-    .device_id = PCI_DEVICE_ID_SUN_SIMBA,
-    .revision = 0x11,
-    .config_write = pci_bridge_write_config,
-    .is_bridge = 1,
+static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = apb_pci_bridge_initfn;
+    k->exit = pci_bridge_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_SUN;
+    k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
+    k->revision = 0x11;
+    k->config_write = pci_bridge_write_config;
+    k->is_bridge = 1;
+}
+
+static DeviceInfo pbm_pci_bridge_info = {
+    .name = "pbm-bridge",
+    .size = sizeof(PCIBridge),
+    .vmsd = &vmstate_pci_device,
+    .reset = pci_bridge_reset,
+    .class_init = pbm_pci_bridge_class_init,
 };
 
 static void pbm_register_devices(void)
diff --git a/hw/bonito.c b/hw/bonito.c
index f2c7837..23384ec 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -766,18 +766,24 @@ PCIBus *bonito_init(qemu_irq *pic)
     return b;
 }
 
-static PCIDeviceInfo bonito_info = {
-    .qdev.name    = "Bonito",
-    .qdev.desc    = "Host bridge",
-    .qdev.size    = sizeof(PCIBonitoState),
-    .qdev.vmsd    = &vmstate_bonito,
-    .qdev.no_user = 1,
-    .init         = bonito_initfn,
-    /*Bonito North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined"*/
-    .vendor_id    = 0xdf53,
-    .device_id    = 0x00d5,
-    .revision     = 0x01,
-    .class_id     = PCI_CLASS_BRIDGE_HOST,
+static void bonito_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = bonito_initfn;
+    k->vendor_id = 0xdf53;
+    k->device_id = 0x00d5;
+    k->revision = 0x01;
+    k->class_id = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo bonito_info = {
+    .name = "Bonito",
+    .desc = "Host bridge",
+    .size = sizeof(PCIBonitoState),
+    .vmsd = &vmstate_bonito,
+    .no_user = 1,
+    .class_init = bonito_class_init,
 };
 
 static SysBusDeviceInfo bonito_pcihost_info = {
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 1d0aadf..3fac2ee 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2935,8 +2935,8 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
 {
      PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
      CirrusVGAState *s = &d->cirrus_vga;
-     PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, qdev_get_info(&dev->qdev));
-     int16_t device_id = info->device_id;
+     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
+     int16_t device_id = pc->device_id;
 
      /* setup VGA */
      vga_common_init(&s->vga, VGA_RAM_SIZE);
@@ -2970,17 +2970,24 @@ DeviceState *pci_cirrus_vga_init(PCIBus *bus)
     return &pci_create_simple(bus, -1, "cirrus-vga")->qdev;
 }
 
-static PCIDeviceInfo cirrus_vga_info = {
-    .qdev.name    = "cirrus-vga",
-    .qdev.desc    = "Cirrus CLGD 54xx VGA",
-    .qdev.size    = sizeof(PCICirrusVGAState),
-    .qdev.vmsd    = &vmstate_pci_cirrus_vga,
-    .no_hotplug   = 1,
-    .init         = pci_cirrus_vga_initfn,
-    .romfile      = VGABIOS_CIRRUS_FILENAME,
-    .vendor_id    = PCI_VENDOR_ID_CIRRUS,
-    .device_id    = CIRRUS_ID_CLGD5446,
-    .class_id     = PCI_CLASS_DISPLAY_VGA,
+static void cirrus_vga_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = pci_cirrus_vga_initfn;
+    k->romfile = VGABIOS_CIRRUS_FILENAME;
+    k->vendor_id = PCI_VENDOR_ID_CIRRUS;
+    k->device_id = CIRRUS_ID_CLGD5446;
+    k->class_id = PCI_CLASS_DISPLAY_VGA;
+}
+
+static DeviceInfo cirrus_vga_info = {
+    .name = "cirrus-vga",
+    .desc = "Cirrus CLGD 54xx VGA",
+    .size = sizeof(PCICirrusVGAState),
+    .vmsd = &vmstate_pci_cirrus_vga,
+    .class_init = cirrus_vga_class_init,
 };
 
 static void cirrus_vga_register(void)
diff --git a/hw/dec_pci.c b/hw/dec_pci.c
index 08d4e06..7c3f50e 100644
--- a/hw/dec_pci.c
+++ b/hw/dec_pci.c
@@ -50,18 +50,25 @@ static int dec_map_irq(PCIDevice *pci_dev, int irq_num)
     return irq_num;
 }
 
-static PCIDeviceInfo dec_21154_pci_bridge_info = {
-    .qdev.name = "dec-21154-p2p-bridge",
-    .qdev.desc = "DEC 21154 PCI-PCI bridge",
-    .qdev.size = sizeof(PCIBridge),
-    .qdev.vmsd = &vmstate_pci_device,
-    .qdev.reset = pci_bridge_reset,
-    .init = pci_bridge_initfn,
-    .exit = pci_bridge_exitfn,
-    .vendor_id = PCI_VENDOR_ID_DEC,
-    .device_id = PCI_DEVICE_ID_DEC_21154,
-    .config_write = pci_bridge_write_config,
-    .is_bridge = 1,
+static void dec_21154_pci_bridge_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_bridge_initfn;
+    k->exit = pci_bridge_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_DEC;
+    k->device_id = PCI_DEVICE_ID_DEC_21154;
+    k->config_write = pci_bridge_write_config;
+    k->is_bridge = 1;
+}
+
+static DeviceInfo dec_21154_pci_bridge_info = {
+    .name = "dec-21154-p2p-bridge",
+    .desc = "DEC 21154 PCI-PCI bridge",
+    .size = sizeof(PCIBridge),
+    .vmsd = &vmstate_pci_device,
+    .reset = pci_bridge_reset,
+    .class_init = dec_21154_pci_bridge_class_init,
 };
 
 PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
@@ -98,21 +105,29 @@ static int dec_21154_pci_host_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo dec_21154_pci_host_info = {
-    .qdev.name = "dec-21154",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = dec_21154_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_DEC,
-    .device_id = PCI_DEVICE_ID_DEC_21154,
-    .revision = 0x02,
-    .class_id = PCI_CLASS_BRIDGE_PCI,
-    .is_bridge  = 1,
+static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = dec_21154_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_DEC;
+    k->device_id = PCI_DEVICE_ID_DEC_21154;
+    k->revision = 0x02;
+    k->class_id = PCI_CLASS_BRIDGE_PCI;
+    k->is_bridge = 1;
+}
+
+static DeviceInfo dec_21154_pci_host_info = {
+    .name = "dec-21154",
+    .size = sizeof(PCIDevice),
+    .class_init = dec_21154_pci_host_class_init,
 };
 
 static void dec_register_devices(void)
 {
     sysbus_register_dev("dec-21154", sizeof(DECState),
                         pci_dec_21154_init_device);
+
     pci_qdev_register(&dec_21154_pci_host_info);
     pci_qdev_register(&dec_21154_pci_bridge_info);
 }
diff --git a/hw/e1000.c b/hw/e1000.c
index 6bab54e..c5d3ecb 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1192,23 +1192,32 @@ static void qdev_e1000_reset(DeviceState *dev)
     e1000_reset(d);
 }
 
-static PCIDeviceInfo e1000_info = {
-    .qdev.name  = "e1000",
-    .qdev.desc  = "Intel Gigabit Ethernet",
-    .qdev.size  = sizeof(E1000State),
-    .qdev.reset = qdev_e1000_reset,
-    .qdev.vmsd  = &vmstate_e1000,
-    .init       = pci_e1000_init,
-    .exit       = pci_e1000_uninit,
-    .romfile    = "pxe-e1000.rom",
-    .vendor_id  = PCI_VENDOR_ID_INTEL,
-    .device_id  = E1000_DEVID,
-    .revision   = 0x03,
-    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(E1000State, conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property e1000_properties[] = {
+    DEFINE_NIC_PROPERTIES(E1000State, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void e1000_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_e1000_init;
+    k->exit = pci_e1000_uninit;
+    k->romfile = "pxe-e1000.rom";
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = E1000_DEVID;
+    k->revision = 0x03;
+    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+}
+
+static DeviceInfo e1000_info = {
+    .name = "e1000",
+    .desc = "Intel Gigabit Ethernet",
+    .size = sizeof(E1000State),
+    .reset = qdev_e1000_reset,
+    .vmsd = &vmstate_e1000,
+    .props = e1000_properties,
+    .class_init = e1000_class_init,
 };
 
 static void e1000_register_devices(void)
diff --git a/hw/eepro100.c b/hw/eepro100.c
index f0059c6..9f6d333 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -128,7 +128,13 @@
 #define DRVR_INT        0x0200  /* Driver generated interrupt. */
 
 typedef struct {
-    PCIDeviceInfo pci;
+    DeviceInfo qdev;
+
+    uint16_t device_id;
+    uint8_t revision;
+    uint16_t subsystem_vendor_id;
+    uint16_t subsystem_id;
+
     uint32_t device;
     uint8_t stats_size;
     bool has_extended_tcb_support;
@@ -318,6 +324,8 @@ static const uint16_t eepro100_mdi_mask[] = {
 
 #define POLYNOMIAL 0x04c11db6
 
+static E100PCIDeviceInfo *eepro100_get_class(EEPRO100State *s);
+
 /* From FreeBSD */
 /* XXX: optimize */
 static unsigned compute_mcast_idx(const uint8_t * ep)
@@ -487,8 +495,9 @@ static void eepro100_fcp_interrupt(EEPRO100State * s)
 }
 #endif
 
-static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
+static void e100_pci_reset(EEPRO100State * s)
 {
+    E100PCIDeviceInfo *info = eepro100_get_class(s);
     uint32_t device = s->device;
     uint8_t *pci_conf = s->dev.config;
 
@@ -508,8 +517,8 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
     /* Maximum Latency */
     pci_set_byte(pci_conf + PCI_MAX_LAT, 0x18);
 
-    s->stats_size = e100_device->stats_size;
-    s->has_extended_tcb_support = e100_device->has_extended_tcb_support;
+    s->stats_size = info->stats_size;
+    s->has_extended_tcb_support = info->has_extended_tcb_support;
 
     switch (device) {
     case i82550:
@@ -558,7 +567,7 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
     }
     assert(s->stats_size > 0 && s->stats_size <= sizeof(s->statistics));
 
-    if (e100_device->power_management) {
+    if (info->power_management) {
         /* Power Management Capabilities */
         int cfg_offset = 0xdc;
         int r = pci_add_capability(&s->dev, PCI_CAP_ID_PM,
@@ -1847,14 +1856,13 @@ static NetClientInfo net_eepro100_info = {
 static int e100_nic_init(PCIDevice *pci_dev)
 {
     EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
-    E100PCIDeviceInfo *e100_device = DO_UPCAST(E100PCIDeviceInfo, pci.qdev,
-                                               qdev_get_info(&pci_dev->qdev));
+    E100PCIDeviceInfo *info = eepro100_get_class(s);
 
     TRACE(OTHER, logout("\n"));
 
-    s->device = e100_device->device;
+    s->device = info->device;
 
-    e100_pci_reset(s, e100_device);
+    e100_pci_reset(s);
 
     /* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM,
      * i82559 and later support 64 or 256 word EEPROM. */
@@ -1897,136 +1905,182 @@ static int e100_nic_init(PCIDevice *pci_dev)
 
 static E100PCIDeviceInfo e100_devices[] = {
     {
-        .pci.qdev.name = "i82550",
-        .pci.qdev.desc = "Intel i82550 Ethernet",
+        .qdev.name = "i82550",
+        .qdev.desc = "Intel i82550 Ethernet",
         .device = i82550,
         /* TODO: check device id. */
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
         /* Revision ID: 0x0c, 0x0d, 0x0e. */
-        .pci.revision = 0x0e,
+        .revision = 0x0e,
         /* TODO: check size of statistical counters. */
         .stats_size = 80,
         /* TODO: check extended tcb support. */
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82551",
-        .pci.qdev.desc = "Intel i82551 Ethernet",
+        .qdev.name = "i82551",
+        .qdev.desc = "Intel i82551 Ethernet",
         .device = i82551,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
         /* Revision ID: 0x0f, 0x10. */
-        .pci.revision = 0x0f,
+        .revision = 0x0f,
         /* TODO: check size of statistical counters. */
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82557a",
-        .pci.qdev.desc = "Intel i82557A Ethernet",
+        .qdev.name = "i82557a",
+        .qdev.desc = "Intel i82557A Ethernet",
         .device = i82557A,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
-        .pci.revision = 0x01,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x01,
         .power_management = false,
     },{
-        .pci.qdev.name = "i82557b",
-        .pci.qdev.desc = "Intel i82557B Ethernet",
+        .qdev.name = "i82557b",
+        .qdev.desc = "Intel i82557B Ethernet",
         .device = i82557B,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
-        .pci.revision = 0x02,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x02,
         .power_management = false,
     },{
-        .pci.qdev.name = "i82557c",
-        .pci.qdev.desc = "Intel i82557C Ethernet",
+        .qdev.name = "i82557c",
+        .qdev.desc = "Intel i82557C Ethernet",
         .device = i82557C,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
-        .pci.revision = 0x03,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x03,
         .power_management = false,
     },{
-        .pci.qdev.name = "i82558a",
-        .pci.qdev.desc = "Intel i82558A Ethernet",
+        .qdev.name = "i82558a",
+        .qdev.desc = "Intel i82558A Ethernet",
         .device = i82558A,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
-        .pci.revision = 0x04,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x04,
         .stats_size = 76,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82558b",
-        .pci.qdev.desc = "Intel i82558B Ethernet",
+        .qdev.name = "i82558b",
+        .qdev.desc = "Intel i82558B Ethernet",
         .device = i82558B,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
-        .pci.revision = 0x05,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x05,
         .stats_size = 76,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82559a",
-        .pci.qdev.desc = "Intel i82559A Ethernet",
+        .qdev.name = "i82559a",
+        .qdev.desc = "Intel i82559A Ethernet",
         .device = i82559A,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
-        .pci.revision = 0x06,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x06,
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82559b",
-        .pci.qdev.desc = "Intel i82559B Ethernet",
+        .qdev.name = "i82559b",
+        .qdev.desc = "Intel i82559B Ethernet",
         .device = i82559B,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
-        .pci.revision = 0x07,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .revision = 0x07,
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82559c",
-        .pci.qdev.desc = "Intel i82559C Ethernet",
+        .qdev.name = "i82559c",
+        .qdev.desc = "Intel i82559C Ethernet",
         .device = i82559C,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+        .device_id = PCI_DEVICE_ID_INTEL_82557,
 #if 0
-        .pci.revision = 0x08,
+        .revision = 0x08,
 #endif
         /* TODO: Windows wants revision id 0x0c. */
-        .pci.revision = 0x0c,
+        .revision = 0x0c,
 #if EEPROM_SIZE > 0
-        .pci.subsystem_vendor_id = PCI_VENDOR_ID_INTEL,
-        .pci.subsystem_id = 0x0040,
+        .subsystem_vendor_id = PCI_VENDOR_ID_INTEL,
+        .subsystem_id = 0x0040,
 #endif
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82559er",
-        .pci.qdev.desc = "Intel i82559ER Ethernet",
+        .qdev.name = "i82559er",
+        .qdev.desc = "Intel i82559ER Ethernet",
         .device = i82559ER,
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
-        .pci.revision = 0x09,
+        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        .revision = 0x09,
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .pci.qdev.name = "i82562",
-        .pci.qdev.desc = "Intel i82562 Ethernet",
+        .qdev.name = "i82562",
+        .qdev.desc = "Intel i82562 Ethernet",
         .device = i82562,
         /* TODO: check device id. */
-        .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
         /* TODO: wrong revision id. */
-        .pci.revision = 0x0e,
+        .revision = 0x0e,
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
         /* Toshiba Tecra 8200. */
-        .pci.qdev.name = "i82801",
-        .pci.qdev.desc = "Intel i82801 Ethernet",
+        .qdev.name = "i82801",
+        .qdev.desc = "Intel i82801 Ethernet",
         .device = i82801,
-        .pci.device_id = 0x2449,
-        .pci.revision = 0x03,
+        .device_id = 0x2449,
+        .revision = 0x03,
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
     }
 };
 
+static E100PCIDeviceInfo *eepro100_get_class_by_name(const char *typename)
+{
+    E100PCIDeviceInfo *info = NULL;
+    int i;
+
+    /* This is admittedly awkward but also temporary.  QOM allows for
+     * parameterized typing and for subclassing both of which would suitable
+     * handle what's going on here.  But class_data is already being used as
+     * a stop-gap hack to allow incremental qdev conversion so we cannot use it
+     * right now.  Once we merge the final QOM series, we can come back here and
+     * do this in a much more elegant fashion.
+     */
+    for (i = 0; i < ARRAY_SIZE(e100_devices); i++) {
+        if (strcmp(e100_devices[i].qdev.name, typename) == 0) {
+            info = &e100_devices[i];
+            break;
+        }
+    }
+    assert(info != NULL);
+
+    return info;
+}
+
+static E100PCIDeviceInfo *eepro100_get_class(EEPRO100State *s)
+{
+    return eepro100_get_class_by_name(object_get_typename(OBJECT(s)));
+}
+
+static void eepro100_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+    E100PCIDeviceInfo *info;
+
+    info = eepro100_get_class_by_name(object_class_get_name(klass));
+
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+    k->romfile = "pxe-eepro100.rom";
+    k->init = e100_nic_init;
+    k->exit = pci_nic_uninit;
+    k->device_id = info->device_id;
+    k->revision = info->revision;
+    k->subsystem_vendor_id = info->subsystem_vendor_id;
+    k->subsystem_id = info->subsystem_id;
+}
+
 static Property e100_properties[] = {
     DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
     DEFINE_PROP_END_OF_LIST(),
@@ -2036,17 +2090,13 @@ static void eepro100_register_devices(void)
 {
     size_t i;
     for (i = 0; i < ARRAY_SIZE(e100_devices); i++) {
-        PCIDeviceInfo *pci_dev = &e100_devices[i].pci;
-        /* We use the same rom file for all device ids.
-           QEMU fixes the device id during rom load. */
-        pci_dev->vendor_id = PCI_VENDOR_ID_INTEL;
-        pci_dev->class_id = PCI_CLASS_NETWORK_ETHERNET;
-        pci_dev->romfile = "pxe-eepro100.rom";
-        pci_dev->init = e100_nic_init;
-        pci_dev->exit = pci_nic_uninit;
-        pci_dev->qdev.props = e100_properties;
-        pci_dev->qdev.size = sizeof(EEPRO100State);
-        pci_qdev_register(pci_dev);
+        DeviceInfo *info = &e100_devices[i].qdev;
+
+        info->class_init = eepro100_class_init;
+        info->size = sizeof(EEPRO100State);
+        info->props = e100_properties;
+        
+        pci_qdev_register(info);
     }
 }
 
diff --git a/hw/es1370.c b/hw/es1370.c
index 3527eb6..205bed7 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -1031,18 +1031,25 @@ int es1370_init (PCIBus *bus)
     return 0;
 }
 
-static PCIDeviceInfo es1370_info = {
-    .qdev.name    = "ES1370",
-    .qdev.desc    = "ENSONIQ AudioPCI ES1370",
-    .qdev.size    = sizeof (ES1370State),
-    .qdev.vmsd    = &vmstate_es1370,
-    .init         = es1370_initfn,
-    .exit         = es1370_exitfn,
-    .vendor_id    = PCI_VENDOR_ID_ENSONIQ,
-    .device_id    = PCI_DEVICE_ID_ENSONIQ_ES1370,
-    .class_id     = PCI_CLASS_MULTIMEDIA_AUDIO,
-    .subsystem_vendor_id = 0x4942,
-    .subsystem_id = 0x4c4c,
+static void es1370_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = es1370_initfn;
+    k->exit = es1370_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_ENSONIQ;
+    k->device_id = PCI_DEVICE_ID_ENSONIQ_ES1370;
+    k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+    k->subsystem_vendor_id = 0x4942;
+    k->subsystem_id = 0x4c4c;
+}
+
+static DeviceInfo es1370_info = {
+    .name = "ES1370",
+    .desc = "ENSONIQ AudioPCI ES1370",
+    .size = sizeof (ES1370State),
+    .vmsd = &vmstate_es1370,
+    .class_init = es1370_class_init,
 };
 
 static void es1370_register (void)
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index be10a6d..a790f97 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -121,15 +121,22 @@ static int grackle_pci_host_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo grackle_pci_info = {
-    .qdev.name = "grackle",
-    .qdev.size = sizeof(PCIDevice),
-    .qdev.no_user = 1,
-    .init      = grackle_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_MOTOROLA,
-    .device_id = PCI_DEVICE_ID_MOTOROLA_MPC106,
-    .revision  = 0x00,
-    .class_id  = PCI_CLASS_BRIDGE_HOST,
+static void grackle_pci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init      = grackle_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_MOTOROLA;
+    k->device_id = PCI_DEVICE_ID_MOTOROLA_MPC106;
+    k->revision  = 0x00;
+    k->class_id  = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo grackle_pci_info = {
+    .name = "grackle",
+    .size = sizeof(PCIDevice),
+    .no_user = 1,
+    .class_init = grackle_pci_class_init,
 };
 
 static SysBusDeviceInfo grackle_pci_host_info = {
diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index 432683a..9fc51f2 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -1136,14 +1136,21 @@ static int gt64120_pci_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo gt64120_pci_info = {
-    .qdev.name = "gt64120_pci",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = gt64120_pci_init,
-    .vendor_id = PCI_VENDOR_ID_MARVELL,
-    .device_id = PCI_DEVICE_ID_MARVELL_GT6412X,
-    .revision  = 0x10,
-    .class_id  = PCI_CLASS_BRIDGE_HOST,
+static void gt64120_pci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = gt64120_pci_init;
+    k->vendor_id = PCI_VENDOR_ID_MARVELL;
+    k->device_id = PCI_DEVICE_ID_MARVELL_GT6412X;
+    k->revision = 0x10;
+    k->class_id = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo gt64120_pci_info = {
+    .name = "gt64120_pci",
+    .size = sizeof(PCIDevice),
+    .class_init = gt64120_pci_class_init,
 };
 
 static void gt64120_pci_register_devices(void)
diff --git a/hw/i82378.c b/hw/i82378.c
index 95ae274..99b453a 100644
--- a/hw/i82378.c
+++ b/hw/i82378.c
@@ -238,18 +238,25 @@ static int pci_i82378_init(PCIDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo pci_i82378_info = {
-    .init = pci_i82378_init,
-    .qdev.name = "i82378",
-    .qdev.size = sizeof(PCIi82378State),
-    .qdev.vmsd = &vmstate_pci_i82378,
-    .vendor_id = PCI_VENDOR_ID_INTEL,
-    .device_id = PCI_DEVICE_ID_INTEL_82378,
-    .revision = 0x03,
-    .class_id = PCI_CLASS_BRIDGE_ISA,
-    .subsystem_vendor_id = 0x0,
-    .subsystem_id = 0x0,
-    .qdev.props = (Property[]) {
+static void pci_i82378_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_i82378_init;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82378;
+    k->revision = 0x03;
+    k->class_id = PCI_CLASS_BRIDGE_ISA;
+    k->subsystem_vendor_id = 0x0;
+    k->subsystem_id = 0x0;
+}
+
+static DeviceInfo pci_i82378_info = {
+    .name = "i82378",
+    .size = sizeof(PCIi82378State),
+    .vmsd = &vmstate_pci_i82378,
+    .class_init = pci_i82378_class_init,
+    .props = (Property[]) {
         DEFINE_PROP_HEX32("iobase", PCIi82378State, isa_io_base, 0x80000000),
         DEFINE_PROP_HEX32("membase", PCIi82378State, isa_mem_base, 0xc0000000),
         DEFINE_PROP_END_OF_LIST()
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 99e7e6f..9c673bb 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -325,20 +325,28 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
     pci_ide_create_devs(dev, hd_table);
 }
 
-static PCIDeviceInfo cmd646_ide_info = {
-    .qdev.name    = "cmd646-ide",
-    .qdev.size    = sizeof(PCIIDEState),
-    .init         = pci_cmd646_ide_initfn,
-    .exit         = pci_cmd646_ide_exitfn,
-    .vendor_id    = PCI_VENDOR_ID_CMD,
-    .device_id    = PCI_DEVICE_ID_CMD_646,
-    /* IDE controller revision */
-    .revision     = 0x07,
-    .class_id     = PCI_CLASS_STORAGE_IDE,
-    .qdev.props   = (Property[]) {
-        DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property cmd646_ide_properties[] = {
+    DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void cmd646_ide_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_cmd646_ide_initfn;
+    k->exit = pci_cmd646_ide_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_CMD;
+    k->device_id = PCI_DEVICE_ID_CMD_646;
+    k->revision = 0x07;
+    k->class_id = PCI_CLASS_STORAGE_IDE;
+}
+
+static DeviceInfo cmd646_ide_info = {
+    .name = "cmd646-ide",
+    .size = sizeof(PCIIDEState),
+    .props = cmd646_ide_properties,
+    .class_init = cmd646_ide_class_init,
 };
 
 static void cmd646_ide_register(void)
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index e6421e2..1cae9f1 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -146,18 +146,25 @@ static void pci_ich9_write_config(PCIDevice *pci, uint32_t addr,
     msi_write_config(pci, addr, val, len);
 }
 
-static PCIDeviceInfo ich_ahci_info = {
-    .qdev.name    = "ich9-ahci",
-    .qdev.alias   = "ahci",
-    .qdev.size    = sizeof(AHCIPCIState),
-    .qdev.vmsd    = &vmstate_ahci,
-    .init         = pci_ich9_ahci_init,
-    .exit         = pci_ich9_uninit,
-    .config_write = pci_ich9_write_config,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82801IR,
-    .revision     = 0x02,
-    .class_id     = PCI_CLASS_STORAGE_SATA,
+static void ich_ahci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_ich9_ahci_init;
+    k->exit = pci_ich9_uninit;
+    k->config_write = pci_ich9_write_config;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82801IR;
+    k->revision = 0x02;
+    k->class_id = PCI_CLASS_STORAGE_SATA;
+}
+
+static DeviceInfo ich_ahci_info = {
+    .name = "ich9-ahci",
+    .alias = "ahci",
+    .size = sizeof(AHCIPCIState),
+    .vmsd = &vmstate_ahci,
+    .class_init = ich_ahci_class_init,
 };
 
 static void ich_ahci_register(void)
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 91b77a2..832a507 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -237,39 +237,60 @@ PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
     return dev;
 }
 
-static PCIDeviceInfo piix3_ide_info = {
-    .qdev.name    = "piix3-ide",
-    .qdev.size    = sizeof(PCIIDEState),
-    .qdev.no_user = 1,
-    .no_hotplug   = 1,
-    .init         = pci_piix_ide_initfn,
-    .exit         = pci_piix_ide_exitfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
-    .class_id     = PCI_CLASS_STORAGE_IDE,
+static void piix3_ide_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = pci_piix_ide_initfn;
+    k->exit = pci_piix_ide_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
+    k->class_id = PCI_CLASS_STORAGE_IDE;
+}
+
+static DeviceInfo piix3_ide_info = {
+    .name = "piix3-ide",
+    .size = sizeof(PCIIDEState),
+    .no_user = 1,
+    .class_init = piix3_ide_class_init,
 };
 
-static PCIDeviceInfo piix3_ide_xen_info = {
-    .qdev.name    = "piix3-ide-xen",
-    .qdev.size    = sizeof(PCIIDEState),
-    .qdev.no_user = 1,
-    .qdev.unplug  = pci_piix3_xen_ide_unplug,
-    .init         = pci_piix_ide_initfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
-    .class_id     = PCI_CLASS_STORAGE_IDE,
+static void piix3_ide_xen_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_piix_ide_initfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
+    k->class_id = PCI_CLASS_STORAGE_IDE;
+}
+
+static DeviceInfo piix3_ide_xen_info = {
+    .name = "piix3-ide-xen",
+    .size = sizeof(PCIIDEState),
+    .no_user = 1,
+    .class_init = piix3_ide_xen_class_init,
+    .unplug = pci_piix3_xen_ide_unplug,
 };
 
-static PCIDeviceInfo piix4_ide_info = {
-    .qdev.name    = "piix4-ide",
-    .qdev.size    = sizeof(PCIIDEState),
-    .qdev.no_user = 1,
-    .no_hotplug   = 1,
-    .init         = pci_piix_ide_initfn,
-    .exit         = pci_piix_ide_exitfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82371AB,
-    .class_id     = PCI_CLASS_STORAGE_IDE,
+static void piix4_ide_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = pci_piix_ide_initfn;
+    k->exit = pci_piix_ide_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82371AB;
+    k->class_id = PCI_CLASS_STORAGE_IDE;
+}
+
+static DeviceInfo piix4_ide_info = {
+    .name = "piix4-ide",
+    .size = sizeof(PCIIDEState),
+    .no_user = 1,
+    .class_init = piix4_ide_class_init,
 };
 
 static void piix_ide_register(void)
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 4ea2064..ef70864 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -213,16 +213,23 @@ void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
     pci_ide_create_devs(dev, hd_table);
 }
 
-static PCIDeviceInfo via_ide_info = {
-    .qdev.name    = "via-ide",
-    .qdev.size    = sizeof(PCIIDEState),
-    .qdev.no_user = 1,
-    .init         = vt82c686b_ide_initfn,
-    .exit         = vt82c686b_ide_exitfn,
-    .vendor_id    = PCI_VENDOR_ID_VIA,
-    .device_id    = PCI_DEVICE_ID_VIA_IDE,
-    .revision     = 0x06,
-    .class_id     = PCI_CLASS_STORAGE_IDE,
+static void via_ide_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = vt82c686b_ide_initfn;
+    k->exit = vt82c686b_ide_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_VIA;
+    k->device_id = PCI_DEVICE_ID_VIA_IDE;
+    k->revision = 0x06;
+    k->class_id = PCI_CLASS_STORAGE_IDE;
+}
+
+static DeviceInfo via_ide_info = {
+    .name = "via-ide",
+    .size = sizeof(PCIIDEState),
+    .no_user = 1,
+    .class_init = via_ide_class_init,
 };
 
 static void via_ide_register(void)
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index f727c22..f062133 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -79,7 +79,7 @@ void hda_codec_register(DeviceInfo *info)
     info->init = hda_codec_dev_init;
     info->exit = hda_codec_dev_exit;
     info->bus_info = &hda_codec_bus_info;
-    qdev_register(info);
+    qdev_register_subclass(info, TYPE_HDA_CODEC_DEVICE);
 }
 
 HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad)
@@ -1247,29 +1247,47 @@ static const VMStateDescription vmstate_intel_hda = {
     }
 };
 
-static PCIDeviceInfo intel_hda_info = {
-    .qdev.name    = "intel-hda",
-    .qdev.desc    = "Intel HD Audio Controller",
-    .qdev.size    = sizeof(IntelHDAState),
-    .qdev.vmsd    = &vmstate_intel_hda,
-    .qdev.reset   = intel_hda_reset,
-    .init         = intel_hda_init,
-    .exit         = intel_hda_exit,
-    .config_write = intel_hda_write_config,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = 0x2668,
-    .revision     = 1,
-    .class_id     = PCI_CLASS_MULTIMEDIA_HD_AUDIO,
-    .qdev.props   = (Property[]) {
-        DEFINE_PROP_UINT32("debug", IntelHDAState, debug, 0),
-        DEFINE_PROP_UINT32("msi", IntelHDAState, msi, 1),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property intel_hda_properties[] = {
+    DEFINE_PROP_UINT32("debug", IntelHDAState, debug, 0),
+    DEFINE_PROP_UINT32("msi", IntelHDAState, msi, 1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void intel_hda_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = intel_hda_init;
+    k->exit = intel_hda_exit;
+    k->config_write = intel_hda_write_config;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = 0x2668;
+    k->revision = 1;
+    k->class_id = PCI_CLASS_MULTIMEDIA_HD_AUDIO;
+}
+
+static DeviceInfo intel_hda_info = {
+    .name = "intel-hda",
+    .desc = "Intel HD Audio Controller",
+    .size = sizeof(IntelHDAState),
+    .vmsd = &vmstate_intel_hda,
+    .reset = intel_hda_reset,
+    .props = intel_hda_properties,
+    .class_init = intel_hda_class_init,
+};
+
+static TypeInfo hda_codec_device_type_info = {
+    .name = TYPE_HDA_CODEC_DEVICE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(HDACodecDevice),
+    .abstract = true,
+    .class_size = sizeof(HDACodecDeviceClass),
 };
 
 static void intel_hda_register(void)
 {
     pci_qdev_register(&intel_hda_info);
+    type_register_static(&hda_codec_device_type_info);
 }
 device_init(intel_hda_register);
 
diff --git a/hw/ioh3420.c b/hw/ioh3420.c
index a6bfbb9..6cfafb3 100644
--- a/hw/ioh3420.c
+++ b/hw/ioh3420.c
@@ -80,7 +80,7 @@ static void ioh3420_write_config(PCIDevice *d,
 
 static void ioh3420_reset(DeviceState *qdev)
 {
-    PCIDevice *d = DO_UPCAST(PCIDevice, qdev, qdev);
+    PCIDevice *d = PCI_DEVICE(qdev);
     msi_reset(d);
     ioh3420_aer_vector_update(d);
     pcie_cap_root_reset(d);
@@ -201,31 +201,38 @@ static const VMStateDescription vmstate_ioh3420 = {
     }
 };
 
-static PCIDeviceInfo ioh3420_info = {
-    .qdev.name = "ioh3420",
-    .qdev.desc = "Intel IOH device id 3420 PCIE Root Port",
-    .qdev.size = sizeof(PCIESlot),
-    .qdev.reset = ioh3420_reset,
-    .qdev.vmsd = &vmstate_ioh3420,
-
-    .is_express = 1,
-    .is_bridge = 1,
-    .config_write = ioh3420_write_config,
-    .init = ioh3420_initfn,
-    .exit = ioh3420_exitfn,
-    .vendor_id = PCI_VENDOR_ID_INTEL,
-    .device_id = PCI_DEVICE_ID_IOH_EPORT,
-    .revision = PCI_DEVICE_ID_IOH_REV,
-
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT8("port", PCIESlot, port.port, 0),
-        DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
-        DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
-        DEFINE_PROP_UINT16("aer_log_max", PCIESlot,
-                           port.br.dev.exp.aer_log.log_max,
-                           PCIE_AER_LOG_MAX_DEFAULT),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property ioh3420_properties[] = {
+    DEFINE_PROP_UINT8("port", PCIESlot, port.port, 0),
+    DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
+    DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
+    DEFINE_PROP_UINT16("aer_log_max", PCIESlot,
+    port.br.dev.exp.aer_log.log_max,
+    PCIE_AER_LOG_MAX_DEFAULT),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ioh3420_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->is_express = 1;
+    k->is_bridge = 1;
+    k->config_write = ioh3420_write_config;
+    k->init = ioh3420_initfn;
+    k->exit = ioh3420_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_IOH_EPORT;
+    k->revision = PCI_DEVICE_ID_IOH_REV;
+}
+
+static DeviceInfo ioh3420_info = {
+    .name = "ioh3420",
+    .desc = "Intel IOH device id 3420 PCIE Root Port",
+    .size = sizeof(PCIESlot),
+    .reset = ioh3420_reset,
+    .vmsd = &vmstate_ioh3420,
+    .props = ioh3420_properties,
+    .class_init = ioh3420_class_init,
 };
 
 static void ioh3420_register(void)
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index bec2e0b..e2880be 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -766,25 +766,34 @@ static int pci_ivshmem_uninit(PCIDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo ivshmem_info = {
-    .qdev.name  = "ivshmem",
-    .qdev.size  = sizeof(IVShmemState),
-    .qdev.reset = ivshmem_reset,
-    .init       = pci_ivshmem_init,
-    .exit       = pci_ivshmem_uninit,
-    .vendor_id  = PCI_VENDOR_ID_REDHAT_QUMRANET,
-    .device_id  = 0x1110,
-    .class_id   = PCI_CLASS_MEMORY_RAM,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_CHR("chardev", IVShmemState, server_chr),
-        DEFINE_PROP_STRING("size", IVShmemState, sizearg),
-        DEFINE_PROP_UINT32("vectors", IVShmemState, vectors, 1),
-        DEFINE_PROP_BIT("ioeventfd", IVShmemState, features, IVSHMEM_IOEVENTFD, false),
-        DEFINE_PROP_BIT("msi", IVShmemState, features, IVSHMEM_MSI, true),
-        DEFINE_PROP_STRING("shm", IVShmemState, shmobj),
-        DEFINE_PROP_STRING("role", IVShmemState, role),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property ivshmem_properties[] = {
+    DEFINE_PROP_CHR("chardev", IVShmemState, server_chr),
+    DEFINE_PROP_STRING("size", IVShmemState, sizearg),
+    DEFINE_PROP_UINT32("vectors", IVShmemState, vectors, 1),
+    DEFINE_PROP_BIT("ioeventfd", IVShmemState, features, IVSHMEM_IOEVENTFD, false),
+    DEFINE_PROP_BIT("msi", IVShmemState, features, IVSHMEM_MSI, true),
+    DEFINE_PROP_STRING("shm", IVShmemState, shmobj),
+    DEFINE_PROP_STRING("role", IVShmemState, role),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ivshmem_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_ivshmem_init;
+    k->exit = pci_ivshmem_uninit;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = 0x1110;
+    k->class_id = PCI_CLASS_MEMORY_RAM;
+}
+
+static DeviceInfo ivshmem_info = {
+    .name = "ivshmem",
+    .size = sizeof(IVShmemState),
+    .reset = ivshmem_reset,
+    .props = ivshmem_properties,
+    .class_init = ivshmem_class_init,
 };
 
 static void ivshmem_register_devices(void)
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 3a87171..3571588 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -2120,18 +2120,25 @@ static int lsi_scsi_init(PCIDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo lsi_info = {
-    .qdev.name  = "lsi53c895a",
-    .qdev.alias = "lsi",
-    .qdev.size  = sizeof(LSIState),
-    .qdev.reset = lsi_scsi_reset,
-    .qdev.vmsd  = &vmstate_lsi_scsi,
-    .init       = lsi_scsi_init,
-    .exit       = lsi_scsi_uninit,
-    .vendor_id  = PCI_VENDOR_ID_LSI_LOGIC,
-    .device_id  = PCI_DEVICE_ID_LSI_53C895A,
-    .class_id   = PCI_CLASS_STORAGE_SCSI,
-    .subsystem_id = 0x1000,
+static void lsi_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = lsi_scsi_init;
+    k->exit = lsi_scsi_uninit;
+    k->vendor_id = PCI_VENDOR_ID_LSI_LOGIC;
+    k->device_id = PCI_DEVICE_ID_LSI_53C895A;
+    k->class_id = PCI_CLASS_STORAGE_SCSI;
+    k->subsystem_id = 0x1000;
+}
+
+static DeviceInfo lsi_info = {
+    .name = "lsi53c895a",
+    .alias = "lsi",
+    .size = sizeof(LSIState),
+    .reset = lsi_scsi_reset,
+    .vmsd = &vmstate_lsi_scsi,
+    .class_init = lsi_class_init,
 };
 
 static void lsi53c895a_register_devices(void)
diff --git a/hw/macio.c b/hw/macio.c
index 357e0ea..ae9db08 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -81,12 +81,19 @@ static int macio_initfn(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo macio_info = {
-    .qdev.name = "macio",
-    .qdev.size = sizeof(MacIOState),
-    .init = macio_initfn,
-    .vendor_id = PCI_VENDOR_ID_APPLE,
-    .class_id = PCI_CLASS_OTHERS << 8,
+static void macio_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = macio_initfn;
+    k->vendor_id = PCI_VENDOR_ID_APPLE;
+    k->class_id = PCI_CLASS_OTHERS << 8;
+}
+
+static DeviceInfo macio_info = {
+    .name = "macio",
+    .size = sizeof(MacIOState),
+    .class_init = macio_class_init,
 };
 
 static void macio_register(void)
diff --git a/hw/ne2000.c b/hw/ne2000.c
index b44eab1..138479a 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -786,19 +786,28 @@ static int pci_ne2000_exit(PCIDevice *pci_dev)
     return 0;
 }
 
-static PCIDeviceInfo ne2000_info = {
-    .qdev.name  = "ne2k_pci",
-    .qdev.size  = sizeof(PCINE2000State),
-    .qdev.vmsd  = &vmstate_pci_ne2000,
-    .init       = pci_ne2000_init,
-    .exit       = pci_ne2000_exit,
-    .vendor_id  = PCI_VENDOR_ID_REALTEK,
-    .device_id  = PCI_DEVICE_ID_REALTEK_8029,
-    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property ne2000_properties[] = {
+    DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ne2000_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_ne2000_init;
+    k->exit = pci_ne2000_exit;
+    k->vendor_id = PCI_VENDOR_ID_REALTEK;
+    k->device_id = PCI_DEVICE_ID_REALTEK_8029;
+    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+}
+
+static DeviceInfo ne2000_info = {
+    .name = "ne2k_pci",
+    .size = sizeof(PCINE2000State),
+    .vmsd = &vmstate_pci_ne2000,
+    .props = ne2000_properties,
+    .class_init = ne2000_class_init,
 };
 
 static void ne2000_register_devices(void)
diff --git a/hw/pci.c b/hw/pci.c
index 516da08..6a0b1f5 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -89,7 +89,6 @@ static const VMStateDescription vmstate_pcibus = {
         VMSTATE_END_OF_LIST()
     }
 };
-
 static int pci_bar(PCIDevice *d, int reg)
 {
     uint8_t type;
@@ -730,11 +729,11 @@ static void pci_config_free(PCIDevice *pci_dev)
 
 /* -1 for devfn means auto assign */
 static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
-                                         const char *name, int devfn,
-                                         const PCIDeviceInfo *info)
+                                         const char *name, int devfn)
 {
-    PCIConfigReadFunc *config_read = info->config_read;
-    PCIConfigWriteFunc *config_write = info->config_write;
+    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
+    PCIConfigReadFunc *config_read = pc->config_read;
+    PCIConfigWriteFunc *config_write = pc->config_write;
 
     if (devfn < 0) {
         for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
@@ -756,29 +755,29 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
     pci_dev->irq_state = 0;
     pci_config_alloc(pci_dev);
 
-    pci_config_set_vendor_id(pci_dev->config, info->vendor_id);
-    pci_config_set_device_id(pci_dev->config, info->device_id);
-    pci_config_set_revision(pci_dev->config, info->revision);
-    pci_config_set_class(pci_dev->config, info->class_id);
+    pci_config_set_vendor_id(pci_dev->config, pc->vendor_id);
+    pci_config_set_device_id(pci_dev->config, pc->device_id);
+    pci_config_set_revision(pci_dev->config, pc->revision);
+    pci_config_set_class(pci_dev->config, pc->class_id);
 
-    if (!info->is_bridge) {
-        if (info->subsystem_vendor_id || info->subsystem_id) {
+    if (!pc->is_bridge) {
+        if (pc->subsystem_vendor_id || pc->subsystem_id) {
             pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID,
-                         info->subsystem_vendor_id);
+                         pc->subsystem_vendor_id);
             pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID,
-                         info->subsystem_id);
+                         pc->subsystem_id);
         } else {
             pci_set_default_subsystem_id(pci_dev);
         }
     } else {
         /* subsystem_vendor_id/subsystem_id are only for header type 0 */
-        assert(!info->subsystem_vendor_id);
-        assert(!info->subsystem_id);
+        assert(!pc->subsystem_vendor_id);
+        assert(!pc->subsystem_id);
     }
     pci_init_cmask(pci_dev);
     pci_init_wmask(pci_dev);
     pci_init_w1cmask(pci_dev);
-    if (info->is_bridge) {
+    if (pc->is_bridge) {
         pci_init_wmask_bridge(pci_dev);
     }
     if (pci_init_multifunction(bus, pci_dev)) {
@@ -805,26 +804,6 @@ static void do_pci_unregister_device(PCIDevice *pci_dev)
     pci_config_free(pci_dev);
 }
 
-/* TODO: obsolete. eliminate this once all pci devices are qdevifed. */
-PCIDevice *pci_register_device(PCIBus *bus, const char *name,
-                               int instance_size, int devfn,
-                               PCIConfigReadFunc *config_read,
-                               PCIConfigWriteFunc *config_write)
-{
-    PCIDevice *pci_dev;
-    PCIDeviceInfo info = {
-        .config_read = config_read,
-        .config_write = config_write,
-    };
-
-    pci_dev = g_malloc0(instance_size);
-    pci_dev = do_pci_register_device(pci_dev, bus, name, devfn, &info);
-    if (pci_dev == NULL) {
-        hw_error("PCI: can't register device\n");
-    }
-    return pci_dev;
-}
-
 static void pci_unregister_io_regions(PCIDevice *pci_dev)
 {
     PCIIORegion *r;
@@ -840,12 +819,12 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
 
 static int pci_unregister_device(DeviceState *dev)
 {
-    PCIDevice *pci_dev = DO_UPCAST(PCIDevice, qdev, dev);
-    PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, qdev_get_info(dev));
+    PCIDevice *pci_dev = PCI_DEVICE(dev);
+    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
     int ret = 0;
 
-    if (info->exit)
-        ret = info->exit(pci_dev);
+    if (pc->exit)
+        ret = pc->exit(pci_dev);
     if (ret)
         return ret;
 
@@ -1477,28 +1456,27 @@ PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn)
 static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
 {
     PCIDevice *pci_dev = (PCIDevice *)qdev;
-    PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
+    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
     PCIBus *bus;
     int rc;
     bool is_default_rom;
 
     /* initialize cap_present for pci_is_express() and pci_config_size() */
-    if (info->is_express) {
+    if (pc->is_express) {
         pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
     }
 
     bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
-    pci_dev = do_pci_register_device(pci_dev, bus, base->name,
-                                     pci_dev->devfn, info);
+    pci_dev = do_pci_register_device(pci_dev, bus, base->name, pci_dev->devfn);
     if (pci_dev == NULL)
         return -1;
-    if (qdev->hotplugged && info->no_hotplug) {
+    if (qdev->hotplugged && pc->no_hotplug) {
         qerror_report(QERR_DEVICE_NO_HOTPLUG, object_get_typename(OBJECT(pci_dev)));
         do_pci_unregister_device(pci_dev);
         return -1;
     }
-    if (info->init) {
-        rc = info->init(pci_dev);
+    if (pc->init) {
+        rc = pc->init(pci_dev);
         if (rc != 0) {
             do_pci_unregister_device(pci_dev);
             return rc;
@@ -1507,8 +1485,8 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
 
     /* rom loading */
     is_default_rom = false;
-    if (pci_dev->romfile == NULL && info->romfile != NULL) {
-        pci_dev->romfile = g_strdup(info->romfile);
+    if (pci_dev->romfile == NULL && pc->romfile != NULL) {
+        pci_dev->romfile = g_strdup(pc->romfile);
         is_default_rom = true;
     }
     pci_add_option_rom(pci_dev, is_default_rom);
@@ -1530,10 +1508,10 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
 
 static int pci_unplug_device(DeviceState *qdev)
 {
-    PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);
-    PCIDeviceInfo *info = container_of(qdev_get_info(qdev), PCIDeviceInfo, qdev);
+    PCIDevice *dev = PCI_DEVICE(qdev);
+    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
 
-    if (info->no_hotplug) {
+    if (pc->no_hotplug) {
         qerror_report(QERR_DEVICE_NO_HOTPLUG, object_get_typename(OBJECT(dev)));
         return -1;
     }
@@ -1541,23 +1519,15 @@ static int pci_unplug_device(DeviceState *qdev)
                              PCI_HOTPLUG_DISABLED);
 }
 
-void pci_qdev_register(PCIDeviceInfo *info)
-{
-    info->qdev.init = pci_qdev_init;
-    if (!info->qdev.unplug) {
-        info->qdev.unplug = pci_unplug_device;
-    }
-    info->qdev.exit = pci_unregister_device;
-    info->qdev.bus_info = &pci_bus_info;
-    qdev_register(&info->qdev);
-}
-
-void pci_qdev_register_many(PCIDeviceInfo *info)
+void pci_qdev_register(DeviceInfo *info)
 {
-    while (info->qdev.name) {
-        pci_qdev_register(info);
-        info++;
+    info->init = pci_qdev_init;
+    if (!info->unplug) {
+        info->unplug = pci_unplug_device;
     }
+    info->exit = pci_unregister_device;
+    info->bus_info = &pci_bus_info;
+    qdev_register_subclass(info, TYPE_PCI_DEVICE);
 }
 
 PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction,
@@ -1568,7 +1538,7 @@ PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction,
     dev = qdev_create(&bus->qbus, name);
     qdev_prop_set_uint32(dev, "addr", devfn);
     qdev_prop_set_bit(dev, "multifunction", multifunction);
-    return DO_UPCAST(PCIDevice, qdev, dev);
+    return PCI_DEVICE(dev);
 }
 
 PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,
@@ -1985,7 +1955,7 @@ static int pci_qdev_find_recursive(PCIBus *bus,
     /* roughly check if given qdev is pci device */
     if (qdev_get_info(qdev)->init == &pci_qdev_init &&
         qdev->parent_bus->info == &pci_bus_info) {
-        *pdev = DO_UPCAST(PCIDevice, qdev, qdev);
+        *pdev = PCI_DEVICE(qdev);
         return 0;
     }
     return -EINVAL;
@@ -2019,3 +1989,18 @@ MemoryRegion *pci_address_space_io(PCIDevice *dev)
 {
     return dev->bus->address_space_io;
 }
+
+static TypeInfo pci_device_type_info = {
+    .name = TYPE_PCI_DEVICE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(PCIDevice),
+    .abstract = true,
+    .class_size = sizeof(PCIDeviceClass),
+};
+
+static void pci_register_devices(void)
+{
+    type_register_static(&pci_device_type_info);
+}
+
+device_init(pci_register_devices);
diff --git a/hw/pci.h b/hw/pci.h
index 5501d95..09b2324 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -127,6 +127,46 @@ enum {
     QEMU_PCI_CAP_SERR = (1 << QEMU_PCI_CAP_SERR_BITNR),
 };
 
+#define TYPE_PCI_DEVICE "pci-device"
+#define PCI_DEVICE(obj) \
+     OBJECT_CHECK(PCIDevice, (obj), TYPE_PCI_DEVICE)
+#define PCI_DEVICE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(PCIDeviceClass, (klass), TYPE_PCI_DEVICE)
+#define PCI_DEVICE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(PCIDeviceClass, (obj), TYPE_PCI_DEVICE)
+
+typedef struct PCIDeviceClass {
+    DeviceClass parent_class;
+
+    int (*init)(PCIDevice *dev);
+    PCIUnregisterFunc *exit;
+    PCIConfigReadFunc *config_read;
+    PCIConfigWriteFunc *config_write;
+
+    uint16_t vendor_id;
+    uint16_t device_id;
+    uint8_t revision;
+    uint16_t class_id;
+    uint16_t subsystem_vendor_id;       /* only for header type = 0 */
+    uint16_t subsystem_id;              /* only for header type = 0 */
+
+    /*
+     * pci-to-pci bridge or normal device.
+     * This doesn't mean pci host switch.
+     * When card bus bridge is supported, this would be enhanced.
+     */
+    int is_bridge;
+
+    /* pcie stuff */
+    int is_express;   /* is this device pci express? */
+
+    /* device isn't hot-pluggable */
+    int no_hotplug;
+
+    /* rom bar */
+    const char *romfile;
+} PCIDeviceClass;
+
 struct PCIDevice {
     DeviceState qdev;
     /* PCI config space */
@@ -196,11 +236,6 @@ struct PCIDevice {
     uint32_t rom_bar;
 };
 
-PCIDevice *pci_register_device(PCIBus *bus, const char *name,
-                               int instance_size, int devfn,
-                               PCIConfigReadFunc *config_read,
-                               PCIConfigWriteFunc *config_write);
-
 void pci_register_bar(PCIDevice *pci_dev, int region_num,
                       uint8_t attr, MemoryRegion *memory);
 pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num);
@@ -429,40 +464,7 @@ pci_quad_test_and_set_mask(uint8_t *config, uint64_t mask)
     return val & mask;
 }
 
-typedef int (*pci_qdev_initfn)(PCIDevice *dev);
-typedef struct {
-    DeviceInfo qdev;
-    pci_qdev_initfn init;
-    PCIUnregisterFunc *exit;
-    PCIConfigReadFunc *config_read;
-    PCIConfigWriteFunc *config_write;
-
-    uint16_t vendor_id;
-    uint16_t device_id;
-    uint8_t revision;
-    uint16_t class_id;
-    uint16_t subsystem_vendor_id;       /* only for header type = 0 */
-    uint16_t subsystem_id;              /* only for header type = 0 */
-
-    /*
-     * pci-to-pci bridge or normal device.
-     * This doesn't mean pci host switch.
-     * When card bus bridge is supported, this would be enhanced.
-     */
-    int is_bridge;
-
-    /* pcie stuff */
-    int is_express;   /* is this device pci express? */
-
-    /* device isn't hot-pluggable */
-    int no_hotplug;
-
-    /* rom bar */
-    const char *romfile;
-} PCIDeviceInfo;
-
-void pci_qdev_register(PCIDeviceInfo *info);
-void pci_qdev_register_many(PCIDeviceInfo *info);
+void pci_qdev_register(DeviceInfo *info);
 
 PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction,
                                     const char *name);
diff --git a/hw/pci_bridge.c b/hw/pci_bridge.c
index 650d165..1ed4339 100644
--- a/hw/pci_bridge.c
+++ b/hw/pci_bridge.c
@@ -294,7 +294,7 @@ void pci_bridge_reset_reg(PCIDevice *dev)
 /* default reset function for PCI-to-PCI bridge */
 void pci_bridge_reset(DeviceState *qdev)
 {
-    PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);
+    PCIDevice *dev = PCI_DEVICE(qdev);
     pci_bridge_reset_reg(dev);
 }
 
diff --git a/hw/pcie.c b/hw/pcie.c
index 5c9eb2f..7c92f19 100644
--- a/hw/pcie.c
+++ b/hw/pcie.c
@@ -203,7 +203,7 @@ static void pcie_cap_slot_event(PCIDevice *dev, PCIExpressHotPlugEvent event)
 static int pcie_cap_slot_hotplug(DeviceState *qdev,
                                  PCIDevice *pci_dev, PCIHotplugState state)
 {
-    PCIDevice *d = DO_UPCAST(PCIDevice, qdev, qdev);
+    PCIDevice *d = PCI_DEVICE(qdev);
     uint8_t *exp_cap = d->config + d->exp.exp_cap;
     uint16_t sltsta = pci_get_word(exp_cap + PCI_EXP_SLTSTA);
 
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 4e164da..be3bd79 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -348,21 +348,30 @@ static void pci_reset(DeviceState *dev)
     pcnet_h_reset(&d->state);
 }
 
-static PCIDeviceInfo pcnet_info = {
-    .qdev.name  = "pcnet",
-    .qdev.size  = sizeof(PCIPCNetState),
-    .qdev.reset = pci_reset,
-    .qdev.vmsd  = &vmstate_pci_pcnet,
-    .init       = pci_pcnet_init,
-    .exit       = pci_pcnet_uninit,
-    .vendor_id  = PCI_VENDOR_ID_AMD,
-    .device_id  = PCI_DEVICE_ID_AMD_LANCE,
-    .revision   = 0x10,
-    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property pcnet_properties[] = {
+    DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pcnet_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_pcnet_init;
+    k->exit = pci_pcnet_uninit;
+    k->vendor_id = PCI_VENDOR_ID_AMD;
+    k->device_id = PCI_DEVICE_ID_AMD_LANCE;
+    k->revision = 0x10;
+    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+}
+
+static DeviceInfo pcnet_info = {
+    .name = "pcnet",
+    .size = sizeof(PCIPCNetState),
+    .reset = pci_reset,
+    .vmsd = &vmstate_pci_pcnet,
+    .props = pcnet_properties,
+    .class_init = pcnet_class_init,
 };
 
 static void pci_pcnet_register_devices(void)
diff --git a/hw/piix4.c b/hw/piix4.c
index 130dfd1..88be535 100644
--- a/hw/piix4.c
+++ b/hw/piix4.c
@@ -102,18 +102,24 @@ int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn)
     return d->devfn;
 }
 
-static PCIDeviceInfo piix4_info = {
-    .qdev.name    = "PIIX4",
-    .qdev.desc    = "ISA bridge",
-    .qdev.size    = sizeof(PIIX4State),
-    .qdev.vmsd    = &vmstate_piix4,
-    .qdev.no_user = 1,
-    .no_hotplug   = 1,
-    .init         = piix4_initfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    /* 82371AB/EB/MB PIIX4 PCI-to-ISA bridge */
-    .device_id    = PCI_DEVICE_ID_INTEL_82371AB_0,
-    .class_id     = PCI_CLASS_BRIDGE_ISA,
+static void piix4_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = piix4_initfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82371AB_0;
+    k->class_id = PCI_CLASS_BRIDGE_ISA;
+}
+
+static DeviceInfo piix4_info = {
+    .name = "PIIX4",
+    .desc = "ISA bridge",
+    .size = sizeof(PIIX4State),
+    .vmsd = &vmstate_piix4,
+    .no_user = 1,
+    .class_init = piix4_class_init,
 };
 
 static void piix4_register(void)
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 5cbeed5..787db4e 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -502,47 +502,68 @@ static int piix3_initfn(PCIDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo i440fx_info = {
-    .qdev.name    = "i440FX",
-    .qdev.desc    = "Host bridge",
-    .qdev.size    = sizeof(PCII440FXState),
-    .qdev.vmsd    = &vmstate_i440fx,
-    .qdev.no_user = 1,
-    .no_hotplug   = 1,
-    .init         = i440fx_initfn,
-    .config_write = i440fx_write_config,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82441,
-    .revision     = 0x02,
-    .class_id     = PCI_CLASS_BRIDGE_HOST,
+static void piix3_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug   = 1;
+    k->init         = piix3_initfn;
+    k->config_write = piix3_write_config;
+    k->vendor_id    = PCI_VENDOR_ID_INTEL;
+    k->device_id    = PCI_DEVICE_ID_INTEL_82371SB_0; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
+    k->class_id     = PCI_CLASS_BRIDGE_ISA;
+}
+
+static DeviceInfo piix3_info = {
+    .name    = "PIIX3",
+    .desc    = "ISA bridge",
+    .size    = sizeof(PIIX3State),
+    .vmsd    = &vmstate_piix3,
+    .no_user = 1,
+    .class_init = piix3_class_init,
 };
 
-static PCIDeviceInfo piix3_info = {
-    .qdev.name    = "PIIX3",
-    .qdev.desc    = "ISA bridge",
-    .qdev.size    = sizeof(PIIX3State),
-    .qdev.vmsd    = &vmstate_piix3,
-    .qdev.no_user = 1,
-    .no_hotplug   = 1,
-    .init         = piix3_initfn,
-    .config_write = piix3_write_config,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
-    .class_id     = PCI_CLASS_BRIDGE_ISA,
+static void piix3_xen_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug   = 1;
+    k->init         = piix3_initfn;
+    k->config_write = piix3_write_config_xen;
+    k->vendor_id    = PCI_VENDOR_ID_INTEL;
+    k->device_id    = PCI_DEVICE_ID_INTEL_82371SB_0; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
+    k->class_id     = PCI_CLASS_BRIDGE_ISA;
 };
 
-static PCIDeviceInfo piix3_xen_info = {
-    .qdev.name    = "PIIX3-xen",
-    .qdev.desc    = "ISA bridge",
-    .qdev.size    = sizeof(PIIX3State),
-    .qdev.vmsd    = &vmstate_piix3,
-    .qdev.no_user = 1,
-    .no_hotplug   = 1,
-    .init         = piix3_initfn,
-    .config_write = piix3_write_config_xen,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
-    .class_id     = PCI_CLASS_BRIDGE_ISA,
+static DeviceInfo piix3_xen_info = {
+    .name    = "PIIX3-xen",
+    .desc    = "ISA bridge",
+    .size    = sizeof(PIIX3State),
+    .vmsd    = &vmstate_piix3,
+    .no_user = 1,
+    .class_init = piix3_xen_class_init,
+};
+
+static void i440fx_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = i440fx_initfn;
+    k->config_write = i440fx_write_config;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82441;
+    k->revision = 0x02;
+    k->class_id = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo i440fx_info = {
+    .name = "i440FX",
+    .desc = "Host bridge",
+    .size = sizeof(PCII440FXState),
+    .vmsd = &vmstate_i440fx,
+    .no_user = 1,
+    .class_init = i440fx_class_init,
 };
 
 static SysBusDeviceInfo i440fx_pcihost_info = {
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index 26de007..b38840e 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -366,13 +366,20 @@ static int ppc4xx_pcihost_initfn(SysBusDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo ppc4xx_host_bridge_info = {
-    .qdev.name    = "ppc4xx-host-bridge",
-    .qdev.desc    = "Host bridge",
-    .qdev.size    = sizeof(PCIDevice),
-    .vendor_id    = PCI_VENDOR_ID_IBM,
-    .device_id    = PCI_DEVICE_ID_IBM_440GX,
-    .class_id     = PCI_CLASS_BRIDGE_OTHER,
+static void ppc4xx_host_bridge_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->vendor_id    = PCI_VENDOR_ID_IBM;
+    k->device_id    = PCI_DEVICE_ID_IBM_440GX;
+    k->class_id     = PCI_CLASS_BRIDGE_OTHER;
+}
+
+static DeviceInfo ppc4xx_host_bridge_info = {
+    .name    = "ppc4xx-host-bridge",
+    .desc    = "Host bridge",
+    .size    = sizeof(PCIDevice),
+    .class_init = ppc4xx_host_bridge_class_init,
 };
 
 static SysBusDeviceInfo ppc4xx_pcihost_info = {
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index b606206..bc783bf 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -339,13 +339,20 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo e500_host_bridge_info = {
-    .qdev.name    = "e500-host-bridge",
-    .qdev.desc    = "Host bridge",
-    .qdev.size    = sizeof(PCIDevice),
-    .vendor_id    = PCI_VENDOR_ID_FREESCALE,
-    .device_id    = PCI_DEVICE_ID_MPC8533E,
-    .class_id     = PCI_CLASS_PROCESSOR_POWERPC,
+static void e500_host_bridge_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->vendor_id = PCI_VENDOR_ID_FREESCALE;
+    k->device_id = PCI_DEVICE_ID_MPC8533E;
+    k->class_id = PCI_CLASS_PROCESSOR_POWERPC;
+}
+
+static DeviceInfo e500_host_bridge_info = {
+    .name = "e500-host-bridge",
+    .desc = "Host bridge",
+    .size = sizeof(PCIDevice),
+    .class_init = e500_host_bridge_class_init,
 };
 
 static SysBusDeviceInfo e500_pcihost_info = {
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index 4961eed..4ff1049 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -134,21 +134,24 @@ static const VMStateDescription vmstate_raven = {
     },
 };
 
-static PCIDeviceInfo raven_info = {
-    .qdev.name = "raven",
-    .qdev.desc = "PReP Host Bridge - Motorola Raven",
-    .qdev.size = sizeof(RavenPCIState),
-    .qdev.vmsd = &vmstate_raven,
-    .qdev.no_user = 1,
-    .no_hotplug = 1,
-    .init = raven_init,
-    .vendor_id = PCI_VENDOR_ID_MOTOROLA,
-    .device_id = PCI_DEVICE_ID_MOTOROLA_RAVEN,
-    .revision = 0x00,
-    .class_id = PCI_CLASS_BRIDGE_HOST,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_END_OF_LIST()
-    },
+static void raven_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = raven_init;
+    k->vendor_id = PCI_VENDOR_ID_MOTOROLA;
+    k->device_id = PCI_DEVICE_ID_MOTOROLA_RAVEN;
+    k->revision = 0x00;
+    k->class_id = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo raven_info = {
+    .name = "raven",
+    .desc = "PReP Host Bridge - Motorola Raven",
+    .size = sizeof(RavenPCIState),
+    .vmsd = &vmstate_raven,
+    .no_user = 1,
+    .class_init = raven_class_init,
 };
 
 static SysBusDeviceInfo raven_pcihost_info = {
diff --git a/hw/qdev.c b/hw/qdev.c
index 81996bb..a8c24de 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -119,6 +119,7 @@ bool qdev_exists(const char *name)
 {
     return !!qdev_find_info(NULL, name);
 }
+
 static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
                                      Error **errp);
 
diff --git a/hw/qxl.c b/hw/qxl.c
index 2a716bf..7aa7d19 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1827,32 +1827,46 @@ static Property qxl_properties[] = {
         DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo qxl_primary_info = {
-    .qdev.name    = "qxl-vga",
-    .qdev.desc    = "Spice QXL GPU (primary, vga compatible)",
-    .qdev.size    = sizeof(PCIQXLDevice),
-    .qdev.reset   = qxl_reset_handler,
-    .qdev.vmsd    = &qxl_vmstate,
-    .no_hotplug   = 1,
-    .init         = qxl_init_primary,
-    .romfile      = "vgabios-qxl.bin",
-    .vendor_id    = REDHAT_PCI_VENDOR_ID,
-    .device_id    = QXL_DEVICE_ID_STABLE,
-    .class_id     = PCI_CLASS_DISPLAY_VGA,
-    .qdev.props   = qxl_properties,
+static void qxl_primary_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = qxl_init_primary;
+    k->romfile = "vgabios-qxl.bin";
+    k->vendor_id = REDHAT_PCI_VENDOR_ID;
+    k->device_id = QXL_DEVICE_ID_STABLE;
+    k->class_id = PCI_CLASS_DISPLAY_VGA;
+}
+
+static DeviceInfo qxl_primary_info = {
+    .name = "qxl-vga",
+    .desc = "Spice QXL GPU (primary, vga compatible)",
+    .size = sizeof(PCIQXLDevice),
+    .reset = qxl_reset_handler,
+    .vmsd = &qxl_vmstate,
+    .props = qxl_properties,
+    .class_init = qxl_primary_class_init,
 };
 
-static PCIDeviceInfo qxl_secondary_info = {
-    .qdev.name    = "qxl",
-    .qdev.desc    = "Spice QXL GPU (secondary)",
-    .qdev.size    = sizeof(PCIQXLDevice),
-    .qdev.reset   = qxl_reset_handler,
-    .qdev.vmsd    = &qxl_vmstate,
-    .init         = qxl_init_secondary,
-    .vendor_id    = REDHAT_PCI_VENDOR_ID,
-    .device_id    = QXL_DEVICE_ID_STABLE,
-    .class_id     = PCI_CLASS_DISPLAY_OTHER,
-    .qdev.props   = qxl_properties,
+static void qxl_secondary_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = qxl_init_secondary;
+    k->vendor_id = REDHAT_PCI_VENDOR_ID;
+    k->device_id = QXL_DEVICE_ID_STABLE;
+    k->class_id = PCI_CLASS_DISPLAY_OTHER;
+}
+
+static DeviceInfo qxl_secondary_info = {
+    .name = "qxl",
+    .desc = "Spice QXL GPU (secondary)",
+    .size = sizeof(PCIQXLDevice),
+    .reset = qxl_reset_handler,
+    .vmsd = &qxl_vmstate,
+    .props = qxl_properties,
+    .class_init = qxl_secondary_class_init,
 };
 
 static void qxl_register(void)
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 2b55c7f..15dec9b 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3494,22 +3494,31 @@ static int pci_rtl8139_init(PCIDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo rtl8139_info = {
-    .qdev.name  = "rtl8139",
-    .qdev.size  = sizeof(RTL8139State),
-    .qdev.reset = rtl8139_reset,
-    .qdev.vmsd  = &vmstate_rtl8139,
-    .init       = pci_rtl8139_init,
-    .exit       = pci_rtl8139_uninit,
-    .romfile    = "pxe-rtl8139.rom",
-    .vendor_id  = PCI_VENDOR_ID_REALTEK,
-    .device_id  = PCI_DEVICE_ID_REALTEK_8139,
-    .revision   = RTL8139_PCI_REVID, /* >=0x20 is for 8139C+ */
-    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(RTL8139State, conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property rtl8139_properties[] = {
+    DEFINE_NIC_PROPERTIES(RTL8139State, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void rtl8139_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_rtl8139_init;
+    k->exit = pci_rtl8139_uninit;
+    k->romfile = "pxe-rtl8139.rom";
+    k->vendor_id = PCI_VENDOR_ID_REALTEK;
+    k->device_id = PCI_DEVICE_ID_REALTEK_8139;
+    k->revision = RTL8139_PCI_REVID; /* >=0x20 is for 8139C+ */
+    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+}
+
+static DeviceInfo rtl8139_info = {
+    .name = "rtl8139",
+    .size = sizeof(RTL8139State),
+    .reset = rtl8139_reset,
+    .vmsd = &vmstate_rtl8139,
+    .props = rtl8139_properties,
+    .class_init = rtl8139_class_init,
 };
 
 static void rtl8139_register_devices(void)
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index d4d028d..baeab9e 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -147,12 +147,19 @@ static int sh_pci_host_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo sh_pci_host_info = {
-    .qdev.name = "sh_pci_host",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = sh_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_HITACHI,
-    .device_id = PCI_DEVICE_ID_HITACHI_SH7751R,
+static void sh_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = sh_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_HITACHI;
+    k->device_id = PCI_DEVICE_ID_HITACHI_SH7751R;
+}
+
+static DeviceInfo sh_pci_host_info = {
+    .name = "sh_pci_host",
+    .size = sizeof(PCIDevice),
+    .class_init = sh_pci_host_class_init,
 };
 
 static void sh_pci_register_devices(void)
diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c
index 2c95faa..8a39f8f 100644
--- a/hw/spapr_pci.c
+++ b/hw/spapr_pci.c
@@ -214,10 +214,17 @@ static int spapr_main_pci_host_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo spapr_main_pci_host_info = {
-    .qdev.name = "spapr-pci-host-bridge",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = spapr_main_pci_host_init,
+static void spapr_main_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = spapr_main_pci_host_init;
+}
+
+static DeviceInfo spapr_main_pci_host_info = {
+    .name = "spapr-pci-host-bridge",
+    .size = sizeof(PCIDevice),
+    .class_init = spapr_main_pci_host_class_init,
 };
 
 static void spapr_register_devices(void)
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 2dc3d04..6d9fdf6 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -562,14 +562,21 @@ pci_ebus_init1(PCIDevice *pci_dev)
     return 0;
 }
 
-static PCIDeviceInfo ebus_info = {
-    .qdev.name = "ebus",
-    .qdev.size = sizeof(EbusState),
-    .init = pci_ebus_init1,
-    .vendor_id = PCI_VENDOR_ID_SUN,
-    .device_id = PCI_DEVICE_ID_SUN_EBUS,
-    .revision = 0x01,
-    .class_id = PCI_CLASS_BRIDGE_OTHER,
+static void ebus_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_ebus_init1;
+    k->vendor_id = PCI_VENDOR_ID_SUN;
+    k->device_id = PCI_DEVICE_ID_SUN_EBUS;
+    k->revision = 0x01;
+    k->class_id = PCI_CLASS_BRIDGE_OTHER;
+}
+
+static DeviceInfo ebus_info = {
+    .name = "ebus",
+    .size = sizeof(EbusState),
+    .class_init = ebus_class_init,
 };
 
 static void pci_ebus_register(void)
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 6a10013..6a148e0 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -339,44 +339,72 @@ static int unin_internal_pci_host_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo unin_main_pci_host_info = {
-    .qdev.name = "uni-north-pci",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = unin_main_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_APPLE,
-    .device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI,
-    .revision  = 0x00,
-    .class_id  = PCI_CLASS_BRIDGE_HOST,
+static void unin_main_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init      = unin_main_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_APPLE;
+    k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI;
+    k->revision  = 0x00;
+    k->class_id  = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo unin_main_pci_host_info = {
+    .name = "uni-north-pci",
+    .size = sizeof(PCIDevice),
+    .class_init = unin_main_pci_host_class_init,
 };
 
-static PCIDeviceInfo u3_agp_pci_host_info = {
-    .qdev.name = "u3-agp",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = u3_agp_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_APPLE,
-    .device_id = PCI_DEVICE_ID_APPLE_U3_AGP,
-    .revision  = 0x00,
-    .class_id  = PCI_CLASS_BRIDGE_HOST,
+static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init      = u3_agp_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_APPLE;
+    k->device_id = PCI_DEVICE_ID_APPLE_U3_AGP;
+    k->revision  = 0x00;
+    k->class_id  = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo u3_agp_pci_host_info = {
+    .name = "u3-agp",
+    .size = sizeof(PCIDevice),
+    .class_init = u3_agp_pci_host_class_init,
 };
 
-static PCIDeviceInfo unin_agp_pci_host_info = {
-    .qdev.name = "uni-north-agp",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = unin_agp_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_APPLE,
-    .device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP,
-    .revision  = 0x00,
-    .class_id  = PCI_CLASS_BRIDGE_HOST,
+static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init      = unin_agp_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_APPLE;
+    k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP;
+    k->revision  = 0x00;
+    k->class_id  = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo unin_agp_pci_host_info = {
+    .name = "uni-north-agp",
+    .size = sizeof(PCIDevice),
+    .class_init = unin_agp_pci_host_class_init,
 };
 
-static PCIDeviceInfo unin_internal_pci_host_info = {
-    .qdev.name = "uni-north-internal-pci",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = unin_internal_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_APPLE,
-    .device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI,
-    .revision  = 0x00,
-    .class_id  = PCI_CLASS_BRIDGE_HOST,
+static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init      = unin_internal_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_APPLE;
+    k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI;
+    k->revision  = 0x00;
+    k->class_id  = PCI_CLASS_BRIDGE_HOST;
+}
+
+static DeviceInfo unin_internal_pci_host_info = {
+    .name = "uni-north-internal-pci",
+    .size = sizeof(PCIDevice),
+    .class_init = unin_internal_pci_host_class_init,
 };
 
 static SysBusDeviceInfo sysbus_unin_pci_host_info = {
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 63fc3c7..8baff1d 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -2263,28 +2263,42 @@ static Property ehci_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo ehci_info = {
-    .qdev.name    = "usb-ehci",
-    .qdev.size    = sizeof(EHCIState),
-    .qdev.vmsd    = &vmstate_ehci,
-    .init         = usb_ehci_initfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82801D, /* ich4 */
-    .revision     = 0x10,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .qdev.props   = ehci_properties,
+static void ehci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_ehci_initfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82801D; /* ich4 */
+    k->revision = 0x10;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo ehci_info = {
+    .name = "usb-ehci",
+    .size = sizeof(EHCIState),
+    .vmsd = &vmstate_ehci,
+    .props = ehci_properties,
+    .class_init = ehci_class_init,
 };
 
-static PCIDeviceInfo ich9_ehci_info = {
-    .qdev.name    = "ich9-usb-ehci1",
-    .qdev.size    = sizeof(EHCIState),
-    .qdev.vmsd    = &vmstate_ehci,
-    .init         = usb_ehci_initfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82801I_EHCI1,
-    .revision     = 0x03,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .qdev.props   = ehci_properties,
+static void ich9_ehci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_ehci_initfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82801I_EHCI1;
+    k->revision = 0x03;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo ich9_ehci_info = {
+    .name = "ich9-usb-ehci1",
+    .size = sizeof(EHCIState),
+    .vmsd = &vmstate_ehci,
+    .props = ehci_properties,
+    .class_init = ich9_ehci_class_init,
 };
 
 static int usb_ehci_initfn(PCIDevice *dev)
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 2df6a6e..b9b37d5 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1836,20 +1836,29 @@ static int ohci_init_pxa(SysBusDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo ohci_pci_info = {
-    .qdev.name    = "pci-ohci",
-    .qdev.desc    = "Apple USB Controller",
-    .qdev.size    = sizeof(OHCIPCIState),
-    .init         = usb_ohci_initfn_pci,
-    .vendor_id    = PCI_VENDOR_ID_APPLE,
-    .device_id    = PCI_DEVICE_ID_APPLE_IPID_USB,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .qdev.props   = (Property[]) {
-        DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus),
-        DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3),
-        DEFINE_PROP_UINT32("firstport", OHCIPCIState, firstport, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property ohci_pci_properties[] = {
+    DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus),
+    DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3),
+    DEFINE_PROP_UINT32("firstport", OHCIPCIState, firstport, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ohci_pci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_ohci_initfn_pci;
+    k->vendor_id = PCI_VENDOR_ID_APPLE;
+    k->device_id = PCI_DEVICE_ID_APPLE_IPID_USB;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo ohci_pci_info = {
+    .name = "pci-ohci",
+    .desc = "Apple USB Controller",
+    .size = sizeof(OHCIPCIState),
+    .props = ohci_pci_properties,
+    .class_init = ohci_pci_class_init,
 };
 
 static SysBusDeviceInfo ohci_sysbus_info = {
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 1821063..e20d7c4 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1192,79 +1192,121 @@ static Property uhci_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo piix3_uhci_info = {
-        .qdev.name    = "piix3-usb-uhci",
-        .qdev.size    = sizeof(UHCIState),
-        .qdev.vmsd    = &vmstate_uhci,
-        .init         = usb_uhci_common_initfn,
-        .exit         = usb_uhci_exit,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371SB_2,
-        .revision     = 0x01,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = uhci_properties,
+static void piix3_uhci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_uhci_common_initfn;
+    k->exit = usb_uhci_exit;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82371SB_2;
+    k->revision = 0x01;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo piix3_uhci_info = {
+    .name = "piix3-usb-uhci",
+    .size = sizeof(UHCIState),
+    .vmsd = &vmstate_uhci,
+    .props = uhci_properties,
+    .class_init = piix3_uhci_class_init,
 };
 
-static PCIDeviceInfo piix4_uhci_info = {
-        .qdev.name    = "piix4-usb-uhci",
-        .qdev.size    = sizeof(UHCIState),
-        .qdev.vmsd    = &vmstate_uhci,
-        .init         = usb_uhci_common_initfn,
-        .exit         = usb_uhci_exit,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371AB_2,
-        .revision     = 0x01,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = uhci_properties,
+static void piix4_uhci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_uhci_common_initfn;
+    k->exit = usb_uhci_exit;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82371AB_2;
+    k->revision = 0x01;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo piix4_uhci_info = {
+    .name = "piix4-usb-uhci",
+    .size = sizeof(UHCIState),
+    .vmsd = &vmstate_uhci,
+    .props = uhci_properties,
+    .class_init = piix4_uhci_class_init,
 };
 
-static PCIDeviceInfo vt82c686b_uhci_info = {
-    .qdev.name    = "vt82c686b-usb-uhci",
-    .qdev.size    = sizeof(UHCIState),
-    .qdev.vmsd    = &vmstate_uhci,
-    .init         = usb_uhci_vt82c686b_initfn,
-    .exit         = usb_uhci_exit,
-    .vendor_id    = PCI_VENDOR_ID_VIA,
-    .device_id    = PCI_DEVICE_ID_VIA_UHCI,
-    .revision     = 0x01,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .qdev.props   = uhci_properties,
+static void vt82c686b_uhci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_uhci_vt82c686b_initfn;
+    k->exit = usb_uhci_exit;
+    k->vendor_id = PCI_VENDOR_ID_VIA;
+    k->device_id = PCI_DEVICE_ID_VIA_UHCI;
+    k->revision = 0x01;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo vt82c686b_uhci_info = {
+    .name = "vt82c686b-usb-uhci",
+    .size = sizeof(UHCIState),
+    .vmsd = &vmstate_uhci,
+    .props = uhci_properties,
+    .class_init = vt82c686b_uhci_class_init,
 };
 
-static PCIDeviceInfo ich9_uhci1_info = {
-    .qdev.name    = "ich9-usb-uhci1",
-    .qdev.size    = sizeof(UHCIState),
-    .qdev.vmsd    = &vmstate_uhci,
-    .init         = usb_uhci_common_initfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI1,
-    .revision     = 0x03,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .qdev.props   = uhci_properties,
+static void ich9_uhci1_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_uhci_common_initfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI1;
+    k->revision = 0x03;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo ich9_uhci1_info = {
+    .name = "ich9-usb-uhci1",
+    .size = sizeof(UHCIState),
+    .vmsd = &vmstate_uhci,
+    .props = uhci_properties,
+    .class_init = ich9_uhci1_class_init,
 };
 
-static PCIDeviceInfo ich9_uhci2_info = {
-    .qdev.name    = "ich9-usb-uhci2",
-    .qdev.size    = sizeof(UHCIState),
-    .qdev.vmsd    = &vmstate_uhci,
-    .init         = usb_uhci_common_initfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI2,
-    .revision     = 0x03,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .qdev.props   = uhci_properties,
+static void ich9_uhci2_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_uhci_common_initfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI2;
+    k->revision = 0x03;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo ich9_uhci2_info = {
+    .name = "ich9-usb-uhci2",
+    .size = sizeof(UHCIState),
+    .vmsd = &vmstate_uhci,
+    .props = uhci_properties,
+    .class_init = ich9_uhci2_class_init,
 };
 
-static PCIDeviceInfo ich9_uhci3_info = {
-    .qdev.name    = "ich9-usb-uhci3",
-    .qdev.size    = sizeof(UHCIState),
-    .qdev.vmsd    = &vmstate_uhci,
-    .init         = usb_uhci_common_initfn,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI3,
-    .revision     = 0x03,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .qdev.props   = uhci_properties,
+static void ich9_uhci3_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = usb_uhci_common_initfn;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI3;
+    k->revision = 0x03;
+    k->class_id = PCI_CLASS_SERIAL_USB;
+}
+
+static DeviceInfo ich9_uhci3_info = {
+    .name = "ich9-usb-uhci3",
+    .size = sizeof(UHCIState),
+    .vmsd = &vmstate_uhci,
+    .props = uhci_properties,
+    .class_init = ich9_uhci3_class_init,
 };
 
 static void uhci_register(void)
diff --git a/hw/usb-xhci.c b/hw/usb-xhci.c
index 95bf010..fba2de3 100644
--- a/hw/usb-xhci.c
+++ b/hw/usb-xhci.c
@@ -2724,19 +2724,26 @@ static const VMStateDescription vmstate_xhci = {
     .unmigratable = 1,
 };
 
-static PCIDeviceInfo xhci_info = {
-    .qdev.name    = "nec-usb-xhci",
-    .qdev.alias   = "xhci",
-    .qdev.size    = sizeof(XHCIState),
-    .qdev.vmsd    = &vmstate_xhci,
-    .init         = usb_xhci_initfn,
-    .vendor_id    = PCI_VENDOR_ID_NEC,
-    .device_id    = PCI_DEVICE_ID_NEC_UPD720200,
-    .class_id     = PCI_CLASS_SERIAL_USB,
-    .revision     = 0x03,
-    .is_express   = 1,
-    .config_write = xhci_write_config,
-    .qdev.props   = (Property[]) {
+static void xhci_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init         = usb_xhci_initfn;
+    k->vendor_id    = PCI_VENDOR_ID_NEC;
+    k->device_id    = PCI_DEVICE_ID_NEC_UPD720200;
+    k->class_id     = PCI_CLASS_SERIAL_USB;
+    k->revision     = 0x03;
+    k->is_express   = 1;
+    k->config_write = xhci_write_config;
+}
+
+static DeviceInfo xhci_info = {
+    .name    = "nec-usb-xhci",
+    .alias   = "xhci",
+    .size    = sizeof(XHCIState),
+    .vmsd    = &vmstate_xhci,
+    .class_init   = xhci_class_init,
+    .props   = (Property[]) {
         DEFINE_PROP_UINT32("msi", XHCIState, msi, 0),
         DEFINE_PROP_END_OF_LIST(),
     }
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index a285f7f..0eb7d32 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -109,14 +109,20 @@ static int versatile_pci_host_init(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo versatile_pci_host_info = {
-    .qdev.name = "versatile_pci_host",
-    .qdev.size = sizeof(PCIDevice),
-    .init      = versatile_pci_host_init,
-    .vendor_id = PCI_VENDOR_ID_XILINX,
-    /* Both boards have the same device ID.  Oh well.  */
-    .device_id = PCI_DEVICE_ID_XILINX_XC2VP30,
-    .class_id  = PCI_CLASS_PROCESSOR_CO,
+static void versatile_pci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = versatile_pci_host_init;
+    k->vendor_id = PCI_VENDOR_ID_XILINX;
+    k->device_id = PCI_DEVICE_ID_XILINX_XC2VP30;
+    k->class_id = PCI_CLASS_PROCESSOR_CO;
+}
+
+static DeviceInfo versatile_pci_host_info = {
+    .name = "versatile_pci_host",
+    .size = sizeof(PCIDevice),
+    .class_init = versatile_pci_host_class_init,
 };
 
 static void versatile_pci_register_devices(void)
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index a75dbf3..ef9f8a5 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -75,18 +75,23 @@ DeviceState *pci_vga_init(PCIBus *bus)
     return &pci_create_simple(bus, -1, "VGA")->qdev;
 }
 
-static PCIDeviceInfo vga_info = {
-    .qdev.name    = "VGA",
-    .qdev.size    = sizeof(PCIVGAState),
-    .qdev.vmsd    = &vmstate_vga_pci,
-    .no_hotplug   = 1,
-    .init         = pci_vga_initfn,
-    .romfile      = "vgabios-stdvga.bin",
+static void vga_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = pci_vga_initfn;
+    k->romfile = "vgabios-stdvga.bin";
+    k->vendor_id = PCI_VENDOR_ID_QEMU;
+    k->device_id = PCI_DEVICE_ID_QEMU_VGA;
+    k->class_id = PCI_CLASS_DISPLAY_VGA;
+}
 
-    /* dummy VGA (same as Bochs ID) */
-    .vendor_id    = PCI_VENDOR_ID_QEMU,
-    .device_id    = PCI_DEVICE_ID_QEMU_VGA,
-    .class_id     = PCI_CLASS_DISPLAY_VGA,
+static DeviceInfo vga_info = {
+    .name = "VGA",
+    .size = sizeof(PCIVGAState),
+    .vmsd = &vmstate_vga_pci,
+    .class_init = vga_class_init,
 };
 
 static void vga_register(void)
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 72b53af..126fb08 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -806,88 +806,124 @@ static int virtio_balloon_exit_pci(PCIDevice *pci_dev)
     return virtio_exit_pci(pci_dev);
 }
 
-static PCIDeviceInfo virtio_blk_info = {
-    .qdev.name = "virtio-blk-pci",
-    .qdev.alias = "virtio-blk",
-    .qdev.size = sizeof(VirtIOPCIProxy),
-    .init      = virtio_blk_init_pci,
-    .exit      = virtio_blk_exit_pci,
-    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
-    .device_id = PCI_DEVICE_ID_VIRTIO_BLOCK,
-    .revision  = VIRTIO_PCI_ABI_VERSION,
-    .class_id  = PCI_CLASS_STORAGE_SCSI,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
-        DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
-        DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial),
-        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
-        DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
-        DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
-        DEFINE_PROP_END_OF_LIST(),
-    },
-    .qdev.reset = virtio_pci_reset,
+static Property virtio_blk_properties[] = {
+    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
+    DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
+    DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial),
+    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
+    DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo virtio_net_info = {
-    .qdev.name  = "virtio-net-pci",
-    .qdev.alias = "virtio-net",
-    .qdev.size  = sizeof(VirtIOPCIProxy),
-    .init       = virtio_net_init_pci,
-    .exit       = virtio_net_exit_pci,
-    .romfile    = "pxe-virtio.rom",
-    .vendor_id  = PCI_VENDOR_ID_REDHAT_QUMRANET,
-    .device_id  = PCI_DEVICE_ID_VIRTIO_NET,
-    .revision   = VIRTIO_PCI_ABI_VERSION,
-    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
-        DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
-        DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
-        DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
-        DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy, net.txtimer, TX_TIMER_INTERVAL),
-        DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy, net.txburst, TX_BURST),
-        DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx),
-        DEFINE_PROP_END_OF_LIST(),
-    },
-    .qdev.reset = virtio_pci_reset,
+static void virtio_blk_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_blk_init_pci;
+    k->exit = virtio_blk_exit_pci;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = PCI_DEVICE_ID_VIRTIO_BLOCK;
+    k->revision = VIRTIO_PCI_ABI_VERSION;
+    k->class_id = PCI_CLASS_STORAGE_SCSI;
+}
+
+static DeviceInfo virtio_blk_info = {
+    .name = "virtio-blk-pci",
+    .alias = "virtio-blk",
+    .size = sizeof(VirtIOPCIProxy),
+    .props = virtio_blk_properties,
+    .reset = virtio_pci_reset,
+    .class_init = virtio_blk_class_init,
+};
+
+static Property virtio_net_properties[] = {
+    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
+    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
+    DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
+    DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
+    DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy, net.txtimer, TX_TIMER_INTERVAL),
+    DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy, net.txburst, TX_BURST),
+    DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_net_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_net_init_pci;
+    k->exit = virtio_net_exit_pci;
+    k->romfile = "pxe-virtio.rom";
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = PCI_DEVICE_ID_VIRTIO_NET;
+    k->revision = VIRTIO_PCI_ABI_VERSION;
+    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+}
+
+static DeviceInfo virtio_net_info = {
+    .name = "virtio-net-pci",
+    .alias = "virtio-net",
+    .size = sizeof(VirtIOPCIProxy),
+    .props = virtio_net_properties,
+    .reset = virtio_pci_reset,
+    .class_init = virtio_net_class_init,
 };
 
-static PCIDeviceInfo virtio_serial_info = {
-    .qdev.name = "virtio-serial-pci",
-    .qdev.alias = "virtio-serial",
-    .qdev.size = sizeof(VirtIOPCIProxy),
-    .init      = virtio_serial_init_pci,
-    .exit      = virtio_serial_exit_pci,
-    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
-    .device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE,
-    .revision  = VIRTIO_PCI_ABI_VERSION,
-    .class_id  = PCI_CLASS_COMMUNICATION_OTHER,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
-        DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, DEV_NVECTORS_UNSPECIFIED),
-        DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
-        DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-        DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, serial.max_virtserial_ports, 31),
-        DEFINE_PROP_END_OF_LIST(),
-    },
-    .qdev.reset = virtio_pci_reset,
+static Property virtio_serial_properties[] = {
+    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, DEV_NVECTORS_UNSPECIFIED),
+    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
+    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+    DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, serial.max_virtserial_ports, 31),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo virtio_balloon_info = {
-    .qdev.name = "virtio-balloon-pci",
-    .qdev.alias = "virtio-balloon",
-    .qdev.size = sizeof(VirtIOPCIProxy),
-    .init      = virtio_balloon_init_pci,
-    .exit      = virtio_balloon_exit_pci,
-    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
-    .device_id = PCI_DEVICE_ID_VIRTIO_BALLOON,
-    .revision  = VIRTIO_PCI_ABI_VERSION,
-    .class_id  = PCI_CLASS_MEMORY_RAM,
-    .qdev.props = (Property[]) {
-        DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-        DEFINE_PROP_END_OF_LIST(),
-    },
-    .qdev.reset = virtio_pci_reset,
+static void virtio_serial_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_serial_init_pci;
+    k->exit = virtio_serial_exit_pci;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE;
+    k->revision = VIRTIO_PCI_ABI_VERSION;
+    k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
+}
+
+static DeviceInfo virtio_serial_info = {
+    .name = "virtio-serial-pci",
+    .alias = "virtio-serial",
+    .size = sizeof(VirtIOPCIProxy),
+    .props = virtio_serial_properties,
+    .reset = virtio_pci_reset,
+    .class_init = virtio_serial_class_init,
+};
+
+static Property virtio_balloon_properties[] = {
+    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_balloon_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_balloon_init_pci;
+    k->exit = virtio_balloon_exit_pci;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = PCI_DEVICE_ID_VIRTIO_BALLOON;
+    k->revision = VIRTIO_PCI_ABI_VERSION;
+    k->class_id = PCI_CLASS_MEMORY_RAM;
+}
+
+static DeviceInfo virtio_balloon_info = {
+    .name = "virtio-balloon-pci",
+    .alias = "virtio-balloon",
+    .size = sizeof(VirtIOPCIProxy),
+    .props = virtio_balloon_properties,
+    .reset = virtio_pci_reset,
+    .class_init = virtio_balloon_class_init,
 };
 
 static void virtio_pci_register_devices(void)
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index b1885c3..e7bbf7c 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1199,20 +1199,26 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo vmsvga_info = {
-    .qdev.name    = "vmware-svga",
-    .qdev.size    = sizeof(struct pci_vmsvga_state_s),
-    .qdev.vmsd    = &vmstate_vmware_vga,
-    .qdev.reset   = vmsvga_reset,
-    .no_hotplug   = 1,
-    .init         = pci_vmsvga_initfn,
-    .romfile      = "vgabios-vmware.bin",
-
-    .vendor_id    =  PCI_VENDOR_ID_VMWARE,
-    .device_id    = SVGA_PCI_DEVICE_ID,
-    .class_id     = PCI_CLASS_DISPLAY_VGA,
-    .subsystem_vendor_id = PCI_VENDOR_ID_VMWARE,
-    .subsystem_id = SVGA_PCI_DEVICE_ID,
+static void vmsvga_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->no_hotplug = 1;
+    k->init = pci_vmsvga_initfn;
+    k->romfile = "vgabios-vmware.bin";
+    k->vendor_id = PCI_VENDOR_ID_VMWARE;
+    k->device_id = SVGA_PCI_DEVICE_ID;
+    k->class_id = PCI_CLASS_DISPLAY_VGA;
+    k->subsystem_vendor_id = PCI_VENDOR_ID_VMWARE;
+    k->subsystem_id = SVGA_PCI_DEVICE_ID;
+}
+
+static DeviceInfo vmsvga_info = {
+    .name = "vmware-svga",
+    .size = sizeof(struct pci_vmsvga_state_s),
+    .vmsd = &vmstate_vmware_vga,
+    .reset = vmsvga_reset,
+    .class_init = vmsvga_class_init,
 };
 
 static void vmsvga_register(void)
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 7fb88a5..72be4fd 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -346,15 +346,22 @@ void vt82c686b_ac97_init(PCIBus *bus, int devfn)
     qdev_init_nofail(&dev->qdev);
 }
 
-static PCIDeviceInfo via_ac97_info = {
-    .qdev.name          = "VT82C686B_AC97",
-    .qdev.desc          = "AC97",
-    .qdev.size          = sizeof(VT686AC97State),
-    .init               = vt82c686b_ac97_initfn,
-    .vendor_id          = PCI_VENDOR_ID_VIA,
-    .device_id          = PCI_DEVICE_ID_VIA_AC97,
-    .revision           = 0x50,
-    .class_id           = PCI_CLASS_MULTIMEDIA_AUDIO,
+static void via_ac97_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = vt82c686b_ac97_initfn;
+    k->vendor_id = PCI_VENDOR_ID_VIA;
+    k->device_id = PCI_DEVICE_ID_VIA_AC97;
+    k->revision = 0x50;
+    k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+}
+
+static DeviceInfo via_ac97_info = {
+    .name = "VT82C686B_AC97",
+    .desc = "AC97",
+    .size = sizeof(VT686AC97State),
+    .class_init = via_ac97_class_init,
 };
 
 static void vt82c686b_ac97_register(void)
@@ -385,15 +392,22 @@ void vt82c686b_mc97_init(PCIBus *bus, int devfn)
     qdev_init_nofail(&dev->qdev);
 }
 
-static PCIDeviceInfo via_mc97_info = {
-    .qdev.name          = "VT82C686B_MC97",
-    .qdev.desc          = "MC97",
-    .qdev.size          = sizeof(VT686MC97State),
-    .init               = vt82c686b_mc97_initfn,
-    .vendor_id          = PCI_VENDOR_ID_VIA,
-    .device_id          = PCI_DEVICE_ID_VIA_MC97,
-    .class_id           = PCI_CLASS_COMMUNICATION_OTHER,
-    .revision           = 0x30,
+static void via_mc97_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = vt82c686b_mc97_initfn;
+    k->vendor_id = PCI_VENDOR_ID_VIA;
+    k->device_id = PCI_DEVICE_ID_VIA_MC97;
+    k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
+    k->revision = 0x30;
+}
+
+static DeviceInfo via_mc97_info = {
+    .name = "VT82C686B_MC97",
+    .desc = "MC97",
+    .size = sizeof(VT686MC97State),
+    .class_init = via_mc97_class_init,
 };
 
 static void vt82c686b_mc97_register(void)
@@ -451,21 +465,30 @@ i2c_bus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
     return s->smb.smbus;
 }
 
-static PCIDeviceInfo via_pm_info = {
-    .qdev.name          = "VT82C686B_PM",
-    .qdev.desc          = "PM",
-    .qdev.size          = sizeof(VT686PMState),
-    .qdev.vmsd          = &vmstate_acpi,
-    .init               = vt82c686b_pm_initfn,
-    .config_write       = pm_write_config,
-    .vendor_id          = PCI_VENDOR_ID_VIA,
-    .device_id          = PCI_DEVICE_ID_VIA_ACPI,
-    .class_id           = PCI_CLASS_BRIDGE_OTHER,
-    .revision           = 0x40,
-    .qdev.props         = (Property[]) {
-        DEFINE_PROP_UINT32("smb_io_base", VT686PMState, smb_io_base, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property via_pm_properties[] = {
+    DEFINE_PROP_UINT32("smb_io_base", VT686PMState, smb_io_base, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void via_pm_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = vt82c686b_pm_initfn;
+    k->config_write = pm_write_config;
+    k->vendor_id = PCI_VENDOR_ID_VIA;
+    k->device_id = PCI_DEVICE_ID_VIA_ACPI;
+    k->class_id = PCI_CLASS_BRIDGE_OTHER;
+    k->revision = 0x40;
+}
+
+static DeviceInfo via_pm_info = {
+    .name = "VT82C686B_PM",
+    .desc = "PM",
+    .size = sizeof(VT686PMState),
+    .vmsd = &vmstate_acpi,
+    .props = via_pm_properties,
+    .class_init = via_pm_class_init,
 };
 
 static void vt82c686b_pm_register(void)
@@ -519,18 +542,25 @@ ISABus *vt82c686b_init(PCIBus *bus, int devfn)
     return DO_UPCAST(ISABus, qbus, qdev_get_child_bus(&d->qdev, "isa.0"));
 }
 
-static PCIDeviceInfo via_info = {
-    .qdev.name    = "VT82C686B",
-    .qdev.desc    = "ISA bridge",
-    .qdev.size    = sizeof(VT82C686BState),
-    .qdev.vmsd    = &vmstate_via,
-    .qdev.no_user = 1,
-    .init         = vt82c686b_initfn,
-    .config_write = vt82c686b_write_config,
-    .vendor_id    = PCI_VENDOR_ID_VIA,
-    .device_id    = PCI_DEVICE_ID_VIA_ISA_BRIDGE,
-    .class_id     = PCI_CLASS_BRIDGE_ISA,
-    .revision     = 0x40,
+static void via_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = vt82c686b_initfn;
+    k->config_write = vt82c686b_write_config;
+    k->vendor_id = PCI_VENDOR_ID_VIA;
+    k->device_id = PCI_DEVICE_ID_VIA_ISA_BRIDGE;
+    k->class_id = PCI_CLASS_BRIDGE_ISA;
+    k->revision = 0x40;
+}
+
+static DeviceInfo via_info = {
+    .name = "VT82C686B",
+    .desc = "ISA bridge",
+    .size = sizeof(VT82C686BState),
+    .vmsd = &vmstate_via,
+    .no_user = 1,
+    .class_init = via_class_init,
 };
 
 static void vt82c686b_register(void)
diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c
index 20d8673..a6ceff8 100644
--- a/hw/wdt_i6300esb.c
+++ b/hw/wdt_i6300esb.c
@@ -143,7 +143,7 @@ static void i6300esb_disable_timer(I6300State *d)
 
 static void i6300esb_reset(DeviceState *dev)
 {
-    PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, dev);
+    PCIDevice *pdev = PCI_DEVICE(dev);
     I6300State *d = DO_UPCAST(I6300State, dev, pdev);
 
     i6300esb_debug("I6300State = %p\n", d);
@@ -425,18 +425,25 @@ static WatchdogTimerModel model = {
     .wdt_description = "Intel 6300ESB",
 };
 
-static PCIDeviceInfo i6300esb_info = {
-    .qdev.name    = "i6300esb",
-    .qdev.size    = sizeof(I6300State),
-    .qdev.vmsd    = &vmstate_i6300esb,
-    .qdev.reset   = i6300esb_reset,
-    .config_read  = i6300esb_config_read,
-    .config_write = i6300esb_config_write,
-    .init         = i6300esb_init,
-    .exit         = i6300esb_exit,
-    .vendor_id    = PCI_VENDOR_ID_INTEL,
-    .device_id    = PCI_DEVICE_ID_INTEL_ESB_9,
-    .class_id     = PCI_CLASS_SYSTEM_OTHER,
+static void i6300esb_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->config_read = i6300esb_config_read;
+    k->config_write = i6300esb_config_write;
+    k->init = i6300esb_init;
+    k->exit = i6300esb_exit;
+    k->vendor_id = PCI_VENDOR_ID_INTEL;
+    k->device_id = PCI_DEVICE_ID_INTEL_ESB_9;
+    k->class_id = PCI_CLASS_SYSTEM_OTHER;
+}
+
+static DeviceInfo i6300esb_info = {
+    .name = "i6300esb",
+    .size = sizeof(I6300State),
+    .vmsd = &vmstate_i6300esb,
+    .reset = i6300esb_reset,
+    .class_init = i6300esb_class_init,
 };
 
 static void i6300esb_register_devices(void)
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index e62eaef..40687fb 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -372,20 +372,26 @@ static void platform_reset(DeviceState *dev)
     platform_fixed_ioport_reset(s);
 }
 
-static PCIDeviceInfo xen_platform_info = {
-    .init = xen_platform_initfn,
-    .qdev.name = "xen-platform",
-    .qdev.desc = "XEN platform pci device",
-    .qdev.size = sizeof(PCIXenPlatformState),
-    .qdev.vmsd = &vmstate_xen_platform,
-    .qdev.reset = platform_reset,
-
-    .vendor_id    =  PCI_VENDOR_ID_XEN,
-    .device_id    = PCI_DEVICE_ID_XEN_PLATFORM,
-    .class_id     = PCI_CLASS_OTHERS << 8 | 0x80,
-    .subsystem_vendor_id = PCI_VENDOR_ID_XEN,
-    .subsystem_id = PCI_DEVICE_ID_XEN_PLATFORM,
-    .revision = 1,
+static void xen_platform_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = xen_platform_initfn;
+    k->vendor_id = PCI_VENDOR_ID_XEN;
+    k->device_id = PCI_DEVICE_ID_XEN_PLATFORM;
+    k->class_id = PCI_CLASS_OTHERS << 8 | 0x80;
+    k->subsystem_vendor_id = PCI_VENDOR_ID_XEN;
+    k->subsystem_id = PCI_DEVICE_ID_XEN_PLATFORM;
+    k->revision = 1;
+}
+
+static DeviceInfo xen_platform_info = {
+    .name = "xen-platform",
+    .desc = "XEN platform pci device",
+    .size = sizeof(PCIXenPlatformState),
+    .vmsd = &vmstate_xen_platform,
+    .reset = platform_reset,
+    .class_init = xen_platform_class_init,
 };
 
 static void xen_platform_register(void)
diff --git a/hw/xio3130_downstream.c b/hw/xio3130_downstream.c
index d3c387d..6d625cb 100644
--- a/hw/xio3130_downstream.c
+++ b/hw/xio3130_downstream.c
@@ -47,7 +47,7 @@ static void xio3130_downstream_write_config(PCIDevice *d, uint32_t address,
 
 static void xio3130_downstream_reset(DeviceState *qdev)
 {
-    PCIDevice *d = DO_UPCAST(PCIDevice, qdev, qdev);
+    PCIDevice *d = PCI_DEVICE(qdev);
     msi_reset(d);
     pcie_cap_deverr_reset(d);
     pcie_cap_slot_reset(d);
@@ -167,31 +167,38 @@ static const VMStateDescription vmstate_xio3130_downstream = {
     }
 };
 
-static PCIDeviceInfo xio3130_downstream_info = {
-    .qdev.name = "xio3130-downstream",
-    .qdev.desc = "TI X3130 Downstream Port of PCI Express Switch",
-    .qdev.size = sizeof(PCIESlot),
-    .qdev.reset = xio3130_downstream_reset,
-    .qdev.vmsd = &vmstate_xio3130_downstream,
-
-    .is_express = 1,
-    .is_bridge = 1,
-    .config_write = xio3130_downstream_write_config,
-    .init = xio3130_downstream_initfn,
-    .exit = xio3130_downstream_exitfn,
-    .vendor_id = PCI_VENDOR_ID_TI,
-    .device_id = PCI_DEVICE_ID_TI_XIO3130D,
-    .revision = XIO3130_REVISION,
-
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT8("port", PCIESlot, port.port, 0),
-        DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
-        DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
-        DEFINE_PROP_UINT16("aer_log_max", PCIESlot,
-                           port.br.dev.exp.aer_log.log_max,
-                           PCIE_AER_LOG_MAX_DEFAULT),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property xio3130_downstream_properties[] = {
+    DEFINE_PROP_UINT8("port", PCIESlot, port.port, 0),
+    DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
+    DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
+    DEFINE_PROP_UINT16("aer_log_max", PCIESlot,
+    port.br.dev.exp.aer_log.log_max,
+    PCIE_AER_LOG_MAX_DEFAULT),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void xio3130_downstream_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->is_express = 1;
+    k->is_bridge = 1;
+    k->config_write = xio3130_downstream_write_config;
+    k->init = xio3130_downstream_initfn;
+    k->exit = xio3130_downstream_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_TI;
+    k->device_id = PCI_DEVICE_ID_TI_XIO3130D;
+    k->revision = XIO3130_REVISION;
+}
+
+static DeviceInfo xio3130_downstream_info = {
+    .name = "xio3130-downstream",
+    .desc = "TI X3130 Downstream Port of PCI Express Switch",
+    .size = sizeof(PCIESlot),
+    .reset = xio3130_downstream_reset,
+    .vmsd = &vmstate_xio3130_downstream,
+    .props = xio3130_downstream_properties,
+    .class_init = xio3130_downstream_class_init,
 };
 
 static void xio3130_downstream_register(void)
diff --git a/hw/xio3130_upstream.c b/hw/xio3130_upstream.c
index 8283695..ec4c5e3 100644
--- a/hw/xio3130_upstream.c
+++ b/hw/xio3130_upstream.c
@@ -46,7 +46,7 @@ static void xio3130_upstream_write_config(PCIDevice *d, uint32_t address,
 
 static void xio3130_upstream_reset(DeviceState *qdev)
 {
-    PCIDevice *d = DO_UPCAST(PCIDevice, qdev, qdev);
+    PCIDevice *d = PCI_DEVICE(qdev);
     msi_reset(d);
     pci_bridge_reset(qdev);
     pcie_cap_deverr_reset(d);
@@ -144,28 +144,35 @@ static const VMStateDescription vmstate_xio3130_upstream = {
     }
 };
 
-static PCIDeviceInfo xio3130_upstream_info = {
-    .qdev.name = "x3130-upstream",
-    .qdev.desc = "TI X3130 Upstream Port of PCI Express Switch",
-    .qdev.size = sizeof(PCIEPort),
-    .qdev.reset = xio3130_upstream_reset,
-    .qdev.vmsd = &vmstate_xio3130_upstream,
-
-    .is_express = 1,
-    .is_bridge = 1,
-    .config_write = xio3130_upstream_write_config,
-    .init = xio3130_upstream_initfn,
-    .exit = xio3130_upstream_exitfn,
-    .vendor_id = PCI_VENDOR_ID_TI,
-    .device_id = PCI_DEVICE_ID_TI_XIO3130U,
-    .revision = XIO3130_REVISION,
-
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT8("port", PCIEPort, port, 0),
-        DEFINE_PROP_UINT16("aer_log_max", PCIEPort, br.dev.exp.aer_log.log_max,
-                           PCIE_AER_LOG_MAX_DEFAULT),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property xio3130_upstream_properties[] = {
+    DEFINE_PROP_UINT8("port", PCIEPort, port, 0),
+    DEFINE_PROP_UINT16("aer_log_max", PCIEPort, br.dev.exp.aer_log.log_max,
+    PCIE_AER_LOG_MAX_DEFAULT),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void xio3130_upstream_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->is_express = 1;
+    k->is_bridge = 1;
+    k->config_write = xio3130_upstream_write_config;
+    k->init = xio3130_upstream_initfn;
+    k->exit = xio3130_upstream_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_TI;
+    k->device_id = PCI_DEVICE_ID_TI_XIO3130U;
+    k->revision = XIO3130_REVISION;
+}
+
+static DeviceInfo xio3130_upstream_info = {
+    .name = "x3130-upstream",
+    .desc = "TI X3130 Upstream Port of PCI Express Switch",
+    .size = sizeof(PCIEPort),
+    .reset = xio3130_upstream_reset,
+    .vmsd = &vmstate_xio3130_upstream,
+    .props = xio3130_upstream_properties,
+    .class_init = xio3130_upstream_class_init,
 };
 
 static void xio3130_upstream_register(void)
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (25 preceding siblings ...)
  2012-01-24 19:33   ` Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 20:01   ` Jan Kiszka
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 28/28] virtio-s390: " Anthony Liguori
                   ` (3 subsequent siblings)
  30 siblings, 1 reply; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Anthony Liguori, Michael S. Tsirkin,
	Alexander Graf, Blue Swirl, Andreas Färber, Jan Kiszka,
	Paul Brook, qemu-ppc, Aurelien Jarno, Gerd Hoffmann

This converts three devices because apic and ioapic are subclasses of sysbus.
Converting subclasses independently of their base class is prohibitively hard.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/a9mpcore.c              |   21 ++++--
 hw/alpha_typhoon.c         |   17 ++++--
 hw/apb_pci.c               |   17 ++++--
 hw/apic.c                  |   21 ++++--
 hw/apic_common.c           |   88 ++++++++++++++++---------
 hw/apic_internal.h         |   32 ++++++----
 hw/arm11mpcore.c           |   68 +++++++++++++-------
 hw/arm_l2x0.c              |   25 +++++---
 hw/arm_mptimer.c           |   23 +++++---
 hw/arm_sysctl.c            |   31 ++++++---
 hw/arm_timer.c             |   46 ++++++++++----
 hw/armv7m.c                |   25 +++++---
 hw/armv7m_nvic.c           |   21 ++++--
 hw/bitbang_i2c.c           |   17 ++++--
 hw/bonito.c                |   17 ++++--
 hw/container.c             |   17 ++++--
 hw/cs4231.c                |   27 +++++---
 hw/dec_pci.c               |   19 +++++-
 hw/ds1225y.c               |   29 ++++++---
 hw/eccmemctl.c             |   29 ++++++---
 hw/empty_slot.c            |   15 +++-
 hw/escc.c                  |   43 ++++++++-----
 hw/esp.c                   |   27 +++++---
 hw/etraxfs_eth.c           |   31 ++++++---
 hw/etraxfs_pic.c           |   25 +++++---
 hw/etraxfs_ser.c           |   17 ++++--
 hw/etraxfs_timer.c         |   16 ++++-
 hw/fdc.c                   |   60 +++++++++++------
 hw/fw_cfg.c                |   33 ++++++----
 hw/g364fb.c                |   33 ++++++----
 hw/grackle_pci.c           |   19 ++++--
 hw/grlib_apbuart.c         |   25 +++++---
 hw/grlib_gptimer.c         |   31 ++++++---
 hw/grlib_irqmp.c           |   29 ++++++---
 hw/gt64xxx.c               |   16 ++++-
 hw/hpet.c                  |   33 ++++++----
 hw/integratorcp.c          |   40 +++++++++---
 hw/ioapic.c                |   17 ++++--
 hw/ioapic_common.c         |   49 ++++++++++----
 hw/ioapic_internal.h       |   26 +++++---
 hw/isa-bus.c               |   19 ++++--
 hw/kvm/apic.c              |   19 ++++--
 hw/kvm/clock.c             |   19 ++++--
 hw/kvm/ioapic.c            |   23 +++++---
 hw/lan9118.c               |   29 ++++++---
 hw/lance.c                 |   33 ++++++----
 hw/lm32_juart.c            |   19 ++++--
 hw/lm32_pic.c              |   19 ++++--
 hw/lm32_sys.c              |   29 ++++++---
 hw/lm32_timer.c            |   31 ++++++----
 hw/lm32_uart.c             |   19 ++++--
 hw/m48t59.c                |   31 ++++++---
 hw/marvell_88w8618_audio.c |   29 ++++++---
 hw/milkymist-ac97.c        |   19 ++++--
 hw/milkymist-hpdmc.c       |   19 ++++--
 hw/milkymist-memcard.c     |   19 ++++--
 hw/milkymist-minimac2.c    |   35 +++++++----
 hw/milkymist-pfpu.c        |   19 ++++--
 hw/milkymist-softusb.c     |   43 +++++++------
 hw/milkymist-sysctl.c      |   43 ++++++++-----
 hw/milkymist-tmu2.c        |   19 ++++--
 hw/milkymist-uart.c        |   19 ++++--
 hw/milkymist-vgafb.c       |   31 ++++++---
 hw/mips_malta.c            |   19 ++++--
 hw/mipsnet.c               |   31 ++++++---
 hw/mpc8544_guts.c          |   15 +++-
 hw/mst_fpga.c              |   19 ++++--
 hw/musicpal.c              |  151 +++++++++++++++++++++++++++++++-------------
 hw/nand.c                  |   33 ++++++----
 hw/omap_gpio.c             |   70 +++++++++++++--------
 hw/omap_intc.c             |   62 ++++++++++++-------
 hw/onenand.c               |   35 +++++++----
 hw/opencores_eth.c         |   29 ++++++---
 hw/piix_pci.c              |   19 ++++--
 hw/pl011.c                 |   36 +++++++++--
 hw/pl022.c                 |   15 ++++-
 hw/pl031.c                 |   19 ++++--
 hw/pl041.c                 |   34 ++++++----
 hw/pl050.c                 |   34 +++++++---
 hw/pl061.c                 |   34 +++++++---
 hw/pl080.c                 |   38 ++++++++----
 hw/pl110.c                 |   57 +++++++++++-----
 hw/pl181.c                 |   23 +++++---
 hw/pl190.c                 |   21 ++++--
 hw/ppc4xx_pci.c            |   17 ++++--
 hw/ppce500_pci.c           |   17 ++++--
 hw/ppce500_spin.c          |   15 +++-
 hw/prep_pci.c              |   19 ++++--
 hw/pxa2xx.c                |   69 ++++++++++++++------
 hw/pxa2xx_dma.c            |   29 ++++++---
 hw/pxa2xx_gpio.c           |   29 ++++++---
 hw/pxa2xx_pic.c            |   19 ++++--
 hw/pxa2xx_timer.c          |   66 ++++++++++++-------
 hw/realview.c              |   15 +++-
 hw/realview_gic.c          |   16 ++++-
 hw/s390-virtio-bus.c       |   17 ++++--
 hw/sbi.c                   |   19 ++++--
 hw/sh_pci.c                |   18 +++++-
 hw/slavio_intctl.c         |   19 ++++--
 hw/slavio_misc.c           |   34 +++++++---
 hw/slavio_timer.c          |   29 ++++++---
 hw/smc91c111.c             |   29 ++++++---
 hw/spapr_pci.c             |   16 ++++-
 hw/spapr_vio.c             |   17 ++++--
 hw/sparc32_dma.c           |   31 ++++++---
 hw/spitz.c                 |   55 +++++++++++------
 hw/stellaris.c             |   48 ++++++++++++--
 hw/stellaris_enet.c        |   25 +++++---
 hw/strongarm.c             |  124 ++++++++++++++++++++++++------------
 hw/sun4c_intctl.c          |   19 ++++--
 hw/sun4m.c                 |   78 ++++++++++++++++-------
 hw/sun4m_iommu.c           |   29 ++++++---
 hw/sun4u.c                 |   48 ++++++++++-----
 hw/sysbus.c                |   40 +++++++-----
 hw/sysbus.h                |   25 +++++---
 hw/tcx.c                   |   37 +++++++----
 hw/tusb6010.c              |   17 ++++--
 hw/unin_pci.c              |   72 ++++++++++++++-------
 hw/usb-ohci.c              |   19 ++++--
 hw/versatile_pci.c         |   31 ++++++++-
 hw/versatilepb.c           |   19 ++++--
 hw/xilinx_axidma.c         |   27 +++++---
 hw/xilinx_axienet.c        |   33 ++++++----
 hw/xilinx_ethlite.c        |   29 ++++++---
 hw/xilinx_intc.c           |   25 +++++---
 hw/xilinx_timer.c          |   27 +++++---
 hw/xilinx_uartlite.c       |   16 ++++-
 hw/zaurus.c                |   27 +++++---
 128 files changed, 2691 insertions(+), 1273 deletions(-)

diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index 521b8cc..b42c475 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -208,13 +208,20 @@ static const VMStateDescription vmstate_a9mp_priv = {
     }
 };
 
-static SysBusDeviceInfo a9mp_priv_info = {
-    .init = a9mp_priv_init,
-    .qdev.name  = "a9mpcore_priv",
-    .qdev.size  = sizeof(a9mp_priv_state),
-    .qdev.vmsd = &vmstate_a9mp_priv,
-    .qdev.reset = a9mp_priv_reset,
-    .qdev.props = (Property[]) {
+static void a9mp_priv_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = a9mp_priv_init;
+}
+
+static DeviceInfo a9mp_priv_info = {
+    .name = "a9mpcore_priv",
+    .size  = sizeof(a9mp_priv_state),
+    .vmsd = &vmstate_a9mp_priv,
+    .reset = a9mp_priv_reset,
+    .class_init = a9mp_priv_class_init,
+    .props = (Property[]) {
         DEFINE_PROP_UINT32("num-cpu", a9mp_priv_state, num_cpu, 1),
         /* The Cortex-A9MP may have anything from 0 to 224 external interrupt
          * IRQ lines (with another 32 internal). We default to 64+32, which
diff --git a/hw/alpha_typhoon.c b/hw/alpha_typhoon.c
index 7d924a3..8a68c7c 100644
--- a/hw/alpha_typhoon.c
+++ b/hw/alpha_typhoon.c
@@ -808,11 +808,18 @@ static int typhoon_pcihost_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo typhoon_pcihost_info = {
-    .init = typhoon_pcihost_init,
-    .qdev.name = "typhoon-pcihost",
-    .qdev.size = sizeof(TyphoonState),
-    .qdev.no_user = 1
+static void typhoon_pcihost_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = typhoon_pcihost_init;
+}
+
+static DeviceInfo typhoon_pcihost_info = {
+    .name = "typhoon-pcihost",
+    .size = sizeof(TyphoonState),
+    .no_user = 1,
+    .class_init = typhoon_pcihost_class_init,
 };
 
 static void typhoon_register(void)
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 70cfc77..173dab3 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -453,11 +453,18 @@ static DeviceInfo pbm_pci_host_info = {
     .class_init = pbm_pci_host_class_init,
 };
 
-static SysBusDeviceInfo pbm_host_info = {
-    .qdev.name = "pbm",
-    .qdev.size = sizeof(APBState),
-    .qdev.reset = pci_pbm_reset,
-    .init = pci_pbm_init_device,
+static void pbm_host_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pci_pbm_init_device;
+}
+
+static DeviceInfo pbm_host_info = {
+    .name = "pbm",
+    .size = sizeof(APBState),
+    .reset = pci_pbm_reset,
+    .class_init = pbm_host_class_init,
 };
 
 static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
diff --git a/hw/apic.c b/hw/apic.c
index e59c964..353119d 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -763,13 +763,20 @@ static void apic_init(APICCommonState *s)
     local_apics[s->idx] = s;
 }
 
-static APICCommonInfo apic_info = {
-    .busdev.qdev.name = "apic",
-    .init = apic_init,
-    .set_base = apic_set_base,
-    .set_tpr = apic_set_tpr,
-    .external_nmi = apic_external_nmi,
-    .post_load = apic_post_load,
+static void apic_class_init(ObjectClass *klass, void *data)
+{
+    APICCommonClass *k = APIC_COMMON_CLASS(klass);
+
+    k->init = apic_init;
+    k->set_base = apic_set_base;
+    k->set_tpr = apic_set_tpr;
+    k->external_nmi = apic_external_nmi;
+    k->post_load = apic_post_load;
+}
+
+static DeviceInfo apic_info = {
+    .name = "apic",
+    .class_init = apic_class_init,
 };
 
 static void apic_register_devices(void)
diff --git a/hw/apic_common.c b/hw/apic_common.c
index ac06147..9a3b1c5 100644
--- a/hw/apic_common.c
+++ b/hw/apic_common.c
@@ -25,35 +25,40 @@ static int apic_irq_delivered;
 
 void cpu_set_apic_base(DeviceState *d, uint64_t val)
 {
-    APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
-    APICCommonInfo *info;
-
     trace_cpu_set_apic_base(val);
 
-    if (s) {
-        info = DO_UPCAST(APICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
+    if (d) {
+        APICCommonState *s = APIC_COMMON(d);
+        APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
         info->set_base(s, val);
     }
 }
 
 uint64_t cpu_get_apic_base(DeviceState *d)
 {
-    APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
-
-    trace_cpu_get_apic_base(s ? (uint64_t)s->apicbase : 0);
-
-    return s ? s->apicbase : 0;
+    if (d) {
+        APICCommonState *s = APIC_COMMON(d);
+        trace_cpu_get_apic_base((uint64_t)s->apicbase);
+        return s->apicbase;
+    } else {
+        trace_cpu_get_apic_base(0);
+        return 0;
+    }
 }
 
 void cpu_set_apic_tpr(DeviceState *d, uint8_t val)
 {
-    APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
-    APICCommonInfo *info;
+    APICCommonState *s;
+    APICCommonClass *info;
 
-    if (s) {
-        info = DO_UPCAST(APICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
-        info->set_tpr(s, val);
+    if (!d) {
+        return;
     }
+
+    s = APIC_COMMON(d);
+    info = APIC_COMMON_GET_CLASS(s);
+
+    info->set_tpr(s, val);
 }
 
 uint8_t cpu_get_apic_tpr(DeviceState *d)
@@ -86,10 +91,9 @@ int apic_get_irq_delivered(void)
 
 void apic_deliver_nmi(DeviceState *d)
 {
-    APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
-    APICCommonInfo *info;
+    APICCommonState *s = APIC_COMMON(d);
+    APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
 
-    info = DO_UPCAST(APICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
     info->external_nmi(s);
 }
 
@@ -223,8 +227,8 @@ static int apic_load_old(QEMUFile *f, void *opaque, int version_id)
 
 static int apic_init_common(SysBusDevice *dev)
 {
-    APICCommonState *s = FROM_SYSBUS(APICCommonState, dev);
-    APICCommonInfo *info;
+    APICCommonState *s = APIC_COMMON(dev);
+    APICCommonClass *info;
     static int apic_no;
 
     if (apic_no >= MAX_APICS) {
@@ -232,7 +236,7 @@ static int apic_init_common(SysBusDevice *dev)
     }
     s->idx = apic_no++;
 
-    info = DO_UPCAST(APICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
+    info = APIC_COMMON_GET_CLASS(s);
     info->init(s);
 
     sysbus_init_mmio(&s->busdev, &s->io_memory);
@@ -241,9 +245,8 @@ static int apic_init_common(SysBusDevice *dev)
 
 static int apic_dispatch_post_load(void *opaque, int version_id)
 {
-    APICCommonState *s = opaque;
-    APICCommonInfo *info =
-        DO_UPCAST(APICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
+    APICCommonState *s = APIC_COMMON(opaque);
+    APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
 
     if (info->post_load) {
         info->post_load(s);
@@ -289,14 +292,35 @@ static Property apic_properties_common[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
+static void apic_common_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sc->init = apic_init_common;
+}
 
-void apic_qdev_register(APICCommonInfo *info)
+static TypeInfo apic_common_type = {
+    .name = TYPE_APIC_COMMON,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(APICCommonState),
+    .class_size = sizeof(APICCommonClass),
+    .class_init = apic_common_class_init,
+    .abstract = true,
+};
+
+void apic_qdev_register(DeviceInfo *info)
 {
-    info->busdev.init = apic_init_common;
-    info->busdev.qdev.size = sizeof(APICCommonState),
-    info->busdev.qdev.vmsd = &vmstate_apic_common;
-    info->busdev.qdev.reset = apic_reset_common;
-    info->busdev.qdev.no_user = 1;
-    info->busdev.qdev.props = apic_properties_common;
-    sysbus_register_withprop(&info->busdev);
+    info->size = sizeof(APICCommonState),
+    info->vmsd = &vmstate_apic_common;
+    info->reset = apic_reset_common;
+    info->no_user = 1;
+    info->props = apic_properties_common;
+    sysbus_qdev_register_subclass(info, TYPE_APIC_COMMON);
 }
+
+static void register_devices(void)
+{
+    type_register_static(&apic_common_type);
+}
+
+device_init(register_devices);
diff --git a/hw/apic_internal.h b/hw/apic_internal.h
index 1db4f06..1c6971c 100644
--- a/hw/apic_internal.h
+++ b/hw/apic_internal.h
@@ -67,6 +67,25 @@
 
 typedef struct APICCommonState APICCommonState;
 
+#define TYPE_APIC_COMMON "apic-common"
+#define APIC_COMMON(obj) \
+     OBJECT_CHECK(APICCommonState, (obj), TYPE_APIC_COMMON)
+#define APIC_COMMON_CLASS(klass) \
+     OBJECT_CLASS_CHECK(APICCommonClass, (klass), TYPE_APIC_COMMON)
+#define APIC_COMMON_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(APICCommonClass, (obj), TYPE_APIC_COMMON)
+
+typedef struct APICCommonClass
+{
+    SysBusDeviceClass parent_class;
+
+    void (*init)(APICCommonState *s);
+    void (*set_base)(APICCommonState *s, uint64_t val);
+    void (*set_tpr)(APICCommonState *s, uint8_t val);
+    void (*external_nmi)(APICCommonState *s);
+    void (*post_load)(APICCommonState *s);
+} APICCommonClass;
+
 struct APICCommonState {
     SysBusDevice busdev;
     MemoryRegion io_memory;
@@ -97,19 +116,8 @@ struct APICCommonState {
     int wait_for_sipi;
 };
 
-typedef struct APICCommonInfo APICCommonInfo;
-
-struct APICCommonInfo {
-    SysBusDeviceInfo busdev;
-    void (*init)(APICCommonState *s);
-    void (*set_base)(APICCommonState *s, uint64_t val);
-    void (*set_tpr)(APICCommonState *s, uint8_t val);
-    void (*external_nmi)(APICCommonState *s);
-    void (*post_load)(APICCommonState *s);
-};
-
 void apic_report_irq_delivered(int delivered);
-void apic_qdev_register(APICCommonInfo *info);
+void apic_qdev_register(DeviceInfo *info);
 bool apic_next_timer(APICCommonState *s, int64_t current_time);
 
 #endif /* !QEMU_APIC_INTERNAL_H */
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index f4d88dc..53c5408 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -201,33 +201,51 @@ static int realview_mpcore_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo mpcore_rirq_info = {
-    .init = realview_mpcore_init,
-    .qdev.name  = "realview_mpcore",
-    .qdev.size  = sizeof(mpcore_rirq_state),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("num-cpu", mpcore_rirq_state, num_cpu, 1),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property mpcore_rirq_properties[] = {
+    DEFINE_PROP_UINT32("num-cpu", mpcore_priv_state, num_cpu, 1),
+    /* The ARM11 MPCORE TRM says the on-chip controller may have
+     * anything from 0 to 224 external interrupt IRQ lines (with another
+     * 32 internal). We default to 32+32, which is the number provided by
+     * the ARM11 MPCore test chip in the Realview Versatile Express
+     * coretile. Other boards may differ and should set this property
+     * appropriately. Some Linux kernels may not boot if the hardware
+     * has more IRQ lines than the kernel expects.
+     */
+    DEFINE_PROP_UINT32("num-irq", mpcore_priv_state, num_irq, 64),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
-static SysBusDeviceInfo mpcore_priv_info = {
-    .init = mpcore_priv_init,
-    .qdev.name  = "arm11mpcore_priv",
-    .qdev.size  = sizeof(mpcore_priv_state),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("num-cpu", mpcore_priv_state, num_cpu, 1),
-        /* The ARM11 MPCORE TRM says the on-chip controller may have
-         * anything from 0 to 224 external interrupt IRQ lines (with another
-         * 32 internal). We default to 32+32, which is the number provided by
-         * the ARM11 MPCore test chip in the Realview Versatile Express
-         * coretile. Other boards may differ and should set this property
-         * appropriately. Some Linux kernels may not boot if the hardware
-         * has more IRQ lines than the kernel expects.
-         */
-        DEFINE_PROP_UINT32("num-irq", mpcore_priv_state, num_irq, 64),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static void mpcore_rirq_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = realview_mpcore_init;
+}
+
+static DeviceInfo mpcore_rirq_info = {
+    .name = "realview_mpcore",
+    .size = sizeof(mpcore_rirq_state),
+    .props = mpcore_rirq_properties,
+    .class_init = mpcore_rirq_class_init,
+};
+
+static Property mpcore_priv_properties[] = {
+    DEFINE_PROP_UINT32("num-cpu", mpcore_priv_state, num_cpu, 1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void mpcore_priv_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = mpcore_priv_init;
+}
+
+static DeviceInfo mpcore_priv_info = {
+    .name = "arm11mpcore_priv",
+    .size = sizeof(mpcore_priv_state),
+    .props = mpcore_priv_properties,
+    .class_init = mpcore_priv_class_init,
 };
 
 static void arm11mpcore_register_devices(void)
diff --git a/hw/arm_l2x0.c b/hw/arm_l2x0.c
index 2faed39..7c5fe32 100644
--- a/hw/arm_l2x0.c
+++ b/hw/arm_l2x0.c
@@ -160,22 +160,29 @@ static int l2x0_priv_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo l2x0_info = {
-    .init = l2x0_priv_init,
-    .qdev.name = "l2x0",
-    .qdev.size = sizeof(l2x0_state),
-    .qdev.vmsd = &vmstate_l2x0,
-    .qdev.no_user = 1,
-    .qdev.props = (Property[]) {
+static void l2x0_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = l2x0_priv_init;
+}
+
+static DeviceInfo l2x0_info = {
+    .name = "l2x0",
+    .size = sizeof(l2x0_state),
+    .vmsd = &vmstate_l2x0,
+    .no_user = 1,
+    .props = (Property[]) {
         DEFINE_PROP_UINT32("type", l2x0_state, cache_type, 0x1c100100),
         DEFINE_PROP_END_OF_LIST(),
     },
-    .qdev.reset = l2x0_priv_reset,
+    .reset = l2x0_priv_reset,
+    .class_init = l2x0_class_init,
 };
 
 static void l2x0_register_device(void)
 {
-    sysbus_register_withprop(&l2x0_info);
+    sysbus_qdev_register(&l2x0_info);
 }
 
 device_init(l2x0_register_device)
diff --git a/hw/arm_mptimer.c b/hw/arm_mptimer.c
index 455a0aa..06319c2 100644
--- a/hw/arm_mptimer.c
+++ b/hw/arm_mptimer.c
@@ -311,14 +311,21 @@ static const VMStateDescription vmstate_arm_mptimer = {
     }
 };
 
-static SysBusDeviceInfo arm_mptimer_info = {
-    .init = arm_mptimer_init,
-    .qdev.name = "arm_mptimer",
-    .qdev.size = sizeof(arm_mptimer_state),
-    .qdev.vmsd = &vmstate_arm_mptimer,
-    .qdev.reset = arm_mptimer_reset,
-    .qdev.no_user = 1,
-    .qdev.props = (Property[]) {
+static void arm_mptimer_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sbc->init = arm_mptimer_init;
+}
+
+static DeviceInfo arm_mptimer_info = {
+    .name = "arm_mptimer",
+    .size = sizeof(arm_mptimer_state),
+    .vmsd = &vmstate_arm_mptimer,
+    .reset = arm_mptimer_reset,
+    .no_user = 1,
+    .class_init = arm_mptimer_class_init,
+    .props = (Property[]) {
         DEFINE_PROP_UINT32("num-cpu", arm_mptimer_state, num_cpu, 0),
         DEFINE_PROP_END_OF_LIST()
     }
diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index 4b88648..08fb443 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -401,17 +401,26 @@ void arm_sysctl_init(uint32_t base, uint32_t sys_id, uint32_t proc_id)
     sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
 }
 
-static SysBusDeviceInfo arm_sysctl_info = {
-    .init = arm_sysctl_init1,
-    .qdev.name  = "realview_sysctl",
-    .qdev.size  = sizeof(arm_sysctl_state),
-    .qdev.vmsd = &vmstate_arm_sysctl,
-    .qdev.reset = arm_sysctl_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("sys_id", arm_sysctl_state, sys_id, 0),
-        DEFINE_PROP_UINT32("proc_id", arm_sysctl_state, proc_id, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property arm_sysctl_properties[] = {
+    DEFINE_PROP_UINT32("sys_id", arm_sysctl_state, sys_id, 0),
+    DEFINE_PROP_UINT32("proc_id", arm_sysctl_state, proc_id, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void arm_sysctl_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = arm_sysctl_init1;
+}
+
+static DeviceInfo arm_sysctl_info = {
+    .name = "realview_sysctl",
+    .size = sizeof(arm_sysctl_state),
+    .vmsd = &vmstate_arm_sysctl,
+    .reset = arm_sysctl_reset,
+    .props = arm_sysctl_properties,
+    .class_init = arm_sysctl_class_init,
 };
 
 static void arm_sysctl_register_devices(void)
diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index ead2535..15eb37c 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -283,17 +283,6 @@ static int sp804_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo sp804_info = {
-    .init = sp804_init,
-    .qdev.name = "sp804",
-    .qdev.size = sizeof(sp804_state),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("freq0", sp804_state, freq0, 1000000),
-        DEFINE_PROP_UINT32("freq1", sp804_state, freq1, 1000000),
-        DEFINE_PROP_END_OF_LIST(),
-    }
-};
-
 /* Integrator/CP timer module.  */
 
 typedef struct {
@@ -358,10 +347,41 @@ static int icp_pit_init(SysBusDevice *dev)
     return 0;
 }
 
+static void icp_pit_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = icp_pit_init;
+}
+
+static DeviceInfo icp_pit_info = {
+    .name = "integrator_pit",
+    .size = sizeof(icp_pit_state),
+    .class_init = icp_pit_class_init,
+};
+
+static void sp804_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = sp804_init;
+}
+
+static DeviceInfo sp804_info = {
+    .name = "sp804",
+    .size = sizeof(sp804_state),
+    .class_init = sp804_class_init,
+    .props = (Property[]) {
+        DEFINE_PROP_UINT32("freq0", sp804_state, freq0, 1000000),
+        DEFINE_PROP_UINT32("freq1", sp804_state, freq1, 1000000),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
 static void arm_timer_register_devices(void)
 {
-    sysbus_register_dev("integrator_pit", sizeof(icp_pit_state), icp_pit_init);
-    sysbus_register_withprop(&sp804_info);
+    sysbus_qdev_register(&icp_pit_info);
+    sysbus_qdev_register(&sp804_info);
 }
 
 device_init(arm_timer_register_devices)
diff --git a/hw/armv7m.c b/hw/armv7m.c
index 5c7a950..884fc90 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -245,14 +245,23 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
     return pic;
 }
 
-static SysBusDeviceInfo bitband_info = {
-    .init = bitband_init,
-    .qdev.name  = "ARM,bitband-memory",
-    .qdev.size  = sizeof(BitBandState),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("base", BitBandState, base, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property bitband_properties[] = {
+    DEFINE_PROP_UINT32("base", BitBandState, base, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void bitband_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = bitband_init;
+}
+
+static DeviceInfo bitband_info = {
+    .name = "ARM,bitband-memory",
+    .size = sizeof(BitBandState),
+    .props = bitband_properties,
+    .class_init = bitband_class_init,
 };
 
 static void armv7m_register_devices(void)
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 28f36ba..2bb94e8 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -391,12 +391,19 @@ static int armv7m_nvic_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo armv7m_nvic_priv_info = {
-    .init = armv7m_nvic_init,
-    .qdev.name  = "armv7m_nvic",
-    .qdev.size  = sizeof(nvic_state),
-    .qdev.vmsd  = &vmstate_nvic,
-    .qdev.props = (Property[]) {
+static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = armv7m_nvic_init;
+}
+
+static DeviceInfo armv7m_nvic_priv_info = {
+    .name = "armv7m_nvic",
+    .size = sizeof(nvic_state),
+    .vmsd  = &vmstate_nvic,
+    .class_init = armv7m_nvic_class_init,
+    .props = (Property[]) {
         /* The ARM v7m may have anything from 0 to 496 external interrupt
          * IRQ lines. We default to 64. Other boards may differ and should
          * set this property appropriately.
@@ -408,7 +415,7 @@ static SysBusDeviceInfo armv7m_nvic_priv_info = {
 
 static void armv7m_nvic_register_devices(void)
 {
-    sysbus_register_withprop(&armv7m_nvic_priv_info);
+    sysbus_qdev_register(&armv7m_nvic_priv_info);
 }
 
 device_init(armv7m_nvic_register_devices)
diff --git a/hw/bitbang_i2c.c b/hw/bitbang_i2c.c
index 93fb2ed..da9e5cf 100644
--- a/hw/bitbang_i2c.c
+++ b/hw/bitbang_i2c.c
@@ -221,11 +221,18 @@ static int gpio_i2c_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo gpio_i2c_info = {
-    .init = gpio_i2c_init,
-    .qdev.name  = "gpio_i2c",
-    .qdev.desc  = "Virtual GPIO to I2C bridge",
-    .qdev.size  = sizeof(GPIOI2CState),
+static void gpio_i2c_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = gpio_i2c_init;
+}
+
+static DeviceInfo gpio_i2c_info = {
+    .name = "gpio_i2c",
+    .desc = "Virtual GPIO to I2C bridge",
+    .size = sizeof(GPIOI2CState),
+    .class_init = gpio_i2c_class_init,
 };
 
 static void bitbang_i2c_register(void)
diff --git a/hw/bonito.c b/hw/bonito.c
index 23384ec..0333a2e 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -786,11 +786,18 @@ static DeviceInfo bonito_info = {
     .class_init = bonito_class_init,
 };
 
-static SysBusDeviceInfo bonito_pcihost_info = {
-    .init         = bonito_pcihost_initfn,
-    .qdev.name    = "Bonito-pcihost",
-    .qdev.size    = sizeof(BonitoState),
-    .qdev.no_user = 1,
+static void bonito_pcihost_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = bonito_pcihost_initfn;
+}
+
+static DeviceInfo bonito_pcihost_info = {
+    .name = "Bonito-pcihost",
+    .size = sizeof(BonitoState),
+    .no_user = 1,
+    .class_init = bonito_pcihost_class_init,
 };
 
 static void bonito_register(void)
diff --git a/hw/container.c b/hw/container.c
index 9cbf399..73f94c5 100644
--- a/hw/container.c
+++ b/hw/container.c
@@ -5,11 +5,18 @@ static int container_initfn(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo container_info = {
-    .init = container_initfn,
-    .qdev.name = "container",
-    .qdev.size = sizeof(SysBusDevice),
-    .qdev.no_user = 1,
+static void container_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = container_initfn;
+}
+
+static DeviceInfo container_info = {
+    .name = "container",
+    .size = sizeof(SysBusDevice),
+    .no_user = 1,
+    .class_init = container_class_init,
 };
 
 static void container_init(void)
diff --git a/hw/cs4231.c b/hw/cs4231.c
index 2dfb708..87c4eb9 100644
--- a/hw/cs4231.c
+++ b/hw/cs4231.c
@@ -151,15 +151,24 @@ static int cs4231_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo cs4231_info = {
-    .init = cs4231_init1,
-    .qdev.name  = "SUNW,CS4231",
-    .qdev.size  = sizeof(CSState),
-    .qdev.vmsd  = &vmstate_cs4231,
-    .qdev.reset = cs_reset,
-    .qdev.props = (Property[]) {
-        {.name = NULL}
-    }
+static Property cs4231_properties[] = {
+    {.name = NULL},
+};
+
+static void cs4231_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = cs4231_init1;
+}
+
+static DeviceInfo cs4231_info = {
+    .name = "SUNW,CS4231",
+    .size = sizeof(CSState),
+    .vmsd = &vmstate_cs4231,
+    .reset = cs_reset,
+    .props = cs4231_properties,
+    .class_init = cs4231_class_init,
 };
 
 static void cs4231_register_devices(void)
diff --git a/hw/dec_pci.c b/hw/dec_pci.c
index 7c3f50e..f0ecaff 100644
--- a/hw/dec_pci.c
+++ b/hw/dec_pci.c
@@ -84,7 +84,7 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
     return pci_bridge_get_sec_bus(br);
 }
 
-static int pci_dec_21154_init_device(SysBusDevice *dev)
+static int pci_dec_21154_device_init(SysBusDevice *dev)
 {
     DECState *s;
 
@@ -123,11 +123,22 @@ static DeviceInfo dec_21154_pci_host_info = {
     .class_init = dec_21154_pci_host_class_init,
 };
 
-static void dec_register_devices(void)
+static void pci_dec_21154_device_class_init(ObjectClass *klass, void *data)
 {
-    sysbus_register_dev("dec-21154", sizeof(DECState),
-                        pci_dec_21154_init_device);
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = pci_dec_21154_device_init;
+}
+
+static DeviceInfo pci_dec_21154_device_info = {
+    .name = "dec-21154",
+    .size = sizeof(DECState),
+    .class_init = pci_dec_21154_device_class_init,
+};
 
+static void dec_register_devices(void)
+{
+    sysbus_qdev_register(&pci_dec_21154_device_info);
     pci_qdev_register(&dec_21154_pci_host_info);
     pci_qdev_register(&dec_21154_pci_bridge_info);
 }
diff --git a/hw/ds1225y.c b/hw/ds1225y.c
index 7aa0832..5890b16 100644
--- a/hw/ds1225y.c
+++ b/hw/ds1225y.c
@@ -134,16 +134,25 @@ static int nvram_sysbus_initfn(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo nvram_sysbus_info = {
-    .qdev.name  = "ds1225y",
-    .qdev.size  = sizeof(SysBusNvRamState),
-    .qdev.vmsd  = &vmstate_nvram,
-    .init       = nvram_sysbus_initfn,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("size", SysBusNvRamState, nvram.chip_size, 0x2000),
-        DEFINE_PROP_STRING("filename", SysBusNvRamState, nvram.filename),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property nvram_sysbus_properties[] = {
+    DEFINE_PROP_UINT32("size", SysBusNvRamState, nvram.chip_size, 0x2000),
+    DEFINE_PROP_STRING("filename", SysBusNvRamState, nvram.filename),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void nvram_sysbus_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = nvram_sysbus_initfn;
+}
+
+static DeviceInfo nvram_sysbus_info = {
+    .name = "ds1225y",
+    .size = sizeof(SysBusNvRamState),
+    .vmsd = &vmstate_nvram,
+    .props = nvram_sysbus_properties,
+    .class_init = nvram_sysbus_class_init,
 };
 
 static void nvram_register(void)
diff --git a/hw/eccmemctl.c b/hw/eccmemctl.c
index 7743465..2d82c48 100644
--- a/hw/eccmemctl.c
+++ b/hw/eccmemctl.c
@@ -308,16 +308,25 @@ static int ecc_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo ecc_info = {
-    .init = ecc_init1,
-    .qdev.name  = "eccmemctl",
-    .qdev.size  = sizeof(ECCState),
-    .qdev.vmsd  = &vmstate_ecc,
-    .qdev.reset = ecc_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_HEX32("version", ECCState, version, -1),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property ecc_properties[] = {
+    DEFINE_PROP_HEX32("version", ECCState, version, -1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ecc_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = ecc_init1;
+}
+
+static DeviceInfo ecc_info = {
+    .name = "eccmemctl",
+    .size = sizeof(ECCState),
+    .vmsd = &vmstate_ecc,
+    .reset = ecc_reset,
+    .props = ecc_properties,
+    .class_init = ecc_class_init,
 };
 
 
diff --git a/hw/empty_slot.c b/hw/empty_slot.c
index 8b734f2..70e45d0 100644
--- a/hw/empty_slot.c
+++ b/hw/empty_slot.c
@@ -76,10 +76,17 @@ static int empty_slot_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo empty_slot_info = {
-    .init = empty_slot_init1,
-    .qdev.name  = "empty_slot",
-    .qdev.size  = sizeof(EmptySlot),
+static void empty_slot_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = empty_slot_init1;
+}
+
+static DeviceInfo empty_slot_info = {
+    .name = "empty_slot",
+    .size = sizeof(EmptySlot),
+    .class_init = empty_slot_class_init,
 };
 
 static void empty_slot_register_devices(void)
diff --git a/hw/escc.c b/hw/escc.c
index 81204a6..d905d96 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -901,23 +901,32 @@ static int escc_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo escc_info = {
-    .init = escc_init1,
-    .qdev.name  = "escc",
-    .qdev.size  = sizeof(SerialState),
-    .qdev.vmsd  = &vmstate_escc,
-    .qdev.reset = escc_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("frequency", SerialState, frequency,   0),
-        DEFINE_PROP_UINT32("it_shift",  SerialState, it_shift,    0),
-        DEFINE_PROP_UINT32("disabled",  SerialState, disabled,    0),
-        DEFINE_PROP_UINT32("disabled",  SerialState, disabled,    0),
-        DEFINE_PROP_UINT32("chnBtype",  SerialState, chn[0].type, 0),
-        DEFINE_PROP_UINT32("chnAtype",  SerialState, chn[1].type, 0),
-        DEFINE_PROP_CHR("chrB", SerialState, chn[0].chr),
-        DEFINE_PROP_CHR("chrA", SerialState, chn[1].chr),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property escc_properties[] = {
+    DEFINE_PROP_UINT32("frequency", SerialState, frequency,   0),
+    DEFINE_PROP_UINT32("it_shift",  SerialState, it_shift,    0),
+    DEFINE_PROP_UINT32("disabled",  SerialState, disabled,    0),
+    DEFINE_PROP_UINT32("disabled",  SerialState, disabled,    0),
+    DEFINE_PROP_UINT32("chnBtype",  SerialState, chn[0].type, 0),
+    DEFINE_PROP_UINT32("chnAtype",  SerialState, chn[1].type, 0),
+    DEFINE_PROP_CHR("chrB", SerialState, chn[0].chr),
+    DEFINE_PROP_CHR("chrA", SerialState, chn[1].chr),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void escc_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = escc_init1;
+}
+
+static DeviceInfo escc_info = {
+    .name = "escc",
+    .size = sizeof(SerialState),
+    .vmsd = &vmstate_escc,
+    .reset = escc_reset,
+    .props = escc_properties,
+    .class_init = escc_class_init,
 };
 
 static void escc_register_devices(void)
diff --git a/hw/esp.c b/hw/esp.c
index 9551c78..71d3e70 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -753,15 +753,24 @@ static int esp_init1(SysBusDevice *dev)
     return scsi_bus_legacy_handle_cmdline(&s->bus);
 }
 
-static SysBusDeviceInfo esp_info = {
-    .init = esp_init1,
-    .qdev.name  = "esp",
-    .qdev.size  = sizeof(ESPState),
-    .qdev.vmsd  = &vmstate_esp,
-    .qdev.reset = esp_hard_reset,
-    .qdev.props = (Property[]) {
-        {.name = NULL}
-    }
+static Property esp_properties[] = {
+    {.name = NULL},
+};
+
+static void esp_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = esp_init1;
+}
+
+static DeviceInfo esp_info = {
+    .name = "esp",
+    .size = sizeof(ESPState),
+    .vmsd = &vmstate_esp,
+    .reset = esp_hard_reset,
+    .props = esp_properties,
+    .class_init = esp_class_init,
 };
 
 static void esp_register_devices(void)
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 1b6b71d..92c822b 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -613,17 +613,26 @@ static int fs_eth_init(SysBusDevice *dev)
 	return 0;
 }
 
-static SysBusDeviceInfo etraxfs_eth_info = {
-	.init = fs_eth_init,
-	.qdev.name  = "etraxfs-eth",
-	.qdev.size  = sizeof(struct fs_eth),
-	.qdev.props = (Property[]) {
-		DEFINE_PROP_UINT32("phyaddr", struct fs_eth, phyaddr, 1),
-		DEFINE_PROP_PTR("dma_out", struct fs_eth, vdma_out),
-		DEFINE_PROP_PTR("dma_in", struct fs_eth, vdma_in),
-		DEFINE_NIC_PROPERTIES(struct fs_eth, conf),
-		DEFINE_PROP_END_OF_LIST(),
-	}
+static Property etraxfs_eth_properties[] = {
+    DEFINE_PROP_UINT32("phyaddr", struct fs_eth, phyaddr, 1),
+    DEFINE_PROP_PTR("dma_out", struct fs_eth, vdma_out),
+    DEFINE_PROP_PTR("dma_in", struct fs_eth, vdma_in),
+    DEFINE_NIC_PROPERTIES(struct fs_eth, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void etraxfs_eth_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = fs_eth_init;
+}
+
+static DeviceInfo etraxfs_eth_info = {
+    .name = "etraxfs-eth",
+    .size = sizeof(struct fs_eth),
+    .props = etraxfs_eth_properties,
+    .class_init = etraxfs_eth_class_init,
 };
 
 static void etraxfs_eth_register(void)
diff --git a/hw/etraxfs_pic.c b/hw/etraxfs_pic.c
index 993d6a8..8acf01e 100644
--- a/hw/etraxfs_pic.c
+++ b/hw/etraxfs_pic.c
@@ -151,14 +151,23 @@ static int etraxfs_pic_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo etraxfs_pic_info = {
-    .init = etraxfs_pic_init,
-    .qdev.name  = "etraxfs,pic",
-    .qdev.size  = sizeof(struct etrax_pic),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_PTR("interrupt_vector", struct etrax_pic, interrupt_vector),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property etraxfs_pic_properties[] = {
+    DEFINE_PROP_PTR("interrupt_vector", struct etrax_pic, interrupt_vector),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void etraxfs_pic_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = etraxfs_pic_init;
+}
+
+static DeviceInfo etraxfs_pic_info = {
+    .name = "etraxfs,pic",
+    .size = sizeof(struct etrax_pic),
+    .props = etraxfs_pic_properties,
+    .class_init = etraxfs_pic_class_init,
 };
 
 static void etraxfs_pic_register(void)
diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
index 2623dab..a487805 100644
--- a/hw/etraxfs_ser.c
+++ b/hw/etraxfs_ser.c
@@ -224,11 +224,18 @@ static int etraxfs_ser_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo etraxfs_ser_info = {
-    .init = etraxfs_ser_init,
-    .qdev.name  = "etraxfs,serial",
-    .qdev.size  = sizeof(struct etrax_serial),
-    .qdev.reset = etraxfs_ser_reset,
+static void etraxfs_ser_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = etraxfs_ser_init;
+}
+
+static DeviceInfo etraxfs_ser_info = {
+    .name = "etraxfs,serial",
+    .size = sizeof(struct etrax_serial),
+    .reset = etraxfs_ser_reset,
+    .class_init = etraxfs_ser_class_init,
 };
 
 static void etraxfs_serial_register(void)
diff --git a/hw/etraxfs_timer.c b/hw/etraxfs_timer.c
index 2dfdb30..c33058c 100644
--- a/hw/etraxfs_timer.c
+++ b/hw/etraxfs_timer.c
@@ -329,10 +329,22 @@ static int etraxfs_timer_init(SysBusDevice *dev)
     return 0;
 }
 
+static void etraxfs_timer_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = etraxfs_timer_init;
+}
+
+static DeviceInfo etraxfs_timer_info = {
+    .name = "etraxfs,timer",
+    .size = sizeof (struct etrax_timer),
+    .class_init = etraxfs_timer_class_init,
+};
+
 static void etraxfs_timer_register(void)
 {
-    sysbus_register_dev("etraxfs,timer", sizeof (struct etrax_timer),
-                        etraxfs_timer_init);
+    sysbus_qdev_register(&etraxfs_timer_info);
 }
 
 device_init(etraxfs_timer_register)
diff --git a/hw/fdc.c b/hw/fdc.c
index f761221..8562284 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1992,29 +1992,47 @@ static const VMStateDescription vmstate_sysbus_fdc ={
     }
 };
 
-static SysBusDeviceInfo sysbus_fdc_info = {
-    .init = sysbus_fdc_init1,
-    .qdev.name  = "sysbus-fdc",
-    .qdev.size  = sizeof(FDCtrlSysBus),
-    .qdev.vmsd  = &vmstate_sysbus_fdc,
-    .qdev.reset = fdctrl_external_reset_sysbus,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.drives[0].bs),
-        DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.drives[1].bs),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property sysbus_fdc_properties[] = {
+    DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.drives[0].bs),
+    DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.drives[1].bs),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
-static SysBusDeviceInfo sun4m_fdc_info = {
-    .init = sun4m_fdc_init1,
-    .qdev.name  = "SUNW,fdtwo",
-    .qdev.size  = sizeof(FDCtrlSysBus),
-    .qdev.vmsd  = &vmstate_sysbus_fdc,
-    .qdev.reset = fdctrl_external_reset_sysbus,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.drives[0].bs),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static void sysbus_fdc_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = sysbus_fdc_init1;
+}
+
+static DeviceInfo sysbus_fdc_info = {
+    .name = "sysbus-fdc",
+    .size = sizeof(FDCtrlSysBus),
+    .vmsd = &vmstate_sysbus_fdc,
+    .reset = fdctrl_external_reset_sysbus,
+    .props = sysbus_fdc_properties,
+    .class_init = sysbus_fdc_class_init,
+};
+
+static Property sun4m_fdc_properties[] = {
+    DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.drives[0].bs),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void sun4m_fdc_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = sun4m_fdc_init1;
+}
+
+static DeviceInfo sun4m_fdc_info = {
+    .name = "SUNW,fdtwo",
+    .size = sizeof(FDCtrlSysBus),
+    .vmsd = &vmstate_sysbus_fdc,
+    .reset = fdctrl_external_reset_sysbus,
+    .props = sun4m_fdc_properties,
+    .class_init = sun4m_fdc_class_init,
 };
 
 static void fdc_register_devices(void)
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index f953532..e669ed4 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -531,18 +531,27 @@ static int fw_cfg_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo fw_cfg_info = {
-    .init = fw_cfg_init1,
-    .qdev.name = "fw_cfg",
-    .qdev.size = sizeof(FWCfgState),
-    .qdev.vmsd = &vmstate_fw_cfg,
-    .qdev.reset = fw_cfg_reset,
-    .qdev.no_user = 1,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_HEX32("ctl_iobase", FWCfgState, ctl_iobase, -1),
-        DEFINE_PROP_HEX32("data_iobase", FWCfgState, data_iobase, -1),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property fw_cfg_properties[] = {
+    DEFINE_PROP_HEX32("ctl_iobase", FWCfgState, ctl_iobase, -1),
+    DEFINE_PROP_HEX32("data_iobase", FWCfgState, data_iobase, -1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void fw_cfg_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = fw_cfg_init1;
+}
+
+static DeviceInfo fw_cfg_info = {
+    .name = "fw_cfg",
+    .size = sizeof(FWCfgState),
+    .vmsd = &vmstate_fw_cfg,
+    .reset = fw_cfg_reset,
+    .no_user = 1,
+    .props = fw_cfg_properties,
+    .class_init = fw_cfg_class_init,
 };
 
 static void fw_cfg_register_devices(void)
diff --git a/hw/g364fb.c b/hw/g364fb.c
index 33ec149..8d6bfac 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -553,18 +553,27 @@ static void g364fb_sysbus_reset(DeviceState *d)
     g364fb_reset(&s->g364);
 }
 
-static SysBusDeviceInfo g364fb_sysbus_info = {
-    .init = g364fb_sysbus_init,
-    .qdev.name = "sysbus-g364",
-    .qdev.desc = "G364 framebuffer",
-    .qdev.size = sizeof(G364SysBusState),
-    .qdev.vmsd = &vmstate_g364fb,
-    .qdev.reset = g364fb_sysbus_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_HEX32("vram_size", G364SysBusState, g364.vram_size,
-                          8 * 1024 * 1024),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property g364fb_sysbus_properties[] = {
+    DEFINE_PROP_HEX32("vram_size", G364SysBusState, g364.vram_size,
+    8 * 1024 * 1024),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void g364fb_sysbus_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = g364fb_sysbus_init;
+}
+
+static DeviceInfo g364fb_sysbus_info = {
+    .name = "sysbus-g364",
+    .desc = "G364 framebuffer",
+    .size = sizeof(G364SysBusState),
+    .vmsd = &vmstate_g364fb,
+    .reset = g364fb_sysbus_reset,
+    .props = g364fb_sysbus_properties,
+    .class_init = g364fb_sysbus_class_init,
 };
 
 static void g364fb_register(void)
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index a790f97..549859d 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -139,16 +139,23 @@ static DeviceInfo grackle_pci_info = {
     .class_init = grackle_pci_class_init,
 };
 
-static SysBusDeviceInfo grackle_pci_host_info = {
-    .qdev.name = "grackle-pcihost",
-    .qdev.size = sizeof(GrackleState),
-    .qdev.no_user = 1,
-    .init = pci_grackle_init_device,
+static void pci_grackle_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pci_grackle_init_device;
+}
+
+static DeviceInfo grackle_pci_host_info = {
+    .name = "grackle-pcihost",
+    .size = sizeof(GrackleState),
+    .no_user = 1,
+    .class_init = pci_grackle_class_init,
 };
 
 static void grackle_register_devices(void)
 {
-    sysbus_register_withprop(&grackle_pci_host_info);
+    sysbus_qdev_register(&grackle_pci_host_info);
     pci_qdev_register(&grackle_pci_info);
 }
 
diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c
index f8a64e1..dc12d58 100644
--- a/hw/grlib_apbuart.c
+++ b/hw/grlib_apbuart.c
@@ -170,14 +170,23 @@ static int grlib_apbuart_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo grlib_gptimer_info = {
-    .init       = grlib_apbuart_init,
-    .qdev.name  = "grlib,apbuart",
-    .qdev.size  = sizeof(UART),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_CHR("chrdev", UART, chr),
-        DEFINE_PROP_END_OF_LIST()
-    }
+static Property grlib_gptimer_properties[] = {
+    DEFINE_PROP_CHR("chrdev", UART, chr),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void grlib_gptimer_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = grlib_apbuart_init;
+}
+
+static DeviceInfo grlib_gptimer_info = {
+    .name = "grlib,apbuart",
+    .size = sizeof(UART),
+    .props = grlib_gptimer_properties,
+    .class_init = grlib_gptimer_class_init,
 };
 
 static void grlib_gptimer_register(void)
diff --git a/hw/grlib_gptimer.c b/hw/grlib_gptimer.c
index 9c98a83..219009e 100644
--- a/hw/grlib_gptimer.c
+++ b/hw/grlib_gptimer.c
@@ -372,17 +372,26 @@ static int grlib_gptimer_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo grlib_gptimer_info = {
-    .init       = grlib_gptimer_init,
-    .qdev.name  = "grlib,gptimer",
-    .qdev.reset = grlib_gptimer_reset,
-    .qdev.size  = sizeof(GPTimerUnit),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("frequency", GPTimerUnit, freq_hz,   40000000),
-        DEFINE_PROP_UINT32("irq-line",  GPTimerUnit, irq_line,  8),
-        DEFINE_PROP_UINT32("nr-timers", GPTimerUnit, nr_timers, 2),
-        DEFINE_PROP_END_OF_LIST()
-    }
+static Property grlib_gptimer_properties[] = {
+    DEFINE_PROP_UINT32("frequency", GPTimerUnit, freq_hz,   40000000),
+    DEFINE_PROP_UINT32("irq-line",  GPTimerUnit, irq_line,  8),
+    DEFINE_PROP_UINT32("nr-timers", GPTimerUnit, nr_timers, 2),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void grlib_gptimer_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = grlib_gptimer_init;
+}
+
+static DeviceInfo grlib_gptimer_info = {
+    .name = "grlib,gptimer",
+    .reset = grlib_gptimer_reset,
+    .size = sizeof(GPTimerUnit),
+    .props = grlib_gptimer_properties,
+    .class_init = grlib_gptimer_class_init,
 };
 
 static void grlib_gptimer_register(void)
diff --git a/hw/grlib_irqmp.c b/hw/grlib_irqmp.c
index 2872556..1ccddfb 100644
--- a/hw/grlib_irqmp.c
+++ b/hw/grlib_irqmp.c
@@ -354,16 +354,25 @@ static int grlib_irqmp_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo grlib_irqmp_info = {
-    .init = grlib_irqmp_init,
-    .qdev.name  = "grlib,irqmp",
-    .qdev.reset = grlib_irqmp_reset,
-    .qdev.size  = sizeof(IRQMP),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_PTR("set_pil_in", IRQMP, set_pil_in),
-        DEFINE_PROP_PTR("set_pil_in_opaque", IRQMP, set_pil_in_opaque),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property grlib_irqmp_properties[] = {
+    DEFINE_PROP_PTR("set_pil_in", IRQMP, set_pil_in),
+    DEFINE_PROP_PTR("set_pil_in_opaque", IRQMP, set_pil_in_opaque),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void grlib_irqmp_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = grlib_irqmp_init;
+}
+
+static DeviceInfo grlib_irqmp_info = {
+    .name = "grlib,irqmp",
+    .reset = grlib_irqmp_reset,
+    .size = sizeof(IRQMP),
+    .props = grlib_irqmp_properties,
+    .class_init = grlib_irqmp_class_init,
 };
 
 static void grlib_irqmp_register(void)
diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index 9fc51f2..79d2dfb 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -1153,10 +1153,22 @@ static DeviceInfo gt64120_pci_info = {
     .class_init = gt64120_pci_class_init,
 };
 
+static void gt64120_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = gt64120_init;
+}
+
+static DeviceInfo gt64120_info = {
+    .name = "gt64120",
+    .size = sizeof(GT64120State),
+    .class_init = gt64120_class_init,
+};
+
 static void gt64120_pci_register_devices(void)
 {
-    sysbus_register_dev("gt64120", sizeof(GT64120State),
-                        gt64120_init);
+    sysbus_qdev_register(&gt64120_info);
     pci_qdev_register(&gt64120_pci_info);
 }
 
diff --git a/hw/hpet.c b/hw/hpet.c
index 5312df7..aba9ea9 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -695,18 +695,27 @@ static int hpet_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo hpet_device_info = {
-    .qdev.name    = "hpet",
-    .qdev.size    = sizeof(HPETState),
-    .qdev.no_user = 1,
-    .qdev.vmsd    = &vmstate_hpet,
-    .qdev.reset   = hpet_reset,
-    .init         = hpet_init,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT8("timers", HPETState, num_timers, HPET_MIN_TIMERS),
-        DEFINE_PROP_BIT("msi", HPETState, flags, HPET_MSI_SUPPORT, false),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property hpet_device_properties[] = {
+    DEFINE_PROP_UINT8("timers", HPETState, num_timers, HPET_MIN_TIMERS),
+    DEFINE_PROP_BIT("msi", HPETState, flags, HPET_MSI_SUPPORT, false),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void hpet_device_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = hpet_init;
+}
+
+static DeviceInfo hpet_device_info = {
+    .name = "hpet",
+    .size = sizeof(HPETState),
+    .no_user = 1,
+    .vmsd = &vmstate_hpet,
+    .reset = hpet_reset,
+    .props = hpet_device_properties,
+    .class_init = hpet_device_class_init,
 };
 
 static void hpet_register_device(void)
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index e5712fc..130accf 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -518,19 +518,41 @@ static void integratorcp_machine_init(void)
 
 machine_init(integratorcp_machine_init);
 
-static SysBusDeviceInfo core_info = {
-    .init = integratorcm_init,
-    .qdev.name  = "integrator_core",
-    .qdev.size  = sizeof(integratorcm_state),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("memsz", integratorcm_state, memsz, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property core_properties[] = {
+    DEFINE_PROP_UINT32("memsz", integratorcm_state, memsz, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void core_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = integratorcm_init;
+}
+
+static DeviceInfo core_info = {
+    .name = "integrator_core",
+    .size = sizeof(integratorcm_state),
+    .props = core_properties,
+    .class_init = core_class_init,
+};
+
+static void icp_pic_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = icp_pic_init;
+}
+
+static DeviceInfo icp_pic_info = {
+    .name = "integrator_pic",
+    .size = sizeof(icp_pic_state),
+    .class_init = icp_pic_class_init,
 };
 
 static void integratorcp_register_devices(void)
 {
-    sysbus_register_dev("integrator_pic", sizeof(icp_pic_state), icp_pic_init);
+    sysbus_qdev_register(&icp_pic_info);
     sysbus_register_withprop(&core_info);
 }
 
diff --git a/hw/ioapic.c b/hw/ioapic.c
index 0c8be50..0939009 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -235,11 +235,18 @@ static void ioapic_init(IOAPICCommonState *s, int instance_no)
     ioapics[instance_no] = s;
 }
 
-static IOAPICCommonInfo ioapic_info = {
-    .busdev.qdev.name = "ioapic",
-    .busdev.qdev.size = sizeof(IOAPICCommonState),
-    .busdev.qdev.reset = ioapic_reset_common,
-    .init = ioapic_init,
+static void ioapic_class_init(ObjectClass *klass, void *data)
+{
+    IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
+
+    k->init = ioapic_init;
+}
+
+static DeviceInfo ioapic_info = {
+    .name = "ioapic",
+    .size = sizeof(IOAPICCommonState),
+    .reset = ioapic_reset_common,
+    .class_init = ioapic_class_init,
 };
 
 static void ioapic_register_devices(void)
diff --git a/hw/ioapic_common.c b/hw/ioapic_common.c
index 4a7624c..4bb7ea9 100644
--- a/hw/ioapic_common.c
+++ b/hw/ioapic_common.c
@@ -25,7 +25,7 @@
 
 void ioapic_reset_common(DeviceState *dev)
 {
-    IOAPICCommonState *s = DO_UPCAST(IOAPICCommonState, busdev.qdev, dev);
+    IOAPICCommonState *s = IOAPIC_COMMON(dev);
     int i;
 
     s->id = 0;
@@ -38,9 +38,8 @@ void ioapic_reset_common(DeviceState *dev)
 
 static void ioapic_dispatch_pre_save(void *opaque)
 {
-    IOAPICCommonState *s = opaque;
-    IOAPICCommonInfo *info =
-        DO_UPCAST(IOAPICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
+    IOAPICCommonState *s = IOAPIC_COMMON(opaque);
+    IOAPICCommonClass *info = IOAPIC_COMMON_GET_CLASS(s);
 
     if (info->pre_save) {
         info->pre_save(s);
@@ -49,9 +48,8 @@ static void ioapic_dispatch_pre_save(void *opaque)
 
 static int ioapic_dispatch_post_load(void *opaque, int version_id)
 {
-    IOAPICCommonState *s = opaque;
-    IOAPICCommonInfo *info =
-        DO_UPCAST(IOAPICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
+    IOAPICCommonState *s = IOAPIC_COMMON(opaque);
+    IOAPICCommonClass *info = IOAPIC_COMMON_GET_CLASS(s);
 
     if (info->post_load) {
         info->post_load(s);
@@ -62,14 +60,14 @@ static int ioapic_dispatch_post_load(void *opaque, int version_id)
 static int ioapic_init_common(SysBusDevice *dev)
 {
     IOAPICCommonState *s = FROM_SYSBUS(IOAPICCommonState, dev);
-    IOAPICCommonInfo *info;
+    IOAPICCommonClass *info;
     static int ioapic_no;
 
     if (ioapic_no >= MAX_IOAPICS) {
         return -1;
     }
 
-    info = DO_UPCAST(IOAPICCommonInfo, busdev.qdev, qdev_get_info(&s->busdev.qdev));
+    info = IOAPIC_COMMON_GET_CLASS(s);
     info->init(s, ioapic_no);
 
     sysbus_init_mmio(&s->busdev, &s->io_memory);
@@ -95,10 +93,33 @@ static const VMStateDescription vmstate_ioapic_common = {
     }
 };
 
-void ioapic_qdev_register(IOAPICCommonInfo *info)
+static void ioapic_common_class_init(ObjectClass *klass, void *data)
 {
-    info->busdev.init = ioapic_init_common;
-    info->busdev.qdev.vmsd = &vmstate_ioapic_common;
-    info->busdev.qdev.no_user = 1;
-    sysbus_register_withprop(&info->busdev);
+    SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sc->init = ioapic_init_common;
+}
+
+static TypeInfo ioapic_common_type = {
+    .name = TYPE_IOAPIC_COMMON,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(IOAPICCommonState),
+    .class_size = sizeof(IOAPICCommonClass),
+    .class_init = ioapic_common_class_init,
+    .abstract = true,
+};
+
+void ioapic_qdev_register(DeviceInfo *info)
+{
+    info->vmsd = &vmstate_ioapic_common;
+    info->no_user = 1;
+    sysbus_qdev_register_subclass(info, TYPE_IOAPIC_COMMON);
 }
+
+static void register_devices(void)
+{
+    type_register_static(&ioapic_common_type);
+}
+
+device_init(register_devices);
+
diff --git a/hw/ioapic_internal.h b/hw/ioapic_internal.h
index f8d90c0..9dff1a7 100644
--- a/hw/ioapic_internal.h
+++ b/hw/ioapic_internal.h
@@ -73,6 +73,21 @@
 
 typedef struct IOAPICCommonState IOAPICCommonState;
 
+#define TYPE_IOAPIC_COMMON "ioapic-common"
+#define IOAPIC_COMMON(obj) \
+     OBJECT_CHECK(IOAPICCommonState, (obj), TYPE_IOAPIC_COMMON)
+#define IOAPIC_COMMON_CLASS(klass) \
+     OBJECT_CLASS_CHECK(IOAPICCommonClass, (klass), TYPE_IOAPIC_COMMON)
+#define IOAPIC_COMMON_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(IOAPICCommonClass, (obj), TYPE_IOAPIC_COMMON)
+
+typedef struct IOAPICCommonClass {
+    SysBusDeviceClass parent_class;
+    void (*init)(IOAPICCommonState *s, int instance_no);
+    void (*pre_save)(IOAPICCommonState *s);
+    void (*post_load)(IOAPICCommonState *s);
+} IOAPICCommonClass;
+
 struct IOAPICCommonState {
     SysBusDevice busdev;
     MemoryRegion io_memory;
@@ -82,16 +97,7 @@ struct IOAPICCommonState {
     uint64_t ioredtbl[IOAPIC_NUM_PINS];
 };
 
-typedef struct IOAPICCommonInfo IOAPICCommonInfo;
-
-struct IOAPICCommonInfo {
-    SysBusDeviceInfo busdev;
-    void (*init)(IOAPICCommonState *s, int instance_no);
-    void (*pre_save)(IOAPICCommonState *s);
-    void (*post_load)(IOAPICCommonState *s);
-};
-
-void ioapic_qdev_register(IOAPICCommonInfo *info);
+void ioapic_qdev_register(DeviceInfo *info);
 void ioapic_reset_common(DeviceState *dev);
 
 #endif /* !QEMU_IOAPIC_INTERNAL_H */
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 6943194..92d8882 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -189,12 +189,19 @@ static int isabus_bridge_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo isabus_bridge_info = {
-    .init = isabus_bridge_init,
-    .qdev.name  = "isabus-bridge",
-    .qdev.fw_name  = "isa",
-    .qdev.size  = sizeof(SysBusDevice),
-    .qdev.no_user = 1,
+static void isabus_bridge_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = isabus_bridge_init;
+}
+
+static DeviceInfo isabus_bridge_info = {
+    .name = "isabus-bridge",
+    .fw_name = "isa",
+    .size = sizeof(SysBusDevice),
+    .no_user = 1,
+    .class_init = isabus_bridge_class_init,
 };
 
 static TypeInfo isa_device_type_info = {
diff --git a/hw/kvm/apic.c b/hw/kvm/apic.c
index 6300695..bc80ae4 100644
--- a/hw/kvm/apic.c
+++ b/hw/kvm/apic.c
@@ -122,12 +122,19 @@ static void kvm_apic_init(APICCommonState *s)
                                    MSI_SPACE_SIZE);
 }
 
-static APICCommonInfo kvm_apic_info = {
-    .busdev.qdev.name = "kvm-apic",
-    .init = kvm_apic_init,
-    .set_base = kvm_apic_set_base,
-    .set_tpr = kvm_apic_set_tpr,
-    .external_nmi = kvm_apic_external_nmi,
+static void kvm_apic_class_init(ObjectClass *klass, void *data)
+{
+    APICCommonClass *k = APIC_COMMON_CLASS(klass);
+
+    k->init = kvm_apic_init;
+    k->set_base = kvm_apic_set_base;
+    k->set_tpr = kvm_apic_set_tpr;
+    k->external_nmi = kvm_apic_external_nmi;
+}
+
+static DeviceInfo kvm_apic_info = {
+    .name = "kvm-apic",
+    .class_init = kvm_apic_class_init,
 };
 
 static void kvm_apic_register_device(void)
diff --git a/hw/kvm/clock.c b/hw/kvm/clock.c
index bb28c08..b997d2a 100644
--- a/hw/kvm/clock.c
+++ b/hw/kvm/clock.c
@@ -92,12 +92,19 @@ static const VMStateDescription kvmclock_vmsd = {
     }
 };
 
-static SysBusDeviceInfo kvmclock_info = {
-    .qdev.name = "kvmclock",
-    .qdev.size = sizeof(KVMClockState),
-    .qdev.vmsd = &kvmclock_vmsd,
-    .qdev.no_user = 1,
-    .init = kvmclock_init,
+static void kvmclock_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = kvmclock_init;
+}
+
+static DeviceInfo kvmclock_info = {
+    .name = "kvmclock",
+    .size = sizeof(KVMClockState),
+    .vmsd = &kvmclock_vmsd,
+    .no_user = 1,
+    .class_init = kvmclock_class_init,
 };
 
 /* Note: Must be called after VCPU initialization. */
diff --git a/hw/kvm/ioapic.c b/hw/kvm/ioapic.c
index 10ffdd4..f8ea0cc 100644
--- a/hw/kvm/ioapic.c
+++ b/hw/kvm/ioapic.c
@@ -93,17 +93,24 @@ static void kvm_ioapic_init(IOAPICCommonState *s, int instance_no)
     qdev_init_gpio_in(&s->busdev.qdev, kvm_ioapic_set_irq, IOAPIC_NUM_PINS);
 }
 
-static IOAPICCommonInfo kvm_ioapic_info = {
-    .busdev.qdev.name  = "kvm-ioapic",
-    .busdev.qdev.size = sizeof(KVMIOAPICState),
-    .busdev.qdev.reset = kvm_ioapic_reset,
-    .busdev.qdev.props = (Property[]) {
+static void kvm_ioapic_class_init(ObjectClass *klass, void *data)
+{
+    IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
+
+    k->init      = kvm_ioapic_init;
+    k->pre_save  = kvm_ioapic_get;
+    k->post_load = kvm_ioapic_put;
+}
+
+static DeviceInfo kvm_ioapic_info = {
+    .name  = "kvm-ioapic",
+    .size = sizeof(KVMIOAPICState),
+    .reset = kvm_ioapic_reset,
+    .class_init = kvm_ioapic_class_init,
+    .props = (Property[]) {
         DEFINE_PROP_UINT32("gsi_base", KVMIOAPICState, kvm_gsi_base, 0),
         DEFINE_PROP_END_OF_LIST()
     },
-    .init      = kvm_ioapic_init,
-    .pre_save  = kvm_ioapic_get,
-    .post_load = kvm_ioapic_put,
 };
 
 static void kvm_ioapic_register_device(void)
diff --git a/hw/lan9118.c b/hw/lan9118.c
index 93e1896..3925b04 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -1238,16 +1238,25 @@ static int lan9118_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo lan9118_info = {
-    .init = lan9118_init1,
-    .qdev.name  = "lan9118",
-    .qdev.size  = sizeof(lan9118_state),
-    .qdev.reset = lan9118_reset,
-    .qdev.vmsd = &vmstate_lan9118,
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(lan9118_state, conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property lan9118_properties[] = {
+    DEFINE_NIC_PROPERTIES(lan9118_state, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void lan9118_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = lan9118_init1;
+}
+
+static DeviceInfo lan9118_info = {
+    .name = "lan9118",
+    .size = sizeof(lan9118_state),
+    .reset = lan9118_reset,
+    .vmsd = &vmstate_lan9118,
+    .props = lan9118_properties,
+    .class_init = lan9118_class_init,
 };
 
 static void lan9118_register_devices(void)
diff --git a/hw/lance.c b/hw/lance.c
index 7164700..969d766 100644
--- a/hw/lance.c
+++ b/hw/lance.c
@@ -137,18 +137,27 @@ static void lance_reset(DeviceState *dev)
     pcnet_h_reset(&d->state);
 }
 
-static SysBusDeviceInfo lance_info = {
-    .init       = lance_init,
-    .qdev.name  = "lance",
-    .qdev.fw_name  = "ethernet",
-    .qdev.size  = sizeof(SysBusPCNetState),
-    .qdev.reset = lance_reset,
-    .qdev.vmsd  = &vmstate_lance,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_PTR("dma", SysBusPCNetState, state.dma_opaque),
-        DEFINE_NIC_PROPERTIES(SysBusPCNetState, state.conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property lance_properties[] = {
+    DEFINE_PROP_PTR("dma", SysBusPCNetState, state.dma_opaque),
+    DEFINE_NIC_PROPERTIES(SysBusPCNetState, state.conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void lance_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = lance_init;
+}
+
+static DeviceInfo lance_info = {
+    .name = "lance",
+    .fw_name = "ethernet",
+    .size = sizeof(SysBusPCNetState),
+    .reset = lance_reset,
+    .vmsd = &vmstate_lance,
+    .props = lance_properties,
+    .class_init = lance_class_init,
 };
 
 static void lance_register_devices(void)
diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c
index 5454aa4..e25a409 100644
--- a/hw/lm32_juart.c
+++ b/hw/lm32_juart.c
@@ -134,12 +134,19 @@ static const VMStateDescription vmstate_lm32_juart = {
     }
 };
 
-static SysBusDeviceInfo lm32_juart_info = {
-    .init = lm32_juart_init,
-    .qdev.name  = "lm32-juart",
-    .qdev.size  = sizeof(LM32JuartState),
-    .qdev.vmsd  = &vmstate_lm32_juart,
-    .qdev.reset = juart_reset,
+static void lm32_juart_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = lm32_juart_init;
+}
+
+static DeviceInfo lm32_juart_info = {
+    .name = "lm32-juart",
+    .size = sizeof(LM32JuartState),
+    .vmsd = &vmstate_lm32_juart,
+    .reset = juart_reset,
+    .class_init = lm32_juart_class_init,
 };
 
 static void lm32_juart_register(void)
diff --git a/hw/lm32_pic.c b/hw/lm32_pic.c
index 8dd0050..b7b1886 100644
--- a/hw/lm32_pic.c
+++ b/hw/lm32_pic.c
@@ -174,12 +174,19 @@ static const VMStateDescription vmstate_lm32_pic = {
     }
 };
 
-static SysBusDeviceInfo lm32_pic_info = {
-    .init = lm32_pic_init,
-    .qdev.name  = "lm32-pic",
-    .qdev.size  = sizeof(LM32PicState),
-    .qdev.vmsd  = &vmstate_lm32_pic,
-    .qdev.reset = pic_reset,
+static void lm32_pic_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = lm32_pic_init;
+}
+
+static DeviceInfo lm32_pic_info = {
+    .name = "lm32-pic",
+    .size = sizeof(LM32PicState),
+    .vmsd = &vmstate_lm32_pic,
+    .reset = pic_reset,
+    .class_init = lm32_pic_class_init,
 };
 
 static void lm32_pic_register(void)
diff --git a/hw/lm32_sys.c b/hw/lm32_sys.c
index 83974ee..c83809e 100644
--- a/hw/lm32_sys.c
+++ b/hw/lm32_sys.c
@@ -141,16 +141,25 @@ static const VMStateDescription vmstate_lm32_sys = {
     }
 };
 
-static SysBusDeviceInfo lm32_sys_info = {
-    .init = lm32_sys_init,
-    .qdev.name  = "lm32-sys",
-    .qdev.size  = sizeof(LM32SysState),
-    .qdev.vmsd  = &vmstate_lm32_sys,
-    .qdev.reset = sys_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("base", LM32SysState, base, 0xffff0000),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property lm32_sys_properties[] = {
+    DEFINE_PROP_UINT32("base", LM32SysState, base, 0xffff0000),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void lm32_sys_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = lm32_sys_init;
+}
+
+static DeviceInfo lm32_sys_info = {
+    .name = "lm32-sys",
+    .size = sizeof(LM32SysState),
+    .vmsd = &vmstate_lm32_sys,
+    .reset = sys_reset,
+    .props = lm32_sys_properties,
+    .class_init = lm32_sys_class_init,
 };
 
 static void lm32_sys_register(void)
diff --git a/hw/lm32_timer.c b/hw/lm32_timer.c
index 115e1e9..932c1f0 100644
--- a/hw/lm32_timer.c
+++ b/hw/lm32_timer.c
@@ -199,18 +199,25 @@ static const VMStateDescription vmstate_lm32_timer = {
     }
 };
 
-static SysBusDeviceInfo lm32_timer_info = {
-    .init = lm32_timer_init,
-    .qdev.name  = "lm32-timer",
-    .qdev.size  = sizeof(LM32TimerState),
-    .qdev.vmsd  = &vmstate_lm32_timer,
-    .qdev.reset = timer_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32(
-                "frequency", LM32TimerState, freq_hz, DEFAULT_FREQUENCY
-        ),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property lm32_timer_properties[] = {
+    DEFINE_PROP_UINT32("frequency", LM32TimerState, freq_hz, DEFAULT_FREQUENCY),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void lm32_timer_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = lm32_timer_init;
+}
+
+static DeviceInfo lm32_timer_info = {
+    .name = "lm32-timer",
+    .size = sizeof(LM32TimerState),
+    .vmsd = &vmstate_lm32_timer,
+    .reset = timer_reset,
+    .props = lm32_timer_properties,
+    .class_init = lm32_timer_class_init,
 };
 
 static void lm32_timer_register(void)
diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c
index d013abd..ea7d00e 100644
--- a/hw/lm32_uart.c
+++ b/hw/lm32_uart.c
@@ -271,12 +271,19 @@ static const VMStateDescription vmstate_lm32_uart = {
     }
 };
 
-static SysBusDeviceInfo lm32_uart_info = {
-    .init = lm32_uart_init,
-    .qdev.name  = "lm32-uart",
-    .qdev.size  = sizeof(LM32UartState),
-    .qdev.vmsd  = &vmstate_lm32_uart,
-    .qdev.reset = uart_reset,
+static void lm32_uart_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = lm32_uart_init;
+}
+
+static DeviceInfo lm32_uart_info = {
+    .name = "lm32-uart",
+    .size = sizeof(LM32UartState),
+    .vmsd = &vmstate_lm32_uart,
+    .reset = uart_reset,
+    .class_init = lm32_uart_class_init,
 };
 
 static void lm32_uart_register(void)
diff --git a/hw/m48t59.c b/hw/m48t59.c
index 5912cd6..262cfb8 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -740,17 +740,26 @@ static DeviceInfo m48t59_isa_info = {
     }
 };
 
-static SysBusDeviceInfo m48t59_info = {
-    .init = m48t59_init1,
-    .qdev.name  = "m48t59",
-    .qdev.size = sizeof(M48t59SysBusState),
-    .qdev.reset = m48t59_reset_sysbus,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("size",    M48t59SysBusState, state.size,    -1),
-        DEFINE_PROP_UINT32("type",    M48t59SysBusState, state.type,    -1),
-        DEFINE_PROP_HEX32( "io_base", M48t59SysBusState, state.io_base,  0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property m48t59_properties[] = {
+    DEFINE_PROP_UINT32("size",    M48t59SysBusState, state.size,    -1),
+    DEFINE_PROP_UINT32("type",    M48t59SysBusState, state.type,    -1),
+    DEFINE_PROP_HEX32( "io_base", M48t59SysBusState, state.io_base,  0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void m48t59_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = m48t59_init1;
+}
+
+static DeviceInfo m48t59_info = {
+    .name = "m48t59",
+    .size = sizeof(M48t59SysBusState),
+    .reset = m48t59_reset_sysbus,
+    .props = m48t59_properties,
+    .class_init = m48t59_class_init,
 };
 
 static void m48t59_register_devices(void)
diff --git a/hw/marvell_88w8618_audio.c b/hw/marvell_88w8618_audio.c
index 409b1eb..355e492 100644
--- a/hw/marvell_88w8618_audio.c
+++ b/hw/marvell_88w8618_audio.c
@@ -272,16 +272,25 @@ static const VMStateDescription mv88w8618_audio_vmsd = {
     }
 };
 
-static SysBusDeviceInfo mv88w8618_audio_info = {
-    .init = mv88w8618_audio_init,
-    .qdev.name  = "mv88w8618_audio",
-    .qdev.size  = sizeof(mv88w8618_audio_state),
-    .qdev.reset = mv88w8618_audio_reset,
-    .qdev.vmsd  = &mv88w8618_audio_vmsd,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_PTR("wm8750", mv88w8618_audio_state, wm),
-        {/* end of list */}
-    }
+static Property mv88w8618_audio_properties[] = {
+    DEFINE_PROP_PTR("wm8750", mv88w8618_audio_state, wm),
+    {/* end of list */},
+};
+
+static void mv88w8618_audio_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = mv88w8618_audio_init;
+}
+
+static DeviceInfo mv88w8618_audio_info = {
+    .name = "mv88w8618_audio",
+    .size = sizeof(mv88w8618_audio_state),
+    .reset = mv88w8618_audio_reset,
+    .vmsd = &mv88w8618_audio_vmsd,
+    .props = mv88w8618_audio_properties,
+    .class_init = mv88w8618_audio_class_init,
 };
 
 static void mv88w8618_register_devices(void)
diff --git a/hw/milkymist-ac97.c b/hw/milkymist-ac97.c
index e824a49..7dce5bc 100644
--- a/hw/milkymist-ac97.c
+++ b/hw/milkymist-ac97.c
@@ -319,12 +319,19 @@ static const VMStateDescription vmstate_milkymist_ac97 = {
     }
 };
 
-static SysBusDeviceInfo milkymist_ac97_info = {
-    .init = milkymist_ac97_init,
-    .qdev.name  = "milkymist-ac97",
-    .qdev.size  = sizeof(MilkymistAC97State),
-    .qdev.vmsd  = &vmstate_milkymist_ac97,
-    .qdev.reset = milkymist_ac97_reset,
+static void milkymist_ac97_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = milkymist_ac97_init;
+}
+
+static DeviceInfo milkymist_ac97_info = {
+    .name = "milkymist-ac97",
+    .size = sizeof(MilkymistAC97State),
+    .vmsd = &vmstate_milkymist_ac97,
+    .reset = milkymist_ac97_reset,
+    .class_init = milkymist_ac97_class_init,
 };
 
 static void milkymist_ac97_register(void)
diff --git a/hw/milkymist-hpdmc.c b/hw/milkymist-hpdmc.c
index be575c9..46e8ae6 100644
--- a/hw/milkymist-hpdmc.c
+++ b/hw/milkymist-hpdmc.c
@@ -145,12 +145,19 @@ static const VMStateDescription vmstate_milkymist_hpdmc = {
     }
 };
 
-static SysBusDeviceInfo milkymist_hpdmc_info = {
-    .init = milkymist_hpdmc_init,
-    .qdev.name  = "milkymist-hpdmc",
-    .qdev.size  = sizeof(MilkymistHpdmcState),
-    .qdev.vmsd  = &vmstate_milkymist_hpdmc,
-    .qdev.reset = milkymist_hpdmc_reset,
+static void milkymist_hpdmc_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = milkymist_hpdmc_init;
+}
+
+static DeviceInfo milkymist_hpdmc_info = {
+    .name = "milkymist-hpdmc",
+    .size = sizeof(MilkymistHpdmcState),
+    .vmsd = &vmstate_milkymist_hpdmc,
+    .reset = milkymist_hpdmc_reset,
+    .class_init = milkymist_hpdmc_class_init,
 };
 
 static void milkymist_hpdmc_register(void)
diff --git a/hw/milkymist-memcard.c b/hw/milkymist-memcard.c
index 865a46c..97eb793 100644
--- a/hw/milkymist-memcard.c
+++ b/hw/milkymist-memcard.c
@@ -278,12 +278,19 @@ static const VMStateDescription vmstate_milkymist_memcard = {
     }
 };
 
-static SysBusDeviceInfo milkymist_memcard_info = {
-    .init = milkymist_memcard_init,
-    .qdev.name  = "milkymist-memcard",
-    .qdev.size  = sizeof(MilkymistMemcardState),
-    .qdev.vmsd  = &vmstate_milkymist_memcard,
-    .qdev.reset = milkymist_memcard_reset,
+static void milkymist_memcard_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = milkymist_memcard_init;
+}
+
+static DeviceInfo milkymist_memcard_info = {
+    .name = "milkymist-memcard",
+    .size = sizeof(MilkymistMemcardState),
+    .vmsd = &vmstate_milkymist_memcard,
+    .reset = milkymist_memcard_reset,
+    .class_init = milkymist_memcard_class_init,
 };
 
 static void milkymist_memcard_register(void)
diff --git a/hw/milkymist-minimac2.c b/hw/milkymist-minimac2.c
index 107ba65..1ac6c6a 100644
--- a/hw/milkymist-minimac2.c
+++ b/hw/milkymist-minimac2.c
@@ -516,19 +516,28 @@ static const VMStateDescription vmstate_milkymist_minimac2 = {
     }
 };
 
-static SysBusDeviceInfo milkymist_minimac2_info = {
-    .init = milkymist_minimac2_init,
-    .qdev.name  = "milkymist-minimac2",
-    .qdev.size  = sizeof(MilkymistMinimac2State),
-    .qdev.vmsd  = &vmstate_milkymist_minimac2,
-    .qdev.reset = milkymist_minimac2_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_TADDR("buffers_base", MilkymistMinimac2State,
-                buffers_base, 0),
-        DEFINE_NIC_PROPERTIES(MilkymistMinimac2State, conf),
-        DEFINE_PROP_STRING("phy_model", MilkymistMinimac2State, phy_model),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property milkymist_minimac2_properties[] = {
+    DEFINE_PROP_TADDR("buffers_base", MilkymistMinimac2State,
+    buffers_base, 0),
+    DEFINE_NIC_PROPERTIES(MilkymistMinimac2State, conf),
+    DEFINE_PROP_STRING("phy_model", MilkymistMinimac2State, phy_model),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void milkymist_minimac2_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = milkymist_minimac2_init;
+}
+
+static DeviceInfo milkymist_minimac2_info = {
+    .name = "milkymist-minimac2",
+    .size = sizeof(MilkymistMinimac2State),
+    .vmsd = &vmstate_milkymist_minimac2,
+    .reset = milkymist_minimac2_reset,
+    .props = milkymist_minimac2_properties,
+    .class_init = milkymist_minimac2_class_init,
 };
 
 static void milkymist_minimac2_register(void)
diff --git a/hw/milkymist-pfpu.c b/hw/milkymist-pfpu.c
index dc92eb6..b6ade5a 100644
--- a/hw/milkymist-pfpu.c
+++ b/hw/milkymist-pfpu.c
@@ -519,12 +519,19 @@ static const VMStateDescription vmstate_milkymist_pfpu = {
     }
 };
 
-static SysBusDeviceInfo milkymist_pfpu_info = {
-    .init = milkymist_pfpu_init,
-    .qdev.name  = "milkymist-pfpu",
-    .qdev.size  = sizeof(MilkymistPFPUState),
-    .qdev.vmsd  = &vmstate_milkymist_pfpu,
-    .qdev.reset = milkymist_pfpu_reset,
+static void milkymist_pfpu_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = milkymist_pfpu_init;
+}
+
+static DeviceInfo milkymist_pfpu_info = {
+    .name = "milkymist-pfpu",
+    .size = sizeof(MilkymistPFPUState),
+    .vmsd = &vmstate_milkymist_pfpu,
+    .reset = milkymist_pfpu_reset,
+    .class_init = milkymist_pfpu_class_init,
 };
 
 static void milkymist_pfpu_register(void)
diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c
index 83bd1c4..f4d2dad 100644
--- a/hw/milkymist-softusb.c
+++ b/hw/milkymist-softusb.c
@@ -297,27 +297,28 @@ static const VMStateDescription vmstate_milkymist_softusb = {
     }
 };
 
-static SysBusDeviceInfo milkymist_softusb_info = {
-    .init = milkymist_softusb_init,
-    .qdev.name  = "milkymist-softusb",
-    .qdev.size  = sizeof(MilkymistSoftUsbState),
-    .qdev.vmsd  = &vmstate_milkymist_softusb,
-    .qdev.reset = milkymist_softusb_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32(
-                "pmem_base", MilkymistSoftUsbState, pmem_base, 0xa0000000
-        ),
-        DEFINE_PROP_UINT32(
-                "pmem_size", MilkymistSoftUsbState, pmem_size, 0x00001000
-        ),
-        DEFINE_PROP_UINT32(
-                "dmem_base", MilkymistSoftUsbState, dmem_base, 0xa0020000
-        ),
-        DEFINE_PROP_UINT32(
-                "dmem_size", MilkymistSoftUsbState, dmem_size, 0x00002000
-        ),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property milkymist_softusb_properties[] = {
+    DEFINE_PROP_UINT32("pmem_base", MilkymistSoftUsbState, pmem_base, 0xa0000000),
+    DEFINE_PROP_UINT32("pmem_size", MilkymistSoftUsbState, pmem_size, 0x00001000),
+    DEFINE_PROP_UINT32("dmem_base", MilkymistSoftUsbState, dmem_base, 0xa0020000),
+    DEFINE_PROP_UINT32("dmem_size", MilkymistSoftUsbState, dmem_size, 0x00002000),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void milkymist_softusb_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = milkymist_softusb_init;
+}
+
+static DeviceInfo milkymist_softusb_info = {
+    .name = "milkymist-softusb",
+    .size = sizeof(MilkymistSoftUsbState),
+    .vmsd = &vmstate_milkymist_softusb,
+    .reset = milkymist_softusb_reset,
+    .props = milkymist_softusb_properties,
+    .class_init = milkymist_softusb_class_init,
 };
 
 static void milkymist_softusb_register(void)
diff --git a/hw/milkymist-sysctl.c b/hw/milkymist-sysctl.c
index bd2a298..4b017fa 100644
--- a/hw/milkymist-sysctl.c
+++ b/hw/milkymist-sysctl.c
@@ -292,23 +292,32 @@ static const VMStateDescription vmstate_milkymist_sysctl = {
     }
 };
 
-static SysBusDeviceInfo milkymist_sysctl_info = {
-    .init = milkymist_sysctl_init,
-    .qdev.name  = "milkymist-sysctl",
-    .qdev.size  = sizeof(MilkymistSysctlState),
-    .qdev.vmsd  = &vmstate_milkymist_sysctl,
-    .qdev.reset = milkymist_sysctl_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("frequency", MilkymistSysctlState,
-                freq_hz, 80000000),
-        DEFINE_PROP_UINT32("capabilities", MilkymistSysctlState,
-                capabilities, 0x00000000),
-        DEFINE_PROP_UINT32("systemid", MilkymistSysctlState,
-                systemid, 0x10014d31),
-        DEFINE_PROP_UINT32("gpio_strappings", MilkymistSysctlState,
-                strappings, 0x00000001),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property milkymist_sysctl_properties[] = {
+    DEFINE_PROP_UINT32("frequency", MilkymistSysctlState,
+    freq_hz, 80000000),
+    DEFINE_PROP_UINT32("capabilities", MilkymistSysctlState,
+    capabilities, 0x00000000),
+    DEFINE_PROP_UINT32("systemid", MilkymistSysctlState,
+    systemid, 0x10014d31),
+    DEFINE_PROP_UINT32("gpio_strappings", MilkymistSysctlState,
+    strappings, 0x00000001),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void milkymist_sysctl_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = milkymist_sysctl_init;
+}
+
+static DeviceInfo milkymist_sysctl_info = {
+    .name = "milkymist-sysctl",
+    .size = sizeof(MilkymistSysctlState),
+    .vmsd = &vmstate_milkymist_sysctl,
+    .reset = milkymist_sysctl_reset,
+    .props = milkymist_sysctl_properties,
+    .class_init = milkymist_sysctl_class_init,
 };
 
 static void milkymist_sysctl_register(void)
diff --git a/hw/milkymist-tmu2.c b/hw/milkymist-tmu2.c
index 20110e5..4004a12 100644
--- a/hw/milkymist-tmu2.c
+++ b/hw/milkymist-tmu2.c
@@ -465,12 +465,19 @@ static const VMStateDescription vmstate_milkymist_tmu2 = {
     }
 };
 
-static SysBusDeviceInfo milkymist_tmu2_info = {
-    .init = milkymist_tmu2_init,
-    .qdev.name  = "milkymist-tmu2",
-    .qdev.size  = sizeof(MilkymistTMU2State),
-    .qdev.vmsd  = &vmstate_milkymist_tmu2,
-    .qdev.reset = milkymist_tmu2_reset,
+static void milkymist_tmu2_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = milkymist_tmu2_init;
+}
+
+static DeviceInfo milkymist_tmu2_info = {
+    .name = "milkymist-tmu2",
+    .size = sizeof(MilkymistTMU2State),
+    .vmsd = &vmstate_milkymist_tmu2,
+    .reset = milkymist_tmu2_reset,
+    .class_init = milkymist_tmu2_class_init,
 };
 
 static void milkymist_tmu2_register(void)
diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c
index eaf1c0d..312976d 100644
--- a/hw/milkymist-uart.c
+++ b/hw/milkymist-uart.c
@@ -218,12 +218,19 @@ static const VMStateDescription vmstate_milkymist_uart = {
     }
 };
 
-static SysBusDeviceInfo milkymist_uart_info = {
-    .init = milkymist_uart_init,
-    .qdev.name  = "milkymist-uart",
-    .qdev.size  = sizeof(MilkymistUartState),
-    .qdev.vmsd  = &vmstate_milkymist_uart,
-    .qdev.reset = milkymist_uart_reset,
+static void milkymist_uart_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = milkymist_uart_init;
+}
+
+static DeviceInfo milkymist_uart_info = {
+    .name = "milkymist-uart",
+    .size = sizeof(MilkymistUartState),
+    .vmsd = &vmstate_milkymist_uart,
+    .reset = milkymist_uart_reset,
+    .class_init = milkymist_uart_class_init,
 };
 
 static void milkymist_uart_register(void)
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index 108115e..81d31fa 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -299,17 +299,26 @@ static const VMStateDescription vmstate_milkymist_vgafb = {
     }
 };
 
-static SysBusDeviceInfo milkymist_vgafb_info = {
-    .init = milkymist_vgafb_init,
-    .qdev.name  = "milkymist-vgafb",
-    .qdev.size  = sizeof(MilkymistVgafbState),
-    .qdev.vmsd  = &vmstate_milkymist_vgafb,
-    .qdev.reset = milkymist_vgafb_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("fb_offset", MilkymistVgafbState, fb_offset, 0x0),
-        DEFINE_PROP_UINT32("fb_mask", MilkymistVgafbState, fb_mask, 0xffffffff),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property milkymist_vgafb_properties[] = {
+    DEFINE_PROP_UINT32("fb_offset", MilkymistVgafbState, fb_offset, 0x0),
+    DEFINE_PROP_UINT32("fb_mask", MilkymistVgafbState, fb_mask, 0xffffffff),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void milkymist_vgafb_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = milkymist_vgafb_init;
+}
+
+static DeviceInfo milkymist_vgafb_info = {
+    .name = "milkymist-vgafb",
+    .size = sizeof(MilkymistVgafbState),
+    .vmsd = &vmstate_milkymist_vgafb,
+    .reset = milkymist_vgafb_reset,
+    .props = milkymist_vgafb_properties,
+    .class_init = milkymist_vgafb_class_init,
 };
 
 static void milkymist_vgafb_register(void)
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 4a4f76d..64603ce 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -1007,11 +1007,18 @@ static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev)
     return 0;
 }
 
-static SysBusDeviceInfo mips_malta_device = {
-    .init = mips_malta_sysbus_device_init,
-    .qdev.name  = "mips-malta",
-    .qdev.size  = sizeof(MaltaState),
-    .qdev.props = (Property[]) {
+static void mips_malta_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = mips_malta_sysbus_device_init;
+}
+
+static DeviceInfo mips_malta_device = {
+    .name  = "mips-malta",
+    .size  = sizeof(MaltaState),
+    .class_init = mips_malta_class_init,
+    .props = (Property[]) {
         DEFINE_PROP_END_OF_LIST(),
     }
 };
@@ -1026,7 +1033,7 @@ static QEMUMachine mips_malta_machine = {
 
 static void mips_malta_device_init(void)
 {
-    sysbus_register_withprop(&mips_malta_device);
+    sysbus_qdev_register(&mips_malta_device);
 }
 
 static void mips_malta_machine_init(void)
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index 0f80cfe..8cf9161 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -252,17 +252,26 @@ static void mipsnet_sysbus_reset(DeviceState *dev)
     mipsnet_reset(s);
 }
 
-static SysBusDeviceInfo mipsnet_info = {
-    .init = mipsnet_sysbus_init,
-    .qdev.name = "mipsnet",
-    .qdev.desc = "MIPS Simulator network device",
-    .qdev.size = sizeof(MIPSnetState),
-    .qdev.vmsd = &vmstate_mipsnet,
-    .qdev.reset = mipsnet_sysbus_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(MIPSnetState, conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property mipsnet_properties[] = {
+    DEFINE_NIC_PROPERTIES(MIPSnetState, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void mipsnet_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = mipsnet_sysbus_init;
+}
+
+static DeviceInfo mipsnet_info = {
+    .name = "mipsnet",
+    .desc = "MIPS Simulator network device",
+    .size = sizeof(MIPSnetState),
+    .vmsd = &vmstate_mipsnet,
+    .reset = mipsnet_sysbus_reset,
+    .props = mipsnet_properties,
+    .class_init = mipsnet_class_init,
 };
 
 static void mipsnet_register_devices(void)
diff --git a/hw/mpc8544_guts.c b/hw/mpc8544_guts.c
index f01b38c..ec6bb4f 100644
--- a/hw/mpc8544_guts.c
+++ b/hw/mpc8544_guts.c
@@ -121,10 +121,17 @@ static int mpc8544_guts_initfn(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo mpc8544_guts_info = {
-    .init         = mpc8544_guts_initfn,
-    .qdev.name    = "mpc8544-guts",
-    .qdev.size    = sizeof(GutsState),
+static void mpc8544_guts_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = mpc8544_guts_initfn;
+}
+
+static DeviceInfo mpc8544_guts_info = {
+    .name = "mpc8544-guts",
+    .size = sizeof(GutsState),
+    .class_init = mpc8544_guts_class_init,
 };
 
 static void mpc8544_guts_register(void)
diff --git a/hw/mst_fpga.c b/hw/mst_fpga.c
index 8bfa5dd..513bfa6 100644
--- a/hw/mst_fpga.c
+++ b/hw/mst_fpga.c
@@ -238,12 +238,19 @@ static VMStateDescription vmstate_mst_fpga_regs = {
 	},
 };
 
-static SysBusDeviceInfo mst_fpga_info = {
-	.init = mst_fpga_init,
-	.qdev.name = "mainstone-fpga",
-	.qdev.desc = "Mainstone II FPGA",
-	.qdev.size = sizeof(mst_irq_state),
-	.qdev.vmsd = &vmstate_mst_fpga_regs,
+static void mst_fpga_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = mst_fpga_init;
+}
+
+static DeviceInfo mst_fpga_info = {
+    .name = "mainstone-fpga",
+    .desc = "Mainstone II FPGA",
+    .size = sizeof(mst_irq_state),
+    .vmsd = &vmstate_mst_fpga_regs,
+    .class_init = mst_fpga_class_init,
 };
 
 static void mst_fpga_register(void)
diff --git a/hw/musicpal.c b/hw/musicpal.c
index bca5ee9..a2fc4bb 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -412,15 +412,24 @@ static const VMStateDescription mv88w8618_eth_vmsd = {
     }
 };
 
-static SysBusDeviceInfo mv88w8618_eth_info = {
-    .init = mv88w8618_eth_init,
-    .qdev.name = "mv88w8618_eth",
-    .qdev.size = sizeof(mv88w8618_eth_state),
-    .qdev.vmsd = &mv88w8618_eth_vmsd,
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(mv88w8618_eth_state, conf),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property mv88w8618_eth_properties[] = {
+    DEFINE_NIC_PROPERTIES(mv88w8618_eth_state, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void mv88w8618_eth_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = mv88w8618_eth_init;
+}
+
+static DeviceInfo mv88w8618_eth_info = {
+    .name = "mv88w8618_eth",
+    .size = sizeof(mv88w8618_eth_state),
+    .vmsd = &mv88w8618_eth_vmsd,
+    .props = mv88w8618_eth_properties,
+    .class_init = mv88w8618_eth_class_init,
 };
 
 /* LCD register offsets */
@@ -624,11 +633,18 @@ static const VMStateDescription musicpal_lcd_vmsd = {
     }
 };
 
-static SysBusDeviceInfo musicpal_lcd_info = {
-    .init = musicpal_lcd_init,
-    .qdev.name = "musicpal_lcd",
-    .qdev.size = sizeof(musicpal_lcd_state),
-    .qdev.vmsd = &musicpal_lcd_vmsd,
+static void musicpal_lcd_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = musicpal_lcd_init;
+}
+
+static DeviceInfo musicpal_lcd_info = {
+    .name = "musicpal_lcd",
+    .size = sizeof(musicpal_lcd_state),
+    .vmsd = &musicpal_lcd_vmsd,
+    .class_init = musicpal_lcd_class_init,
 };
 
 /* PIC register offsets */
@@ -733,12 +749,19 @@ static const VMStateDescription mv88w8618_pic_vmsd = {
     }
 };
 
-static SysBusDeviceInfo mv88w8618_pic_info = {
-    .init = mv88w8618_pic_init,
-    .qdev.name = "mv88w8618_pic",
-    .qdev.size = sizeof(mv88w8618_pic_state),
-    .qdev.reset = mv88w8618_pic_reset,
-    .qdev.vmsd = &mv88w8618_pic_vmsd,
+static void mv88w8618_pic_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = mv88w8618_pic_init;
+}
+
+static DeviceInfo mv88w8618_pic_info = {
+    .name = "mv88w8618_pic",
+    .size = sizeof(mv88w8618_pic_state),
+    .reset = mv88w8618_pic_reset,
+    .vmsd = &mv88w8618_pic_vmsd,
+    .class_init = mv88w8618_pic_class_init,
 };
 
 /* PIT register offsets */
@@ -901,12 +924,19 @@ static const VMStateDescription mv88w8618_pit_vmsd = {
     }
 };
 
-static SysBusDeviceInfo mv88w8618_pit_info = {
-    .init = mv88w8618_pit_init,
-    .qdev.name  = "mv88w8618_pit",
-    .qdev.size  = sizeof(mv88w8618_pit_state),
-    .qdev.reset = mv88w8618_pit_reset,
-    .qdev.vmsd  = &mv88w8618_pit_vmsd,
+static void mv88w8618_pit_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = mv88w8618_pit_init;
+}
+
+static DeviceInfo mv88w8618_pit_info = {
+    .name = "mv88w8618_pit",
+    .size = sizeof(mv88w8618_pit_state),
+    .reset = mv88w8618_pit_reset,
+    .vmsd = &mv88w8618_pit_vmsd,
+    .class_init = mv88w8618_pit_class_init,
 };
 
 /* Flash config register offsets */
@@ -973,11 +1003,18 @@ static const VMStateDescription mv88w8618_flashcfg_vmsd = {
     }
 };
 
-static SysBusDeviceInfo mv88w8618_flashcfg_info = {
-    .init = mv88w8618_flashcfg_init,
-    .qdev.name  = "mv88w8618_flashcfg",
-    .qdev.size  = sizeof(mv88w8618_flashcfg_state),
-    .qdev.vmsd  = &mv88w8618_flashcfg_vmsd,
+static void mv88w8618_flashcfg_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = mv88w8618_flashcfg_init;
+}
+
+static DeviceInfo mv88w8618_flashcfg_info = {
+    .name = "mv88w8618_flashcfg",
+    .size = sizeof(mv88w8618_flashcfg_state),
+    .vmsd = &mv88w8618_flashcfg_vmsd,
+    .class_init = mv88w8618_flashcfg_class_init,
 };
 
 /* Misc register offsets */
@@ -1285,12 +1322,19 @@ static const VMStateDescription musicpal_gpio_vmsd = {
     }
 };
 
-static SysBusDeviceInfo musicpal_gpio_info = {
-    .init = musicpal_gpio_init,
-    .qdev.name  = "musicpal_gpio",
-    .qdev.size  = sizeof(musicpal_gpio_state),
-    .qdev.reset = musicpal_gpio_reset,
-    .qdev.vmsd  = &musicpal_gpio_vmsd,
+static void musicpal_gpio_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = musicpal_gpio_init;
+}
+
+static DeviceInfo musicpal_gpio_info = {
+    .name = "musicpal_gpio",
+    .size = sizeof(musicpal_gpio_state),
+    .reset = musicpal_gpio_reset,
+    .vmsd = &musicpal_gpio_vmsd,
+    .class_init = musicpal_gpio_class_init,
 };
 
 /* Keyboard codes & masks */
@@ -1431,11 +1475,18 @@ static const VMStateDescription musicpal_key_vmsd = {
     }
 };
 
-static SysBusDeviceInfo musicpal_key_info = {
-    .init = musicpal_key_init,
-    .qdev.name  = "musicpal_key",
-    .qdev.size  = sizeof(musicpal_key_state),
-    .qdev.vmsd  = &musicpal_key_vmsd,
+static void musicpal_key_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = musicpal_key_init;
+}
+
+static DeviceInfo musicpal_key_info = {
+    .name = "musicpal_key",
+    .size = sizeof(musicpal_key_state),
+    .vmsd = &musicpal_key_vmsd,
+    .class_init = musicpal_key_class_init,
 };
 
 static struct arm_boot_info musicpal_binfo = {
@@ -1602,14 +1653,26 @@ static void musicpal_machine_init(void)
 
 machine_init(musicpal_machine_init);
 
+static void mv88w8618_wlan_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = mv88w8618_wlan_init;
+}
+
+static DeviceInfo mv88w8618_wlan_info = {
+    .name = "mv88w8618_wlan",
+    .size = sizeof(SysBusDevice),
+    .class_init = mv88w8618_wlan_class_init,
+};
+
 static void musicpal_register_devices(void)
 {
     sysbus_register_withprop(&mv88w8618_pic_info);
     sysbus_register_withprop(&mv88w8618_pit_info);
     sysbus_register_withprop(&mv88w8618_flashcfg_info);
     sysbus_register_withprop(&mv88w8618_eth_info);
-    sysbus_register_dev("mv88w8618_wlan", sizeof(SysBusDevice),
-                        mv88w8618_wlan_init);
+    sysbus_qdev_register(&mv88w8618_wlan_info);
     sysbus_register_withprop(&musicpal_lcd_info);
     sysbus_register_withprop(&musicpal_gpio_info);
     sysbus_register_withprop(&musicpal_key_info);
diff --git a/hw/nand.c b/hw/nand.c
index 8597aa6..6248731 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -417,18 +417,27 @@ static int nand_device_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo nand_info = {
-    .init = nand_device_init,
-    .qdev.name = "nand",
-    .qdev.size = sizeof(NANDFlashState),
-    .qdev.reset = nand_reset,
-    .qdev.vmsd = &vmstate_nand,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT8("manufacturer_id", NANDFlashState, manf_id, 0),
-        DEFINE_PROP_UINT8("chip_id", NANDFlashState, chip_id, 0),
-        DEFINE_PROP_DRIVE("drive", NANDFlashState, bdrv),
-        DEFINE_PROP_END_OF_LIST()
-    }
+static Property nand_properties[] = {
+    DEFINE_PROP_UINT8("manufacturer_id", NANDFlashState, manf_id, 0),
+    DEFINE_PROP_UINT8("chip_id", NANDFlashState, chip_id, 0),
+    DEFINE_PROP_DRIVE("drive", NANDFlashState, bdrv),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void nand_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = nand_device_init;
+}
+
+static DeviceInfo nand_info = {
+    .name = "nand",
+    .size = sizeof(NANDFlashState),
+    .reset = nand_reset,
+    .vmsd = &vmstate_nand,
+    .props = nand_properties,
+    .class_init = nand_class_init,
 };
 
 static void nand_create_device(void)
diff --git a/hw/omap_gpio.c b/hw/omap_gpio.c
index 29147be..97d2d93 100644
--- a/hw/omap_gpio.c
+++ b/hw/omap_gpio.c
@@ -731,34 +731,52 @@ static int omap2_gpio_init(SysBusDevice *dev)
  * translation.)
  */
 
-static SysBusDeviceInfo omap_gpio_info = {
-    .init = omap_gpio_init,
-    .qdev.name = "omap-gpio",
-    .qdev.size = sizeof(struct omap_gpif_s),
-    .qdev.reset = omap_gpif_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_INT32("mpu_model", struct omap_gpif_s, mpu_model, 0),
-        DEFINE_PROP_PTR("clk", struct omap_gpif_s, clk),
-        DEFINE_PROP_END_OF_LIST()
-    }
+static Property omap_gpio_properties[] = {
+    DEFINE_PROP_INT32("mpu_model", struct omap_gpif_s, mpu_model, 0),
+    DEFINE_PROP_PTR("clk", struct omap_gpif_s, clk),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
-static SysBusDeviceInfo omap2_gpio_info = {
-    .init = omap2_gpio_init,
-    .qdev.name = "omap2-gpio",
-    .qdev.size = sizeof(struct omap2_gpif_s),
-    .qdev.reset = omap2_gpif_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_INT32("mpu_model", struct omap2_gpif_s, mpu_model, 0),
-        DEFINE_PROP_PTR("iclk", struct omap2_gpif_s, iclk),
-        DEFINE_PROP_PTR("fclk0", struct omap2_gpif_s, fclk[0]),
-        DEFINE_PROP_PTR("fclk1", struct omap2_gpif_s, fclk[1]),
-        DEFINE_PROP_PTR("fclk2", struct omap2_gpif_s, fclk[2]),
-        DEFINE_PROP_PTR("fclk3", struct omap2_gpif_s, fclk[3]),
-        DEFINE_PROP_PTR("fclk4", struct omap2_gpif_s, fclk[4]),
-        DEFINE_PROP_PTR("fclk5", struct omap2_gpif_s, fclk[5]),
-        DEFINE_PROP_END_OF_LIST()
-    }
+static void omap_gpio_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = omap_gpio_init;
+}
+
+static DeviceInfo omap_gpio_info = {
+    .name = "omap-gpio",
+    .size = sizeof(struct omap_gpif_s),
+    .reset = omap_gpif_reset,
+    .props = omap_gpio_properties,
+    .class_init = omap_gpio_class_init,
+};
+
+static Property omap2_gpio_properties[] = {
+    DEFINE_PROP_INT32("mpu_model", struct omap2_gpif_s, mpu_model, 0),
+    DEFINE_PROP_PTR("iclk", struct omap2_gpif_s, iclk),
+    DEFINE_PROP_PTR("fclk0", struct omap2_gpif_s, fclk[0]),
+    DEFINE_PROP_PTR("fclk1", struct omap2_gpif_s, fclk[1]),
+    DEFINE_PROP_PTR("fclk2", struct omap2_gpif_s, fclk[2]),
+    DEFINE_PROP_PTR("fclk3", struct omap2_gpif_s, fclk[3]),
+    DEFINE_PROP_PTR("fclk4", struct omap2_gpif_s, fclk[4]),
+    DEFINE_PROP_PTR("fclk5", struct omap2_gpif_s, fclk[5]),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void omap2_gpio_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = omap2_gpio_init;
+}
+
+static DeviceInfo omap2_gpio_info = {
+    .name = "omap2-gpio",
+    .size = sizeof(struct omap2_gpif_s),
+    .reset = omap2_gpif_reset,
+    .props = omap2_gpio_properties,
+    .class_init = omap2_gpio_class_init,
 };
 
 static void omap_gpio_register_device(void)
diff --git a/hw/omap_intc.c b/hw/omap_intc.c
index fc53ec7..310fe2d 100644
--- a/hw/omap_intc.c
+++ b/hw/omap_intc.c
@@ -373,16 +373,25 @@ static int omap_intc_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo omap_intc_info = {
-    .init = omap_intc_init,
-    .qdev.name = "omap-intc",
-    .qdev.size = sizeof(struct omap_intr_handler_s),
-    .qdev.reset = omap_inth_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("size", struct omap_intr_handler_s, size, 0x100),
-        DEFINE_PROP_PTR("clk", struct omap_intr_handler_s, iclk),
-        DEFINE_PROP_END_OF_LIST()
-    }
+static Property omap_intc_properties[] = {
+    DEFINE_PROP_UINT32("size", struct omap_intr_handler_s, size, 0x100),
+    DEFINE_PROP_PTR("clk", struct omap_intr_handler_s, iclk),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void omap_intc_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = omap_intc_init;
+}
+
+static DeviceInfo omap_intc_info = {
+    .name = "omap-intc",
+    .size = sizeof(struct omap_intr_handler_s),
+    .reset = omap_inth_reset,
+    .props = omap_intc_properties,
+    .class_init = omap_intc_class_init,
 };
 
 static uint64_t omap2_inth_read(void *opaque, target_phys_addr_t addr,
@@ -604,18 +613,27 @@ static int omap2_intc_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo omap2_intc_info = {
-    .init = omap2_intc_init,
-    .qdev.name = "omap2-intc",
-    .qdev.size = sizeof(struct omap_intr_handler_s),
-    .qdev.reset = omap_inth_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT8("revision", struct omap_intr_handler_s,
-                          revision, 0x21),
-        DEFINE_PROP_PTR("iclk", struct omap_intr_handler_s, iclk),
-        DEFINE_PROP_PTR("fclk", struct omap_intr_handler_s, fclk),
-        DEFINE_PROP_END_OF_LIST()
-    }
+static Property omap2_intc_properties[] = {
+    DEFINE_PROP_UINT8("revision", struct omap_intr_handler_s,
+    revision, 0x21),
+    DEFINE_PROP_PTR("iclk", struct omap_intr_handler_s, iclk),
+    DEFINE_PROP_PTR("fclk", struct omap_intr_handler_s, fclk),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void omap2_intc_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = omap2_intc_init;
+}
+
+static DeviceInfo omap2_intc_info = {
+    .name = "omap2-intc",
+    .size = sizeof(struct omap_intr_handler_s),
+    .reset = omap_inth_reset,
+    .props = omap2_intc_properties,
+    .class_init = omap2_intc_class_init,
 };
 
 static void omap_intc_register_device(void)
diff --git a/hw/onenand.c b/hw/onenand.c
index 33c9718..e20d4d9 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -802,19 +802,28 @@ static int onenand_initfn(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo onenand_info = {
-    .init = onenand_initfn,
-    .qdev.name = "onenand",
-    .qdev.size = sizeof(OneNANDState),
-    .qdev.reset = onenand_system_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT16("manufacturer_id", OneNANDState, id.man, 0),
-        DEFINE_PROP_UINT16("device_id", OneNANDState, id.dev, 0),
-        DEFINE_PROP_UINT16("version_id", OneNANDState, id.ver, 0),
-        DEFINE_PROP_INT32("shift", OneNANDState, shift, 0),
-        DEFINE_PROP_DRIVE("drive", OneNANDState, bdrv),
-        DEFINE_PROP_END_OF_LIST()
-    }
+static Property onenand_properties[] = {
+    DEFINE_PROP_UINT16("manufacturer_id", OneNANDState, id.man, 0),
+    DEFINE_PROP_UINT16("device_id", OneNANDState, id.dev, 0),
+    DEFINE_PROP_UINT16("version_id", OneNANDState, id.ver, 0),
+    DEFINE_PROP_INT32("shift", OneNANDState, shift, 0),
+    DEFINE_PROP_DRIVE("drive", OneNANDState, bdrv),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void onenand_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = onenand_initfn;
+}
+
+static DeviceInfo onenand_info = {
+    .name = "onenand",
+    .size = sizeof(OneNANDState),
+    .reset = onenand_system_reset,
+    .props = onenand_properties,
+    .class_init = onenand_class_init,
 };
 
 static void onenand_register_device(void)
diff --git a/hw/opencores_eth.c b/hw/opencores_eth.c
index 5161b0c..1f45506 100644
--- a/hw/opencores_eth.c
+++ b/hw/opencores_eth.c
@@ -727,16 +727,25 @@ static void qdev_open_eth_reset(DeviceState *dev)
     open_eth_reset(d);
 }
 
-static SysBusDeviceInfo open_eth_info = {
-    .qdev.name  = "open_eth",
-    .qdev.desc  = "Opencores 10/100 Mbit Ethernet",
-    .qdev.size  = sizeof(OpenEthState),
-    .qdev.reset = qdev_open_eth_reset,
-    .init       = sysbus_open_eth_init,
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(OpenEthState, conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property open_eth_properties[] = {
+    DEFINE_NIC_PROPERTIES(OpenEthState, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void open_eth_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = sysbus_open_eth_init;
+}
+
+static DeviceInfo open_eth_info = {
+    .name = "open_eth",
+    .desc = "Opencores 10/100 Mbit Ethernet",
+    .size = sizeof(OpenEthState),
+    .reset = qdev_open_eth_reset,
+    .props = open_eth_properties,
+    .class_init = open_eth_class_init,
 };
 
 static void open_eth_register_devices(void)
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 787db4e..8b01782 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -566,12 +566,19 @@ static DeviceInfo i440fx_info = {
     .class_init = i440fx_class_init,
 };
 
-static SysBusDeviceInfo i440fx_pcihost_info = {
-    .init         = i440fx_pcihost_initfn,
-    .qdev.name    = "i440FX-pcihost",
-    .qdev.fw_name = "pci",
-    .qdev.size    = sizeof(I440FXState),
-    .qdev.no_user = 1,
+static void i440fx_pcihost_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = i440fx_pcihost_initfn;
+}
+
+static DeviceInfo i440fx_pcihost_info = {
+    .name = "i440FX-pcihost",
+    .fw_name = "pci",
+    .size = sizeof(I440FXState),
+    .no_user = 1,
+    .class_init = i440fx_pcihost_class_init,
 };
 
 static void i440fx_register(void)
diff --git a/hw/pl011.c b/hw/pl011.c
index 1b05d76..088aa44 100644
--- a/hw/pl011.c
+++ b/hw/pl011.c
@@ -278,22 +278,46 @@ static int pl011_init(SysBusDevice *dev, const unsigned char *id)
     return 0;
 }
 
-static int pl011_init_arm(SysBusDevice *dev)
+static int pl011_arm_init(SysBusDevice *dev)
 {
     return pl011_init(dev, pl011_id_arm);
 }
 
-static int pl011_init_luminary(SysBusDevice *dev)
+static int pl011_luminary_init(SysBusDevice *dev)
 {
     return pl011_init(dev, pl011_id_luminary);
 }
 
+static void pl011_arm_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = pl011_arm_init;
+}
+
+static DeviceInfo pl011_arm_info = {
+    .name = "pl011",
+    .size = sizeof(pl011_state),
+    .class_init = pl011_arm_class_init,
+};
+
+static void pl011_luminary_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = pl011_luminary_init;
+}
+
+static DeviceInfo pl011_luminary_info = {
+    .name = "pl011_luminary",
+    .size = sizeof(pl011_state),
+    .class_init = pl011_luminary_class_init,
+};
+
 static void pl011_register_devices(void)
 {
-    sysbus_register_dev("pl011", sizeof(pl011_state),
-                        pl011_init_arm);
-    sysbus_register_dev("pl011_luminary", sizeof(pl011_state),
-                        pl011_init_luminary);
+    sysbus_qdev_register(&pl011_arm_info);
+    sysbus_qdev_register(&pl011_luminary_info);
 }
 
 device_init(pl011_register_devices)
diff --git a/hw/pl022.c b/hw/pl022.c
index d43e4a2..4f62712 100644
--- a/hw/pl022.c
+++ b/hw/pl022.c
@@ -285,9 +285,22 @@ static int pl022_init(SysBusDevice *dev)
     return 0;
 }
 
+static void pl022_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = pl022_init;
+}
+
+static DeviceInfo pl022_info = {
+    .name = "pl022",
+    .size = sizeof(pl022_state),
+    .class_init = pl022_class_init,
+};
+
 static void pl022_register_devices(void)
 {
-    sysbus_register_dev("pl022", sizeof(pl022_state), pl022_init);
+    sysbus_qdev_register(&pl022_info);
 }
 
 device_init(pl022_register_devices)
diff --git a/hw/pl031.c b/hw/pl031.c
index 2fb0c8e..4cb8528 100644
--- a/hw/pl031.c
+++ b/hw/pl031.c
@@ -213,12 +213,19 @@ static int pl031_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo pl031_info = {
-    .init = pl031_init,
-    .qdev.name = "pl031",
-    .qdev.size = sizeof(pl031_state),
-    .qdev.vmsd = &vmstate_pl031,
-    .qdev.no_user = 1,
+static void pl031_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pl031_init;
+}
+
+static DeviceInfo pl031_info = {
+    .name = "pl031",
+    .size = sizeof(pl031_state),
+    .vmsd = &vmstate_pl031,
+    .no_user = 1,
+    .class_init = pl031_class_init,
 };
 
 static void pl031_register_devices(void)
diff --git a/hw/pl041.c b/hw/pl041.c
index 4585ccf..0482851 100644
--- a/hw/pl041.c
+++ b/hw/pl041.c
@@ -613,19 +613,27 @@ static const VMStateDescription vmstate_pl041 = {
     }
 };
 
-static SysBusDeviceInfo pl041_device_info = {
-    .init = pl041_init,
-    .qdev.name = "pl041",
-    .qdev.size = sizeof(pl041_state),
-    .qdev.vmsd = &vmstate_pl041,
-    .qdev.reset = pl041_device_reset,
-    .qdev.no_user = 1,
-    .qdev.props = (Property[]) {
-        /* Non-compact FIFO depth property */
-        DEFINE_PROP_UINT32("nc_fifo_depth", pl041_state,
-                           fifo_depth, DEFAULT_FIFO_DEPTH),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property pl041_device_properties[] = {
+    /* Non-compact FIFO depth property */
+    DEFINE_PROP_UINT32("nc_fifo_depth", pl041_state, fifo_depth, DEFAULT_FIFO_DEPTH),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pl041_device_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pl041_init;
+}
+
+static DeviceInfo pl041_device_info = {
+    .name = "pl041",
+    .size = sizeof(pl041_state),
+    .vmsd = &vmstate_pl041,
+    .reset = pl041_device_reset,
+    .no_user = 1,
+    .props = pl041_device_properties,
+    .class_init = pl041_device_class_init,
 };
 
 static void pl041_register_device(void)
diff --git a/hw/pl050.c b/hw/pl050.c
index 8182a1c..5f60508 100644
--- a/hw/pl050.c
+++ b/hw/pl050.c
@@ -157,18 +157,32 @@ static int pl050_init_mouse(SysBusDevice *dev)
     return pl050_init(dev, 1);
 }
 
-static SysBusDeviceInfo pl050_kbd_info = {
-    .init = pl050_init_keyboard,
-    .qdev.name  = "pl050_keyboard",
-    .qdev.size  = sizeof(pl050_state),
-    .qdev.vmsd = &vmstate_pl050,
+static void pl050_kbd_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pl050_init_keyboard;
+}
+
+static DeviceInfo pl050_kbd_info = {
+    .name = "pl050_keyboard",
+    .size = sizeof(pl050_state),
+    .vmsd = &vmstate_pl050,
+    .class_init = pl050_kbd_class_init,
 };
 
-static SysBusDeviceInfo pl050_mouse_info = {
-    .init = pl050_init_mouse,
-    .qdev.name  = "pl050_mouse",
-    .qdev.size  = sizeof(pl050_state),
-    .qdev.vmsd = &vmstate_pl050,
+static void pl050_mouse_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pl050_init_mouse;
+}
+
+static DeviceInfo pl050_mouse_info = {
+    .name = "pl050_mouse",
+    .size = sizeof(pl050_state),
+    .vmsd = &vmstate_pl050,
+    .class_init = pl050_mouse_class_init,
 };
 
 static void pl050_register_devices(void)
diff --git a/hw/pl061.c b/hw/pl061.c
index f33ae84..9dc9406 100644
--- a/hw/pl061.c
+++ b/hw/pl061.c
@@ -293,18 +293,32 @@ static int pl061_init_arm(SysBusDevice *dev)
     return pl061_init(dev, pl061_id);
 }
 
-static SysBusDeviceInfo pl061_info = {
-    .init = pl061_init_arm,
-    .qdev.name = "pl061",
-    .qdev.size = sizeof(pl061_state),
-    .qdev.vmsd = &vmstate_pl061,
+static void pl061_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pl061_init_arm;
+}
+
+static DeviceInfo pl061_info = {
+    .name = "pl061",
+    .size = sizeof(pl061_state),
+    .vmsd = &vmstate_pl061,
+    .class_init = pl061_class_init,
 };
 
-static SysBusDeviceInfo pl061_luminary_info = {
-    .init = pl061_init_luminary,
-    .qdev.name = "pl061_luminary",
-    .qdev.size = sizeof(pl061_state),
-    .qdev.vmsd = &vmstate_pl061,
+static void pl061_luminary_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pl061_init_luminary;
+}
+
+static DeviceInfo pl061_luminary_info = {
+    .name = "pl061_luminary",
+    .size = sizeof(pl061_state),
+    .vmsd = &vmstate_pl061,
+    .class_init = pl061_luminary_class_init,
 };
 
 static void pl061_register_devices(void)
diff --git a/hw/pl080.c b/hw/pl080.c
index e001df9..727bfa1 100644
--- a/hw/pl080.c
+++ b/hw/pl080.c
@@ -373,20 +373,34 @@ static int pl081_init(SysBusDevice *dev)
     return pl08x_init(dev, 2);
 }
 
-static SysBusDeviceInfo pl080_info = {
-    .init = pl080_init,
-    .qdev.name = "pl080",
-    .qdev.size = sizeof(pl080_state),
-    .qdev.vmsd = &vmstate_pl080,
-    .qdev.no_user = 1,
+static void pl080_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pl080_init;
+}
+
+static DeviceInfo pl080_info = {
+    .name = "pl080",
+    .size = sizeof(pl080_state),
+    .vmsd = &vmstate_pl080,
+    .no_user = 1,
+    .class_init = pl080_class_init,
 };
 
-static SysBusDeviceInfo pl081_info = {
-    .init = pl081_init,
-    .qdev.name = "pl081",
-    .qdev.size = sizeof(pl080_state),
-    .qdev.vmsd = &vmstate_pl080,
-    .qdev.no_user = 1,
+static void pl081_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pl081_init;
+}
+
+static DeviceInfo pl081_info = {
+    .name = "pl081",
+    .size = sizeof(pl080_state),
+    .vmsd = &vmstate_pl080,
+    .no_user = 1,
+    .class_init = pl081_class_init,
 };
 
 /* The PL080 and PL081 are the same except for the number of channels
diff --git a/hw/pl110.c b/hw/pl110.c
index 0e1f415..58fb9d3 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -469,28 +469,49 @@ static int pl111_init(SysBusDevice *dev)
     return pl110_init(dev);
 }
 
-static SysBusDeviceInfo pl110_info = {
-    .init = pl110_init,
-    .qdev.name = "pl110",
-    .qdev.size = sizeof(pl110_state),
-    .qdev.vmsd = &vmstate_pl110,
-    .qdev.no_user = 1,
+static void pl110_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pl110_init;
+}
+
+static DeviceInfo pl110_info = {
+    .name = "pl110",
+    .size = sizeof(pl110_state),
+    .vmsd = &vmstate_pl110,
+    .no_user = 1,
+    .class_init = pl110_class_init,
 };
 
-static SysBusDeviceInfo pl110_versatile_info = {
-    .init = pl110_versatile_init,
-    .qdev.name = "pl110_versatile",
-    .qdev.size = sizeof(pl110_state),
-    .qdev.vmsd = &vmstate_pl110,
-    .qdev.no_user = 1,
+static void pl110_versatile_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pl110_versatile_init;
+}
+
+static DeviceInfo pl110_versatile_info = {
+    .name = "pl110_versatile",
+    .size = sizeof(pl110_state),
+    .vmsd = &vmstate_pl110,
+    .no_user = 1,
+    .class_init = pl110_versatile_class_init,
 };
 
-static SysBusDeviceInfo pl111_info = {
-    .init = pl111_init,
-    .qdev.name = "pl111",
-    .qdev.size = sizeof(pl110_state),
-    .qdev.vmsd = &vmstate_pl110,
-    .qdev.no_user = 1,
+static void pl111_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pl111_init;
+}
+
+static DeviceInfo pl111_info = {
+    .name = "pl111",
+    .size = sizeof(pl110_state),
+    .vmsd = &vmstate_pl110,
+    .no_user = 1,
+    .class_init = pl111_class_init,
 };
 
 static void pl110_register_devices(void)
diff --git a/hw/pl181.c b/hw/pl181.c
index b79aa41..973d3fc 100644
--- a/hw/pl181.c
+++ b/hw/pl181.c
@@ -487,18 +487,25 @@ static int pl181_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo pl181_info = {
-    .init = pl181_init,
-    .qdev.name = "pl181",
-    .qdev.size = sizeof(pl181_state),
-    .qdev.vmsd = &vmstate_pl181,
-    .qdev.reset = pl181_reset,
-    .qdev.no_user = 1,
+static void pl181_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = pl181_init;
+}
+
+static DeviceInfo pl181_info = {
+    .name = "pl181",
+    .size = sizeof(pl181_state),
+    .class_init = pl181_class_init,
+    .vmsd = &vmstate_pl181,
+    .reset = pl181_reset,
+    .no_user = 1,
 };
 
 static void pl181_register_devices(void)
 {
-    sysbus_register_withprop(&pl181_info);
+    sysbus_qdev_register(&pl181_info);
 }
 
 device_init(pl181_register_devices)
diff --git a/hw/pl190.c b/hw/pl190.c
index 6fc2656..79322aa 100644
--- a/hw/pl190.c
+++ b/hw/pl190.c
@@ -255,13 +255,20 @@ static const VMStateDescription vmstate_pl190 = {
     }
 };
 
-static SysBusDeviceInfo pl190_info = {
-    .init = pl190_init,
-    .qdev.name = "pl190",
-    .qdev.size = sizeof(pl190_state),
-    .qdev.vmsd = &vmstate_pl190,
-    .qdev.reset = pl190_reset,
-    .qdev.no_user = 1,
+static void pl190_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pl190_init;
+}
+
+static DeviceInfo pl190_info = {
+    .name = "pl190",
+    .size = sizeof(pl190_state),
+    .vmsd = &vmstate_pl190,
+    .reset = pl190_reset,
+    .no_user = 1,
+    .class_init = pl190_class_init,
 };
 
 static void pl190_register_devices(void)
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index b38840e..36fb9f9 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -382,11 +382,18 @@ static DeviceInfo ppc4xx_host_bridge_info = {
     .class_init = ppc4xx_host_bridge_class_init,
 };
 
-static SysBusDeviceInfo ppc4xx_pcihost_info = {
-    .init         = ppc4xx_pcihost_initfn,
-    .qdev.name    = "ppc4xx-pcihost",
-    .qdev.size    = sizeof(PPC4xxPCIState),
-    .qdev.vmsd    = &vmstate_ppc4xx_pci,
+static void ppc4xx_pcihost_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = ppc4xx_pcihost_initfn;
+}
+
+static DeviceInfo ppc4xx_pcihost_info = {
+    .name    = "ppc4xx-pcihost",
+    .size    = sizeof(PPC4xxPCIState),
+    .vmsd    = &vmstate_ppc4xx_pci,
+    .class_init = ppc4xx_pcihost_class_init,
 };
 
 static void ppc4xx_pci_register(void)
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index bc783bf..f8c4f11 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -355,11 +355,18 @@ static DeviceInfo e500_host_bridge_info = {
     .class_init = e500_host_bridge_class_init,
 };
 
-static SysBusDeviceInfo e500_pcihost_info = {
-    .init         = e500_pcihost_initfn,
-    .qdev.name    = "e500-pcihost",
-    .qdev.size    = sizeof(PPCE500PCIState),
-    .qdev.vmsd    = &vmstate_ppce500_pci,
+static void e500_pcihost_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = e500_pcihost_initfn;
+}
+
+static DeviceInfo e500_pcihost_info = {
+    .name = "e500-pcihost",
+    .size = sizeof(PPCE500PCIState),
+    .vmsd = &vmstate_ppce500_pci,
+    .class_init = e500_pcihost_class_init,
 };
 
 static void e500_pci_register(void)
diff --git a/hw/ppce500_spin.c b/hw/ppce500_spin.c
index e7b1453..cb5bc97 100644
--- a/hw/ppce500_spin.c
+++ b/hw/ppce500_spin.c
@@ -203,10 +203,17 @@ static int ppce500_spin_initfn(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo ppce500_spin_info = {
-    .init         = ppce500_spin_initfn,
-    .qdev.name    = "e500-spin",
-    .qdev.size    = sizeof(SpinState),
+static void ppce500_spin_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = ppce500_spin_initfn;
+}
+
+static DeviceInfo ppce500_spin_info = {
+    .name = "e500-spin",
+    .size = sizeof(SpinState),
+    .class_init = ppce500_spin_class_init,
 };
 
 static void ppce500_spin_register(void)
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index 4ff1049..b3b85b7 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -154,12 +154,19 @@ static DeviceInfo raven_info = {
     .class_init = raven_class_init,
 };
 
-static SysBusDeviceInfo raven_pcihost_info = {
-    .qdev.name = "raven-pcihost",
-    .qdev.fw_name = "pci",
-    .qdev.size = sizeof(PREPPCIState),
-    .qdev.no_user = 1,
-    .init = raven_pcihost_init,
+static void raven_pcihost_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = raven_pcihost_init;
+}
+
+static DeviceInfo raven_pcihost_info = {
+    .name = "raven-pcihost",
+    .fw_name = "pci",
+    .size = sizeof(PREPPCIState),
+    .class_init = raven_pcihost_class_init,
+    .no_user = 1,
 };
 
 static void raven_register_devices(void)
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 2ebb739..fbc397f 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -1233,12 +1233,19 @@ static const VMStateDescription vmstate_pxa2xx_rtc_regs = {
     },
 };
 
-static SysBusDeviceInfo pxa2xx_rtc_sysbus_info = {
-    .init       = pxa2xx_rtc_init,
-    .qdev.name  = "pxa2xx_rtc",
-    .qdev.desc  = "PXA2xx RTC Controller",
-    .qdev.size  = sizeof(PXA2xxRTCState),
-    .qdev.vmsd  = &vmstate_pxa2xx_rtc_regs,
+static void pxa2xx_rtc_sysbus_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pxa2xx_rtc_init;
+}
+
+static DeviceInfo pxa2xx_rtc_sysbus_info = {
+    .name = "pxa2xx_rtc",
+    .desc = "PXA2xx RTC Controller",
+    .size = sizeof(PXA2xxRTCState),
+    .vmsd = &vmstate_pxa2xx_rtc_regs,
+    .class_init = pxa2xx_rtc_sysbus_class_init,
 };
 
 /* I2C Interface */
@@ -1472,7 +1479,7 @@ static int pxa2xx_i2c_slave_init(I2CSlave *i2c)
     return 0;
 }
 
-static void pxapxa2xx_i2c_slave_class_init(ObjectClass *klass, void *data)
+static void pxa2xx_i2c_slave_class_init(ObjectClass *klass, void *data)
 {
     I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
 
@@ -1485,7 +1492,7 @@ static void pxapxa2xx_i2c_slave_class_init(ObjectClass *klass, void *data)
 static DeviceInfo pxa2xx_i2c_slave_info = {
     .name = "pxa2xx-i2c-slave",
     .size = sizeof(PXA2xxI2CSlaveState),
-    .class_init = pxapxa2xx_i2c_slave_class_init,
+    .class_init = pxa2xx_i2c_slave_class_init,
 };
 
 PXA2xxI2CState *pxa2xx_i2c_init(target_phys_addr_t base,
@@ -1533,17 +1540,26 @@ i2c_bus *pxa2xx_i2c_bus(PXA2xxI2CState *s)
     return s->bus;
 }
 
-static SysBusDeviceInfo pxa2xx_i2c_info = {
-    .init       = pxa2xx_i2c_initfn,
-    .qdev.name  = "pxa2xx_i2c",
-    .qdev.desc  = "PXA2xx I2C Bus Controller",
-    .qdev.size  = sizeof(PXA2xxI2CState),
-    .qdev.vmsd  = &vmstate_pxa2xx_i2c,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("size", PXA2xxI2CState, region_size, 0x10000),
-        DEFINE_PROP_UINT32("offset", PXA2xxI2CState, offset, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property pxa2xx_i2c_properties[] = {
+    DEFINE_PROP_UINT32("size", PXA2xxI2CState, region_size, 0x10000),
+    DEFINE_PROP_UINT32("offset", PXA2xxI2CState, offset, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pxa2xx_i2c_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pxa2xx_i2c_initfn;
+}
+
+static DeviceInfo pxa2xx_i2c_info = {
+    .name = "pxa2xx_i2c",
+    .desc = "PXA2xx I2C Bus Controller",
+    .size = sizeof(PXA2xxI2CState),
+    .vmsd = &vmstate_pxa2xx_i2c,
+    .props = pxa2xx_i2c_properties,
+    .class_init = pxa2xx_i2c_class_init,
 };
 
 /* PXA Inter-IC Sound Controller */
@@ -2295,10 +2311,23 @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
     return s;
 }
 
+static void pxa2xx_ssp_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = pxa2xx_ssp_init;
+}
+
+static DeviceInfo pxa2xx_ssp_info = {
+    .name = "pxa2xx-ssp",
+    .size = sizeof(PXA2xxSSPState),
+    .class_init = pxa2xx_ssp_class_init,
+};
+
 static void pxa2xx_register_devices(void)
 {
     i2c_register_slave(&pxa2xx_i2c_slave_info);
-    sysbus_register_dev("pxa2xx-ssp", sizeof(PXA2xxSSPState), pxa2xx_ssp_init);
+    sysbus_qdev_register(&pxa2xx_ssp_info);
     sysbus_register_withprop(&pxa2xx_i2c_info);
     sysbus_register_withprop(&pxa2xx_rtc_sysbus_info);
 }
diff --git a/hw/pxa2xx_dma.c b/hw/pxa2xx_dma.c
index cb28107..9ecec33 100644
--- a/hw/pxa2xx_dma.c
+++ b/hw/pxa2xx_dma.c
@@ -543,16 +543,25 @@ static VMStateDescription vmstate_pxa2xx_dma = {
     },
 };
 
-static SysBusDeviceInfo pxa2xx_dma_info = {
-    .init       = pxa2xx_dma_init,
-    .qdev.name  = "pxa2xx-dma",
-    .qdev.desc  = "PXA2xx DMA controller",
-    .qdev.size  = sizeof(PXA2xxDMAState),
-    .qdev.vmsd  = &vmstate_pxa2xx_dma,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_INT32("channels", PXA2xxDMAState, channels, -1),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property pxa2xx_dma_properties[] = {
+    DEFINE_PROP_INT32("channels", PXA2xxDMAState, channels, -1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pxa2xx_dma_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pxa2xx_dma_init;
+}
+
+static DeviceInfo pxa2xx_dma_info = {
+    .name = "pxa2xx-dma",
+    .desc = "PXA2xx DMA controller",
+    .size = sizeof(PXA2xxDMAState),
+    .vmsd = &vmstate_pxa2xx_dma,
+    .props = pxa2xx_dma_properties,
+    .class_init = pxa2xx_dma_class_init,
 };
 
 static void pxa2xx_dma_register(void)
diff --git a/hw/pxa2xx_gpio.c b/hw/pxa2xx_gpio.c
index cc58c40..7a1333f 100644
--- a/hw/pxa2xx_gpio.c
+++ b/hw/pxa2xx_gpio.c
@@ -317,16 +317,25 @@ static const VMStateDescription vmstate_pxa2xx_gpio_regs = {
     },
 };
 
-static SysBusDeviceInfo pxa2xx_gpio_info = {
-    .init       = pxa2xx_gpio_initfn,
-    .qdev.name  = "pxa2xx-gpio",
-    .qdev.desc  = "PXA2xx GPIO controller",
-    .qdev.size  = sizeof(PXA2xxGPIOInfo),
-    .qdev.props = (Property []) {
-        DEFINE_PROP_INT32("lines", PXA2xxGPIOInfo, lines, 0),
-        DEFINE_PROP_INT32("ncpu", PXA2xxGPIOInfo, ncpu, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property pxa2xx_gpio_properties[] = {
+    DEFINE_PROP_INT32("lines", PXA2xxGPIOInfo, lines, 0),
+    DEFINE_PROP_INT32("ncpu", PXA2xxGPIOInfo, ncpu, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pxa2xx_gpio_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pxa2xx_gpio_initfn;
+}
+
+static DeviceInfo pxa2xx_gpio_info = {
+    .name = "pxa2xx-gpio",
+    .desc = "PXA2xx GPIO controller",
+    .size = sizeof(PXA2xxGPIOInfo),
+    .props = pxa2xx_gpio_properties,
+    .class_init = pxa2xx_gpio_class_init,
 };
 
 static void pxa2xx_gpio_register(void)
diff --git a/hw/pxa2xx_pic.c b/hw/pxa2xx_pic.c
index 92effbc..d318e83 100644
--- a/hw/pxa2xx_pic.c
+++ b/hw/pxa2xx_pic.c
@@ -296,12 +296,19 @@ static int pxa2xx_pic_initfn(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo pxa2xx_pic_info = {
-    .init       = pxa2xx_pic_initfn,
-    .qdev.name  = "pxa2xx_pic",
-    .qdev.desc  = "PXA2xx PIC",
-    .qdev.size  = sizeof(PXA2xxPICState),
-    .qdev.vmsd  = &vmstate_pxa2xx_pic_regs,
+static void pxa2xx_pic_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pxa2xx_pic_initfn;
+}
+
+static DeviceInfo pxa2xx_pic_info = {
+    .name = "pxa2xx_pic",
+    .desc = "PXA2xx PIC",
+    .size = sizeof(PXA2xxPICState),
+    .vmsd = &vmstate_pxa2xx_pic_regs,
+    .class_init = pxa2xx_pic_class_init,
 };
 
 static void pxa2xx_pic_register(void)
diff --git a/hw/pxa2xx_timer.c b/hw/pxa2xx_timer.c
index 50e2678..cd78d41 100644
--- a/hw/pxa2xx_timer.c
+++ b/hw/pxa2xx_timer.c
@@ -477,32 +477,50 @@ static const VMStateDescription vmstate_pxa2xx_timer_regs = {
     }
 };
 
-static SysBusDeviceInfo pxa25x_timer_dev_info = {
-    .init       = pxa2xx_timer_init,
-    .qdev.name  = "pxa25x-timer",
-    .qdev.desc  = "PXA25x timer",
-    .qdev.size  = sizeof(PXA2xxTimerInfo),
-    .qdev.vmsd  = &vmstate_pxa2xx_timer_regs,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA25X_FREQ),
-        DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
-                        PXA2XX_TIMER_HAVE_TM4, false),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property pxa25x_timer_dev_properties[] = {
+    DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA25X_FREQ),
+    DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
+    PXA2XX_TIMER_HAVE_TM4, false),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
-static SysBusDeviceInfo pxa27x_timer_dev_info = {
-    .init       = pxa2xx_timer_init,
-    .qdev.name  = "pxa27x-timer",
-    .qdev.desc  = "PXA27x timer",
-    .qdev.size  = sizeof(PXA2xxTimerInfo),
-    .qdev.vmsd  = &vmstate_pxa2xx_timer_regs,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA27X_FREQ),
-        DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
-                        PXA2XX_TIMER_HAVE_TM4, true),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static void pxa25x_timer_dev_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pxa2xx_timer_init;
+}
+
+static DeviceInfo pxa25x_timer_dev_info = {
+    .name = "pxa25x-timer",
+    .desc = "PXA25x timer",
+    .size = sizeof(PXA2xxTimerInfo),
+    .vmsd = &vmstate_pxa2xx_timer_regs,
+    .props = pxa25x_timer_dev_properties,
+    .class_init = pxa25x_timer_dev_class_init,
+};
+
+static Property pxa27x_timer_dev_properties[] = {
+    DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA27X_FREQ),
+    DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
+    PXA2XX_TIMER_HAVE_TM4, true),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pxa27x_timer_dev_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = pxa2xx_timer_init;
+}
+
+static DeviceInfo pxa27x_timer_dev_info = {
+    .name = "pxa27x-timer",
+    .desc = "PXA27x timer",
+    .size = sizeof(PXA2xxTimerInfo),
+    .vmsd = &vmstate_pxa2xx_timer_regs,
+    .props = pxa27x_timer_dev_properties,
+    .class_init = pxa27x_timer_dev_class_init,
 };
 
 static void pxa2xx_timer_register(void)
diff --git a/hw/realview.c b/hw/realview.c
index d2fde44..42a0f20 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -82,10 +82,17 @@ static int realview_i2c_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo realview_i2c_info = {
-    .init = realview_i2c_init,
-    .qdev.name  = "realview_i2c",
-    .qdev.size  = sizeof(RealViewI2CState),
+static void realview_i2c_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = realview_i2c_init;
+}
+
+static DeviceInfo realview_i2c_info = {
+    .name = "realview_i2c",
+    .size = sizeof(RealViewI2CState),
+    .class_init = realview_i2c_class_init,
 };
 
 static void realview_register_devices(void)
diff --git a/hw/realview_gic.c b/hw/realview_gic.c
index 7342ede..0ccf21a 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -46,10 +46,22 @@ static int realview_gic_init(SysBusDevice *dev)
     return 0;
 }
 
+static void realview_gic_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = realview_gic_init;
+}
+
+static DeviceInfo realview_gic_info = {
+    .name = "realview_gic",
+    .size = sizeof(RealViewGICState),
+    .class_init = realview_gic_class_init,
+};
+
 static void realview_gic_register_devices(void)
 {
-    sysbus_register_dev("realview_gic", sizeof(RealViewGICState),
-                        realview_gic_init);
+    sysbus_qdev_register(&realview_gic_info);
 }
 
 device_init(realview_gic_register_devices)
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 2efea9f..8e34a78 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -419,11 +419,18 @@ static int s390_virtio_bridge_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo s390_virtio_bridge_info = {
-    .init = s390_virtio_bridge_init,
-    .qdev.name  = "s390-virtio-bridge",
-    .qdev.size  = sizeof(SysBusDevice),
-    .qdev.no_user = 1,
+static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = s390_virtio_bridge_init;
+}
+
+static DeviceInfo s390_virtio_bridge_info = {
+    .name = "s390-virtio-bridge",
+    .size = sizeof(SysBusDevice),
+    .no_user = 1,
+    .class_init = s390_virtio_bridge_class_init,
 };
 
 static void s390_virtio_register_devices(void)
diff --git a/hw/sbi.c b/hw/sbi.c
index 8965a71..0a062fc 100644
--- a/hw/sbi.c
+++ b/hw/sbi.c
@@ -131,12 +131,19 @@ static int sbi_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo sbi_info = {
-    .init = sbi_init1,
-    .qdev.name  = "sbi",
-    .qdev.size  = sizeof(SBIState),
-    .qdev.vmsd  = &vmstate_sbi,
-    .qdev.reset = sbi_reset,
+static void sbi_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = sbi_init1;
+}
+
+static DeviceInfo sbi_info = {
+    .name = "sbi",
+    .size = sizeof(SBIState),
+    .vmsd = &vmstate_sbi,
+    .reset = sbi_reset,
+    .class_init = sbi_class_init,
 };
 
 static void sbi_register_devices(void)
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index baeab9e..a849176 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -110,7 +110,7 @@ static void sh_pci_set_irq(void *opaque, int irq_num, int level)
     qemu_set_irq(pic[irq_num], level);
 }
 
-static int sh_pci_init_device(SysBusDevice *dev)
+static int sh_pci_device_init(SysBusDevice *dev)
 {
     SHPCIState *s;
     int i;
@@ -162,10 +162,22 @@ static DeviceInfo sh_pci_host_info = {
     .class_init = sh_pci_host_class_init,
 };
 
+static void sh_pci_device_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = sh_pci_device_init;
+}
+
+static DeviceInfo sh_pci_device_info = {
+    .name = "sh_pci",
+    .size = sizeof(SHPCIState),
+    .class_init = sh_pci_device_class_init,
+};
+
 static void sh_pci_register_devices(void)
 {
-    sysbus_register_dev("sh_pci", sizeof(SHPCIState),
-                        sh_pci_init_device);
+    sysbus_qdev_register(&sh_pci_device_info);
     pci_qdev_register(&sh_pci_host_info);
 }
 
diff --git a/hw/slavio_intctl.c b/hw/slavio_intctl.c
index 9925e64..12ce342 100644
--- a/hw/slavio_intctl.c
+++ b/hw/slavio_intctl.c
@@ -446,12 +446,19 @@ static int slavio_intctl_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo slavio_intctl_info = {
-    .init = slavio_intctl_init1,
-    .qdev.name  = "slavio_intctl",
-    .qdev.size  = sizeof(SLAVIO_INTCTLState),
-    .qdev.vmsd  = &vmstate_intctl,
-    .qdev.reset = slavio_intctl_reset,
+static void slavio_intctl_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = slavio_intctl_init1;
+}
+
+static DeviceInfo slavio_intctl_info = {
+    .name = "slavio_intctl",
+    .size = sizeof(SLAVIO_INTCTLState),
+    .vmsd = &vmstate_intctl,
+    .reset = slavio_intctl_reset,
+    .class_init = slavio_intctl_class_init,
 };
 
 static void slavio_intctl_register_devices(void)
diff --git a/hw/slavio_misc.c b/hw/slavio_misc.c
index 484301c..39a5269 100644
--- a/hw/slavio_misc.c
+++ b/hw/slavio_misc.c
@@ -468,18 +468,32 @@ static int slavio_misc_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo slavio_misc_info = {
-    .init = slavio_misc_init1,
-    .qdev.name  = "slavio_misc",
-    .qdev.size  = sizeof(MiscState),
-    .qdev.vmsd  = &vmstate_misc,
-    .qdev.reset  = slavio_misc_reset,
+static void slavio_misc_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = slavio_misc_init1;
+}
+
+static DeviceInfo slavio_misc_info = {
+    .name = "slavio_misc",
+    .size = sizeof(MiscState),
+    .vmsd = &vmstate_misc,
+    .reset = slavio_misc_reset,
+    .class_init = slavio_misc_class_init,
 };
 
-static SysBusDeviceInfo apc_info = {
-    .init = apc_init1,
-    .qdev.name  = "apc",
-    .qdev.size  = sizeof(MiscState),
+static void apc_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = apc_init1;
+}
+
+static DeviceInfo apc_info = {
+    .name = "apc",
+    .size = sizeof(MiscState),
+    .class_init = apc_class_init,
 };
 
 static void slavio_misc_register_devices(void)
diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c
index 44b500a..a3bebcd 100644
--- a/hw/slavio_timer.c
+++ b/hw/slavio_timer.c
@@ -404,16 +404,25 @@ static int slavio_timer_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo slavio_timer_info = {
-    .init = slavio_timer_init1,
-    .qdev.name  = "slavio_timer",
-    .qdev.size  = sizeof(SLAVIO_TIMERState),
-    .qdev.vmsd  = &vmstate_slavio_timer,
-    .qdev.reset = slavio_timer_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("num_cpus",  SLAVIO_TIMERState, num_cpus,  0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property slavio_timer_properties[] = {
+    DEFINE_PROP_UINT32("num_cpus",  SLAVIO_TIMERState, num_cpus,  0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void slavio_timer_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = slavio_timer_init1;
+}
+
+static DeviceInfo slavio_timer_info = {
+    .name = "slavio_timer",
+    .size = sizeof(SLAVIO_TIMERState),
+    .vmsd = &vmstate_slavio_timer,
+    .reset = slavio_timer_reset,
+    .props = slavio_timer_properties,
+    .class_init = slavio_timer_class_init,
 };
 
 static void slavio_timer_register_devices(void)
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index 4a68f6b..4220880 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -758,16 +758,25 @@ static int smc91c111_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo smc91c111_info = {
-    .init = smc91c111_init1,
-    .qdev.name  = "smc91c111",
-    .qdev.size  = sizeof(smc91c111_state),
-    .qdev.vmsd = &vmstate_smc91c111,
-    .qdev.reset = smc91c111_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(smc91c111_state, conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property smc91c111_properties[] = {
+    DEFINE_NIC_PROPERTIES(smc91c111_state, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void smc91c111_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = smc91c111_init1;
+}
+
+static DeviceInfo smc91c111_info = {
+    .name = "smc91c111",
+    .size = sizeof(smc91c111_state),
+    .vmsd = &vmstate_smc91c111,
+    .reset = smc91c111_reset,
+    .props = smc91c111_properties,
+    .class_init = smc91c111_class_init,
 };
 
 static void smc91c111_register_devices(void)
diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c
index 8a39f8f..b6ac0d4 100644
--- a/hw/spapr_pci.c
+++ b/hw/spapr_pci.c
@@ -227,10 +227,22 @@ static DeviceInfo spapr_main_pci_host_info = {
     .class_init = spapr_main_pci_host_class_init,
 };
 
+static void spapr_phb_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = spapr_phb_init;
+}
+
+static DeviceInfo spapr_phb_info = {
+    .name = "spapr-pci-host-bridge",
+    .size = sizeof(sPAPRPHBState),
+    .class_init = spapr_phb_class_init,
+};
+
 static void spapr_register_devices(void)
 {
-    sysbus_register_dev("spapr-pci-host-bridge", sizeof(sPAPRPHBState),
-                        spapr_phb_init);
+    sysbus_qdev_register(&spapr_phb_info);
     pci_qdev_register(&spapr_main_pci_host_info);
 }
 
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index bc586bf..dc2e9c9 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -755,11 +755,18 @@ static int spapr_vio_bridge_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo spapr_vio_bridge_info = {
-    .init = spapr_vio_bridge_init,
-    .qdev.name  = "spapr-vio-bridge",
-    .qdev.size  = sizeof(SysBusDevice),
-    .qdev.no_user = 1,
+static void spapr_vio_bridge_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sbc->init = spapr_vio_bridge_init;
+}
+
+static DeviceInfo spapr_vio_bridge_info = {
+    .name  = "spapr-vio-bridge",
+    .size  = sizeof(SysBusDevice),
+    .no_user = 1,
+    .class_init = spapr_vio_bridge_class_init,
 };
 
 static TypeInfo spapr_vio_type_info = {
diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
index 035d2e2..582f2f0 100644
--- a/hw/sparc32_dma.c
+++ b/hw/sparc32_dma.c
@@ -283,17 +283,26 @@ static int sparc32_dma_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo sparc32_dma_info = {
-    .init = sparc32_dma_init1,
-    .qdev.name  = "sparc32_dma",
-    .qdev.size  = sizeof(DMAState),
-    .qdev.vmsd  = &vmstate_dma,
-    .qdev.reset = dma_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_PTR("iommu_opaque", DMAState, iommu),
-        DEFINE_PROP_UINT32("is_ledma", DMAState, is_ledma, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property sparc32_dma_properties[] = {
+    DEFINE_PROP_PTR("iommu_opaque", DMAState, iommu),
+    DEFINE_PROP_UINT32("is_ledma", DMAState, is_ledma, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void sparc32_dma_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = sparc32_dma_init1;
+}
+
+static DeviceInfo sparc32_dma_info = {
+    .name = "sparc32_dma",
+    .size = sizeof(DMAState),
+    .vmsd = &vmstate_dma,
+    .reset = dma_reset,
+    .props = sparc32_dma_properties,
+    .class_init = sparc32_dma_class_init,
 };
 
 static void sparc32_dma_register_devices(void)
diff --git a/hw/spitz.c b/hw/spitz.c
index a2a778f..046efad 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -1023,16 +1023,25 @@ static VMStateDescription vmstate_sl_nand_info = {
     },
 };
 
-static SysBusDeviceInfo sl_nand_info = {
-    .init = sl_nand_init,
-    .qdev.name = "sl-nand",
-    .qdev.size = sizeof(SLNANDState),
-    .qdev.vmsd = &vmstate_sl_nand_info,
-    .qdev.props = (Property []) {
-        DEFINE_PROP_UINT8("manf_id", SLNANDState, manf_id, NAND_MFR_SAMSUNG),
-        DEFINE_PROP_UINT8("chip_id", SLNANDState, chip_id, 0xf1),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property sl_nand_properties[] = {
+    DEFINE_PROP_UINT8("manf_id", SLNANDState, manf_id, NAND_MFR_SAMSUNG),
+    DEFINE_PROP_UINT8("chip_id", SLNANDState, chip_id, 0xf1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void sl_nand_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = sl_nand_init;
+}
+
+static DeviceInfo sl_nand_info = {
+    .name = "sl-nand",
+    .size = sizeof(SLNANDState),
+    .vmsd = &vmstate_sl_nand_info,
+    .props = sl_nand_properties,
+    .class_init = sl_nand_class_init,
 };
 
 static VMStateDescription vmstate_spitz_kbd = {
@@ -1049,14 +1058,23 @@ static VMStateDescription vmstate_spitz_kbd = {
     },
 };
 
-static SysBusDeviceInfo spitz_keyboard_info = {
-    .init = spitz_keyboard_init,
-    .qdev.name = "spitz-keyboard",
-    .qdev.size = sizeof(SpitzKeyboardState),
-    .qdev.vmsd = &vmstate_spitz_kbd,
-    .qdev.props = (Property []) {
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static Property spitz_keyboard_properties[] = {
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void spitz_keyboard_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = spitz_keyboard_init;
+}
+
+static DeviceInfo spitz_keyboard_info = {
+    .name = "spitz-keyboard",
+    .size = sizeof(SpitzKeyboardState),
+    .vmsd = &vmstate_spitz_kbd,
+    .props = spitz_keyboard_properties,
+    .class_init = spitz_keyboard_class_init,
 };
 
 static const VMStateDescription vmstate_corgi_ssp_regs = {
@@ -1078,7 +1096,6 @@ static void corgi_ssp_class_init(ObjectClass *klass, void *data)
     k->transfer = corgi_ssp_transfer;
 }
 
-
 static DeviceInfo corgi_ssp_info = {
     .name = "corgi-ssp",
     .size = sizeof(CorgiSSPState),
diff --git a/hw/stellaris.c b/hw/stellaris.c
index a1620cb..b91139e 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -1408,14 +1408,50 @@ static DeviceInfo stellaris_ssi_bus_info = {
     .class_init = stellaris_ssi_bus_class_init,
 };
 
+static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = stellaris_i2c_init;
+}
+
+static DeviceInfo stellaris_i2c_info = {
+    .name = "stellaris-i2c",
+    .size = sizeof(stellaris_i2c_state),
+    .class_init = stellaris_i2c_class_init,
+};
+
+static void stellaris_gptm_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = stellaris_gptm_init;
+}
+
+static DeviceInfo stellaris_gptm_info = {
+    .name = "stellaris-gptm",
+    .size = sizeof(gptm_state),
+    .class_init = stellaris_gptm_class_init,
+};
+
+static void stellaris_adc_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = stellaris_adc_init;
+}
+
+static DeviceInfo stellaris_adc_info = {
+    .name = "stellaris-adc",
+    .size = sizeof(stellaris_adc_state),
+    .class_init = stellaris_adc_class_init,
+};
+
 static void stellaris_register_devices(void)
 {
-    sysbus_register_dev("stellaris-i2c", sizeof(stellaris_i2c_state),
-                        stellaris_i2c_init);
-    sysbus_register_dev("stellaris-gptm", sizeof(gptm_state),
-                        stellaris_gptm_init);
-    sysbus_register_dev("stellaris-adc", sizeof(stellaris_adc_state),
-                        stellaris_adc_init);
+    sysbus_qdev_register(&stellaris_i2c_info);
+    sysbus_qdev_register(&stellaris_gptm_info);
+    sysbus_qdev_register(&stellaris_adc_info);
     ssi_register_slave(&stellaris_ssi_bus_info);
 }
 
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index ecd750c..3d3ef66 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -420,14 +420,23 @@ static int stellaris_enet_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo stellaris_enet_info = {
-    .init = stellaris_enet_init,
-    .qdev.name  = "stellaris_enet",
-    .qdev.size  = sizeof(stellaris_enet_state),
-    .qdev.props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(stellaris_enet_state, conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property stellaris_enet_properties[] = {
+    DEFINE_NIC_PROPERTIES(stellaris_enet_state, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void stellaris_enet_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = stellaris_enet_init;
+}
+
+static DeviceInfo stellaris_enet_info = {
+    .name = "stellaris_enet",
+    .size = sizeof(stellaris_enet_state),
+    .props = stellaris_enet_properties,
+    .class_init = stellaris_enet_class_init,
 };
 
 static void stellaris_enet_register_devices(void)
diff --git a/hw/strongarm.c b/hw/strongarm.c
index fe63fd7..15828bf 100644
--- a/hw/strongarm.c
+++ b/hw/strongarm.c
@@ -201,12 +201,19 @@ static VMStateDescription vmstate_strongarm_pic_regs = {
     },
 };
 
-static SysBusDeviceInfo strongarm_pic_info = {
-    .init       = strongarm_pic_initfn,
-    .qdev.name  = "strongarm_pic",
-    .qdev.desc  = "StrongARM PIC",
-    .qdev.size  = sizeof(StrongARMPICState),
-    .qdev.vmsd  = &vmstate_strongarm_pic_regs,
+static void strongarm_pic_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = strongarm_pic_initfn;
+}
+
+static DeviceInfo strongarm_pic_info = {
+    .name = "strongarm_pic",
+    .desc = "StrongARM PIC",
+    .size = sizeof(StrongARMPICState),
+    .vmsd = &vmstate_strongarm_pic_regs,
+    .class_init = strongarm_pic_class_init,
 };
 
 /* Real-Time Clock */
@@ -413,12 +420,19 @@ static const VMStateDescription vmstate_strongarm_rtc_regs = {
     },
 };
 
-static SysBusDeviceInfo strongarm_rtc_sysbus_info = {
-    .init       = strongarm_rtc_init,
-    .qdev.name  = "strongarm-rtc",
-    .qdev.desc  = "StrongARM RTC Controller",
-    .qdev.size  = sizeof(StrongARMRTCState),
-    .qdev.vmsd  = &vmstate_strongarm_rtc_regs,
+static void strongarm_rtc_sysbus_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = strongarm_rtc_init;
+}
+
+static DeviceInfo strongarm_rtc_sysbus_info = {
+    .name = "strongarm-rtc",
+    .desc = "StrongARM RTC Controller",
+    .size = sizeof(StrongARMRTCState),
+    .vmsd = &vmstate_strongarm_rtc_regs,
+    .class_init = strongarm_rtc_sysbus_class_init,
 };
 
 /* GPIO */
@@ -646,11 +660,18 @@ static const VMStateDescription vmstate_strongarm_gpio_regs = {
     },
 };
 
-static SysBusDeviceInfo strongarm_gpio_info = {
-    .init       = strongarm_gpio_initfn,
-    .qdev.name  = "strongarm-gpio",
-    .qdev.desc  = "StrongARM GPIO controller",
-    .qdev.size  = sizeof(StrongARMGPIOInfo),
+static void strongarm_gpio_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = strongarm_gpio_initfn;
+}
+
+static DeviceInfo strongarm_gpio_info = {
+    .name = "strongarm-gpio",
+    .desc = "StrongARM GPIO controller",
+    .size = sizeof(StrongARMGPIOInfo),
+    .class_init = strongarm_gpio_class_init,
 };
 
 /* Peripheral Pin Controller */
@@ -803,11 +824,18 @@ static const VMStateDescription vmstate_strongarm_ppc_regs = {
     },
 };
 
-static SysBusDeviceInfo strongarm_ppc_info = {
-    .init       = strongarm_ppc_init,
-    .qdev.name  = "strongarm-ppc",
-    .qdev.desc  = "StrongARM PPC controller",
-    .qdev.size  = sizeof(StrongARMPPCInfo),
+static void strongarm_ppc_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = strongarm_ppc_init;
+}
+
+static DeviceInfo strongarm_ppc_info = {
+    .name = "strongarm-ppc",
+    .desc = "StrongARM PPC controller",
+    .size = sizeof(StrongARMPPCInfo),
+    .class_init = strongarm_ppc_class_init,
 };
 
 /* UART Ports */
@@ -1245,17 +1273,26 @@ static const VMStateDescription vmstate_strongarm_uart_regs = {
     },
 };
 
-static SysBusDeviceInfo strongarm_uart_info = {
-    .init       = strongarm_uart_init,
-    .qdev.name  = "strongarm-uart",
-    .qdev.desc  = "StrongARM UART controller",
-    .qdev.size  = sizeof(StrongARMUARTState),
-    .qdev.reset = strongarm_uart_reset,
-    .qdev.vmsd  = &vmstate_strongarm_uart_regs,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_CHR("chardev", StrongARMUARTState, chr),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property strongarm_uart_properties[] = {
+    DEFINE_PROP_CHR("chardev", StrongARMUARTState, chr),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void strongarm_uart_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = strongarm_uart_init;
+}
+
+static DeviceInfo strongarm_uart_info = {
+    .name = "strongarm-uart",
+    .desc = "StrongARM UART controller",
+    .size = sizeof(StrongARMUARTState),
+    .reset = strongarm_uart_reset,
+    .vmsd = &vmstate_strongarm_uart_regs,
+    .props = strongarm_uart_properties,
+    .class_init = strongarm_uart_class_init,
 };
 
 /* Synchronous Serial Ports */
@@ -1479,13 +1516,20 @@ static const VMStateDescription vmstate_strongarm_ssp_regs = {
     },
 };
 
-static SysBusDeviceInfo strongarm_ssp_info = {
-    .init       = strongarm_ssp_init,
-    .qdev.name  = "strongarm-ssp",
-    .qdev.desc  = "StrongARM SSP controller",
-    .qdev.size  = sizeof(StrongARMSSPState),
-    .qdev.reset = strongarm_ssp_reset,
-    .qdev.vmsd  = &vmstate_strongarm_ssp_regs,
+static void strongarm_ssp_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = strongarm_ssp_init;
+}
+
+static DeviceInfo strongarm_ssp_info = {
+    .name = "strongarm-ssp",
+    .desc = "StrongARM SSP controller",
+    .size = sizeof(StrongARMSSPState),
+    .reset = strongarm_ssp_reset,
+    .vmsd = &vmstate_strongarm_ssp_regs,
+    .class_init = strongarm_ssp_class_init,
 };
 
 /* Main CPU functions */
diff --git a/hw/sun4c_intctl.c b/hw/sun4c_intctl.c
index e15b167..111d31b 100644
--- a/hw/sun4c_intctl.c
+++ b/hw/sun4c_intctl.c
@@ -206,12 +206,19 @@ static int sun4c_intctl_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo sun4c_intctl_info = {
-    .init = sun4c_intctl_init1,
-    .qdev.name  = "sun4c_intctl",
-    .qdev.size  = sizeof(Sun4c_INTCTLState),
-    .qdev.vmsd  = &vmstate_sun4c_intctl,
-    .qdev.reset = sun4c_intctl_reset,
+static void sun4c_intctl_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = sun4c_intctl_init1;
+}
+
+static DeviceInfo sun4c_intctl_info = {
+    .name = "sun4c_intctl",
+    .size = sizeof(Sun4c_INTCTLState),
+    .vmsd = &vmstate_sun4c_intctl,
+    .reset = sun4c_intctl_reset,
+    .class_init = sun4c_intctl_class_init,
 };
 
 static void sun4c_intctl_register_devices(void)
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 941cc98..f2ff0bd 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -609,10 +609,17 @@ static int idreg_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo idreg_info = {
-    .init = idreg_init1,
-    .qdev.name  = "macio_idreg",
-    .qdev.size  = sizeof(IDRegState),
+static void idreg_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = idreg_init1;
+}
+
+static DeviceInfo idreg_info = {
+    .name = "macio_idreg",
+    .size = sizeof(IDRegState),
+    .class_init = idreg_class_init,
 };
 
 static void idreg_register_devices(void)
@@ -650,10 +657,17 @@ static int afx_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo afx_info = {
-    .init = afx_init1,
-    .qdev.name  = "tcx_afx",
-    .qdev.size  = sizeof(AFXState),
+static void afx_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = afx_init1;
+}
+
+static DeviceInfo afx_info = {
+    .name = "tcx_afx",
+    .size = sizeof(AFXState),
+    .class_init = afx_class_init,
 };
 
 static void afx_register_devices(void)
@@ -720,13 +734,22 @@ static int prom_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo prom_info = {
-    .init = prom_init1,
-    .qdev.name  = "openprom",
-    .qdev.size  = sizeof(PROMState),
-    .qdev.props = (Property[]) {
-        {/* end of property list */}
-    }
+static Property prom_properties[] = {
+    {/* end of property list */},
+};
+
+static void prom_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = prom_init1;
+}
+
+static DeviceInfo prom_info = {
+    .name = "openprom",
+    .size = sizeof(PROMState),
+    .props = prom_properties,
+    .class_init = prom_class_init,
 };
 
 static void prom_register_devices(void)
@@ -779,14 +802,23 @@ static void ram_init(target_phys_addr_t addr, ram_addr_t RAM_size,
     sysbus_mmio_map(s, 0, addr);
 }
 
-static SysBusDeviceInfo ram_info = {
-    .init = ram_init1,
-    .qdev.name  = "memory",
-    .qdev.size  = sizeof(RamDevice),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT64("size", RamDevice, size, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property ram_properties[] = {
+    DEFINE_PROP_UINT64("size", RamDevice, size, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ram_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = ram_init1;
+}
+
+static DeviceInfo ram_info = {
+    .name = "memory",
+    .size = sizeof(RamDevice),
+    .props = ram_properties,
+    .class_init = ram_class_init,
 };
 
 static void ram_register_devices(void)
diff --git a/hw/sun4m_iommu.c b/hw/sun4m_iommu.c
index ef7627c..823bfac 100644
--- a/hw/sun4m_iommu.c
+++ b/hw/sun4m_iommu.c
@@ -357,16 +357,25 @@ static int iommu_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo iommu_info = {
-    .init = iommu_init1,
-    .qdev.name  = "iommu",
-    .qdev.size  = sizeof(IOMMUState),
-    .qdev.vmsd  = &vmstate_iommu,
-    .qdev.reset = iommu_reset,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_HEX32("version", IOMMUState, version, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property iommu_properties[] = {
+    DEFINE_PROP_HEX32("version", IOMMUState, version, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void iommu_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = iommu_init1;
+}
+
+static DeviceInfo iommu_info = {
+    .name = "iommu",
+    .size = sizeof(IOMMUState),
+    .vmsd = &vmstate_iommu,
+    .reset = iommu_reset,
+    .props = iommu_properties,
+    .class_init = iommu_class_init,
 };
 
 static void iommu_register_devices(void)
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 6d9fdf6..f3bb226 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -643,13 +643,22 @@ static int prom_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo prom_info = {
-    .init = prom_init1,
-    .qdev.name  = "openprom",
-    .qdev.size  = sizeof(PROMState),
-    .qdev.props = (Property[]) {
-        {/* end of property list */}
-    }
+static Property prom_properties[] = {
+    {/* end of property list */},
+};
+
+static void prom_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = prom_init1;
+}
+
+static DeviceInfo prom_info = {
+    .name = "openprom",
+    .size = sizeof(PROMState),
+    .props = prom_properties,
+    .class_init = prom_class_init,
 };
 
 static void prom_register_devices(void)
@@ -695,14 +704,23 @@ static void ram_init(target_phys_addr_t addr, ram_addr_t RAM_size)
     sysbus_mmio_map(s, 0, addr);
 }
 
-static SysBusDeviceInfo ram_info = {
-    .init = ram_init1,
-    .qdev.name  = "memory",
-    .qdev.size  = sizeof(RamDevice),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT64("size", RamDevice, size, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property ram_properties[] = {
+    DEFINE_PROP_UINT64("size", RamDevice, size, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ram_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = ram_init1;
+}
+
+static DeviceInfo ram_info = {
+    .name = "memory",
+    .size = sizeof(RamDevice),
+    .props = ram_properties,
+    .class_init = ram_class_init,
 };
 
 static void ram_register_devices(void)
diff --git a/hw/sysbus.c b/hw/sysbus.c
index 2e06fe8..7d122f9 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -107,29 +107,24 @@ void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size)
 
 static int sysbus_device_init(DeviceState *dev, DeviceInfo *base)
 {
-    SysBusDeviceInfo *info = container_of(base, SysBusDeviceInfo, qdev);
+    SysBusDevice *sd = SYS_BUS_DEVICE(dev);
+    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_GET_CLASS(sd);
 
-    return info->init(sysbus_from_qdev(dev));
+    return sbc->init(sd);
 }
 
-void sysbus_register_withprop(SysBusDeviceInfo *info)
+void sysbus_qdev_register_subclass(DeviceInfo *info, const char *parent)
 {
-    info->qdev.init = sysbus_device_init;
-    info->qdev.bus_info = &system_bus_info;
+    info->init = sysbus_device_init;
+    info->bus_info = &system_bus_info;
 
-    assert(info->qdev.size >= sizeof(SysBusDevice));
-    qdev_register(&info->qdev);
+    assert(info->size >= sizeof(SysBusDevice));
+    qdev_register_subclass(info, parent);
 }
 
-void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init)
+void sysbus_qdev_register(DeviceInfo *info)
 {
-    SysBusDeviceInfo *info;
-
-    info = g_malloc0(sizeof(*info));
-    info->qdev.name = g_strdup(name);
-    info->qdev.size = size;
-    info->init = init;
-    sysbus_register_withprop(info);
+    sysbus_qdev_register_subclass(info, TYPE_SYS_BUS_DEVICE);
 }
 
 DeviceState *sysbus_create_varargs(const char *name,
@@ -258,3 +253,18 @@ MemoryRegion *sysbus_address_space(SysBusDevice *dev)
 {
     return get_system_memory();
 }
+
+static TypeInfo sysbus_device_type_info = {
+    .name = TYPE_SYS_BUS_DEVICE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(SysBusDevice),
+    .abstract = true,
+    .class_size = sizeof(SysBusDeviceClass),
+};
+
+static void sysbus_register(void)
+{
+    type_register_static(&sysbus_device_type_info);
+}
+
+device_init(sysbus_register);
diff --git a/hw/sysbus.h b/hw/sysbus.h
index 7b8ca23..a406077 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -12,6 +12,20 @@
 
 typedef struct SysBusDevice SysBusDevice;
 
+#define TYPE_SYS_BUS_DEVICE "sys-bus-device"
+#define SYS_BUS_DEVICE(obj) \
+     OBJECT_CHECK(SysBusDevice, (obj), TYPE_SYS_BUS_DEVICE)
+#define SYS_BUS_DEVICE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(SysBusDeviceClass, (klass), TYPE_SYS_BUS_DEVICE)
+#define SYS_BUS_DEVICE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(SysBusDeviceClass, (obj), TYPE_SYS_BUS_DEVICE)
+
+typedef struct SysBusDeviceClass {
+    DeviceClass parent_class;
+
+    int (*init)(SysBusDevice *dev);
+} SysBusDeviceClass;
+
 struct SysBusDevice {
     DeviceState qdev;
     int num_irq;
@@ -26,19 +40,14 @@ struct SysBusDevice {
     pio_addr_t pio[QDEV_MAX_PIO];
 };
 
-typedef int (*sysbus_initfn)(SysBusDevice *dev);
-
 /* Macros to compensate for lack of type inheritance in C.  */
 #define sysbus_from_qdev(dev) ((SysBusDevice *)(dev))
 #define FROM_SYSBUS(type, dev) DO_UPCAST(type, busdev, dev)
 
-typedef struct {
-    DeviceInfo qdev;
-    sysbus_initfn init;
-} SysBusDeviceInfo;
+#define sysbus_register_withprop(info) sysbus_qdev_register(info)
+void sysbus_qdev_register(DeviceInfo *info);
+void sysbus_qdev_register_subclass(DeviceInfo *info, const char *parent);
 
-void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init);
-void sysbus_register_withprop(SysBusDeviceInfo *info);
 void *sysbus_new(void);
 void sysbus_init_mmio(SysBusDevice *dev, MemoryRegion *memory);
 MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n);
diff --git a/hw/tcx.c b/hw/tcx.c
index 75a28f2..7c8677b 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -646,20 +646,29 @@ static void tcx24_screen_dump(void *opaque, const char *filename)
     return;
 }
 
-static SysBusDeviceInfo tcx_info = {
-    .init = tcx_init1,
-    .qdev.name  = "SUNW,tcx",
-    .qdev.size  = sizeof(TCXState),
-    .qdev.reset = tcx_reset,
-    .qdev.vmsd  = &vmstate_tcx,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_TADDR("addr",      TCXState, addr,      -1),
-        DEFINE_PROP_HEX32("vram_size", TCXState, vram_size, -1),
-        DEFINE_PROP_UINT16("width",    TCXState, width,     -1),
-        DEFINE_PROP_UINT16("height",   TCXState, height,    -1),
-        DEFINE_PROP_UINT16("depth",    TCXState, depth,     -1),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property tcx_properties[] = {
+    DEFINE_PROP_TADDR("addr",      TCXState, addr,      -1),
+    DEFINE_PROP_HEX32("vram_size", TCXState, vram_size, -1),
+    DEFINE_PROP_UINT16("width",    TCXState, width,     -1),
+    DEFINE_PROP_UINT16("height",   TCXState, height,    -1),
+    DEFINE_PROP_UINT16("depth",    TCXState, depth,     -1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void tcx_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = tcx_init1;
+}
+
+static DeviceInfo tcx_info = {
+    .name = "SUNW,tcx",
+    .size = sizeof(TCXState),
+    .reset = tcx_reset,
+    .vmsd = &vmstate_tcx,
+    .props = tcx_properties,
+    .class_init = tcx_class_init,
 };
 
 static void tcx_register_devices(void)
diff --git a/hw/tusb6010.c b/hw/tusb6010.c
index 276300a..8e11c54 100644
--- a/hw/tusb6010.c
+++ b/hw/tusb6010.c
@@ -789,11 +789,18 @@ static int tusb6010_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo tusb6010_info = {
-    .init = tusb6010_init,
-    .qdev.name = "tusb6010",
-    .qdev.size = sizeof(TUSBState),
-    .qdev.reset = tusb6010_reset,
+static void tusb6010_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = tusb6010_init;
+}
+
+static DeviceInfo tusb6010_info = {
+    .name = "tusb6010",
+    .size = sizeof(TUSBState),
+    .reset = tusb6010_reset,
+    .class_init = tusb6010_class_init,
 };
 
 static void tusb6010_register_device(void)
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 6a148e0..2b394c0 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -407,43 +407,69 @@ static DeviceInfo unin_internal_pci_host_info = {
     .class_init = unin_internal_pci_host_class_init,
 };
 
-static SysBusDeviceInfo sysbus_unin_pci_host_info = {
-    .qdev.name = "uni-north-pci-pcihost",
-    .qdev.size = sizeof(UNINState),
-    .init      = pci_unin_main_init_device,
+static void pci_unin_main_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sbc->init = pci_unin_main_init_device;
+}
+
+static DeviceInfo pci_unin_main_info = {
+    .name = "uni-north-pci-pchost",
+    .size = sizeof(UNINState),
+    .class_init = pci_unin_main_class_init,
 };
 
-static SysBusDeviceInfo sysbus_u3_agp_pci_host_info = {
-    .qdev.name = "u3-agp-pcihost",
-    .qdev.size = sizeof(UNINState),
-    .init      = pci_u3_agp_init_device,
+static void pci_u3_agp_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sbc->init = pci_u3_agp_init_device;
+}
+
+static DeviceInfo pci_u3_agp_info = {
+    .name = "u3-agp-pcihost",
+    .size = sizeof(UNINState),
+    .class_init = pci_u3_agp_class_init,
 };
 
-static SysBusDeviceInfo sysbus_unin_agp_pci_host_info = {
-    .qdev.name = "uni-north-agp-pcihost",
-    .qdev.size = sizeof(UNINState),
-    .init      = pci_unin_agp_init_device,
+static void pci_unin_agp_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sbc->init = pci_unin_agp_init_device;
+}
+
+static DeviceInfo pci_unin_agp_info = {
+    .name = "uni-north-agp-pcihost",
+    .size = sizeof(UNINState),
+    .class_init = pci_unin_agp_class_init,
 };
 
-static SysBusDeviceInfo sysbus_unin_internal_pci_host_info = {
-    .qdev.name = "uni-north-internal-pci-pcihost",
-    .qdev.size = sizeof(UNINState),
-    .init      = pci_unin_internal_init_device,
+static void pci_unin_internal_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sbc->init = pci_unin_internal_init_device;
+}
+
+static DeviceInfo pci_unin_internal_info = {
+    .name = "uni-north-internal-pci-pichost",
+    .size = sizeof(UNINState),
+    .class_init = pci_unin_internal_class_init,
 };
 
 static void unin_register_devices(void)
 {
-    sysbus_register_withprop(&sysbus_unin_pci_host_info);
     pci_qdev_register(&unin_main_pci_host_info);
-
-    sysbus_register_withprop(&sysbus_u3_agp_pci_host_info);
     pci_qdev_register(&u3_agp_pci_host_info);
-
-    sysbus_register_withprop(&sysbus_unin_agp_pci_host_info);
     pci_qdev_register(&unin_agp_pci_host_info);
-
-    sysbus_register_withprop(&sysbus_unin_internal_pci_host_info);
     pci_qdev_register(&unin_internal_pci_host_info);
+
+    sysbus_register_withprop(&pci_unin_main_info);
+    sysbus_register_withprop(&pci_u3_agp_info);
+    sysbus_register_withprop(&pci_unin_agp_info);
+    sysbus_register_withprop(&pci_unin_internal_info);
 }
 
 device_init(unin_register_devices)
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index b9b37d5..3437da1 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1861,12 +1861,19 @@ static DeviceInfo ohci_pci_info = {
     .class_init = ohci_pci_class_init,
 };
 
-static SysBusDeviceInfo ohci_sysbus_info = {
-    .init         = ohci_init_pxa,
-    .qdev.name    = "sysbus-ohci",
-    .qdev.desc    = "OHCI USB Controller",
-    .qdev.size    = sizeof(OHCISysBusState),
-    .qdev.props = (Property[]) {
+static void ohci_sysbus_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sbc->init = ohci_init_pxa;
+}
+
+static DeviceInfo ohci_sysbus_info = {
+    .name    = "sysbus-ohci",
+    .desc    = "OHCI USB Controller",
+    .size    = sizeof(OHCISysBusState),
+    .class_init = ohci_sysbus_class_init,
+    .props = (Property[]) {
         DEFINE_PROP_UINT32("num-ports", OHCISysBusState, num_ports, 3),
         DEFINE_PROP_TADDR("dma-offset", OHCISysBusState, dma_offset, 3),
         DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index 0eb7d32..c2eb4dd 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -125,11 +125,36 @@ static DeviceInfo versatile_pci_host_info = {
     .class_init = versatile_pci_host_class_init,
 };
 
+static void pci_vpb_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = pci_vpb_init;
+}
+
+static DeviceInfo pci_vpb_info = {
+    .name = "versatile_pci",
+    .size = sizeof(PCIVPBState),
+    .class_init = pci_vpb_class_init,
+};
+
+static void pci_realview_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = pci_realview_init;
+}
+
+static DeviceInfo pci_realview_info = {
+    .name = "realview_pci",
+    .size = sizeof(PCIVPBState),
+    .class_init = pci_realview_class_init,
+};
+
 static void versatile_pci_register_devices(void)
 {
-    sysbus_register_dev("versatile_pci", sizeof(PCIVPBState), pci_vpb_init);
-    sysbus_register_dev("realview_pci", sizeof(PCIVPBState),
-                        pci_realview_init);
+    sysbus_qdev_register(&pci_vpb_info);
+    sysbus_qdev_register(&pci_realview_info);
     pci_qdev_register(&versatile_pci_host_info);
 }
 
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 0312b75..3f7490c 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -365,12 +365,19 @@ static void versatile_machine_init(void)
 
 machine_init(versatile_machine_init);
 
-static SysBusDeviceInfo vpb_sic_info = {
-    .init = vpb_sic_init,
-    .qdev.name = "versatilepb_sic",
-    .qdev.size = sizeof(vpb_sic_state),
-    .qdev.vmsd = &vmstate_vpb_sic,
-    .qdev.no_user = 1,
+static void vpb_sic_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = vpb_sic_init;
+}
+
+static DeviceInfo vpb_sic_info = {
+    .name = "versatilepb_sic",
+    .size = sizeof(vpb_sic_state),
+    .vmsd = &vmstate_vpb_sic,
+    .no_user = 1,
+    .class_init = vpb_sic_class_init,
 };
 
 static void versatilepb_register_devices(void)
diff --git a/hw/xilinx_axidma.c b/hw/xilinx_axidma.c
index 0da20d9..0fbe415 100644
--- a/hw/xilinx_axidma.c
+++ b/hw/xilinx_axidma.c
@@ -486,15 +486,24 @@ static int xilinx_axidma_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo axidma_info = {
-    .init = xilinx_axidma_init,
-    .qdev.name  = "xilinx,axidma",
-    .qdev.size  = sizeof(struct XilinxAXIDMA),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("freqhz", struct XilinxAXIDMA, freqhz, 50000000),
-        DEFINE_PROP_PTR("dmach", struct XilinxAXIDMA, dmach),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property axidma_properties[] = {
+    DEFINE_PROP_UINT32("freqhz", struct XilinxAXIDMA, freqhz, 50000000),
+    DEFINE_PROP_PTR("dmach", struct XilinxAXIDMA, dmach),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void axidma_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = xilinx_axidma_init;
+}
+
+static DeviceInfo axidma_info = {
+    .name = "xilinx,axidma",
+    .size = sizeof(struct XilinxAXIDMA),
+    .props = axidma_properties,
+    .class_init = axidma_class_init,
 };
 
 static void xilinx_axidma_register(void)
diff --git a/hw/xilinx_axienet.c b/hw/xilinx_axienet.c
index e713248..c7dbe00 100644
--- a/hw/xilinx_axienet.c
+++ b/hw/xilinx_axienet.c
@@ -870,18 +870,27 @@ static int xilinx_enet_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo xilinx_enet_info = {
-    .init = xilinx_enet_init,
-    .qdev.name  = "xilinx,axienet",
-    .qdev.size  = sizeof(struct XilinxAXIEnet),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("phyaddr", struct XilinxAXIEnet, c_phyaddr, 7),
-        DEFINE_PROP_UINT32("c_rxmem", struct XilinxAXIEnet, c_rxmem, 0x1000),
-        DEFINE_PROP_UINT32("c_txmem", struct XilinxAXIEnet, c_txmem, 0x1000),
-        DEFINE_PROP_PTR("dmach", struct XilinxAXIEnet, dmach),
-        DEFINE_NIC_PROPERTIES(struct XilinxAXIEnet, conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property xilinx_enet_properties[] = {
+    DEFINE_PROP_UINT32("phyaddr", struct XilinxAXIEnet, c_phyaddr, 7),
+    DEFINE_PROP_UINT32("c_rxmem", struct XilinxAXIEnet, c_rxmem, 0x1000),
+    DEFINE_PROP_UINT32("c_txmem", struct XilinxAXIEnet, c_txmem, 0x1000),
+    DEFINE_PROP_PTR("dmach", struct XilinxAXIEnet, dmach),
+    DEFINE_NIC_PROPERTIES(struct XilinxAXIEnet, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void xilinx_enet_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = xilinx_enet_init;
+}
+
+static DeviceInfo xilinx_enet_info = {
+    .name = "xilinx,axienet",
+    .size = sizeof(struct XilinxAXIEnet),
+    .props = xilinx_enet_properties,
+    .class_init = xilinx_enet_class_init,
 };
 static void xilinx_enet_register(void)
 {
diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c
index de595f4..dc7c0c8 100644
--- a/hw/xilinx_ethlite.c
+++ b/hw/xilinx_ethlite.c
@@ -226,16 +226,25 @@ static int xilinx_ethlite_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo xilinx_ethlite_info = {
-    .init = xilinx_ethlite_init,
-    .qdev.name  = "xilinx,ethlite",
-    .qdev.size  = sizeof(struct xlx_ethlite),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("txpingpong", struct xlx_ethlite, c_tx_pingpong, 1),
-        DEFINE_PROP_UINT32("rxpingpong", struct xlx_ethlite, c_rx_pingpong, 1),
-        DEFINE_NIC_PROPERTIES(struct xlx_ethlite, conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property xilinx_ethlite_properties[] = {
+    DEFINE_PROP_UINT32("txpingpong", struct xlx_ethlite, c_tx_pingpong, 1),
+    DEFINE_PROP_UINT32("rxpingpong", struct xlx_ethlite, c_rx_pingpong, 1),
+    DEFINE_NIC_PROPERTIES(struct xlx_ethlite, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void xilinx_ethlite_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = xilinx_ethlite_init;
+}
+
+static DeviceInfo xilinx_ethlite_info = {
+    .name = "xilinx,ethlite",
+    .size = sizeof(struct xlx_ethlite),
+    .props = xilinx_ethlite_properties,
+    .class_init = xilinx_ethlite_class_init,
 };
 
 static void xilinx_ethlite_register(void)
diff --git a/hw/xilinx_intc.c b/hw/xilinx_intc.c
index c567885..c26b4ea 100644
--- a/hw/xilinx_intc.c
+++ b/hw/xilinx_intc.c
@@ -161,14 +161,23 @@ static int xilinx_intc_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo xilinx_intc_info = {
-    .init = xilinx_intc_init,
-    .qdev.name  = "xilinx,intc",
-    .qdev.size  = sizeof(struct xlx_pic),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("kind-of-intr", struct xlx_pic, c_kind_of_intr, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property xilinx_intc_properties[] = {
+    DEFINE_PROP_UINT32("kind-of-intr", struct xlx_pic, c_kind_of_intr, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void xilinx_intc_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = xilinx_intc_init;
+}
+
+static DeviceInfo xilinx_intc_info = {
+    .name = "xilinx,intc",
+    .size = sizeof(struct xlx_pic),
+    .props = xilinx_intc_properties,
+    .class_init = xilinx_intc_class_init,
 };
 
 static void xilinx_intc_register(void)
diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c
index adca53b..0755e1b 100644
--- a/hw/xilinx_timer.c
+++ b/hw/xilinx_timer.c
@@ -219,15 +219,24 @@ static int xilinx_timer_init(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo xilinx_timer_info = {
-    .init = xilinx_timer_init,
-    .qdev.name  = "xilinx,timer",
-    .qdev.size  = sizeof(struct timerblock),
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("frequency", struct timerblock, freq_hz,   0),
-        DEFINE_PROP_UINT32("nr-timers", struct timerblock, nr_timers, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property xilinx_timer_properties[] = {
+    DEFINE_PROP_UINT32("frequency", struct timerblock, freq_hz,   0),
+    DEFINE_PROP_UINT32("nr-timers", struct timerblock, nr_timers, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void xilinx_timer_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = xilinx_timer_init;
+}
+
+static DeviceInfo xilinx_timer_info = {
+    .name = "xilinx,timer",
+    .size = sizeof(struct timerblock),
+    .props = xilinx_timer_properties,
+    .class_init = xilinx_timer_class_init,
 };
 
 static void xilinx_timer_register(void)
diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c
index 6533df9..8baabc7 100644
--- a/hw/xilinx_uartlite.c
+++ b/hw/xilinx_uartlite.c
@@ -211,10 +211,22 @@ static int xilinx_uartlite_init(SysBusDevice *dev)
     return 0;
 }
 
+static void xilinx_uartlite_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = xilinx_uartlite_init;
+}
+
+static DeviceInfo xilinx_uartlite_info = {
+    .name = "xilinx,uartlite",
+    .size = sizeof (struct xlx_uartlite),
+    .class_init = xilinx_uartlite_class_init,
+};
+
 static void xilinx_uart_register(void)
 {
-    sysbus_register_dev("xilinx,uartlite", sizeof (struct xlx_uartlite),
-                        xilinx_uartlite_init);
+    sysbus_qdev_register(&xilinx_uartlite_info);
 }
 
 device_init(xilinx_uart_register)
diff --git a/hw/zaurus.c b/hw/zaurus.c
index c4bcd29..b14240c 100644
--- a/hw/zaurus.c
+++ b/hw/zaurus.c
@@ -221,15 +221,24 @@ static const VMStateDescription vmstate_scoop_regs = {
     },
 };
 
-static SysBusDeviceInfo scoop_sysbus_info = {
-    .init           = scoop_init,
-    .qdev.name      = "scoop",
-    .qdev.desc      = "Scoop2 Sharp custom ASIC",
-    .qdev.size      = sizeof(ScoopInfo),
-    .qdev.vmsd      = &vmstate_scoop_regs,
-    .qdev.props     = (Property[]) {
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property scoop_sysbus_properties[] = {
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void scoop_sysbus_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = scoop_init;
+}
+
+static DeviceInfo scoop_sysbus_info = {
+    .name = "scoop",
+    .desc = "Scoop2 Sharp custom ASIC",
+    .size = sizeof(ScoopInfo),
+    .vmsd = &vmstate_scoop_regs,
+    .props = scoop_sysbus_properties,
+    .class_init = scoop_sysbus_class_init,
 };
 
 static void scoop_register(void)
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 28/28] virtio-s390: convert to QEMU Object Model
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (26 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: " Anthony Liguori
@ 2012-01-24 19:33 ` Anthony Liguori
  2012-01-24 23:13 ` [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Peter Maydell
                   ` (2 subsequent siblings)
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 19:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Alexander Graf

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/s390-virtio-bus.c |   93 +++++++++++++++++++++++++++++++++++---------------
 1 files changed, 65 insertions(+), 28 deletions(-)

diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 8e34a78..565941a 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -50,11 +50,19 @@ struct BusInfo s390_virtio_bus_info = {
     .size       = sizeof(VirtIOS390Bus),
 };
 
-typedef struct {
-    DeviceInfo qdev;
+typedef struct VirtIOS390DeviceClass
+{
+    DeviceClass parent_class;
     int (*init)(VirtIOS390Device *dev);
-} VirtIOS390DeviceInfo;
+} VirtIOS390DeviceClass;
 
+#define TYPE_VIRTIO_S390_DEVICE "virtio-s390-device"
+#define VIRTIO_S390_DEVICE(obj) \
+     OBJECT_CHECK(VirtIOS390Device, (obj), TYPE_VIRTIO_S390_DEVICE)
+#define VIRTIO_S390_DEVICE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(VirtIOS390DeviceClass, (klass), TYPE_VIRTIO_S390_DEVICE)
+#define VIRTIO_S390_DEVICE_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(VirtIOS390DeviceClass, (obj), TYPE_VIRTIO_S390_DEVICE)
 
 static const VirtIOBindings virtio_s390_bindings;
 
@@ -343,12 +351,19 @@ static const VirtIOBindings virtio_s390_bindings = {
     .get_features = virtio_s390_get_features,
 };
 
-static VirtIOS390DeviceInfo s390_virtio_net = {
-    .init = s390_virtio_net_init,
-    .qdev.name = "virtio-net-s390",
-    .qdev.alias = "virtio-net",
-    .qdev.size = sizeof(VirtIOS390Device),
-    .qdev.props = (Property[]) {
+static void s390_virtio_net_class_init(ObjectClass *klass, void *data)
+{
+    VirtIOS390DeviceClass *dc = VIRTIO_S390_DEVICE_CLASS(klass);
+
+    dc->init = s390_virtio_net_init;
+}
+
+static DeviceInfo s390_virtio_net = {
+    .name = "virtio-net-s390",
+    .alias = "virtio-net",
+    .size = sizeof(VirtIOS390Device),
+    .class_init = s390_virtio_net_class_init,
+    .props = (Property[]) {
         DEFINE_NIC_PROPERTIES(VirtIOS390Device, nic),
         DEFINE_PROP_UINT32("x-txtimer", VirtIOS390Device,
                            net.txtimer, TX_TIMER_INTERVAL),
@@ -359,24 +374,38 @@ static VirtIOS390DeviceInfo s390_virtio_net = {
     },
 };
 
-static VirtIOS390DeviceInfo s390_virtio_blk = {
-    .init = s390_virtio_blk_init,
-    .qdev.name = "virtio-blk-s390",
-    .qdev.alias = "virtio-blk",
-    .qdev.size = sizeof(VirtIOS390Device),
-    .qdev.props = (Property[]) {
+static void s390_virtio_blk_class_init(ObjectClass *klass, void *data)
+{
+    VirtIOS390DeviceClass *dc = VIRTIO_S390_DEVICE_CLASS(klass);
+
+    dc->init = s390_virtio_blk_init;
+}
+
+static DeviceInfo s390_virtio_blk = {
+    .name = "virtio-blk-s390",
+    .alias = "virtio-blk",
+    .size = sizeof(VirtIOS390Device),
+    .class_init = s390_virtio_blk_class_init,
+    .props = (Property[]) {
         DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, block),
         DEFINE_PROP_STRING("serial", VirtIOS390Device, block_serial),
         DEFINE_PROP_END_OF_LIST(),
     },
 };
 
-static VirtIOS390DeviceInfo s390_virtio_serial = {
-    .init = s390_virtio_serial_init,
-    .qdev.name = "virtio-serial-s390",
-    .qdev.alias = "virtio-serial",
-    .qdev.size = sizeof(VirtIOS390Device),
-    .qdev.props = (Property[]) {
+static void s390_virtio_serial_class_init(ObjectClass *klass, void *data)
+{
+    VirtIOS390DeviceClass *dc = VIRTIO_S390_DEVICE_CLASS(klass);
+
+    dc->init = s390_virtio_serial_init;
+}
+
+static DeviceInfo s390_virtio_serial = {
+    .name = "virtio-serial-s390",
+    .alias = "virtio-serial",
+    .size = sizeof(VirtIOS390Device),
+    .class_init = s390_virtio_serial_class_init,
+    .props = (Property[]) {
         DEFINE_PROP_UINT32("max_ports", VirtIOS390Device,
                            serial.max_virtserial_ports, 31),
         DEFINE_PROP_END_OF_LIST(),
@@ -385,24 +414,32 @@ static VirtIOS390DeviceInfo s390_virtio_serial = {
 
 static int s390_virtio_busdev_init(DeviceState *dev, DeviceInfo *info)
 {
-    VirtIOS390DeviceInfo *_info = (VirtIOS390DeviceInfo *)info;
     VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
+    VirtIOS390DeviceClass *_info = VIRTIO_S390_DEVICE_GET_CLASS(dev);
 
     return _info->init(_dev);
 }
 
-static void s390_virtio_bus_register_withprop(VirtIOS390DeviceInfo *info)
+static void s390_virtio_bus_register_withprop(DeviceInfo *info)
 {
-    info->qdev.init = s390_virtio_busdev_init;
-    info->qdev.bus_info = &s390_virtio_bus_info;
-    info->qdev.unplug = qdev_simple_unplug_cb;
+    info->init = s390_virtio_busdev_init;
+    info->bus_info = &s390_virtio_bus_info;
+    info->unplug = qdev_simple_unplug_cb;
 
-    assert(info->qdev.size >= sizeof(VirtIOS390Device));
-    qdev_register(&info->qdev);
+    assert(info->size >= sizeof(VirtIOS390Device));
+    qdev_register_subclass(info, TYPE_VIRTIO_S390_DEVICE);
 }
 
+static TypeInfo virtio_s390_device_info = {
+    .name = TYPE_VIRTIO_S390_DEVICE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(VirtIOS390Device),
+    .abstract = true,
+};
+
 static void s390_virtio_register(void)
 {
+    type_register_static(&virtio_s390_device_info);
     s390_virtio_bus_register_withprop(&s390_virtio_serial);
     s390_virtio_bus_register_withprop(&s390_virtio_blk);
     s390_virtio_bus_register_withprop(&s390_virtio_net);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 22/28] virtio-serial: convert to QEMU Object Model
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 22/28] virtio-serial: convert to QEMU Object Model Anthony Liguori
@ 2012-01-24 19:59   ` Amit Shah
  2012-01-24 20:13     ` Anthony Liguori
  0 siblings, 1 reply; 77+ messages in thread
From: Amit Shah @ 2012-01-24 19:59 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On (Tue) 24 Jan 2012 [13:33:14], Anthony Liguori wrote:

> diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
> index 982ffbf..edf54d7 100644
> --- a/hw/virtio-serial-bus.c
> +++ b/hw/virtio-serial-bus.c


> @@ -157,7 +157,7 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
>              ssize_t ret;
>  
>              buf_size = port->elem.out_sg[i].iov_len - port->iov_offset;
> -            ret = info->have_data(port,
> +            ret = vsc->have_data(port,
>                                    port->elem.out_sg[i].iov_base
>                                    + port->iov_offset,
>                                    buf_size);

Would be nice if everything was re-indented.

> @@ -176,7 +176,7 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
>                   * 1: chardevs can notify frondends
>                   * 2: the guest driver does not spin in these cases
>                   */
> -                if (!info->is_console) {
> +                if (vsc->is_console) {
>                      virtio_serial_throttle_port(port, true);
>                  }
>                  port->iov_idx = i;

This change is wrong, reverses the if condition.  Was this done
manually or via a script?  If the latter, it would be worthwhile to
check all the conversions.

> -void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info)
> +void virtio_serial_port_qdev_register(DeviceInfo *info)

Should the fn be renamed (replace qdev)?

		Amit

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: " Anthony Liguori
@ 2012-01-24 20:01   ` Jan Kiszka
  2012-01-24 20:21     ` Anthony Liguori
  0 siblings, 1 reply; 77+ messages in thread
From: Jan Kiszka @ 2012-01-24 20:01 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Michael S. Tsirkin, qemu-devel, Alexander Graf,
	Blue Swirl, Andreas Färber, qemu-ppc, Paul Brook,
	Aurelien Jarno, Gerd Hoffmann

[-- Attachment #1: Type: text/plain, Size: 494 bytes --]

On 2012-01-24 20:33, Anthony Liguori wrote:
> This converts three devices because apic and ioapic are subclasses of sysbus.
> Converting subclasses independently of their base class is prohibitively hard.

Hmm, I think that's more than three... Can you split up? At least per
target or per board/machine.

Also, I see a lot of programmatic initialization and a lot of repeating
patterns (specifically regarding trivial class initialization) - there
is no better alternative?

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 22/28] virtio-serial: convert to QEMU Object Model
  2012-01-24 19:59   ` Amit Shah
@ 2012-01-24 20:13     ` Anthony Liguori
  0 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 20:13 UTC (permalink / raw)
  To: Amit Shah; +Cc: qemu-devel

On 01/24/2012 01:59 PM, Amit Shah wrote:
> On (Tue) 24 Jan 2012 [13:33:14], Anthony Liguori wrote:
>
>> diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
>> index 982ffbf..edf54d7 100644
>> --- a/hw/virtio-serial-bus.c
>> +++ b/hw/virtio-serial-bus.c
>
>
>> @@ -157,7 +157,7 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
>>               ssize_t ret;
>>
>>               buf_size = port->elem.out_sg[i].iov_len - port->iov_offset;
>> -            ret = info->have_data(port,
>> +            ret = vsc->have_data(port,
>>                                     port->elem.out_sg[i].iov_base
>>                                     + port->iov_offset,
>>                                     buf_size);
>
> Would be nice if everything was re-indented.

That'll need to be a follow-on.  This was mostly scripted.

>
>> @@ -176,7 +176,7 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
>>                    * 1: chardevs can notify frondends
>>                    * 2: the guest driver does not spin in these cases
>>                    */
>> -                if (!info->is_console) {
>> +                if (vsc->is_console) {
>>                       virtio_serial_throttle_port(port, true);
>>                   }
>>                   port->iov_idx = i;
>
> This change is wrong, reverses the if condition.  Was this done
> manually or via a script?  If the latter, it would be worthwhile to
> check all the conversions.

This was a manual rebase conflict resolution change on my part.  I'll fix.

>
>> -void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info)
>> +void virtio_serial_port_qdev_register(DeviceInfo *info)
>
> Should the fn be renamed (replace qdev)?

It'll go away entirely in 3/3 which I'll post in a couple days.

Regards,

Anthony Liguori

>
> 		Amit
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-24 20:01   ` Jan Kiszka
@ 2012-01-24 20:21     ` Anthony Liguori
  2012-01-24 21:01       ` Jan Kiszka
  0 siblings, 1 reply; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 20:21 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Peter Maydell, Michael S. Tsirkin, qemu-devel, Alexander Graf,
	Blue Swirl, Andreas Färber, qemu-ppc, Paul Brook,
	Aurelien Jarno, Gerd Hoffmann

On 01/24/2012 02:01 PM, Jan Kiszka wrote:
> On 2012-01-24 20:33, Anthony Liguori wrote:
>> This converts three devices because apic and ioapic are subclasses of sysbus.
>> Converting subclasses independently of their base class is prohibitively hard.
>
> Hmm, I think that's more than three... Can you split up? At least per
> target or per board/machine.

I meant three classes of devices.

I don't see a reasonable way to split it up.  I put an awful lot of work into 
just splitting things up at this level.  I know it's a big patch but at the same 
time, the changes are entirely mechanical so reviewing shouldn't be that bad.

>
> Also, I see a lot of programmatic initialization and a lot of repeating
> patterns (specifically regarding trivial class initialization) - there
> is no better alternative?

Not really, no.  It looks bad now because you have DeviceInfo still.  Once 
DeviceInfo goes away, all of the initialization will happen in the class_init 
function.

The design of QOM is such that a lot of what was previously done via declarative 
structures is now done imperatively.  But the code bloat that came in this patch 
series will decrease significantly with the next series as we eliminate DeviceInfo.

Regards,

Anthony Liguori

> Jan

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-24 20:21     ` Anthony Liguori
@ 2012-01-24 21:01       ` Jan Kiszka
  2012-01-24 21:11         ` Anthony Liguori
  0 siblings, 1 reply; 77+ messages in thread
From: Jan Kiszka @ 2012-01-24 21:01 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Michael S. Tsirkin, qemu-devel, Alexander Graf,
	Blue Swirl, Andreas Färber, qemu-ppc, Paul Brook,
	Aurelien Jarno, Gerd Hoffmann

[-- Attachment #1: Type: text/plain, Size: 744 bytes --]

On 2012-01-24 21:21, Anthony Liguori wrote:
>> Also, I see a lot of programmatic initialization and a lot of repeating
>> patterns (specifically regarding trivial class initialization) - there
>> is no better alternative?
> 
> Not really, no.  It looks bad now because you have DeviceInfo still. 
> Once DeviceInfo goes away, all of the initialization will happen in the
> class_init function.
> 
> The design of QOM is such that a lot of what was previously done via
> declarative structures is now done imperatively.  But the code bloat
> that came in this patch series will decrease significantly with the next
> series as we eliminate DeviceInfo.

Are there examples of fully converted devices to get an impression?

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-24 21:01       ` Jan Kiszka
@ 2012-01-24 21:11         ` Anthony Liguori
  2012-01-24 21:31           ` Jan Kiszka
  0 siblings, 1 reply; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 21:11 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Peter Maydell, Anthony Liguori, Michael S. Tsirkin, qemu-devel,
	Alexander Graf, Blue Swirl, Andreas Färber, qemu-ppc,
	Paul Brook, Aurelien Jarno, Gerd Hoffmann

On 01/24/2012 03:01 PM, Jan Kiszka wrote:
> On 2012-01-24 21:21, Anthony Liguori wrote:
>>> Also, I see a lot of programmatic initialization and a lot of repeating
>>> patterns (specifically regarding trivial class initialization) - there
>>> is no better alternative?
>>
>> Not really, no.  It looks bad now because you have DeviceInfo still.
>> Once DeviceInfo goes away, all of the initialization will happen in the
>> class_init function.
>>
>> The design of QOM is such that a lot of what was previously done via
>> declarative structures is now done imperatively.  But the code bloat
>> that came in this patch series will decrease significantly with the next
>> series as we eliminate DeviceInfo.
>
> Are there examples of fully converted devices to get an impression?

https://github.com/aliguori/qemu/tree/qom-rebase.8

Has everything fully converted (including BusState).

If you look at qdev.[ch], you'll notice the remaining qdev infrastructure 
becomes greatly simplified.

Regards,

Anthony Liguori

>
> Jan
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-24 21:11         ` Anthony Liguori
@ 2012-01-24 21:31           ` Jan Kiszka
  2012-01-24 21:53             ` Anthony Liguori
  0 siblings, 1 reply; 77+ messages in thread
From: Jan Kiszka @ 2012-01-24 21:31 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Anthony Liguori, Michael S. Tsirkin, qemu-devel,
	Alexander Graf, Blue Swirl, Andreas Färber, qemu-ppc,
	Paul Brook, Aurelien Jarno, Gerd Hoffmann

[-- Attachment #1: Type: text/plain, Size: 1604 bytes --]

On 2012-01-24 22:11, Anthony Liguori wrote:
> On 01/24/2012 03:01 PM, Jan Kiszka wrote:
>> On 2012-01-24 21:21, Anthony Liguori wrote:
>>>> Also, I see a lot of programmatic initialization and a lot of repeating
>>>> patterns (specifically regarding trivial class initialization) - there
>>>> is no better alternative?
>>>
>>> Not really, no.  It looks bad now because you have DeviceInfo still.
>>> Once DeviceInfo goes away, all of the initialization will happen in the
>>> class_init function.
>>>
>>> The design of QOM is such that a lot of what was previously done via
>>> declarative structures is now done imperatively.  But the code bloat
>>> that came in this patch series will decrease significantly with the next
>>> series as we eliminate DeviceInfo.
>>
>> Are there examples of fully converted devices to get an impression?
> 
> https://github.com/aliguori/qemu/tree/qom-rebase.8
> 
> Has everything fully converted (including BusState).
> 
> If you look at qdev.[ch], you'll notice the remaining qdev
> infrastructure becomes greatly simplified.

But I don't get yet why all these repeating initialization tasks need to
be open-coded instead of remaining declarative.

Why can't a generic class init handler of TYPE_DEVICE not copy over all
relevant fields from a, say, DeviceTypeInfo super-struct? And a sysbus
class init handler could do the same from SysBusTypeInfo. That way you
could define your device class again in a single struct instead of
multiple ones + the init handler. If there are special needs, that
handler would still be there.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-24 21:31           ` Jan Kiszka
@ 2012-01-24 21:53             ` Anthony Liguori
  2012-01-24 22:06               ` Jan Kiszka
  0 siblings, 1 reply; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 21:53 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Peter Maydell, Michael S. Tsirkin, Alexander Graf, qemu-devel,
	Blue Swirl, Andreas Färber, qemu-ppc, Paul Brook,
	Aurelien Jarno, Gerd Hoffmann

On 01/24/2012 03:31 PM, Jan Kiszka wrote:
> On 2012-01-24 22:11, Anthony Liguori wrote:
>> On 01/24/2012 03:01 PM, Jan Kiszka wrote:
>>> On 2012-01-24 21:21, Anthony Liguori wrote:
>>>>> Also, I see a lot of programmatic initialization and a lot of repeating
>>>>> patterns (specifically regarding trivial class initialization) - there
>>>>> is no better alternative?
>>>>
>>>> Not really, no.  It looks bad now because you have DeviceInfo still.
>>>> Once DeviceInfo goes away, all of the initialization will happen in the
>>>> class_init function.
>>>>
>>>> The design of QOM is such that a lot of what was previously done via
>>>> declarative structures is now done imperatively.  But the code bloat
>>>> that came in this patch series will decrease significantly with the next
>>>> series as we eliminate DeviceInfo.
>>>
>>> Are there examples of fully converted devices to get an impression?
>>
>> https://github.com/aliguori/qemu/tree/qom-rebase.8
>>
>> Has everything fully converted (including BusState).
>>
>> If you look at qdev.[ch], you'll notice the remaining qdev
>> infrastructure becomes greatly simplified.
>
> But I don't get yet why all these repeating initialization tasks need to
> be open-coded instead of remaining declarative.

It would look like:

static void device_generic_class_init(ObjectClass *klass, void *data)
{
     DeviceClass *dc = DEVICE_CLASS(klass);
     DeviceTypeInfo *ti = data;

     if (ti->reset) {
        dc->reset = ti->reset;
     }
     if (ti->vmsd) {
        dc->vmsd = ti->vmsd;
     }
}

void device_type_register_static(DeviceTypeInfo *ti)
{
     TypeInfo ti = {
       .class_init = device_generic_class_init,
       .class_data = ti,
       // ...
     }
     type_register_static(&ti);
}

But I don't like this.  The problem is that the declarative syntax we have 
doesn't distinguish between "not-specified" and "zero-initialized".  It's also 
tempting to just drop the if (ti->reset) check but that means that you 
unconditionally override the base class implementation even if it's not specified.

I don't see any tangible benefits to a declarative syntax except that it makes 
it harder to get right because you have to write per-base class initialization 
functions and it's very easy to get polymorphism wrong there.

We're not talking about a code size difference.  It's a wash in terms of number 
of lines of code.

Imperative allows you to explicit zero-initialize, accept the previous version 
(from the base class), or override with a new value.

Regards,

Anthony Liguori

>
> Jan
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-24 21:53             ` Anthony Liguori
@ 2012-01-24 22:06               ` Jan Kiszka
  2012-01-24 23:03                 ` Anthony Liguori
  0 siblings, 1 reply; 77+ messages in thread
From: Jan Kiszka @ 2012-01-24 22:06 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Michael S. Tsirkin, Alexander Graf, qemu-devel,
	Blue Swirl, Andreas Färber, qemu-ppc, Paul Brook,
	Aurelien Jarno, Gerd Hoffmann

[-- Attachment #1: Type: text/plain, Size: 3157 bytes --]

On 2012-01-24 22:53, Anthony Liguori wrote:
> On 01/24/2012 03:31 PM, Jan Kiszka wrote:
>> On 2012-01-24 22:11, Anthony Liguori wrote:
>>> On 01/24/2012 03:01 PM, Jan Kiszka wrote:
>>>> On 2012-01-24 21:21, Anthony Liguori wrote:
>>>>>> Also, I see a lot of programmatic initialization and a lot of
>>>>>> repeating
>>>>>> patterns (specifically regarding trivial class initialization) -
>>>>>> there
>>>>>> is no better alternative?
>>>>>
>>>>> Not really, no.  It looks bad now because you have DeviceInfo still.
>>>>> Once DeviceInfo goes away, all of the initialization will happen in
>>>>> the
>>>>> class_init function.
>>>>>
>>>>> The design of QOM is such that a lot of what was previously done via
>>>>> declarative structures is now done imperatively.  But the code bloat
>>>>> that came in this patch series will decrease significantly with the
>>>>> next
>>>>> series as we eliminate DeviceInfo.
>>>>
>>>> Are there examples of fully converted devices to get an impression?
>>>
>>> https://github.com/aliguori/qemu/tree/qom-rebase.8
>>>
>>> Has everything fully converted (including BusState).
>>>
>>> If you look at qdev.[ch], you'll notice the remaining qdev
>>> infrastructure becomes greatly simplified.
>>
>> But I don't get yet why all these repeating initialization tasks need to
>> be open-coded instead of remaining declarative.
> 
> It would look like:
> 
> static void device_generic_class_init(ObjectClass *klass, void *data)
> {
>     DeviceClass *dc = DEVICE_CLASS(klass);
>     DeviceTypeInfo *ti = data;
> 
>     if (ti->reset) {
>        dc->reset = ti->reset;
>     }
>     if (ti->vmsd) {
>        dc->vmsd = ti->vmsd;
>     }
> }
> 
> void device_type_register_static(DeviceTypeInfo *ti)
> {
>     TypeInfo ti = {
>       .class_init = device_generic_class_init,
>       .class_data = ti,
>       // ...
>     }
>     type_register_static(&ti);
> }
> 
> But I don't like this.  The problem is that the declarative syntax we
> have doesn't distinguish between "not-specified" and
> "zero-initialized".

That's surely solvable.

>  It's also tempting to just drop the if (ti->reset)
> check but that means that you unconditionally override the base class
> implementation even if it's not specified.

That as well, just wrap this repeating pattern in a macro.

> 
> I don't see any tangible benefits to a declarative syntax except that it
> makes it harder to get right because you have to write per-base class
> initialization functions and it's very easy to get polymorphism wrong
> there.

Now you have to write way more derived class init functions - provided a
base class is used more than once.

> 
> We're not talking about a code size difference.  It's a wash in terms of
> number of lines of code.

We are. Code size will be smaller, so the number of lines. How much,
that depends on the number of users per base class.

> 
> Imperative allows you to explicit zero-initialize, accept the previous
> version (from the base class), or override with a new value.

None of this is impossible with a declarative approach.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-24 22:06               ` Jan Kiszka
@ 2012-01-24 23:03                 ` Anthony Liguori
  2012-01-25  8:33                   ` Andreas Färber
  2012-01-25  8:37                   ` Jan Kiszka
  0 siblings, 2 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 23:03 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Peter Maydell, Michael S. Tsirkin, qemu-devel, Alexander Graf,
	Blue Swirl, Andreas Färber, qemu-ppc, Paul Brook,
	Aurelien Jarno, Gerd Hoffmann

On 01/24/2012 04:06 PM, Jan Kiszka wrote:
> On 2012-01-24 22:53, Anthony Liguori wrote:
>> But I don't like this.  The problem is that the declarative syntax we
>> have doesn't distinguish between "not-specified" and
>> "zero-initialized".
>
> That's surely solvable.

Please try :-)

I've spent a good chunk of time mulling this over and could not find an 
acceptable solution.  I think the same is true for the GObject folks.

There is a declarative solution for this that I know of, a C++ class definition ;-)

>>   It's also tempting to just drop the if (ti->reset)
>> check but that means that you unconditionally override the base class
>> implementation even if it's not specified.
>
> That as well, just wrap this repeating pattern in a macro.

I'm fairly certain that would be hideous.

>> I don't see any tangible benefits to a declarative syntax except that it
>> makes it harder to get right because you have to write per-base class
>> initialization functions and it's very easy to get polymorphism wrong
>> there.
>
> Now you have to write way more derived class init functions - provided a
> base class is used more than once.

I don't understand why that's a problem.

>> We're not talking about a code size difference.  It's a wash in terms of
>> number of lines of code.
>
> We are. Code size will be smaller, so the number of lines. How much,
> that depends on the number of users per base class.

Compare:

static void my_device_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    dc->reset = my_device_reset;
}

static TypeInfo my_device_type_info = {
    .name = TYPE_MY_DEVICE,
    .parent = TYPE_DEVICE,
    .class_init = my_device_class_init,
};

static void register_devices(void)
{
    type_register_static(&my_device_type_info);
}

To:

static DeviceTypeInfo my_device_ops = {
     .reset = my_device_reset,
};

static TypeInfo my_device_type_info = {
     .name = TYPE_MY_DEVICE,
     .parent = TYPE_DEVICE,
     .class_init = device_generic_init,
     .class_data = my_device_ops,
};

static void register_devices(void)
{
    type_register_static(&my_device_type_info);
}

They're exactly the same size (16 lines).  If you embed TypeInfo into 
DeviceTypeInfo, and introduce a Device specific type registration function, then 
you could do:

static DeviceTypeInfo my_device_type_info = {
     .type.name = TYPE_MY_DEVICE,
     .type.parent = TYPE_PARENT_DEVICE,
     .reset = my_device_reset,
};

static void register_devices(void)
{
     device_type_register_static(&my_device_type_info);
}

Which admittedly saves 6 lines, but also is a big step backwards IMHO.  Now 
you've got a lot of one-off functions which means you loose the advantage of 
having everything work through the same infrastructure.  The likelihood that 
someone is going to do something whacky in device_type_register_static is high 
IMHO.  I think parent initialization (.type.name) is ugly.

Plus, if you do need a class_init function (if you want to save off the super 
class value for some function), then you need to revert back to style (1) anyway.

It'll never get better than this.  The 6 line difference is fixed and is mostly 
whitespace/curly brackets.

>>
>> Imperative allows you to explicit zero-initialize, accept the previous
>> version (from the base class), or override with a new value.
>
> None of this is impossible with a declarative approach.

The class_data method would allow for class initialization based on a 
declarative description so it will always be possible to add at some point if 
someone figures out the ultimate clever way to do it.

Regards,

Anthony Liguori

>
> Jan
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (27 preceding siblings ...)
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 28/28] virtio-s390: " Anthony Liguori
@ 2012-01-24 23:13 ` Peter Maydell
  2012-01-24 23:16   ` Anthony Liguori
  2012-01-25 18:31 ` Blue Swirl
  2012-01-27 17:34 ` Anthony Liguori
  30 siblings, 1 reply; 77+ messages in thread
From: Peter Maydell @ 2012-01-24 23:13 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On 24 January 2012 19:32, Anthony Liguori <aliguori@us.ibm.com> wrote:
> This series makes qdev a proper Object and converts qdev's type inheritance to
> QOM inheritance.

> I've tested this series extensively for the pc target including bisectability.
> I have not tested any other targets yet so your mileage may vary.

I've tested the vexpress target (including serial, mouse, video,
lan9118, sdcard),
seems to still work ok...

-- PMM

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev
  2012-01-24 23:13 ` [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Peter Maydell
@ 2012-01-24 23:16   ` Anthony Liguori
  0 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-24 23:16 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Anthony Liguori, qemu-devel

On 01/24/2012 05:13 PM, Peter Maydell wrote:
> On 24 January 2012 19:32, Anthony Liguori<aliguori@us.ibm.com>  wrote:
>> This series makes qdev a proper Object and converts qdev's type inheritance to
>> QOM inheritance.
>
>> I've tested this series extensively for the pc target including bisectability.
>> I have not tested any other targets yet so your mileage may vary.
>
> I've tested the vexpress target (including serial, mouse, video,
> lan9118, sdcard),
> seems to still work ok...

Great, thanks!  I was planning on running vexpress through qemu-test.

Regards,

Anthony Liguori

>
> -- PMM
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-24 23:03                 ` Anthony Liguori
@ 2012-01-25  8:33                   ` Andreas Färber
  2012-01-25 12:09                     ` Avi Kivity
                                       ` (2 more replies)
  2012-01-25  8:37                   ` Jan Kiszka
  1 sibling, 3 replies; 77+ messages in thread
From: Andreas Färber @ 2012-01-25  8:33 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Michael S. Tsirkin, qemu-devel, Alexander Graf,
	Blue Swirl, Jan Kiszka, Paul Brook, qemu-ppc, Aurelien Jarno,
	Gerd Hoffmann

Am 25.01.2012 00:03, schrieb Anthony Liguori:
> On 01/24/2012 04:06 PM, Jan Kiszka wrote:
>> On 2012-01-24 22:53, Anthony Liguori wrote:
>>> But I don't like this.  The problem is that the declarative syntax we
>>> have doesn't distinguish between "not-specified" and
>>> "zero-initialized".
>>
>> That's surely solvable.
> 
> Please try :-)
> 
> I've spent a good chunk of time mulling this over and could not find an
> acceptable solution.  I think the same is true for the GObject folks.
> 
> There is a declarative solution for this that I know of, a C++ class
> definition ;-)

So what's the reason not to go with one of the object-oriented,
C-compatible languages GCC supports, like C++ or Objective-C/C++?
(Objective-C has native reflection capabilities fwiw.)

Personally I disliked those trivial mini init functions in the initial
2/4 series, too, but I don't really mind an imperative approach either.

Andreas
-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-24 23:03                 ` Anthony Liguori
  2012-01-25  8:33                   ` Andreas Färber
@ 2012-01-25  8:37                   ` Jan Kiszka
  2012-01-25 10:15                     ` Paolo Bonzini
  2012-01-25 14:00                     ` Anthony Liguori
  1 sibling, 2 replies; 77+ messages in thread
From: Jan Kiszka @ 2012-01-25  8:37 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Michael S. Tsirkin, qemu-devel, Alexander Graf,
	Blue Swirl, Andreas Färber, qemu-ppc, Paul Brook,
	Aurelien Jarno, Gerd Hoffmann

[-- Attachment #1: Type: text/plain, Size: 1327 bytes --]

On 2012-01-25 00:03, Anthony Liguori wrote:
> They're exactly the same size (16 lines).  If you embed TypeInfo into
> DeviceTypeInfo, and introduce a Device specific type registration
> function, then you could do:
> 
> static DeviceTypeInfo my_device_type_info = {
>     .type.name = TYPE_MY_DEVICE,
>     .type.parent = TYPE_PARENT_DEVICE,
>     .reset = my_device_reset,

And if you introduce some

#define TYPE_UNIMPLEMENTED (void *)&dummy_variable

you can easily express

[.field = NULL]         => use parent
 .field = UNIMPLEMENTED => don't run any handler

> };
> 
> static void register_devices(void)
> {
>     device_type_register_static(&my_device_type_info);
> }
> 
> Which admittedly saves 6 lines, but also is a big step backwards IMHO. 
> Now you've got a lot of one-off functions which means you loose the
> advantage of having everything work through the same infrastructure. 

Can't follow. Four lines

[static inline] void device_type_register_static(DeviceTypeInfo *dt)
{
    type_register_static(&dt->type);
}

are neither ugly nor complex. Rather, this helps concentrating effort at
_central_ places instead of decentralizing and duplicating lines like in
your imperative approach. That's the whole point: keep the common case
(derived classes) compact.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-25  8:37                   ` Jan Kiszka
@ 2012-01-25 10:15                     ` Paolo Bonzini
  2012-01-25 10:27                       ` Jan Kiszka
  2012-01-25 14:00                     ` Anthony Liguori
  1 sibling, 1 reply; 77+ messages in thread
From: Paolo Bonzini @ 2012-01-25 10:15 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Peter Maydell, Michael S. Tsirkin, Alexander Graf, qemu-devel,
	Blue Swirl, Andreas Färber, qemu-ppc, Paul Brook,
	Aurelien Jarno, Gerd Hoffmann

On 01/25/2012 09:37 AM, Jan Kiszka wrote:
>> >  They're exactly the same size (16 lines).  If you embed TypeInfo into
>> >  DeviceTypeInfo, and introduce a Device specific type registration
>> >  function, then you could do:
>> >
>> >  static DeviceTypeInfo my_device_type_info = {
>> >       .type.name = TYPE_MY_DEVICE,
>> >       .type.parent = TYPE_PARENT_DEVICE,
>> >       .reset = my_device_reset,
> And if you introduce some
>
> #define TYPE_UNIMPLEMENTED (void *)&dummy_variable
>
> you can easily express
>
> [.field = NULL]         =>  use parent
>   .field = UNIMPLEMENTED =>  don't run any handler
>

I agree with Anthony, this would get really ugly where you are calling 
the functions and doing the class initialization.  It's a different 
style from what we're used to, granted, but the difference in code size 
is not relevant (not enough to introduce a level of macro magic, at 
least) and the diffstat in this series is misleading because qdev is 
left with temporary duplication for now.

(I also complained with him about this a month ago or so).

Paolo

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-25 10:15                     ` Paolo Bonzini
@ 2012-01-25 10:27                       ` Jan Kiszka
  2012-01-25 11:15                         ` Paolo Bonzini
  0 siblings, 1 reply; 77+ messages in thread
From: Jan Kiszka @ 2012-01-25 10:27 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Peter Maydell, Michael S. Tsirkin, Alexander Graf, qemu-devel,
	Blue Swirl, Andreas Färber, qemu-ppc, Paul Brook,
	Aurelien Jarno, Gerd Hoffmann

[-- Attachment #1: Type: text/plain, Size: 1387 bytes --]

On 2012-01-25 11:15, Paolo Bonzini wrote:
> On 01/25/2012 09:37 AM, Jan Kiszka wrote:
>>> >  They're exactly the same size (16 lines).  If you embed TypeInfo into
>>> >  DeviceTypeInfo, and introduce a Device specific type registration
>>> >  function, then you could do:
>>> >
>>> >  static DeviceTypeInfo my_device_type_info = {
>>> >       .type.name = TYPE_MY_DEVICE,
>>> >       .type.parent = TYPE_PARENT_DEVICE,
>>> >       .reset = my_device_reset,
>> And if you introduce some
>>
>> #define TYPE_UNIMPLEMENTED (void *)&dummy_variable
>>
>> you can easily express
>>
>> [.field = NULL]         =>  use parent
>>   .field = UNIMPLEMENTED =>  don't run any handler
>>
> 
> I agree with Anthony, this would get really ugly where you are calling
> the functions and doing the class initialization.

I think we need to try it first.

There is a lot of repetition, and that gets boring at beat and ugly at
worst when doing it for hundreds of devices - compared to the number of
base classes we will have.

>  It's a different
> style from what we're used to, granted, but the difference in code size
> is not relevant (not enough to introduce a level of macro magic, at
> least) and the diffstat in this series is misleading because qdev is
> left with temporary duplication for now.

I was looking at the final version Anthony pointed at.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-25 10:27                       ` Jan Kiszka
@ 2012-01-25 11:15                         ` Paolo Bonzini
  0 siblings, 0 replies; 77+ messages in thread
From: Paolo Bonzini @ 2012-01-25 11:15 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Peter Maydell, Michael S. Tsirkin, qemu-devel, Alexander Graf,
	Blue Swirl, Andreas Färber, qemu-ppc, Paul Brook,
	Aurelien Jarno, Gerd Hoffmann

On 01/25/2012 11:27 AM, Jan Kiszka wrote:
> >  I agree with Anthony, this would get really ugly where you are calling
> >  the functions and doing the class initialization.
>
> I think we need to try it first.
>
> There is a lot of repetition, and that gets boring at beat and ugly at
> worst when doing it for hundreds of devices - compared to the number of
> base classes we will have.

I think we have to trust Anthony's judgement that he tried it and didn't 
like it.  Perhaps he didn't try _exactly_ the version that you gave, but 
I think it's not fair to say "please try redoing it this way---maybe" a 
month after the first version has been posted.

So far, we were always able to reach a compromise between Anthony's 
taste and others', and also on the order with which to do things.  I 
understand this is a pretty major issue, but it's going to be one more 
such compromise (and one that I thought had already been settled).

Note that it's not impossible to change directions!  QOM started with 
the idea of converting devices _last_.  We are converting them _first_. 
  That was a very early change in plans, and very much against Anthony. 
  It's fair and natural that the balance swings in the other direction 
now.  As a reviewer, the later you join the party, the harder it will be 
to swallow the pill.

> >  It's a different
> >  style from what we're used to, granted, but the difference in code size
> >  is not relevant (not enough to introduce a level of macro magic, at
> >  least) and the diffstat in this series is misleading because qdev is
> >  left with temporary duplication for now.
>
> I was looking at the final version Anthony pointed at.

There _are_ things that leave something to be desired in there.  For 
example I don't like accessing the base class with a different name, as in:

     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

     dc->props = e100_properties;
     dc->desc = info->desc;
     k->vendor_id = PCI_VENDOR_ID_INTEL;
     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
     k->romfile = "pxe-eepro100.rom";
     ...

and a few more things that we'll discuss as soon as he posts the third 
instalment.  I know we're all busy, but the only way to solve these 
problems is prompt review.

Paolo

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-25  8:33                   ` Andreas Färber
@ 2012-01-25 12:09                     ` Avi Kivity
  2012-01-25 13:02                     ` Paul Brook
  2012-01-25 14:25                     ` Anthony Liguori
  2 siblings, 0 replies; 77+ messages in thread
From: Avi Kivity @ 2012-01-25 12:09 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Michael S. Tsirkin, Alexander Graf, qemu-devel,
	Blue Swirl, Jan Kiszka, Paul Brook, qemu-ppc, Aurelien Jarno,
	Gerd Hoffmann

On 01/25/2012 10:33 AM, Andreas Färber wrote:
> > 
> > There is a declarative solution for this that I know of, a C++ class
> > definition ;-)
>
> So what's the reason not to go with one of the object-oriented,
> C-compatible languages GCC supports, like C++ or Objective-C/C++?
> (Objective-C has native reflection capabilities fwiw.)

I believe everyone except Anthony and myself is against it.  But now we
are three.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 26/28] pci: convert to QEMU Object Model
  2012-01-24 19:33   ` Anthony Liguori
@ 2012-01-25 12:41     ` Michael S. Tsirkin
  -1 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2012-01-25 12:41 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Kevin Wolf, xen-devel, Stefano Stabellini, qemu-devel,
	Alexander Graf, Blue Swirl, Andreas Färber, qemu-ppc,
	Paul Brook, Gerd Hoffmann

On Tue, Jan 24, 2012 at 01:33:18PM -0600, Anthony Liguori wrote:
> diff --git a/hw/ac97.c b/hw/ac97.c
> index 03be99b..33b85f5 100644
> --- a/hw/ac97.c
> +++ b/hw/ac97.c
> @@ -1344,21 +1344,30 @@ int ac97_init (PCIBus *bus)
>      return 0;
>  }
>  
> -static PCIDeviceInfo ac97_info = {
> -    .qdev.name    = "AC97",
> -    .qdev.desc    = "Intel 82801AA AC97 Audio",
> -    .qdev.size    = sizeof (AC97LinkState),
> -    .qdev.vmsd    = &vmstate_ac97,
> -    .init         = ac97_initfn,
> -    .exit         = ac97_exitfn,
> -    .vendor_id    = PCI_VENDOR_ID_INTEL,
> -    .device_id    = PCI_DEVICE_ID_INTEL_82801AA_5,
> -    .revision     = 0x01,
> -    .class_id     = PCI_CLASS_MULTIMEDIA_AUDIO,
> -    .qdev.props   = (Property[]) {
> -        DEFINE_PROP_UINT32("use_broken_id", AC97LinkState, use_broken_id, 0),
> -        DEFINE_PROP_END_OF_LIST(),
> -    }
> +static Property ac97_properties[] = {
> +    DEFINE_PROP_UINT32("use_broken_id", AC97LinkState, use_broken_id, 0),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void ac97_class_init(ObjectClass *klass, void *data)
> +{
> +    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> +
> +    k->init = ac97_initfn;
> +    k->exit = ac97_exitfn;
> +    k->vendor_id = PCI_VENDOR_ID_INTEL;
> +    k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
> +    k->revision = 0x01;
> +    k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
> +}
> +
> +static DeviceInfo ac97_info = {
> +    .name = "AC97",
> +    .desc = "Intel 82801AA AC97 Audio",
> +    .size = sizeof (AC97LinkState),
> +    .vmsd = &vmstate_ac97,
> +    .props = ac97_properties,
> +    .class_init = ac97_class_init,
>  };
>  
>  static void ac97_register (void)

So I have a question on this: the whole reason
we moved class, vendor id etc away from device init
functions to a table was to make it possible
to perform queries, like list all available sound device
types, or sort devices based on type, based on these tables.

Another purpose was to remove the manually written description/name,
embedding pci id database in qemu instead, and performing
lookups based on device/vendor id.

We never got these patches but it sounds like a genuinely useful
functionality.

Is this no longer possible?

-- 
MST

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 26/28] pci: convert to QEMU Object Model
@ 2012-01-25 12:41     ` Michael S. Tsirkin
  0 siblings, 0 replies; 77+ messages in thread
From: Michael S. Tsirkin @ 2012-01-25 12:41 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Kevin Wolf, xen-devel, Stefano Stabellini, qemu-devel,
	Alexander Graf, Blue Swirl, Andreas Färber, qemu-ppc,
	Paul Brook, Gerd Hoffmann

On Tue, Jan 24, 2012 at 01:33:18PM -0600, Anthony Liguori wrote:
> diff --git a/hw/ac97.c b/hw/ac97.c
> index 03be99b..33b85f5 100644
> --- a/hw/ac97.c
> +++ b/hw/ac97.c
> @@ -1344,21 +1344,30 @@ int ac97_init (PCIBus *bus)
>      return 0;
>  }
>  
> -static PCIDeviceInfo ac97_info = {
> -    .qdev.name    = "AC97",
> -    .qdev.desc    = "Intel 82801AA AC97 Audio",
> -    .qdev.size    = sizeof (AC97LinkState),
> -    .qdev.vmsd    = &vmstate_ac97,
> -    .init         = ac97_initfn,
> -    .exit         = ac97_exitfn,
> -    .vendor_id    = PCI_VENDOR_ID_INTEL,
> -    .device_id    = PCI_DEVICE_ID_INTEL_82801AA_5,
> -    .revision     = 0x01,
> -    .class_id     = PCI_CLASS_MULTIMEDIA_AUDIO,
> -    .qdev.props   = (Property[]) {
> -        DEFINE_PROP_UINT32("use_broken_id", AC97LinkState, use_broken_id, 0),
> -        DEFINE_PROP_END_OF_LIST(),
> -    }
> +static Property ac97_properties[] = {
> +    DEFINE_PROP_UINT32("use_broken_id", AC97LinkState, use_broken_id, 0),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void ac97_class_init(ObjectClass *klass, void *data)
> +{
> +    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> +
> +    k->init = ac97_initfn;
> +    k->exit = ac97_exitfn;
> +    k->vendor_id = PCI_VENDOR_ID_INTEL;
> +    k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
> +    k->revision = 0x01;
> +    k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
> +}
> +
> +static DeviceInfo ac97_info = {
> +    .name = "AC97",
> +    .desc = "Intel 82801AA AC97 Audio",
> +    .size = sizeof (AC97LinkState),
> +    .vmsd = &vmstate_ac97,
> +    .props = ac97_properties,
> +    .class_init = ac97_class_init,
>  };
>  
>  static void ac97_register (void)

So I have a question on this: the whole reason
we moved class, vendor id etc away from device init
functions to a table was to make it possible
to perform queries, like list all available sound device
types, or sort devices based on type, based on these tables.

Another purpose was to remove the manually written description/name,
embedding pci id database in qemu instead, and performing
lookups based on device/vendor id.

We never got these patches but it sounds like a genuinely useful
functionality.

Is this no longer possible?

-- 
MST

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 03/28] pci: call reset unconditionally
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 03/28] pci: call reset unconditionally Anthony Liguori
@ 2012-01-25 12:42   ` Michael S. Tsirkin
  2012-01-25 13:28     ` Anthony Liguori
  0 siblings, 1 reply; 77+ messages in thread
From: Michael S. Tsirkin @ 2012-01-25 12:42 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On Tue, Jan 24, 2012 at 01:32:55PM -0600, Anthony Liguori wrote:
> Because now all PCI devices are converted to qdev.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

Finally!

> ---
>  hw/pci.c |    7 ++-----
>  1 files changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/pci.c b/hw/pci.c
> index 54400ac..ab3b53d 100644
> --- a/hw/pci.c
> +++ b/hw/pci.c
> @@ -159,11 +159,8 @@ void pci_device_deassert_intx(PCIDevice *dev)
>  void pci_device_reset(PCIDevice *dev)
>  {
>      int r;
> -    /* TODO: call the below unconditionally once all pci devices
> -     * are qdevified */
> -    if (dev->qdev.info) {
> -        qdev_reset_all(&dev->qdev);
> -    }
> +
> +    qdev_reset_all(&dev->qdev);
>  
>      dev->irq_state = 0;
>      pci_update_irq_status(dev);
> -- 
> 1.7.4.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-25  8:33                   ` Andreas Färber
  2012-01-25 12:09                     ` Avi Kivity
@ 2012-01-25 13:02                     ` Paul Brook
  2012-01-25 14:25                     ` Anthony Liguori
  2 siblings, 0 replies; 77+ messages in thread
From: Paul Brook @ 2012-01-25 13:02 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Michael S. Tsirkin, qemu-devel, Alexander Graf,
	Blue Swirl, Jan Kiszka, Gerd Hoffmann, qemu-ppc, Aurelien Jarno

> > There is a declarative solution for this that I know of, a C++ class
> > definition ;-)
> 
> So what's the reason not to go with one of the object-oriented,
> C-compatible languages GCC supports, like C++ or Objective-C/C++?
> (Objective-C has native reflection capabilities fwiw.)

I'd avoid Objective-C as it has very little use (and thus real 
support/testing) outside of Apple.  Even more so for Objective-C++.

I've no objection in principle to C++, though it does raise various practical 
issues.  I'm suspicious of a plan that only converts some of the codebase to 
C++.

Paul

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 03/28] pci: call reset unconditionally
  2012-01-25 12:42   ` Michael S. Tsirkin
@ 2012-01-25 13:28     ` Anthony Liguori
  0 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-25 13:28 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: qemu-devel

On 01/25/2012 06:42 AM, Michael S. Tsirkin wrote:
> On Tue, Jan 24, 2012 at 01:32:55PM -0600, Anthony Liguori wrote:
>> Because now all PCI devices are converted to qdev.
>>
>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>
> Finally!

Yeah, I hope there's more cleanup that can come out of this.

Regards,

Anthony Liguori

>
>> ---
>>   hw/pci.c |    7 ++-----
>>   1 files changed, 2 insertions(+), 5 deletions(-)
>>
>> diff --git a/hw/pci.c b/hw/pci.c
>> index 54400ac..ab3b53d 100644
>> --- a/hw/pci.c
>> +++ b/hw/pci.c
>> @@ -159,11 +159,8 @@ void pci_device_deassert_intx(PCIDevice *dev)
>>   void pci_device_reset(PCIDevice *dev)
>>   {
>>       int r;
>> -    /* TODO: call the below unconditionally once all pci devices
>> -     * are qdevified */
>> -    if (dev->qdev.info) {
>> -        qdev_reset_all(&dev->qdev);
>> -    }
>> +
>> +    qdev_reset_all(&dev->qdev);
>>
>>       dev->irq_state = 0;
>>       pci_update_irq_status(dev);
>> --
>> 1.7.4.1
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 26/28] pci: convert to QEMU Object Model
  2012-01-25 12:41     ` Michael S. Tsirkin
@ 2012-01-25 13:34       ` Anthony Liguori
  -1 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-25 13:34 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Kevin Wolf, Anthony Liguori, xen-devel, Stefano Stabellini,
	Alexander Graf, qemu-devel, Blue Swirl, Andreas Färber,
	qemu-ppc, Paul Brook, Gerd Hoffmann

On 01/25/2012 06:41 AM, Michael S. Tsirkin wrote:
> On Tue, Jan 24, 2012 at 01:33:18PM -0600, Anthony Liguori wrote:
>> diff --git a/hw/ac97.c b/hw/ac97.c
>> index 03be99b..33b85f5 100644
>> --- a/hw/ac97.c
>> +++ b/hw/ac97.c
>> @@ -1344,21 +1344,30 @@ int ac97_init (PCIBus *bus)
>>       return 0;
>>   }
>>
>> -static PCIDeviceInfo ac97_info = {
>> -    .qdev.name    = "AC97",
>> -    .qdev.desc    = "Intel 82801AA AC97 Audio",
>> -    .qdev.size    = sizeof (AC97LinkState),
>> -    .qdev.vmsd    =&vmstate_ac97,
>> -    .init         = ac97_initfn,
>> -    .exit         = ac97_exitfn,
>> -    .vendor_id    = PCI_VENDOR_ID_INTEL,
>> -    .device_id    = PCI_DEVICE_ID_INTEL_82801AA_5,
>> -    .revision     = 0x01,
>> -    .class_id     = PCI_CLASS_MULTIMEDIA_AUDIO,
>> -    .qdev.props   = (Property[]) {
>> -        DEFINE_PROP_UINT32("use_broken_id", AC97LinkState, use_broken_id, 0),
>> -        DEFINE_PROP_END_OF_LIST(),
>> -    }
>> +static Property ac97_properties[] = {
>> +    DEFINE_PROP_UINT32("use_broken_id", AC97LinkState, use_broken_id, 0),
>> +    DEFINE_PROP_END_OF_LIST(),
>> +};
>> +
>> +static void ac97_class_init(ObjectClass *klass, void *data)
>> +{
>> +    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>> +
>> +    k->init = ac97_initfn;
>> +    k->exit = ac97_exitfn;
>> +    k->vendor_id = PCI_VENDOR_ID_INTEL;
>> +    k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
>> +    k->revision = 0x01;
>> +    k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
>> +}
>> +
>> +static DeviceInfo ac97_info = {
>> +    .name = "AC97",
>> +    .desc = "Intel 82801AA AC97 Audio",
>> +    .size = sizeof (AC97LinkState),
>> +    .vmsd =&vmstate_ac97,
>> +    .props = ac97_properties,
>> +    .class_init = ac97_class_init,
>>   };
>>
>>   static void ac97_register (void)
>
> So I have a question on this: the whole reason
> we moved class, vendor id etc away from device init
> functions to a table was to make it possible
> to perform queries, like list all available sound device
> types, or sort devices based on type, based on these tables.
>
> Another purpose was to remove the manually written description/name,
> embedding pci id database in qemu instead, and performing
> lookups based on device/vendor id.
>
> We never got these patches but it sounds like a genuinely useful
> functionality.
>
> Is this no longer possible?

There is one class instance per type.  It's initialized lazily but the types are 
always known.  IOW, ac97_class_init() is called once on the global 
PCIDeviceClass object, most likely very early during init.

These class objects can be searched and interacted with independently of any 
existing object.  What you're after is:

static void show_pci_device(ObjectClass *klass, void *opaque)
{
     PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);

     printf("Device %s is %02x:%02x\n",
            object_class_get_name(klass), pc->vendor_id, pc->device_id);
}

{
     ...
     object_class_foreach(show_pci_device, TYPE_PCI_DEVICE, false, NULL);
}

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [PATCH 26/28] pci: convert to QEMU Object Model
@ 2012-01-25 13:34       ` Anthony Liguori
  0 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-25 13:34 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Kevin Wolf, Anthony Liguori, xen-devel, Stefano Stabellini,
	Alexander Graf, qemu-devel, Blue Swirl, Andreas Färber,
	qemu-ppc, Paul Brook, Gerd Hoffmann

On 01/25/2012 06:41 AM, Michael S. Tsirkin wrote:
> On Tue, Jan 24, 2012 at 01:33:18PM -0600, Anthony Liguori wrote:
>> diff --git a/hw/ac97.c b/hw/ac97.c
>> index 03be99b..33b85f5 100644
>> --- a/hw/ac97.c
>> +++ b/hw/ac97.c
>> @@ -1344,21 +1344,30 @@ int ac97_init (PCIBus *bus)
>>       return 0;
>>   }
>>
>> -static PCIDeviceInfo ac97_info = {
>> -    .qdev.name    = "AC97",
>> -    .qdev.desc    = "Intel 82801AA AC97 Audio",
>> -    .qdev.size    = sizeof (AC97LinkState),
>> -    .qdev.vmsd    =&vmstate_ac97,
>> -    .init         = ac97_initfn,
>> -    .exit         = ac97_exitfn,
>> -    .vendor_id    = PCI_VENDOR_ID_INTEL,
>> -    .device_id    = PCI_DEVICE_ID_INTEL_82801AA_5,
>> -    .revision     = 0x01,
>> -    .class_id     = PCI_CLASS_MULTIMEDIA_AUDIO,
>> -    .qdev.props   = (Property[]) {
>> -        DEFINE_PROP_UINT32("use_broken_id", AC97LinkState, use_broken_id, 0),
>> -        DEFINE_PROP_END_OF_LIST(),
>> -    }
>> +static Property ac97_properties[] = {
>> +    DEFINE_PROP_UINT32("use_broken_id", AC97LinkState, use_broken_id, 0),
>> +    DEFINE_PROP_END_OF_LIST(),
>> +};
>> +
>> +static void ac97_class_init(ObjectClass *klass, void *data)
>> +{
>> +    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>> +
>> +    k->init = ac97_initfn;
>> +    k->exit = ac97_exitfn;
>> +    k->vendor_id = PCI_VENDOR_ID_INTEL;
>> +    k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
>> +    k->revision = 0x01;
>> +    k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
>> +}
>> +
>> +static DeviceInfo ac97_info = {
>> +    .name = "AC97",
>> +    .desc = "Intel 82801AA AC97 Audio",
>> +    .size = sizeof (AC97LinkState),
>> +    .vmsd =&vmstate_ac97,
>> +    .props = ac97_properties,
>> +    .class_init = ac97_class_init,
>>   };
>>
>>   static void ac97_register (void)
>
> So I have a question on this: the whole reason
> we moved class, vendor id etc away from device init
> functions to a table was to make it possible
> to perform queries, like list all available sound device
> types, or sort devices based on type, based on these tables.
>
> Another purpose was to remove the manually written description/name,
> embedding pci id database in qemu instead, and performing
> lookups based on device/vendor id.
>
> We never got these patches but it sounds like a genuinely useful
> functionality.
>
> Is this no longer possible?

There is one class instance per type.  It's initialized lazily but the types are 
always known.  IOW, ac97_class_init() is called once on the global 
PCIDeviceClass object, most likely very early during init.

These class objects can be searched and interacted with independently of any 
existing object.  What you're after is:

static void show_pci_device(ObjectClass *klass, void *opaque)
{
     PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);

     printf("Device %s is %02x:%02x\n",
            object_class_get_name(klass), pc->vendor_id, pc->device_id);
}

{
     ...
     object_class_foreach(show_pci_device, TYPE_PCI_DEVICE, false, NULL);
}

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-25  8:37                   ` Jan Kiszka
  2012-01-25 10:15                     ` Paolo Bonzini
@ 2012-01-25 14:00                     ` Anthony Liguori
  2012-01-25 14:23                       ` Jan Kiszka
  1 sibling, 1 reply; 77+ messages in thread
From: Anthony Liguori @ 2012-01-25 14:00 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Peter Maydell, Michael S. Tsirkin, Alexander Graf, qemu-devel,
	Blue Swirl, Andreas Färber, qemu-ppc, Paul Brook,
	Aurelien Jarno, Gerd Hoffmann

On 01/25/2012 02:37 AM, Jan Kiszka wrote:
> On 2012-01-25 00:03, Anthony Liguori wrote:
>> They're exactly the same size (16 lines).  If you embed TypeInfo into
>> DeviceTypeInfo, and introduce a Device specific type registration
>> function, then you could do:
>>
>> static DeviceTypeInfo my_device_type_info = {
>>      .type.name = TYPE_MY_DEVICE,
>>      .type.parent = TYPE_PARENT_DEVICE,
>>      .reset = my_device_reset,
>
> And if you introduce some
>
> #define TYPE_UNIMPLEMENTED (void *)&dummy_variable

(void *) isn't compatible with integers or function pointers (at least not in a 
portable way).

You would need to use type specific unimplemented mechanisms.

>
> you can easily express
>
> [.field = NULL]         =>  use parent
>   .field = UNIMPLEMENTED =>  don't run any handler
>
>> };
>>
>> static void register_devices(void)
>> {
>>      device_type_register_static(&my_device_type_info);
>> }
>>
>> Which admittedly saves 6 lines, but also is a big step backwards IMHO.
>> Now you've got a lot of one-off functions which means you loose the
>> advantage of having everything work through the same infrastructure.
>
> Can't follow. Four lines
>
> [static inline] void device_type_register_static(DeviceTypeInfo *dt)
> {
>      type_register_static(&dt->type);
> }
>
> are neither ugly nor complex. Rather, this helps concentrating effort at
> _central_ places instead of decentralizing and duplicating lines like in
> your imperative approach. That's the whole point: keep the common case
> (derived classes) compact.

Send a patch.  The infrastructure available should be enough to do whatever you 
need to.

I'm not being dismissive, I've already spent a lot of time trying to make it 
work and have convinced myself that it isn't workable.

If you can show a mechanism that works, I don't mind scripting a mass 
conversion.  I'm also fairly confident that a workable solution is going to be 
better than what we have.

Regards,

Anthony Liguori

>
> Jan
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-25 14:00                     ` Anthony Liguori
@ 2012-01-25 14:23                       ` Jan Kiszka
  2012-01-25 14:40                         ` Anthony Liguori
  0 siblings, 1 reply; 77+ messages in thread
From: Jan Kiszka @ 2012-01-25 14:23 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Michael S. Tsirkin, Alexander Graf, qemu-devel,
	Blue Swirl, Andreas Färber, qemu-ppc, Paul Brook,
	Aurelien Jarno, Gerd Hoffmann

[-- Attachment #1: Type: text/plain, Size: 2526 bytes --]

On 2012-01-25 15:00, Anthony Liguori wrote:
> On 01/25/2012 02:37 AM, Jan Kiszka wrote:
>> On 2012-01-25 00:03, Anthony Liguori wrote:
>>> They're exactly the same size (16 lines).  If you embed TypeInfo into
>>> DeviceTypeInfo, and introduce a Device specific type registration
>>> function, then you could do:
>>>
>>> static DeviceTypeInfo my_device_type_info = {
>>>      .type.name = TYPE_MY_DEVICE,
>>>      .type.parent = TYPE_PARENT_DEVICE,
>>>      .reset = my_device_reset,
>>
>> And if you introduce some
>>
>> #define TYPE_UNIMPLEMENTED (void *)&dummy_variable
> 
> (void *) isn't compatible with integers or function pointers (at least
> not in a portable way).

The former is true, the latter not. However, if you use pointers in the
TypeInfo structs consistently (const int * etc.), this issue should be
solvable as well.

> 
> You would need to use type specific unimplemented mechanisms.
> 
>>
>> you can easily express
>>
>> [.field = NULL]         =>  use parent
>>   .field = UNIMPLEMENTED =>  don't run any handler
>>
>>> };
>>>
>>> static void register_devices(void)
>>> {
>>>      device_type_register_static(&my_device_type_info);
>>> }
>>>
>>> Which admittedly saves 6 lines, but also is a big step backwards IMHO.
>>> Now you've got a lot of one-off functions which means you loose the
>>> advantage of having everything work through the same infrastructure.
>>
>> Can't follow. Four lines
>>
>> [static inline] void device_type_register_static(DeviceTypeInfo *dt)
>> {
>>      type_register_static(&dt->type);
>> }
>>
>> are neither ugly nor complex. Rather, this helps concentrating effort at
>> _central_ places instead of decentralizing and duplicating lines like in
>> your imperative approach. That's the whole point: keep the common case
>> (derived classes) compact.
> 
> Send a patch.  The infrastructure available should be enough to do
> whatever you need to.
> 
> I'm not being dismissive, I've already spent a lot of time trying to
> make it work and have convinced myself that it isn't workable.
> 
> If you can show a mechanism that works, I don't mind scripting a mass
> conversion.  I'm also fairly confident that a workable solution is going
> to be better than what we have.

Well, I'm surely not happy having to go through all of the devices
again, even if scripted (scripts tend to neglect some coding style rules
e.g.). But if this change is in a hurry and my concern is the only one,
then let it be.

Jan


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-25  8:33                   ` Andreas Färber
  2012-01-25 12:09                     ` Avi Kivity
  2012-01-25 13:02                     ` Paul Brook
@ 2012-01-25 14:25                     ` Anthony Liguori
  2 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-25 14:25 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Michael S. Tsirkin, Alexander Graf, qemu-devel,
	Blue Swirl, Jan Kiszka, Paul Brook, qemu-ppc, Aurelien Jarno,
	Gerd Hoffmann

On 01/25/2012 02:33 AM, Andreas Färber wrote:
> Am 25.01.2012 00:03, schrieb Anthony Liguori:
>> On 01/24/2012 04:06 PM, Jan Kiszka wrote:
>>> On 2012-01-24 22:53, Anthony Liguori wrote:
>>>> But I don't like this.  The problem is that the declarative syntax we
>>>> have doesn't distinguish between "not-specified" and
>>>> "zero-initialized".
>>>
>>> That's surely solvable.
>>
>> Please try :-)
>>
>> I've spent a good chunk of time mulling this over and could not find an
>> acceptable solution.  I think the same is true for the GObject folks.
>>
>> There is a declarative solution for this that I know of, a C++ class
>> definition ;-)
>
> So what's the reason not to go with one of the object-oriented,
> C-compatible languages GCC supports, like C++ or Objective-C/C++?
> (Objective-C has native reflection capabilities fwiw.)

I actually prefer C++ but much in the same fashion that I prefer 8-space indenting.

I think it's objectively better, but not significantly better enough to warrant 
the disruption of introducing it.

C++ makes polymorphism easier and declaring classes a little nicer, but it 
doesn't help significantly with factories, properties, or introspection.

Polymorphism in C is mostly a one-time cost so once you have the infrastructure 
(object.c), it's not really that bad.

Regards,

Anthony Liguori

>
> Personally I disliked those trivial mini init functions in the initial
> 2/4 series, too, but I don't really mind an imperative approach either.
>
> Andreas

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-25 14:23                       ` Jan Kiszka
@ 2012-01-25 14:40                         ` Anthony Liguori
  2012-01-25 15:18                           ` Andreas Färber
  2012-01-25 15:34                           ` Eric Blake
  0 siblings, 2 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-25 14:40 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Peter Maydell, Michael S. Tsirkin, qemu-devel, Alexander Graf,
	Blue Swirl, Andreas Färber, qemu-ppc, Paul Brook,
	Aurelien Jarno, Gerd Hoffmann

On 01/25/2012 08:23 AM, Jan Kiszka wrote:
> On 2012-01-25 15:00, Anthony Liguori wrote:
>> On 01/25/2012 02:37 AM, Jan Kiszka wrote:
>>> On 2012-01-25 00:03, Anthony Liguori wrote:
>>>> They're exactly the same size (16 lines).  If you embed TypeInfo into
>>>> DeviceTypeInfo, and introduce a Device specific type registration
>>>> function, then you could do:
>>>>
>>>> static DeviceTypeInfo my_device_type_info = {
>>>>       .type.name = TYPE_MY_DEVICE,
>>>>       .type.parent = TYPE_PARENT_DEVICE,
>>>>       .reset = my_device_reset,
>>>
>>> And if you introduce some
>>>
>>> #define TYPE_UNIMPLEMENTED (void *)&dummy_variable
>>
>> (void *) isn't compatible with integers or function pointers (at least
>> not in a portable way).

I don't see how they can be compatible since on some platforms sizeof(void 
(*)(void)) != sizeof(void *).

>
> The former is true, the latter not. However, if you use pointers in the
> TypeInfo structs consistently (const int * etc.), this issue should be
> solvable as well.

How would you handle PCIDeviceInfo?

>> I'm not being dismissive, I've already spent a lot of time trying to
>> make it work and have convinced myself that it isn't workable.
>>
>> If you can show a mechanism that works, I don't mind scripting a mass
>> conversion.  I'm also fairly confident that a workable solution is going
>> to be better than what we have.
>
> Well, I'm surely not happy having to go through all of the devices
> again, even if scripted (scripts tend to neglect some coding style rules
> e.g.). But if this change is in a hurry and my concern is the only one,
> then let it be.

I wouldn't be happy with it either, but in the absence of a concrete counter 
proposal and given that I've spent a fair amount of time trying to figure this 
out, I strongly believe we won't need to make the change.

I'm happy to be proven wrong though.

Regards,

Anthony Liguori

>
> Jan
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-25 14:40                         ` Anthony Liguori
@ 2012-01-25 15:18                           ` Andreas Färber
  2012-01-25 15:34                           ` Eric Blake
  1 sibling, 0 replies; 77+ messages in thread
From: Andreas Färber @ 2012-01-25 15:18 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Michael S. Tsirkin, Alexander Graf, qemu-devel,
	Blue Swirl, Jan Kiszka, Paul Brook, qemu-ppc, Aurelien Jarno,
	Gerd Hoffmann

Am 25.01.2012 15:40, schrieb Anthony Liguori:
> On 01/25/2012 08:23 AM, Jan Kiszka wrote:
>> On 2012-01-25 15:00, Anthony Liguori wrote:
>>> On 01/25/2012 02:37 AM, Jan Kiszka wrote:
>>>> On 2012-01-25 00:03, Anthony Liguori wrote:
>>>>> They're exactly the same size (16 lines).  If you embed TypeInfo into
>>>>> DeviceTypeInfo, and introduce a Device specific type registration
>>>>> function, then you could do:
>>>>>
>>>>> static DeviceTypeInfo my_device_type_info = {
>>>>>       .type.name = TYPE_MY_DEVICE,
>>>>>       .type.parent = TYPE_PARENT_DEVICE,
>>>>>       .reset = my_device_reset,
>>>>
>>>> And if you introduce some
>>>>
>>>> #define TYPE_UNIMPLEMENTED (void *)&dummy_variable
>>>
>>> (void *) isn't compatible with integers or function pointers (at least
>>> not in a portable way).
> 
> I don't see how they can be compatible since on some platforms
> sizeof(void (*)(void)) != sizeof(void *).

Do you have an example of a platform relevant to QEMU?
Microcontrollers and DOS come to my mind.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model
  2012-01-25 14:40                         ` Anthony Liguori
  2012-01-25 15:18                           ` Andreas Färber
@ 2012-01-25 15:34                           ` Eric Blake
  1 sibling, 0 replies; 77+ messages in thread
From: Eric Blake @ 2012-01-25 15:34 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Michael S. Tsirkin, Alexander Graf, qemu-devel,
	Blue Swirl, Andreas Färber, Jan Kiszka, Paul Brook,
	qemu-ppc, Aurelien Jarno, Gerd Hoffmann

[-- Attachment #1: Type: text/plain, Size: 763 bytes --]

On 01/25/2012 07:40 AM, Anthony Liguori wrote:
>>>
>>> (void *) isn't compatible with integers or function pointers (at least
>>> not in a portable way).
> 
> I don't see how they can be compatible since on some platforms
> sizeof(void (*)(void)) != sizeof(void *).

C99 says they are not required to be the same, but POSIX adds an
additional requirement on top of C that all function pointers must be
convertible to void* and back without loss of data.  Pretty much any
system where qemu can compile is probably already complying with that
particular POSIX extension to C, even if it is not portable in practice
to a pure C environment.

-- 
Eric Blake   eblake@redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 620 bytes --]

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (28 preceding siblings ...)
  2012-01-24 23:13 ` [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Peter Maydell
@ 2012-01-25 18:31 ` Blue Swirl
  2012-01-25 19:43   ` Anthony Liguori
  2012-01-27 17:34 ` Anthony Liguori
  30 siblings, 1 reply; 77+ messages in thread
From: Blue Swirl @ 2012-01-25 18:31 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On Tue, Jan 24, 2012 at 19:32, Anthony Liguori <aliguori@us.ibm.com> wrote:
> This series makes qdev a proper Object and converts qdev's type inheritance to
> QOM inheritance.
>
> The first half of the series are manual cleanups/refactorings.  The second half
> is mostly scripted conversion, separated out into reviewable and bisectable
> chunks.
>
> I've tested this series extensively for the pc target including bisectability.
> I have not tested any other targets yet so your mileage may vary.
>
> Since the original RFC, I've fixed any of the not-for-upstream issues.  This
> also includes some uni-north patches that are in ppc-next.
>
> Paolo and Andreas have asked that I declare a date when I'll merge this so that
> people can be prepared for the rebase fall out.  I will merge this on Friday
> unless there is a major problem found in review.

I get this with Sparc64:
$ qemu-system-sparc64
qemu-system-sparc64: PCI: slot 0 function 0 not available for pbm, in use by
qemu-system-sparc64: Initialization of device pbm failed

Maybe because device "pbm" exists for both as SysBusDevice and as
PCIDevice. Text "in use by" is suspiciously clipped.

Sparc32, PPC32 and PPC64 seem to be OK.

> This is also available at:
>
> https://github.com/aliguori/qemu/tree/qom-upstream.10
>
> For full context, the whole tree is located at:
>
> https://github.com/aliguori/qemu/commits/qom-rebase.7
>
> git diffstat origin/master HEAD
>  Makefile                   |    2
>  Makefile.hw                |    1
>  Makefile.objs              |    3
>  Makefile.target            |    2
>  configure                  |    2
>  hw/9pfs/virtio-9p-device.c |   44 ++--
>  hw/a9mpcore.c              |   21 +
>  hw/ac97.c                  |   39 ++-
>  hw/acpi_piix4.c            |   59 +++--
>  hw/ads7846.c               |   17 +
>  hw/alpha_typhoon.c         |   17 +
>  hw/apb_pci.c               |   71 ++++--
>  hw/apic.c                  |   21 +
>  hw/apic_common.c           |   88 +++++---
>  hw/apic_internal.h         |   32 +-
>  hw/applesmc.c              |   18 +
>  hw/arm11mpcore.c           |   68 +++---
>  hw/arm_l2x0.c              |   25 +-
>  hw/arm_mptimer.c           |   23 +-
>  hw/arm_sysctl.c            |   31 +-
>  hw/arm_timer.c             |   46 +++-
>  hw/armv7m.c                |   25 +-
>  hw/armv7m_nvic.c           |   21 +
>  hw/bitbang_i2c.c           |   17 +
>  hw/bonito.c                |   47 ++--
>  hw/ccid-card-emulated.c    |   27 +-
>  hw/ccid-card-passthru.c    |   27 +-
>  hw/ccid.h                  |   28 +-
>  hw/cirrus_vga.c            |   50 ++--
>  hw/container.c             |   17 +
>  hw/cs4231.c                |   27 +-
>  hw/cs4231a.c               |   20 +
>  hw/debugcon.c              |   16 +
>  hw/dec_pci.c               |   74 ++++--
>  hw/ds1225y.c               |   29 +-
>  hw/ds1338.c                |   31 +-
>  hw/e1000.c                 |   45 ++--
>  hw/eccmemctl.c             |   29 +-
>  hw/eepro100.c              |  202 +++++++++++-------
>  hw/empty_slot.c            |   15 +
>  hw/es1370.c                |   36 +--
>  hw/escc.c                  |   43 ++-
>  hw/esp.c                   |   27 +-
>  hw/etraxfs_eth.c           |   33 +--
>  hw/etraxfs_pic.c           |   25 +-
>  hw/etraxfs_ser.c           |   17 +
>  hw/etraxfs_timer.c         |   16 +
>  hw/fdc.c                   |   84 +++++--
>  hw/fw_cfg.c                |   33 +--
>  hw/g364fb.c                |   33 +--
>  hw/grackle_pci.c           |   44 ++--
>  hw/grlib_apbuart.c         |   25 +-
>  hw/grlib_gptimer.c         |   31 +-
>  hw/grlib_irqmp.c           |   29 +-
>  hw/gt64xxx.c               |   39 ++-
>  hw/gus.c                   |   20 +
>  hw/hda-audio.c             |   60 +++--
>  hw/hpet.c                  |   33 +--
>  hw/i2c.c                   |  111 +++++++---
>  hw/i2c.h                   |   52 ++--
>  hw/i82374.c                |   19 +
>  hw/i82378.c                |   31 +-
>  hw/i8254.c                 |   22 +-
>  hw/i8259.c                 |   15 +
>  hw/i8259_common.c          |   45 ++--
>  hw/i8259_internal.h        |   27 +-
>  hw/ide/cmd646.c            |   41 ++-
>  hw/ide/ich.c               |   37 +--
>  hw/ide/internal.h          |   20 +
>  hw/ide/isa.c               |   20 +
>  hw/ide/piix.c              |   91 +++++---
>  hw/ide/qdev.c              |  111 ++++++----
>  hw/ide/via.c               |   27 +-
>  hw/integratorcp.c          |   40 ++-
>  hw/intel-hda.c             |   91 +++++---
>  hw/intel-hda.h             |   26 +-
>  hw/ioapic.c                |   17 +
>  hw/ioapic_common.c         |   49 +++-
>  hw/ioapic_internal.h       |   26 +-
>  hw/ioh3420.c               |   59 +++--
>  hw/isa-bus.c               |   57 +++--
>  hw/isa.h                   |   23 +-
>  hw/ivshmem.c               |   47 ++--
>  hw/kvm/apic.c              |   19 +
>  hw/kvm/clock.c             |   19 +
>  hw/kvm/i8259.c             |   19 +
>  hw/kvm/ioapic.c            |   23 +-
>  hw/lan9118.c               |   31 +-
>  hw/lance.c                 |   33 +--
>  hw/lm32_juart.c            |   19 +
>  hw/lm32_pic.c              |   19 +
>  hw/lm32_sys.c              |   29 +-
>  hw/lm32_timer.c            |   31 +-
>  hw/lm32_uart.c             |   19 +
>  hw/lm832x.c                |   33 +--
>  hw/lsi53c895a.c            |   33 +--
>  hw/m48t59.c                |   51 +++-
>  hw/macio.c                 |   50 +++-
>  hw/marvell_88w8618_audio.c |   35 +--
>  hw/max111x.c               |   34 ++-
>  hw/max7310.c               |   35 +--
>  hw/mc146818rtc.c           |   22 +-
>  hw/milkymist-ac97.c        |   19 +
>  hw/milkymist-hpdmc.c       |   19 +
>  hw/milkymist-memcard.c     |   19 +
>  hw/milkymist-minimac2.c    |   37 ++-
>  hw/milkymist-pfpu.c        |   19 +
>  hw/milkymist-softusb.c     |   43 ++-
>  hw/milkymist-sysctl.c      |   43 ++-
>  hw/milkymist-tmu2.c        |   19 +
>  hw/milkymist-uart.c        |   19 +
>  hw/milkymist-vgafb.c       |   31 +-
>  hw/mips_malta.c            |   19 +
>  hw/mipsnet.c               |   33 +--
>  hw/mpc8544_guts.c          |   15 +
>  hw/mst_fpga.c              |   19 +
>  hw/musicpal.c              |  153 ++++++++++----
>  hw/nand.c                  |   33 +--
>  hw/ne2000-isa.c            |   18 +
>  hw/ne2000.c                |   37 ++-
>  hw/omap_gpio.c             |   70 ++++--
>  hw/omap_intc.c             |   62 +++--
>  hw/onenand.c               |   35 ++-
>  hw/opencores_eth.c         |   31 +-
>  hw/openpic.c               |   30 --
>  hw/openpic.h               |    2
>  hw/parallel.c              |   16 +
>  hw/pc.c                    |   20 +
>  hw/pci.c                   |  140 +++++-------
>  hw/pci.h                   |   80 +++----
>  hw/pci_bridge.c            |    2
>  hw/pcie.c                  |    2
>  hw/pckbd.c                 |   18 +
>  hw/pcnet-pci.c             |   39 ++-
>  hw/pcnet.c                 |    2
>  hw/piix4.c                 |   35 +--
>  hw/piix_pci.c              |  126 +++++++----
>  hw/pl011.c                 |   36 ++-
>  hw/pl022.c                 |   15 +
>  hw/pl031.c                 |   19 +
>  hw/pl041.c                 |   34 +--
>  hw/pl050.c                 |   34 ++-
>  hw/pl061.c                 |   34 ++-
>  hw/pl080.c                 |   38 ++-
>  hw/pl110.c                 |   57 +++--
>  hw/pl181.c                 |   23 +-
>  hw/pl190.c                 |   21 +
>  hw/ppc4xx_pci.c            |   38 ++-
>  hw/ppc_newworld.c          |    2
>  hw/ppce500_pci.c           |   38 ++-
>  hw/ppce500_spin.c          |   15 +
>  hw/prep_pci.c              |   52 ++--
>  hw/pxa2xx.c                |   96 ++++++--
>  hw/pxa2xx_dma.c            |   29 +-
>  hw/pxa2xx_gpio.c           |   29 +-
>  hw/pxa2xx_pic.c            |   19 +
>  hw/pxa2xx_timer.c          |   66 +++---
>  hw/qdev-properties.c       |   20 -
>  hw/qdev.c                  |  123 ++++++++---
>  hw/qdev.h                  |   40 +++
>  hw/qxl.c                   |   66 +++---
>  hw/realview.c              |   15 +
>  hw/realview_gic.c          |   16 +
>  hw/rtl8139.c               |   43 ++-
>  hw/s390-virtio-bus.c       |  110 +++++++---
>  hw/sb16.c                  |   20 +
>  hw/sbi.c                   |   19 +
>  hw/scsi-bus.c              |   95 ++++++--
>  hw/scsi-disk.c             |  159 ++++++++------
>  hw/scsi-generic.c          |   29 +-
>  hw/scsi.h                  |   31 +-
>  hw/serial.c                |   18 +
>  hw/sga.c                   |   15 -
>  hw/sh_pci.c                |   37 ++-
>  hw/slavio_intctl.c         |   19 +
>  hw/slavio_misc.c           |   34 ++-
>  hw/slavio_timer.c          |   29 +-
>  hw/smbus.c                 |   85 +++++--
>  hw/smbus.h                 |   42 ++-
>  hw/smbus_eeprom.c          |   27 +-
>  hw/smc91c111.c             |   31 +-
>  hw/spapr_llan.c            |   41 ++-
>  hw/spapr_pci.c             |   31 ++
>  hw/spapr_vio.c             |   72 ++++--
>  hw/spapr_vio.h             |   35 ++-
>  hw/spapr_vscsi.c           |   37 ++-
>  hw/spapr_vty.c             |   37 ++-
>  hw/sparc32_dma.c           |   31 +-
>  hw/spitz.c                 |   94 +++++---
>  hw/ssd0303.c               |   33 +--
>  hw/ssd0323.c               |   17 +
>  hw/ssi-sd.c                |   17 +
>  hw/ssi.c                   |   23 +-
>  hw/ssi.h                   |   18 +
>  hw/stellaris.c             |   65 +++++-
>  hw/stellaris_enet.c        |   27 +-
>  hw/strongarm.c             |  124 +++++++----
>  hw/sun4c_intctl.c          |   19 +
>  hw/sun4m.c                 |   78 +++++--
>  hw/sun4m_iommu.c           |   29 +-
>  hw/sun4u.c                 |   71 ++++--
>  hw/sysbus.c                |   40 ++-
>  hw/sysbus.h                |   25 +-
>  hw/tcx.c                   |   37 ++-
>  hw/tmp105.c                |   37 ++-
>  hw/tosa.c                  |   50 ++--
>  hw/tusb6010.c              |   17 +
>  hw/twl92230.c              |   35 +--
>  hw/unin_pci.c              |  204 +++++++++++++-----
>  hw/usb-audio.c             |   38 ++-
>  hw/usb-bt.c                |   33 +--
>  hw/usb-bus.c               |  190 +++++++++++++----
>  hw/usb-ccid.c              |  114 +++++++---
>  hw/usb-desc.c              |   22 +-
>  hw/usb-ehci.c              |   63 +++--
>  hw/usb-hid.c               |  108 +++++-----
>  hw/usb-hub.c               |   35 +--
>  hw/usb-msd.c               |   41 ++-
>  hw/usb-net.c               |   43 ++-
>  hw/usb-ohci.c              |   58 +++--
>  hw/usb-serial.c            |   74 +++---
>  hw/usb-uhci.c              |  189 +++++++++++------
>  hw/usb-wacom.c             |   36 +--
>  hw/usb-xhci.c              |   37 ++-
>  hw/usb.c                   |   24 --
>  hw/usb.h                   |   50 +++-
>  hw/versatile_pci.c         |   53 +++-
>  hw/versatilepb.c           |   19 +
>  hw/vga-isa.c               |   18 +
>  hw/vga-pci.c               |   27 +-
>  hw/virtio-console.c        |   69 +++---
>  hw/virtio-net.c            |    2
>  hw/virtio-pci.c            |  210 +++++++++++--------
>  hw/virtio-serial-bus.c     |   68 +++---
>  hw/virtio-serial.h         |   81 ++++---
>  hw/vmmouse.c               |   22 +-
>  hw/vmport.c                |   16 +
>  hw/vmware_vga.c            |   34 +--
>  hw/vt82c686.c              |  120 ++++++-----
>  hw/wdt_i6300esb.c          |   33 +--
>  hw/wdt_ib700.c             |   18 +
>  hw/wm8750.c                |   37 ++-
>  hw/xen_platform.c          |   34 +--
>  hw/xilinx_axidma.c         |   27 +-
>  hw/xilinx_axienet.c        |   35 ++-
>  hw/xilinx_ethlite.c        |   31 +-
>  hw/xilinx_intc.c           |   25 +-
>  hw/xilinx_timer.c          |   27 +-
>  hw/xilinx_uartlite.c       |   16 +
>  hw/xio3130_downstream.c    |   59 +++--
>  hw/xio3130_upstream.c      |   53 ++--
>  hw/z2.c                    |   52 +++-
>  hw/zaurus.c                |   27 +-
>  include/qemu/object.h      |  436 ++++++++++++++++++++++++++++++++++++++++
>  qom/Makefile               |    1
>  qom/object.c               |  485 +++++++++++++++++++++++++++++++++++++++++++++
>  usb-bsd.c                  |   29 +-
>  usb-linux.c                |   37 +--
>  usb-redir.c                |   33 +--
>  259 files changed, 7764 insertions(+), 3755 deletions(-)
>
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev
  2012-01-25 18:31 ` Blue Swirl
@ 2012-01-25 19:43   ` Anthony Liguori
  2012-01-25 20:09     ` Blue Swirl
  0 siblings, 1 reply; 77+ messages in thread
From: Anthony Liguori @ 2012-01-25 19:43 UTC (permalink / raw)
  To: Blue Swirl; +Cc: qemu-devel, Alexander Graf

[-- Attachment #1: Type: text/plain, Size: 13245 bytes --]

On 01/25/2012 12:31 PM, Blue Swirl wrote:
> On Tue, Jan 24, 2012 at 19:32, Anthony Liguori<aliguori@us.ibm.com>  wrote:
>> This series makes qdev a proper Object and converts qdev's type inheritance to
>> QOM inheritance.
>>
>> The first half of the series are manual cleanups/refactorings.  The second half
>> is mostly scripted conversion, separated out into reviewable and bisectable
>> chunks.
>>
>> I've tested this series extensively for the pc target including bisectability.
>> I have not tested any other targets yet so your mileage may vary.
>>
>> Since the original RFC, I've fixed any of the not-for-upstream issues.  This
>> also includes some uni-north patches that are in ppc-next.
>>
>> Paolo and Andreas have asked that I declare a date when I'll merge this so that
>> people can be prepared for the rebase fall out.  I will merge this on Friday
>> unless there is a major problem found in review.
>
> I get this with Sparc64:
> $ qemu-system-sparc64
> qemu-system-sparc64: PCI: slot 0 function 0 not available for pbm, in use by\

The casts in qdev are not type safe (because they don't do RTTI).  You're 
probably getting the sysbus version of pbm but then casting to a PCI device 
which is resulting in a garbage name pointer.

As we switch to use the QOM dynamic casts, a similar situation would trigger an 
abort().

> qemu-system-sparc64: Initialization of device pbm failed
>
> Maybe because device "pbm" exists for both as SysBusDevice and as
> PCIDevice. Text "in use by" is suspiciously clipped.
>
> Sparc32, PPC32 and PPC64 seem to be OK.

This should address that and the other occurrences.

Regards,

Anthony Liguori

>
>> This is also available at:
>>
>> https://github.com/aliguori/qemu/tree/qom-upstream.10
>>
>> For full context, the whole tree is located at:
>>
>> https://github.com/aliguori/qemu/commits/qom-rebase.7
>>
>> git diffstat origin/master HEAD
>>   Makefile                   |    2
>>   Makefile.hw                |    1
>>   Makefile.objs              |    3
>>   Makefile.target            |    2
>>   configure                  |    2
>>   hw/9pfs/virtio-9p-device.c |   44 ++--
>>   hw/a9mpcore.c              |   21 +
>>   hw/ac97.c                  |   39 ++-
>>   hw/acpi_piix4.c            |   59 +++--
>>   hw/ads7846.c               |   17 +
>>   hw/alpha_typhoon.c         |   17 +
>>   hw/apb_pci.c               |   71 ++++--
>>   hw/apic.c                  |   21 +
>>   hw/apic_common.c           |   88 +++++---
>>   hw/apic_internal.h         |   32 +-
>>   hw/applesmc.c              |   18 +
>>   hw/arm11mpcore.c           |   68 +++---
>>   hw/arm_l2x0.c              |   25 +-
>>   hw/arm_mptimer.c           |   23 +-
>>   hw/arm_sysctl.c            |   31 +-
>>   hw/arm_timer.c             |   46 +++-
>>   hw/armv7m.c                |   25 +-
>>   hw/armv7m_nvic.c           |   21 +
>>   hw/bitbang_i2c.c           |   17 +
>>   hw/bonito.c                |   47 ++--
>>   hw/ccid-card-emulated.c    |   27 +-
>>   hw/ccid-card-passthru.c    |   27 +-
>>   hw/ccid.h                  |   28 +-
>>   hw/cirrus_vga.c            |   50 ++--
>>   hw/container.c             |   17 +
>>   hw/cs4231.c                |   27 +-
>>   hw/cs4231a.c               |   20 +
>>   hw/debugcon.c              |   16 +
>>   hw/dec_pci.c               |   74 ++++--
>>   hw/ds1225y.c               |   29 +-
>>   hw/ds1338.c                |   31 +-
>>   hw/e1000.c                 |   45 ++--
>>   hw/eccmemctl.c             |   29 +-
>>   hw/eepro100.c              |  202 +++++++++++-------
>>   hw/empty_slot.c            |   15 +
>>   hw/es1370.c                |   36 +--
>>   hw/escc.c                  |   43 ++-
>>   hw/esp.c                   |   27 +-
>>   hw/etraxfs_eth.c           |   33 +--
>>   hw/etraxfs_pic.c           |   25 +-
>>   hw/etraxfs_ser.c           |   17 +
>>   hw/etraxfs_timer.c         |   16 +
>>   hw/fdc.c                   |   84 +++++--
>>   hw/fw_cfg.c                |   33 +--
>>   hw/g364fb.c                |   33 +--
>>   hw/grackle_pci.c           |   44 ++--
>>   hw/grlib_apbuart.c         |   25 +-
>>   hw/grlib_gptimer.c         |   31 +-
>>   hw/grlib_irqmp.c           |   29 +-
>>   hw/gt64xxx.c               |   39 ++-
>>   hw/gus.c                   |   20 +
>>   hw/hda-audio.c             |   60 +++--
>>   hw/hpet.c                  |   33 +--
>>   hw/i2c.c                   |  111 +++++++---
>>   hw/i2c.h                   |   52 ++--
>>   hw/i82374.c                |   19 +
>>   hw/i82378.c                |   31 +-
>>   hw/i8254.c                 |   22 +-
>>   hw/i8259.c                 |   15 +
>>   hw/i8259_common.c          |   45 ++--
>>   hw/i8259_internal.h        |   27 +-
>>   hw/ide/cmd646.c            |   41 ++-
>>   hw/ide/ich.c               |   37 +--
>>   hw/ide/internal.h          |   20 +
>>   hw/ide/isa.c               |   20 +
>>   hw/ide/piix.c              |   91 +++++---
>>   hw/ide/qdev.c              |  111 ++++++----
>>   hw/ide/via.c               |   27 +-
>>   hw/integratorcp.c          |   40 ++-
>>   hw/intel-hda.c             |   91 +++++---
>>   hw/intel-hda.h             |   26 +-
>>   hw/ioapic.c                |   17 +
>>   hw/ioapic_common.c         |   49 +++-
>>   hw/ioapic_internal.h       |   26 +-
>>   hw/ioh3420.c               |   59 +++--
>>   hw/isa-bus.c               |   57 +++--
>>   hw/isa.h                   |   23 +-
>>   hw/ivshmem.c               |   47 ++--
>>   hw/kvm/apic.c              |   19 +
>>   hw/kvm/clock.c             |   19 +
>>   hw/kvm/i8259.c             |   19 +
>>   hw/kvm/ioapic.c            |   23 +-
>>   hw/lan9118.c               |   31 +-
>>   hw/lance.c                 |   33 +--
>>   hw/lm32_juart.c            |   19 +
>>   hw/lm32_pic.c              |   19 +
>>   hw/lm32_sys.c              |   29 +-
>>   hw/lm32_timer.c            |   31 +-
>>   hw/lm32_uart.c             |   19 +
>>   hw/lm832x.c                |   33 +--
>>   hw/lsi53c895a.c            |   33 +--
>>   hw/m48t59.c                |   51 +++-
>>   hw/macio.c                 |   50 +++-
>>   hw/marvell_88w8618_audio.c |   35 +--
>>   hw/max111x.c               |   34 ++-
>>   hw/max7310.c               |   35 +--
>>   hw/mc146818rtc.c           |   22 +-
>>   hw/milkymist-ac97.c        |   19 +
>>   hw/milkymist-hpdmc.c       |   19 +
>>   hw/milkymist-memcard.c     |   19 +
>>   hw/milkymist-minimac2.c    |   37 ++-
>>   hw/milkymist-pfpu.c        |   19 +
>>   hw/milkymist-softusb.c     |   43 ++-
>>   hw/milkymist-sysctl.c      |   43 ++-
>>   hw/milkymist-tmu2.c        |   19 +
>>   hw/milkymist-uart.c        |   19 +
>>   hw/milkymist-vgafb.c       |   31 +-
>>   hw/mips_malta.c            |   19 +
>>   hw/mipsnet.c               |   33 +--
>>   hw/mpc8544_guts.c          |   15 +
>>   hw/mst_fpga.c              |   19 +
>>   hw/musicpal.c              |  153 ++++++++++----
>>   hw/nand.c                  |   33 +--
>>   hw/ne2000-isa.c            |   18 +
>>   hw/ne2000.c                |   37 ++-
>>   hw/omap_gpio.c             |   70 ++++--
>>   hw/omap_intc.c             |   62 +++--
>>   hw/onenand.c               |   35 ++-
>>   hw/opencores_eth.c         |   31 +-
>>   hw/openpic.c               |   30 --
>>   hw/openpic.h               |    2
>>   hw/parallel.c              |   16 +
>>   hw/pc.c                    |   20 +
>>   hw/pci.c                   |  140 +++++-------
>>   hw/pci.h                   |   80 +++----
>>   hw/pci_bridge.c            |    2
>>   hw/pcie.c                  |    2
>>   hw/pckbd.c                 |   18 +
>>   hw/pcnet-pci.c             |   39 ++-
>>   hw/pcnet.c                 |    2
>>   hw/piix4.c                 |   35 +--
>>   hw/piix_pci.c              |  126 +++++++----
>>   hw/pl011.c                 |   36 ++-
>>   hw/pl022.c                 |   15 +
>>   hw/pl031.c                 |   19 +
>>   hw/pl041.c                 |   34 +--
>>   hw/pl050.c                 |   34 ++-
>>   hw/pl061.c                 |   34 ++-
>>   hw/pl080.c                 |   38 ++-
>>   hw/pl110.c                 |   57 +++--
>>   hw/pl181.c                 |   23 +-
>>   hw/pl190.c                 |   21 +
>>   hw/ppc4xx_pci.c            |   38 ++-
>>   hw/ppc_newworld.c          |    2
>>   hw/ppce500_pci.c           |   38 ++-
>>   hw/ppce500_spin.c          |   15 +
>>   hw/prep_pci.c              |   52 ++--
>>   hw/pxa2xx.c                |   96 ++++++--
>>   hw/pxa2xx_dma.c            |   29 +-
>>   hw/pxa2xx_gpio.c           |   29 +-
>>   hw/pxa2xx_pic.c            |   19 +
>>   hw/pxa2xx_timer.c          |   66 +++---
>>   hw/qdev-properties.c       |   20 -
>>   hw/qdev.c                  |  123 ++++++++---
>>   hw/qdev.h                  |   40 +++
>>   hw/qxl.c                   |   66 +++---
>>   hw/realview.c              |   15 +
>>   hw/realview_gic.c          |   16 +
>>   hw/rtl8139.c               |   43 ++-
>>   hw/s390-virtio-bus.c       |  110 +++++++---
>>   hw/sb16.c                  |   20 +
>>   hw/sbi.c                   |   19 +
>>   hw/scsi-bus.c              |   95 ++++++--
>>   hw/scsi-disk.c             |  159 ++++++++------
>>   hw/scsi-generic.c          |   29 +-
>>   hw/scsi.h                  |   31 +-
>>   hw/serial.c                |   18 +
>>   hw/sga.c                   |   15 -
>>   hw/sh_pci.c                |   37 ++-
>>   hw/slavio_intctl.c         |   19 +
>>   hw/slavio_misc.c           |   34 ++-
>>   hw/slavio_timer.c          |   29 +-
>>   hw/smbus.c                 |   85 +++++--
>>   hw/smbus.h                 |   42 ++-
>>   hw/smbus_eeprom.c          |   27 +-
>>   hw/smc91c111.c             |   31 +-
>>   hw/spapr_llan.c            |   41 ++-
>>   hw/spapr_pci.c             |   31 ++
>>   hw/spapr_vio.c             |   72 ++++--
>>   hw/spapr_vio.h             |   35 ++-
>>   hw/spapr_vscsi.c           |   37 ++-
>>   hw/spapr_vty.c             |   37 ++-
>>   hw/sparc32_dma.c           |   31 +-
>>   hw/spitz.c                 |   94 +++++---
>>   hw/ssd0303.c               |   33 +--
>>   hw/ssd0323.c               |   17 +
>>   hw/ssi-sd.c                |   17 +
>>   hw/ssi.c                   |   23 +-
>>   hw/ssi.h                   |   18 +
>>   hw/stellaris.c             |   65 +++++-
>>   hw/stellaris_enet.c        |   27 +-
>>   hw/strongarm.c             |  124 +++++++----
>>   hw/sun4c_intctl.c          |   19 +
>>   hw/sun4m.c                 |   78 +++++--
>>   hw/sun4m_iommu.c           |   29 +-
>>   hw/sun4u.c                 |   71 ++++--
>>   hw/sysbus.c                |   40 ++-
>>   hw/sysbus.h                |   25 +-
>>   hw/tcx.c                   |   37 ++-
>>   hw/tmp105.c                |   37 ++-
>>   hw/tosa.c                  |   50 ++--
>>   hw/tusb6010.c              |   17 +
>>   hw/twl92230.c              |   35 +--
>>   hw/unin_pci.c              |  204 +++++++++++++-----
>>   hw/usb-audio.c             |   38 ++-
>>   hw/usb-bt.c                |   33 +--
>>   hw/usb-bus.c               |  190 +++++++++++++----
>>   hw/usb-ccid.c              |  114 +++++++---
>>   hw/usb-desc.c              |   22 +-
>>   hw/usb-ehci.c              |   63 +++--
>>   hw/usb-hid.c               |  108 +++++-----
>>   hw/usb-hub.c               |   35 +--
>>   hw/usb-msd.c               |   41 ++-
>>   hw/usb-net.c               |   43 ++-
>>   hw/usb-ohci.c              |   58 +++--
>>   hw/usb-serial.c            |   74 +++---
>>   hw/usb-uhci.c              |  189 +++++++++++------
>>   hw/usb-wacom.c             |   36 +--
>>   hw/usb-xhci.c              |   37 ++-
>>   hw/usb.c                   |   24 --
>>   hw/usb.h                   |   50 +++-
>>   hw/versatile_pci.c         |   53 +++-
>>   hw/versatilepb.c           |   19 +
>>   hw/vga-isa.c               |   18 +
>>   hw/vga-pci.c               |   27 +-
>>   hw/virtio-console.c        |   69 +++---
>>   hw/virtio-net.c            |    2
>>   hw/virtio-pci.c            |  210 +++++++++++--------
>>   hw/virtio-serial-bus.c     |   68 +++---
>>   hw/virtio-serial.h         |   81 ++++---
>>   hw/vmmouse.c               |   22 +-
>>   hw/vmport.c                |   16 +
>>   hw/vmware_vga.c            |   34 +--
>>   hw/vt82c686.c              |  120 ++++++-----
>>   hw/wdt_i6300esb.c          |   33 +--
>>   hw/wdt_ib700.c             |   18 +
>>   hw/wm8750.c                |   37 ++-
>>   hw/xen_platform.c          |   34 +--
>>   hw/xilinx_axidma.c         |   27 +-
>>   hw/xilinx_axienet.c        |   35 ++-
>>   hw/xilinx_ethlite.c        |   31 +-
>>   hw/xilinx_intc.c           |   25 +-
>>   hw/xilinx_timer.c          |   27 +-
>>   hw/xilinx_uartlite.c       |   16 +
>>   hw/xio3130_downstream.c    |   59 +++--
>>   hw/xio3130_upstream.c      |   53 ++--
>>   hw/z2.c                    |   52 +++-
>>   hw/zaurus.c                |   27 +-
>>   include/qemu/object.h      |  436 ++++++++++++++++++++++++++++++++++++++++
>>   qom/Makefile               |    1
>>   qom/object.c               |  485 +++++++++++++++++++++++++++++++++++++++++++++
>>   usb-bsd.c                  |   29 +-
>>   usb-linux.c                |   37 +--
>>   usb-redir.c                |   33 +--
>>   259 files changed, 7764 insertions(+), 3755 deletions(-)
>>
>>


[-- Attachment #2: 0001-qdev-change-ambiguous-qdev-names.patch --]
[-- Type: text/x-patch, Size: 2459 bytes --]

>From 196d73de2cc0687b9d5b159d9421ae85c8deff68 Mon Sep 17 00:00:00 2001
From: Anthony Liguori <aliguori@us.ibm.com>
Date: Wed, 25 Jan 2012 13:37:36 -0600
Subject: [PATCH] qdev: change ambiguous qdev names

Reported-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/apb_pci.c   |    4 ++--
 hw/dec_pci.c   |    2 +-
 hw/spapr_pci.c |    2 +-
 qom/object.c   |    5 +++++
 4 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 173dab3..1a45420 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -350,7 +350,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
         sysbus_connect_irq(s, i, pic[i]);
     }
 
-    pci_create_simple(d->bus, 0, "pbm");
+    pci_create_simple(d->bus, 0, "pbm-pci");
 
     /* APB secondary busses */
     pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 0), true,
@@ -448,7 +448,7 @@ static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
 }
 
 static DeviceInfo pbm_pci_host_info = {
-    .name = "pbm",
+    .name = "pbm-pci",
     .size = sizeof(PCIDevice),
     .class_init = pbm_pci_host_class_init,
 };
diff --git a/hw/dec_pci.c b/hw/dec_pci.c
index f0ecaff..333bad9 100644
--- a/hw/dec_pci.c
+++ b/hw/dec_pci.c
@@ -131,7 +131,7 @@ static void pci_dec_21154_device_class_init(ObjectClass *klass, void *data)
 }
 
 static DeviceInfo pci_dec_21154_device_info = {
-    .name = "dec-21154",
+    .name = "dec-21154-sysbus",
     .size = sizeof(DECState),
     .class_init = pci_dec_21154_device_class_init,
 };
diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c
index b6ac0d4..2a82eae 100644
--- a/hw/spapr_pci.c
+++ b/hw/spapr_pci.c
@@ -222,7 +222,7 @@ static void spapr_main_pci_host_class_init(ObjectClass *klass, void *data)
 }
 
 static DeviceInfo spapr_main_pci_host_info = {
-    .name = "spapr-pci-host-bridge",
+    .name = "spapr-pci-host-bridge-pci",
     .size = sizeof(PCIDevice),
     .class_init = spapr_main_pci_host_class_init,
 };
diff --git a/qom/object.c b/qom/object.c
index ef37e08..a12895f 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -87,6 +87,11 @@ TypeImpl *type_register(const TypeInfo *info)
 
     g_assert(info->name != NULL);
 
+    if (type_table_lookup(info->name) != NULL) {
+        fprintf(stderr, "Registering `%s' which already exists\n", info->name);
+        abort();
+    }
+
     ti->name = g_strdup(info->name);
     ti->parent = g_strdup(info->parent);
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev
  2012-01-25 19:43   ` Anthony Liguori
@ 2012-01-25 20:09     ` Blue Swirl
  0 siblings, 0 replies; 77+ messages in thread
From: Blue Swirl @ 2012-01-25 20:09 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, Alexander Graf

On Wed, Jan 25, 2012 at 19:43, Anthony Liguori <aliguori@us.ibm.com> wrote:
> On 01/25/2012 12:31 PM, Blue Swirl wrote:
>>
>> On Tue, Jan 24, 2012 at 19:32, Anthony Liguori<aliguori@us.ibm.com>
>>  wrote:
>>>
>>> This series makes qdev a proper Object and converts qdev's type
>>> inheritance to
>>> QOM inheritance.
>>>
>>> The first half of the series are manual cleanups/refactorings.  The
>>> second half
>>> is mostly scripted conversion, separated out into reviewable and
>>> bisectable
>>> chunks.
>>>
>>> I've tested this series extensively for the pc target including
>>> bisectability.
>>> I have not tested any other targets yet so your mileage may vary.
>>>
>>> Since the original RFC, I've fixed any of the not-for-upstream issues.
>>>  This
>>> also includes some uni-north patches that are in ppc-next.
>>>
>>> Paolo and Andreas have asked that I declare a date when I'll merge this
>>> so that
>>> people can be prepared for the rebase fall out.  I will merge this on
>>> Friday
>>> unless there is a major problem found in review.
>>
>>
>> I get this with Sparc64:
>> $ qemu-system-sparc64
>> qemu-system-sparc64: PCI: slot 0 function 0 not available for pbm, in use
>> by\
>
>
> The casts in qdev are not type safe (because they don't do RTTI).  You're
> probably getting the sysbus version of pbm but then casting to a PCI device
> which is resulting in a garbage name pointer.
>
> As we switch to use the QOM dynamic casts, a similar situation would trigger
> an abort().
>
>
>> qemu-system-sparc64: Initialization of device pbm failed
>>
>> Maybe because device "pbm" exists for both as SysBusDevice and as
>> PCIDevice. Text "in use by" is suspiciously clipped.
>>
>> Sparc32, PPC32 and PPC64 seem to be OK.
>
>
> This should address that and the other occurrences.

Yes, it fixes the problem.

> Regards,
>
> Anthony Liguori
>
>
>>
>>> This is also available at:
>>>
>>> https://github.com/aliguori/qemu/tree/qom-upstream.10
>>>
>>> For full context, the whole tree is located at:
>>>
>>> https://github.com/aliguori/qemu/commits/qom-rebase.7
>>>
>>> git diffstat origin/master HEAD
>>>  Makefile                   |    2
>>>  Makefile.hw                |    1
>>>  Makefile.objs              |    3
>>>  Makefile.target            |    2
>>>  configure                  |    2
>>>  hw/9pfs/virtio-9p-device.c |   44 ++--
>>>  hw/a9mpcore.c              |   21 +
>>>  hw/ac97.c                  |   39 ++-
>>>  hw/acpi_piix4.c            |   59 +++--
>>>  hw/ads7846.c               |   17 +
>>>  hw/alpha_typhoon.c         |   17 +
>>>  hw/apb_pci.c               |   71 ++++--
>>>  hw/apic.c                  |   21 +
>>>  hw/apic_common.c           |   88 +++++---
>>>  hw/apic_internal.h         |   32 +-
>>>  hw/applesmc.c              |   18 +
>>>  hw/arm11mpcore.c           |   68 +++---
>>>  hw/arm_l2x0.c              |   25 +-
>>>  hw/arm_mptimer.c           |   23 +-
>>>  hw/arm_sysctl.c            |   31 +-
>>>  hw/arm_timer.c             |   46 +++-
>>>  hw/armv7m.c                |   25 +-
>>>  hw/armv7m_nvic.c           |   21 +
>>>  hw/bitbang_i2c.c           |   17 +
>>>  hw/bonito.c                |   47 ++--
>>>  hw/ccid-card-emulated.c    |   27 +-
>>>  hw/ccid-card-passthru.c    |   27 +-
>>>  hw/ccid.h                  |   28 +-
>>>  hw/cirrus_vga.c            |   50 ++--
>>>  hw/container.c             |   17 +
>>>  hw/cs4231.c                |   27 +-
>>>  hw/cs4231a.c               |   20 +
>>>  hw/debugcon.c              |   16 +
>>>  hw/dec_pci.c               |   74 ++++--
>>>  hw/ds1225y.c               |   29 +-
>>>  hw/ds1338.c                |   31 +-
>>>  hw/e1000.c                 |   45 ++--
>>>  hw/eccmemctl.c             |   29 +-
>>>  hw/eepro100.c              |  202 +++++++++++-------
>>>  hw/empty_slot.c            |   15 +
>>>  hw/es1370.c                |   36 +--
>>>  hw/escc.c                  |   43 ++-
>>>  hw/esp.c                   |   27 +-
>>>  hw/etraxfs_eth.c           |   33 +--
>>>  hw/etraxfs_pic.c           |   25 +-
>>>  hw/etraxfs_ser.c           |   17 +
>>>  hw/etraxfs_timer.c         |   16 +
>>>  hw/fdc.c                   |   84 +++++--
>>>  hw/fw_cfg.c                |   33 +--
>>>  hw/g364fb.c                |   33 +--
>>>  hw/grackle_pci.c           |   44 ++--
>>>  hw/grlib_apbuart.c         |   25 +-
>>>  hw/grlib_gptimer.c         |   31 +-
>>>  hw/grlib_irqmp.c           |   29 +-
>>>  hw/gt64xxx.c               |   39 ++-
>>>  hw/gus.c                   |   20 +
>>>  hw/hda-audio.c             |   60 +++--
>>>  hw/hpet.c                  |   33 +--
>>>  hw/i2c.c                   |  111 +++++++---
>>>  hw/i2c.h                   |   52 ++--
>>>  hw/i82374.c                |   19 +
>>>  hw/i82378.c                |   31 +-
>>>  hw/i8254.c                 |   22 +-
>>>  hw/i8259.c                 |   15 +
>>>  hw/i8259_common.c          |   45 ++--
>>>  hw/i8259_internal.h        |   27 +-
>>>  hw/ide/cmd646.c            |   41 ++-
>>>  hw/ide/ich.c               |   37 +--
>>>  hw/ide/internal.h          |   20 +
>>>  hw/ide/isa.c               |   20 +
>>>  hw/ide/piix.c              |   91 +++++---
>>>  hw/ide/qdev.c              |  111 ++++++----
>>>  hw/ide/via.c               |   27 +-
>>>  hw/integratorcp.c          |   40 ++-
>>>  hw/intel-hda.c             |   91 +++++---
>>>  hw/intel-hda.h             |   26 +-
>>>  hw/ioapic.c                |   17 +
>>>  hw/ioapic_common.c         |   49 +++-
>>>  hw/ioapic_internal.h       |   26 +-
>>>  hw/ioh3420.c               |   59 +++--
>>>  hw/isa-bus.c               |   57 +++--
>>>  hw/isa.h                   |   23 +-
>>>  hw/ivshmem.c               |   47 ++--
>>>  hw/kvm/apic.c              |   19 +
>>>  hw/kvm/clock.c             |   19 +
>>>  hw/kvm/i8259.c             |   19 +
>>>  hw/kvm/ioapic.c            |   23 +-
>>>  hw/lan9118.c               |   31 +-
>>>  hw/lance.c                 |   33 +--
>>>  hw/lm32_juart.c            |   19 +
>>>  hw/lm32_pic.c              |   19 +
>>>  hw/lm32_sys.c              |   29 +-
>>>  hw/lm32_timer.c            |   31 +-
>>>  hw/lm32_uart.c             |   19 +
>>>  hw/lm832x.c                |   33 +--
>>>  hw/lsi53c895a.c            |   33 +--
>>>  hw/m48t59.c                |   51 +++-
>>>  hw/macio.c                 |   50 +++-
>>>  hw/marvell_88w8618_audio.c |   35 +--
>>>  hw/max111x.c               |   34 ++-
>>>  hw/max7310.c               |   35 +--
>>>  hw/mc146818rtc.c           |   22 +-
>>>  hw/milkymist-ac97.c        |   19 +
>>>  hw/milkymist-hpdmc.c       |   19 +
>>>  hw/milkymist-memcard.c     |   19 +
>>>  hw/milkymist-minimac2.c    |   37 ++-
>>>  hw/milkymist-pfpu.c        |   19 +
>>>  hw/milkymist-softusb.c     |   43 ++-
>>>  hw/milkymist-sysctl.c      |   43 ++-
>>>  hw/milkymist-tmu2.c        |   19 +
>>>  hw/milkymist-uart.c        |   19 +
>>>  hw/milkymist-vgafb.c       |   31 +-
>>>  hw/mips_malta.c            |   19 +
>>>  hw/mipsnet.c               |   33 +--
>>>  hw/mpc8544_guts.c          |   15 +
>>>  hw/mst_fpga.c              |   19 +
>>>  hw/musicpal.c              |  153 ++++++++++----
>>>  hw/nand.c                  |   33 +--
>>>  hw/ne2000-isa.c            |   18 +
>>>  hw/ne2000.c                |   37 ++-
>>>  hw/omap_gpio.c             |   70 ++++--
>>>  hw/omap_intc.c             |   62 +++--
>>>  hw/onenand.c               |   35 ++-
>>>  hw/opencores_eth.c         |   31 +-
>>>  hw/openpic.c               |   30 --
>>>  hw/openpic.h               |    2
>>>  hw/parallel.c              |   16 +
>>>  hw/pc.c                    |   20 +
>>>  hw/pci.c                   |  140 +++++-------
>>>  hw/pci.h                   |   80 +++----
>>>  hw/pci_bridge.c            |    2
>>>  hw/pcie.c                  |    2
>>>  hw/pckbd.c                 |   18 +
>>>  hw/pcnet-pci.c             |   39 ++-
>>>  hw/pcnet.c                 |    2
>>>  hw/piix4.c                 |   35 +--
>>>  hw/piix_pci.c              |  126 +++++++----
>>>  hw/pl011.c                 |   36 ++-
>>>  hw/pl022.c                 |   15 +
>>>  hw/pl031.c                 |   19 +
>>>  hw/pl041.c                 |   34 +--
>>>  hw/pl050.c                 |   34 ++-
>>>  hw/pl061.c                 |   34 ++-
>>>  hw/pl080.c                 |   38 ++-
>>>  hw/pl110.c                 |   57 +++--
>>>  hw/pl181.c                 |   23 +-
>>>  hw/pl190.c                 |   21 +
>>>  hw/ppc4xx_pci.c            |   38 ++-
>>>  hw/ppc_newworld.c          |    2
>>>  hw/ppce500_pci.c           |   38 ++-
>>>  hw/ppce500_spin.c          |   15 +
>>>  hw/prep_pci.c              |   52 ++--
>>>  hw/pxa2xx.c                |   96 ++++++--
>>>  hw/pxa2xx_dma.c            |   29 +-
>>>  hw/pxa2xx_gpio.c           |   29 +-
>>>  hw/pxa2xx_pic.c            |   19 +
>>>  hw/pxa2xx_timer.c          |   66 +++---
>>>  hw/qdev-properties.c       |   20 -
>>>  hw/qdev.c                  |  123 ++++++++---
>>>  hw/qdev.h                  |   40 +++
>>>  hw/qxl.c                   |   66 +++---
>>>  hw/realview.c              |   15 +
>>>  hw/realview_gic.c          |   16 +
>>>  hw/rtl8139.c               |   43 ++-
>>>  hw/s390-virtio-bus.c       |  110 +++++++---
>>>  hw/sb16.c                  |   20 +
>>>  hw/sbi.c                   |   19 +
>>>  hw/scsi-bus.c              |   95 ++++++--
>>>  hw/scsi-disk.c             |  159 ++++++++------
>>>  hw/scsi-generic.c          |   29 +-
>>>  hw/scsi.h                  |   31 +-
>>>  hw/serial.c                |   18 +
>>>  hw/sga.c                   |   15 -
>>>  hw/sh_pci.c                |   37 ++-
>>>  hw/slavio_intctl.c         |   19 +
>>>  hw/slavio_misc.c           |   34 ++-
>>>  hw/slavio_timer.c          |   29 +-
>>>  hw/smbus.c                 |   85 +++++--
>>>  hw/smbus.h                 |   42 ++-
>>>  hw/smbus_eeprom.c          |   27 +-
>>>  hw/smc91c111.c             |   31 +-
>>>  hw/spapr_llan.c            |   41 ++-
>>>  hw/spapr_pci.c             |   31 ++
>>>  hw/spapr_vio.c             |   72 ++++--
>>>  hw/spapr_vio.h             |   35 ++-
>>>  hw/spapr_vscsi.c           |   37 ++-
>>>  hw/spapr_vty.c             |   37 ++-
>>>  hw/sparc32_dma.c           |   31 +-
>>>  hw/spitz.c                 |   94 +++++---
>>>  hw/ssd0303.c               |   33 +--
>>>  hw/ssd0323.c               |   17 +
>>>  hw/ssi-sd.c                |   17 +
>>>  hw/ssi.c                   |   23 +-
>>>  hw/ssi.h                   |   18 +
>>>  hw/stellaris.c             |   65 +++++-
>>>  hw/stellaris_enet.c        |   27 +-
>>>  hw/strongarm.c             |  124 +++++++----
>>>  hw/sun4c_intctl.c          |   19 +
>>>  hw/sun4m.c                 |   78 +++++--
>>>  hw/sun4m_iommu.c           |   29 +-
>>>  hw/sun4u.c                 |   71 ++++--
>>>  hw/sysbus.c                |   40 ++-
>>>  hw/sysbus.h                |   25 +-
>>>  hw/tcx.c                   |   37 ++-
>>>  hw/tmp105.c                |   37 ++-
>>>  hw/tosa.c                  |   50 ++--
>>>  hw/tusb6010.c              |   17 +
>>>  hw/twl92230.c              |   35 +--
>>>  hw/unin_pci.c              |  204 +++++++++++++-----
>>>  hw/usb-audio.c             |   38 ++-
>>>  hw/usb-bt.c                |   33 +--
>>>  hw/usb-bus.c               |  190 +++++++++++++----
>>>  hw/usb-ccid.c              |  114 +++++++---
>>>  hw/usb-desc.c              |   22 +-
>>>  hw/usb-ehci.c              |   63 +++--
>>>  hw/usb-hid.c               |  108 +++++-----
>>>  hw/usb-hub.c               |   35 +--
>>>  hw/usb-msd.c               |   41 ++-
>>>  hw/usb-net.c               |   43 ++-
>>>  hw/usb-ohci.c              |   58 +++--
>>>  hw/usb-serial.c            |   74 +++---
>>>  hw/usb-uhci.c              |  189 +++++++++++------
>>>  hw/usb-wacom.c             |   36 +--
>>>  hw/usb-xhci.c              |   37 ++-
>>>  hw/usb.c                   |   24 --
>>>  hw/usb.h                   |   50 +++-
>>>  hw/versatile_pci.c         |   53 +++-
>>>  hw/versatilepb.c           |   19 +
>>>  hw/vga-isa.c               |   18 +
>>>  hw/vga-pci.c               |   27 +-
>>>  hw/virtio-console.c        |   69 +++---
>>>  hw/virtio-net.c            |    2
>>>  hw/virtio-pci.c            |  210 +++++++++++--------
>>>  hw/virtio-serial-bus.c     |   68 +++---
>>>  hw/virtio-serial.h         |   81 ++++---
>>>  hw/vmmouse.c               |   22 +-
>>>  hw/vmport.c                |   16 +
>>>  hw/vmware_vga.c            |   34 +--
>>>  hw/vt82c686.c              |  120 ++++++-----
>>>  hw/wdt_i6300esb.c          |   33 +--
>>>  hw/wdt_ib700.c             |   18 +
>>>  hw/wm8750.c                |   37 ++-
>>>  hw/xen_platform.c          |   34 +--
>>>  hw/xilinx_axidma.c         |   27 +-
>>>  hw/xilinx_axienet.c        |   35 ++-
>>>  hw/xilinx_ethlite.c        |   31 +-
>>>  hw/xilinx_intc.c           |   25 +-
>>>  hw/xilinx_timer.c          |   27 +-
>>>  hw/xilinx_uartlite.c       |   16 +
>>>  hw/xio3130_downstream.c    |   59 +++--
>>>  hw/xio3130_upstream.c      |   53 ++--
>>>  hw/z2.c                    |   52 +++-
>>>  hw/zaurus.c                |   27 +-
>>>  include/qemu/object.h      |  436
>>> ++++++++++++++++++++++++++++++++++++++++
>>>  qom/Makefile               |    1
>>>  qom/object.c               |  485
>>> +++++++++++++++++++++++++++++++++++++++++++++
>>>  usb-bsd.c                  |   29 +-
>>>  usb-linux.c                |   37 +--
>>>  usb-redir.c                |   33 +--
>>>  259 files changed, 7764 insertions(+), 3755 deletions(-)
>>>
>>>
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 04/28] qom: add the base Object class (v2)
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 04/28] qom: add the base Object class (v2) Anthony Liguori
@ 2012-01-25 21:30   ` Andreas Färber
  2012-01-25 21:37     ` Anthony Liguori
  0 siblings, 1 reply; 77+ messages in thread
From: Andreas Färber @ 2012-01-25 21:30 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

Am 24.01.2012 20:32, schrieb Anthony Liguori:
> This class provides the main building block for QEMU Object Model and is
> extensively documented in the header file.  It is largely inspired by GObject.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
> v1 -> v2
>  - remove printf() in type registration
>  - fix typo in comment (Paolo)
>  - make Interface private
>  - move object into a new directory and move header into include/qemu/

Some of us had expressed concerns over introducing include/. Any
particular reason you're doing it still?

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 04/28] qom: add the base Object class (v2)
  2012-01-25 21:30   ` Andreas Färber
@ 2012-01-25 21:37     ` Anthony Liguori
  2012-01-26  7:43       ` Paolo Bonzini
  2012-01-27 15:05       ` Andreas Färber
  0 siblings, 2 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-25 21:37 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 01/25/2012 03:30 PM, Andreas Färber wrote:
> Am 24.01.2012 20:32, schrieb Anthony Liguori:
>> This class provides the main building block for QEMU Object Model and is
>> extensively documented in the header file.  It is largely inspired by GObject.
>>
>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>> ---
>> v1 ->  v2
>>   - remove printf() in type registration
>>   - fix typo in comment (Paolo)
>>   - make Interface private
>>   - move object into a new directory and move header into include/qemu/
>
> Some of us had expressed concerns over introducing include/. Any
> particular reason you're doing it still?

Because it's a great idea and I thought everyone loved it?

Can you point me to the concerns raised, I'll go back and look.  I didn't think 
it was contentious...

To summarize my rationale for it:

  1) It avoids all of the non-sense with conflicting system headers (because we 
-Iinclude and the headers live in include/qemu)

  2) It establishes what are public functions for use in other parts of qemu vs. 
private headers (which we currently use based on ad-hoc naming schemes like 
block_int.h).

  3) I think the kernel serves as an existence proof that this method to manage 
headers works really well in practice.

Regards,

Anthony Liguori

>
> Andreas
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 04/28] qom: add the base Object class (v2)
  2012-01-25 21:37     ` Anthony Liguori
@ 2012-01-26  7:43       ` Paolo Bonzini
  2012-01-27 15:05       ` Andreas Färber
  1 sibling, 0 replies; 77+ messages in thread
From: Paolo Bonzini @ 2012-01-26  7:43 UTC (permalink / raw)
  To: qemu-devel

On 01/25/2012 10:37 PM, Anthony Liguori wrote:
> On 01/25/2012 03:30 PM, Andreas Färber wrote:
>> Am 24.01.2012 20:32, schrieb Anthony Liguori:
>>> This class provides the main building block for QEMU Object Model and is
>>> extensively documented in the header file. It is largely inspired by
>>> GObject.
>>>
>>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>>> ---
>>> v1 -> v2
>>> - remove printf() in type registration
>>> - fix typo in comment (Paolo)
>>> - make Interface private
>>> - move object into a new directory and move header into include/qemu/
>>
>> Some of us had expressed concerns over introducing include/. Any
>> particular reason you're doing it still?
>
> Because it's a great idea and I thought everyone loved it?
>
> Can you point me to the concerns raised, I'll go back and look. I didn't
> think it was contentious...
>
> To summarize my rationale for it:
>
> 1) It avoids all of the non-sense with conflicting system headers
> (because we -Iinclude and the headers live in include/qemu)
>
> 2) It establishes what are public functions for use in other parts of
> qemu vs. private headers (which we currently use based on ad-hoc naming
> schemes like block_int.h).
>
> 3) I think the kernel serves as an existence proof that this method to
> manage headers works really well in practice.

4) Because it's easy enough to complete the transition with a few "git 
mv", so there's hope not to be stuck with 2 headers in include/ for 5 years.

Paolo

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 1/3] es1370: Drop dead code
  2012-01-24 19:33 ` [Qemu-devel] [PATCH 11/28] qdev: prepare source tree for code conversion Anthony Liguori
@ 2012-01-26 17:35   ` Andreas Färber
  2012-01-26 17:35     ` [Qemu-devel] [PATCH 2/3] marvell_88w8618_audio: Use DEFINE_PROP_* macros Andreas Färber
  2012-01-26 17:35     ` [Qemu-devel] [PATCH 3/3] qdev: prepare source tree for code conversion Andreas Färber
  0 siblings, 2 replies; 77+ messages in thread
From: Andreas Färber @ 2012-01-26 17:35 UTC (permalink / raw)
  To: qemu-devel
  Cc: Anthony Liguori, Michael S. Tsirkin, Stefan Weil, Avi Kivity,
	Andreas Färber, Richard Henderson

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 Anthony, as requested before, please pull these out of the stylistic changes.

 hw/es1370.c |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/hw/es1370.c b/hw/es1370.c
index 6a3ba55..3527eb6 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -1041,13 +1041,8 @@ static PCIDeviceInfo es1370_info = {
     .vendor_id    = PCI_VENDOR_ID_ENSONIQ,
     .device_id    = PCI_DEVICE_ID_ENSONIQ_ES1370,
     .class_id     = PCI_CLASS_MULTIMEDIA_AUDIO,
-#if 1
     .subsystem_vendor_id = 0x4942,
     .subsystem_id = 0x4c4c,
-#else
-    .subsystem_vendor_id = 0x1274,
-    .subsystem_id = 0x1371,
-#endif
 };
 
 static void es1370_register (void)
-- 
1.7.7

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 2/3] marvell_88w8618_audio: Use DEFINE_PROP_* macros
  2012-01-26 17:35   ` [Qemu-devel] [PATCH 1/3] es1370: Drop dead code Andreas Färber
@ 2012-01-26 17:35     ` Andreas Färber
  2012-01-26 17:35     ` [Qemu-devel] [PATCH 3/3] qdev: prepare source tree for code conversion Andreas Färber
  1 sibling, 0 replies; 77+ messages in thread
From: Andreas Färber @ 2012-01-26 17:35 UTC (permalink / raw)
  To: qemu-devel
  Cc: Stefan Weil, Anthony Liguori, Matthew Fernandez,
	Andreas Färber, Avi Kivity

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
[AF: Use DEFINE_PROP_END_OF_LIST() as well]
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 If we're touching it, let's do it right. Causes a trivial merge conflict
 in [PATCH 27/28] sysbus: apic: ioapic: convert to QEMU Object Model.

 hw/marvell_88w8618_audio.c |   10 +++-------
 1 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/hw/marvell_88w8618_audio.c b/hw/marvell_88w8618_audio.c
index 0cd8410..8b6a5c0 100644
--- a/hw/marvell_88w8618_audio.c
+++ b/hw/marvell_88w8618_audio.c
@@ -50,7 +50,7 @@ typedef struct mv88w8618_audio_state {
     uint32_t play_pos;
     uint32_t last_free;
     uint32_t clock_div;
-    DeviceState *wm;
+    void *wm;
 } mv88w8618_audio_state;
 
 static void mv88w8618_audio_callback(void *opaque, int free_out, int free_in)
@@ -279,12 +279,8 @@ static SysBusDeviceInfo mv88w8618_audio_info = {
     .qdev.reset = mv88w8618_audio_reset,
     .qdev.vmsd  = &mv88w8618_audio_vmsd,
     .qdev.props = (Property[]) {
-        {
-            .name   = "wm8750",
-            .info   = &qdev_prop_ptr,
-            .offset = offsetof(mv88w8618_audio_state, wm),
-        },
-        {/* end of list */}
+        DEFINE_PROP_PTR("wm8750", mv88w8618_audio_state, wm),
+        DEFINE_PROP_END_OF_LIST()
     }
 };
 
-- 
1.7.7

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH 3/3] qdev: prepare source tree for code conversion
  2012-01-26 17:35   ` [Qemu-devel] [PATCH 1/3] es1370: Drop dead code Andreas Färber
  2012-01-26 17:35     ` [Qemu-devel] [PATCH 2/3] marvell_88w8618_audio: Use DEFINE_PROP_* macros Andreas Färber
@ 2012-01-26 17:35     ` Andreas Färber
  1 sibling, 0 replies; 77+ messages in thread
From: Andreas Färber @ 2012-01-26 17:35 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Anthony Liguori, Stefan Hajnoczi, Michael S. Tsirkin,
	Harsh Prateek Bora, Alexander Graf, Markus Armbruster,
	Michael Ellerman, Christoph Hellwig, Aneesh Kumar K.V,
	David Gibson, Paolo Bonzini, Richard Henderson,
	Venkateswararao Jujjuri, Avi Kivity, Gerd Hoffmann

From: Anthony Liguori <aliguori@us.ibm.com>

These are various small stylistic changes which help make things more
consistent such that the automated conversion script can be simpler.

It's not necessary to agree or disagree with these style changes because all
of this code is going to be rewritten by the patch monkey script anyway.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/9pfs/virtio-9p-device.c |    3 +-
 hw/ide/cmd646.c            |   33 ++++-----
 hw/ide/ich.c               |   30 +++----
 hw/ide/piix.c              |   70 +++++++++---------
 hw/piix4.c                 |   29 +++----
 hw/piix_pci.c              |   86 +++++++++++-----------
 hw/qxl.c                   |    8 +-
 hw/spapr_llan.c            |    4 +-
 hw/spapr_vscsi.c           |    4 +-
 hw/spapr_vty.c             |    6 +-
 hw/usb-ehci.c              |   49 ++++++------
 hw/usb-uhci.c              |  107 +++++++++++++++------------
 hw/virtio-pci.c            |  174 ++++++++++++++++++++++----------------------
 13 files changed, 302 insertions(+), 301 deletions(-)

diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 642d5e2..1325f2f 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -172,8 +172,7 @@ static PCIDeviceInfo virtio_9p_info = {
     .revision  = VIRTIO_PCI_ABI_VERSION,
     .class_id  = 0x2,
     .qdev.props = (Property[]) {
-        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
-                        VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
         DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
         DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
         DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 5fe98b1..99e7e6f 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -325,27 +325,24 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
     pci_ide_create_devs(dev, hd_table);
 }
 
-static PCIDeviceInfo cmd646_ide_info[] = {
-    {
-        .qdev.name    = "cmd646-ide",
-        .qdev.size    = sizeof(PCIIDEState),
-        .init         = pci_cmd646_ide_initfn,
-        .exit         = pci_cmd646_ide_exitfn,
-        .vendor_id    = PCI_VENDOR_ID_CMD,
-        .device_id    = PCI_DEVICE_ID_CMD_646,
-        .revision     = 0x07, // IDE controller revision
-        .class_id     = PCI_CLASS_STORAGE_IDE,
-        .qdev.props   = (Property[]) {
-            DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
-            DEFINE_PROP_END_OF_LIST(),
-        },
-    },{
-        /* end of list */
-    }
+static PCIDeviceInfo cmd646_ide_info = {
+    .qdev.name    = "cmd646-ide",
+    .qdev.size    = sizeof(PCIIDEState),
+    .init         = pci_cmd646_ide_initfn,
+    .exit         = pci_cmd646_ide_exitfn,
+    .vendor_id    = PCI_VENDOR_ID_CMD,
+    .device_id    = PCI_DEVICE_ID_CMD_646,
+    /* IDE controller revision */
+    .revision     = 0x07,
+    .class_id     = PCI_CLASS_STORAGE_IDE,
+    .qdev.props   = (Property[]) {
+        DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
+        DEFINE_PROP_END_OF_LIST(),
+    },
 };
 
 static void cmd646_ide_register(void)
 {
-    pci_qdev_register_many(cmd646_ide_info);
+    pci_qdev_register(&cmd646_ide_info);
 }
 device_init(cmd646_ide_register);
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 3f7510f..e6421e2 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -146,26 +146,22 @@ static void pci_ich9_write_config(PCIDevice *pci, uint32_t addr,
     msi_write_config(pci, addr, val, len);
 }
 
-static PCIDeviceInfo ich_ahci_info[] = {
-    {
-        .qdev.name    = "ich9-ahci",
-        .qdev.alias   = "ahci",
-        .qdev.size    = sizeof(AHCIPCIState),
-        .qdev.vmsd    = &vmstate_ahci,
-        .init         = pci_ich9_ahci_init,
-        .exit         = pci_ich9_uninit,
-        .config_write = pci_ich9_write_config,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82801IR,
-        .revision     = 0x02,
-        .class_id     = PCI_CLASS_STORAGE_SATA,
-    },{
-        /* end of list */
-    }
+static PCIDeviceInfo ich_ahci_info = {
+    .qdev.name    = "ich9-ahci",
+    .qdev.alias   = "ahci",
+    .qdev.size    = sizeof(AHCIPCIState),
+    .qdev.vmsd    = &vmstate_ahci,
+    .init         = pci_ich9_ahci_init,
+    .exit         = pci_ich9_uninit,
+    .config_write = pci_ich9_write_config,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82801IR,
+    .revision     = 0x02,
+    .class_id     = PCI_CLASS_STORAGE_SATA,
 };
 
 static void ich_ahci_register(void)
 {
-    pci_qdev_register_many(ich_ahci_info);
+    pci_qdev_register(&ich_ahci_info);
 }
 device_init(ich_ahci_register);
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index c0e3450..91b77a2 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -237,43 +237,45 @@ PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
     return dev;
 }
 
-static PCIDeviceInfo piix_ide_info[] = {
-    {
-        .qdev.name    = "piix3-ide",
-        .qdev.size    = sizeof(PCIIDEState),
-        .qdev.no_user = 1,
-        .no_hotplug   = 1,
-        .init         = pci_piix_ide_initfn,
-        .exit         = pci_piix_ide_exitfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
-        .class_id     = PCI_CLASS_STORAGE_IDE,
-    },{
-        .qdev.name    = "piix3-ide-xen",
-        .qdev.size    = sizeof(PCIIDEState),
-        .qdev.no_user = 1,
-        .qdev.unplug  = pci_piix3_xen_ide_unplug,
-        .init         = pci_piix_ide_initfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
-        .class_id     = PCI_CLASS_STORAGE_IDE,
-    },{
-        .qdev.name    = "piix4-ide",
-        .qdev.size    = sizeof(PCIIDEState),
-        .qdev.no_user = 1,
-        .no_hotplug   = 1,
-        .init         = pci_piix_ide_initfn,
-        .exit         = pci_piix_ide_exitfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371AB,
-        .class_id     = PCI_CLASS_STORAGE_IDE,
-    },{
-        /* end of list */
-    }
+static PCIDeviceInfo piix3_ide_info = {
+    .qdev.name    = "piix3-ide",
+    .qdev.size    = sizeof(PCIIDEState),
+    .qdev.no_user = 1,
+    .no_hotplug   = 1,
+    .init         = pci_piix_ide_initfn,
+    .exit         = pci_piix_ide_exitfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
+    .class_id     = PCI_CLASS_STORAGE_IDE,
+};
+
+static PCIDeviceInfo piix3_ide_xen_info = {
+    .qdev.name    = "piix3-ide-xen",
+    .qdev.size    = sizeof(PCIIDEState),
+    .qdev.no_user = 1,
+    .qdev.unplug  = pci_piix3_xen_ide_unplug,
+    .init         = pci_piix_ide_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
+    .class_id     = PCI_CLASS_STORAGE_IDE,
+};
+
+static PCIDeviceInfo piix4_ide_info = {
+    .qdev.name    = "piix4-ide",
+    .qdev.size    = sizeof(PCIIDEState),
+    .qdev.no_user = 1,
+    .no_hotplug   = 1,
+    .init         = pci_piix_ide_initfn,
+    .exit         = pci_piix_ide_exitfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82371AB,
+    .class_id     = PCI_CLASS_STORAGE_IDE,
 };
 
 static void piix_ide_register(void)
 {
-    pci_qdev_register_many(piix_ide_info);
+    pci_qdev_register(&piix3_ide_info);
+    pci_qdev_register(&piix3_ide_xen_info);
+    pci_qdev_register(&piix4_ide_info);
 }
 device_init(piix_ide_register);
diff --git a/hw/piix4.c b/hw/piix4.c
index 51af459..130dfd1 100644
--- a/hw/piix4.c
+++ b/hw/piix4.c
@@ -102,25 +102,22 @@ int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn)
     return d->devfn;
 }
 
-static PCIDeviceInfo piix4_info[] = {
-    {
-        .qdev.name    = "PIIX4",
-        .qdev.desc    = "ISA bridge",
-        .qdev.size    = sizeof(PIIX4State),
-        .qdev.vmsd    = &vmstate_piix4,
-        .qdev.no_user = 1,
-        .no_hotplug   = 1,
-        .init         = piix4_initfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371AB_0, // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge
-        .class_id     = PCI_CLASS_BRIDGE_ISA,
-    },{
-        /* end of list */
-    }
+static PCIDeviceInfo piix4_info = {
+    .qdev.name    = "PIIX4",
+    .qdev.desc    = "ISA bridge",
+    .qdev.size    = sizeof(PIIX4State),
+    .qdev.vmsd    = &vmstate_piix4,
+    .qdev.no_user = 1,
+    .no_hotplug   = 1,
+    .init         = piix4_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    /* 82371AB/EB/MB PIIX4 PCI-to-ISA bridge */
+    .device_id    = PCI_DEVICE_ID_INTEL_82371AB_0,
+    .class_id     = PCI_CLASS_BRIDGE_ISA,
 };
 
 static void piix4_register(void)
 {
-    pci_qdev_register_many(piix4_info);
+    pci_qdev_register(&piix4_info);
 }
 device_init(piix4_register);
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 3652522..5cbeed5 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -502,47 +502,47 @@ static int piix3_initfn(PCIDevice *dev)
     return 0;
 }
 
-static PCIDeviceInfo i440fx_info[] = {
-    {
-        .qdev.name    = "i440FX",
-        .qdev.desc    = "Host bridge",
-        .qdev.size    = sizeof(PCII440FXState),
-        .qdev.vmsd    = &vmstate_i440fx,
-        .qdev.no_user = 1,
-        .no_hotplug   = 1,
-        .init         = i440fx_initfn,
-        .config_write = i440fx_write_config,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82441,
-        .revision     = 0x02,
-        .class_id     = PCI_CLASS_BRIDGE_HOST,
-    },{
-        .qdev.name    = "PIIX3",
-        .qdev.desc    = "ISA bridge",
-        .qdev.size    = sizeof(PIIX3State),
-        .qdev.vmsd    = &vmstate_piix3,
-        .qdev.no_user = 1,
-        .no_hotplug   = 1,
-        .init         = piix3_initfn,
-        .config_write = piix3_write_config,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
-        .class_id     = PCI_CLASS_BRIDGE_ISA,
-    },{
-        .qdev.name    = "PIIX3-xen",
-        .qdev.desc    = "ISA bridge",
-        .qdev.size    = sizeof(PIIX3State),
-        .qdev.vmsd    = &vmstate_piix3,
-        .qdev.no_user = 1,
-        .no_hotplug   = 1,
-        .init         = piix3_initfn,
-        .config_write = piix3_write_config_xen,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
-        .class_id     = PCI_CLASS_BRIDGE_ISA,
-    },{
-        /* end of list */
-    }
+static PCIDeviceInfo i440fx_info = {
+    .qdev.name    = "i440FX",
+    .qdev.desc    = "Host bridge",
+    .qdev.size    = sizeof(PCII440FXState),
+    .qdev.vmsd    = &vmstate_i440fx,
+    .qdev.no_user = 1,
+    .no_hotplug   = 1,
+    .init         = i440fx_initfn,
+    .config_write = i440fx_write_config,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82441,
+    .revision     = 0x02,
+    .class_id     = PCI_CLASS_BRIDGE_HOST,
+};
+
+static PCIDeviceInfo piix3_info = {
+    .qdev.name    = "PIIX3",
+    .qdev.desc    = "ISA bridge",
+    .qdev.size    = sizeof(PIIX3State),
+    .qdev.vmsd    = &vmstate_piix3,
+    .qdev.no_user = 1,
+    .no_hotplug   = 1,
+    .init         = piix3_initfn,
+    .config_write = piix3_write_config,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
+    .class_id     = PCI_CLASS_BRIDGE_ISA,
+};
+
+static PCIDeviceInfo piix3_xen_info = {
+    .qdev.name    = "PIIX3-xen",
+    .qdev.desc    = "ISA bridge",
+    .qdev.size    = sizeof(PIIX3State),
+    .qdev.vmsd    = &vmstate_piix3,
+    .qdev.no_user = 1,
+    .no_hotplug   = 1,
+    .init         = piix3_initfn,
+    .config_write = piix3_write_config_xen,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
+    .class_id     = PCI_CLASS_BRIDGE_ISA,
 };
 
 static SysBusDeviceInfo i440fx_pcihost_info = {
@@ -555,7 +555,9 @@ static SysBusDeviceInfo i440fx_pcihost_info = {
 
 static void i440fx_register(void)
 {
+    pci_qdev_register(&i440fx_info);
+    pci_qdev_register(&piix3_info);
+    pci_qdev_register(&piix3_xen_info);
     sysbus_register_withprop(&i440fx_pcihost_info);
-    pci_qdev_register_many(i440fx_info);
 }
 device_init(i440fx_register);
diff --git a/hw/qxl.c b/hw/qxl.c
index 6442193..a00dc33 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1824,7 +1824,7 @@ static Property qxl_properties[] = {
         DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo qxl_info_primary = {
+static PCIDeviceInfo qxl_primary_info = {
     .qdev.name    = "qxl-vga",
     .qdev.desc    = "Spice QXL GPU (primary, vga compatible)",
     .qdev.size    = sizeof(PCIQXLDevice),
@@ -1839,7 +1839,7 @@ static PCIDeviceInfo qxl_info_primary = {
     .qdev.props   = qxl_properties,
 };
 
-static PCIDeviceInfo qxl_info_secondary = {
+static PCIDeviceInfo qxl_secondary_info = {
     .qdev.name    = "qxl",
     .qdev.desc    = "Spice QXL GPU (secondary)",
     .qdev.size    = sizeof(PCIQXLDevice),
@@ -1854,8 +1854,8 @@ static PCIDeviceInfo qxl_info_secondary = {
 
 static void qxl_register(void)
 {
-    pci_qdev_register(&qxl_info_primary);
-    pci_qdev_register(&qxl_info_secondary);
+    pci_qdev_register(&qxl_primary_info);
+    pci_qdev_register(&qxl_secondary_info);
 }
 
 device_init(qxl_register);
diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c
index 91003cc..b9a5afc 100644
--- a/hw/spapr_llan.c
+++ b/hw/spapr_llan.c
@@ -474,7 +474,7 @@ static target_ulong h_multicast_ctrl(CPUState *env, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static VIOsPAPRDeviceInfo spapr_vlan = {
+static VIOsPAPRDeviceInfo spapr_vlan_info = {
     .init = spapr_vlan_init,
     .devnode = spapr_vlan_devnode,
     .dt_name = "l-lan",
@@ -492,12 +492,12 @@ static VIOsPAPRDeviceInfo spapr_vlan = {
 
 static void spapr_vlan_register(void)
 {
-    spapr_vio_bus_register_withprop(&spapr_vlan);
     spapr_register_hypercall(H_REGISTER_LOGICAL_LAN, h_register_logical_lan);
     spapr_register_hypercall(H_FREE_LOGICAL_LAN, h_free_logical_lan);
     spapr_register_hypercall(H_SEND_LOGICAL_LAN, h_send_logical_lan);
     spapr_register_hypercall(H_ADD_LOGICAL_LAN_BUFFER,
                              h_add_logical_lan_buffer);
     spapr_register_hypercall(H_MULTICAST_CTRL, h_multicast_ctrl);
+    spapr_vio_bus_register_withprop(&spapr_vlan_info);
 }
 device_init(spapr_vlan_register);
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index 00e2d2d..21d946e 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -947,7 +947,7 @@ static int spapr_vscsi_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
     return 0;
 }
 
-static VIOsPAPRDeviceInfo spapr_vscsi = {
+static VIOsPAPRDeviceInfo spapr_vscsi_info = {
     .init = spapr_vscsi_init,
     .devnode = spapr_vscsi_devnode,
     .dt_name = "v-scsi",
@@ -964,6 +964,6 @@ static VIOsPAPRDeviceInfo spapr_vscsi = {
 
 static void spapr_vscsi_register(void)
 {
-    spapr_vio_bus_register_withprop(&spapr_vscsi);
+    spapr_vio_bus_register_withprop(&spapr_vscsi_info);
 }
 device_init(spapr_vscsi_register);
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index 181dd0e..3d5c579 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -135,7 +135,7 @@ void spapr_vty_create(VIOsPAPRBus *bus, uint32_t reg, CharDriverState *chardev)
     qdev_init_nofail(dev);
 }
 
-static VIOsPAPRDeviceInfo spapr_vty = {
+static VIOsPAPRDeviceInfo spapr_vty_info = {
     .init = spapr_vty_init,
     .dt_name = "vty",
     .dt_type = "serial",
@@ -163,7 +163,7 @@ VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
     selected = NULL;
     QTAILQ_FOREACH(iter, &bus->bus.children, sibling) {
         /* Only look at VTY devices */
-        if (qdev_get_info(iter) != &spapr_vty.qdev) {
+        if (qdev_get_info(iter) != &spapr_vty_info.qdev) {
             continue;
         }
 
@@ -203,8 +203,8 @@ static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg)
 
 static void spapr_vty_register(void)
 {
-    spapr_vio_bus_register_withprop(&spapr_vty);
     spapr_register_hypercall(H_PUT_TERM_CHAR, h_put_term_char);
     spapr_register_hypercall(H_GET_TERM_CHAR, h_get_term_char);
+    spapr_vio_bus_register_withprop(&spapr_vty_info);
 }
 device_init(spapr_vty_register);
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index a305661..63fc3c7 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -2263,30 +2263,28 @@ static Property ehci_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo ehci_info[] = {
-    {
-        .qdev.name    = "usb-ehci",
-        .qdev.size    = sizeof(EHCIState),
-        .qdev.vmsd    = &vmstate_ehci,
-        .init         = usb_ehci_initfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82801D, /* ich4 */
-        .revision     = 0x10,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = ehci_properties,
-    },{
-        .qdev.name    = "ich9-usb-ehci1",
-        .qdev.size    = sizeof(EHCIState),
-        .qdev.vmsd    = &vmstate_ehci,
-        .init         = usb_ehci_initfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82801I_EHCI1,
-        .revision     = 0x03,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = ehci_properties,
-    },{
-        /* end of list */
-    }
+static PCIDeviceInfo ehci_info = {
+    .qdev.name    = "usb-ehci",
+    .qdev.size    = sizeof(EHCIState),
+    .qdev.vmsd    = &vmstate_ehci,
+    .init         = usb_ehci_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82801D, /* ich4 */
+    .revision     = 0x10,
+    .class_id     = PCI_CLASS_SERIAL_USB,
+    .qdev.props   = ehci_properties,
+};
+
+static PCIDeviceInfo ich9_ehci_info = {
+    .qdev.name    = "ich9-usb-ehci1",
+    .qdev.size    = sizeof(EHCIState),
+    .qdev.vmsd    = &vmstate_ehci,
+    .init         = usb_ehci_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82801I_EHCI1,
+    .revision     = 0x03,
+    .class_id     = PCI_CLASS_SERIAL_USB,
+    .qdev.props   = ehci_properties,
 };
 
 static int usb_ehci_initfn(PCIDevice *dev)
@@ -2362,7 +2360,8 @@ static int usb_ehci_initfn(PCIDevice *dev)
 
 static void ehci_register(void)
 {
-    pci_qdev_register_many(ehci_info);
+    pci_qdev_register(&ehci_info);
+    pci_qdev_register(&ich9_ehci_info);
 }
 device_init(ehci_register);
 
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 25d4e8c..1821063 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1192,8 +1192,7 @@ static Property uhci_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static PCIDeviceInfo uhci_info[] = {
-    {
+static PCIDeviceInfo piix3_uhci_info = {
         .qdev.name    = "piix3-usb-uhci",
         .qdev.size    = sizeof(UHCIState),
         .qdev.vmsd    = &vmstate_uhci,
@@ -1204,7 +1203,9 @@ static PCIDeviceInfo uhci_info[] = {
         .revision     = 0x01,
         .class_id     = PCI_CLASS_SERIAL_USB,
         .qdev.props   = uhci_properties,
-    },{
+};
+
+static PCIDeviceInfo piix4_uhci_info = {
         .qdev.name    = "piix4-usb-uhci",
         .qdev.size    = sizeof(UHCIState),
         .qdev.vmsd    = &vmstate_uhci,
@@ -1215,55 +1216,65 @@ static PCIDeviceInfo uhci_info[] = {
         .revision     = 0x01,
         .class_id     = PCI_CLASS_SERIAL_USB,
         .qdev.props   = uhci_properties,
-    },{
-        .qdev.name    = "vt82c686b-usb-uhci",
-        .qdev.size    = sizeof(UHCIState),
-        .qdev.vmsd    = &vmstate_uhci,
-        .init         = usb_uhci_vt82c686b_initfn,
-        .exit         = usb_uhci_exit,
-        .vendor_id    = PCI_VENDOR_ID_VIA,
-        .device_id    = PCI_DEVICE_ID_VIA_UHCI,
-        .revision     = 0x01,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = uhci_properties,
-    },{
-        .qdev.name    = "ich9-usb-uhci1",
-        .qdev.size    = sizeof(UHCIState),
-        .qdev.vmsd    = &vmstate_uhci,
-        .init         = usb_uhci_common_initfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI1,
-        .revision     = 0x03,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = uhci_properties,
-    },{
-        .qdev.name    = "ich9-usb-uhci2",
-        .qdev.size    = sizeof(UHCIState),
-        .qdev.vmsd    = &vmstate_uhci,
-        .init         = usb_uhci_common_initfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI2,
-        .revision     = 0x03,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = uhci_properties,
-    },{
-        .qdev.name    = "ich9-usb-uhci3",
-        .qdev.size    = sizeof(UHCIState),
-        .qdev.vmsd    = &vmstate_uhci,
-        .init         = usb_uhci_common_initfn,
-        .vendor_id    = PCI_VENDOR_ID_INTEL,
-        .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI3,
-        .revision     = 0x03,
-        .class_id     = PCI_CLASS_SERIAL_USB,
-        .qdev.props   = uhci_properties,
-    },{
-        /* end of list */
-    }
+};
+
+static PCIDeviceInfo vt82c686b_uhci_info = {
+    .qdev.name    = "vt82c686b-usb-uhci",
+    .qdev.size    = sizeof(UHCIState),
+    .qdev.vmsd    = &vmstate_uhci,
+    .init         = usb_uhci_vt82c686b_initfn,
+    .exit         = usb_uhci_exit,
+    .vendor_id    = PCI_VENDOR_ID_VIA,
+    .device_id    = PCI_DEVICE_ID_VIA_UHCI,
+    .revision     = 0x01,
+    .class_id     = PCI_CLASS_SERIAL_USB,
+    .qdev.props   = uhci_properties,
+};
+
+static PCIDeviceInfo ich9_uhci1_info = {
+    .qdev.name    = "ich9-usb-uhci1",
+    .qdev.size    = sizeof(UHCIState),
+    .qdev.vmsd    = &vmstate_uhci,
+    .init         = usb_uhci_common_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI1,
+    .revision     = 0x03,
+    .class_id     = PCI_CLASS_SERIAL_USB,
+    .qdev.props   = uhci_properties,
+};
+
+static PCIDeviceInfo ich9_uhci2_info = {
+    .qdev.name    = "ich9-usb-uhci2",
+    .qdev.size    = sizeof(UHCIState),
+    .qdev.vmsd    = &vmstate_uhci,
+    .init         = usb_uhci_common_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI2,
+    .revision     = 0x03,
+    .class_id     = PCI_CLASS_SERIAL_USB,
+    .qdev.props   = uhci_properties,
+};
+
+static PCIDeviceInfo ich9_uhci3_info = {
+    .qdev.name    = "ich9-usb-uhci3",
+    .qdev.size    = sizeof(UHCIState),
+    .qdev.vmsd    = &vmstate_uhci,
+    .init         = usb_uhci_common_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82801I_UHCI3,
+    .revision     = 0x03,
+    .class_id     = PCI_CLASS_SERIAL_USB,
+    .qdev.props   = uhci_properties,
 };
 
 static void uhci_register(void)
 {
-    pci_qdev_register_many(uhci_info);
+    pci_qdev_register(&piix3_uhci_info);
+    pci_qdev_register(&piix4_uhci_info);
+    pci_qdev_register(&vt82c686b_uhci_info);
+    pci_qdev_register(&ich9_uhci1_info);
+    pci_qdev_register(&ich9_uhci2_info);
+    pci_qdev_register(&ich9_uhci3_info);
 }
 device_init(uhci_register);
 
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index c93889a..72b53af 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -806,98 +806,96 @@ static int virtio_balloon_exit_pci(PCIDevice *pci_dev)
     return virtio_exit_pci(pci_dev);
 }
 
-static PCIDeviceInfo virtio_info[] = {
-    {
-        .qdev.name = "virtio-blk-pci",
-        .qdev.alias = "virtio-blk",
-        .qdev.size = sizeof(VirtIOPCIProxy),
-        .init      = virtio_blk_init_pci,
-        .exit      = virtio_blk_exit_pci,
-        .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
-        .device_id = PCI_DEVICE_ID_VIRTIO_BLOCK,
-        .revision  = VIRTIO_PCI_ABI_VERSION,
-        .class_id  = PCI_CLASS_STORAGE_SCSI,
-        .qdev.props = (Property[]) {
-            DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
-            DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
-            DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial),
-            DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
-                            VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
-            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
-            DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
-            DEFINE_PROP_END_OF_LIST(),
-        },
-        .qdev.reset = virtio_pci_reset,
-    },{
-        .qdev.name  = "virtio-net-pci",
-        .qdev.alias = "virtio-net",
-        .qdev.size  = sizeof(VirtIOPCIProxy),
-        .init       = virtio_net_init_pci,
-        .exit       = virtio_net_exit_pci,
-        .romfile    = "pxe-virtio.rom",
-        .vendor_id  = PCI_VENDOR_ID_REDHAT_QUMRANET,
-        .device_id  = PCI_DEVICE_ID_VIRTIO_NET,
-        .revision   = VIRTIO_PCI_ABI_VERSION,
-        .class_id   = PCI_CLASS_NETWORK_ETHERNET,
-        .qdev.props = (Property[]) {
-            DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
-                            VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
-            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
-            DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
-            DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
-            DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy,
-                               net.txtimer, TX_TIMER_INTERVAL),
-            DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy,
-                              net.txburst, TX_BURST),
-            DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx),
-            DEFINE_PROP_END_OF_LIST(),
-        },
-        .qdev.reset = virtio_pci_reset,
-    },{
-        .qdev.name = "virtio-serial-pci",
-        .qdev.alias = "virtio-serial",
-        .qdev.size = sizeof(VirtIOPCIProxy),
-        .init      = virtio_serial_init_pci,
-        .exit      = virtio_serial_exit_pci,
-        .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
-        .device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE,
-        .revision  = VIRTIO_PCI_ABI_VERSION,
-        .class_id  = PCI_CLASS_COMMUNICATION_OTHER,
-        .qdev.props = (Property[]) {
-            DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
-                            VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
-            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
-                               DEV_NVECTORS_UNSPECIFIED),
-            DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
-            DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-            DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy,
-                               serial.max_virtserial_ports, 31),
-            DEFINE_PROP_END_OF_LIST(),
-        },
-        .qdev.reset = virtio_pci_reset,
-    },{
-        .qdev.name = "virtio-balloon-pci",
-        .qdev.alias = "virtio-balloon",
-        .qdev.size = sizeof(VirtIOPCIProxy),
-        .init      = virtio_balloon_init_pci,
-        .exit      = virtio_balloon_exit_pci,
-        .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
-        .device_id = PCI_DEVICE_ID_VIRTIO_BALLOON,
-        .revision  = VIRTIO_PCI_ABI_VERSION,
-        .class_id  = PCI_CLASS_MEMORY_RAM,
-        .qdev.props = (Property[]) {
-            DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-            DEFINE_PROP_END_OF_LIST(),
-        },
-        .qdev.reset = virtio_pci_reset,
-    },{
-        /* end of list */
-    }
+static PCIDeviceInfo virtio_blk_info = {
+    .qdev.name = "virtio-blk-pci",
+    .qdev.alias = "virtio-blk",
+    .qdev.size = sizeof(VirtIOPCIProxy),
+    .init      = virtio_blk_init_pci,
+    .exit      = virtio_blk_exit_pci,
+    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+    .device_id = PCI_DEVICE_ID_VIRTIO_BLOCK,
+    .revision  = VIRTIO_PCI_ABI_VERSION,
+    .class_id  = PCI_CLASS_STORAGE_SCSI,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
+        DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
+        DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial),
+        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+        DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
+        DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+    .qdev.reset = virtio_pci_reset,
+};
+
+static PCIDeviceInfo virtio_net_info = {
+    .qdev.name  = "virtio-net-pci",
+    .qdev.alias = "virtio-net",
+    .qdev.size  = sizeof(VirtIOPCIProxy),
+    .init       = virtio_net_init_pci,
+    .exit       = virtio_net_exit_pci,
+    .romfile    = "pxe-virtio.rom",
+    .vendor_id  = PCI_VENDOR_ID_REDHAT_QUMRANET,
+    .device_id  = PCI_DEVICE_ID_VIRTIO_NET,
+    .revision   = VIRTIO_PCI_ABI_VERSION,
+    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
+        DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
+        DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
+        DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
+        DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy, net.txtimer, TX_TIMER_INTERVAL),
+        DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy, net.txburst, TX_BURST),
+        DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+    .qdev.reset = virtio_pci_reset,
+};
+
+static PCIDeviceInfo virtio_serial_info = {
+    .qdev.name = "virtio-serial-pci",
+    .qdev.alias = "virtio-serial",
+    .qdev.size = sizeof(VirtIOPCIProxy),
+    .init      = virtio_serial_init_pci,
+    .exit      = virtio_serial_exit_pci,
+    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+    .device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE,
+    .revision  = VIRTIO_PCI_ABI_VERSION,
+    .class_id  = PCI_CLASS_COMMUNICATION_OTHER,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+        DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, DEV_NVECTORS_UNSPECIFIED),
+        DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
+        DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+        DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, serial.max_virtserial_ports, 31),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+    .qdev.reset = virtio_pci_reset,
+};
+
+static PCIDeviceInfo virtio_balloon_info = {
+    .qdev.name = "virtio-balloon-pci",
+    .qdev.alias = "virtio-balloon",
+    .qdev.size = sizeof(VirtIOPCIProxy),
+    .init      = virtio_balloon_init_pci,
+    .exit      = virtio_balloon_exit_pci,
+    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+    .device_id = PCI_DEVICE_ID_VIRTIO_BALLOON,
+    .revision  = VIRTIO_PCI_ABI_VERSION,
+    .class_id  = PCI_CLASS_MEMORY_RAM,
+    .qdev.props = (Property[]) {
+        DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+    .qdev.reset = virtio_pci_reset,
 };
 
 static void virtio_pci_register_devices(void)
 {
-    pci_qdev_register_many(virtio_info);
+    pci_qdev_register(&virtio_blk_info);
+    pci_qdev_register(&virtio_net_info);
+    pci_qdev_register(&virtio_serial_info);
+    pci_qdev_register(&virtio_balloon_info);
 }
 
 device_init(virtio_pci_register_devices)
-- 
1.7.7

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* [Qemu-devel] [PATCH] macio: Convert to qdev
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 01/28] macio: convert " Anthony Liguori
@ 2012-01-26 23:17   ` Andreas Färber
  2012-03-06 22:56     ` Alexander Graf
  0 siblings, 1 reply; 77+ messages in thread
From: Andreas Färber @ 2012-01-26 23:17 UTC (permalink / raw)
  To: qemu-devel
  Cc: Anthony Liguori, Alexander Graf, Laurent Vivier, qemu-ppc,
	Avi Kivity, Andreas Färber, Richard Henderson

From: Anthony Liguori <aliguori@us.ibm.com>

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

Split macio into two PCIDevices with declarative device ID,
macio-oldworld and macio-newworld. Drop is_oldworld state in favor
of two separate init functions and deferred creation.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Cc: Alexander Graf <agraf@suse.de>
---
 Anthony, I've extended and tested your patch, please consider using this version.
 (In that case feel free to move your Signed-off-by down.)

 Alex, please ack. We could inline macio_init() and get rid of is_oldworld but
 would have to move MacIOState into ppc_mac.h then.

 hw/macio.c        |  114 +++++++++++++++++++++++++++++++++++++---------------
 hw/ppc_mac.h      |    8 ++--
 hw/ppc_newworld.c |    2 +-
 hw/ppc_oldworld.c |    2 +-
 4 files changed, 87 insertions(+), 39 deletions(-)

diff --git a/hw/macio.c b/hw/macio.c
index cc6ae40..3fb49fb 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -27,9 +27,8 @@
 #include "pci.h"
 #include "escc.h"
 
-typedef struct macio_state_t macio_state_t;
-struct macio_state_t {
-    int is_oldworld;
+typedef struct MacIOState {
+    PCIDevice parent;
     MemoryRegion bar;
     MemoryRegion *pic_mem;
     MemoryRegion *dbdma_mem;
@@ -38,23 +37,14 @@ struct macio_state_t {
     void *nvram;
     int nb_ide;
     MemoryRegion *ide_mem[4];
-};
+} MacIOState;
 
-static void macio_bar_setup(macio_state_t *macio_state)
+static void macio_bar_setup(MacIOState *macio_state)
 {
     int i;
     MemoryRegion *bar = &macio_state->bar;
 
     memory_region_init(bar, "macio", 0x80000);
-    if (macio_state->pic_mem) {
-        if (macio_state->is_oldworld) {
-            /* Heathrow PIC */
-            memory_region_add_subregion(bar, 0x00000, macio_state->pic_mem);
-        } else {
-            /* OpenPIC */
-            memory_region_add_subregion(bar, 0x40000, macio_state->pic_mem);
-        }
-    }
     if (macio_state->dbdma_mem) {
         memory_region_add_subregion(bar, 0x08000, macio_state->dbdma_mem);
     }
@@ -70,25 +60,82 @@ static void macio_bar_setup(macio_state_t *macio_state)
                                         macio_state->ide_mem[i]);
         }
     }
-    if (macio_state->nvram != NULL)
+    if (macio_state->nvram != NULL) {
         macio_nvram_setup_bar(macio_state->nvram, bar, 0x60000);
+    }
+}
+
+static void macio_common_init(MacIOState *macio_state)
+{
+    PCIDevice *d = &macio_state->parent;
+
+    d->config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt on pin 1 */
+
+    macio_bar_setup(macio_state);
+    pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &macio_state->bar);
+}
+
+static int macio_oldworld_initfn(PCIDevice *d)
+{
+    MacIOState *s = DO_UPCAST(MacIOState, parent, d);
+
+    macio_common_init(s);
+
+    if (s->pic_mem != NULL) {
+        /* Heathrow PIC */
+        memory_region_add_subregion(&s->bar, 0x00000, s->pic_mem);
+    }
+    return 0;
 }
 
-void macio_init (PCIBus *bus, int device_id, int is_oldworld,
-                 MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
-                 MemoryRegion *cuda_mem, void *nvram,
-                 int nb_ide, MemoryRegion **ide_mem,
-                 MemoryRegion *escc_mem)
+static int macio_newworld_initfn(PCIDevice *d)
+{
+    MacIOState *s = DO_UPCAST(MacIOState, parent, d);
+
+    macio_common_init(s);
+
+    if (s->pic_mem != NULL) {
+        /* OpenPIC */
+        memory_region_add_subregion(&s->bar, 0x40000, s->pic_mem);
+    }
+    return 0;
+}
+
+static PCIDeviceInfo macio_oldworld_info = {
+    .qdev.name = "macio-oldworld",
+    .qdev.size = sizeof(MacIOState),
+    .qdev.no_user = 1,
+    .no_hotplug = 1,
+    .init = macio_oldworld_initfn,
+    .vendor_id = PCI_VENDOR_ID_APPLE,
+    .device_id = PCI_DEVICE_ID_APPLE_343S1201,
+    .class_id = PCI_CLASS_OTHERS << 8,
+};
+
+static PCIDeviceInfo macio_newworld_info = {
+    .qdev.name = "macio-newworld",
+    .qdev.size = sizeof(MacIOState),
+    .qdev.no_user = 1,
+    .no_hotplug = 1,
+    .init = macio_newworld_initfn,
+    .vendor_id = PCI_VENDOR_ID_APPLE,
+    .device_id = PCI_DEVICE_ID_APPLE_UNI_N_KEYL,
+    .class_id = PCI_CLASS_OTHERS << 8,
+};
+
+void macio_init(PCIBus *bus, bool is_oldworld,
+                MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+                MemoryRegion *cuda_mem, void *nvram,
+                int nb_ide, MemoryRegion **ide_mem,
+                MemoryRegion *escc_mem)
 {
     PCIDevice *d;
-    macio_state_t *macio_state;
+    MacIOState *macio_state;
     int i;
 
-    d = pci_register_device(bus, "macio",
-                            sizeof(PCIDevice) + sizeof(macio_state_t),
-                            -1, NULL, NULL);
-    macio_state = (macio_state_t *)(d + 1);
-    macio_state->is_oldworld = is_oldworld;
+    d = pci_create(bus, -1, is_oldworld ? "macio-oldworld" : "macio-newworld");
+
+    macio_state = DO_UPCAST(MacIOState, parent, d);
     macio_state->pic_mem = pic_mem;
     macio_state->dbdma_mem = dbdma_mem;
     macio_state->cuda_mem = cuda_mem;
@@ -104,12 +151,13 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld,
     /* Note: this code is strongly inspirated from the corresponding code
        in PearPC */
 
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);
-    pci_config_set_device_id(d->config, device_id);
-    pci_config_set_class(d->config, PCI_CLASS_OTHERS << 8);
-
-    d->config[0x3d] = 0x01; // interrupt on pin 1
+    qdev_init_nofail(&d->qdev);
+}
 
-    macio_bar_setup(macio_state);
-    pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &macio_state->bar);
+static void macio_register(void)
+{
+    pci_qdev_register(&macio_oldworld_info);
+    pci_qdev_register(&macio_newworld_info);
 }
+
+device_init(macio_register)
diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h
index af75e45..c165096 100644
--- a/hw/ppc_mac.h
+++ b/hw/ppc_mac.h
@@ -45,10 +45,10 @@
 void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq);
 
 /* MacIO */
-void macio_init (PCIBus *bus, int device_id, int is_oldworld,
-                 MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
-                 MemoryRegion *cuda_mem, void *nvram,
-                 int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem);
+void macio_init(PCIBus *bus, bool is_oldworld,
+                MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+                MemoryRegion *cuda_mem, void *nvram,
+                int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem);
 
 /* Heathrow PIC */
 qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index a746c9c..83c09fa 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -348,7 +348,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
     adb_kbd_init(&adb_bus);
     adb_mouse_init(&adb_bus);
 
-    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem,
+    macio_init(pci_bus, false, pic_mem,
                dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_bar);
 
     if (usb_enabled) {
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 9295a34..7a74b61 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -274,7 +274,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     nvr = macio_nvram_init(0x2000, 4);
     pmac_format_nvram_partition(nvr, 0x2000);
 
-    macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem,
+    macio_init(pci_bus, true, pic_mem,
                dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_bar);
 
     if (usb_enabled) {
-- 
1.7.7

^ permalink raw reply related	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 02/28] openpic: remove dead code to make a PCI device version
  2012-01-24 19:32 ` [Qemu-devel] [PATCH 02/28] openpic: remove dead code to make a PCI device version Anthony Liguori
@ 2012-01-26 23:57   ` Andreas Färber
  0 siblings, 0 replies; 77+ messages in thread
From: Andreas Färber @ 2012-01-26 23:57 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-ppc, qemu-devel, Alexander Graf

Am 24.01.2012 20:32, schrieb Anthony Liguori:
> bus is always NULL so the code in this if clause is dead (and therefore
> untested).
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  hw/openpic.c      |   30 +++---------------------------
>  hw/openpic.h      |    2 +-
>  hw/ppc_newworld.c |    2 +-
>  3 files changed, 5 insertions(+), 29 deletions(-)
> 
> diff --git a/hw/openpic.c b/hw/openpic.c
> index 22fc275..280b7a9 100644
> --- a/hw/openpic.c
> +++ b/hw/openpic.c
> @@ -1181,41 +1181,17 @@ static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src)
>      qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
>  }
>  
> -qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus,
> +qemu_irq *openpic_init (MemoryRegion **pmem, int nb_cpus,
>                          qemu_irq **irqs, qemu_irq irq_out)

Here a reindentation (space) would've been nice.

>  {
>      openpic_t *opp;
> -    uint8_t *pci_conf;
>      int i, m;
>  
>      /* XXX: for now, only one CPU is supported */
>      if (nb_cpus != 1)
>          return NULL;
> -    if (bus) {
> -        opp = (openpic_t *)pci_register_device(bus, "OpenPIC", sizeof(openpic_t),
> -                                               -1, NULL, NULL);
> -        pci_conf = opp->pci_dev.config;
> -        pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_IBM);
> -        pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_IBM_OPENPIC2);
> -        pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER); // FIXME?
> -        pci_conf[0x3d] = 0x00; // no interrupt pin

I'm not too fond of losing PCI device infos from dead code, but
registering an unused PCIDeviceInfo doesn't seem right either...

AFAIU this function implements a PCI and a non-PCI version of the
device. The PCI version is unused and is now being ripped out.

> -
> -        memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000);
> -#if 0 // Don't implement ISU for now
> -        opp_io_memory = cpu_register_io_memory(openpic_src_read,
> -                                               openpic_src_write, NULL
> -                                               DEVICE_NATIVE_ENDIAN);
> -        cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2),
> -                                     opp_io_memory);
> -#endif
> -
> -        /* Register I/O spaces */
> -        pci_register_bar(&opp->pci_dev, 0,
> -                         PCI_BASE_ADDRESS_SPACE_MEMORY, &opp->mem);
> -    } else {
> -        opp = g_malloc0(sizeof(openpic_t));
> -        memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000);
> -    }
> +    opp = g_malloc0(sizeof(openpic_t));

Ugh. But just moved around.
(More non-qdev'ified code lurking in that file.)

> +    memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000);
>  
>      //    isu_base &= 0xFFFC0000;
>      opp->nb_cpus = nb_cpus;
> diff --git a/hw/openpic.h b/hw/openpic.h
> index 715f084..8556030 100644
> --- a/hw/openpic.h
> +++ b/hw/openpic.h
> @@ -11,7 +11,7 @@ enum {
>      OPENPIC_OUTPUT_NB,
>  };
>  
> -qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus,
> +qemu_irq *openpic_init (MemoryRegion **pmem, int nb_cpus,
>                          qemu_irq **irqs, qemu_irq irq_out);

Space.

>  qemu_irq *mpic_init (MemoryRegion *address_space, target_phys_addr_t base,
>                       int nb_cpus, qemu_irq **irqs, qemu_irq irq_out);
> diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
> index a746c9c..506187b 100644
> --- a/hw/ppc_newworld.c
> +++ b/hw/ppc_newworld.c
> @@ -311,7 +311,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
>              exit(1);
>          }
>      }
> -    pic = openpic_init(NULL, &pic_mem, smp_cpus, openpic_irqs, NULL);
> +    pic = openpic_init(&pic_mem, smp_cpus, openpic_irqs, NULL);
>      if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
>          /* 970 gets a U3 bus */
>          pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io());

Anyway, to keep moving forward,

Reviewed-by: Andreas Färber <afaerber@suse.de>

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 04/28] qom: add the base Object class (v2)
  2012-01-25 21:37     ` Anthony Liguori
  2012-01-26  7:43       ` Paolo Bonzini
@ 2012-01-27 15:05       ` Andreas Färber
  2012-01-27 15:42         ` Anthony Liguori
  1 sibling, 1 reply; 77+ messages in thread
From: Andreas Färber @ 2012-01-27 15:05 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

Am 25.01.2012 22:37, schrieb Anthony Liguori:
> On 01/25/2012 03:30 PM, Andreas Färber wrote:
>> Am 24.01.2012 20:32, schrieb Anthony Liguori:
>>> This class provides the main building block for QEMU Object Model and is
>>> extensively documented in the header file.  It is largely inspired by
>>> GObject.
>>>
>>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>>> ---
>>> v1 ->  v2
>>>   - remove printf() in type registration
>>>   - fix typo in comment (Paolo)
>>>   - make Interface private
>>>   - move object into a new directory and move header into include/qemu/
>>
>> Some of us had expressed concerns over introducing include/. Any
>> particular reason you're doing it still?
> 
> Because it's a great idea and I thought everyone loved it?
> 
> Can you point me to the concerns raised, I'll go back and look.  I
> didn't think it was contentious...

Can't find it right now (stupid search keyword!) but I remember having a
discussion around whether these are actually "public" APIs because to
date we have always claimed that all APIs are internal and no guarantees
are made. IMO moving headers to an include/ dir marks a change of that
policy because header in include/ usually get installed alongside a
library so if we do it we should do it conciously.

Thing is, headers that are private to one part of code are public to
another. It's not black and white. E.g., hw -> IDE -> AHCI -> ICH9.
Whenever there's multiple subclasses code needs to be shared; it
shouldn't usually be poked at from the outside though in favor of
qdev/QOM properties.

Personally, I find it more handy to find pci_dec.c and pci_dec.h in the
same directory in Nautilus/gedit/whatever (but bad example because I'm
working on making that header go away). On the other hand compared to
like r955 we have seen a huge inflation in hw/ files.
I can live with it either way, and as Paolo says, it can easily be
changed later with git-mv. And #include "qemu/foo.h" sounds fair.

For these new "public" headers I'd be interested in finding a solution
where we can all easily collaborate on the documentation though. Right
now we need to trust you to get the markup right.

Andreas

> To summarize my rationale for it:
> 
>  1) It avoids all of the non-sense with conflicting system headers
> (because we -Iinclude and the headers live in include/qemu)
> 
>  2) It establishes what are public functions for use in other parts of
> qemu vs. private headers (which we currently use based on ad-hoc naming
> schemes like block_int.h).
> 
>  3) I think the kernel serves as an existence proof that this method to
> manage headers works really well in practice.
> 
> Regards,
> 
> Anthony Liguori

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 04/28] qom: add the base Object class (v2)
  2012-01-27 15:05       ` Andreas Färber
@ 2012-01-27 15:42         ` Anthony Liguori
  2012-01-27 15:43           ` Andreas Färber
  0 siblings, 1 reply; 77+ messages in thread
From: Anthony Liguori @ 2012-01-27 15:42 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 01/27/2012 09:05 AM, Andreas Färber wrote:
> Am 25.01.2012 22:37, schrieb Anthony Liguori:
>> On 01/25/2012 03:30 PM, Andreas Färber wrote:
>>> Am 24.01.2012 20:32, schrieb Anthony Liguori:
>>>> This class provides the main building block for QEMU Object Model and is
>>>> extensively documented in the header file.  It is largely inspired by
>>>> GObject.
>>>>
>>>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>>>> ---
>>>> v1 ->   v2
>>>>    - remove printf() in type registration
>>>>    - fix typo in comment (Paolo)
>>>>    - make Interface private
>>>>    - move object into a new directory and move header into include/qemu/
>>>
>>> Some of us had expressed concerns over introducing include/. Any
>>> particular reason you're doing it still?
>>
>> Because it's a great idea and I thought everyone loved it?
>>
>> Can you point me to the concerns raised, I'll go back and look.  I
>> didn't think it was contentious...
>
> Can't find it right now (stupid search keyword!)

No problem.

> but I remember having a
> discussion around whether these are actually "public" APIs because to
> date we have always claimed that all APIs are internal and no guarantees
> are made. IMO moving headers to an include/ dir marks a change of that
> policy because header in include/ usually get installed alongside a
> library so if we do it we should do it conciously.
>
> Thing is, headers that are private to one part of code are public to
> another. It's not black and white. E.g., hw ->  IDE ->  AHCI ->  ICH9.
> Whenever there's multiple subclasses code needs to be shared; it
> shouldn't usually be poked at from the outside though in favor of
> qdev/QOM properties.
>
> Personally, I find it more handy to find pci_dec.c and pci_dec.h in the
> same directory in Nautilus/gedit/whatever (but bad example because I'm
> working on making that header go away). On the other hand compared to
> like r955 we have seen a huge inflation in hw/ files.
> I can live with it either way, and as Paolo says, it can easily be
> changed later with git-mv. And #include "qemu/foo.h" sounds fair.

When I think of include/, I think of "internally public" headers.  IOW, things 
that are meant to be shared in other parts of QEMU.  For instance, something 
like qemu-queue.h.

In fact, there are 25 header files in $SRCDIR that are in the form qemu-$file.h. 
  They could (and should) probably be moved to include/qemu/$file.h

As we introduce more directory structure, having a single include directory will 
be very handy.  For instance, pci_dec.c may move to drivers/ppc/pci_dec.c.  But 
having pci_dec.h in include/qemu means that we don't have to worry about very 
long #include paths.

Regards,

Anthony Liguori

>
> For these new "public" headers I'd be interested in finding a solution
> where we can all easily collaborate on the documentation though. Right
> now we need to trust you to get the markup right.
>
> Andreas
>
>> To summarize my rationale for it:
>>
>>   1) It avoids all of the non-sense with conflicting system headers
>> (because we -Iinclude and the headers live in include/qemu)
>>
>>   2) It establishes what are public functions for use in other parts of
>> qemu vs. private headers (which we currently use based on ad-hoc naming
>> schemes like block_int.h).
>>
>>   3) I think the kernel serves as an existence proof that this method to
>> manage headers works really well in practice.
>>
>> Regards,
>>
>> Anthony Liguori
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH 04/28] qom: add the base Object class (v2)
  2012-01-27 15:42         ` Anthony Liguori
@ 2012-01-27 15:43           ` Andreas Färber
  0 siblings, 0 replies; 77+ messages in thread
From: Andreas Färber @ 2012-01-27 15:43 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

Am 27.01.2012 16:42, schrieb Anthony Liguori:
> On 01/27/2012 09:05 AM, Andreas Färber wrote:
>> Am 25.01.2012 22:37, schrieb Anthony Liguori:
>>> On 01/25/2012 03:30 PM, Andreas Färber wrote:
>>>> Am 24.01.2012 20:32, schrieb Anthony Liguori:
>>>>> This class provides the main building block for QEMU Object Model
>>>>> and is
>>>>> extensively documented in the header file.  It is largely inspired by
>>>>> GObject.
>>>>>
>>>>> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>>>>> ---
>>>>> v1 ->   v2
>>>>>    - remove printf() in type registration
>>>>>    - fix typo in comment (Paolo)
>>>>>    - make Interface private
>>>>>    - move object into a new directory and move header into
>>>>> include/qemu/
>>>>
>>>> Some of us had expressed concerns over introducing include/. Any
>>>> particular reason you're doing it still?
>>>
>>> Because it's a great idea and I thought everyone loved it?
>>>
>>> Can you point me to the concerns raised, I'll go back and look.  I
>>> didn't think it was contentious...
>>
>> Can't find it right now (stupid search keyword!)
> 
> No problem.
> 
>> but I remember having a
>> discussion around whether these are actually "public" APIs because to
>> date we have always claimed that all APIs are internal and no guarantees
>> are made. IMO moving headers to an include/ dir marks a change of that
>> policy because header in include/ usually get installed alongside a
>> library so if we do it we should do it conciously.
>>
>> Thing is, headers that are private to one part of code are public to
>> another. It's not black and white. E.g., hw ->  IDE ->  AHCI ->  ICH9.
>> Whenever there's multiple subclasses code needs to be shared; it
>> shouldn't usually be poked at from the outside though in favor of
>> qdev/QOM properties.
>>
>> Personally, I find it more handy to find pci_dec.c and pci_dec.h in the
>> same directory in Nautilus/gedit/whatever (but bad example because I'm
>> working on making that header go away). On the other hand compared to
>> like r955 we have seen a huge inflation in hw/ files.
>> I can live with it either way, and as Paolo says, it can easily be
>> changed later with git-mv. And #include "qemu/foo.h" sounds fair.
> 
> When I think of include/, I think of "internally public" headers.  IOW,
> things that are meant to be shared in other parts of QEMU.  For
> instance, something like qemu-queue.h.
> 
> In fact, there are 25 header files in $SRCDIR that are in the form
> qemu-$file.h.  They could (and should) probably be moved to
> include/qemu/$file.h

Okay, agree.

Regards,
Andreas

> 
> As we introduce more directory structure, having a single include
> directory will be very handy.  For instance, pci_dec.c may move to
> drivers/ppc/pci_dec.c.  But having pci_dec.h in include/qemu means that
> we don't have to worry about very long #include paths.
> 
> Regards,
> 
> Anthony Liguori
> 
>>
>> For these new "public" headers I'd be interested in finding a solution
>> where we can all easily collaborate on the documentation though. Right
>> now we need to trust you to get the markup right.
>>
>> Andreas
>>
>>> To summarize my rationale for it:
>>>
>>>   1) It avoids all of the non-sense with conflicting system headers
>>> (because we -Iinclude and the headers live in include/qemu)
>>>
>>>   2) It establishes what are public functions for use in other parts of
>>> qemu vs. private headers (which we currently use based on ad-hoc naming
>>> schemes like block_int.h).
>>>
>>>   3) I think the kernel serves as an existence proof that this method to
>>> manage headers works really well in practice.
>>>
>>> Regards,
>>>
>>> Anthony Liguori
>>
> 


-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev
  2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
                   ` (29 preceding siblings ...)
  2012-01-25 18:31 ` Blue Swirl
@ 2012-01-27 17:34 ` Anthony Liguori
  30 siblings, 0 replies; 77+ messages in thread
From: Anthony Liguori @ 2012-01-27 17:34 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On 01/24/2012 01:32 PM, Anthony Liguori wrote:
> This series makes qdev a proper Object and converts qdev's type inheritance to
> QOM inheritance.
>
> The first half of the series are manual cleanups/refactorings.  The second half
> is mostly scripted conversion, separated out into reviewable and bisectable
> chunks.
>
> I've tested this series extensively for the pc target including bisectability.
> I have not tested any other targets yet so your mileage may vary.
>
> Since the original RFC, I've fixed any of the not-for-upstream issues.  This
> also includes some uni-north patches that are in ppc-next.
>
> Paolo and Andreas have asked that I declare a date when I'll merge this so that
> people can be prepared for the rebase fall out.  I will merge this on Friday
> unless there is a major problem found in review.

Applied (with the few changes requested).

Even anyone encounters a problem rebasing after this series, please feel free to 
poke me for help.  There should be ample examples of how to use the new 
infrastructure too.

Regards,

Anthony Liguori

>
> This is also available at:
>
> https://github.com/aliguori/qemu/tree/qom-upstream.10
>
> For full context, the whole tree is located at:
>
> https://github.com/aliguori/qemu/commits/qom-rebase.7
>
> git diffstat origin/master HEAD
>   Makefile                   |    2
>   Makefile.hw                |    1
>   Makefile.objs              |    3
>   Makefile.target            |    2
>   configure                  |    2
>   hw/9pfs/virtio-9p-device.c |   44 ++--
>   hw/a9mpcore.c              |   21 +
>   hw/ac97.c                  |   39 ++-
>   hw/acpi_piix4.c            |   59 +++--
>   hw/ads7846.c               |   17 +
>   hw/alpha_typhoon.c         |   17 +
>   hw/apb_pci.c               |   71 ++++--
>   hw/apic.c                  |   21 +
>   hw/apic_common.c           |   88 +++++---
>   hw/apic_internal.h         |   32 +-
>   hw/applesmc.c              |   18 +
>   hw/arm11mpcore.c           |   68 +++---
>   hw/arm_l2x0.c              |   25 +-
>   hw/arm_mptimer.c           |   23 +-
>   hw/arm_sysctl.c            |   31 +-
>   hw/arm_timer.c             |   46 +++-
>   hw/armv7m.c                |   25 +-
>   hw/armv7m_nvic.c           |   21 +
>   hw/bitbang_i2c.c           |   17 +
>   hw/bonito.c                |   47 ++--
>   hw/ccid-card-emulated.c    |   27 +-
>   hw/ccid-card-passthru.c    |   27 +-
>   hw/ccid.h                  |   28 +-
>   hw/cirrus_vga.c            |   50 ++--
>   hw/container.c             |   17 +
>   hw/cs4231.c                |   27 +-
>   hw/cs4231a.c               |   20 +
>   hw/debugcon.c              |   16 +
>   hw/dec_pci.c               |   74 ++++--
>   hw/ds1225y.c               |   29 +-
>   hw/ds1338.c                |   31 +-
>   hw/e1000.c                 |   45 ++--
>   hw/eccmemctl.c             |   29 +-
>   hw/eepro100.c              |  202 +++++++++++-------
>   hw/empty_slot.c            |   15 +
>   hw/es1370.c                |   36 +--
>   hw/escc.c                  |   43 ++-
>   hw/esp.c                   |   27 +-
>   hw/etraxfs_eth.c           |   33 +--
>   hw/etraxfs_pic.c           |   25 +-
>   hw/etraxfs_ser.c           |   17 +
>   hw/etraxfs_timer.c         |   16 +
>   hw/fdc.c                   |   84 +++++--
>   hw/fw_cfg.c                |   33 +--
>   hw/g364fb.c                |   33 +--
>   hw/grackle_pci.c           |   44 ++--
>   hw/grlib_apbuart.c         |   25 +-
>   hw/grlib_gptimer.c         |   31 +-
>   hw/grlib_irqmp.c           |   29 +-
>   hw/gt64xxx.c               |   39 ++-
>   hw/gus.c                   |   20 +
>   hw/hda-audio.c             |   60 +++--
>   hw/hpet.c                  |   33 +--
>   hw/i2c.c                   |  111 +++++++---
>   hw/i2c.h                   |   52 ++--
>   hw/i82374.c                |   19 +
>   hw/i82378.c                |   31 +-
>   hw/i8254.c                 |   22 +-
>   hw/i8259.c                 |   15 +
>   hw/i8259_common.c          |   45 ++--
>   hw/i8259_internal.h        |   27 +-
>   hw/ide/cmd646.c            |   41 ++-
>   hw/ide/ich.c               |   37 +--
>   hw/ide/internal.h          |   20 +
>   hw/ide/isa.c               |   20 +
>   hw/ide/piix.c              |   91 +++++---
>   hw/ide/qdev.c              |  111 ++++++----
>   hw/ide/via.c               |   27 +-
>   hw/integratorcp.c          |   40 ++-
>   hw/intel-hda.c             |   91 +++++---
>   hw/intel-hda.h             |   26 +-
>   hw/ioapic.c                |   17 +
>   hw/ioapic_common.c         |   49 +++-
>   hw/ioapic_internal.h       |   26 +-
>   hw/ioh3420.c               |   59 +++--
>   hw/isa-bus.c               |   57 +++--
>   hw/isa.h                   |   23 +-
>   hw/ivshmem.c               |   47 ++--
>   hw/kvm/apic.c              |   19 +
>   hw/kvm/clock.c             |   19 +
>   hw/kvm/i8259.c             |   19 +
>   hw/kvm/ioapic.c            |   23 +-
>   hw/lan9118.c               |   31 +-
>   hw/lance.c                 |   33 +--
>   hw/lm32_juart.c            |   19 +
>   hw/lm32_pic.c              |   19 +
>   hw/lm32_sys.c              |   29 +-
>   hw/lm32_timer.c            |   31 +-
>   hw/lm32_uart.c             |   19 +
>   hw/lm832x.c                |   33 +--
>   hw/lsi53c895a.c            |   33 +--
>   hw/m48t59.c                |   51 +++-
>   hw/macio.c                 |   50 +++-
>   hw/marvell_88w8618_audio.c |   35 +--
>   hw/max111x.c               |   34 ++-
>   hw/max7310.c               |   35 +--
>   hw/mc146818rtc.c           |   22 +-
>   hw/milkymist-ac97.c        |   19 +
>   hw/milkymist-hpdmc.c       |   19 +
>   hw/milkymist-memcard.c     |   19 +
>   hw/milkymist-minimac2.c    |   37 ++-
>   hw/milkymist-pfpu.c        |   19 +
>   hw/milkymist-softusb.c     |   43 ++-
>   hw/milkymist-sysctl.c      |   43 ++-
>   hw/milkymist-tmu2.c        |   19 +
>   hw/milkymist-uart.c        |   19 +
>   hw/milkymist-vgafb.c       |   31 +-
>   hw/mips_malta.c            |   19 +
>   hw/mipsnet.c               |   33 +--
>   hw/mpc8544_guts.c          |   15 +
>   hw/mst_fpga.c              |   19 +
>   hw/musicpal.c              |  153 ++++++++++----
>   hw/nand.c                  |   33 +--
>   hw/ne2000-isa.c            |   18 +
>   hw/ne2000.c                |   37 ++-
>   hw/omap_gpio.c             |   70 ++++--
>   hw/omap_intc.c             |   62 +++--
>   hw/onenand.c               |   35 ++-
>   hw/opencores_eth.c         |   31 +-
>   hw/openpic.c               |   30 --
>   hw/openpic.h               |    2
>   hw/parallel.c              |   16 +
>   hw/pc.c                    |   20 +
>   hw/pci.c                   |  140 +++++-------
>   hw/pci.h                   |   80 +++----
>   hw/pci_bridge.c            |    2
>   hw/pcie.c                  |    2
>   hw/pckbd.c                 |   18 +
>   hw/pcnet-pci.c             |   39 ++-
>   hw/pcnet.c                 |    2
>   hw/piix4.c                 |   35 +--
>   hw/piix_pci.c              |  126 +++++++----
>   hw/pl011.c                 |   36 ++-
>   hw/pl022.c                 |   15 +
>   hw/pl031.c                 |   19 +
>   hw/pl041.c                 |   34 +--
>   hw/pl050.c                 |   34 ++-
>   hw/pl061.c                 |   34 ++-
>   hw/pl080.c                 |   38 ++-
>   hw/pl110.c                 |   57 +++--
>   hw/pl181.c                 |   23 +-
>   hw/pl190.c                 |   21 +
>   hw/ppc4xx_pci.c            |   38 ++-
>   hw/ppc_newworld.c          |    2
>   hw/ppce500_pci.c           |   38 ++-
>   hw/ppce500_spin.c          |   15 +
>   hw/prep_pci.c              |   52 ++--
>   hw/pxa2xx.c                |   96 ++++++--
>   hw/pxa2xx_dma.c            |   29 +-
>   hw/pxa2xx_gpio.c           |   29 +-
>   hw/pxa2xx_pic.c            |   19 +
>   hw/pxa2xx_timer.c          |   66 +++---
>   hw/qdev-properties.c       |   20 -
>   hw/qdev.c                  |  123 ++++++++---
>   hw/qdev.h                  |   40 +++
>   hw/qxl.c                   |   66 +++---
>   hw/realview.c              |   15 +
>   hw/realview_gic.c          |   16 +
>   hw/rtl8139.c               |   43 ++-
>   hw/s390-virtio-bus.c       |  110 +++++++---
>   hw/sb16.c                  |   20 +
>   hw/sbi.c                   |   19 +
>   hw/scsi-bus.c              |   95 ++++++--
>   hw/scsi-disk.c             |  159 ++++++++------
>   hw/scsi-generic.c          |   29 +-
>   hw/scsi.h                  |   31 +-
>   hw/serial.c                |   18 +
>   hw/sga.c                   |   15 -
>   hw/sh_pci.c                |   37 ++-
>   hw/slavio_intctl.c         |   19 +
>   hw/slavio_misc.c           |   34 ++-
>   hw/slavio_timer.c          |   29 +-
>   hw/smbus.c                 |   85 +++++--
>   hw/smbus.h                 |   42 ++-
>   hw/smbus_eeprom.c          |   27 +-
>   hw/smc91c111.c             |   31 +-
>   hw/spapr_llan.c            |   41 ++-
>   hw/spapr_pci.c             |   31 ++
>   hw/spapr_vio.c             |   72 ++++--
>   hw/spapr_vio.h             |   35 ++-
>   hw/spapr_vscsi.c           |   37 ++-
>   hw/spapr_vty.c             |   37 ++-
>   hw/sparc32_dma.c           |   31 +-
>   hw/spitz.c                 |   94 +++++---
>   hw/ssd0303.c               |   33 +--
>   hw/ssd0323.c               |   17 +
>   hw/ssi-sd.c                |   17 +
>   hw/ssi.c                   |   23 +-
>   hw/ssi.h                   |   18 +
>   hw/stellaris.c             |   65 +++++-
>   hw/stellaris_enet.c        |   27 +-
>   hw/strongarm.c             |  124 +++++++----
>   hw/sun4c_intctl.c          |   19 +
>   hw/sun4m.c                 |   78 +++++--
>   hw/sun4m_iommu.c           |   29 +-
>   hw/sun4u.c                 |   71 ++++--
>   hw/sysbus.c                |   40 ++-
>   hw/sysbus.h                |   25 +-
>   hw/tcx.c                   |   37 ++-
>   hw/tmp105.c                |   37 ++-
>   hw/tosa.c                  |   50 ++--
>   hw/tusb6010.c              |   17 +
>   hw/twl92230.c              |   35 +--
>   hw/unin_pci.c              |  204 +++++++++++++-----
>   hw/usb-audio.c             |   38 ++-
>   hw/usb-bt.c                |   33 +--
>   hw/usb-bus.c               |  190 +++++++++++++----
>   hw/usb-ccid.c              |  114 +++++++---
>   hw/usb-desc.c              |   22 +-
>   hw/usb-ehci.c              |   63 +++--
>   hw/usb-hid.c               |  108 +++++-----
>   hw/usb-hub.c               |   35 +--
>   hw/usb-msd.c               |   41 ++-
>   hw/usb-net.c               |   43 ++-
>   hw/usb-ohci.c              |   58 +++--
>   hw/usb-serial.c            |   74 +++---
>   hw/usb-uhci.c              |  189 +++++++++++------
>   hw/usb-wacom.c             |   36 +--
>   hw/usb-xhci.c              |   37 ++-
>   hw/usb.c                   |   24 --
>   hw/usb.h                   |   50 +++-
>   hw/versatile_pci.c         |   53 +++-
>   hw/versatilepb.c           |   19 +
>   hw/vga-isa.c               |   18 +
>   hw/vga-pci.c               |   27 +-
>   hw/virtio-console.c        |   69 +++---
>   hw/virtio-net.c            |    2
>   hw/virtio-pci.c            |  210 +++++++++++--------
>   hw/virtio-serial-bus.c     |   68 +++---
>   hw/virtio-serial.h         |   81 ++++---
>   hw/vmmouse.c               |   22 +-
>   hw/vmport.c                |   16 +
>   hw/vmware_vga.c            |   34 +--
>   hw/vt82c686.c              |  120 ++++++-----
>   hw/wdt_i6300esb.c          |   33 +--
>   hw/wdt_ib700.c             |   18 +
>   hw/wm8750.c                |   37 ++-
>   hw/xen_platform.c          |   34 +--
>   hw/xilinx_axidma.c         |   27 +-
>   hw/xilinx_axienet.c        |   35 ++-
>   hw/xilinx_ethlite.c        |   31 +-
>   hw/xilinx_intc.c           |   25 +-
>   hw/xilinx_timer.c          |   27 +-
>   hw/xilinx_uartlite.c       |   16 +
>   hw/xio3130_downstream.c    |   59 +++--
>   hw/xio3130_upstream.c      |   53 ++--
>   hw/z2.c                    |   52 +++-
>   hw/zaurus.c                |   27 +-
>   include/qemu/object.h      |  436 ++++++++++++++++++++++++++++++++++++++++
>   qom/Makefile               |    1
>   qom/object.c               |  485 +++++++++++++++++++++++++++++++++++++++++++++
>   usb-bsd.c                  |   29 +-
>   usb-linux.c                |   37 +--
>   usb-redir.c                |   33 +--
>   259 files changed, 7764 insertions(+), 3755 deletions(-)
>
>
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [Qemu-devel] [PATCH] macio: Convert to qdev
  2012-01-26 23:17   ` [Qemu-devel] [PATCH] macio: Convert " Andreas Färber
@ 2012-03-06 22:56     ` Alexander Graf
  0 siblings, 0 replies; 77+ messages in thread
From: Alexander Graf @ 2012-03-06 22:56 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Anthony Liguori, Laurent Vivier, qemu-devel, qemu-ppc,
	Avi Kivity, Richard Henderson


On 27.01.2012, at 00:17, Andreas Färber wrote:

> From: Anthony Liguori <aliguori@us.ibm.com>
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> 
> Split macio into two PCIDevices with declarative device ID,
> macio-oldworld and macio-newworld. Drop is_oldworld state in favor
> of two separate init functions and deferred creation.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> Cc: Alexander Graf <agraf@suse.de>
> ---
> Anthony, I've extended and tested your patch, please consider using this version.
> (In that case feel free to move your Signed-off-by down.)
> 
> Alex, please ack. We could inline macio_init() and get rid of is_oldworld but
> would have to move MacIOState into ppc_mac.h then.

I don't see anything obviously wrong with the patch, but this is the type of thing that you just have to shove through testing and if it works, it works :).


Alex

^ permalink raw reply	[flat|nested] 77+ messages in thread

end of thread, other threads:[~2012-03-06 22:56 UTC | newest]

Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-24 19:32 [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Anthony Liguori
2012-01-24 19:32 ` [Qemu-devel] [PATCH 01/28] macio: convert " Anthony Liguori
2012-01-26 23:17   ` [Qemu-devel] [PATCH] macio: Convert " Andreas Färber
2012-03-06 22:56     ` Alexander Graf
2012-01-24 19:32 ` [Qemu-devel] [PATCH 02/28] openpic: remove dead code to make a PCI device version Anthony Liguori
2012-01-26 23:57   ` Andreas Färber
2012-01-24 19:32 ` [Qemu-devel] [PATCH 03/28] pci: call reset unconditionally Anthony Liguori
2012-01-25 12:42   ` Michael S. Tsirkin
2012-01-25 13:28     ` Anthony Liguori
2012-01-24 19:32 ` [Qemu-devel] [PATCH 04/28] qom: add the base Object class (v2) Anthony Liguori
2012-01-25 21:30   ` Andreas Färber
2012-01-25 21:37     ` Anthony Liguori
2012-01-26  7:43       ` Paolo Bonzini
2012-01-27 15:05       ` Andreas Färber
2012-01-27 15:42         ` Anthony Liguori
2012-01-27 15:43           ` Andreas Färber
2012-01-24 19:32 ` [Qemu-devel] [PATCH 05/28] qdev: integrate with QEMU Object Model (v2) Anthony Liguori
2012-01-24 19:32 ` [Qemu-devel] [PATCH 06/28] qdev: move qdev->info to class Anthony Liguori
2012-01-24 19:32 ` [Qemu-devel] [PATCH 07/28] qdev: don't access name through info Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 08/28] qdev: use a wrapper to access reset and promote reset to a class method Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 09/28] qdev: add a interface to register subclasses Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 10/28] qdev: add class_init to DeviceInfo Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 11/28] qdev: prepare source tree for code conversion Anthony Liguori
2012-01-26 17:35   ` [Qemu-devel] [PATCH 1/3] es1370: Drop dead code Andreas Färber
2012-01-26 17:35     ` [Qemu-devel] [PATCH 2/3] marvell_88w8618_audio: Use DEFINE_PROP_* macros Andreas Färber
2012-01-26 17:35     ` [Qemu-devel] [PATCH 3/3] qdev: prepare source tree for code conversion Andreas Färber
2012-01-24 19:33 ` [Qemu-devel] [PATCH 12/28] isa: pic: convert to QEMU Object Model Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 13/28] usb: " Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 14/28] ccid: " Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 15/28] ssi: " Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 16/28] i2c: rename i2c_slave -> I2CSlave Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 17/28] i2c: smbus: convert to QEMU Object Model Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 18/28] hda-codec: " Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 19/28] ide: " Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 20/28] scsi: " Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 21/28] spapr: convert to QEMU Object Model (v2) Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 22/28] virtio-serial: convert to QEMU Object Model Anthony Liguori
2012-01-24 19:59   ` Amit Shah
2012-01-24 20:13     ` Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 23/28] unin_pci: Clean up qdev names Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 24/28] unin_pci: Drop duplicate busdev Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 25/28] unin_pci: Drop unused reset handler Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 26/28] pci: convert to QEMU Object Model Anthony Liguori
2012-01-24 19:33   ` Anthony Liguori
2012-01-25 12:41   ` [Qemu-devel] " Michael S. Tsirkin
2012-01-25 12:41     ` Michael S. Tsirkin
2012-01-25 13:34     ` [Qemu-devel] " Anthony Liguori
2012-01-25 13:34       ` Anthony Liguori
2012-01-24 19:33 ` [Qemu-devel] [PATCH 27/28] sysbus: apic: ioapic: " Anthony Liguori
2012-01-24 20:01   ` Jan Kiszka
2012-01-24 20:21     ` Anthony Liguori
2012-01-24 21:01       ` Jan Kiszka
2012-01-24 21:11         ` Anthony Liguori
2012-01-24 21:31           ` Jan Kiszka
2012-01-24 21:53             ` Anthony Liguori
2012-01-24 22:06               ` Jan Kiszka
2012-01-24 23:03                 ` Anthony Liguori
2012-01-25  8:33                   ` Andreas Färber
2012-01-25 12:09                     ` Avi Kivity
2012-01-25 13:02                     ` Paul Brook
2012-01-25 14:25                     ` Anthony Liguori
2012-01-25  8:37                   ` Jan Kiszka
2012-01-25 10:15                     ` Paolo Bonzini
2012-01-25 10:27                       ` Jan Kiszka
2012-01-25 11:15                         ` Paolo Bonzini
2012-01-25 14:00                     ` Anthony Liguori
2012-01-25 14:23                       ` Jan Kiszka
2012-01-25 14:40                         ` Anthony Liguori
2012-01-25 15:18                           ` Andreas Färber
2012-01-25 15:34                           ` Eric Blake
2012-01-24 19:33 ` [Qemu-devel] [PATCH 28/28] virtio-s390: " Anthony Liguori
2012-01-24 23:13 ` [Qemu-devel] [PATCH v3 0/28] qom: add QEMU Object Model type hierarchy to qdev Peter Maydell
2012-01-24 23:16   ` Anthony Liguori
2012-01-25 18:31 ` Blue Swirl
2012-01-25 19:43   ` Anthony Liguori
2012-01-25 20:09     ` Blue Swirl
2012-01-27 17:34 ` Anthony Liguori

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.