All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2)
@ 2012-01-03  0:51 Anthony Liguori
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 01/30] macio: convert to qdev Anthony Liguori
                   ` (29 more replies)
  0 siblings, 30 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Markus Armbruster, Andreas Färber

This is series 2/4 of the QOM refactoring.  These series are divided up based
on the major scripted code conversions.

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 but I am
aware that this breaks mac99 for the powerpc target.  I will fix that before the
next submission.

This is also available at:

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

For full context, the whole tree is located at:

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

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

* [Qemu-devel] [PATCH 01/30] macio: convert to qdev
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
@ 2012-01-03  0:51 ` Anthony Liguori
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 02/30] openpic: remove dead code to make a PCI device version Anthony Liguori
                   ` (28 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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] 50+ messages in thread

* [Qemu-devel] [PATCH 02/30] openpic: remove dead code to make a PCI device version
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 01/30] macio: convert to qdev Anthony Liguori
@ 2012-01-03  0:51 ` Anthony Liguori
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support Anthony Liguori
                   ` (27 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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 8c84f9e..34d81d9 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -309,7 +309,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] 50+ messages in thread

* [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 01/30] macio: convert to qdev Anthony Liguori
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 02/30] openpic: remove dead code to make a PCI device version Anthony Liguori
@ 2012-01-03  0:51 ` Anthony Liguori
  2012-01-05 15:16   ` François Revol
  2012-01-13 10:59   ` Benjamin Herrenschmidt
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 04/30] ppc_prep: convert host bridge to qdev Anthony Liguori
                   ` (26 subsequent siblings)
  29 siblings, 2 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

This board never worked with TCG.  It hasn't been updated since 0.13.0.  I'm
fairly sure hardware doesn't exist anymore that you can run the KVM support
with.

So let's remove it.  It can always be restored later if there is interest again.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 Makefile.target    |    3 +-
 hw/ppc440.c        |  106 ---------------
 hw/ppc440.h        |   21 ---
 hw/ppc440_bamboo.c |  215 -----------------------------
 hw/ppc4xx_pci.c    |  381 ----------------------------------------------------
 hw/virtex_ml507.c  |    1 -
 6 files changed, 1 insertions(+), 726 deletions(-)
 delete mode 100644 hw/ppc440.c
 delete mode 100644 hw/ppc440.h
 delete mode 100644 hw/ppc440_bamboo.c
 delete mode 100644 hw/ppc4xx_pci.c

diff --git a/Makefile.target b/Makefile.target
index 3261383..b8ccf07 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -246,8 +246,7 @@ obj-ppc-$(CONFIG_PSERIES) += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o
 obj-ppc-$(CONFIG_PSERIES) += xics.o spapr_vty.o spapr_llan.o spapr_vscsi.o
 obj-ppc-$(CONFIG_PSERIES) += spapr_pci.o device-hotplug.o pci-hotplug.o
 # PowerPC 4xx boards
-obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
-obj-ppc-y += ppc440.o ppc440_bamboo.o
+obj-ppc-y += ppc4xx_devs.o ppc405_uc.o ppc405_boards.o
 # PowerPC E500 boards
 obj-ppc-y += ppce500_mpc8544ds.o mpc8544_guts.o ppce500_spin.o
 # PowerPC 440 Xilinx ML507 reference board.
diff --git a/hw/ppc440.c b/hw/ppc440.c
deleted file mode 100644
index cd8a95d..0000000
--- a/hw/ppc440.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Qemu PowerPC 440 chip emulation
- *
- * Copyright 2007 IBM Corporation.
- * Authors:
- * 	Jerone Young <jyoung5@us.ibm.com>
- * 	Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
- * 	Hollis Blanchard <hollisb@us.ibm.com>
- *
- * This work is licensed under the GNU GPL license version 2 or later.
- *
- */
-
-#include "hw.h"
-#include "pc.h"
-#include "isa.h"
-#include "ppc.h"
-#include "ppc4xx.h"
-#include "ppc440.h"
-#include "ppc405.h"
-#include "sysemu.h"
-#include "kvm.h"
-
-#define PPC440EP_PCI_CONFIG     0xeec00000
-#define PPC440EP_PCI_INTACK     0xeed00000
-#define PPC440EP_PCI_SPECIAL    0xeed00000
-#define PPC440EP_PCI_REGS       0xef400000
-#define PPC440EP_PCI_IO         0xe8000000
-#define PPC440EP_PCI_IOLEN      0x00010000
-
-#define PPC440EP_SDRAM_NR_BANKS 4
-
-static const unsigned int ppc440ep_sdram_bank_sizes[] = {
-    256<<20, 128<<20, 64<<20, 32<<20, 16<<20, 8<<20, 0
-};
-
-CPUState *ppc440ep_init(MemoryRegion *address_space_mem, ram_addr_t *ram_size,
-                        PCIBus **pcip, const unsigned int pci_irq_nrs[4],
-                        int do_init, const char *cpu_model)
-{
-    MemoryRegion *ram_memories
-        = g_malloc(PPC440EP_SDRAM_NR_BANKS * sizeof(*ram_memories));
-    target_phys_addr_t ram_bases[PPC440EP_SDRAM_NR_BANKS];
-    target_phys_addr_t ram_sizes[PPC440EP_SDRAM_NR_BANKS];
-    CPUState *env;
-    qemu_irq *pic;
-    qemu_irq *irqs;
-    qemu_irq *pci_irqs;
-
-    if (cpu_model == NULL) {
-        cpu_model = "440-Xilinx"; // XXX: should be 440EP
-    }
-    env = cpu_init(cpu_model);
-    if (!env) {
-        fprintf(stderr, "Unable to initialize CPU!\n");
-        exit(1);
-    }
-
-    ppc_dcr_init(env, NULL, NULL);
-
-    /* interrupt controller */
-    irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
-    irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];
-    irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT];
-    pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
-
-    /* SDRAM controller */
-    memset(ram_bases, 0, sizeof(ram_bases));
-    memset(ram_sizes, 0, sizeof(ram_sizes));
-    *ram_size = ppc4xx_sdram_adjust(*ram_size, PPC440EP_SDRAM_NR_BANKS,
-                                    ram_memories,
-                                    ram_bases, ram_sizes,
-                                    ppc440ep_sdram_bank_sizes);
-    /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */
-    ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_memories,
-                      ram_bases, ram_sizes, do_init);
-
-    /* PCI */
-    pci_irqs = g_malloc(sizeof(qemu_irq) * 4);
-    pci_irqs[0] = pic[pci_irq_nrs[0]];
-    pci_irqs[1] = pic[pci_irq_nrs[1]];
-    pci_irqs[2] = pic[pci_irq_nrs[2]];
-    pci_irqs[3] = pic[pci_irq_nrs[3]];
-    *pcip = ppc4xx_pci_init(env, pci_irqs,
-                            PPC440EP_PCI_CONFIG,
-                            PPC440EP_PCI_INTACK,
-                            PPC440EP_PCI_SPECIAL,
-                            PPC440EP_PCI_REGS);
-    if (!*pcip)
-        printf("couldn't create PCI controller!\n");
-
-    isa_mmio_init(PPC440EP_PCI_IO, PPC440EP_PCI_IOLEN);
-
-    if (serial_hds[0] != NULL) {
-        serial_mm_init(address_space_mem, 0xef600300, 0, pic[0],
-                       PPC_SERIAL_MM_BAUDBASE, serial_hds[0],
-                       DEVICE_BIG_ENDIAN);
-    }
-    if (serial_hds[1] != NULL) {
-        serial_mm_init(address_space_mem, 0xef600400, 0, pic[1],
-                       PPC_SERIAL_MM_BAUDBASE, serial_hds[1],
-                       DEVICE_BIG_ENDIAN);
-    }
-
-    return env;
-}
diff --git a/hw/ppc440.h b/hw/ppc440.h
deleted file mode 100644
index 9c27c36..0000000
--- a/hw/ppc440.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Qemu PowerPC 440 board emualtion
- *
- * Copyright 2007 IBM Corporation.
- * Authors: Jerone Young <jyoung5@us.ibm.com>
- * 	    Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
- *
- * This work is licensed under the GNU GPL licence version 2 or later
- *
- */
-
-#ifndef QEMU_PPC440_H
-#define QEMU_PPC440_H
-
-#include "hw.h"
-
-CPUState *ppc440ep_init(MemoryRegion *address_space, ram_addr_t *ram_size,
-                        PCIBus **pcip, const unsigned int pci_irq_nrs[4],
-                        int do_init, const char *cpu_model);
-
-#endif
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
deleted file mode 100644
index b734e3a..0000000
--- a/hw/ppc440_bamboo.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Qemu PowerPC 440 Bamboo board emulation
- *
- * Copyright 2007 IBM Corporation.
- * Authors:
- * 	Jerone Young <jyoung5@us.ibm.com>
- * 	Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
- * 	Hollis Blanchard <hollisb@us.ibm.com>
- *
- * This work is licensed under the GNU GPL license version 2 or later.
- *
- */
-
-#include "config.h"
-#include "qemu-common.h"
-#include "net.h"
-#include "hw.h"
-#include "pci.h"
-#include "boards.h"
-#include "ppc440.h"
-#include "kvm.h"
-#include "kvm_ppc.h"
-#include "device_tree.h"
-#include "loader.h"
-#include "elf.h"
-#include "exec-memory.h"
-
-#define BINARY_DEVICE_TREE_FILE "bamboo.dtb"
-
-/* from u-boot */
-#define KERNEL_ADDR  0x1000000
-#define FDT_ADDR     0x1800000
-#define RAMDISK_ADDR 0x1900000
-
-static int bamboo_load_device_tree(target_phys_addr_t addr,
-                                     uint32_t ramsize,
-                                     target_phys_addr_t initrd_base,
-                                     target_phys_addr_t initrd_size,
-                                     const char *kernel_cmdline)
-{
-    int ret = -1;
-#ifdef CONFIG_FDT
-    uint32_t mem_reg_property[] = { 0, 0, ramsize };
-    char *filename;
-    int fdt_size;
-    void *fdt;
-    uint32_t tb_freq = 400000000;
-    uint32_t clock_freq = 400000000;
-
-    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
-    if (!filename) {
-        goto out;
-    }
-    fdt = load_device_tree(filename, &fdt_size);
-    g_free(filename);
-    if (fdt == NULL) {
-        goto out;
-    }
-
-    /* Manipulate device tree in memory. */
-
-    ret = qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
-                               sizeof(mem_reg_property));
-    if (ret < 0)
-        fprintf(stderr, "couldn't set /memory/reg\n");
-
-    ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
-                                    initrd_base);
-    if (ret < 0)
-        fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
-
-    ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
-                                    (initrd_base + initrd_size));
-    if (ret < 0)
-        fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
-
-    ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
-                                      kernel_cmdline);
-    if (ret < 0)
-        fprintf(stderr, "couldn't set /chosen/bootargs\n");
-
-    /* Copy data from the host device tree into the guest. Since the guest can
-     * directly access the timebase without host involvement, we must expose
-     * the correct frequencies. */
-    if (kvm_enabled()) {
-        tb_freq = kvmppc_get_tbfreq();
-        clock_freq = kvmppc_get_clockfreq();
-    }
-
-    qemu_devtree_setprop_cell(fdt, "/cpus/cpu@0", "clock-frequency",
-                              clock_freq);
-    qemu_devtree_setprop_cell(fdt, "/cpus/cpu@0", "timebase-frequency",
-                              tb_freq);
-
-    ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
-    g_free(fdt);
-
-out:
-#endif
-
-    return ret;
-}
-
-static void bamboo_init(ram_addr_t ram_size,
-                        const char *boot_device,
-                        const char *kernel_filename,
-                        const char *kernel_cmdline,
-                        const char *initrd_filename,
-                        const char *cpu_model)
-{
-    unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 };
-    MemoryRegion *address_space_mem = get_system_memory();
-    PCIBus *pcibus;
-    CPUState *env;
-    uint64_t elf_entry;
-    uint64_t elf_lowaddr;
-    target_phys_addr_t entry = 0;
-    target_phys_addr_t loadaddr = 0;
-    target_long initrd_size = 0;
-    int success;
-    int i;
-
-    /* Setup CPU. */
-    env = ppc440ep_init(address_space_mem, &ram_size, &pcibus,
-                        pci_irq_nrs, 1, cpu_model);
-
-    if (pcibus) {
-        /* Register network interfaces. */
-        for (i = 0; i < nb_nics; i++) {
-            /* There are no PCI NICs on the Bamboo board, but there are
-             * PCI slots, so we can pick whatever default model we want. */
-            pci_nic_init_nofail(&nd_table[i], "e1000", NULL);
-        }
-    }
-
-    /* Load kernel. */
-    if (kernel_filename) {
-        success = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
-        if (success < 0) {
-            success = load_elf(kernel_filename, NULL, NULL, &elf_entry,
-                               &elf_lowaddr, NULL, 1, ELF_MACHINE, 0);
-            entry = elf_entry;
-            loadaddr = elf_lowaddr;
-        }
-        /* XXX try again as binary */
-        if (success < 0) {
-            fprintf(stderr, "qemu: could not load kernel '%s'\n",
-                    kernel_filename);
-            exit(1);
-        }
-    }
-
-    /* Load initrd. */
-    if (initrd_filename) {
-        initrd_size = load_image_targphys(initrd_filename, RAMDISK_ADDR,
-                                          ram_size - RAMDISK_ADDR);
-
-        if (initrd_size < 0) {
-            fprintf(stderr, "qemu: could not load ram disk '%s' at %x\n",
-                    initrd_filename, RAMDISK_ADDR);
-            exit(1);
-        }
-    }
-
-    /* If we're loading a kernel directly, we must load the device tree too. */
-    if (kernel_filename) {
-        if (bamboo_load_device_tree(FDT_ADDR, ram_size, RAMDISK_ADDR,
-                                    initrd_size, kernel_cmdline) < 0) {
-            fprintf(stderr, "couldn't load device tree\n");
-            exit(1);
-        }
-
-        /* Set initial guest state. */
-        env->gpr[1] = (16<<20) - 8;
-        env->gpr[3] = FDT_ADDR;
-        env->nip = entry;
-        /* XXX we currently depend on KVM to create some initial TLB entries. */
-    }
-
-    if (kvm_enabled())
-        kvmppc_init();
-}
-
-static QEMUMachine bamboo_machine = {
-    .name = "bamboo-0.13",
-    .alias = "bamboo",
-    .desc = "bamboo",
-    .init = bamboo_init,
-};
-
-static QEMUMachine bamboo_machine_v0_12 = {
-    .name = "bamboo-0.12",
-    .desc = "bamboo",
-    .init = bamboo_init,
-    .compat_props = (GlobalProperty[]) {
-        {
-            .driver   = "virtio-serial-pci",
-            .property = "max_ports",
-            .value    = stringify(1),
-        },{
-            .driver   = "virtio-serial-pci",
-            .property = "vectors",
-            .value    = stringify(0),
-        },
-        { /* end of list */ }
-    },
-};
-
-static void bamboo_machine_init(void)
-{
-    qemu_register_machine(&bamboo_machine);
-    qemu_register_machine(&bamboo_machine_v0_12);
-}
-
-machine_init(bamboo_machine_init);
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
deleted file mode 100644
index 2c69210..0000000
--- a/hw/ppc4xx_pci.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- * Copyright IBM Corp. 2008
- *
- * Authors: Hollis Blanchard <hollisb@us.ibm.com>
- */
-
-/* This file implements emulation of the 32-bit PCI controller found in some
- * 4xx SoCs, such as the 440EP. */
-
-#include "hw.h"
-#include "ppc.h"
-#include "ppc4xx.h"
-#include "pci.h"
-#include "pci_host.h"
-#include "exec-memory.h"
-
-#undef DEBUG
-#ifdef DEBUG
-#define DPRINTF(fmt, ...) do { printf(fmt, ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif /* DEBUG */
-
-struct PCIMasterMap {
-    uint32_t la;
-    uint32_t ma;
-    uint32_t pcila;
-    uint32_t pciha;
-};
-
-struct PCITargetMap {
-    uint32_t ms;
-    uint32_t la;
-};
-
-#define PPC4xx_PCI_NR_PMMS 3
-#define PPC4xx_PCI_NR_PTMS 2
-
-struct PPC4xxPCIState {
-    struct PCIMasterMap pmm[PPC4xx_PCI_NR_PMMS];
-    struct PCITargetMap ptm[PPC4xx_PCI_NR_PTMS];
-
-    PCIHostState pci_state;
-    PCIDevice *pci_dev;
-    MemoryRegion iomem_addr;
-    MemoryRegion iomem_regs;
-};
-typedef struct PPC4xxPCIState PPC4xxPCIState;
-
-#define PCIC0_CFGADDR       0x0
-#define PCIC0_CFGDATA       0x4
-
-/* PLB Memory Map (PMM) registers specify which PLB addresses are translated to
- * PCI accesses. */
-#define PCIL0_PMM0LA        0x0
-#define PCIL0_PMM0MA        0x4
-#define PCIL0_PMM0PCILA     0x8
-#define PCIL0_PMM0PCIHA     0xc
-#define PCIL0_PMM1LA        0x10
-#define PCIL0_PMM1MA        0x14
-#define PCIL0_PMM1PCILA     0x18
-#define PCIL0_PMM1PCIHA     0x1c
-#define PCIL0_PMM2LA        0x20
-#define PCIL0_PMM2MA        0x24
-#define PCIL0_PMM2PCILA     0x28
-#define PCIL0_PMM2PCIHA     0x2c
-
-/* PCI Target Map (PTM) registers specify which PCI addresses are translated to
- * PLB accesses. */
-#define PCIL0_PTM1MS        0x30
-#define PCIL0_PTM1LA        0x34
-#define PCIL0_PTM2MS        0x38
-#define PCIL0_PTM2LA        0x3c
-#define PCI_REG_SIZE        0x40
-
-
-static uint64_t pci4xx_cfgaddr_read(void *opaque, target_phys_addr_t addr,
-                                    unsigned size)
-{
-    PPC4xxPCIState *ppc4xx_pci = opaque;
-
-    return ppc4xx_pci->pci_state.config_reg;
-}
-
-static void pci4xx_cfgaddr_write(void *opaque, target_phys_addr_t addr,
-                                  uint64_t value, unsigned size)
-{
-    PPC4xxPCIState *ppc4xx_pci = opaque;
-
-    ppc4xx_pci->pci_state.config_reg = value & ~0x3;
-}
-
-static const MemoryRegionOps pci4xx_cfgaddr_ops = {
-    .read = pci4xx_cfgaddr_read,
-    .write = pci4xx_cfgaddr_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static void ppc4xx_pci_reg_write4(void *opaque, target_phys_addr_t offset,
-                                  uint64_t value, unsigned size)
-{
-    struct PPC4xxPCIState *pci = opaque;
-
-    /* We ignore all target attempts at PCI configuration, effectively
-     * assuming a bidirectional 1:1 mapping of PLB and PCI space. */
-
-    switch (offset) {
-    case PCIL0_PMM0LA:
-        pci->pmm[0].la = value;
-        break;
-    case PCIL0_PMM0MA:
-        pci->pmm[0].ma = value;
-        break;
-    case PCIL0_PMM0PCIHA:
-        pci->pmm[0].pciha = value;
-        break;
-    case PCIL0_PMM0PCILA:
-        pci->pmm[0].pcila = value;
-        break;
-
-    case PCIL0_PMM1LA:
-        pci->pmm[1].la = value;
-        break;
-    case PCIL0_PMM1MA:
-        pci->pmm[1].ma = value;
-        break;
-    case PCIL0_PMM1PCIHA:
-        pci->pmm[1].pciha = value;
-        break;
-    case PCIL0_PMM1PCILA:
-        pci->pmm[1].pcila = value;
-        break;
-
-    case PCIL0_PMM2LA:
-        pci->pmm[2].la = value;
-        break;
-    case PCIL0_PMM2MA:
-        pci->pmm[2].ma = value;
-        break;
-    case PCIL0_PMM2PCIHA:
-        pci->pmm[2].pciha = value;
-        break;
-    case PCIL0_PMM2PCILA:
-        pci->pmm[2].pcila = value;
-        break;
-
-    case PCIL0_PTM1MS:
-        pci->ptm[0].ms = value;
-        break;
-    case PCIL0_PTM1LA:
-        pci->ptm[0].la = value;
-        break;
-    case PCIL0_PTM2MS:
-        pci->ptm[1].ms = value;
-        break;
-    case PCIL0_PTM2LA:
-        pci->ptm[1].la = value;
-        break;
-
-    default:
-        printf("%s: unhandled PCI internal register 0x%lx\n", __func__,
-               (unsigned long)offset);
-        break;
-    }
-}
-
-static uint64_t ppc4xx_pci_reg_read4(void *opaque, target_phys_addr_t offset,
-                                     unsigned size)
-{
-    struct PPC4xxPCIState *pci = opaque;
-    uint32_t value;
-
-    switch (offset) {
-    case PCIL0_PMM0LA:
-        value = pci->pmm[0].la;
-        break;
-    case PCIL0_PMM0MA:
-        value = pci->pmm[0].ma;
-        break;
-    case PCIL0_PMM0PCIHA:
-        value = pci->pmm[0].pciha;
-        break;
-    case PCIL0_PMM0PCILA:
-        value = pci->pmm[0].pcila;
-        break;
-
-    case PCIL0_PMM1LA:
-        value = pci->pmm[1].la;
-        break;
-    case PCIL0_PMM1MA:
-        value = pci->pmm[1].ma;
-        break;
-    case PCIL0_PMM1PCIHA:
-        value = pci->pmm[1].pciha;
-        break;
-    case PCIL0_PMM1PCILA:
-        value = pci->pmm[1].pcila;
-        break;
-
-    case PCIL0_PMM2LA:
-        value = pci->pmm[2].la;
-        break;
-    case PCIL0_PMM2MA:
-        value = pci->pmm[2].ma;
-        break;
-    case PCIL0_PMM2PCIHA:
-        value = pci->pmm[2].pciha;
-        break;
-    case PCIL0_PMM2PCILA:
-        value = pci->pmm[2].pcila;
-        break;
-
-    case PCIL0_PTM1MS:
-        value = pci->ptm[0].ms;
-        break;
-    case PCIL0_PTM1LA:
-        value = pci->ptm[0].la;
-        break;
-    case PCIL0_PTM2MS:
-        value = pci->ptm[1].ms;
-        break;
-    case PCIL0_PTM2LA:
-        value = pci->ptm[1].la;
-        break;
-
-    default:
-        printf("%s: invalid PCI internal register 0x%lx\n", __func__,
-               (unsigned long)offset);
-        value = 0;
-    }
-
-    return value;
-}
-
-static const MemoryRegionOps pci_reg_ops = {
-    .read = ppc4xx_pci_reg_read4,
-    .write = ppc4xx_pci_reg_write4,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static void ppc4xx_pci_reset(void *opaque)
-{
-    struct PPC4xxPCIState *pci = opaque;
-
-    memset(pci->pmm, 0, sizeof(pci->pmm));
-    memset(pci->ptm, 0, sizeof(pci->ptm));
-}
-
-/* On Bamboo, all pins from each slot are tied to a single board IRQ. This
- * may need further refactoring for other boards. */
-static int ppc4xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
-{
-    int slot = pci_dev->devfn >> 3;
-
-    DPRINTF("%s: devfn %x irq %d -> %d\n", __func__,
-            pci_dev->devfn, irq_num, slot);
-
-    return slot - 1;
-}
-
-static void ppc4xx_pci_set_irq(void *opaque, int irq_num, int level)
-{
-    qemu_irq *pci_irqs = opaque;
-
-    DPRINTF("%s: PCI irq %d\n", __func__, irq_num);
-    qemu_set_irq(pci_irqs[irq_num], level);
-}
-
-static const VMStateDescription vmstate_pci_master_map = {
-    .name = "pci_master_map",
-    .version_id = 0,
-    .minimum_version_id = 0,
-    .minimum_version_id_old = 0,
-    .fields      = (VMStateField[]) {
-        VMSTATE_UINT32(la, struct PCIMasterMap),
-        VMSTATE_UINT32(ma, struct PCIMasterMap),
-        VMSTATE_UINT32(pcila, struct PCIMasterMap),
-        VMSTATE_UINT32(pciha, struct PCIMasterMap),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static const VMStateDescription vmstate_pci_target_map = {
-    .name = "pci_target_map",
-    .version_id = 0,
-    .minimum_version_id = 0,
-    .minimum_version_id_old = 0,
-    .fields      = (VMStateField[]) {
-        VMSTATE_UINT32(ms, struct PCITargetMap),
-        VMSTATE_UINT32(la, struct PCITargetMap),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static const VMStateDescription vmstate_ppc4xx_pci = {
-    .name = "ppc4xx_pci",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
-    .fields      = (VMStateField[]) {
-        VMSTATE_PCI_DEVICE_POINTER(pci_dev, PPC4xxPCIState),
-        VMSTATE_STRUCT_ARRAY(pmm, PPC4xxPCIState, PPC4xx_PCI_NR_PMMS, 1,
-                             vmstate_pci_master_map,
-                             struct PCIMasterMap),
-        VMSTATE_STRUCT_ARRAY(ptm, PPC4xxPCIState, PPC4xx_PCI_NR_PTMS, 1,
-                             vmstate_pci_target_map,
-                             struct PCITargetMap),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-/* XXX Interrupt acknowledge cycles not supported. */
-PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
-                        target_phys_addr_t config_space,
-                        target_phys_addr_t int_ack,
-                        target_phys_addr_t special_cycle,
-                        target_phys_addr_t registers)
-{
-    PPC4xxPCIState *controller;
-    static int ppc4xx_pci_id;
-    uint8_t *pci_conf;
-
-    controller = g_malloc0(sizeof(PPC4xxPCIState));
-
-    controller->pci_state.bus = pci_register_bus(NULL, "pci",
-                                                 ppc4xx_pci_set_irq,
-                                                 ppc4xx_pci_map_irq,
-                                                 pci_irqs,
-                                                 get_system_memory(),
-                                                 get_system_io(),
-                                                 0, 4);
-
-    controller->pci_dev = pci_register_device(controller->pci_state.bus,
-                                              "host bridge", sizeof(PCIDevice),
-                                              0, NULL, NULL);
-    pci_conf = controller->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_440GX);
-    pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER);
-
-    /* CFGADDR */
-    memory_region_init_io(&controller->iomem_addr, &pci4xx_cfgaddr_ops,
-                          controller, "pci.cfgaddr", 4);
-    memory_region_add_subregion(get_system_memory(),
-                                config_space + PCIC0_CFGADDR,
-                                &controller->iomem_addr);
-
-    /* CFGDATA */
-    memory_region_init_io(&controller->pci_state.data_mem,
-                          &pci_host_data_be_ops,
-                          &controller->pci_state, "pci-conf-data", 4);
-    memory_region_add_subregion(get_system_memory(),
-                                config_space + PCIC0_CFGDATA,
-                                &controller->pci_state.data_mem);
-
-    /* Internal registers */
-    memory_region_init_io(&controller->iomem_regs, &pci_reg_ops, controller,
-                          "pci.regs", PCI_REG_SIZE);
-    memory_region_add_subregion(get_system_memory(), registers,
-                                &controller->iomem_regs);
-
-    qemu_register_reset(ppc4xx_pci_reset, controller);
-
-    /* XXX load/save code not tested. */
-    vmstate_register(&controller->pci_dev->qdev, ppc4xx_pci_id++,
-                     &vmstate_ppc4xx_pci, controller);
-
-    return controller->pci_state.bus;
-}
diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c
index 6ffb896..1dc8a8f 100644
--- a/hw/virtex_ml507.c
+++ b/hw/virtex_ml507.c
@@ -38,7 +38,6 @@
 
 #include "ppc.h"
 #include "ppc4xx.h"
-#include "ppc440.h"
 #include "ppc405.h"
 
 #include "blockdev.h"
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 04/30] ppc_prep: convert host bridge to qdev
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (2 preceding siblings ...)
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support Anthony Liguori
@ 2012-01-03  0:51 ` Anthony Liguori
  2012-01-03 14:57   ` Andreas Färber
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 05/30] pseries: Remove hcalls callback Anthony Liguori
                   ` (25 subsequent siblings)
  29 siblings, 1 reply; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

Untested beyond compile.  But it's a very simple conversion.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/prep_pci.c |   38 +++++++++++++++++++++++++++-----------
 1 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index ea9fb69..16c036f 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -106,12 +106,37 @@ static void prep_set_irq(void *opaque, int irq_num, int level)
     qemu_set_irq(pic[(irq_num & 1) ? 11 : 9] , level);
 }
 
+static int prep_hb_initfn(PCIDevice *d)
+{
+    d->config[0x0C] = 0x08; // cache_line_size
+    d->config[0x0D] = 0x10; // latency_timer
+    d->config[0x34] = 0x00; // capabilities_pointer
+
+    return 0;
+}
+
+static PCIDeviceInfo prep_hb_info = {
+    .qdev.name = "PREP Host Bridge - Motorola Raven",
+    .qdev.size = sizeof(PCIDevice),
+    .init = prep_hb_initfn,
+    .vendor_id = PCI_VENDOR_ID_MOTOROLA,
+    .device_id = PCI_DEVICE_ID_MOTOROLA_RAVEN,
+    .revision = 0x00,
+    .class_id = PCI_CLASS_BRIDGE_HOST,
+};
+
+static void prep_register(void)
+{
+    pci_qdev_register(&prep_hb_info);
+}
+
+device_init(prep_register);
+
 PCIBus *pci_prep_init(qemu_irq *pic,
                       MemoryRegion *address_space_mem,
                       MemoryRegion *address_space_io)
 {
     PREPPCIState *s;
-    PCIDevice *d;
 
     s = g_malloc0(sizeof(PREPPCIState));
     s->bus = pci_register_bus(NULL, "pci",
@@ -133,16 +158,7 @@ PCIBus *pci_prep_init(qemu_irq *pic,
     memory_region_init_io(&s->mmcfg, &PPC_PCIIO_ops, s, "pciio", 0x00400000);
     memory_region_add_subregion(address_space_mem, 0x80800000, &s->mmcfg);
 
-    /* PCI host bridge */
-    d = pci_register_device(s->bus, "PREP Host Bridge - Motorola Raven",
-                            sizeof(PCIDevice), 0, NULL, NULL);
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_MOTOROLA);
-    pci_config_set_device_id(d->config, PCI_DEVICE_ID_MOTOROLA_RAVEN);
-    d->config[0x08] = 0x00; // revision
-    pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
-    d->config[0x0C] = 0x08; // cache_line_size
-    d->config[0x0D] = 0x10; // latency_timer
-    d->config[0x34] = 0x00; // capabilities_pointer
+    pci_create_simple(s->bus, 0, "PREP Host Bridge - Motorola Raven");
 
     return s->bus;
 }
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 05/30] pseries: Remove hcalls callback
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (3 preceding siblings ...)
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 04/30] ppc_prep: convert host bridge to qdev Anthony Liguori
@ 2012-01-03  0:51 ` Anthony Liguori
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 06/30] pci: call reset unconditionally Anthony Liguori
                   ` (24 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, David Gibson, Markus Armbruster,
	Andreas Färber

From: David Gibson <david@gibson.dropbear.id.au>

For forgotten historical reasons, PAPR hypercalls for specific virtual IO
devices (oh which there are quite a number) are registered via a callback
in the VIOsPAPRDeviceInfo structure.

This is kind of ugly, so this patch instead registers hypercalls from
device_init() functions for each device type.  This works just as well,
and is cleaner.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/spapr_llan.c |   17 ++++++-----------
 hw/spapr_vio.c  |   13 -------------
 hw/spapr_vio.h  |    1 -
 hw/spapr_vty.c  |    9 ++-------
 4 files changed, 8 insertions(+), 32 deletions(-)

diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c
index abe1297..45674c4 100644
--- a/hw/spapr_llan.c
+++ b/hw/spapr_llan.c
@@ -474,16 +474,6 @@ static target_ulong h_multicast_ctrl(CPUState *env, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
-static void vlan_hcalls(VIOsPAPRBus *bus)
-{
-    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);
-}
-
 static VIOsPAPRDeviceInfo spapr_vlan = {
     .init = spapr_vlan_init,
     .devnode = spapr_vlan_devnode,
@@ -491,7 +481,6 @@ static VIOsPAPRDeviceInfo spapr_vlan = {
     .dt_type = "network",
     .dt_compatible = "IBM,l-lan",
     .signal_mask = 0x1,
-    .hcalls = vlan_hcalls,
     .qdev.name = "spapr-vlan",
     .qdev.size = sizeof(VIOsPAPRVLANDevice),
     .qdev.props = (Property[]) {
@@ -504,5 +493,11 @@ 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);
 }
 device_init(spapr_vlan_register);
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 2dcc036..5a35541 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -684,7 +684,6 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
     VIOsPAPRBus *bus;
     BusState *qbus;
     DeviceState *dev;
-    DeviceInfo *qinfo;
 
     /* Create bridge device */
     dev = qdev_create(NULL, "spapr-vio-bridge");
@@ -711,18 +710,6 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
     spapr_rtas_register("ibm,set-tce-bypass", rtas_set_tce_bypass);
     spapr_rtas_register("quiesce", rtas_quiesce);
 
-    for (qinfo = device_info_list; qinfo; qinfo = qinfo->next) {
-        VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
-
-        if (qinfo->bus_info != &spapr_vio_bus_info) {
-            continue;
-        }
-
-        if (info->hcalls) {
-            info->hcalls(bus);
-        }
-    }
-
     return bus;
 }
 
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index a325a5f..2430d45 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -75,7 +75,6 @@ typedef struct {
     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);
 } VIOsPAPRDeviceInfo;
 
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index f23cc36..e217314 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -135,18 +135,11 @@ void spapr_vty_create(VIOsPAPRBus *bus, uint32_t reg, CharDriverState *chardev)
     qdev_init_nofail(dev);
 }
 
-static void vty_hcalls(VIOsPAPRBus *bus)
-{
-    spapr_register_hypercall(H_PUT_TERM_CHAR, h_put_term_char);
-    spapr_register_hypercall(H_GET_TERM_CHAR, h_get_term_char);
-}
-
 static VIOsPAPRDeviceInfo spapr_vty = {
     .init = spapr_vty_init,
     .dt_name = "vty",
     .dt_type = "serial",
     .dt_compatible = "hvterm1",
-    .hcalls = vty_hcalls,
     .qdev.name = "spapr-vty",
     .qdev.size = sizeof(VIOsPAPRVTYDevice),
     .qdev.props = (Property[]) {
@@ -182,5 +175,7 @@ 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);
 }
 device_init(spapr_vty_register);
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 06/30] pci: call reset unconditionally
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (4 preceding siblings ...)
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 05/30] pseries: Remove hcalls callback Anthony Liguori
@ 2012-01-03  0:51 ` Anthony Liguori
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 07/30] qom: add the base Object class (v2) Anthony Liguori
                   ` (23 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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 399227f..fd575ac 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] 50+ messages in thread

* [Qemu-devel] [PATCH 07/30] qom: add the base Object class (v2)
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (5 preceding siblings ...)
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 06/30] pci: call reset unconditionally Anthony Liguori
@ 2012-01-03  0:51 ` Anthony Liguori
  2012-01-03  9:02   ` Paolo Bonzini
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 08/30] qdev: integrate with QEMU Object Model (v2) Anthony Liguori
                   ` (22 subsequent siblings)
  29 siblings, 1 reply; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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 0838bc4..f2e99c8 100644
--- a/Makefile
+++ b/Makefile
@@ -113,6 +113,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 8813673..1ae2ecc 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 b8ccf07..0a7445b 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 640e815..a09028e 100755
--- a/configure
+++ b/configure
@@ -3801,7 +3801,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/Makefile qdict-test-data.txt"
 FILES="$FILES tests/cris/Makefile tests/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] 50+ messages in thread

* [Qemu-devel] [PATCH 08/30] qdev: integrate with QEMU Object Model (v2)
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (6 preceding siblings ...)
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 07/30] qom: add the base Object class (v2) Anthony Liguori
@ 2012-01-03  0:51 ` Anthony Liguori
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 09/30] qdev: move qdev->info to class Anthony Liguori
                   ` (21 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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 d0cf66d..2646d8e 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;
 }
@@ -89,7 +97,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);
@@ -491,7 +499,7 @@ void qdev_free(DeviceState *dev)
             prop->info->free(dev, prop);
         }
     }
-    g_free(dev);
+    object_delete(OBJECT(dev));
 }
 
 void qdev_machine_creation_done(void)
@@ -1535,3 +1543,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 2abb767..d45a6e0 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] 50+ messages in thread

* [Qemu-devel] [PATCH 09/30] qdev: move qdev->info to class
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (7 preceding siblings ...)
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 08/30] qdev: integrate with QEMU Object Model (v2) Anthony Liguori
@ 2012-01-03  0:51 ` Anthony Liguori
  2012-01-08  2:27   ` Andreas Färber
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 10/30] qdev: don't access name through info Anthony Liguori
                   ` (20 subsequent siblings)
  29 siblings, 1 reply; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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/cirrus_vga.c        |    2 +-
 hw/e1000.c             |    2 +-
 hw/eepro100.c          |    4 +-
 hw/hda-audio.c         |    2 +-
 hw/ide/piix.c          |    2 +-
 hw/intel-hda.c         |    6 ++--
 hw/lsi53c895a.c        |    2 +-
 hw/ne2000-isa.c        |    2 +-
 hw/ne2000.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/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 ++--
 25 files changed, 103 insertions(+), 77 deletions(-)

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index d9075e6..30c62ac 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -277,7 +277,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);
 
@@ -488,7 +488,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/cirrus_vga.c b/hw/cirrus_vga.c
index f7b1d3d..2505f22 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2911,7 +2911,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 a29c944..7e17d85 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1174,7 +1174,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/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/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/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/pci.c b/hw/pci.c
index fd575ac..64cd08f 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);
@@ -1757,10 +1759,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, &pdev->qdev, name, size);
     ptr = memory_region_get_ram_ptr(&pdev->rom);
@@ -1999,7 +2001,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 cba253b..e58b195 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -1718,7 +1718,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 663c2a0..a11127f 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -955,7 +955,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;
 
@@ -978,16 +978,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;
@@ -1007,7 +1007,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);
@@ -1028,12 +1028,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);
@@ -1082,7 +1082,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;
     }
@@ -1154,8 +1154,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 2646d8e..1b25304 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);
 
@@ -98,9 +111,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);
@@ -113,12 +125,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);
     }
@@ -351,19 +363,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;
 }
@@ -382,7 +394,7 @@ 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);
 
     if (dev->ref != 0) {
         qerror_report(QERR_DEVICE_IN_USE, dev->id?:"");
@@ -391,13 +403,13 @@ int qdev_unplug(DeviceState *dev)
 
     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;
@@ -448,7 +460,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);
@@ -486,15 +498,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);
         }
@@ -680,7 +692,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 = ", ";
@@ -695,7 +707,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 = ", ";
@@ -731,12 +743,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;
         }
     }
@@ -938,7 +950,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) {
@@ -947,7 +959,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);
@@ -1028,7 +1040,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, "/");
@@ -1050,7 +1062,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)
@@ -1252,7 +1264,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, NULL, child, errp);
@@ -1303,7 +1315,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 d45a6e0..702b65f 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;
@@ -388,9 +390,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/spapr_vio.c b/hw/spapr_vio.c
index 5a35541..be6d2bd 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;
 
@@ -668,7 +668,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 e217314..9291beb 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -163,7 +163,7 @@ static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg)
          * (early debug does work there, despite having no vty with
          * reg==0. */
         QTAILQ_FOREACH(qdev, &spapr->vio_bus->bus.children, sibling) {
-            if (qdev->info == &spapr_vty.qdev) {
+            if (qdev_get_info(qdev) == &spapr_vty.qdev) {
                 return DO_UPCAST(VIOsPAPRDevice, qdev, qdev);
             }
         }
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 8203390..71ef794 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -249,7 +249,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 cd349f3..8a79729 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -1122,7 +1122,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 f91fa32..710c4d9 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1351,7 +1351,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 e68be70..833fa7c 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1775,7 +1775,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 73d866a..cd20174 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 fe0233f..cc4e4f6 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -135,7 +135,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;
@@ -358,7 +358,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:
@@ -809,7 +809,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] 50+ messages in thread

* [Qemu-devel] [PATCH 10/30] qdev: don't access name through info
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (8 preceding siblings ...)
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 09/30] qdev: move qdev->info to class Anthony Liguori
@ 2012-01-03  0:51 ` Anthony Liguori
  2012-01-03  9:06   ` Paolo Bonzini
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 11/30] qdev: use a wrapper to access reset and promote reset to a class method Anthony Liguori
                   ` (19 subsequent siblings)
  29 siblings, 1 reply; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:51 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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 7e17d85..7ad0ea4 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1174,7 +1174,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 b525258..ad059ca 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 7e64c5d..ebe39ad 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -1137,7 +1137,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);
+                          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 b5e0dac..d4a321a 100644
--- a/hw/milkymist-minimac2.c
+++ b/hw/milkymist-minimac2.c
@@ -478,7 +478,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 b1234b8..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,
-                          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/musicpal.c b/hw/musicpal.c
index 3c6cefe..fbed503 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -383,7 +383,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 f7cc1b4..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,
-                          s->dev.qdev.info->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 64cd08f..3ffc32f 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,
@@ -1762,7 +1762,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, &pdev->qdev, name, size);
     ptr = memory_region_get_ram_ptr(&pdev->rom);
diff --git a/hw/pcnet.c b/hw/pcnet.c
index e58b195..9b5f1c3 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -1718,7 +1718,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 a11127f..8a5a67d 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -978,16 +978,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;
@@ -1007,7 +1007,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);
@@ -1028,12 +1028,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);
@@ -1082,7 +1082,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;
     }
@@ -1154,7 +1154,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 1b25304..9f92c7f 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -692,7 +692,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 = ", ";
@@ -707,7 +707,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 = ", ";
@@ -743,7 +743,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;
         }
     }
@@ -950,7 +950,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) {
@@ -1040,7 +1040,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, "/");
@@ -1062,7 +1062,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)
@@ -1264,7 +1264,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, NULL, child, errp);
@@ -1315,7 +1315,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 702b65f..329724e 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -402,7 +402,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 82b8811..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,
-                          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);
     /* ??? 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 71ef794..f8745f9 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -249,7 +249,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 710c4d9..263e6b7 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1351,7 +1351,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 833fa7c..6b28a0c 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1775,7 +1775,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] 50+ messages in thread

* [Qemu-devel] [PATCH 11/30] qdev: use a wrapper to access reset and promote reset to a class method
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (9 preceding siblings ...)
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 10/30] qdev: don't access name through info Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 12/30] qdev: add a interface to register subclasses Anthony Liguori
                   ` (18 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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 9f92c7f..c26b1e7 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)
@@ -374,8 +379,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;
 }
@@ -408,9 +413,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;
 }
@@ -1556,6 +1559,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 329724e..822186e 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
@@ -646,4 +647,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] 50+ messages in thread

* [Qemu-devel] [PATCH 12/30] qdev: add a interface to register subclasses
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (10 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 11/30] qdev: use a wrapper to access reset and promote reset to a class method Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 13/30] qdev: add class_init to DeviceInfo Anthony Liguori
                   ` (17 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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 c26b1e7..7c4d3ca 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 822186e..742f421 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -240,6 +240,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] 50+ messages in thread

* [Qemu-devel] [PATCH 13/30] qdev: add class_init to DeviceInfo
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (11 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 12/30] qdev: add a interface to register subclasses Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 14/30] qdev: prepare source tree for code conversion Anthony Liguori
                   ` (16 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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 7c4d3ca..c6a6d20 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 742f421..6e86826 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -230,6 +230,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] 50+ messages in thread

* [Qemu-devel] [PATCH 14/30] qdev: prepare source tree for code conversion
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (12 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 13/30] qdev: add class_init to DeviceInfo Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-04 14:07   ` Andreas Färber
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 15/30] isa: convert to QEMU Object Model Anthony Liguori
                   ` (15 subsequent siblings)
  29 siblings, 1 reply; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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 cd343e1..3db2e0d 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -169,8 +169,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 855b792..dacc0ab 100644
--- a/hw/marvell_88w8618_audio.c
+++ b/hw/marvell_88w8618_audio.c
@@ -47,7 +47,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)
@@ -276,11 +276,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 41500e9..5f30525 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 9291beb..2849961 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 @@ static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg)
          * (early debug does work there, despite having no vty with
          * reg==0. */
         QTAILQ_FOREACH(qdev, &spapr->vio_bus->bus.children, sibling) {
-            if (qdev_get_info(qdev) == &spapr_vty.qdev) {
+            if (qdev_get_info(qdev) == &spapr_vty_info.qdev) {
                 return DO_UPCAST(VIOsPAPRDevice, qdev, qdev);
             }
         }
@@ -174,8 +174,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 7c926c0..1b10449 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -2262,30 +2262,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)
@@ -2361,7 +2359,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 f8912e2..88b464b 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1191,8 +1191,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,
@@ -1203,7 +1202,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,
@@ -1214,55 +1215,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 77b75bc..9af8e3f 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -780,98 +780,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] 50+ messages in thread

* [Qemu-devel] [PATCH 15/30] isa: convert to QEMU Object Model
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (13 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 14/30] qdev: prepare source tree for code conversion Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 16/30] usb: " Anthony Liguori
                   ` (14 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/applesmc.c    |   18 ++++++++++++------
 hw/cs4231a.c     |   20 +++++++++++++-------
 hw/debugcon.c    |   16 +++++++++++-----
 hw/fdc.c         |   24 +++++++++++++++---------
 hw/gus.c         |   20 +++++++++++++-------
 hw/i8254.c       |   22 ++++++++++++++--------
 hw/i8259.c       |   22 ++++++++++++++--------
 hw/ide/isa.c     |   20 +++++++++++++-------
 hw/isa-bus.c     |   33 +++++++++++++++++++++++----------
 hw/isa.h         |   22 ++++++++++++++--------
 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         |   16 +++++++++++-----
 hw/vga-isa.c     |   18 ++++++++++++------
 hw/vmmouse.c     |   22 ++++++++++++++--------
 hw/vmport.c      |   16 +++++++++++-----
 hw/wdt_ib700.c   |   18 ++++++++++++------
 23 files changed, 301 insertions(+), 156 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/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/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 7331e0e..6502c48 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -556,14 +556,20 @@ qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq)
     return irq_set;
 }
 
-static ISADeviceInfo i8259_info = {
-    .qdev.name     = "isa-i8259",
-    .qdev.size     = sizeof(PicState),
-    .qdev.vmsd     = &vmstate_pic,
-    .qdev.reset    = pic_reset,
-    .qdev.no_user  = 1,
-    .init          = pic_initfn,
-    .qdev.props = (Property[]) {
+static void pic_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = pic_initfn;
+}
+
+static DeviceInfo i8259_info = {
+    .name     = "isa-i8259",
+    .size     = sizeof(PicState),
+    .vmsd     = &vmstate_pic,
+    .reset    = pic_reset,
+    .no_user  = 1,
+    .class_init          = pic_class_initfn,
+    .props = (Property[]) {
         DEFINE_PROP_HEX32("iobase", PicState, iobase,  -1),
         DEFINE_PROP_HEX32("elcr_addr", PicState, elcr_addr,  -1),
         DEFINE_PROP_HEX8("elcr_mask", PicState, elcr_mask,  -1),
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..cef6e8f 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -112,20 +112,24 @@ 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(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);
+    info->init = isa_qdev_init;
+    info->bus_info = &isa_bus_info;
+    qdev_register_subclass(info, TYPE_ISA_DEVICE);
 }
 
 ISADevice *isa_create(ISABus *bus, const char *name)
@@ -137,7 +141,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 +153,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 +167,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 +192,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..a6e1d7e 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,11 @@ 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);
 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/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 9cbd052..1437375 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -624,7 +624,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);
@@ -694,13 +694,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 f51afa8..a9df616 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -496,13 +496,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 7ef750a..07ed2d0 100644
--- a/hw/sga.c
+++ b/hw/sga.c
@@ -41,11 +41,17 @@ static int isa_cirrus_vga_initfn(ISADevice *dev)
     return 0;
 }
 
-static ISADeviceInfo sga_info = {
-    .qdev.name    = "sga",
-    .qdev.desc    = "Serial Graphics Adapter",
-    .qdev.size    = sizeof(ISASGAState),
-    .init         = isa_cirrus_vga_initfn,
+static void isa_cirrus_vga_class_initfn(ObjectClass *klass, void *data)
+{
+    ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    ic->init = isa_cirrus_vga_initfn;
+}
+
+static DeviceInfo sga_info = {
+    .name    = "sga",
+    .desc    = "Serial Graphics Adapter",
+    .size    = sizeof(ISASGAState),
+    .class_init         = isa_cirrus_vga_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] 50+ messages in thread

* [Qemu-devel] [PATCH 16/30] usb: convert to QEMU Object Model
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (14 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 15/30] isa: convert to QEMU Object Model Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 17/30] ccid: " Anthony Liguori
                   ` (13 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/usb-bt.c     |   33 ++++++----
 hw/usb-bus.c    |  179 +++++++++++++++++++++++++++++++++++++++++++------------
 hw/usb-ccid.c   |   38 +++++++-----
 hw/usb-desc.c   |   18 +++---
 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.c        |   24 +++----
 hw/usb.h        |   98 +++++++++++++++++++-----------
 usb-bsd.c       |   29 ++++++----
 usb-linux.c     |   37 +++++++-----
 usb-redir.c     |   33 ++++++----
 15 files changed, 516 insertions(+), 308 deletions(-)

diff --git a/hw/usb-bt.c b/hw/usb-bt.c
index f30eec1..6e210ac 100644
--- a/hw/usb-bt.c
+++ b/hw/usb-bt.c
@@ -549,22 +549,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 f8745f9..175b85e 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -65,21 +65,102 @@ 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;
+}
+
 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);
     rc = usb_claim_port(dev);
     if (rc != 0) {
         return rc;
     }
-    rc = dev->info->init(dev);
+    rc = usb_device_init(dev);
     if (rc != 0) {
         usb_release_port(dev);
         return rc;
@@ -96,34 +177,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);
     }
 }
 
@@ -143,7 +233,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)
@@ -364,7 +454,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",
@@ -376,13 +466,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;
@@ -433,8 +523,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;
@@ -451,17 +541,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);
@@ -469,12 +555,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 8a79729..47b1120 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -1294,28 +1294,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 ae2d384..1f5fc7a 100644
--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -225,7 +225,7 @@ int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len)
 
 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) {
@@ -242,7 +242,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;
@@ -258,7 +258,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)) {
@@ -267,7 +267,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);
@@ -323,7 +323,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;
         }
@@ -342,7 +342,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;
@@ -350,9 +350,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) {
@@ -407,7 +407,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 i, ret = -1;
 
     assert(desc != NULL);
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index a110c74..2538b9c 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -560,53 +560,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 e195937..f997152 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -540,23 +540,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 4c06950..e4a1e4e 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -634,23 +634,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),
@@ -660,6 +665,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 263e6b7..c0d1f8e 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1399,29 +1399,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 7dbf6df..73bb80b 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -577,41 +577,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(),
     },
@@ -619,7 +629,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 2558006..12c949f 100644
--- a/hw/usb-wacom.c
+++ b/hw/usb-wacom.c
@@ -356,24 +356,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.c b/hw/usb.c
index 2216efe..e1cbfec 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 = dev;
@@ -357,7 +353,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
 void usb_cancel_packet(USBPacket * p)
 {
     assert(p->owner != NULL);
-    p->owner->info->cancel_packet(p->owner, p);
+    usb_device_cancel_packet(p->owner, p);
     p->owner = NULL;
 }
 
diff --git a/hw/usb.h b/hw/usb.h
index c6e1870..2bbfb0a 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -1,3 +1,6 @@
+#ifndef QEMU_USB_H
+#define QEMU_USB_H
+
 /*
  * QEMU USB API
  *
@@ -142,7 +145,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 USBDesc USBDesc;
@@ -161,38 +163,17 @@ struct USBDescString {
     QLIST_ENTRY(USBDescString) next;
 };
 
-/* definition of a USB device */
-struct USBDevice {
-    DeviceState qdev;
-    USBDeviceInfo *info;
-    USBPort *port;
-    char *port_path;
-    void *opaque;
-
-    /* Actual connected speed */
-    int speed;
-    /* Supported speeds, not in info because it may be variable (hostdevs) */
-    int speedmask;
-    uint8_t addr;
-    char product_desc[32];
-    int auto_attach;
-    int attached;
-
-    int32_t state;
-    uint8_t setup_buf[8];
-    uint8_t data_buf[4096];
-    int32_t remote_wakeup;
-    int32_t setup_state;
-    int32_t setup_len;
-    int32_t setup_index;
+#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)
 
-    QLIST_HEAD(, USBDescString) strings;
-    const USBDescDevice *device;
-    const USBDescConfig *config;
-};
+typedef struct USBDeviceClass {
+    DeviceClass parent_class;
 
-struct USBDeviceInfo {
-    DeviceInfo qdev;
     int (*init)(USBDevice *dev);
 
     /*
@@ -243,10 +224,35 @@ struct USBDeviceInfo {
 
     const char *product_desc;
     const USBDesc *usb_desc;
+} USBDeviceClass;
+
+/* definition of a USB device */
+struct USBDevice {
+    DeviceState qdev;
+    USBPort *port;
+    char *port_path;
+    void *opaque;
+
+    /* Actual connected speed */
+    int speed;
+    /* Supported speeds, not in info because it may be variable (hostdevs) */
+    int speedmask;
+    uint8_t addr;
+    char product_desc[32];
+    int auto_attach;
+    int attached;
+
+    int32_t state;
+    uint8_t setup_buf[8];
+    uint8_t data_buf[4096];
+    int32_t remote_wakeup;
+    int32_t setup_state;
+    int32_t setup_len;
+    int32_t setup_index;
 
-    /* handle legacy -usbdevice command line options */
-    const char *usbdevice_name;
-    USBDevice *(*usbdevice_init)(const char *params);
+    QLIST_HEAD(, USBDescString) strings;
+    const USBDescDevice *device;
+    const USBDescConfig *config;
 };
 
 typedef struct USBPortOps {
@@ -370,8 +376,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);
@@ -392,3 +399,22 @@ static inline USBBus *usb_bus_from_device(USBDevice *d)
 {
     return DO_UPCAST(USBBus, qbus, d->qdev.parent_bus);
 }
+
+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);
+
+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 ab4c693..82d7e7e 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -1428,21 +1428,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),
@@ -1455,7 +1460,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 a36f2a7..26a9ba3 100644
--- a/usb-redir.c
+++ b/usb-redir.c
@@ -1227,18 +1227,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(),
@@ -1247,6 +1254,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] 50+ messages in thread

* [Qemu-devel] [PATCH 17/30] ccid: convert to QEMU Object Model
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (15 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 16/30] usb: " Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 18/30] ssi: " Anthony Liguori
                   ` (12 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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 47b1120..a803c71 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;
@@ -749,7 +785,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);
 }
@@ -835,7 +871,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");
     }
@@ -1121,26 +1157,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;
@@ -1154,20 +1185,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)
@@ -1178,7 +1208,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;
@@ -1320,8 +1349,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] 50+ messages in thread

* [Qemu-devel] [PATCH 18/30] ssi: convert to QEMU Object Model
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (16 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 17/30] ccid: " Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 19/30] i2c: rename i2c_slave -> I2CSlave Anthony Liguori
                   ` (11 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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 9c58a5f..9ea7cab 100644
--- a/hw/ads7846.c
+++ b/hw/ads7846.c
@@ -150,11 +150,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 70cd1af..305392c 100644
--- a/hw/max111x.c
+++ b/hw/max111x.c
@@ -150,18 +150,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 df0e146..8e3aeda 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -1066,12 +1066,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 = {
@@ -1086,12 +1094,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 18dabd6..e559264 100644
--- a/hw/ssi-sd.c
+++ b/hw/ssi-sd.c
@@ -241,11 +241,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 9842fe7..3c7867d 100644
--- a/hw/ssi.c
+++ b/hw/ssi.c
@@ -20,8 +20,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));
@@ -30,16 +30,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)
@@ -61,10 +60,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 67a71fe..0977cc9 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -262,13 +262,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 a03bb33..96a8587 100644
--- a/hw/z2.c
+++ b/hw/z2.c
@@ -171,12 +171,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] 50+ messages in thread

* [Qemu-devel] [PATCH 19/30] i2c: rename i2c_slave -> I2CSlave
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (17 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 18/30] ssi: " Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 20/30] i2c: smbus: convert to QEMU Object Model Anthony Liguori
                   ` (10 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/ds1338.c   |   10 +++++-----
 hw/hw.h       |    4 ++--
 hw/i2c.c      |   30 +++++++++++++++---------------
 hw/i2c.h      |   18 ++++++++++--------
 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 +++++-----
 16 files changed, 88 insertions(+), 86 deletions(-)

diff --git a/hw/ds1338.c b/hw/ds1338.c
index 3522af5..88d6d18 100644
--- a/hw/ds1338.c
+++ b/hw/ds1338.c
@@ -10,7 +10,7 @@
 #include "i2c.h"
 
 typedef struct {
-    i2c_slave i2c;
+    I2CSlave i2c;
     time_t offset;
     struct tm now;
     uint8_t nvram[56];
@@ -18,7 +18,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);
 
@@ -48,7 +48,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;
@@ -58,7 +58,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) {
@@ -110,7 +110,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/hw.h b/hw/hw.h
index efa04d1..fba1f87 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -668,10 +668,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),   \
 }
 
 extern const VMStateDescription vmstate_usb_device;
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 9381d01..28401f0 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);
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 bd177b7..ad45f68 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 8e3aeda..93a54e0 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -714,7 +714,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 0977cc9..d71e34f 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -130,12 +130,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;
@@ -154,7 +154,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;
@@ -177,13 +177,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 39383f4..edb7dbf 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 96a8587..3f540fc 100644
--- a/hw/z2.c
+++ b/hw/z2.c
@@ -187,12 +187,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;
@@ -210,7 +210,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) {
@@ -229,7 +229,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);
@@ -252,7 +252,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] 50+ messages in thread

* [Qemu-devel] [PATCH 20/30] i2c: smbus: convert to QEMU Object Model
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (18 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 19/30] i2c: rename i2c_slave -> I2CSlave Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 21/30] hda-codec: " Anthony Liguori
                   ` (9 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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 88d6d18..ecaf0fd 100644
--- a/hw/ds1338.c
+++ b/hw/ds1338.c
@@ -115,13 +115,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 28401f0..178351a 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 ad45f68..8f10f14 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 d71e34f..1a50afa 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -255,13 +255,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 edb7dbf..31e48f3 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 3f540fc..57cd726 100644
--- a/hw/z2.c
+++ b/hw/z2.c
@@ -270,14 +270,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] 50+ messages in thread

* [Qemu-devel] [PATCH 21/30] hda-codec: convert to QEMU Object Model
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (19 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 20/30] i2c: smbus: convert to QEMU Object Model Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 22/30] ide: " Anthony Liguori
                   ` (8 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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] 50+ messages in thread

* [Qemu-devel] [PATCH 22/30] ide: convert to QEMU Object Model
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (20 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 21/30] hda-codec: " Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 23/30] scsi: " Anthony Liguori
                   ` (7 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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] 50+ messages in thread

* [Qemu-devel] [PATCH 23/30] scsi: convert to QEMU Object Model
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (21 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 22/30] ide: " Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 24/30] spapr: convert to QEMU Object Model (v2) Anthony Liguori
                   ` (6 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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 505accd..5846708 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 6f7d3db..5acbb7c 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] 50+ messages in thread

* [Qemu-devel] [PATCH 24/30] spapr: convert to QEMU Object Model (v2)
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (22 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 23/30] scsi: " Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 25/30] virtio-serial: convert to QEMU Object Model Anthony Liguori
                   ` (5 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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   |   47 ++++++++++++++++++++++++++++-------------------
 hw/spapr_vio.h   |   35 ++++++++++++++++++++++++++---------
 hw/spapr_vscsi.c |   35 ++++++++++++++++++++++-------------
 hw/spapr_vty.c   |   35 ++++++++++++++++++++++-------------
 5 files changed, 121 insertions(+), 68 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 be6d2bd..0f9daa9 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;
         }
@@ -623,8 +623,8 @@ static void rtas_quiesce(sPAPREnvironment *spapr, uint32_t token,
 
 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;
 
     /* Don't overwrite ids assigned on the command line */
@@ -643,16 +643,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,
@@ -662,15 +662,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;
     }
 
@@ -728,9 +728,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 2430d45..2555f41 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_vio_signal(VIOsPAPRDevice *dev, target_ulong mode);
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 2849961..59a7eaa 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,
 };
 
 static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg)
@@ -163,7 +172,7 @@ static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg)
          * (early debug does work there, despite having no vty with
          * reg==0. */
         QTAILQ_FOREACH(qdev, &spapr->vio_bus->bus.children, sibling) {
-            if (qdev_get_info(qdev) == &spapr_vty_info.qdev) {
+            if (object_dynamic_cast(OBJECT(qdev), "spapr-vty")) {
                 return DO_UPCAST(VIOsPAPRDevice, qdev, qdev);
             }
         }
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 25/30] virtio-serial: convert to QEMU Object Model
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (23 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 24/30] spapr: convert to QEMU Object Model (v2) Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 26/30] grackle: remove broken pci device Anthony Liguori
                   ` (4 subsequent siblings)
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index cd20174..2e65d63 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;
     }
@@ -140,19 +139,28 @@ static int virtconsole_exitfn(VirtIOSerialPort *port)
     return 0;
 }
 
-static VirtIOSerialPortInfo virtconsole_info = {
-    .qdev.name     = "virtconsole",
-    .qdev.size     = sizeof(VirtConsole),
-    .is_console    = true,
-    .init          = virtconsole_initfn,
-    .exit          = virtconsole_exitfn,
-    .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->exit = virtconsole_exitfn;
+    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)
@@ -161,18 +169,27 @@ static void virtconsole_register(void)
 }
 device_init(virtconsole_register)
 
-static VirtIOSerialPortInfo virtserialport_info = {
-    .qdev.name     = "virtserialport",
-    .qdev.size     = sizeof(VirtConsole),
-    .init          = virtconsole_initfn,
-    .exit          = virtconsole_exitfn,
-    .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->exit = virtconsole_exitfn;
+    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 cc4e4f6..c33ad57 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -130,12 +130,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;
@@ -154,7 +154,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);
@@ -316,7 +316,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;
@@ -358,7 +358,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:
@@ -374,7 +374,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);
         }
 
@@ -403,21 +403,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;
     }
@@ -736,7 +736,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;
@@ -744,14 +744,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",
@@ -778,7 +778,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;
     }
@@ -808,8 +808,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);
@@ -817,19 +816,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)
@@ -925,3 +924,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] 50+ messages in thread

* [Qemu-devel] [PATCH 26/30] grackle: remove broken pci device
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (24 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 25/30] virtio-serial: convert to QEMU Object Model Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-08  1:46   ` Aurelien Jarno
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 27/30] unin_pci: remove phantom qdev devices in unin_pci Anthony Liguori
                   ` (3 subsequent siblings)
  29 siblings, 1 reply; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

I have no idea what's going on here, but this is broken and cannot possibly
work because:

 1) It's qdev name conflicts with a device that sits on SysBus

 2) The PCI constructor expects a SysBus device... but's it's a PCIDevice

If you do qdev_create("grackle"), the code expects to get the SysBus version
so drop the mystery PCI version.

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

diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index 1e529fb..84f1a47 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -115,27 +115,10 @@ static int pci_grackle_init_device(SysBusDevice *dev)
     return 0;
 }
 
-static int grackle_pci_host_init(PCIDevice *d)
-{
-    d->config[0x09] = 0x01;
-    return 0;
-}
-
-static PCIDeviceInfo grackle_pci_host_info = {
-    .qdev.name = "grackle",
-    .qdev.size = sizeof(PCIDevice),
-    .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_register_devices(void)
 {
     sysbus_register_dev("grackle", sizeof(GrackleState),
                         pci_grackle_init_device);
-    pci_qdev_register(&grackle_pci_host_info);
 }
 
 device_init(grackle_register_devices)
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 27/30] unin_pci: remove phantom qdev devices in unin_pci
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (25 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 26/30] grackle: remove broken pci device Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-08  2:04   ` Andreas Färber
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 28/30] pci: convert to QEMU Object Model Anthony Liguori
                   ` (2 subsequent siblings)
  29 siblings, 1 reply; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

Same problem as with grackle.  This code can't possibly work.

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

diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 14d9914..b3365fe 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -301,93 +301,16 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
     return d->host_state.bus;
 }
 
-static int unin_main_pci_host_init(PCIDevice *d)
-{
-    d->config[0x0C] = 0x08; // cache_line_size
-    d->config[0x0D] = 0x10; // latency_timer
-    d->config[0x34] = 0x00; // capabilities_pointer
-    return 0;
-}
-
-static int unin_agp_pci_host_init(PCIDevice *d)
-{
-    d->config[0x0C] = 0x08; // cache_line_size
-    d->config[0x0D] = 0x10; // latency_timer
-    //    d->config[0x34] = 0x80; // capabilities_pointer
-    return 0;
-}
-
-static int u3_agp_pci_host_init(PCIDevice *d)
-{
-    /* cache line size */
-    d->config[0x0C] = 0x08;
-    /* latency timer */
-    d->config[0x0D] = 0x10;
-    return 0;
-}
-
-static int unin_internal_pci_host_init(PCIDevice *d)
-{
-    d->config[0x0C] = 0x08; // cache_line_size
-    d->config[0x0D] = 0x10; // latency_timer
-    d->config[0x34] = 0x00; // capabilities_pointer
-    return 0;
-}
-
-static PCIDeviceInfo unin_main_pci_host_info = {
-    .qdev.name = "uni-north",
-    .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 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 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 PCIDeviceInfo unin_internal_pci_host_info = {
-    .qdev.name = "uni-north-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_register_devices(void)
 {
     sysbus_register_dev("uni-north", sizeof(UNINState),
                         pci_unin_main_init_device);
-    pci_qdev_register(&unin_main_pci_host_info);
     sysbus_register_dev("u3-agp", sizeof(UNINState),
                         pci_u3_agp_init_device);
-    pci_qdev_register(&u3_agp_pci_host_info);
     sysbus_register_dev("uni-north-agp", sizeof(UNINState),
                         pci_unin_agp_init_device);
-    pci_qdev_register(&unin_agp_pci_host_info);
     sysbus_register_dev("uni-north-pci", sizeof(UNINState),
                         pci_unin_internal_init_device);
-    pci_qdev_register(&unin_internal_pci_host_info);
 }
 
 device_init(unin_register_devices)
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 28/30] pci: convert to QEMU Object Model
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (26 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 27/30] unin_pci: remove phantom qdev devices in unin_pci Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 29/30] sysbus: " Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 30/30] virtio-s390: " Anthony Liguori
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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               |   71 ++++++++++------
 hw/bonito.c                |   47 +++++++----
 hw/cirrus_vga.c            |   33 +++++---
 hw/dec_pci.c               |   74 +++++++++++-----
 hw/e1000.c                 |   43 ++++++----
 hw/eepro100.c              |  200 +++++++++++++++++++++++++++----------------
 hw/es1370.c                |   31 ++++---
 hw/gt64xxx.c               |   39 +++++++--
 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                   |  125 ++++++++++++---------------
 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              |  114 ++++++++++++++++----------
 hw/ppce500_pci.c           |   38 ++++++---
 hw/prep_pci.c              |   23 ++++--
 hw/qdev.c                  |    1 +
 hw/qxl.c                   |   62 ++++++++-----
 hw/rtl8139.c               |   41 ++++++----
 hw/sh_pci.c                |   37 ++++++--
 hw/spapr_pci.c             |   33 ++++++--
 hw/sun4u.c                 |   71 +++++++++++-----
 hw/usb-ehci.c              |   54 ++++++++-----
 hw/usb-ohci.c              |   37 +++++---
 hw/usb-uhci.c              |  168 +++++++++++++++++++++++--------------
 hw/versatile_pci.c         |   53 +++++++++---
 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 +++++++-----
 48 files changed, 1636 insertions(+), 1021 deletions(-)

diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 3db2e0d..0a53601 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -160,23 +160,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 0dbba3b..3f8075a 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -1341,21 +1341,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 30c62ac..3455b43 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -277,11 +277,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);
         }
     }
@@ -393,23 +393,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)
@@ -482,14 +491,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);
         }
     }
@@ -550,7 +557,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..173dab3 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -436,35 +436,56 @@ 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 = {
-    .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 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 04d706a..b1fe918 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -763,25 +763,38 @@ 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 = {
-    .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/cirrus_vga.c b/hw/cirrus_vga.c
index 2505f22..5d034c6 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2911,8 +2911,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);
@@ -2946,17 +2946,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..f0ecaff 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)
@@ -77,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;
 
@@ -98,21 +105,40 @@ 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 pci_dec_21154_device_class_init(ObjectClass *klass, void *data)
+{
+    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_register_dev("dec-21154", sizeof(DECState),
-                        pci_dec_21154_init_device);
+    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/e1000.c b/hw/e1000.c
index 7ad0ea4..91fbf28 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1189,23 +1189,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/gt64xxx.c b/hw/gt64xxx.c
index 432683a..79d2dfb 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -1136,20 +1136,39 @@ 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_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/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 7b4dbf6..cddbf21 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -760,25 +760,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 3ffc32f..f6b6578 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_try_create_multifunction(PCIBus *bus, int devfn,
@@ -1583,7 +1553,7 @@ PCIDevice *pci_try_create_multifunction(PCIBus *bus, int devfn,
     }
     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,
@@ -2003,7 +1973,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;
@@ -2037,3 +2007,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 625e717..311b38c 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..8b01782 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -502,55 +502,83 @@ 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 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_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 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/ppce500_pci.c b/hw/ppce500_pci.c
index b606206..f8c4f11 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -339,20 +339,34 @@ 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 = {
-    .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/prep_pci.c b/hw/prep_pci.c
index 16c036f..d481d5f 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -115,14 +115,21 @@ static int prep_hb_initfn(PCIDevice *d)
     return 0;
 }
 
-static PCIDeviceInfo prep_hb_info = {
-    .qdev.name = "PREP Host Bridge - Motorola Raven",
-    .qdev.size = sizeof(PCIDevice),
-    .init = prep_hb_initfn,
-    .vendor_id = PCI_VENDOR_ID_MOTOROLA,
-    .device_id = PCI_DEVICE_ID_MOTOROLA_RAVEN,
-    .revision = 0x00,
-    .class_id = PCI_CLASS_BRIDGE_HOST,
+static void prep_hb_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = prep_hb_initfn;
+    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 prep_hb_info = {
+    .name = "PREP Host Bridge - Motorola Raven",
+    .size = sizeof(PCIDevice),
+    .class_init = prep_hb_class_init,
 };
 
 static void prep_register(void)
diff --git a/hw/qdev.c b/hw/qdev.c
index c6a6d20..8d2f0c0 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -115,6 +115,7 @@ static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
     return NULL;
 }
 
+
 static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
                                      Error **errp);
 
diff --git a/hw/qxl.c b/hw/qxl.c
index 5f30525..3e2653d 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..64bdcd0 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;
@@ -147,18 +147,37 @@ 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_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 = "",
+    .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/spapr_pci.c b/hw/spapr_pci.c
index 9b6a032..d088ede 100644
--- a/hw/spapr_pci.c
+++ b/hw/spapr_pci.c
@@ -190,16 +190,35 @@ 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_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);
 }
 
@@ -398,7 +417,7 @@ int spapr_populate_pci_devices(sPAPRPHBState *phb,
     /* Populate PCI devices and allocate IRQs */
     devices = 0;
     QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) {
-        PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);
+        PCIDevice *dev = PCI_DEVICE(qdev);
         int irq_index = pci_spapr_map_irq(dev, 0);
         uint32_t *irqmap = interrupt_map[devices];
         uint8_t *config = dev->config;
diff --git a/hw/sun4u.c b/hw/sun4u.c
index e3e8dde..eb114ee 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)
@@ -635,13 +642,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)
@@ -686,14 +702,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/usb-ehci.c b/hw/usb-ehci.c
index 1b10449..4beed9f 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -2262,28 +2262,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 6b28a0c..2e07a49 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1834,20 +1834,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 88b464b..f7132b1 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1191,79 +1191,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/versatile_pci.c b/hw/versatile_pci.c
index a285f7f..c2eb4dd 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -109,21 +109,52 @@ 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 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/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 9af8e3f..6bea41d 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -780,88 +780,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 af70bde..e2791cb 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1198,20 +1198,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 038128b..08c657a 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -343,15 +343,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)
@@ -382,15 +389,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)
@@ -448,21 +462,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)
@@ -516,18 +539,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] 50+ messages in thread

* [Qemu-devel] [PATCH 29/30] sysbus: convert to QEMU Object Model
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (27 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 28/30] pci: convert to QEMU Object Model Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 30/30] virtio-s390: " Anthony Liguori
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/a9mpcore.c              |   29 ++++++---
 hw/alpha_typhoon.c         |   17 ++++--
 hw/apic.c                  |   33 ++++++----
 hw/arm11mpcore.c           |   50 ++++++++++-----
 hw/arm_mptimer.c           |   23 +++++---
 hw/arm_sysctl.c            |   31 ++++++---
 hw/arm_timer.c             |   30 ++++++++-
 hw/armv7m.c                |   25 +++++---
 hw/armv7m_nvic.c           |   15 ++++-
 hw/bitbang_i2c.c           |   17 ++++--
 hw/container.c             |   17 ++++--
 hw/cs4231.c                |   27 +++++---
 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           |   16 ++++-
 hw/grlib_apbuart.c         |   25 +++++---
 hw/grlib_gptimer.c         |   31 ++++++---
 hw/grlib_irqmp.c           |   29 ++++++---
 hw/hpet.c                  |   33 ++++++----
 hw/integratorcp.c          |   40 +++++++++---
 hw/ioapic.c                |   21 ++++--
 hw/isa-bus.c               |   19 ++++--
 hw/kvmclock.c              |   19 ++++--
 hw/lan9118.c               |   27 +++++---
 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/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/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                 |   15 ++++-
 hw/pl190.c                 |   21 ++++--
 hw/ppce500_spin.c          |   15 +++-
 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/slavio_intctl.c         |   19 ++++--
 hw/slavio_misc.c           |   34 +++++++---
 hw/slavio_timer.c          |   29 ++++++---
 hw/smc91c111.c             |   29 ++++++---
 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/sysbus.c                |   41 +++++++-----
 hw/sysbus.h                |   24 +++++---
 hw/tcx.c                   |   37 +++++++----
 hw/tusb6010.c              |   17 ++++--
 hw/unin_pci.c              |   64 ++++++++++++++++---
 hw/usb-ohci.c              |   19 ++++--
 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 +++++---
 108 files changed, 2317 insertions(+), 1075 deletions(-)

diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index cd2985f..43bdfc4 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -178,16 +178,25 @@ 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[]) {
-        DEFINE_PROP_UINT32("num-cpu", a9mp_priv_state, num_cpu, 1),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property a9mp_priv_properties[] = {
+    DEFINE_PROP_UINT32("num-cpu", a9mp_priv_state, num_cpu, 1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+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),
+    .props = a9mp_priv_properties,
+    .vmsd = &vmstate_a9mp_priv,
+    .reset = a9mp_priv_reset,
+    .class_init = a9mp_priv_class_init,
 };
 
 static void a9mp_register_devices(void)
diff --git a/hw/alpha_typhoon.c b/hw/alpha_typhoon.c
index adf7382..c48094e 100644
--- a/hw/alpha_typhoon.c
+++ b/hw/alpha_typhoon.c
@@ -807,11 +807,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/apic.c b/hw/apic.c
index 9d0f460..f374230 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -1006,18 +1006,27 @@ static int apic_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo apic_info = {
-    .init = apic_init1,
-    .qdev.name = "apic",
-    .qdev.size = sizeof(APICState),
-    .qdev.vmsd = &vmstate_apic,
-    .qdev.reset = apic_reset,
-    .qdev.no_user = 1,
-    .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT8("id", APICState, id, -1),
-        DEFINE_PROP_PTR("cpu_env", APICState, cpu_env),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static Property apic_properties[] = {
+    DEFINE_PROP_UINT8("id", APICState, id, -1),
+    DEFINE_PROP_PTR("cpu_env", APICState, cpu_env),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void apic_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = apic_init1;
+}
+
+static DeviceInfo apic_info = {
+    .name = "apic",
+    .size = sizeof(APICState),
+    .vmsd = &vmstate_apic,
+    .reset = apic_reset,
+    .no_user = 1,
+    .props = apic_properties,
+    .class_init = apic_class_init,
 };
 
 static void apic_register_devices(void)
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index bc0457e..63e20d2 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -205,24 +205,42 @@ 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_rirq_state, num_cpu, 1),
+    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),
-        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_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 0a5b9d2..57d389a 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -346,10 +346,36 @@ 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,
+};
+
 static void arm_timer_register_devices(void)
 {
-    sysbus_register_dev("integrator_pit", sizeof(icp_pit_state), icp_pit_init);
-    sysbus_register_dev("sp804", sizeof(sp804_state), sp804_init);
+    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 eb8c0d6..2b02121 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -242,14 +242,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 bf8c3c5..5da2672 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -391,9 +391,22 @@ static int armv7m_nvic_init(SysBusDevice *dev)
     return 0;
 }
 
+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_info = {
+    .name = "armv7m_nvic",
+    .size = sizeof(nvic_state),
+    .class_init = armv7m_nvic_class_init,
+};
+
 static void armv7m_nvic_register_devices(void)
 {
-    sysbus_register_dev("armv7m_nvic", sizeof(nvic_state), armv7m_nvic_init);
+    sysbus_qdev_register(&armv7m_nvic_info);
 }
 
 device_init(armv7m_nvic_register_devices)
diff --git a/hw/bitbang_i2c.c b/hw/bitbang_i2c.c
index 18df411..b5fabd1 100644
--- a/hw/bitbang_i2c.c
+++ b/hw/bitbang_i2c.c
@@ -218,11 +218,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/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/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 ad059ca..12b3433 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 319cee1..33b395c 100644
--- a/hw/etraxfs_timer.c
+++ b/hw/etraxfs_timer.c
@@ -328,10 +328,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 34fb08c..3f68705 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -552,18 +552,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 84f1a47..530a72a 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -115,10 +115,22 @@ static int pci_grackle_init_device(SysBusDevice *dev)
     return 0;
 }
 
+static void grackle_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sbc->init = pci_grackle_init_device;
+}
+
+static DeviceInfo grackle_info = {
+    .name = "grackle",
+    .size = sizeof(GrackleState),
+    .class_init = grackle_class_init,
+};
+
 static void grackle_register_devices(void)
 {
-    sysbus_register_dev("grackle", sizeof(GrackleState),
-                        pci_grackle_init_device);
+    sysbus_register_withprop(&grackle_info);
 }
 
 device_init(grackle_register_devices)
diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c
index 62bdb03..63cf383 100644
--- a/hw/grlib_apbuart.c
+++ b/hw/grlib_apbuart.c
@@ -169,14 +169,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 5645054..f9f6cf8 100644
--- a/hw/grlib_gptimer.c
+++ b/hw/grlib_gptimer.c
@@ -371,17 +371,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/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 2551236..3c968c9 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -528,19 +528,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 27b07c6..bd10c7f 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -343,13 +343,20 @@ static int ioapic_init1(SysBusDevice *dev)
     return 0;
 }
 
-static SysBusDeviceInfo ioapic_info = {
-    .init = ioapic_init1,
-    .qdev.name = "ioapic",
-    .qdev.size = sizeof(IOAPICState),
-    .qdev.vmsd = &vmstate_ioapic,
-    .qdev.reset = ioapic_reset,
-    .qdev.no_user = 1,
+static void ioapic_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = ioapic_init1;
+}
+
+static DeviceInfo ioapic_info = {
+    .name = "ioapic",
+    .size = sizeof(IOAPICState),
+    .vmsd = &vmstate_ioapic,
+    .reset = ioapic_reset,
+    .no_user = 1,
+    .class_init = ioapic_class_init,
 };
 
 static void ioapic_register_devices(void)
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index cef6e8f..92d3f9c 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -184,12 +184,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/kvmclock.c b/hw/kvmclock.c
index 5388bc4..ab5db50 100644
--- a/hw/kvmclock.c
+++ b/hw/kvmclock.c
@@ -90,12 +90,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/lan9118.c b/hw/lan9118.c
index ebe39ad..1b8c6dd 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -1155,15 +1155,24 @@ 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.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,
+    .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 445847f..aaf0334 100644
--- a/hw/lm32_timer.c
+++ b/hw/lm32_timer.c
@@ -198,18 +198,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 dacc0ab..c0ff016 100644
--- a/hw/marvell_88w8618_audio.c
+++ b/hw/marvell_88w8618_audio.c
@@ -269,16 +269,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 d4a321a..798f707 100644
--- a/hw/milkymist-minimac2.c
+++ b/hw/milkymist-minimac2.c
@@ -515,19 +515,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 6dd953c..de98c68 100644
--- a/hw/milkymist-softusb.c
+++ b/hw/milkymist-softusb.c
@@ -295,27 +295,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 6326b70..aa66275 100644
--- a/hw/milkymist-sysctl.c
+++ b/hw/milkymist-sysctl.c
@@ -291,23 +291,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 01cd309..0adfddc 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/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 9324702..5a3e6e2 100644
--- a/hw/mst_fpga.c
+++ b/hw/mst_fpga.c
@@ -235,12 +235,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 fbed503..511140c 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -408,15 +408,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 */
@@ -620,11 +629,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 */
@@ -729,12 +745,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 */
@@ -897,12 +920,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 */
@@ -969,11 +999,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 */
@@ -1281,12 +1318,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 */
@@ -1427,11 +1471,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 = {
@@ -1596,14 +1647,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 7f25814..3711688 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -414,18 +414,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 a9d8d67..70f03a6 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -801,19 +801,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/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 a007ff0..71185c6 100644
--- a/hw/pl031.c
+++ b/hw/pl031.c
@@ -211,12 +211,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 cc1eb6d..cb3cd8f 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -458,28 +458,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 d05bc19..a91be28 100644
--- a/hw/pl181.c
+++ b/hw/pl181.c
@@ -465,9 +465,22 @@ static int pl181_init(SysBusDevice *dev)
     return 0;
 }
 
+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,
+};
+
 static void pl181_register_devices(void)
 {
-    sysbus_register_dev("pl181", sizeof(pl181_state), pl181_init);
+    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/ppce500_spin.c b/hw/ppce500_spin.c
index df74953..d650aee 100644
--- a/hw/ppce500_spin.c
+++ b/hw/ppce500_spin.c
@@ -202,10 +202,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/pxa2xx.c b/hw/pxa2xx.c
index 8f10f14..1fa0ef6 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 */
@@ -2291,10 +2307,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 750a279..3993955 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -81,10 +81,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 8c4d509..4102432 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -43,10 +43,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 c4b9a99..a047bbf 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -405,11 +405,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/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 2353c43..5c8c179 100644
--- a/hw/slavio_timer.c
+++ b/hw/slavio_timer.c
@@ -403,16 +403,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_vio.c b/hw/spapr_vio.c
index 0f9daa9..d5d7580 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -721,11 +721,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 93a54e0..05fd7c8 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -1019,16 +1019,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 = {
@@ -1045,14 +1054,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 = {
@@ -1074,7 +1092,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 7c75bb9..0238358 100644
--- a/hw/strongarm.c
+++ b/hw/strongarm.c
@@ -198,12 +198,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 */
@@ -410,12 +417,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 */
@@ -643,11 +657,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 */
@@ -800,11 +821,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 */
@@ -1242,17 +1270,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 */
@@ -1476,13 +1513,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 3f172ad..0a66185 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -608,10 +608,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)
@@ -648,10 +655,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)
@@ -717,13 +731,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)
@@ -775,14 +798,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/sysbus.c b/hw/sysbus.c
index 24f619f..1647b3e 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -107,29 +107,19 @@ 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_register_withprop(DeviceInfo *info)
 {
-    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);
-}
-
-void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init)
-{
-    SysBusDeviceInfo *info;
-
-    info = g_malloc0(sizeof(*info));
-    info->qdev.name = g_strdup(name);
-    info->qdev.size = size;
-    info->init = init;
-    sysbus_register_withprop(info);
+    assert(info->size >= sizeof(SysBusDevice));
+    qdev_register_subclass(info, TYPE_SYS_BUS_DEVICE);
 }
 
 DeviceState *sysbus_create_varargs(const char *name,
@@ -253,3 +243,18 @@ void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem)
 {
     memory_region_del_subregion(get_system_io(), mem);
 }
+
+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 2f4025b..33cbbf9 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,13 @@ 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_qdev_register(info) sysbus_register_withprop(info)
+void sysbus_register_withprop(DeviceInfo *info);
 
-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 a987357..5a2ab93 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -645,20 +645,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 b3365fe..43796e7 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -301,16 +301,64 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
     return d->host_state.bus;
 }
 
+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",
+    .size = sizeof(UNINState),
+    .class_init = pci_unin_main_class_init,
+};
+
+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",
+    .size = sizeof(UNINState),
+    .class_init = pci_u3_agp_class_init,
+};
+
+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",
+    .size = sizeof(UNINState),
+    .class_init = pci_unin_agp_class_init,
+};
+
+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-pci",
+    .size = sizeof(UNINState),
+    .class_init = pci_unin_internal_class_init,
+};
+
 static void unin_register_devices(void)
 {
-    sysbus_register_dev("uni-north", sizeof(UNINState),
-                        pci_unin_main_init_device);
-    sysbus_register_dev("u3-agp", sizeof(UNINState),
-                        pci_u3_agp_init_device);
-    sysbus_register_dev("uni-north-agp", sizeof(UNINState),
-                        pci_unin_agp_init_device);
-    sysbus_register_dev("uni-north-pci", sizeof(UNINState),
-                        pci_unin_internal_init_device);
+    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 2e07a49..cf10d05 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1859,12 +1859,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/versatilepb.c b/hw/versatilepb.c
index a6315fc..b752cfe 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -364,12 +364,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 596ec0e..f8fa4ab 100644
--- a/hw/xilinx_axidma.c
+++ b/hw/xilinx_axidma.c
@@ -485,15 +485,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 0b2f32a..4f3434e 100644
--- a/hw/xilinx_timer.c
+++ b/hw/xilinx_timer.c
@@ -218,15 +218,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] 50+ messages in thread

* [Qemu-devel] [PATCH 30/30] virtio-s390: convert to QEMU Object Model
  2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
                   ` (28 preceding siblings ...)
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 29/30] sysbus: " Anthony Liguori
@ 2012-01-03  0:52 ` Anthony Liguori
  29 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03  0:52 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Anthony Liguori, Markus Armbruster, Andreas Färber

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

diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index a047bbf..3bce5e4 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;
 
@@ -330,12 +338,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),
@@ -346,24 +361,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(),
@@ -372,23 +401,31 @@ 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->init = s390_virtio_busdev_init;
+    info->bus_info = &s390_virtio_bus_info;
 
-    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] 50+ messages in thread

* Re: [Qemu-devel] [PATCH 07/30] qom: add the base Object class (v2)
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 07/30] qom: add the base Object class (v2) Anthony Liguori
@ 2012-01-03  9:02   ` Paolo Bonzini
  0 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2012-01-03  9:02 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, Andreas Färber, Markus Armbruster

On 01/03/2012 01:51 AM, Anthony Liguori wrote:
> 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>

Very nice.  I still have some minor remarks, but nothing that cannot be 
bik^Wdiscussed later.

Paolo

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

* Re: [Qemu-devel] [PATCH 10/30] qdev: don't access name through info
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 10/30] qdev: don't access name through info Anthony Liguori
@ 2012-01-03  9:06   ` Paolo Bonzini
  2012-01-03 13:39     ` Anthony Liguori
  0 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2012-01-03  9:06 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel, Andreas Färber, Markus Armbruster

On 01/03/2012 01:51 AM, Anthony Liguori wrote:
>       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);

It's a pity that this loses type-safety.

Perhaps we should look at adding a warning for "unsafe" pointer casts to 
GCC.

Paolo

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

* Re: [Qemu-devel] [PATCH 10/30] qdev: don't access name through info
  2012-01-03  9:06   ` Paolo Bonzini
@ 2012-01-03 13:39     ` Anthony Liguori
  2012-01-03 13:41       ` Paolo Bonzini
  0 siblings, 1 reply; 50+ messages in thread
From: Anthony Liguori @ 2012-01-03 13:39 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Markus Armbruster, Anthony Liguori, qemu-devel, Andreas Färber

On 01/03/2012 03:06 AM, Paolo Bonzini wrote:
> On 01/03/2012 01:51 AM, Anthony Liguori wrote:
>> 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);
>
> It's a pity that this loses type-safety.

You mean at run time or because OBJECT() cast is so lose?  We can fix the later..

Regards,

Anthony Liguori

>
> Perhaps we should look at adding a warning for "unsafe" pointer casts to GCC.
>
> Paolo
>

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

* Re: [Qemu-devel] [PATCH 10/30] qdev: don't access name through info
  2012-01-03 13:39     ` Anthony Liguori
@ 2012-01-03 13:41       ` Paolo Bonzini
  0 siblings, 0 replies; 50+ messages in thread
From: Paolo Bonzini @ 2012-01-03 13:41 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Markus Armbruster, Anthony Liguori, qemu-devel, Andreas Färber

On 01/03/2012 02:39 PM, Anthony Liguori wrote:
>>
>> It's a pity that this loses type-safety.
>
> You mean at run time or because OBJECT() cast is so lose?  We can fix
> the later..

At compile-time, i.e. the latter.  But no problem, I really think it 
should be fixed in the compiler.

Paolo

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

* Re: [Qemu-devel] [PATCH 04/30] ppc_prep: convert host bridge to qdev
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 04/30] ppc_prep: convert host bridge to qdev Anthony Liguori
@ 2012-01-03 14:57   ` Andreas Färber
  2012-01-07  0:11     ` Andreas Färber
  0 siblings, 1 reply; 50+ messages in thread
From: Andreas Färber @ 2012-01-03 14:57 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Paolo Bonzini, Hervé Poussineau, qemu-devel, Markus Armbruster

Am 03.01.2012 01:51, schrieb Anthony Liguori:
> Untested beyond compile.  But it's a very simple conversion.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

Seems like we've crossed paths now. I have a more complete patch using
different naming, but it's not yet working. I'll have to bisect.

Andreas

> ---
>  hw/prep_pci.c |   38 +++++++++++++++++++++++++++-----------
>  1 files changed, 27 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/prep_pci.c b/hw/prep_pci.c
> index ea9fb69..16c036f 100644
> --- a/hw/prep_pci.c
> +++ b/hw/prep_pci.c
> @@ -106,12 +106,37 @@ static void prep_set_irq(void *opaque, int irq_num, int level)
>      qemu_set_irq(pic[(irq_num & 1) ? 11 : 9] , level);
>  }
>  
> +static int prep_hb_initfn(PCIDevice *d)
> +{
> +    d->config[0x0C] = 0x08; // cache_line_size
> +    d->config[0x0D] = 0x10; // latency_timer
> +    d->config[0x34] = 0x00; // capabilities_pointer
> +
> +    return 0;
> +}
> +
> +static PCIDeviceInfo prep_hb_info = {
> +    .qdev.name = "PREP Host Bridge - Motorola Raven",
> +    .qdev.size = sizeof(PCIDevice),
> +    .init = prep_hb_initfn,
> +    .vendor_id = PCI_VENDOR_ID_MOTOROLA,
> +    .device_id = PCI_DEVICE_ID_MOTOROLA_RAVEN,
> +    .revision = 0x00,
> +    .class_id = PCI_CLASS_BRIDGE_HOST,
> +};
> +
> +static void prep_register(void)
> +{
> +    pci_qdev_register(&prep_hb_info);
> +}
> +
> +device_init(prep_register);
> +
>  PCIBus *pci_prep_init(qemu_irq *pic,
>                        MemoryRegion *address_space_mem,
>                        MemoryRegion *address_space_io)
>  {
>      PREPPCIState *s;
> -    PCIDevice *d;
>  
>      s = g_malloc0(sizeof(PREPPCIState));
>      s->bus = pci_register_bus(NULL, "pci",
> @@ -133,16 +158,7 @@ PCIBus *pci_prep_init(qemu_irq *pic,
>      memory_region_init_io(&s->mmcfg, &PPC_PCIIO_ops, s, "pciio", 0x00400000);
>      memory_region_add_subregion(address_space_mem, 0x80800000, &s->mmcfg);
>  
> -    /* PCI host bridge */
> -    d = pci_register_device(s->bus, "PREP Host Bridge - Motorola Raven",
> -                            sizeof(PCIDevice), 0, NULL, NULL);
> -    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_MOTOROLA);
> -    pci_config_set_device_id(d->config, PCI_DEVICE_ID_MOTOROLA_RAVEN);
> -    d->config[0x08] = 0x00; // revision
> -    pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
> -    d->config[0x0C] = 0x08; // cache_line_size
> -    d->config[0x0D] = 0x10; // latency_timer
> -    d->config[0x34] = 0x00; // capabilities_pointer
> +    pci_create_simple(s->bus, 0, "PREP Host Bridge - Motorola Raven");
>  
>      return s->bus;
>  }

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

* Re: [Qemu-devel] [PATCH 14/30] qdev: prepare source tree for code conversion
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 14/30] qdev: prepare source tree for code conversion Anthony Liguori
@ 2012-01-04 14:07   ` Andreas Färber
  2012-01-04 14:24     ` Anthony Liguori
  0 siblings, 1 reply; 50+ messages in thread
From: Andreas Färber @ 2012-01-04 14:07 UTC (permalink / raw)
  To: Anthony Liguori, malc; +Cc: Paolo Bonzini, qemu-devel, Markus Armbruster

Am 03.01.2012 01:52, schrieb Anthony Liguori:
> 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>
> ---

> 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)

It is worth noting that this is *not* a stylistic change but actually
dropping device information from the tree.

malc, what is the meaning of the currently unused values? Would it make
sense to move them to a separate PCIDeviceInfo so that they survive the
QOM introduction?

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] 50+ messages in thread

* Re: [Qemu-devel] [PATCH 14/30] qdev: prepare source tree for code conversion
  2012-01-04 14:07   ` Andreas Färber
@ 2012-01-04 14:24     ` Anthony Liguori
  0 siblings, 0 replies; 50+ messages in thread
From: Anthony Liguori @ 2012-01-04 14:24 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Paolo Bonzini, Anthony Liguori, qemu-devel, Markus Armbruster

On 01/04/2012 08:07 AM, Andreas Färber wrote:
> Am 03.01.2012 01:52, schrieb Anthony Liguori:
>> 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>
>> ---
>
>> 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)
>
> It is worth noting that this is *not* a stylistic change but actually
> dropping device information from the tree.

The #else clause is dead code.  It continues to remain in git history but it 
doesn't serve any purpose in it's current form (it does not affect the build 
whatsoever).

>
> malc, what is the meaning of the currently unused values? Would it make
> sense to move them to a separate PCIDeviceInfo so that they survive the
> QOM introduction?

FWIW, I'm fairly sure you can set subsystem vendor and device id via qdev 
properties so you can always override to these values if you want.

Regards,

Anthony Liguori

> Andreas
>

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

* Re: [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support Anthony Liguori
@ 2012-01-05 15:16   ` François Revol
  2012-01-13 10:59   ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 50+ messages in thread
From: François Revol @ 2012-01-05 15:16 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Paolo Bonzini, qemu-devel, Andreas Färber, Markus Armbruster

Le -10/01/-28163 20:59, Anthony Liguori a écrit :
> This board never worked with TCG.  It hasn't been updated since 0.13.0.  I'm
> fairly sure hardware doesn't exist anymore that you can run the KVM support
> with.
> 
> So let's remove it.  It can always be restored later if there is interest again.


I'd like to have a ppc440 board around still...
I once pondered adding the sam440, but don't have the time.

Anyone looking into it ?

It'd be quite wow to have the latest Amiga X-1000 too but it has a very
custom chipset.

François.

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

* Re: [Qemu-devel] [PATCH 04/30] ppc_prep: convert host bridge to qdev
  2012-01-03 14:57   ` Andreas Färber
@ 2012-01-07  0:11     ` Andreas Färber
  0 siblings, 0 replies; 50+ messages in thread
From: Andreas Färber @ 2012-01-07  0:11 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Paolo Bonzini, Anthony Liguori, Hervé Poussineau,
	qemu-devel, Markus Armbruster

Am 03.01.2012 15:57, schrieb Andreas Färber:
> Am 03.01.2012 01:51, schrieb Anthony Liguori:
>> Untested beyond compile.  But it's a very simple conversion.
>>
>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> 
> Seems like we've crossed paths now. I have a more complete patch using
> different naming

Minimal series sent out. Please review.

Andreas

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

* Re: [Qemu-devel] [PATCH 26/30] grackle: remove broken pci device
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 26/30] grackle: remove broken pci device Anthony Liguori
@ 2012-01-08  1:46   ` Aurelien Jarno
  2012-01-08  1:55     ` Andreas Färber
  0 siblings, 1 reply; 50+ messages in thread
From: Aurelien Jarno @ 2012-01-08  1:46 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Paolo Bonzini, qemu-devel, Andreas Färber, Markus Armbruster

On Mon, Jan 02, 2012 at 06:52:15PM -0600, Anthony Liguori wrote:
> I have no idea what's going on here, but this is broken and cannot possibly
> work because:
> 
>  1) It's qdev name conflicts with a device that sits on SysBus
> 
>  2) The PCI constructor expects a SysBus device... but's it's a PCIDevice
> 
> If you do qdev_create("grackle"), the code expects to get the SysBus version
> so drop the mystery PCI version.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  hw/grackle_pci.c |   17 -----------------
>  1 files changed, 0 insertions(+), 17 deletions(-)

NACK. Maybe the current code is not correct, but it actually works, and
a PCI host device like this one is definitely needed on the system.

Trying to apply this patch, qemu-system-ppc fails to start with:

  qemu: hardware error: Unknown device 'grackle' for bus 'PCI'
 

-- 
Aurelien Jarno	                        GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net

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

* Re: [Qemu-devel] [PATCH 26/30] grackle: remove broken pci device
  2012-01-08  1:46   ` Aurelien Jarno
@ 2012-01-08  1:55     ` Andreas Färber
  0 siblings, 0 replies; 50+ messages in thread
From: Andreas Färber @ 2012-01-08  1:55 UTC (permalink / raw)
  To: Aurelien Jarno
  Cc: Paolo Bonzini, Anthony Liguori, qemu-devel, Alexander Graf,
	Markus Armbruster

Am 08.01.2012 02:46, schrieb Aurelien Jarno:
> On Mon, Jan 02, 2012 at 06:52:15PM -0600, Anthony Liguori wrote:
>> I have no idea what's going on here, but this is broken and cannot possibly
>> work because:
>>
>>  1) It's qdev name conflicts with a device that sits on SysBus
>>
>>  2) The PCI constructor expects a SysBus device... but's it's a PCIDevice
>>
>> If you do qdev_create("grackle"), the code expects to get the SysBus version
>> so drop the mystery PCI version.
>>
>> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
>> ---
>>  hw/grackle_pci.c |   17 -----------------
>>  1 files changed, 0 insertions(+), 17 deletions(-)
> 
> NACK. Maybe the current code is not correct, but it actually works, and
> a PCI host device like this one is definitely needed on the system.
> 
> Trying to apply this patch, qemu-system-ppc fails to start with:
> 
>   qemu: hardware error: Unknown device 'grackle' for bus 'PCI'

Similar for uni-north and qemu-system-ppc64 or -M mac99 (cf. v1).

Now that PReP is somewhat restored on my branch, if Anthony wants, I can
send patches to resolve the name conflicts next week.

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] 50+ messages in thread

* Re: [Qemu-devel] [PATCH 27/30] unin_pci: remove phantom qdev devices in unin_pci
  2012-01-03  0:52 ` [Qemu-devel] [PATCH 27/30] unin_pci: remove phantom qdev devices in unin_pci Anthony Liguori
@ 2012-01-08  2:04   ` Andreas Färber
  0 siblings, 0 replies; 50+ messages in thread
From: Andreas Färber @ 2012-01-08  2:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Aurelien Jarno

Am 03.01.2012 01:52, schrieb Anthony Liguori:
> Same problem as with grackle.  This code can't possibly work.

For the record, this comment was not updated for v2: It does work.

The name conflict needs to be resolved, e.g., by adding -pcihost to the
SysBus device names.

Andreas

> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  hw/unin_pci.c |   77 ---------------------------------------------------------
>  1 files changed, 0 insertions(+), 77 deletions(-)
> 
> diff --git a/hw/unin_pci.c b/hw/unin_pci.c
> index 14d9914..b3365fe 100644
> --- a/hw/unin_pci.c
> +++ b/hw/unin_pci.c
> @@ -301,93 +301,16 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
>      return d->host_state.bus;
>  }
>  
> -static int unin_main_pci_host_init(PCIDevice *d)
> -{
> -    d->config[0x0C] = 0x08; // cache_line_size
> -    d->config[0x0D] = 0x10; // latency_timer
> -    d->config[0x34] = 0x00; // capabilities_pointer
> -    return 0;
> -}
> -
> -static int unin_agp_pci_host_init(PCIDevice *d)
> -{
> -    d->config[0x0C] = 0x08; // cache_line_size
> -    d->config[0x0D] = 0x10; // latency_timer
> -    //    d->config[0x34] = 0x80; // capabilities_pointer
> -    return 0;
> -}
> -
> -static int u3_agp_pci_host_init(PCIDevice *d)
> -{
> -    /* cache line size */
> -    d->config[0x0C] = 0x08;
> -    /* latency timer */
> -    d->config[0x0D] = 0x10;
> -    return 0;
> -}
> -
> -static int unin_internal_pci_host_init(PCIDevice *d)
> -{
> -    d->config[0x0C] = 0x08; // cache_line_size
> -    d->config[0x0D] = 0x10; // latency_timer
> -    d->config[0x34] = 0x00; // capabilities_pointer
> -    return 0;
> -}
> -
> -static PCIDeviceInfo unin_main_pci_host_info = {
> -    .qdev.name = "uni-north",
> -    .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 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 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 PCIDeviceInfo unin_internal_pci_host_info = {
> -    .qdev.name = "uni-north-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_register_devices(void)
>  {
>      sysbus_register_dev("uni-north", sizeof(UNINState),
>                          pci_unin_main_init_device);
> -    pci_qdev_register(&unin_main_pci_host_info);
>      sysbus_register_dev("u3-agp", sizeof(UNINState),
>                          pci_u3_agp_init_device);
> -    pci_qdev_register(&u3_agp_pci_host_info);
>      sysbus_register_dev("uni-north-agp", sizeof(UNINState),
>                          pci_unin_agp_init_device);
> -    pci_qdev_register(&unin_agp_pci_host_info);
>      sysbus_register_dev("uni-north-pci", sizeof(UNINState),
>                          pci_unin_internal_init_device);
> -    pci_qdev_register(&unin_internal_pci_host_info);
>  }
>  
>  device_init(unin_register_devices)

-- 
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] 50+ messages in thread

* Re: [Qemu-devel] [PATCH 09/30] qdev: move qdev->info to class
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 09/30] qdev: move qdev->info to class Anthony Liguori
@ 2012-01-08  2:27   ` Andreas Färber
  0 siblings, 0 replies; 50+ messages in thread
From: Andreas Färber @ 2012-01-08  2:27 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, qemu-devel, Markus Armbruster

Am 03.01.2012 01:51, schrieb Anthony Liguori:
> 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>
> ---

> 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/pci.c b/hw/pci.c
> index fd575ac..64cd08f 100644
> --- a/hw/pci.c
> +++ b/hw/pci.c

> @@ -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);

Would've been worth its own preparatory patch IMO since going beyond
pure qdev_get_info(&dev->qdev)->unplug conversion for piix3-ide-xen.

> @@ -1757,10 +1759,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);

Add braces while you're touching it?

Otherwise mostly mechanical and looks okay:

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] 50+ messages in thread

* Re: [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support
  2012-01-03  0:51 ` [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support Anthony Liguori
  2012-01-05 15:16   ` François Revol
@ 2012-01-13 10:59   ` Benjamin Herrenschmidt
  2012-01-13 11:04     ` Andreas Färber
  1 sibling, 1 reply; 50+ messages in thread
From: Benjamin Herrenschmidt @ 2012-01-13 10:59 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Paolo Bonzini, qemu-devel, Andreas Färber, Markus Armbruster

On Mon, 2012-01-02 at 18:51 -0600, Anthony Liguori wrote:
> This board never worked with TCG.  It hasn't been updated since 0.13.0.  I'm
> fairly sure hardware doesn't exist anymore that you can run the KVM support
> with.

It does exist, I have one :-)

> So let's remove it.  It can always be restored later if there is interest again.

Cheers,
Ben.

> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> ---
>  Makefile.target    |    3 +-
>  hw/ppc440.c        |  106 ---------------
>  hw/ppc440.h        |   21 ---
>  hw/ppc440_bamboo.c |  215 -----------------------------
>  hw/ppc4xx_pci.c    |  381 ----------------------------------------------------
>  hw/virtex_ml507.c  |    1 -
>  6 files changed, 1 insertions(+), 726 deletions(-)
>  delete mode 100644 hw/ppc440.c
>  delete mode 100644 hw/ppc440.h
>  delete mode 100644 hw/ppc440_bamboo.c
>  delete mode 100644 hw/ppc4xx_pci.c
> 
> diff --git a/Makefile.target b/Makefile.target
> index 3261383..b8ccf07 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -246,8 +246,7 @@ obj-ppc-$(CONFIG_PSERIES) += spapr.o spapr_hcall.o spapr_rtas.o spapr_vio.o
>  obj-ppc-$(CONFIG_PSERIES) += xics.o spapr_vty.o spapr_llan.o spapr_vscsi.o
>  obj-ppc-$(CONFIG_PSERIES) += spapr_pci.o device-hotplug.o pci-hotplug.o
>  # PowerPC 4xx boards
> -obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
> -obj-ppc-y += ppc440.o ppc440_bamboo.o
> +obj-ppc-y += ppc4xx_devs.o ppc405_uc.o ppc405_boards.o
>  # PowerPC E500 boards
>  obj-ppc-y += ppce500_mpc8544ds.o mpc8544_guts.o ppce500_spin.o
>  # PowerPC 440 Xilinx ML507 reference board.
> diff --git a/hw/ppc440.c b/hw/ppc440.c
> deleted file mode 100644
> index cd8a95d..0000000
> --- a/hw/ppc440.c
> +++ /dev/null
> @@ -1,106 +0,0 @@
> -/*
> - * Qemu PowerPC 440 chip emulation
> - *
> - * Copyright 2007 IBM Corporation.
> - * Authors:
> - * 	Jerone Young <jyoung5@us.ibm.com>
> - * 	Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
> - * 	Hollis Blanchard <hollisb@us.ibm.com>
> - *
> - * This work is licensed under the GNU GPL license version 2 or later.
> - *
> - */
> -
> -#include "hw.h"
> -#include "pc.h"
> -#include "isa.h"
> -#include "ppc.h"
> -#include "ppc4xx.h"
> -#include "ppc440.h"
> -#include "ppc405.h"
> -#include "sysemu.h"
> -#include "kvm.h"
> -
> -#define PPC440EP_PCI_CONFIG     0xeec00000
> -#define PPC440EP_PCI_INTACK     0xeed00000
> -#define PPC440EP_PCI_SPECIAL    0xeed00000
> -#define PPC440EP_PCI_REGS       0xef400000
> -#define PPC440EP_PCI_IO         0xe8000000
> -#define PPC440EP_PCI_IOLEN      0x00010000
> -
> -#define PPC440EP_SDRAM_NR_BANKS 4
> -
> -static const unsigned int ppc440ep_sdram_bank_sizes[] = {
> -    256<<20, 128<<20, 64<<20, 32<<20, 16<<20, 8<<20, 0
> -};
> -
> -CPUState *ppc440ep_init(MemoryRegion *address_space_mem, ram_addr_t *ram_size,
> -                        PCIBus **pcip, const unsigned int pci_irq_nrs[4],
> -                        int do_init, const char *cpu_model)
> -{
> -    MemoryRegion *ram_memories
> -        = g_malloc(PPC440EP_SDRAM_NR_BANKS * sizeof(*ram_memories));
> -    target_phys_addr_t ram_bases[PPC440EP_SDRAM_NR_BANKS];
> -    target_phys_addr_t ram_sizes[PPC440EP_SDRAM_NR_BANKS];
> -    CPUState *env;
> -    qemu_irq *pic;
> -    qemu_irq *irqs;
> -    qemu_irq *pci_irqs;
> -
> -    if (cpu_model == NULL) {
> -        cpu_model = "440-Xilinx"; // XXX: should be 440EP
> -    }
> -    env = cpu_init(cpu_model);
> -    if (!env) {
> -        fprintf(stderr, "Unable to initialize CPU!\n");
> -        exit(1);
> -    }
> -
> -    ppc_dcr_init(env, NULL, NULL);
> -
> -    /* interrupt controller */
> -    irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
> -    irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];
> -    irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT];
> -    pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
> -
> -    /* SDRAM controller */
> -    memset(ram_bases, 0, sizeof(ram_bases));
> -    memset(ram_sizes, 0, sizeof(ram_sizes));
> -    *ram_size = ppc4xx_sdram_adjust(*ram_size, PPC440EP_SDRAM_NR_BANKS,
> -                                    ram_memories,
> -                                    ram_bases, ram_sizes,
> -                                    ppc440ep_sdram_bank_sizes);
> -    /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */
> -    ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_memories,
> -                      ram_bases, ram_sizes, do_init);
> -
> -    /* PCI */
> -    pci_irqs = g_malloc(sizeof(qemu_irq) * 4);
> -    pci_irqs[0] = pic[pci_irq_nrs[0]];
> -    pci_irqs[1] = pic[pci_irq_nrs[1]];
> -    pci_irqs[2] = pic[pci_irq_nrs[2]];
> -    pci_irqs[3] = pic[pci_irq_nrs[3]];
> -    *pcip = ppc4xx_pci_init(env, pci_irqs,
> -                            PPC440EP_PCI_CONFIG,
> -                            PPC440EP_PCI_INTACK,
> -                            PPC440EP_PCI_SPECIAL,
> -                            PPC440EP_PCI_REGS);
> -    if (!*pcip)
> -        printf("couldn't create PCI controller!\n");
> -
> -    isa_mmio_init(PPC440EP_PCI_IO, PPC440EP_PCI_IOLEN);
> -
> -    if (serial_hds[0] != NULL) {
> -        serial_mm_init(address_space_mem, 0xef600300, 0, pic[0],
> -                       PPC_SERIAL_MM_BAUDBASE, serial_hds[0],
> -                       DEVICE_BIG_ENDIAN);
> -    }
> -    if (serial_hds[1] != NULL) {
> -        serial_mm_init(address_space_mem, 0xef600400, 0, pic[1],
> -                       PPC_SERIAL_MM_BAUDBASE, serial_hds[1],
> -                       DEVICE_BIG_ENDIAN);
> -    }
> -
> -    return env;
> -}
> diff --git a/hw/ppc440.h b/hw/ppc440.h
> deleted file mode 100644
> index 9c27c36..0000000
> --- a/hw/ppc440.h
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -/*
> - * Qemu PowerPC 440 board emualtion
> - *
> - * Copyright 2007 IBM Corporation.
> - * Authors: Jerone Young <jyoung5@us.ibm.com>
> - * 	    Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
> - *
> - * This work is licensed under the GNU GPL licence version 2 or later
> - *
> - */
> -
> -#ifndef QEMU_PPC440_H
> -#define QEMU_PPC440_H
> -
> -#include "hw.h"
> -
> -CPUState *ppc440ep_init(MemoryRegion *address_space, ram_addr_t *ram_size,
> -                        PCIBus **pcip, const unsigned int pci_irq_nrs[4],
> -                        int do_init, const char *cpu_model);
> -
> -#endif
> diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
> deleted file mode 100644
> index b734e3a..0000000
> --- a/hw/ppc440_bamboo.c
> +++ /dev/null
> @@ -1,215 +0,0 @@
> -/*
> - * Qemu PowerPC 440 Bamboo board emulation
> - *
> - * Copyright 2007 IBM Corporation.
> - * Authors:
> - * 	Jerone Young <jyoung5@us.ibm.com>
> - * 	Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
> - * 	Hollis Blanchard <hollisb@us.ibm.com>
> - *
> - * This work is licensed under the GNU GPL license version 2 or later.
> - *
> - */
> -
> -#include "config.h"
> -#include "qemu-common.h"
> -#include "net.h"
> -#include "hw.h"
> -#include "pci.h"
> -#include "boards.h"
> -#include "ppc440.h"
> -#include "kvm.h"
> -#include "kvm_ppc.h"
> -#include "device_tree.h"
> -#include "loader.h"
> -#include "elf.h"
> -#include "exec-memory.h"
> -
> -#define BINARY_DEVICE_TREE_FILE "bamboo.dtb"
> -
> -/* from u-boot */
> -#define KERNEL_ADDR  0x1000000
> -#define FDT_ADDR     0x1800000
> -#define RAMDISK_ADDR 0x1900000
> -
> -static int bamboo_load_device_tree(target_phys_addr_t addr,
> -                                     uint32_t ramsize,
> -                                     target_phys_addr_t initrd_base,
> -                                     target_phys_addr_t initrd_size,
> -                                     const char *kernel_cmdline)
> -{
> -    int ret = -1;
> -#ifdef CONFIG_FDT
> -    uint32_t mem_reg_property[] = { 0, 0, ramsize };
> -    char *filename;
> -    int fdt_size;
> -    void *fdt;
> -    uint32_t tb_freq = 400000000;
> -    uint32_t clock_freq = 400000000;
> -
> -    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
> -    if (!filename) {
> -        goto out;
> -    }
> -    fdt = load_device_tree(filename, &fdt_size);
> -    g_free(filename);
> -    if (fdt == NULL) {
> -        goto out;
> -    }
> -
> -    /* Manipulate device tree in memory. */
> -
> -    ret = qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,
> -                               sizeof(mem_reg_property));
> -    if (ret < 0)
> -        fprintf(stderr, "couldn't set /memory/reg\n");
> -
> -    ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
> -                                    initrd_base);
> -    if (ret < 0)
> -        fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
> -
> -    ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
> -                                    (initrd_base + initrd_size));
> -    if (ret < 0)
> -        fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
> -
> -    ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
> -                                      kernel_cmdline);
> -    if (ret < 0)
> -        fprintf(stderr, "couldn't set /chosen/bootargs\n");
> -
> -    /* Copy data from the host device tree into the guest. Since the guest can
> -     * directly access the timebase without host involvement, we must expose
> -     * the correct frequencies. */
> -    if (kvm_enabled()) {
> -        tb_freq = kvmppc_get_tbfreq();
> -        clock_freq = kvmppc_get_clockfreq();
> -    }
> -
> -    qemu_devtree_setprop_cell(fdt, "/cpus/cpu@0", "clock-frequency",
> -                              clock_freq);
> -    qemu_devtree_setprop_cell(fdt, "/cpus/cpu@0", "timebase-frequency",
> -                              tb_freq);
> -
> -    ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
> -    g_free(fdt);
> -
> -out:
> -#endif
> -
> -    return ret;
> -}
> -
> -static void bamboo_init(ram_addr_t ram_size,
> -                        const char *boot_device,
> -                        const char *kernel_filename,
> -                        const char *kernel_cmdline,
> -                        const char *initrd_filename,
> -                        const char *cpu_model)
> -{
> -    unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 };
> -    MemoryRegion *address_space_mem = get_system_memory();
> -    PCIBus *pcibus;
> -    CPUState *env;
> -    uint64_t elf_entry;
> -    uint64_t elf_lowaddr;
> -    target_phys_addr_t entry = 0;
> -    target_phys_addr_t loadaddr = 0;
> -    target_long initrd_size = 0;
> -    int success;
> -    int i;
> -
> -    /* Setup CPU. */
> -    env = ppc440ep_init(address_space_mem, &ram_size, &pcibus,
> -                        pci_irq_nrs, 1, cpu_model);
> -
> -    if (pcibus) {
> -        /* Register network interfaces. */
> -        for (i = 0; i < nb_nics; i++) {
> -            /* There are no PCI NICs on the Bamboo board, but there are
> -             * PCI slots, so we can pick whatever default model we want. */
> -            pci_nic_init_nofail(&nd_table[i], "e1000", NULL);
> -        }
> -    }
> -
> -    /* Load kernel. */
> -    if (kernel_filename) {
> -        success = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
> -        if (success < 0) {
> -            success = load_elf(kernel_filename, NULL, NULL, &elf_entry,
> -                               &elf_lowaddr, NULL, 1, ELF_MACHINE, 0);
> -            entry = elf_entry;
> -            loadaddr = elf_lowaddr;
> -        }
> -        /* XXX try again as binary */
> -        if (success < 0) {
> -            fprintf(stderr, "qemu: could not load kernel '%s'\n",
> -                    kernel_filename);
> -            exit(1);
> -        }
> -    }
> -
> -    /* Load initrd. */
> -    if (initrd_filename) {
> -        initrd_size = load_image_targphys(initrd_filename, RAMDISK_ADDR,
> -                                          ram_size - RAMDISK_ADDR);
> -
> -        if (initrd_size < 0) {
> -            fprintf(stderr, "qemu: could not load ram disk '%s' at %x\n",
> -                    initrd_filename, RAMDISK_ADDR);
> -            exit(1);
> -        }
> -    }
> -
> -    /* If we're loading a kernel directly, we must load the device tree too. */
> -    if (kernel_filename) {
> -        if (bamboo_load_device_tree(FDT_ADDR, ram_size, RAMDISK_ADDR,
> -                                    initrd_size, kernel_cmdline) < 0) {
> -            fprintf(stderr, "couldn't load device tree\n");
> -            exit(1);
> -        }
> -
> -        /* Set initial guest state. */
> -        env->gpr[1] = (16<<20) - 8;
> -        env->gpr[3] = FDT_ADDR;
> -        env->nip = entry;
> -        /* XXX we currently depend on KVM to create some initial TLB entries. */
> -    }
> -
> -    if (kvm_enabled())
> -        kvmppc_init();
> -}
> -
> -static QEMUMachine bamboo_machine = {
> -    .name = "bamboo-0.13",
> -    .alias = "bamboo",
> -    .desc = "bamboo",
> -    .init = bamboo_init,
> -};
> -
> -static QEMUMachine bamboo_machine_v0_12 = {
> -    .name = "bamboo-0.12",
> -    .desc = "bamboo",
> -    .init = bamboo_init,
> -    .compat_props = (GlobalProperty[]) {
> -        {
> -            .driver   = "virtio-serial-pci",
> -            .property = "max_ports",
> -            .value    = stringify(1),
> -        },{
> -            .driver   = "virtio-serial-pci",
> -            .property = "vectors",
> -            .value    = stringify(0),
> -        },
> -        { /* end of list */ }
> -    },
> -};
> -
> -static void bamboo_machine_init(void)
> -{
> -    qemu_register_machine(&bamboo_machine);
> -    qemu_register_machine(&bamboo_machine_v0_12);
> -}
> -
> -machine_init(bamboo_machine_init);
> diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
> deleted file mode 100644
> index 2c69210..0000000
> --- a/hw/ppc4xx_pci.c
> +++ /dev/null
> @@ -1,381 +0,0 @@
> -/*
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License, version 2, as
> - * published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - * GNU General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, see <http://www.gnu.org/licenses/>.
> - *
> - * Copyright IBM Corp. 2008
> - *
> - * Authors: Hollis Blanchard <hollisb@us.ibm.com>
> - */
> -
> -/* This file implements emulation of the 32-bit PCI controller found in some
> - * 4xx SoCs, such as the 440EP. */
> -
> -#include "hw.h"
> -#include "ppc.h"
> -#include "ppc4xx.h"
> -#include "pci.h"
> -#include "pci_host.h"
> -#include "exec-memory.h"
> -
> -#undef DEBUG
> -#ifdef DEBUG
> -#define DPRINTF(fmt, ...) do { printf(fmt, ## __VA_ARGS__); } while (0)
> -#else
> -#define DPRINTF(fmt, ...)
> -#endif /* DEBUG */
> -
> -struct PCIMasterMap {
> -    uint32_t la;
> -    uint32_t ma;
> -    uint32_t pcila;
> -    uint32_t pciha;
> -};
> -
> -struct PCITargetMap {
> -    uint32_t ms;
> -    uint32_t la;
> -};
> -
> -#define PPC4xx_PCI_NR_PMMS 3
> -#define PPC4xx_PCI_NR_PTMS 2
> -
> -struct PPC4xxPCIState {
> -    struct PCIMasterMap pmm[PPC4xx_PCI_NR_PMMS];
> -    struct PCITargetMap ptm[PPC4xx_PCI_NR_PTMS];
> -
> -    PCIHostState pci_state;
> -    PCIDevice *pci_dev;
> -    MemoryRegion iomem_addr;
> -    MemoryRegion iomem_regs;
> -};
> -typedef struct PPC4xxPCIState PPC4xxPCIState;
> -
> -#define PCIC0_CFGADDR       0x0
> -#define PCIC0_CFGDATA       0x4
> -
> -/* PLB Memory Map (PMM) registers specify which PLB addresses are translated to
> - * PCI accesses. */
> -#define PCIL0_PMM0LA        0x0
> -#define PCIL0_PMM0MA        0x4
> -#define PCIL0_PMM0PCILA     0x8
> -#define PCIL0_PMM0PCIHA     0xc
> -#define PCIL0_PMM1LA        0x10
> -#define PCIL0_PMM1MA        0x14
> -#define PCIL0_PMM1PCILA     0x18
> -#define PCIL0_PMM1PCIHA     0x1c
> -#define PCIL0_PMM2LA        0x20
> -#define PCIL0_PMM2MA        0x24
> -#define PCIL0_PMM2PCILA     0x28
> -#define PCIL0_PMM2PCIHA     0x2c
> -
> -/* PCI Target Map (PTM) registers specify which PCI addresses are translated to
> - * PLB accesses. */
> -#define PCIL0_PTM1MS        0x30
> -#define PCIL0_PTM1LA        0x34
> -#define PCIL0_PTM2MS        0x38
> -#define PCIL0_PTM2LA        0x3c
> -#define PCI_REG_SIZE        0x40
> -
> -
> -static uint64_t pci4xx_cfgaddr_read(void *opaque, target_phys_addr_t addr,
> -                                    unsigned size)
> -{
> -    PPC4xxPCIState *ppc4xx_pci = opaque;
> -
> -    return ppc4xx_pci->pci_state.config_reg;
> -}
> -
> -static void pci4xx_cfgaddr_write(void *opaque, target_phys_addr_t addr,
> -                                  uint64_t value, unsigned size)
> -{
> -    PPC4xxPCIState *ppc4xx_pci = opaque;
> -
> -    ppc4xx_pci->pci_state.config_reg = value & ~0x3;
> -}
> -
> -static const MemoryRegionOps pci4xx_cfgaddr_ops = {
> -    .read = pci4xx_cfgaddr_read,
> -    .write = pci4xx_cfgaddr_write,
> -    .endianness = DEVICE_LITTLE_ENDIAN,
> -};
> -
> -static void ppc4xx_pci_reg_write4(void *opaque, target_phys_addr_t offset,
> -                                  uint64_t value, unsigned size)
> -{
> -    struct PPC4xxPCIState *pci = opaque;
> -
> -    /* We ignore all target attempts at PCI configuration, effectively
> -     * assuming a bidirectional 1:1 mapping of PLB and PCI space. */
> -
> -    switch (offset) {
> -    case PCIL0_PMM0LA:
> -        pci->pmm[0].la = value;
> -        break;
> -    case PCIL0_PMM0MA:
> -        pci->pmm[0].ma = value;
> -        break;
> -    case PCIL0_PMM0PCIHA:
> -        pci->pmm[0].pciha = value;
> -        break;
> -    case PCIL0_PMM0PCILA:
> -        pci->pmm[0].pcila = value;
> -        break;
> -
> -    case PCIL0_PMM1LA:
> -        pci->pmm[1].la = value;
> -        break;
> -    case PCIL0_PMM1MA:
> -        pci->pmm[1].ma = value;
> -        break;
> -    case PCIL0_PMM1PCIHA:
> -        pci->pmm[1].pciha = value;
> -        break;
> -    case PCIL0_PMM1PCILA:
> -        pci->pmm[1].pcila = value;
> -        break;
> -
> -    case PCIL0_PMM2LA:
> -        pci->pmm[2].la = value;
> -        break;
> -    case PCIL0_PMM2MA:
> -        pci->pmm[2].ma = value;
> -        break;
> -    case PCIL0_PMM2PCIHA:
> -        pci->pmm[2].pciha = value;
> -        break;
> -    case PCIL0_PMM2PCILA:
> -        pci->pmm[2].pcila = value;
> -        break;
> -
> -    case PCIL0_PTM1MS:
> -        pci->ptm[0].ms = value;
> -        break;
> -    case PCIL0_PTM1LA:
> -        pci->ptm[0].la = value;
> -        break;
> -    case PCIL0_PTM2MS:
> -        pci->ptm[1].ms = value;
> -        break;
> -    case PCIL0_PTM2LA:
> -        pci->ptm[1].la = value;
> -        break;
> -
> -    default:
> -        printf("%s: unhandled PCI internal register 0x%lx\n", __func__,
> -               (unsigned long)offset);
> -        break;
> -    }
> -}
> -
> -static uint64_t ppc4xx_pci_reg_read4(void *opaque, target_phys_addr_t offset,
> -                                     unsigned size)
> -{
> -    struct PPC4xxPCIState *pci = opaque;
> -    uint32_t value;
> -
> -    switch (offset) {
> -    case PCIL0_PMM0LA:
> -        value = pci->pmm[0].la;
> -        break;
> -    case PCIL0_PMM0MA:
> -        value = pci->pmm[0].ma;
> -        break;
> -    case PCIL0_PMM0PCIHA:
> -        value = pci->pmm[0].pciha;
> -        break;
> -    case PCIL0_PMM0PCILA:
> -        value = pci->pmm[0].pcila;
> -        break;
> -
> -    case PCIL0_PMM1LA:
> -        value = pci->pmm[1].la;
> -        break;
> -    case PCIL0_PMM1MA:
> -        value = pci->pmm[1].ma;
> -        break;
> -    case PCIL0_PMM1PCIHA:
> -        value = pci->pmm[1].pciha;
> -        break;
> -    case PCIL0_PMM1PCILA:
> -        value = pci->pmm[1].pcila;
> -        break;
> -
> -    case PCIL0_PMM2LA:
> -        value = pci->pmm[2].la;
> -        break;
> -    case PCIL0_PMM2MA:
> -        value = pci->pmm[2].ma;
> -        break;
> -    case PCIL0_PMM2PCIHA:
> -        value = pci->pmm[2].pciha;
> -        break;
> -    case PCIL0_PMM2PCILA:
> -        value = pci->pmm[2].pcila;
> -        break;
> -
> -    case PCIL0_PTM1MS:
> -        value = pci->ptm[0].ms;
> -        break;
> -    case PCIL0_PTM1LA:
> -        value = pci->ptm[0].la;
> -        break;
> -    case PCIL0_PTM2MS:
> -        value = pci->ptm[1].ms;
> -        break;
> -    case PCIL0_PTM2LA:
> -        value = pci->ptm[1].la;
> -        break;
> -
> -    default:
> -        printf("%s: invalid PCI internal register 0x%lx\n", __func__,
> -               (unsigned long)offset);
> -        value = 0;
> -    }
> -
> -    return value;
> -}
> -
> -static const MemoryRegionOps pci_reg_ops = {
> -    .read = ppc4xx_pci_reg_read4,
> -    .write = ppc4xx_pci_reg_write4,
> -    .endianness = DEVICE_LITTLE_ENDIAN,
> -};
> -
> -static void ppc4xx_pci_reset(void *opaque)
> -{
> -    struct PPC4xxPCIState *pci = opaque;
> -
> -    memset(pci->pmm, 0, sizeof(pci->pmm));
> -    memset(pci->ptm, 0, sizeof(pci->ptm));
> -}
> -
> -/* On Bamboo, all pins from each slot are tied to a single board IRQ. This
> - * may need further refactoring for other boards. */
> -static int ppc4xx_pci_map_irq(PCIDevice *pci_dev, int irq_num)
> -{
> -    int slot = pci_dev->devfn >> 3;
> -
> -    DPRINTF("%s: devfn %x irq %d -> %d\n", __func__,
> -            pci_dev->devfn, irq_num, slot);
> -
> -    return slot - 1;
> -}
> -
> -static void ppc4xx_pci_set_irq(void *opaque, int irq_num, int level)
> -{
> -    qemu_irq *pci_irqs = opaque;
> -
> -    DPRINTF("%s: PCI irq %d\n", __func__, irq_num);
> -    qemu_set_irq(pci_irqs[irq_num], level);
> -}
> -
> -static const VMStateDescription vmstate_pci_master_map = {
> -    .name = "pci_master_map",
> -    .version_id = 0,
> -    .minimum_version_id = 0,
> -    .minimum_version_id_old = 0,
> -    .fields      = (VMStateField[]) {
> -        VMSTATE_UINT32(la, struct PCIMasterMap),
> -        VMSTATE_UINT32(ma, struct PCIMasterMap),
> -        VMSTATE_UINT32(pcila, struct PCIMasterMap),
> -        VMSTATE_UINT32(pciha, struct PCIMasterMap),
> -        VMSTATE_END_OF_LIST()
> -    }
> -};
> -
> -static const VMStateDescription vmstate_pci_target_map = {
> -    .name = "pci_target_map",
> -    .version_id = 0,
> -    .minimum_version_id = 0,
> -    .minimum_version_id_old = 0,
> -    .fields      = (VMStateField[]) {
> -        VMSTATE_UINT32(ms, struct PCITargetMap),
> -        VMSTATE_UINT32(la, struct PCITargetMap),
> -        VMSTATE_END_OF_LIST()
> -    }
> -};
> -
> -static const VMStateDescription vmstate_ppc4xx_pci = {
> -    .name = "ppc4xx_pci",
> -    .version_id = 1,
> -    .minimum_version_id = 1,
> -    .minimum_version_id_old = 1,
> -    .fields      = (VMStateField[]) {
> -        VMSTATE_PCI_DEVICE_POINTER(pci_dev, PPC4xxPCIState),
> -        VMSTATE_STRUCT_ARRAY(pmm, PPC4xxPCIState, PPC4xx_PCI_NR_PMMS, 1,
> -                             vmstate_pci_master_map,
> -                             struct PCIMasterMap),
> -        VMSTATE_STRUCT_ARRAY(ptm, PPC4xxPCIState, PPC4xx_PCI_NR_PTMS, 1,
> -                             vmstate_pci_target_map,
> -                             struct PCITargetMap),
> -        VMSTATE_END_OF_LIST()
> -    }
> -};
> -
> -/* XXX Interrupt acknowledge cycles not supported. */
> -PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
> -                        target_phys_addr_t config_space,
> -                        target_phys_addr_t int_ack,
> -                        target_phys_addr_t special_cycle,
> -                        target_phys_addr_t registers)
> -{
> -    PPC4xxPCIState *controller;
> -    static int ppc4xx_pci_id;
> -    uint8_t *pci_conf;
> -
> -    controller = g_malloc0(sizeof(PPC4xxPCIState));
> -
> -    controller->pci_state.bus = pci_register_bus(NULL, "pci",
> -                                                 ppc4xx_pci_set_irq,
> -                                                 ppc4xx_pci_map_irq,
> -                                                 pci_irqs,
> -                                                 get_system_memory(),
> -                                                 get_system_io(),
> -                                                 0, 4);
> -
> -    controller->pci_dev = pci_register_device(controller->pci_state.bus,
> -                                              "host bridge", sizeof(PCIDevice),
> -                                              0, NULL, NULL);
> -    pci_conf = controller->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_440GX);
> -    pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER);
> -
> -    /* CFGADDR */
> -    memory_region_init_io(&controller->iomem_addr, &pci4xx_cfgaddr_ops,
> -                          controller, "pci.cfgaddr", 4);
> -    memory_region_add_subregion(get_system_memory(),
> -                                config_space + PCIC0_CFGADDR,
> -                                &controller->iomem_addr);
> -
> -    /* CFGDATA */
> -    memory_region_init_io(&controller->pci_state.data_mem,
> -                          &pci_host_data_be_ops,
> -                          &controller->pci_state, "pci-conf-data", 4);
> -    memory_region_add_subregion(get_system_memory(),
> -                                config_space + PCIC0_CFGDATA,
> -                                &controller->pci_state.data_mem);
> -
> -    /* Internal registers */
> -    memory_region_init_io(&controller->iomem_regs, &pci_reg_ops, controller,
> -                          "pci.regs", PCI_REG_SIZE);
> -    memory_region_add_subregion(get_system_memory(), registers,
> -                                &controller->iomem_regs);
> -
> -    qemu_register_reset(ppc4xx_pci_reset, controller);
> -
> -    /* XXX load/save code not tested. */
> -    vmstate_register(&controller->pci_dev->qdev, ppc4xx_pci_id++,
> -                     &vmstate_ppc4xx_pci, controller);
> -
> -    return controller->pci_state.bus;
> -}
> diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c
> index 6ffb896..1dc8a8f 100644
> --- a/hw/virtex_ml507.c
> +++ b/hw/virtex_ml507.c
> @@ -38,7 +38,6 @@
>  
>  #include "ppc.h"
>  #include "ppc4xx.h"
> -#include "ppc440.h"
>  #include "ppc405.h"
>  
>  #include "blockdev.h"

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

* Re: [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support
  2012-01-13 10:59   ` Benjamin Herrenschmidt
@ 2012-01-13 11:04     ` Andreas Färber
  2012-01-13 11:45       ` Paolo Bonzini
  0 siblings, 1 reply; 50+ messages in thread
From: Andreas Färber @ 2012-01-13 11:04 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Paolo Bonzini, Anthony Liguori, qemu-devel, Alexander Graf,
	Markus Armbruster

Am 13.01.2012 11:59, schrieb Benjamin Herrenschmidt:
> On Mon, 2012-01-02 at 18:51 -0600, Anthony Liguori wrote:
>> This board never worked with TCG.  It hasn't been updated since 0.13.0.  I'm
>> fairly sure hardware doesn't exist anymore that you can run the KVM support
>> with.
> 
> It does exist, I have one :-)

Alex has already posted series to not only qdev'ify it but to also add
TCG support so other people can test it. Review and testing would
probably be appreciated. :)

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] 50+ messages in thread

* Re: [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support
  2012-01-13 11:04     ` Andreas Färber
@ 2012-01-13 11:45       ` Paolo Bonzini
  2012-01-13 12:30         ` Alexander Graf
  0 siblings, 1 reply; 50+ messages in thread
From: Paolo Bonzini @ 2012-01-13 11:45 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Anthony Liguori, qemu-devel, Alexander Graf, Markus Armbruster

On 01/13/2012 12:04 PM, Andreas Färber wrote:
>>> >>  This board never worked with TCG.  It hasn't been updated since 0.13.0.  I'm
>>> >>  fairly sure hardware doesn't exist anymore that you can run the KVM support
>>> >>  with.
>> >
>> >  It does exist, I have one:-)
> Alex has already posted series to not only qdev'ify it but to also add
> TCG support so other people can test it. Review and testing would
> probably be appreciated.:)

The work that you guys are putting in modernizing the PPC boards is 
really cool.  Please, let's start working on the 1.1 changelog now so 
that it doesn't get lost!

Paolo

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

* Re: [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support
  2012-01-13 11:45       ` Paolo Bonzini
@ 2012-01-13 12:30         ` Alexander Graf
  2012-01-13 14:24           ` Andreas Färber
  0 siblings, 1 reply; 50+ messages in thread
From: Alexander Graf @ 2012-01-13 12:30 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Anthony Liguori, Andreas Färber, Markus Armbruster, qemu-devel


On 13.01.2012, at 12:45, Paolo Bonzini wrote:

> On 01/13/2012 12:04 PM, Andreas Färber wrote:
>>>> >>  This board never worked with TCG.  It hasn't been updated since 0.13.0.  I'm
>>>> >>  fairly sure hardware doesn't exist anymore that you can run the KVM support
>>>> >>  with.
>>> >
>>> >  It does exist, I have one:-)
>> Alex has already posted series to not only qdev'ify it but to also add
>> TCG support so other people can test it. Review and testing would
>> probably be appreciated.:)
> 
> The work that you guys are putting in modernizing the PPC boards is really cool.  Please, let's start working on the 1.1 changelog now so that it doesn't get lost!

Good point :). I'm not sure how useful something like "Qdev'ified board xxx" really is in a changelog though. It's mostly invisible to users.


Alex

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

* Re: [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support
  2012-01-13 12:30         ` Alexander Graf
@ 2012-01-13 14:24           ` Andreas Färber
  2012-01-13 14:29             ` Alexander Graf
  0 siblings, 1 reply; 50+ messages in thread
From: Andreas Färber @ 2012-01-13 14:24 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Paolo Bonzini, Anthony Liguori, qemu-devel, Markus Armbruster

Am 13.01.2012 13:30, schrieb Alexander Graf:
> 
> On 13.01.2012, at 12:45, Paolo Bonzini wrote:
> 
>> On 01/13/2012 12:04 PM, Andreas Färber wrote:
>>>>>>>  This board never worked with TCG.  It hasn't been updated since 0.13.0.  I'm
>>>>>>>  fairly sure hardware doesn't exist anymore that you can run the KVM support
>>>>>>>  with.
>>>>>
>>>>>  It does exist, I have one:-)
>>> Alex has already posted series to not only qdev'ify it but to also add
>>> TCG support so other people can test it. Review and testing would
>>> probably be appreciated.:)
>>
>> The work that you guys are putting in modernizing the PPC boards is really cool.  Please, let's start working on the 1.1 changelog now so that it doesn't get lost!
> 
> Good point :). I'm not sure how useful something like "Qdev'ified board xxx" really is in a changelog though. It's mostly invisible to users.

This is inviting a flame war on whether users read Change Logs and
whether a Change Log needs to be useful to them. ;)

I concur with Paolo that TCG support for Bamboo is worth mentioning
(user-visible feature) and so would a new, real PReP machine if we
manage in time. The conversions could be summarized under a QOM heading.
But since neither has been applied to master yet, we should wait with
the Change Log update. But thanks for the reminder, good idea!

Andreas

http://wiki.qemu.org/ChangeLog/1.1

-- 
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] 50+ messages in thread

* Re: [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support
  2012-01-13 14:24           ` Andreas Färber
@ 2012-01-13 14:29             ` Alexander Graf
  0 siblings, 0 replies; 50+ messages in thread
From: Alexander Graf @ 2012-01-13 14:29 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Paolo Bonzini, Anthony Liguori, qemu-devel, Markus Armbruster


On 13.01.2012, at 15:24, Andreas Färber wrote:

> Am 13.01.2012 13:30, schrieb Alexander Graf:
>> 
>> On 13.01.2012, at 12:45, Paolo Bonzini wrote:
>> 
>>> On 01/13/2012 12:04 PM, Andreas Färber wrote:
>>>>>>>> This board never worked with TCG.  It hasn't been updated since 0.13.0.  I'm
>>>>>>>> fairly sure hardware doesn't exist anymore that you can run the KVM support
>>>>>>>> with.
>>>>>> 
>>>>>> It does exist, I have one:-)
>>>> Alex has already posted series to not only qdev'ify it but to also add
>>>> TCG support so other people can test it. Review and testing would
>>>> probably be appreciated.:)
>>> 
>>> The work that you guys are putting in modernizing the PPC boards is really cool.  Please, let's start working on the 1.1 changelog now so that it doesn't get lost!
>> 
>> Good point :). I'm not sure how useful something like "Qdev'ified board xxx" really is in a changelog though. It's mostly invisible to users.
> 
> This is inviting a flame war on whether users read Change Logs and
> whether a Change Log needs to be useful to them. ;)

Users read changelogs. Packagers read changelogs. QEMU Developers read mailing lists. Libvirt developers might read changelogs. Qdev is a QEMU developer visible feature, so it doesn't belong into the changelog. Unless you want to argue that it makes stuff available through -device at which point it's management tool visible. Oh well. I probably just don't want to bloat it too much :).

> I concur with Paolo that TCG support for Bamboo is worth mentioning
> (user-visible feature) and so would a new, real PReP machine if we
> manage in time.

Yes, both definitely should show up!

> The conversions could be summarized under a QOM heading.
> But since neither has been applied to master yet, we should wait with
> the Change Log update. But thanks for the reminder, good idea!

If it's been posted on the ML, nobody complained on it and it's in the maintainer's queue, it's fine to update the changelog imho :).


Alex

> 
> Andreas
> 
> http://wiki.qemu.org/ChangeLog/1.1
> 
> -- 
> 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] 50+ messages in thread

end of thread, other threads:[~2012-01-13 14:30 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-03  0:51 [Qemu-devel] qom: add QEMU Object Model type hierarchy to qdev (v2) Anthony Liguori
2012-01-03  0:51 ` [Qemu-devel] [PATCH 01/30] macio: convert to qdev Anthony Liguori
2012-01-03  0:51 ` [Qemu-devel] [PATCH 02/30] openpic: remove dead code to make a PCI device version Anthony Liguori
2012-01-03  0:51 ` [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support Anthony Liguori
2012-01-05 15:16   ` François Revol
2012-01-13 10:59   ` Benjamin Herrenschmidt
2012-01-13 11:04     ` Andreas Färber
2012-01-13 11:45       ` Paolo Bonzini
2012-01-13 12:30         ` Alexander Graf
2012-01-13 14:24           ` Andreas Färber
2012-01-13 14:29             ` Alexander Graf
2012-01-03  0:51 ` [Qemu-devel] [PATCH 04/30] ppc_prep: convert host bridge to qdev Anthony Liguori
2012-01-03 14:57   ` Andreas Färber
2012-01-07  0:11     ` Andreas Färber
2012-01-03  0:51 ` [Qemu-devel] [PATCH 05/30] pseries: Remove hcalls callback Anthony Liguori
2012-01-03  0:51 ` [Qemu-devel] [PATCH 06/30] pci: call reset unconditionally Anthony Liguori
2012-01-03  0:51 ` [Qemu-devel] [PATCH 07/30] qom: add the base Object class (v2) Anthony Liguori
2012-01-03  9:02   ` Paolo Bonzini
2012-01-03  0:51 ` [Qemu-devel] [PATCH 08/30] qdev: integrate with QEMU Object Model (v2) Anthony Liguori
2012-01-03  0:51 ` [Qemu-devel] [PATCH 09/30] qdev: move qdev->info to class Anthony Liguori
2012-01-08  2:27   ` Andreas Färber
2012-01-03  0:51 ` [Qemu-devel] [PATCH 10/30] qdev: don't access name through info Anthony Liguori
2012-01-03  9:06   ` Paolo Bonzini
2012-01-03 13:39     ` Anthony Liguori
2012-01-03 13:41       ` Paolo Bonzini
2012-01-03  0:52 ` [Qemu-devel] [PATCH 11/30] qdev: use a wrapper to access reset and promote reset to a class method Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 12/30] qdev: add a interface to register subclasses Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 13/30] qdev: add class_init to DeviceInfo Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 14/30] qdev: prepare source tree for code conversion Anthony Liguori
2012-01-04 14:07   ` Andreas Färber
2012-01-04 14:24     ` Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 15/30] isa: convert to QEMU Object Model Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 16/30] usb: " Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 17/30] ccid: " Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 18/30] ssi: " Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 19/30] i2c: rename i2c_slave -> I2CSlave Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 20/30] i2c: smbus: convert to QEMU Object Model Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 21/30] hda-codec: " Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 22/30] ide: " Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 23/30] scsi: " Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 24/30] spapr: convert to QEMU Object Model (v2) Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 25/30] virtio-serial: convert to QEMU Object Model Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 26/30] grackle: remove broken pci device Anthony Liguori
2012-01-08  1:46   ` Aurelien Jarno
2012-01-08  1:55     ` Andreas Färber
2012-01-03  0:52 ` [Qemu-devel] [PATCH 27/30] unin_pci: remove phantom qdev devices in unin_pci Anthony Liguori
2012-01-08  2:04   ` Andreas Färber
2012-01-03  0:52 ` [Qemu-devel] [PATCH 28/30] pci: convert to QEMU Object Model Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 29/30] sysbus: " Anthony Liguori
2012-01-03  0:52 ` [Qemu-devel] [PATCH 30/30] virtio-s390: " 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.