qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit
@ 2012-01-30 21:08 Anthony Liguori
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 03/23] qdev: make DeviceInfo private Anthony Liguori
                   ` (21 more replies)
  0 siblings, 22 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

We can probably model USBHidDevice as a base class to get even better code
sharing but for now, just use a common function to initialize the common class
members.

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

diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 88fdd35..4af27a2 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -553,13 +553,10 @@ static const VMStateDescription vmstate_usb_kbd = {
     }
 };
 
-static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
+static void usb_hid_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;
@@ -567,6 +564,16 @@ static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
     uc->handle_destroy = usb_hid_handle_destroy;
 }
 
+static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
+{
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    usb_hid_class_initfn(klass, data);
+    uc->init           = usb_tablet_initfn;
+    uc->product_desc   = "QEMU USB Tablet";
+    uc->usb_desc       = &desc_tablet;
+}
+
 static struct DeviceInfo usb_tablet_info = {
     .name      = "usb-tablet",
     .size      = sizeof(USBHIDState),
@@ -578,14 +585,10 @@ static void usb_mouse_class_initfn(ObjectClass *klass, void *data)
 {
     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 
+    usb_hid_class_initfn(klass, data);
     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 = {
@@ -599,14 +602,10 @@ static void usb_keyboard_class_initfn(ObjectClass *klass, void *data)
 {
     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 
+    usb_hid_class_initfn(klass, data);
     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 = {
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 03/23] qdev: make DeviceInfo private
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-30 22:31   ` Andreas Färber
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 04/23] qdev: remove info from class Anthony Liguori
                   ` (20 subsequent siblings)
  21 siblings, 1 reply; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

Introduce accessors and remove any code that directly accesses DeviceInfo
members.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/pci.c             |   13 ++++++++-----
 hw/qdev-properties.c |    4 ++--
 hw/qdev.c            |   30 +++++++++++++++++++++++++++++-
 hw/qdev.h            |   24 +++++++++---------------
 4 files changed, 48 insertions(+), 23 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 6a0b1f5..235ea00 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1673,6 +1673,7 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
     char *path;
     void *ptr;
     char name[32];
+    const VMStateDescription *vmsd;
 
     if (!pdev->romfile)
         return 0;
@@ -1709,10 +1710,13 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
         size = 1 << qemu_fls(size);
     }
 
-    if (qdev_get_info(&pdev->qdev)->vmsd)
-        snprintf(name, sizeof(name), "%s.rom", qdev_get_info(&pdev->qdev)->vmsd->name);
-    else
+    vmsd = qdev_get_vmsd(DEVICE(pdev));
+
+    if (vmsd) {
+        snprintf(name, sizeof(name), "%s.rom", vmsd->name);
+    } else {
         snprintf(name, sizeof(name), "%s.rom", object_get_typename(OBJECT(pdev)));
+    }
     pdev->has_rom = true;
     memory_region_init_ram(&pdev->rom, name, size);
     vmstate_register_ram(&pdev->rom, &pdev->qdev);
@@ -1953,8 +1957,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) {
+    if (object_dynamic_cast(OBJECT(qdev), TYPE_PCI_DEVICE)) {
         *pdev = PCI_DEVICE(qdev);
         return 0;
     }
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index c98219a..724dce5 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -966,7 +966,7 @@ static Property *qdev_prop_find(DeviceState *dev, const char *name)
     Property *prop;
 
     /* device properties */
-    prop = qdev_prop_walk(qdev_get_info(dev)->props, name);
+    prop = qdev_prop_walk(qdev_get_props(dev), name);
     if (prop)
         return prop;
 
@@ -1166,7 +1166,7 @@ void qdev_prop_set_globals(DeviceState *dev)
 
     QTAILQ_FOREACH(prop, &global_props, next) {
         if (strcmp(object_get_typename(OBJECT(dev)), prop->driver) != 0 &&
-            strcmp(qdev_get_info(dev)->bus_info->name, prop->driver) != 0) {
+            strcmp(qdev_get_bus_info(dev)->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 a8c24de..18c5876 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -60,11 +60,39 @@ static void qdev_subclass_init(ObjectClass *klass, void *data)
     }
 }
 
-DeviceInfo *qdev_get_info(DeviceState *dev)
+static DeviceInfo *qdev_get_info(DeviceState *dev)
 {
     return DEVICE_GET_CLASS(dev)->info;
 }
 
+const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
+{
+    return qdev_get_info(dev)->vmsd;
+}
+
+BusInfo *qdev_get_bus_info(DeviceState *dev)
+{
+    return qdev_get_info(dev)->bus_info;
+}
+
+Property *qdev_get_props(DeviceState *dev)
+{
+    return qdev_get_info(dev)->props;
+}
+
+const char *qdev_fw_name(DeviceState *dev)
+{
+    DeviceInfo *info = qdev_get_info(dev);
+
+    if (info->fw_name) {
+        return info->fw_name;
+    } else if (info->alias) {
+        return info->alias;
+    }
+
+    return object_get_typename(OBJECT(dev));
+}
+
 void qdev_register_subclass(DeviceInfo *info, const char *parent)
 {
     TypeInfo type_info = {};
diff --git a/hw/qdev.h b/hw/qdev.h
index c9572a5..dc6a6fe 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -398,22 +398,8 @@ 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)
-{
-    DeviceInfo *info = qdev_get_info(dev);
-
-    if (info->fw_name) {
-        return info->fw_name;
-    } else if (info->alias) {
-        return info->alias;
-    }
-
-    return object_get_typename(OBJECT(dev));
-}
-
 char *qdev_get_fw_dev_path(DeviceState *dev);
+
 /* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
 extern struct BusInfo system_bus_info;
 
@@ -661,4 +647,12 @@ void qdev_machine_init(void);
  */
 void device_reset(DeviceState *dev);
 
+const VMStateDescription *qdev_get_vmsd(DeviceState *dev);
+
+const char *qdev_fw_name(DeviceState *dev);
+
+BusInfo *qdev_get_bus_info(DeviceState *dev);
+
+Property *qdev_get_props(DeviceState *dev);
+
 #endif
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 04/23] qdev: remove info from class
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 03/23] qdev: make DeviceInfo private Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 05/23] qdev: allow classes to overload qdev functions Anthony Liguori
                   ` (19 subsequent siblings)
  21 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

Now DeviceInfo is no longer used after object construction.  All of the
relevant members have been moved to DeviceClass.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/pci.c  |    4 ++-
 hw/qdev.c |   94 ++++++++++++++++++++++++++++++++++++------------------------
 hw/qdev.h |   26 +++++++++++++---
 3 files changed, 80 insertions(+), 44 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 235ea00..43dc1fb 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1467,7 +1467,9 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
     }
 
     bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
-    pci_dev = do_pci_register_device(pci_dev, bus, base->name, pci_dev->devfn);
+    pci_dev = do_pci_register_device(pci_dev, bus,
+                                     object_get_typename(OBJECT(qdev)),
+                                     pci_dev->devfn);
     if (pci_dev == NULL)
         return -1;
     if (qdev->hotplugged && pc->no_hotplug) {
diff --git a/hw/qdev.c b/hw/qdev.c
index 18c5876..b273cd2 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -48,46 +48,54 @@ static BusState *qbus_find(const char *path);
 static void qdev_subclass_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    DeviceInfo *info = data;
 
-    dc->info = data;
-    dc->reset = dc->info->reset;
+    dc->fw_name = info->fw_name;
+    dc->alias = info->alias;
+    dc->desc = info->desc;
+    dc->props = info->props;
+    dc->no_user = info->no_user;
 
-    /* Poison to try to detect future uses */
-    dc->info->reset = NULL;
+    dc->reset = info->reset;
 
-    if (dc->info->class_init) {
-        dc->info->class_init(klass, data);
-    }
-}
+    dc->vmsd = info->vmsd;
 
-static DeviceInfo *qdev_get_info(DeviceState *dev)
-{
-    return DEVICE_GET_CLASS(dev)->info;
+    dc->init = info->init;
+    dc->unplug = info->unplug;
+    dc->exit = info->exit;
+    dc->bus_info = info->bus_info;
+
+    if (info->class_init) {
+        info->class_init(klass, data);
+    }
 }
 
 const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
 {
-    return qdev_get_info(dev)->vmsd;
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+    return dc->vmsd;
 }
 
 BusInfo *qdev_get_bus_info(DeviceState *dev)
 {
-    return qdev_get_info(dev)->bus_info;
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+    return dc->bus_info;
 }
 
 Property *qdev_get_props(DeviceState *dev)
 {
-    return qdev_get_info(dev)->props;
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+    return dc->props;
 }
 
 const char *qdev_fw_name(DeviceState *dev)
 {
-    DeviceInfo *info = qdev_get_info(dev);
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
 
-    if (info->fw_name) {
-        return info->fw_name;
-    } else if (info->alias) {
-        return info->alias;
+    if (dc->fw_name) {
+        return dc->fw_name;
+    } else if (dc->alias) {
+        return dc->alias;
     }
 
     return object_get_typename(OBJECT(dev));
@@ -159,7 +167,7 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
     assert(bus->info == info->bus_info);
     dev = DEVICE(object_new(info->name));
     dev->parent_bus = bus;
-    qdev_prop_set_defaults(dev, qdev_get_info(dev)->props);
+    qdev_prop_set_defaults(dev, qdev_get_props(dev));
     qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
     qdev_prop_set_globals(dev);
     QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
@@ -172,12 +180,12 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
     QTAILQ_INIT(&dev->properties);
     dev->state = DEV_STATE_CREATED;
 
-    for (prop = qdev_get_info(dev)->props; prop && prop->name; prop++) {
+    for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
         qdev_property_add_legacy(dev, prop, NULL);
         qdev_property_add_static(dev, prop, NULL);
     }
 
-    for (prop = qdev_get_info(dev)->bus_info->props; prop && prop->name; prop++) {
+    for (prop = qdev_get_bus_info(dev)->props; prop && prop->name; prop++) {
         qdev_property_add_legacy(dev, prop, NULL);
         qdev_property_add_static(dev, prop, NULL);
     }
@@ -407,16 +415,19 @@ DeviceState *qdev_device_add(QemuOpts *opts)
    Return 0 on success.  */
 int qdev_init(DeviceState *dev)
 {
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
     int rc;
 
     assert(dev->state == DEV_STATE_CREATED);
-    rc = qdev_get_info(dev)->init(dev, qdev_get_info(dev));
+
+    /* FIXME hopefully this doesn't break anything */
+    rc = dc->init(dev, NULL);
     if (rc < 0) {
         qdev_free(dev);
         return rc;
     }
-    if (qdev_get_info(dev)->vmsd) {
-        vmstate_register_with_alias_id(dev, -1, qdev_get_info(dev)->vmsd, dev,
+    if (qdev_get_vmsd(dev)) {
+        vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
                                        dev->instance_id_alias,
                                        dev->alias_required_for_version);
     }
@@ -437,15 +448,17 @@ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
 
 int qdev_unplug(DeviceState *dev)
 {
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+
     if (!dev->parent_bus->allow_hotplug) {
         qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
         return -1;
     }
-    assert(qdev_get_info(dev)->unplug != NULL);
+    assert(dc->unplug != NULL);
 
     qdev_hot_removed = true;
 
-    return qdev_get_info(dev)->unplug(dev);
+    return dc->unplug(dev);
 }
 
 static int qdev_reset_one(DeviceState *dev, void *opaque)
@@ -500,10 +513,9 @@ int qdev_simple_unplug_cb(DeviceState *dev)
    way is somewhat unclean, and best avoided.  */
 void qdev_init_nofail(DeviceState *dev)
 {
-    DeviceInfo *info = qdev_get_info(dev);
-
     if (qdev_init(dev) < 0) {
-        error_report("Initialization of device %s failed", info->name);
+        error_report("Initialization of device %s failed",
+                     object_get_typename(OBJECT(dev)));
         exit(1);
     }
 }
@@ -553,6 +565,7 @@ void qdev_free(DeviceState *dev)
 {
     BusState *bus;
     Property *prop;
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
 
     qdev_property_del_all(dev);
 
@@ -561,15 +574,18 @@ void qdev_free(DeviceState *dev)
             bus = QLIST_FIRST(&dev->child_bus);
             qbus_free(bus);
         }
-        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)
+        if (qdev_get_vmsd(dev)) {
+            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
+        }
+        if (dc->exit) {
+            dc->exit(dev);
+        }
+        if (dev->opts) {
             qemu_opts_del(dev->opts);
+        }
     }
     QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
-    for (prop = qdev_get_info(dev)->props; prop && prop->name; prop++) {
+    for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
         if (prop->info->free) {
             prop->info->free(dev, prop);
         }
@@ -817,7 +833,9 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
         }
     }
     QTAILQ_FOREACH(dev, &bus->children, sibling) {
-        if (qdev_get_info(dev)->alias && strcmp(qdev_get_info(dev)->alias, elem) == 0) {
+        DeviceClass *dc = DEVICE_GET_CLASS(dev);
+
+        if (dc->alias && strcmp(dc->alias, elem) == 0) {
             return dev;
         }
     }
@@ -1028,7 +1046,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, qdev_get_info(dev)->props, "dev", indent);
+    qdev_print_props(mon, dev, qdev_get_props(dev), "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);
diff --git a/hw/qdev.h b/hw/qdev.h
index dc6a6fe..7e4c632 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -72,10 +72,30 @@ typedef struct DeviceProperty
 #define DEVICE_CLASS(klass) OBJECT_CLASS_CHECK(DeviceClass, (klass), TYPE_DEVICE)
 #define DEVICE_GET_CLASS(obj) OBJECT_GET_CLASS(DeviceClass, (obj), TYPE_DEVICE)
 
+typedef int (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
+typedef int (*qdev_event)(DeviceState *dev);
+typedef void (*qdev_resetfn)(DeviceState *dev);
+
 typedef struct DeviceClass {
     ObjectClass parent_class;
-    DeviceInfo *info;
+
+    const char *fw_name;
+    const char *alias;
+    const char *desc;
+    Property *props;
+    int no_user;
+
+    /* callbacks */
     void (*reset)(DeviceState *dev);
+
+    /* device state */
+    const VMStateDescription *vmsd;
+
+    /* Private to qdev / bus.  */
+    qdev_initfn init;
+    qdev_event unplug;
+    qdev_event exit;
+    BusInfo *bus_info;
 } DeviceClass;
 
 /* This structure should not be accessed directly.  We declare it here
@@ -212,10 +232,6 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
 
 /*** Device API.  ***/
 
-typedef int (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
-typedef int (*qdev_event)(DeviceState *dev);
-typedef void (*qdev_resetfn)(DeviceState *dev);
-
 struct DeviceInfo {
     const char *name;
     const char *fw_name;
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 05/23] qdev: allow classes to overload qdev functions
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 03/23] qdev: make DeviceInfo private Anthony Liguori
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 04/23] qdev: remove info from class Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 06/23] qdev: refactor device creation to allow bus_info to be set only in class Anthony Liguori
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

This allows us to drop per-Device registration functions by allowing the
class_init functions to overload qdev methods.

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

diff --git a/hw/qdev.c b/hw/qdev.c
index b273cd2..c9f890c 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -50,21 +50,39 @@ static void qdev_subclass_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     DeviceInfo *info = data;
 
-    dc->fw_name = info->fw_name;
-    dc->alias = info->alias;
-    dc->desc = info->desc;
-    dc->props = info->props;
-    dc->no_user = info->no_user;
-
-    dc->reset = info->reset;
-
-    dc->vmsd = info->vmsd;
-
-    dc->init = info->init;
-    dc->unplug = info->unplug;
-    dc->exit = info->exit;
-    dc->bus_info = info->bus_info;
-
+    if (info->fw_name) {
+        dc->fw_name = info->fw_name;
+    }
+    if (info->alias) {
+        dc->alias = info->alias;
+    }
+    if (info->desc) {
+        dc->desc = info->desc;
+    }
+    if (info->props) {
+        dc->props = info->props;
+    }
+    if (info->no_user) {
+        dc->no_user = info->no_user;
+    }
+    if (info->reset) {
+        dc->reset = info->reset;
+    }
+    if (info->vmsd) {
+        dc->vmsd = info->vmsd;
+    }
+    if (info->init) {
+        dc->init = info->init;
+    }
+    if (info->unplug) {
+        dc->unplug = info->unplug;
+    }
+    if (info->exit) {
+        dc->exit = info->exit;
+    }
+    if (info->bus_info) {
+        dc->bus_info = info->bus_info;
+    }
     if (info->class_init) {
         info->class_init(klass, data);
     }
@@ -131,8 +149,6 @@ static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
 
     /* first check device names */
     for (info = device_info_list; info != NULL; info = info->next) {
-        if (bus_info && info->bus_info != bus_info)
-            continue;
         if (strcmp(info->name, name) != 0)
             continue;
         return info;
@@ -140,8 +156,6 @@ static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
 
     /* failing that check the aliases */
     for (info = device_info_list; info != NULL; info = info->next) {
-        if (bus_info && info->bus_info != bus_info)
-            continue;
         if (!info->alias)
             continue;
         if (strcmp(info->alias, name) != 0)
@@ -164,7 +178,6 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
     DeviceState *dev;
     Property *prop;
 
-    assert(bus->info == info->bus_info);
     dev = DEVICE(object_new(info->name));
     dev->parent_bus = bus;
     qdev_prop_set_defaults(dev, qdev_get_props(dev));
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 06/23] qdev: refactor device creation to allow bus_info to be set only in class
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (2 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 05/23] qdev: allow classes to overload qdev functions Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 07/23] qdev: kill off DeviceInfo list Anthony Liguori
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

As we use class_init to set class members, DeviceInfo no longer holds this
information.

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

diff --git a/hw/qdev.c b/hw/qdev.c
index c9f890c..bba84e2 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -119,21 +119,29 @@ const char *qdev_fw_name(DeviceState *dev)
     return object_get_typename(OBJECT(dev));
 }
 
-void qdev_register_subclass(DeviceInfo *info, const char *parent)
+static void qdev_do_register_subclass(DeviceInfo *info, const char *parent,
+                                      const char *name)
 {
     TypeInfo type_info = {};
 
     assert(info->size >= sizeof(DeviceState));
     assert(!info->next);
 
-    type_info.name = info->name;
+    type_info.name = name;
     type_info.parent = parent;
     type_info.instance_size = info->size;
     type_info.class_init = qdev_subclass_init;
     type_info.class_data = info;
 
     type_register_static(&type_info);
+}
 
+void qdev_register_subclass(DeviceInfo *info, const char *parent)
+{
+    qdev_do_register_subclass(info, parent, info->name);
+    if (info->alias) {
+        qdev_do_register_subclass(info, parent, info->alias);
+    }
     info->next = device_info_list;
     device_info_list = info;
 }
@@ -173,12 +181,12 @@ bool qdev_exists(const char *name)
 static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
                                      Error **errp);
 
-static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
+static DeviceState *qdev_create_from_info(BusState *bus, const char *typename)
 {
     DeviceState *dev;
     Property *prop;
 
-    dev = DEVICE(object_new(info->name));
+    dev = DEVICE(object_new(typename));
     dev->parent_bus = bus;
     qdev_prop_set_defaults(dev, qdev_get_props(dev));
     qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
@@ -230,18 +238,11 @@ DeviceState *qdev_create(BusState *bus, const char *name)
 
 DeviceState *qdev_try_create(BusState *bus, const char *name)
 {
-    DeviceInfo *info;
-
     if (!bus) {
         bus = sysbus_get_default();
     }
 
-    info = qdev_find_info(bus->info, name);
-    if (!info) {
-        return NULL;
-    }
-
-    return qdev_create_from_info(bus, info);
+    return qdev_create_from_info(bus, name);
 }
 
 static void qdev_print_devinfo(DeviceInfo *info)
@@ -352,8 +353,8 @@ static DeviceState *qdev_get_peripheral_anon(void)
 
 DeviceState *qdev_device_add(QemuOpts *opts)
 {
+    DeviceClass *k;
     const char *driver, *path, *id;
-    DeviceInfo *info;
     DeviceState *qdev;
     BusState *bus;
 
@@ -364,12 +365,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
     }
 
     /* find driver */
-    info = qdev_find_info(NULL, driver);
-    if (!info || info->no_user) {
-        qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
-        error_printf_unless_qmp("Try with argument '?' for a list.\n");
-        return NULL;
-    }
+    k = DEVICE_CLASS(object_class_by_name(driver));
 
     /* find bus */
     path = qemu_opt_get(opts, "bus");
@@ -378,16 +374,16 @@ DeviceState *qdev_device_add(QemuOpts *opts)
         if (!bus) {
             return NULL;
         }
-        if (bus->info != info->bus_info) {
+        if (bus->info != k->bus_info) {
             qerror_report(QERR_BAD_BUS_FOR_DEVICE,
                            driver, bus->info->name);
             return NULL;
         }
     } else {
-        bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
+        bus = qbus_find_recursive(main_system_bus, NULL, k->bus_info);
         if (!bus) {
             qerror_report(QERR_NO_BUS_FOR_DEVICE,
-                           info->name, info->bus_info->name);
+                          driver, k->bus_info->name);
             return NULL;
         }
     }
@@ -397,7 +393,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
     }
 
     /* create device, set properties */
-    qdev = qdev_create_from_info(bus, info);
+    qdev = qdev_create_from_info(bus, driver);
     id = qemu_opts_id(opts);
     if (id) {
         qdev->id = id;
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 07/23] qdev: kill off DeviceInfo list
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (3 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 06/23] qdev: refactor device creation to allow bus_info to be set only in class Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-31 13:51   ` Andreas Färber
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 08/23] qdev: register all types natively through QEMU Object Model Anthony Liguori
                   ` (16 subsequent siblings)
  21 siblings, 1 reply; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

Teach the various bits of code that need to walk through available devices to
do so via QOM.

Signed-off-by: Anthony Liguori
---
 hw/qdev.c |   87 +++++++++++++++++++++----------------------------------------
 hw/qdev.h |    2 -
 2 files changed, 30 insertions(+), 59 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index bba84e2..ea917ad 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -38,8 +38,6 @@ static bool qdev_hot_removed = false;
 static BusState *main_system_bus;
 static void main_system_bus_create(void);
 
-DeviceInfo *device_info_list;
-
 static BusState *qbus_find_recursive(BusState *bus, const char *name,
                                      const BusInfo *info);
 static BusState *qbus_find(const char *path);
@@ -125,7 +123,6 @@ static void qdev_do_register_subclass(DeviceInfo *info, const char *parent,
     TypeInfo type_info = {};
 
     assert(info->size >= sizeof(DeviceState));
-    assert(!info->next);
 
     type_info.name = name;
     type_info.parent = parent;
@@ -142,40 +139,11 @@ void qdev_register_subclass(DeviceInfo *info, const char *parent)
     if (info->alias) {
         qdev_do_register_subclass(info, parent, info->alias);
     }
-    info->next = device_info_list;
-    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;
-
-    /* first check device names */
-    for (info = device_info_list; info != NULL; info = info->next) {
-        if (strcmp(info->name, name) != 0)
-            continue;
-        return info;
-    }
-
-    /* failing that check the aliases */
-    for (info = device_info_list; info != NULL; info = info->next) {
-        if (!info->alias)
-            continue;
-        if (strcmp(info->alias, name) != 0)
-            continue;
-        return info;
-    }
-    return NULL;
 }
 
 bool qdev_exists(const char *name)
 {
-    return !!qdev_find_info(NULL, name);
+    return !!object_class_by_name(name);
 }
 
 static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
@@ -245,17 +213,28 @@ DeviceState *qdev_try_create(BusState *bus, const char *name)
     return qdev_create_from_info(bus, name);
 }
 
-static void qdev_print_devinfo(DeviceInfo *info)
+static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
 {
-    error_printf("name \"%s\", bus %s",
-                 info->name, info->bus_info->name);
-    if (info->alias) {
-        error_printf(", alias \"%s\"", info->alias);
+    DeviceClass *dc;
+    bool *show_no_user = opaque;
+
+    dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
+
+    if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
+        return;
     }
-    if (info->desc) {
-        error_printf(", desc \"%s\"", info->desc);
+
+    error_printf("name \"%s\"", object_class_get_name(klass));
+    if (dc->bus_info) {
+        error_printf(", bus %s", dc->bus_info->name);
     }
-    if (info->no_user) {
+    if (dc->alias) {
+        error_printf(", alias \"%s\"", dc->alias);
+    }
+    if (dc->desc) {
+        error_printf(", desc \"%s\"", dc->desc);
+    }
+    if (dc->no_user) {
         error_printf(", no-user");
     }
     error_printf("\n");
@@ -279,17 +258,14 @@ static int set_property(const char *name, const char *value, void *opaque)
 int qdev_device_help(QemuOpts *opts)
 {
     const char *driver;
-    DeviceInfo *info;
     Property *prop;
+    ObjectClass *klass;
+    DeviceClass *info;
 
     driver = qemu_opt_get(opts, "driver");
     if (driver && !strcmp(driver, "?")) {
-        for (info = device_info_list; info != NULL; info = info->next) {
-            if (info->no_user) {
-                continue;       /* not available, don't show */
-            }
-            qdev_print_devinfo(info);
-        }
+        bool show_no_user = false;
+        object_class_foreach(qdev_print_devinfo, &show_no_user);
         return 1;
     }
 
@@ -297,10 +273,11 @@ int qdev_device_help(QemuOpts *opts)
         return 0;
     }
 
-    info = qdev_find_info(NULL, driver);
-    if (!info) {
+    klass = object_class_by_name(driver);
+    if (!klass) {
         return 0;
     }
+    info = DEVICE_CLASS(klass);
 
     for (prop = info->props; prop && prop->name; prop++) {
         /*
@@ -312,14 +289,14 @@ int qdev_device_help(QemuOpts *opts)
         if (!prop->info->parse) {
             continue;           /* no way to set it, don't show */
         }
-        error_printf("%s.%s=%s\n", info->name, prop->name,
+        error_printf("%s.%s=%s\n", driver, prop->name,
                      prop->info->legacy_name ?: prop->info->name);
     }
     for (prop = info->bus_info->props; prop && prop->name; prop++) {
         if (!prop->info->parse) {
             continue;           /* no way to set it, don't show */
         }
-        error_printf("%s.%s=%s\n", info->name, prop->name,
+        error_printf("%s.%s=%s\n", driver, prop->name,
                      prop->info->legacy_name ?: prop->info->name);
     }
     return 1;
@@ -1085,11 +1062,7 @@ void do_info_qtree(Monitor *mon)
 
 void do_info_qdm(Monitor *mon)
 {
-    DeviceInfo *info;
-
-    for (info = device_info_list; info != NULL; info = info->next) {
-        qdev_print_devinfo(info);
-    }
+    object_class_foreach(qdev_print_devinfo, NULL);
 }
 
 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
diff --git a/hw/qdev.h b/hw/qdev.h
index 7e4c632..05ebf7e 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -257,9 +257,7 @@ struct DeviceInfo {
     qdev_event unplug;
     qdev_event exit;
     BusInfo *bus_info;
-    struct DeviceInfo *next;
 };
-extern DeviceInfo *device_info_list;
 
 void qdev_register(DeviceInfo *info);
 void qdev_register_subclass(DeviceInfo *info, const char *parent);
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 08/23] qdev: register all types natively through QEMU Object Model
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (4 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 07/23] qdev: kill off DeviceInfo list Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-30 22:29   ` Peter Maydell
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 09/23] qdev: kill of DeviceInfo Anthony Liguori
                   ` (15 subsequent siblings)
  21 siblings, 1 reply; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

This was done in a mostly automated fashion.  I did it in three steps and then
rebased it into a single step which avoids repeatedly touching every file in
the tree.

The first step was a sed-based addition of the parent type to the subclass
registration functions.

The second step was another sed-based removal of subclass registration functions
while also adding virtual functions from the base class into a class_init
function as appropriate.

Finally, a python script was used to convert the DeviceInfo structures and
qdev_register_subclass functions to TypeInfo structures, class_init functions,
and type_register_static calls.

We are almost fully converted to QOM after this commit.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/9pfs/virtio-9p-device.c |   16 +++--
 hw/a9mpcore.c              |   40 +++++++------
 hw/ac97.c                  |   18 +++---
 hw/acpi_piix4.c            |   20 ++++---
 hw/ads7846.c               |   11 ++--
 hw/alpha_typhoon.c         |   14 +++--
 hw/apb_pci.c               |   41 +++++++------
 hw/apic.c                  |   10 ++-
 hw/apic_common.c           |   15 ++---
 hw/apic_internal.h         |    1 -
 hw/applesmc.c              |   28 +++++----
 hw/arm11mpcore.c           |   28 +++++----
 hw/arm_l2x0.c              |   24 +++++---
 hw/arm_mptimer.c           |   28 +++++----
 hw/arm_sysctl.c            |   18 +++---
 hw/arm_timer.c             |   35 ++++++-----
 hw/armv7m.c                |   14 +++--
 hw/armv7m_nvic.c           |   32 ++++++-----
 hw/bitbang_i2c.c           |   14 +++--
 hw/bonito.c                |   32 ++++++-----
 hw/ccid-card-emulated.c    |   35 ++++++-----
 hw/ccid-card-passthru.c    |   28 +++++----
 hw/ccid.h                  |    1 -
 hw/cirrus_vga.c            |   30 ++++++----
 hw/container.c             |   14 +++--
 hw/cs4231.c                |   18 +++---
 hw/cs4231a.c               |   30 ++++++----
 hw/debugcon.c              |   26 +++++----
 hw/dec_pci.c               |   40 +++++++------
 hw/ds1225y.c               |   16 +++--
 hw/ds1338.c                |   11 ++--
 hw/e1000.c                 |   20 ++++---
 hw/eccmemctl.c             |   18 +++---
 hw/eepro100.c              |   83 ++++++++++++++------------
 hw/empty_slot.c            |   11 ++--
 hw/es1370.c                |   16 +++--
 hw/escc.c                  |   18 +++---
 hw/esp.c                   |   18 +++---
 hw/etraxfs_eth.c           |   14 +++--
 hw/etraxfs_pic.c           |   14 +++--
 hw/etraxfs_ser.c           |   14 +++--
 hw/etraxfs_timer.c         |   11 ++--
 hw/fdc.c                   |   76 +++++++++++++-----------
 hw/fw_cfg.c                |   20 ++++---
 hw/g364fb.c                |   20 ++++---
 hw/grackle_pci.c           |   26 +++++----
 hw/grlib_apbuart.c         |   14 +++--
 hw/grlib_gptimer.c         |   16 +++--
 hw/grlib_irqmp.c           |   16 +++--
 hw/gt64xxx.c               |   22 ++++---
 hw/gus.c                   |   32 ++++++-----
 hw/hda-audio.c             |   36 ++++++-----
 hw/highbank.c              |   18 +++---
 hw/hpet.c                  |   20 ++++---
 hw/i2c.c                   |   21 +++----
 hw/i2c.h                   |    3 -
 hw/i82374.c                |   22 ++++---
 hw/i82378.c                |   22 ++++---
 hw/i8254.c                 |   30 ++++++----
 hw/i8259.c                 |   11 ++-
 hw/i8259_common.c          |   13 +---
 hw/i8259_internal.h        |    1 -
 hw/ide/ahci.c              |   24 +++++---
 hw/ide/cmd646.c            |   14 +++--
 hw/ide/ich.c               |   17 +++--
 hw/ide/isa.c               |   30 ++++++----
 hw/ide/piix.c              |   44 ++++++++------
 hw/ide/qdev.c              |   93 +++++++++++++++++-------------
 hw/ide/via.c               |   14 +++--
 hw/integratorcp.c          |   25 +++++----
 hw/intel-hda.c             |   37 ++++++------
 hw/intel-hda.h             |    1 -
 hw/ioapic.c                |   14 +++--
 hw/ioapic_common.c         |   10 +--
 hw/ioapic_internal.h       |    1 -
 hw/ioh3420.c               |   20 ++++---
 hw/isa-bus.c               |   36 ++++++------
 hw/isa.h                   |    2 -
 hw/ivshmem.c               |   16 +++--
 hw/kvm/apic.c              |    5 +-
 hw/kvm/clock.c             |   16 +++--
 hw/kvm/i8259.c             |    8 ++-
 hw/kvm/ioapic.c            |   20 ++++---
 hw/lan9118.c               |   18 +++---
 hw/lance.c                 |   20 ++++---
 hw/lm32_juart.c            |   16 +++--
 hw/lm32_pic.c              |   16 +++--
 hw/lm32_sys.c              |   18 +++---
 hw/lm32_timer.c            |   18 +++---
 hw/lm32_uart.c             |   16 +++--
 hw/lm832x.c                |   14 +++--
 hw/lsi53c895a.c            |   19 ++++---
 hw/m48t59.c                |   46 ++++++++------
 hw/macio.c                 |   11 ++--
 hw/marvell_88w8618_audio.c |   18 +++---
 hw/max111x.c               |   22 ++++---
 hw/max7310.c               |   16 +++--
 hw/mc146818rtc.c           |   26 +++++----
 hw/milkymist-ac97.c        |   16 +++--
 hw/milkymist-hpdmc.c       |   16 +++--
 hw/milkymist-memcard.c     |   16 +++--
 hw/milkymist-minimac2.c    |   18 +++---
 hw/milkymist-pfpu.c        |   16 +++--
 hw/milkymist-softusb.c     |   18 +++---
 hw/milkymist-sysctl.c      |   18 +++---
 hw/milkymist-tmu2.c        |   16 +++--
 hw/milkymist-uart.c        |   16 +++--
 hw/milkymist-vgafb.c       |   18 +++---
 hw/mips_malta.c            |   14 ++---
 hw/mipsnet.c               |   20 ++++---
 hw/mpc8544_guts.c          |   11 ++--
 hw/mst_fpga.c              |   16 +++--
 hw/musicpal.c              |  117 +++++++++++++++++++++----------------
 hw/nand.c                  |   18 +++---
 hw/ne2000-isa.c            |   26 +++++----
 hw/ne2000.c                |   16 +++--
 hw/omap_gpio.c             |   32 ++++++-----
 hw/omap_intc.c             |   32 ++++++-----
 hw/onenand.c               |   16 +++--
 hw/opencores_eth.c         |   18 +++---
 hw/parallel.c              |   28 +++++----
 hw/pc.c                    |   18 +++---
 hw/pci.c                   |   21 +++----
 hw/pci.h                   |    2 -
 hw/pckbd.c                 |   16 +++--
 hw/pcnet-pci.c             |   18 +++---
 hw/piix4.c                 |   18 +++---
 hw/piix_pci.c              |   70 ++++++++++++----------
 hw/pl011.c                 |   22 ++++---
 hw/pl022.c                 |   11 ++--
 hw/pl031.c                 |   16 +++--
 hw/pl041.c                 |   20 ++++---
 hw/pl050.c                 |   28 +++++----
 hw/pl061.c                 |   28 +++++----
 hw/pl080.c                 |   32 ++++++-----
 hw/pl110.c                 |   48 +++++++++-------
 hw/pl181.c                 |   18 +++---
 hw/pl190.c                 |   18 +++---
 hw/ppc4xx_pci.c            |   28 +++++----
 hw/ppc_prep.c              |    2 +-
 hw/ppce500_pci.c           |   28 +++++----
 hw/ppce500_spin.c          |   11 ++--
 hw/prep_pci.c              |   26 +++++----
 hw/pxa2xx.c                |   56 ++++++++++--------
 hw/pxa2xx_dma.c            |   18 +++---
 hw/pxa2xx_gpio.c           |   16 +++--
 hw/pxa2xx_pic.c            |   16 +++--
 hw/pxa2xx_timer.c          |   36 ++++++-----
 hw/qdev.h                  |    1 -
 hw/qxl.c                   |   40 +++++++------
 hw/realview.c              |   11 ++--
 hw/realview_gic.c          |   11 ++--
 hw/rtl8139.c               |   18 +++---
 hw/s390-virtio-bus.c       |  138 ++++++++++++++++++++++----------------------
 hw/s390-virtio-bus.h       |   19 ++++++-
 hw/sb16.c                  |   34 ++++++-----
 hw/sbi.c                   |   16 +++--
 hw/scsi-bus.c              |   19 +++---
 hw/scsi-disk.c             |  116 +++++++++++++++++++++----------------
 hw/scsi-generic.c          |   28 +++++----
 hw/scsi.h                  |    1 -
 hw/serial.c                |   30 ++++++----
 hw/sga.c                   |   14 +++--
 hw/sh_pci.c                |   22 ++++---
 hw/slavio_intctl.c         |   16 +++--
 hw/slavio_misc.c           |   27 +++++----
 hw/slavio_timer.c          |   18 +++---
 hw/smbus.c                 |    6 --
 hw/smbus.h                 |    2 -
 hw/smbus_eeprom.c          |   22 ++++---
 hw/smc91c111.c             |   18 +++---
 hw/spapr_llan.c            |   14 +++--
 hw/spapr_pci.c             |   22 ++++---
 hw/spapr_vio.c             |   35 ++++++------
 hw/spapr_vio.h             |    1 -
 hw/spapr_vscsi.c           |   14 +++--
 hw/spapr_vty.c             |   14 +++--
 hw/sparc32_dma.c           |   18 +++---
 hw/spitz.c                 |   60 +++++++++++--------
 hw/ssd0303.c               |   14 +++--
 hw/ssd0323.c               |   11 ++--
 hw/ssi-sd.c                |   11 ++--
 hw/ssi.c                   |   24 ++++++--
 hw/ssi.h                   |    2 -
 hw/stellaris.c             |   44 ++++++++------
 hw/stellaris_enet.c        |   14 +++--
 hw/strongarm.c             |   98 +++++++++++++++++--------------
 hw/sun4c_intctl.c          |   16 +++--
 hw/sun4m.c                 |   50 +++++++++-------
 hw/sun4m_iommu.c           |   18 +++---
 hw/sun4u.c                 |   39 +++++++------
 hw/sysbus.c                |   22 +++-----
 hw/sysbus.h                |    4 -
 hw/tcx.c                   |   18 +++---
 hw/tmp105.c                |   14 +++--
 hw/tosa.c                  |   24 ++++----
 hw/tusb6010.c              |   14 +++--
 hw/twl92230.c              |   14 +++--
 hw/unin_pci.c              |   74 +++++++++++++-----------
 hw/usb-audio.c             |   29 ++++++----
 hw/usb-bt.c                |   14 +++--
 hw/usb-bus.c               |   19 +++---
 hw/usb-ccid.c              |   43 ++++++++------
 hw/usb-ehci.c              |   32 ++++++-----
 hw/usb-hid.c               |   42 ++++++++------
 hw/usb-hub.c               |   18 +++---
 hw/usb-msd.c               |   30 ++++++----
 hw/usb-net.c               |   26 +++++----
 hw/usb-ohci.c              |   42 ++++++++------
 hw/usb-serial.c            |   48 +++++++++------
 hw/usb-uhci.c              |   96 +++++++++++++++++-------------
 hw/usb-wacom.c             |   20 ++++---
 hw/usb-xhci.c              |   25 +++++----
 hw/usb.h                   |    1 -
 hw/versatile_pci.c         |   33 ++++++-----
 hw/versatilepb.c           |   16 +++--
 hw/vga-isa.c               |   16 +++--
 hw/vga-pci.c               |   14 +++--
 hw/virtio-console.c        |   28 +++++----
 hw/virtio-pci.c            |   76 ++++++++++++++----------
 hw/virtio-serial-bus.c     |   19 +++---
 hw/virtio-serial.h         |    6 --
 hw/vmmouse.c               |   28 +++++----
 hw/vmport.c                |   14 +++--
 hw/vmware_vga.c            |   16 +++--
 hw/vt82c686.c              |   64 +++++++++++---------
 hw/wdt_i6300esb.c          |   16 +++--
 hw/wdt_ib700.c             |   16 +++--
 hw/wm8750.c                |   14 +++--
 hw/xen_platform.c          |   18 +++---
 hw/xgmac.c                 |   25 +++++---
 hw/xilinx_axidma.c         |   14 +++--
 hw/xilinx_axienet.c        |   14 +++--
 hw/xilinx_ethlite.c        |   14 +++--
 hw/xilinx_intc.c           |   14 +++--
 hw/xilinx_timer.c          |   14 +++--
 hw/xilinx_uartlite.c       |   11 ++--
 hw/xio3130_downstream.c    |   20 ++++---
 hw/xio3130_upstream.c      |   20 ++++---
 hw/z2.c                    |   28 +++++----
 hw/zaurus.c                |   18 +++---
 usb-linux.c                |   34 ++++++-----
 242 files changed, 3169 insertions(+), 2544 deletions(-)

diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index aded048..3f15540 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -174,6 +174,7 @@ static Property virtio_9p_properties[] = {
 
 static void virtio_9p_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = virtio_9p_init_pci;
@@ -181,19 +182,20 @@ static void virtio_9p_class_init(ObjectClass *klass, void *data)
     k->device_id = 0x1009;
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = 0x2;
+    dc->props = virtio_9p_properties;
+    dc->reset = virtio_pci_reset;
 }
 
-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 TypeInfo virtio_9p_info = {
+    .name          = "virtio-9p-pci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(VirtIOPCIProxy),
+    .class_init    = virtio_9p_class_init,
 };
 
 static void virtio_9p_register_devices(void)
 {
-    pci_qdev_register(&virtio_9p_info);
+    type_register_static(&virtio_9p_info);
     virtio_9p_set_fd_limit();
 }
 
diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index b42c475..19de12b 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -208,35 +208,39 @@ static const VMStateDescription vmstate_a9mp_priv = {
     }
 };
 
+static Property a9mp_priv_properties[] = {
+    DEFINE_PROP_UINT32("num-cpu", a9mp_priv_state, num_cpu, 1),
+    /* The Cortex-A9MP may have anything from 0 to 224 external interrupt
+     * IRQ lines (with another 32 internal). We default to 64+32, which
+     * is the number provided by the Cortex-A9MP test chip in the
+     * Realview PBX-A9 and Versatile Express A9 development boards.
+     * Other boards may differ and should set this property appropriately.
+     */
+    DEFINE_PROP_UINT32("num-irq", a9mp_priv_state, num_irq, 96),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void a9mp_priv_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = a9mp_priv_init;
+    dc->props = a9mp_priv_properties;
+    dc->vmsd = &vmstate_a9mp_priv;
+    dc->reset = a9mp_priv_reset;
 }
 
-static DeviceInfo a9mp_priv_info = {
-    .name = "a9mpcore_priv",
-    .size  = sizeof(a9mp_priv_state),
-    .vmsd = &vmstate_a9mp_priv,
-    .reset = a9mp_priv_reset,
-    .class_init = a9mp_priv_class_init,
-    .props = (Property[]) {
-        DEFINE_PROP_UINT32("num-cpu", a9mp_priv_state, num_cpu, 1),
-        /* The Cortex-A9MP may have anything from 0 to 224 external interrupt
-         * IRQ lines (with another 32 internal). We default to 64+32, which
-         * is the number provided by the Cortex-A9MP test chip in the
-         * Realview PBX-A9 and Versatile Express A9 development boards.
-         * Other boards may differ and should set this property appropriately.
-         */
-        DEFINE_PROP_UINT32("num-irq", a9mp_priv_state, num_irq, 96),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static TypeInfo a9mp_priv_info = {
+    .name          = "a9mpcore_priv",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(a9mp_priv_state),
+    .class_init    = a9mp_priv_class_init,
 };
 
 static void a9mp_register_devices(void)
 {
-    sysbus_register_withprop(&a9mp_priv_info);
+    type_register_static(&a9mp_priv_info);
 }
 
 device_init(a9mp_register_devices)
diff --git a/hw/ac97.c b/hw/ac97.c
index 33b85f5..ed2e4cd 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -1351,6 +1351,7 @@ static Property ac97_properties[] = {
 
 static void ac97_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = ac97_initfn;
@@ -1359,20 +1360,21 @@ static void ac97_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
     k->revision = 0x01;
     k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+    dc->desc = "Intel 82801AA AC97 Audio";
+    dc->vmsd = &vmstate_ac97;
+    dc->props = ac97_properties;
 }
 
-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 TypeInfo ac97_info = {
+    .name          = "AC97",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof (AC97LinkState),
+    .class_init    = ac97_class_init,
 };
 
 static void ac97_register (void)
 {
-    pci_qdev_register (&ac97_info);
+    type_register_static(&ac97_info);
 }
 device_init (ac97_register);
 
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 9058a7c..21484ae 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -403,6 +403,7 @@ static Property piix4_pm_properties[] = {
 
 static void piix4_pm_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->no_hotplug = 1;
@@ -412,21 +413,22 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_INTEL_82371AB_3;
     k->revision = 0x03;
     k->class_id = PCI_CLASS_BRIDGE_OTHER;
+    dc->desc = "PM";
+    dc->no_user = 1;
+    dc->vmsd = &vmstate_acpi;
+    dc->props = piix4_pm_properties;
 }
 
-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 TypeInfo piix4_pm_info = {
+    .name          = "PIIX4_PM",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PIIX4PMState),
+    .class_init    = piix4_pm_class_init,
 };
 
 static void piix4_pm_register(void)
 {
-    pci_qdev_register(&piix4_pm_info);
+    type_register_static(&piix4_pm_info);
 }
 
 device_init(piix4_pm_register);
diff --git a/hw/ads7846.c b/hw/ads7846.c
index c1b894e..3cfdecb 100644
--- a/hw/ads7846.c
+++ b/hw/ads7846.c
@@ -161,15 +161,16 @@ static void ads7846_class_init(ObjectClass *klass, void *data)
     k->transfer = ads7846_transfer;
 }
 
-static DeviceInfo ads7846_info = {
-    .name = "ads7846",
-    .size = sizeof(ADS7846State),
-    .class_init = ads7846_class_init,
+static TypeInfo ads7846_info = {
+    .name          = "ads7846",
+    .parent        = TYPE_SSI_SLAVE,
+    .instance_size = sizeof(ADS7846State),
+    .class_init    = ads7846_class_init,
 };
 
 static void ads7846_register_devices(void)
 {
-    ssi_register_slave(&ads7846_info);
+    type_register_static(&ads7846_info);
 }
 
 device_init(ads7846_register_devices)
diff --git a/hw/alpha_typhoon.c b/hw/alpha_typhoon.c
index 8a68c7c..736c28a 100644
--- a/hw/alpha_typhoon.c
+++ b/hw/alpha_typhoon.c
@@ -810,20 +810,22 @@ static int typhoon_pcihost_init(SysBusDevice *dev)
 
 static void typhoon_pcihost_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = typhoon_pcihost_init;
+    dc->no_user = 1;
 }
 
-static DeviceInfo typhoon_pcihost_info = {
-    .name = "typhoon-pcihost",
-    .size = sizeof(TyphoonState),
-    .no_user = 1,
-    .class_init = typhoon_pcihost_class_init,
+static TypeInfo typhoon_pcihost_info = {
+    .name          = "typhoon-pcihost",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(TyphoonState),
+    .class_init    = typhoon_pcihost_class_init,
 };
 
 static void typhoon_register(void)
 {
-    sysbus_register_withprop(&typhoon_pcihost_info);
+    type_register_static(&typhoon_pcihost_info);
 }
 device_init(typhoon_register);
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 1a45420..c7aaa72 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -447,28 +447,32 @@ static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
     k->is_bridge = 1;
 }
 
-static DeviceInfo pbm_pci_host_info = {
-    .name = "pbm-pci",
-    .size = sizeof(PCIDevice),
-    .class_init = pbm_pci_host_class_init,
+static TypeInfo pbm_pci_host_info = {
+    .name          = "pbm-pci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
+    .class_init    = pbm_pci_host_class_init,
 };
 
 static void pbm_host_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pci_pbm_init_device;
+    dc->reset = pci_pbm_reset;
 }
 
-static DeviceInfo pbm_host_info = {
-    .name = "pbm",
-    .size = sizeof(APBState),
-    .reset = pci_pbm_reset,
-    .class_init = pbm_host_class_init,
+static TypeInfo pbm_host_info = {
+    .name          = "pbm",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(APBState),
+    .class_init    = pbm_host_class_init,
 };
 
 static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = apb_pci_bridge_initfn;
@@ -478,21 +482,22 @@ static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
     k->revision = 0x11;
     k->config_write = pci_bridge_write_config;
     k->is_bridge = 1;
+    dc->reset = pci_bridge_reset;
+    dc->vmsd = &vmstate_pci_device;
 }
 
-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 TypeInfo pbm_pci_bridge_info = {
+    .name          = "pbm-bridge",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIBridge),
+    .class_init    = pbm_pci_bridge_class_init,
 };
 
 static void pbm_register_devices(void)
 {
-    sysbus_register_withprop(&pbm_host_info);
-    pci_qdev_register(&pbm_pci_host_info);
-    pci_qdev_register(&pbm_pci_bridge_info);
+    type_register_static(&pbm_host_info);
+    type_register_static(&pbm_pci_host_info);
+    type_register_static(&pbm_pci_bridge_info);
 }
 
 device_init(pbm_register_devices)
diff --git a/hw/apic.c b/hw/apic.c
index 353119d..086c544 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -774,14 +774,16 @@ static void apic_class_init(ObjectClass *klass, void *data)
     k->post_load = apic_post_load;
 }
 
-static DeviceInfo apic_info = {
-    .name = "apic",
-    .class_init = apic_class_init,
+static TypeInfo apic_info = {
+    .name          = "apic",
+    .instance_size = sizeof(APICCommonState),
+    .parent        = TYPE_APIC_COMMON,
+    .class_init    = apic_class_init,
 };
 
 static void apic_register_devices(void)
 {
-    apic_qdev_register(&apic_info);
+    type_register_static(&apic_info);
 }
 
 device_init(apic_register_devices)
diff --git a/hw/apic_common.c b/hw/apic_common.c
index 9a3b1c5..26991b4 100644
--- a/hw/apic_common.c
+++ b/hw/apic_common.c
@@ -295,7 +295,12 @@ static Property apic_properties_common[] = {
 static void apic_common_class_init(ObjectClass *klass, void *data)
 {
     SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
+    dc->vmsd = &vmstate_apic_common;
+    dc->reset = apic_reset_common;
+    dc->no_user = 1;
+    dc->props = apic_properties_common;
     sc->init = apic_init_common;
 }
 
@@ -308,16 +313,6 @@ static TypeInfo apic_common_type = {
     .abstract = true,
 };
 
-void apic_qdev_register(DeviceInfo *info)
-{
-    info->size = sizeof(APICCommonState),
-    info->vmsd = &vmstate_apic_common;
-    info->reset = apic_reset_common;
-    info->no_user = 1;
-    info->props = apic_properties_common;
-    sysbus_qdev_register_subclass(info, TYPE_APIC_COMMON);
-}
-
 static void register_devices(void)
 {
     type_register_static(&apic_common_type);
diff --git a/hw/apic_internal.h b/hw/apic_internal.h
index 1c6971c..0cab010 100644
--- a/hw/apic_internal.h
+++ b/hw/apic_internal.h
@@ -117,7 +117,6 @@ struct APICCommonState {
 };
 
 void apic_report_irq_delivered(int delivered);
-void apic_qdev_register(DeviceInfo *info);
 bool apic_next_timer(APICCommonState *s, int64_t current_time);
 
 #endif /* !QEMU_APIC_INTERNAL_H */
diff --git a/hw/applesmc.c b/hw/applesmc.c
index a6e88bc..b06487f 100644
--- a/hw/applesmc.c
+++ b/hw/applesmc.c
@@ -220,28 +220,32 @@ static int applesmc_isa_init(ISADevice *dev)
     return 0;
 }
 
+static Property applesmc_isa_properties[] = {
+    DEFINE_PROP_HEX32("iobase", struct AppleSMCStatus, iobase,
+                      APPLESMC_DEFAULT_IOBASE),
+    DEFINE_PROP_STRING("osk", struct AppleSMCStatus, osk),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void qdev_applesmc_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = applesmc_isa_init;
+    dc->reset = qdev_applesmc_isa_reset;
+    dc->props = applesmc_isa_properties;
 }
 
-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),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static TypeInfo applesmc_isa_info = {
+    .name          = "isa-applesmc",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(struct AppleSMCStatus),
+    .class_init    = qdev_applesmc_class_init,
 };
 
 static void applesmc_register_devices(void)
 {
-    isa_qdev_register(&applesmc_isa_info);
+    type_register_static(&applesmc_isa_info);
 }
 
 device_init(applesmc_register_devices)
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index 53c5408..3c0839c 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -217,16 +217,18 @@ static Property mpcore_rirq_properties[] = {
 
 static void mpcore_rirq_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = realview_mpcore_init;
+    dc->props = mpcore_rirq_properties;
 }
 
-static DeviceInfo mpcore_rirq_info = {
-    .name = "realview_mpcore",
-    .size = sizeof(mpcore_rirq_state),
-    .props = mpcore_rirq_properties,
-    .class_init = mpcore_rirq_class_init,
+static TypeInfo mpcore_rirq_info = {
+    .name          = "realview_mpcore",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(mpcore_rirq_state),
+    .class_init    = mpcore_rirq_class_init,
 };
 
 static Property mpcore_priv_properties[] = {
@@ -236,22 +238,24 @@ static Property mpcore_priv_properties[] = {
 
 static void mpcore_priv_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = mpcore_priv_init;
+    dc->props = mpcore_priv_properties;
 }
 
-static DeviceInfo mpcore_priv_info = {
-    .name = "arm11mpcore_priv",
-    .size = sizeof(mpcore_priv_state),
-    .props = mpcore_priv_properties,
-    .class_init = mpcore_priv_class_init,
+static TypeInfo mpcore_priv_info = {
+    .name          = "arm11mpcore_priv",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(mpcore_priv_state),
+    .class_init    = mpcore_priv_class_init,
 };
 
 static void arm11mpcore_register_devices(void)
 {
-    sysbus_register_withprop(&mpcore_rirq_info);
-    sysbus_register_withprop(&mpcore_priv_info);
+    type_register_static(&mpcore_rirq_info);
+    type_register_static(&mpcore_priv_info);
 }
 
 device_init(arm11mpcore_register_devices)
diff --git a/hw/arm_l2x0.c b/hw/arm_l2x0.c
index 7c5fe32..ba26abc 100644
--- a/hw/arm_l2x0.c
+++ b/hw/arm_l2x0.c
@@ -160,29 +160,33 @@ static int l2x0_priv_init(SysBusDevice *dev)
     return 0;
 }
 
+static Property l2x0_properties[] = {
+    DEFINE_PROP_UINT32("type", l2x0_state, cache_type, 0x1c100100),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void l2x0_class_init(ObjectClass *klass, void *data)
 {
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     k->init = l2x0_priv_init;
+    dc->vmsd = &vmstate_l2x0;
+    dc->no_user = 1;
+    dc->props = l2x0_properties;
+    dc->reset = l2x0_priv_reset;
 }
 
-static DeviceInfo l2x0_info = {
+static TypeInfo l2x0_info = {
     .name = "l2x0",
-    .size = sizeof(l2x0_state),
-    .vmsd = &vmstate_l2x0,
-    .no_user = 1,
-    .props = (Property[]) {
-        DEFINE_PROP_UINT32("type", l2x0_state, cache_type, 0x1c100100),
-        DEFINE_PROP_END_OF_LIST(),
-    },
-    .reset = l2x0_priv_reset,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(l2x0_state),
     .class_init = l2x0_class_init,
 };
 
 static void l2x0_register_device(void)
 {
-    sysbus_qdev_register(&l2x0_info);
+    type_register_static(&l2x0_info);
 }
 
 device_init(l2x0_register_device)
diff --git a/hw/arm_mptimer.c b/hw/arm_mptimer.c
index 06319c2..5a02365 100644
--- a/hw/arm_mptimer.c
+++ b/hw/arm_mptimer.c
@@ -311,29 +311,33 @@ static const VMStateDescription vmstate_arm_mptimer = {
     }
 };
 
+static Property arm_mptimer_properties[] = {
+    DEFINE_PROP_UINT32("num-cpu", arm_mptimer_state, num_cpu, 0),
+    DEFINE_PROP_END_OF_LIST()
+};
+
 static void arm_mptimer_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
 
     sbc->init = arm_mptimer_init;
+    dc->vmsd = &vmstate_arm_mptimer;
+    dc->reset = arm_mptimer_reset;
+    dc->no_user = 1;
+    dc->props = arm_mptimer_properties;
 }
 
-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()
-    }
+static TypeInfo arm_mptimer_info = {
+    .name          = "arm_mptimer",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(arm_mptimer_state),
+    .class_init    = arm_mptimer_class_init,
 };
 
 static void arm_mptimer_register_devices(void)
 {
-    sysbus_register_withprop(&arm_mptimer_info);
+    type_register_static(&arm_mptimer_info);
 }
 
 device_init(arm_mptimer_register_devices)
diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index 08fb443..9d25799 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -409,23 +409,25 @@ static Property arm_sysctl_properties[] = {
 
 static void arm_sysctl_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = arm_sysctl_init1;
+    dc->reset = arm_sysctl_reset;
+    dc->vmsd = &vmstate_arm_sysctl;
+    dc->props = arm_sysctl_properties;
 }
 
-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 TypeInfo arm_sysctl_info = {
+    .name          = "realview_sysctl",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(arm_sysctl_state),
+    .class_init    = arm_sysctl_class_init,
 };
 
 static void arm_sysctl_register_devices(void)
 {
-    sysbus_register_withprop(&arm_sysctl_info);
+    type_register_static(&arm_sysctl_info);
 }
 
 device_init(arm_sysctl_register_devices)
diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index 15eb37c..1019d41 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -354,34 +354,39 @@ static void icp_pit_class_init(ObjectClass *klass, void *data)
     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 TypeInfo icp_pit_info = {
+    .name          = "integrator_pit",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(icp_pit_state),
+    .class_init    = icp_pit_class_init,
+};
+
+static Property sp804_properties[] = {
+    DEFINE_PROP_UINT32("freq0", sp804_state, freq0, 1000000),
+    DEFINE_PROP_UINT32("freq1", sp804_state, freq1, 1000000),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
 static void sp804_class_init(ObjectClass *klass, void *data)
 {
     SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *k = DEVICE_CLASS(klass);
 
     sdc->init = sp804_init;
+    k->props = sp804_properties;
 }
 
-static DeviceInfo sp804_info = {
-    .name = "sp804",
-    .size = sizeof(sp804_state),
-    .class_init = sp804_class_init,
-    .props = (Property[]) {
-        DEFINE_PROP_UINT32("freq0", sp804_state, freq0, 1000000),
-        DEFINE_PROP_UINT32("freq1", sp804_state, freq1, 1000000),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static TypeInfo sp804_info = {
+    .name          = "sp804",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(sp804_state),
+    .class_init    = sp804_class_init,
 };
 
 static void arm_timer_register_devices(void)
 {
-    sysbus_qdev_register(&icp_pit_info);
-    sysbus_qdev_register(&sp804_info);
+    type_register_static(&icp_pit_info);
+    type_register_static(&sp804_info);
 }
 
 device_init(arm_timer_register_devices)
diff --git a/hw/armv7m.c b/hw/armv7m.c
index 884fc90..de3d7e0 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -252,21 +252,23 @@ static Property bitband_properties[] = {
 
 static void bitband_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = bitband_init;
+    dc->props = bitband_properties;
 }
 
-static DeviceInfo bitband_info = {
-    .name = "ARM,bitband-memory",
-    .size = sizeof(BitBandState),
-    .props = bitband_properties,
-    .class_init = bitband_class_init,
+static TypeInfo bitband_info = {
+    .name          = "ARM,bitband-memory",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(BitBandState),
+    .class_init    = bitband_class_init,
 };
 
 static void armv7m_register_devices(void)
 {
-    sysbus_register_withprop(&bitband_info);
+    type_register_static(&bitband_info);
 }
 
 device_init(armv7m_register_devices)
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 2bb94e8..1ed0abc 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -391,31 +391,35 @@ static int armv7m_nvic_init(SysBusDevice *dev)
     return 0;
 }
 
+static Property armv7m_nvic_properties[] = {
+    /* The ARM v7m may have anything from 0 to 496 external interrupt
+     * IRQ lines. We default to 64. Other boards may differ and should
+     * set this property appropriately.
+     */
+    DEFINE_PROP_UINT32("num-irq", nvic_state, num_irq, 64),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
 
     sdc->init = armv7m_nvic_init;
+    dc->vmsd  = &vmstate_nvic;
+    dc->props = armv7m_nvic_properties;
 }
 
-static DeviceInfo armv7m_nvic_priv_info = {
-    .name = "armv7m_nvic",
-    .size = sizeof(nvic_state),
-    .vmsd  = &vmstate_nvic,
-    .class_init = armv7m_nvic_class_init,
-    .props = (Property[]) {
-        /* The ARM v7m may have anything from 0 to 496 external interrupt
-         * IRQ lines. We default to 64. Other boards may differ and should
-         * set this property appropriately.
-         */
-        DEFINE_PROP_UINT32("num-irq", nvic_state, num_irq, 64),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static TypeInfo armv7m_nvic_info = {
+    .name          = "armv7m_nvic",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(nvic_state),
+    .class_init    = armv7m_nvic_class_init,
 };
 
 static void armv7m_nvic_register_devices(void)
 {
-    sysbus_qdev_register(&armv7m_nvic_priv_info);
+    type_register_static(&armv7m_nvic_info);
 }
 
 device_init(armv7m_nvic_register_devices)
diff --git a/hw/bitbang_i2c.c b/hw/bitbang_i2c.c
index da9e5cf..c9c1182 100644
--- a/hw/bitbang_i2c.c
+++ b/hw/bitbang_i2c.c
@@ -223,21 +223,23 @@ static int gpio_i2c_init(SysBusDevice *dev)
 
 static void gpio_i2c_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = gpio_i2c_init;
+    dc->desc = "Virtual GPIO to I2C bridge";
 }
 
-static DeviceInfo gpio_i2c_info = {
-    .name = "gpio_i2c",
-    .desc = "Virtual GPIO to I2C bridge",
-    .size = sizeof(GPIOI2CState),
-    .class_init = gpio_i2c_class_init,
+static TypeInfo gpio_i2c_info = {
+    .name          = "gpio_i2c",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(GPIOI2CState),
+    .class_init    = gpio_i2c_class_init,
 };
 
 static void bitbang_i2c_register(void)
 {
-    sysbus_register_withprop(&gpio_i2c_info);
+    type_register_static(&gpio_i2c_info);
 }
 
 device_init(bitbang_i2c_register)
diff --git a/hw/bonito.c b/hw/bonito.c
index 0333a2e..7350a4f 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -768,6 +768,7 @@ PCIBus *bonito_init(qemu_irq *pic)
 
 static void bonito_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = bonito_initfn;
@@ -775,34 +776,37 @@ static void bonito_class_init(ObjectClass *klass, void *data)
     k->device_id = 0x00d5;
     k->revision = 0x01;
     k->class_id = PCI_CLASS_BRIDGE_HOST;
+    dc->desc = "Host bridge";
+    dc->no_user = 1;
+    dc->vmsd = &vmstate_bonito;
 }
 
-static DeviceInfo bonito_info = {
-    .name = "Bonito",
-    .desc = "Host bridge",
-    .size = sizeof(PCIBonitoState),
-    .vmsd = &vmstate_bonito,
-    .no_user = 1,
-    .class_init = bonito_class_init,
+static TypeInfo bonito_info = {
+    .name          = "Bonito",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIBonitoState),
+    .class_init    = bonito_class_init,
 };
 
 static void bonito_pcihost_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = bonito_pcihost_initfn;
+    dc->no_user = 1;
 }
 
-static DeviceInfo bonito_pcihost_info = {
-    .name = "Bonito-pcihost",
-    .size = sizeof(BonitoState),
-    .no_user = 1,
-    .class_init = bonito_pcihost_class_init,
+static TypeInfo bonito_pcihost_info = {
+    .name          = "Bonito-pcihost",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(BonitoState),
+    .class_init    = bonito_pcihost_class_init,
 };
 
 static void bonito_register(void)
 {
-    sysbus_register_withprop(&bonito_pcihost_info);
-    pci_qdev_register(&bonito_info);
+    type_register_static(&bonito_pcihost_info);
+    type_register_static(&bonito_info);
 }
 device_init(bonito_register);
diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c
index 6dabe7a..9510ed4 100644
--- a/hw/ccid-card-emulated.c
+++ b/hw/ccid-card-emulated.c
@@ -564,36 +564,39 @@ static int emulated_exitfn(CCIDCardState *base)
     return 0;
 }
 
+static Property emulated_card_properties[] = {
+    DEFINE_PROP_STRING("backend", EmulatedState, backend_str),
+    DEFINE_PROP_STRING("cert1", EmulatedState, cert1),
+    DEFINE_PROP_STRING("cert2", EmulatedState, cert2),
+    DEFINE_PROP_STRING("cert3", EmulatedState, cert3),
+    DEFINE_PROP_STRING("db", EmulatedState, db),
+    DEFINE_PROP_UINT8("debug", EmulatedState, debug, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void emulated_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     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;
+    dc->desc = "emulated smartcard";
+    dc->props = emulated_card_properties;
 }
 
-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),
-        DEFINE_PROP_STRING("cert3", EmulatedState, cert3),
-        DEFINE_PROP_STRING("db", EmulatedState, db),
-        DEFINE_PROP_UINT8("debug", EmulatedState, debug, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static TypeInfo emulated_card_info = {
+    .name          = EMULATED_DEV_NAME,
+    .parent        = TYPE_CCID_CARD,
+    .instance_size = sizeof(EmulatedState),
+    .class_init    = emulated_class_initfn,
 };
 
 static void ccid_card_emulated_register_devices(void)
 {
-    ccid_card_qdev_register(&emulated_card_info);
+    type_register_static(&emulated_card_info);
 }
 
 device_init(ccid_card_emulated_register_devices)
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
index f563d97..a7006ca 100644
--- a/hw/ccid-card-passthru.c
+++ b/hw/ccid-card-passthru.c
@@ -316,32 +316,36 @@ static VMStateDescription passthru_vmstate = {
     }
 };
 
+static Property passthru_card_properties[] = {
+    DEFINE_PROP_CHR("chardev", PassthruState, cs),
+    DEFINE_PROP_UINT8("debug", PassthruState, debug, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void passthru_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     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;
+    dc->desc = "passthrough smartcard";
+    dc->vmsd = &passthru_vmstate;
+    dc->props = passthru_card_properties;
 }
 
-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(),
-    },
+static TypeInfo passthru_card_info = {
+    .name          = PASSTHRU_DEV_NAME,
+    .parent        = TYPE_CCID_CARD,
+    .instance_size = sizeof(PassthruState),
+    .class_init    = passthru_class_initfn,
 };
 
 static void ccid_card_passthru_register_devices(void)
 {
-    ccid_card_qdev_register(&passthru_card_info);
+    type_register_static(&passthru_card_info);
 }
 
 device_init(ccid_card_passthru_register_devices)
diff --git a/hw/ccid.h b/hw/ccid.h
index 9e4979c..6adc745 100644
--- a/hw/ccid.h
+++ b/hw/ccid.h
@@ -54,7 +54,6 @@ 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(DeviceInfo *card);
 
 /*
  * support guest visible insertion/removal of ccid devices based on actual
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index c203080..116e2b1 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2901,20 +2901,22 @@ static int vga_initfn(ISADevice *dev)
 static void isa_cirrus_vga_class_init(ObjectClass *klass, void *data)
 {
     ISADeviceClass *k = ISA_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
-    k->init          = vga_initfn;
+    dc->vmsd  = &vmstate_cirrus_vga;
+    k->init   = vga_initfn;
 }
 
-static DeviceInfo isa_cirrus_vga_info = {
-    .name     = "isa-cirrus-vga",
-    .size     = sizeof(ISACirrusVGAState),
-    .vmsd     = &vmstate_cirrus_vga,
+static TypeInfo isa_cirrus_vga_info = {
+    .name          = "isa-cirrus-vga",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(ISACirrusVGAState),
     .class_init = isa_cirrus_vga_class_init,
 };
 
 static void isa_cirrus_vga_register(void)
 {
-    isa_qdev_register(&isa_cirrus_vga_info);
+    type_register_static(&isa_cirrus_vga_info);
 }
 device_init(isa_cirrus_vga_register)
 
@@ -2965,6 +2967,7 @@ DeviceState *pci_cirrus_vga_init(PCIBus *bus)
 
 static void cirrus_vga_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->no_hotplug = 1;
@@ -2973,18 +2976,19 @@ static void cirrus_vga_class_init(ObjectClass *klass, void *data)
     k->vendor_id = PCI_VENDOR_ID_CIRRUS;
     k->device_id = CIRRUS_ID_CLGD5446;
     k->class_id = PCI_CLASS_DISPLAY_VGA;
+    dc->desc = "Cirrus CLGD 54xx VGA";
+    dc->vmsd = &vmstate_pci_cirrus_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 TypeInfo cirrus_vga_info = {
+    .name          = "cirrus-vga",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCICirrusVGAState),
+    .class_init    = cirrus_vga_class_init,
 };
 
 static void cirrus_vga_register(void)
 {
-    pci_qdev_register(&cirrus_vga_info);
+    type_register_static(&cirrus_vga_info);
 }
 device_init(cirrus_vga_register);
diff --git a/hw/container.c b/hw/container.c
index 73f94c5..1e97031 100644
--- a/hw/container.c
+++ b/hw/container.c
@@ -7,21 +7,23 @@ static int container_initfn(SysBusDevice *dev)
 
 static void container_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = container_initfn;
+    dc->no_user = 1;
 }
 
-static DeviceInfo container_info = {
-    .name = "container",
-    .size = sizeof(SysBusDevice),
-    .no_user = 1,
-    .class_init = container_class_init,
+static TypeInfo container_info = {
+    .name          = "container",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SysBusDevice),
+    .class_init    = container_class_init,
 };
 
 static void container_init(void)
 {
-    sysbus_register_withprop(&container_info);
+    type_register_static(&container_info);
 }
 
 device_init(container_init);
diff --git a/hw/cs4231.c b/hw/cs4231.c
index 87c4eb9..c0badbf 100644
--- a/hw/cs4231.c
+++ b/hw/cs4231.c
@@ -157,23 +157,25 @@ static Property cs4231_properties[] = {
 
 static void cs4231_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = cs4231_init1;
+    dc->reset = cs_reset;
+    dc->vmsd = &vmstate_cs4231;
+    dc->props = cs4231_properties;
 }
 
-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 TypeInfo cs4231_info = {
+    .name          = "SUNW,CS4231",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(CSState),
+    .class_init    = cs4231_class_init,
 };
 
 static void cs4231_register_devices(void)
 {
-    sysbus_register_withprop(&cs4231_info);
+    type_register_static(&cs4231_info);
 }
 
 device_init(cs4231_register_devices)
diff --git a/hw/cs4231a.c b/hw/cs4231a.c
index 811c76b..811dda6 100644
--- a/hw/cs4231a.c
+++ b/hw/cs4231a.c
@@ -665,28 +665,32 @@ int cs4231a_init (ISABus *bus)
     return 0;
 }
 
+static Property cs4231a_properties[] = {
+    DEFINE_PROP_HEX32  ("iobase",  CSState, port, 0x534),
+    DEFINE_PROP_UINT32 ("irq",     CSState, irq,  9),
+    DEFINE_PROP_UINT32 ("dma",     CSState, dma,  3),
+    DEFINE_PROP_END_OF_LIST (),
+};
+
 static void cs4231a_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = cs4231a_initfn;
+    dc->desc = "Crystal Semiconductor CS4231A";
+    dc->vmsd = &vmstate_cs4231a;
+    dc->props = cs4231a_properties;
 }
 
-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),
-        DEFINE_PROP_END_OF_LIST (),
-    },
+static TypeInfo cs4231a_info = {
+    .name          = "cs4231a",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof (CSState),
+    .class_init    = cs4231a_class_initfn,
 };
 
 static void cs4231a_register (void)
 {
-    isa_qdev_register (&cs4231a_info);
+    type_register_static(&cs4231a_info);
 }
 device_init (cs4231a_register)
diff --git a/hw/debugcon.c b/hw/debugcon.c
index f290122..3903b26 100644
--- a/hw/debugcon.c
+++ b/hw/debugcon.c
@@ -87,27 +87,31 @@ static int debugcon_isa_initfn(ISADevice *dev)
     return 0;
 }
 
+static Property debugcon_isa_properties[] = {
+    DEFINE_PROP_HEX32("iobase", ISADebugconState, iobase, 0xe9),
+    DEFINE_PROP_CHR("chardev",  ISADebugconState, state.chr),
+    DEFINE_PROP_HEX32("readback", ISADebugconState, state.readback, 0xe9),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void debugcon_isa_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = debugcon_isa_initfn;
+    dc->props = debugcon_isa_properties;
 }
 
-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),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static TypeInfo debugcon_isa_info = {
+    .name          = "isa-debugcon",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(ISADebugconState),
+    .class_init    = debugcon_isa_class_initfn,
 };
 
 static void debugcon_register_devices(void)
 {
-    isa_qdev_register(&debugcon_isa_info);
+    type_register_static(&debugcon_isa_info);
 }
 
 device_init(debugcon_register_devices)
diff --git a/hw/dec_pci.c b/hw/dec_pci.c
index 333bad9..a40fbcf 100644
--- a/hw/dec_pci.c
+++ b/hw/dec_pci.c
@@ -52,6 +52,7 @@ static int dec_map_irq(PCIDevice *pci_dev, int irq_num)
 
 static void dec_21154_pci_bridge_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = pci_bridge_initfn;
@@ -60,15 +61,16 @@ static void dec_21154_pci_bridge_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_DEC_21154;
     k->config_write = pci_bridge_write_config;
     k->is_bridge = 1;
+    dc->desc = "DEC 21154 PCI-PCI bridge";
+    dc->reset = pci_bridge_reset;
+    dc->vmsd = &vmstate_pci_device;
 }
 
-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,
+static TypeInfo dec_21154_pci_bridge_info = {
+    .name          = "dec-21154-p2p-bridge",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIBridge),
+    .class_init    = dec_21154_pci_bridge_class_init,
 };
 
 PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
@@ -117,10 +119,11 @@ static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
     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 TypeInfo dec_21154_pci_host_info = {
+    .name          = "dec-21154",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
+    .class_init    = dec_21154_pci_host_class_init,
 };
 
 static void pci_dec_21154_device_class_init(ObjectClass *klass, void *data)
@@ -130,17 +133,18 @@ static void pci_dec_21154_device_class_init(ObjectClass *klass, void *data)
     sdc->init = pci_dec_21154_device_init;
 }
 
-static DeviceInfo pci_dec_21154_device_info = {
-    .name = "dec-21154-sysbus",
-    .size = sizeof(DECState),
-    .class_init = pci_dec_21154_device_class_init,
+static TypeInfo pci_dec_21154_device_info = {
+    .name          = "dec-21154-sysbus",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(DECState),
+    .class_init    = pci_dec_21154_device_class_init,
 };
 
 static void dec_register_devices(void)
 {
-    sysbus_qdev_register(&pci_dec_21154_device_info);
-    pci_qdev_register(&dec_21154_pci_host_info);
-    pci_qdev_register(&dec_21154_pci_bridge_info);
+    type_register_static(&pci_dec_21154_device_info);
+    type_register_static(&dec_21154_pci_host_info);
+    type_register_static(&dec_21154_pci_bridge_info);
 }
 
 device_init(dec_register_devices)
diff --git a/hw/ds1225y.c b/hw/ds1225y.c
index 5890b16..539bceb 100644
--- a/hw/ds1225y.c
+++ b/hw/ds1225y.c
@@ -142,22 +142,24 @@ static Property nvram_sysbus_properties[] = {
 
 static void nvram_sysbus_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = nvram_sysbus_initfn;
+    dc->vmsd = &vmstate_nvram;
+    dc->props = nvram_sysbus_properties;
 }
 
-static DeviceInfo nvram_sysbus_info = {
-    .name = "ds1225y",
-    .size = sizeof(SysBusNvRamState),
-    .vmsd = &vmstate_nvram,
-    .props = nvram_sysbus_properties,
-    .class_init = nvram_sysbus_class_init,
+static TypeInfo nvram_sysbus_info = {
+    .name          = "ds1225y",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SysBusNvRamState),
+    .class_init    = nvram_sysbus_class_init,
 };
 
 static void nvram_register(void)
 {
-    sysbus_register_withprop(&nvram_sysbus_info);
+    type_register_static(&nvram_sysbus_info);
 }
 
 device_init(nvram_register)
diff --git a/hw/ds1338.c b/hw/ds1338.c
index 4e09efe..b137e13 100644
--- a/hw/ds1338.c
+++ b/hw/ds1338.c
@@ -128,15 +128,16 @@ static void ds1338_class_init(ObjectClass *klass, void *data)
     k->send = ds1338_send;
 }
 
-static DeviceInfo ds1338_info = {
-    .name = "ds1338",
-    .size = sizeof(DS1338State),
-    .class_init = ds1338_class_init,
+static TypeInfo ds1338_info = {
+    .name          = "ds1338",
+    .parent        = TYPE_I2C_SLAVE,
+    .instance_size = sizeof(DS1338State),
+    .class_init    = ds1338_class_init,
 };
 
 static void ds1338_register_devices(void)
 {
-    i2c_register_slave(&ds1338_info);
+    type_register_static(&ds1338_info);
 }
 
 device_init(ds1338_register_devices)
diff --git a/hw/e1000.c b/hw/e1000.c
index 200eed6..751f79d 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1204,6 +1204,7 @@ static Property e1000_properties[] = {
 
 static void e1000_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = pci_e1000_init;
@@ -1213,21 +1214,22 @@ static void e1000_class_init(ObjectClass *klass, void *data)
     k->device_id = E1000_DEVID;
     k->revision = 0x03;
     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+    dc->desc = "Intel Gigabit Ethernet";
+    dc->reset = qdev_e1000_reset;
+    dc->vmsd = &vmstate_e1000;
+    dc->props = e1000_properties;
 }
 
-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 TypeInfo e1000_info = {
+    .name          = "e1000",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(E1000State),
+    .class_init    = e1000_class_init,
 };
 
 static void e1000_register_devices(void)
 {
-    pci_qdev_register(&e1000_info);
+    type_register_static(&e1000_info);
 }
 
 device_init(e1000_register_devices)
diff --git a/hw/eccmemctl.c b/hw/eccmemctl.c
index 2d82c48..1cf2090 100644
--- a/hw/eccmemctl.c
+++ b/hw/eccmemctl.c
@@ -315,24 +315,26 @@ static Property ecc_properties[] = {
 
 static void ecc_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = ecc_init1;
+    dc->reset = ecc_reset;
+    dc->vmsd = &vmstate_ecc;
+    dc->props = ecc_properties;
 }
 
-static DeviceInfo ecc_info = {
-    .name = "eccmemctl",
-    .size = sizeof(ECCState),
-    .vmsd = &vmstate_ecc,
-    .reset = ecc_reset,
-    .props = ecc_properties,
-    .class_init = ecc_class_init,
+static TypeInfo ecc_info = {
+    .name          = "eccmemctl",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(ECCState),
+    .class_init    = ecc_class_init,
 };
 
 
 static void ecc_register_devices(void)
 {
-    sysbus_register_withprop(&ecc_info);
+    type_register_static(&ecc_info);
 }
 
 device_init(ecc_register_devices)
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 9f6d333..843610c 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -128,8 +128,8 @@
 #define DRVR_INT        0x0200  /* Driver generated interrupt. */
 
 typedef struct {
-    DeviceInfo qdev;
-
+    const char *name;
+    const char *desc;
     uint16_t device_id;
     uint8_t revision;
     uint16_t subsystem_vendor_id;
@@ -1905,8 +1905,8 @@ static int e100_nic_init(PCIDevice *pci_dev)
 
 static E100PCIDeviceInfo e100_devices[] = {
     {
-        .qdev.name = "i82550",
-        .qdev.desc = "Intel i82550 Ethernet",
+        .name = "i82550",
+        .desc = "Intel i82550 Ethernet",
         .device = i82550,
         /* TODO: check device id. */
         .device_id = PCI_DEVICE_ID_INTEL_82551IT,
@@ -1918,8 +1918,8 @@ static E100PCIDeviceInfo e100_devices[] = {
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .qdev.name = "i82551",
-        .qdev.desc = "Intel i82551 Ethernet",
+        .name = "i82551",
+        .desc = "Intel i82551 Ethernet",
         .device = i82551,
         .device_id = PCI_DEVICE_ID_INTEL_82551IT,
         /* Revision ID: 0x0f, 0x10. */
@@ -1929,29 +1929,29 @@ static E100PCIDeviceInfo e100_devices[] = {
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .qdev.name = "i82557a",
-        .qdev.desc = "Intel i82557A Ethernet",
+        .name = "i82557a",
+        .desc = "Intel i82557A Ethernet",
         .device = i82557A,
         .device_id = PCI_DEVICE_ID_INTEL_82557,
         .revision = 0x01,
         .power_management = false,
     },{
-        .qdev.name = "i82557b",
-        .qdev.desc = "Intel i82557B Ethernet",
+        .name = "i82557b",
+        .desc = "Intel i82557B Ethernet",
         .device = i82557B,
         .device_id = PCI_DEVICE_ID_INTEL_82557,
         .revision = 0x02,
         .power_management = false,
     },{
-        .qdev.name = "i82557c",
-        .qdev.desc = "Intel i82557C Ethernet",
+        .name = "i82557c",
+        .desc = "Intel i82557C Ethernet",
         .device = i82557C,
         .device_id = PCI_DEVICE_ID_INTEL_82557,
         .revision = 0x03,
         .power_management = false,
     },{
-        .qdev.name = "i82558a",
-        .qdev.desc = "Intel i82558A Ethernet",
+        .name = "i82558a",
+        .desc = "Intel i82558A Ethernet",
         .device = i82558A,
         .device_id = PCI_DEVICE_ID_INTEL_82557,
         .revision = 0x04,
@@ -1959,8 +1959,8 @@ static E100PCIDeviceInfo e100_devices[] = {
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .qdev.name = "i82558b",
-        .qdev.desc = "Intel i82558B Ethernet",
+        .name = "i82558b",
+        .desc = "Intel i82558B Ethernet",
         .device = i82558B,
         .device_id = PCI_DEVICE_ID_INTEL_82557,
         .revision = 0x05,
@@ -1968,8 +1968,8 @@ static E100PCIDeviceInfo e100_devices[] = {
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .qdev.name = "i82559a",
-        .qdev.desc = "Intel i82559A Ethernet",
+        .name = "i82559a",
+        .desc = "Intel i82559A Ethernet",
         .device = i82559A,
         .device_id = PCI_DEVICE_ID_INTEL_82557,
         .revision = 0x06,
@@ -1977,8 +1977,8 @@ static E100PCIDeviceInfo e100_devices[] = {
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .qdev.name = "i82559b",
-        .qdev.desc = "Intel i82559B Ethernet",
+        .name = "i82559b",
+        .desc = "Intel i82559B Ethernet",
         .device = i82559B,
         .device_id = PCI_DEVICE_ID_INTEL_82557,
         .revision = 0x07,
@@ -1986,8 +1986,8 @@ static E100PCIDeviceInfo e100_devices[] = {
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .qdev.name = "i82559c",
-        .qdev.desc = "Intel i82559C Ethernet",
+        .name = "i82559c",
+        .desc = "Intel i82559C Ethernet",
         .device = i82559C,
         .device_id = PCI_DEVICE_ID_INTEL_82557,
 #if 0
@@ -2003,8 +2003,8 @@ static E100PCIDeviceInfo e100_devices[] = {
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .qdev.name = "i82559er",
-        .qdev.desc = "Intel i82559ER Ethernet",
+        .name = "i82559er",
+        .desc = "Intel i82559ER Ethernet",
         .device = i82559ER,
         .device_id = PCI_DEVICE_ID_INTEL_82551IT,
         .revision = 0x09,
@@ -2012,8 +2012,8 @@ static E100PCIDeviceInfo e100_devices[] = {
         .has_extended_tcb_support = true,
         .power_management = true,
     },{
-        .qdev.name = "i82562",
-        .qdev.desc = "Intel i82562 Ethernet",
+        .name = "i82562",
+        .desc = "Intel i82562 Ethernet",
         .device = i82562,
         /* TODO: check device id. */
         .device_id = PCI_DEVICE_ID_INTEL_82551IT,
@@ -2024,8 +2024,8 @@ static E100PCIDeviceInfo e100_devices[] = {
         .power_management = true,
     },{
         /* Toshiba Tecra 8200. */
-        .qdev.name = "i82801",
-        .qdev.desc = "Intel i82801 Ethernet",
+        .name = "i82801",
+        .desc = "Intel i82801 Ethernet",
         .device = i82801,
         .device_id = 0x2449,
         .revision = 0x03,
@@ -2048,7 +2048,7 @@ static E100PCIDeviceInfo *eepro100_get_class_by_name(const char *typename)
      * 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) {
+        if (strcmp(e100_devices[i].name, typename) == 0) {
             info = &e100_devices[i];
             break;
         }
@@ -2063,13 +2063,21 @@ static E100PCIDeviceInfo *eepro100_get_class(EEPRO100State *s)
     return eepro100_get_class_by_name(object_get_typename(OBJECT(s)));
 }
 
+static Property e100_properties[] = {
+    DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void eepro100_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
     E100PCIDeviceInfo *info;
 
     info = eepro100_get_class_by_name(object_class_get_name(klass));
 
+    dc->props = e100_properties;
+    dc->desc = info->desc;
     k->vendor_id = PCI_VENDOR_ID_INTEL;
     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
     k->romfile = "pxe-eepro100.rom";
@@ -2081,22 +2089,19 @@ static void eepro100_class_init(ObjectClass *klass, void *data)
     k->subsystem_id = info->subsystem_id;
 }
 
-static Property e100_properties[] = {
-    DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
 static void eepro100_register_devices(void)
 {
     size_t i;
     for (i = 0; i < ARRAY_SIZE(e100_devices); i++) {
-        DeviceInfo *info = &e100_devices[i].qdev;
+        TypeInfo type_info = {};
+        E100PCIDeviceInfo *info = &e100_devices[i];
 
-        info->class_init = eepro100_class_init;
-        info->size = sizeof(EEPRO100State);
-        info->props = e100_properties;
+        type_info.name = info->name;
+        type_info.parent = TYPE_PCI_DEVICE;
+        type_info.class_init = eepro100_class_init;
+        type_info.instance_size = sizeof(EEPRO100State);
         
-        pci_qdev_register(info);
+        type_register(&type_info);
     }
 }
 
diff --git a/hw/empty_slot.c b/hw/empty_slot.c
index 70e45d0..1bc1815 100644
--- a/hw/empty_slot.c
+++ b/hw/empty_slot.c
@@ -83,15 +83,16 @@ static void empty_slot_class_init(ObjectClass *klass, void *data)
     k->init = empty_slot_init1;
 }
 
-static DeviceInfo empty_slot_info = {
-    .name = "empty_slot",
-    .size = sizeof(EmptySlot),
-    .class_init = empty_slot_class_init,
+static TypeInfo empty_slot_info = {
+    .name          = "empty_slot",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(EmptySlot),
+    .class_init    = empty_slot_class_init,
 };
 
 static void empty_slot_register_devices(void)
 {
-    sysbus_register_withprop(&empty_slot_info);
+    type_register_static(&empty_slot_info);
 }
 
 device_init(empty_slot_register_devices);
diff --git a/hw/es1370.c b/hw/es1370.c
index 205bed7..95e88b9 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -1033,6 +1033,7 @@ int es1370_init (PCIBus *bus)
 
 static void es1370_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = es1370_initfn;
@@ -1042,19 +1043,20 @@ static void es1370_class_init(ObjectClass *klass, void *data)
     k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
     k->subsystem_vendor_id = 0x4942;
     k->subsystem_id = 0x4c4c;
+    dc->desc = "ENSONIQ AudioPCI ES1370";
+    dc->vmsd = &vmstate_es1370;
 }
 
-static DeviceInfo es1370_info = {
-    .name = "ES1370",
-    .desc = "ENSONIQ AudioPCI ES1370",
-    .size = sizeof (ES1370State),
-    .vmsd = &vmstate_es1370,
-    .class_init = es1370_class_init,
+static TypeInfo es1370_info = {
+    .name          = "ES1370",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof (ES1370State),
+    .class_init    = es1370_class_init,
 };
 
 static void es1370_register (void)
 {
-    pci_qdev_register (&es1370_info);
+    type_register_static(&es1370_info);
 }
 device_init (es1370_register);
 
diff --git a/hw/escc.c b/hw/escc.c
index d905d96..9fe282f 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -915,23 +915,25 @@ static Property escc_properties[] = {
 
 static void escc_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = escc_init1;
+    dc->reset = escc_reset;
+    dc->vmsd = &vmstate_escc;
+    dc->props = escc_properties;
 }
 
-static DeviceInfo escc_info = {
-    .name = "escc",
-    .size = sizeof(SerialState),
-    .vmsd = &vmstate_escc,
-    .reset = escc_reset,
-    .props = escc_properties,
-    .class_init = escc_class_init,
+static TypeInfo escc_info = {
+    .name          = "escc",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SerialState),
+    .class_init    = escc_class_init,
 };
 
 static void escc_register_devices(void)
 {
-    sysbus_register_withprop(&escc_info);
+    type_register_static(&escc_info);
 }
 
 device_init(escc_register_devices)
diff --git a/hw/esp.c b/hw/esp.c
index 71d3e70..2f44386 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -759,23 +759,25 @@ static Property esp_properties[] = {
 
 static void esp_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = esp_init1;
+    dc->reset = esp_hard_reset;
+    dc->vmsd = &vmstate_esp;
+    dc->props = esp_properties;
 }
 
-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 TypeInfo esp_info = {
+    .name          = "esp",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(ESPState),
+    .class_init    = esp_class_init,
 };
 
 static void esp_register_devices(void)
 {
-    sysbus_register_withprop(&esp_info);
+    type_register_static(&esp_info);
 }
 
 device_init(esp_register_devices)
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 92c822b..aefd577 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -623,21 +623,23 @@ static Property etraxfs_eth_properties[] = {
 
 static void etraxfs_eth_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = fs_eth_init;
+    dc->props = etraxfs_eth_properties;
 }
 
-static DeviceInfo etraxfs_eth_info = {
-    .name = "etraxfs-eth",
-    .size = sizeof(struct fs_eth),
-    .props = etraxfs_eth_properties,
-    .class_init = etraxfs_eth_class_init,
+static TypeInfo etraxfs_eth_info = {
+    .name          = "etraxfs-eth",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(struct fs_eth),
+    .class_init    = etraxfs_eth_class_init,
 };
 
 static void etraxfs_eth_register(void)
 {
-	sysbus_register_withprop(&etraxfs_eth_info);
+    type_register_static(&etraxfs_eth_info);
 }
 
 device_init(etraxfs_eth_register)
diff --git a/hw/etraxfs_pic.c b/hw/etraxfs_pic.c
index 8acf01e..33541fc 100644
--- a/hw/etraxfs_pic.c
+++ b/hw/etraxfs_pic.c
@@ -158,21 +158,23 @@ static Property etraxfs_pic_properties[] = {
 
 static void etraxfs_pic_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = etraxfs_pic_init;
+    dc->props = etraxfs_pic_properties;
 }
 
-static DeviceInfo etraxfs_pic_info = {
-    .name = "etraxfs,pic",
-    .size = sizeof(struct etrax_pic),
-    .props = etraxfs_pic_properties,
-    .class_init = etraxfs_pic_class_init,
+static TypeInfo etraxfs_pic_info = {
+    .name          = "etraxfs,pic",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(struct etrax_pic),
+    .class_init    = etraxfs_pic_class_init,
 };
 
 static void etraxfs_pic_register(void)
 {
-    sysbus_register_withprop(&etraxfs_pic_info);
+    type_register_static(&etraxfs_pic_info);
 }
 
 device_init(etraxfs_pic_register)
diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
index a487805..b8acd43 100644
--- a/hw/etraxfs_ser.c
+++ b/hw/etraxfs_ser.c
@@ -226,21 +226,23 @@ static int etraxfs_ser_init(SysBusDevice *dev)
 
 static void etraxfs_ser_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = etraxfs_ser_init;
+    dc->reset = etraxfs_ser_reset;
 }
 
-static DeviceInfo etraxfs_ser_info = {
-    .name = "etraxfs,serial",
-    .size = sizeof(struct etrax_serial),
-    .reset = etraxfs_ser_reset,
-    .class_init = etraxfs_ser_class_init,
+static TypeInfo etraxfs_ser_info = {
+    .name          = "etraxfs,serial",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(struct etrax_serial),
+    .class_init    = etraxfs_ser_class_init,
 };
 
 static void etraxfs_serial_register(void)
 {
-    sysbus_register_withprop(&etraxfs_ser_info);
+    type_register_static(&etraxfs_ser_info);
 }
 
 device_init(etraxfs_serial_register)
diff --git a/hw/etraxfs_timer.c b/hw/etraxfs_timer.c
index c33058c..b71c5ee 100644
--- a/hw/etraxfs_timer.c
+++ b/hw/etraxfs_timer.c
@@ -336,15 +336,16 @@ static void etraxfs_timer_class_init(ObjectClass *klass, void *data)
     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 TypeInfo etraxfs_timer_info = {
+    .name          = "etraxfs,timer",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof (struct etrax_timer),
+    .class_init    = etraxfs_timer_class_init,
 };
 
 static void etraxfs_timer_register(void)
 {
-    sysbus_qdev_register(&etraxfs_timer_info);
+    type_register_static(&etraxfs_timer_info);
 }
 
 device_init(etraxfs_timer_register)
diff --git a/hw/fdc.c b/hw/fdc.c
index 8562284..f575a2c 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1959,27 +1959,31 @@ static const VMStateDescription vmstate_isa_fdc ={
     }
 };
 
+static Property isa_fdc_properties[] = {
+    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),
+    DEFINE_PROP_INT32("bootindexB", FDCtrlISABus, bootindexB, -1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void isabus_fdc_class_init1(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     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),
-        DEFINE_PROP_INT32("bootindexB", FDCtrlISABus, bootindexB, -1),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+    dc->fw_name = "fdc";
+    dc->no_user = 1;
+    dc->reset = fdctrl_external_reset_isa;
+    dc->vmsd = &vmstate_isa_fdc;
+    dc->props = isa_fdc_properties;
+}
+
+static TypeInfo isa_fdc_info = {
+    .name          = "isa-fdc",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(FDCtrlISABus),
+    .class_init    = isabus_fdc_class_init1,
 };
 
 static const VMStateDescription vmstate_sysbus_fdc ={
@@ -2000,18 +2004,20 @@ static Property sysbus_fdc_properties[] = {
 
 static void sysbus_fdc_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = sysbus_fdc_init1;
+    dc->reset = fdctrl_external_reset_sysbus;
+    dc->vmsd = &vmstate_sysbus_fdc;
+    dc->props = sysbus_fdc_properties;
 }
 
-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 TypeInfo sysbus_fdc_info = {
+    .name          = "sysbus-fdc",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(FDCtrlSysBus),
+    .class_init    = sysbus_fdc_class_init,
 };
 
 static Property sun4m_fdc_properties[] = {
@@ -2021,25 +2027,27 @@ static Property sun4m_fdc_properties[] = {
 
 static void sun4m_fdc_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = sun4m_fdc_init1;
+    dc->reset = fdctrl_external_reset_sysbus;
+    dc->vmsd = &vmstate_sysbus_fdc;
+    dc->props = sun4m_fdc_properties;
 }
 
-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 TypeInfo sun4m_fdc_info = {
+    .name          = "SUNW,fdtwo",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(FDCtrlSysBus),
+    .class_init    = sun4m_fdc_class_init,
 };
 
 static void fdc_register_devices(void)
 {
-    isa_qdev_register(&isa_fdc_info);
-    sysbus_register_withprop(&sysbus_fdc_info);
-    sysbus_register_withprop(&sun4m_fdc_info);
+    type_register_static(&isa_fdc_info);
+    type_register_static(&sysbus_fdc_info);
+    type_register_static(&sun4m_fdc_info);
 }
 
 device_init(fdc_register_devices)
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index e669ed4..6b2f7d1 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -539,24 +539,26 @@ static Property fw_cfg_properties[] = {
 
 static void fw_cfg_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = fw_cfg_init1;
+    dc->no_user = 1;
+    dc->reset = fw_cfg_reset;
+    dc->vmsd = &vmstate_fw_cfg;
+    dc->props = fw_cfg_properties;
 }
 
-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 TypeInfo fw_cfg_info = {
+    .name          = "fw_cfg",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(FWCfgState),
+    .class_init    = fw_cfg_class_init,
 };
 
 static void fw_cfg_register_devices(void)
 {
-    sysbus_register_withprop(&fw_cfg_info);
+    type_register_static(&fw_cfg_info);
 }
 
 device_init(fw_cfg_register_devices)
diff --git a/hw/g364fb.c b/hw/g364fb.c
index 82b31f7..f47acc5 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -556,24 +556,26 @@ static Property g364fb_sysbus_properties[] = {
 
 static void g364fb_sysbus_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = g364fb_sysbus_init;
+    dc->desc = "G364 framebuffer";
+    dc->reset = g364fb_sysbus_reset;
+    dc->vmsd = &vmstate_g364fb;
+    dc->props = g364fb_sysbus_properties;
 }
 
-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 TypeInfo g364fb_sysbus_info = {
+    .name          = "sysbus-g364",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(G364SysBusState),
+    .class_init    = g364fb_sysbus_class_init,
 };
 
 static void g364fb_register(void)
 {
-    sysbus_register_withprop(&g364fb_sysbus_info);
+    type_register_static(&g364fb_sysbus_info);
 }
 
 device_init(g364fb_register);
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index 549859d..8122baf 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -124,39 +124,43 @@ static int grackle_pci_host_init(PCIDevice *d)
 static void grackle_pci_class_init(ObjectClass *klass, void *data)
 {
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     k->init      = grackle_pci_host_init;
     k->vendor_id = PCI_VENDOR_ID_MOTOROLA;
     k->device_id = PCI_DEVICE_ID_MOTOROLA_MPC106;
     k->revision  = 0x00;
     k->class_id  = PCI_CLASS_BRIDGE_HOST;
+    dc->no_user = 1;
 }
 
-static DeviceInfo grackle_pci_info = {
-    .name = "grackle",
-    .size = sizeof(PCIDevice),
-    .no_user = 1,
+static TypeInfo grackle_pci_info = {
+    .name          = "grackle",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
     .class_init = grackle_pci_class_init,
 };
 
 static void pci_grackle_class_init(ObjectClass *klass, void *data)
 {
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     k->init = pci_grackle_init_device;
+    dc->no_user = 1;
 }
 
-static DeviceInfo grackle_pci_host_info = {
-    .name = "grackle-pcihost",
-    .size = sizeof(GrackleState),
-    .no_user = 1,
-    .class_init = pci_grackle_class_init,
+static TypeInfo grackle_pci_host_info = {
+    .name          = "grackle-pcihost",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(GrackleState),
+    .class_init    = pci_grackle_class_init,
 };
 
 static void grackle_register_devices(void)
 {
-    sysbus_qdev_register(&grackle_pci_host_info);
-    pci_qdev_register(&grackle_pci_info);
+    type_register_static(&grackle_pci_info);
+    type_register_static(&grackle_pci_host_info);
 }
 
 device_init(grackle_register_devices)
diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c
index dc12d58..3286651 100644
--- a/hw/grlib_apbuart.c
+++ b/hw/grlib_apbuart.c
@@ -177,21 +177,23 @@ static Property grlib_gptimer_properties[] = {
 
 static void grlib_gptimer_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = grlib_apbuart_init;
+    dc->props = grlib_gptimer_properties;
 }
 
-static DeviceInfo grlib_gptimer_info = {
-    .name = "grlib,apbuart",
-    .size = sizeof(UART),
-    .props = grlib_gptimer_properties,
-    .class_init = grlib_gptimer_class_init,
+static TypeInfo grlib_gptimer_info = {
+    .name          = "grlib,apbuart",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(UART),
+    .class_init    = grlib_gptimer_class_init,
 };
 
 static void grlib_gptimer_register(void)
 {
-    sysbus_register_withprop(&grlib_gptimer_info);
+    type_register_static(&grlib_gptimer_info);
 }
 
 device_init(grlib_gptimer_register)
diff --git a/hw/grlib_gptimer.c b/hw/grlib_gptimer.c
index 219009e..fb0b236 100644
--- a/hw/grlib_gptimer.c
+++ b/hw/grlib_gptimer.c
@@ -381,22 +381,24 @@ static Property grlib_gptimer_properties[] = {
 
 static void grlib_gptimer_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = grlib_gptimer_init;
+    dc->reset = grlib_gptimer_reset;
+    dc->props = grlib_gptimer_properties;
 }
 
-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 TypeInfo grlib_gptimer_info = {
+    .name          = "grlib,gptimer",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(GPTimerUnit),
+    .class_init    = grlib_gptimer_class_init,
 };
 
 static void grlib_gptimer_register(void)
 {
-    sysbus_register_withprop(&grlib_gptimer_info);
+    type_register_static(&grlib_gptimer_info);
 }
 
 device_init(grlib_gptimer_register)
diff --git a/hw/grlib_irqmp.c b/hw/grlib_irqmp.c
index 1ccddfb..1e5ad82 100644
--- a/hw/grlib_irqmp.c
+++ b/hw/grlib_irqmp.c
@@ -362,22 +362,24 @@ static Property grlib_irqmp_properties[] = {
 
 static void grlib_irqmp_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = grlib_irqmp_init;
+    dc->reset = grlib_irqmp_reset;
+    dc->props = grlib_irqmp_properties;
 }
 
-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 TypeInfo grlib_irqmp_info = {
+    .name          = "grlib,irqmp",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(IRQMP),
+    .class_init    = grlib_irqmp_class_init,
 };
 
 static void grlib_irqmp_register(void)
 {
-    sysbus_register_withprop(&grlib_irqmp_info);
+    type_register_static(&grlib_irqmp_info);
 }
 
 device_init(grlib_irqmp_register)
diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index 79d2dfb..e8cd59c 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -1147,10 +1147,11 @@ static void gt64120_pci_class_init(ObjectClass *klass, void *data)
     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 TypeInfo gt64120_pci_info = {
+    .name          = "gt64120_pci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
+    .class_init    = gt64120_pci_class_init,
 };
 
 static void gt64120_class_init(ObjectClass *klass, void *data)
@@ -1160,16 +1161,17 @@ static void gt64120_class_init(ObjectClass *klass, void *data)
     sdc->init = gt64120_init;
 }
 
-static DeviceInfo gt64120_info = {
-    .name = "gt64120",
-    .size = sizeof(GT64120State),
-    .class_init = gt64120_class_init,
+static TypeInfo gt64120_info = {
+    .name          = "gt64120",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(GT64120State),
+    .class_init    = gt64120_class_init,
 };
 
 static void gt64120_pci_register_devices(void)
 {
-    sysbus_qdev_register(&gt64120_info);
-    pci_qdev_register(&gt64120_pci_info);
+    type_register_static(&gt64120_info);
+    type_register_static(&gt64120_pci_info);
 }
 
 device_init(gt64120_pci_register_devices)
diff --git a/hw/gus.c b/hw/gus.c
index 6603aab..49e5dbf 100644
--- a/hw/gus.c
+++ b/hw/gus.c
@@ -299,29 +299,33 @@ int GUS_init (ISABus *bus)
     return 0;
 }
 
+static Property gus_properties[] = {
+    DEFINE_PROP_UINT32 ("freq",    GUSState, freq,        44100),
+    DEFINE_PROP_HEX32  ("iobase",  GUSState, port,        0x240),
+    DEFINE_PROP_UINT32 ("irq",     GUSState, emu.gusirq,  7),
+    DEFINE_PROP_UINT32 ("dma",     GUSState, emu.gusdma,  3),
+    DEFINE_PROP_END_OF_LIST (),
+};
+
 static void gus_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = gus_initfn;
+    dc->desc = "Gravis Ultrasound GF1";
+    dc->vmsd = &vmstate_gus;
+    dc->props = gus_properties;
 }
 
-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),
-        DEFINE_PROP_UINT32 ("dma",     GUSState, emu.gusdma,  3),
-        DEFINE_PROP_END_OF_LIST (),
-    },
+static TypeInfo gus_info = {
+    .name          = "gus",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof (GUSState),
+    .class_init    = gus_class_initfn,
 };
 
 static void gus_register (void)
 {
-    isa_qdev_register (&gus_info);
+    type_register_static(&gus_info);
 }
 device_init (gus_register)
diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index 2b3ce2f..152f8e6 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -908,45 +908,49 @@ static int hda_audio_init_duplex(HDACodecDevice *hda)
 
 static void hda_audio_output_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     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;
+    dc->desc = "HDA Audio Codec, output-only";
+    dc->vmsd = &vmstate_hda_audio;
+    dc->props = hda_audio_properties;
 }
 
-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 TypeInfo hda_audio_output_info = {
+    .name          = "hda-output",
+    .parent        = TYPE_HDA_CODEC_DEVICE,
+    .instance_size = sizeof(HDAAudioState),
+    .class_init    = hda_audio_output_class_init,
 };
 
 static void hda_audio_duplex_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     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;
+    dc->desc = "HDA Audio Codec, duplex";
+    dc->vmsd = &vmstate_hda_audio;
+    dc->props = hda_audio_properties;
 }
 
-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 TypeInfo hda_audio_duplex_info = {
+    .name          = "hda-duplex",
+    .parent        = TYPE_HDA_CODEC_DEVICE,
+    .instance_size = sizeof(HDAAudioState),
+    .class_init    = hda_audio_duplex_class_init,
 };
 
 static void hda_audio_register(void)
 {
-    hda_codec_register(&hda_audio_output_info);
-    hda_codec_register(&hda_audio_duplex_info);
+    type_register_static(&hda_audio_output_info);
+    type_register_static(&hda_audio_duplex_info);
 }
 device_init(hda_audio_register);
diff --git a/hw/highbank.c b/hw/highbank.c
index 9f76716..684178e 100644
--- a/hw/highbank.c
+++ b/hw/highbank.c
@@ -162,22 +162,24 @@ static int highbank_regs_init(SysBusDevice *dev)
 static void highbank_regs_class_init(ObjectClass *klass, void *data)
 {
     SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     sbc->init = highbank_regs_init;
+    dc->desc = "Calxeda Highbank registers";
+    dc->vmsd = &vmstate_highbank_regs;
+    dc->reset = highbank_regs_reset;
 }
 
-static DeviceInfo highbank_regs_info = {
-    .name  = "highbank-regs",
-    .desc  = "Calxeda Highbank registers",
-    .size  = sizeof(HighbankRegsState),
-    .vmsd  = &vmstate_highbank_regs,
-    .class_init = highbank_regs_class_init,
-    .reset = highbank_regs_reset,
+static TypeInfo highbank_regs_info = {
+    .name          = "highbank-regs",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(HighbankRegsState),
+    .class_init    = highbank_regs_class_init,
 };
 
 static void highbank_regs_register_device(void)
 {
-    sysbus_qdev_register(&highbank_regs_info);
+    type_register_static(&highbank_regs_info);
 }
 
 device_init(highbank_regs_register_device)
diff --git a/hw/hpet.c b/hw/hpet.c
index aba9ea9..b6ace4e 100644
--- a/hw/hpet.c
+++ b/hw/hpet.c
@@ -703,24 +703,26 @@ static Property hpet_device_properties[] = {
 
 static void hpet_device_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = hpet_init;
+    dc->no_user = 1;
+    dc->reset = hpet_reset;
+    dc->vmsd = &vmstate_hpet;
+    dc->props = hpet_device_properties;
 }
 
-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 TypeInfo hpet_device_info = {
+    .name          = "hpet",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(HPETState),
+    .class_init    = hpet_device_class_init,
 };
 
 static void hpet_register_device(void)
 {
-    sysbus_register_withprop(&hpet_device_info);
+    type_register_static(&hpet_device_info);
 }
 
 device_init(hpet_register_device)
diff --git a/hw/i2c.c b/hw/i2c.c
index 9e5d3df..e21a666 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -204,19 +204,6 @@ static int i2c_slave_qdev_init(DeviceState *dev, DeviceInfo *base)
     return sc->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(DeviceInfo *info)
-{
-    i2c_register_slave_subclass(info, TYPE_I2C_SLAVE);
-}
-
 DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr)
 {
     DeviceState *dev;
@@ -227,12 +214,20 @@ DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr)
     return dev;
 }
 
+static void i2c_slave_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *k = DEVICE_CLASS(klass);
+    k->init = i2c_slave_qdev_init;
+    k->bus_info = &i2c_bus_info;
+}
+
 static TypeInfo i2c_slave_type_info = {
     .name = TYPE_I2C_SLAVE,
     .parent = TYPE_DEVICE,
     .instance_size = sizeof(I2CSlave),
     .abstract = true,
     .class_size = sizeof(I2CSlaveClass),
+    .class_init = i2c_slave_class_init,
 };
 
 static void i2c_slave_register_devices(void)
diff --git a/hw/i2c.h b/hw/i2c.h
index 31fd59c..0f5682b 100644
--- a/hw/i2c.h
+++ b/hw/i2c.h
@@ -62,9 +62,6 @@ 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(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);
 
 /* wm8750.c */
diff --git a/hw/i82374.c b/hw/i82374.c
index 2814379..220e8cc 100644
--- a/hw/i82374.c
+++ b/hw/i82374.c
@@ -135,27 +135,31 @@ static int i82374_isa_init(ISADevice *dev)
     return 0;
 }
 
+static Property i82374_properties[] = {
+    DEFINE_PROP_HEX32("iobase", ISAi82374State, iobase, 0x400),
+    DEFINE_PROP_END_OF_LIST()
+};
+
 static void i82374_class_init(ObjectClass *klass, void *data)
 {
     ISADeviceClass *k = ISA_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
     
-    k->init       = i82374_isa_init;
+    k->init  = i82374_isa_init;
+    dc->vmsd = &vmstate_isa_i82374;
+    dc->props = i82374_properties;
 }
 
-static DeviceInfo i82374_isa_info = {
+static TypeInfo i82374_isa_info = {
     .name  = "i82374",
-    .size  = sizeof(ISAi82374State),
-    .vmsd  = &vmstate_isa_i82374,
+    .parent = TYPE_ISA_DEVICE,
+    .instance_size  = sizeof(ISAi82374State),
     .class_init = i82374_class_init,
-    .props = (Property[]) {
-        DEFINE_PROP_HEX32("iobase", ISAi82374State, iobase, 0x400),
-        DEFINE_PROP_END_OF_LIST()
-    },
 };
 
 static void i82374_register_devices(void)
 {
-    isa_qdev_register(&i82374_isa_info);
+    type_register_static(&i82374_isa_info);
 }
 
 device_init(i82374_register_devices)
diff --git a/hw/i82378.c b/hw/i82378.c
index 99b453a..9c3efe8 100644
--- a/hw/i82378.c
+++ b/hw/i82378.c
@@ -238,9 +238,16 @@ static int pci_i82378_init(PCIDevice *dev)
     return 0;
 }
 
+static Property i82378_properties[] = {
+    DEFINE_PROP_HEX32("iobase", PCIi82378State, isa_io_base, 0x80000000),
+    DEFINE_PROP_HEX32("membase", PCIi82378State, isa_mem_base, 0xc0000000),
+    DEFINE_PROP_END_OF_LIST()
+};
+
 static void pci_i82378_class_init(ObjectClass *klass, void *data)
 {
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     k->init = pci_i82378_init;
     k->vendor_id = PCI_VENDOR_ID_INTEL;
@@ -249,23 +256,20 @@ static void pci_i82378_class_init(ObjectClass *klass, void *data)
     k->class_id = PCI_CLASS_BRIDGE_ISA;
     k->subsystem_vendor_id = 0x0;
     k->subsystem_id = 0x0;
+    dc->vmsd = &vmstate_pci_i82378;
+    dc->props = i82378_properties;
 }
 
-static DeviceInfo pci_i82378_info = {
+static TypeInfo pci_i82378_info = {
     .name = "i82378",
-    .size = sizeof(PCIi82378State),
-    .vmsd = &vmstate_pci_i82378,
+    .parent = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIi82378State),
     .class_init = pci_i82378_class_init,
-    .props = (Property[]) {
-        DEFINE_PROP_HEX32("iobase", PCIi82378State, isa_io_base, 0x80000000),
-        DEFINE_PROP_HEX32("membase", PCIi82378State, isa_mem_base, 0xc0000000),
-        DEFINE_PROP_END_OF_LIST()
-    },
 };
 
 static void i82378_register_devices(void)
 {
-    pci_qdev_register(&pci_i82378_info);
+    type_register_static(&pci_i82378_info);
 }
 
 device_init(i82378_register_devices)
diff --git a/hw/i8254.c b/hw/i8254.c
index add1fab..522fed8 100644
--- a/hw/i8254.c
+++ b/hw/i8254.c
@@ -535,28 +535,32 @@ static int pit_initfn(ISADevice *dev)
     return 0;
 }
 
+static Property pit_properties[] = {
+    DEFINE_PROP_UINT32("irq", PITState, irq,  -1),
+    DEFINE_PROP_HEX32("iobase", PITState, iobase,  -1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void pit_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = pit_initfn;
+    dc->no_user = 1;
+    dc->reset = pit_reset;
+    dc->vmsd = &vmstate_pit;
+    dc->props = pit_properties;
 }
 
-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(),
-    },
+static TypeInfo pit_info = {
+    .name          = "isa-pit",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(PITState),
+    .class_init    = pit_class_initfn,
 };
 
 static void pit_register(void)
 {
-    isa_qdev_register(&pit_info);
+    type_register_static(&pit_info);
 }
 device_init(pit_register)
diff --git a/hw/i8259.c b/hw/i8259.c
index e083bb6..7ae5380 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -475,19 +475,22 @@ qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq)
 static void i8259_class_init(ObjectClass *klass, void *data)
 {
     PICCommonClass *k = PIC_COMMON_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     k->init = pic_init;
+    dc->reset = pic_reset;
 }
 
-static DeviceInfo i8259_info = {
-    .name  = "isa-i8259",
-    .reset = pic_reset,
+static TypeInfo i8259_info = {
+    .name       = "isa-i8259",
+    .instance_size = sizeof(PICCommonState),
+    .parent     = TYPE_PIC_COMMON,
     .class_init = i8259_class_init,
 };
 
 static void pic_register(void)
 {
-    pic_qdev_register(&i8259_info);
+    type_register_static(&i8259_info);
 }
 
 device_init(pic_register)
diff --git a/hw/i8259_common.c b/hw/i8259_common.c
index 24b1076..9f150bc 100644
--- a/hw/i8259_common.c
+++ b/hw/i8259_common.c
@@ -133,19 +133,14 @@ static Property pic_properties_common[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-void pic_qdev_register(DeviceInfo *info)
-{
-    info->size = sizeof(PICCommonState);
-    info->vmsd = &vmstate_pic_common;
-    info->no_user = 1;
-    info->props = pic_properties_common;
-    isa_qdev_register_subclass(info, TYPE_PIC_COMMON);
-}
-
 static void pic_common_class_init(ObjectClass *klass, void *data)
 {
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
+    dc->vmsd = &vmstate_pic_common;
+    dc->no_user = 1;
+    dc->props = pic_properties_common;
     ic->init = pic_init_common;
 }
 
diff --git a/hw/i8259_internal.h b/hw/i8259_internal.h
index e9d1732..4137b61 100644
--- a/hw/i8259_internal.h
+++ b/hw/i8259_internal.h
@@ -78,6 +78,5 @@ void pic_reset_common(PICCommonState *s);
 
 ISADevice *i8259_init_chip(const char *name, ISABus *bus, bool master);
 
-void pic_qdev_register(DeviceInfo *info);
 
 #endif /* !QEMU_I8259_INTERNAL_H */
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 8869fd6..c87a6ca 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1239,27 +1239,31 @@ static int sysbus_ahci_init(SysBusDevice *dev)
     return 0;
 }
 
+static Property sysbus_ahci_properties[] = {
+    DEFINE_PROP_UINT32("num-ports", SysbusAHCIState, num_ports, 1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void sysbus_ahci_class_init(ObjectClass *klass, void *data)
 {
     SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     sbc->init = sysbus_ahci_init;
+    dc->vmsd = &vmstate_sysbus_ahci;
+    dc->props = sysbus_ahci_properties;
 }
 
-static DeviceInfo sysbus_ahci_info = {
-    .name    = "sysbus-ahci",
-    .size    = sizeof(SysbusAHCIState),
-    .vmsd    = &vmstate_sysbus_ahci,
-    .class_init = sysbus_ahci_class_init,
-    .props = (Property[]) {
-        DEFINE_PROP_UINT32("num-ports", SysbusAHCIState, num_ports, 1),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static TypeInfo sysbus_ahci_info = {
+    .name          = "sysbus-ahci",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SysbusAHCIState),
+    .class_init    = sysbus_ahci_class_init,
 };
 
 static void sysbus_ahci_register(void)
 {
-    sysbus_qdev_register(&sysbus_ahci_info);
+    type_register_static(&sysbus_ahci_info);
 }
 
 device_init(sysbus_ahci_register);
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 9c673bb..a119500 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -332,6 +332,7 @@ static Property cmd646_ide_properties[] = {
 
 static void cmd646_ide_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = pci_cmd646_ide_initfn;
@@ -340,17 +341,18 @@ static void cmd646_ide_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_CMD_646;
     k->revision = 0x07;
     k->class_id = PCI_CLASS_STORAGE_IDE;
+    dc->props = cmd646_ide_properties;
 }
 
-static DeviceInfo cmd646_ide_info = {
-    .name = "cmd646-ide",
-    .size = sizeof(PCIIDEState),
-    .props = cmd646_ide_properties,
-    .class_init = cmd646_ide_class_init,
+static TypeInfo cmd646_ide_info = {
+    .name          = "cmd646-ide",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIIDEState),
+    .class_init    = cmd646_ide_class_init,
 };
 
 static void cmd646_ide_register(void)
 {
-    pci_qdev_register(&cmd646_ide_info);
+    type_register_static(&cmd646_ide_info);
 }
 device_init(cmd646_ide_register);
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 1cae9f1..0e819f6 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -148,6 +148,7 @@ static void pci_ich9_write_config(PCIDevice *pci, uint32_t addr,
 
 static void ich_ahci_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = pci_ich9_ahci_init;
@@ -157,18 +158,20 @@ static void ich_ahci_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_INTEL_82801IR;
     k->revision = 0x02;
     k->class_id = PCI_CLASS_STORAGE_SATA;
+    dc->alias = "ahci";
+    dc->vmsd = &vmstate_ahci;
 }
 
-static DeviceInfo ich_ahci_info = {
-    .name = "ich9-ahci",
-    .alias = "ahci",
-    .size = sizeof(AHCIPCIState),
-    .vmsd = &vmstate_ahci,
-    .class_init = ich_ahci_class_init,
+static TypeInfo ich_ahci_info = {
+    .name          = "ich9-ahci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(AHCIPCIState),
+    .class_init    = ich_ahci_class_init,
 };
 
 static void ich_ahci_register(void)
 {
-    pci_qdev_register(&ich_ahci_info);
+    type_register_static(&ich_ahci_info);
+    type_register_static_alias(&ich_ahci_info, "ahci");
 }
 device_init(ich_ahci_register);
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 464473a..a0bcb43 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -94,29 +94,33 @@ ISADevice *isa_ide_init(ISABus *bus, int iobase, int iobase2, int isairq,
     return dev;
 }
 
+static Property isa_ide_properties[] = {
+    DEFINE_PROP_HEX32("iobase",  ISAIDEState, iobase,  0x1f0),
+    DEFINE_PROP_HEX32("iobase2", ISAIDEState, iobase2, 0x3f6),
+    DEFINE_PROP_UINT32("irq",    ISAIDEState, isairq,  14),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void isa_ide_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = isa_ide_initfn;
+    dc->fw_name = "ide";
+    dc->reset = isa_ide_reset;
+    dc->props = isa_ide_properties;
 }
 
-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),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static TypeInfo isa_ide_info = {
+    .name          = "isa-ide",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(ISAIDEState),
+    .class_init    = isa_ide_class_initfn,
 };
 
 static void isa_ide_register_devices(void)
 {
-    isa_qdev_register(&isa_ide_info);
+    type_register_static(&isa_ide_info);
 }
 
 device_init(isa_ide_register_devices)
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 832a507..bf4465b 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -239,6 +239,7 @@ PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
 
 static void piix3_ide_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->no_hotplug = 1;
@@ -247,35 +248,39 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data)
     k->vendor_id = PCI_VENDOR_ID_INTEL;
     k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
     k->class_id = PCI_CLASS_STORAGE_IDE;
+    dc->no_user = 1;
 }
 
-static DeviceInfo piix3_ide_info = {
-    .name = "piix3-ide",
-    .size = sizeof(PCIIDEState),
-    .no_user = 1,
-    .class_init = piix3_ide_class_init,
+static TypeInfo piix3_ide_info = {
+    .name          = "piix3-ide",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIIDEState),
+    .class_init    = piix3_ide_class_init,
 };
 
 static void piix3_ide_xen_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     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;
+    dc->no_user = 1;
+    dc->unplug = pci_piix3_xen_ide_unplug;
 }
 
-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 TypeInfo piix3_ide_xen_info = {
+    .name          = "piix3-ide-xen",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIIDEState),
+    .class_init    = piix3_ide_xen_class_init,
 };
 
 static void piix4_ide_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->no_hotplug = 1;
@@ -284,19 +289,20 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data)
     k->vendor_id = PCI_VENDOR_ID_INTEL;
     k->device_id = PCI_DEVICE_ID_INTEL_82371AB;
     k->class_id = PCI_CLASS_STORAGE_IDE;
+    dc->no_user = 1;
 }
 
-static DeviceInfo piix4_ide_info = {
-    .name = "piix4-ide",
-    .size = sizeof(PCIIDEState),
-    .no_user = 1,
-    .class_init = piix4_ide_class_init,
+static TypeInfo piix4_ide_info = {
+    .name          = "piix4-ide",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIIDEState),
+    .class_init    = piix4_ide_class_init,
 };
 
 static void piix_ide_register(void)
 {
-    pci_qdev_register(&piix3_ide_info);
-    pci_qdev_register(&piix3_ide_xen_info);
-    pci_qdev_register(&piix4_ide_info);
+    type_register_static(&piix3_ide_info);
+    type_register_static(&piix3_ide_xen_info);
+    type_register_static(&piix4_ide_info);
 }
 device_init(piix_ide_register);
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index b507e34..1335615 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -91,13 +91,6 @@ err:
     return -1;
 }
 
-static void ide_qdev_register(DeviceInfo *info)
-{
-    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)
 {
     DeviceState *dev;
@@ -182,73 +175,93 @@ static int ide_drive_initfn(IDEDevice *dev)
     DEFINE_PROP_STRING("ver",  IDEDrive, dev.version),  \
     DEFINE_PROP_STRING("serial",  IDEDrive, dev.serial)
 
+static Property ide_hd_properties[] = {
+    DEFINE_IDE_DEV_PROPERTIES(),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void ide_hd_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     IDEDeviceClass *k = IDE_DEVICE_CLASS(klass);
     k->init = ide_hd_initfn;
+    dc->fw_name = "drive";
+    dc->desc = "virtual IDE disk";
+    dc->props = ide_hd_properties;
 }
 
-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 TypeInfo ide_hd_info = {
+    .name          = "ide-hd",
+    .parent        = TYPE_IDE_DEVICE,
+    .instance_size = sizeof(IDEDrive),
+    .class_init    = ide_hd_class_init,
+};
+
+static Property ide_cd_properties[] = {
+    DEFINE_IDE_DEV_PROPERTIES(),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
 static void ide_cd_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     IDEDeviceClass *k = IDE_DEVICE_CLASS(klass);
     k->init = ide_cd_initfn;
+    dc->fw_name = "drive";
+    dc->desc = "virtual IDE CD-ROM";
+    dc->props = ide_cd_properties;
 }
 
-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 TypeInfo ide_cd_info = {
+    .name          = "ide-cd",
+    .parent        = TYPE_IDE_DEVICE,
+    .instance_size = sizeof(IDEDrive),
+    .class_init    = ide_cd_class_init,
+};
+
+static Property ide_drive_properties[] = {
+    DEFINE_IDE_DEV_PROPERTIES(),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
 static void ide_drive_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     IDEDeviceClass *k = IDE_DEVICE_CLASS(klass);
     k->init = ide_drive_initfn;
+    dc->fw_name = "drive";
+    dc->desc = "virtual IDE disk or CD-ROM (legacy)";
+    dc->props = ide_drive_properties;
 }
 
-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_drive_info = {
+    .name          = "ide-drive",
+    .parent        = TYPE_IDE_DEVICE,
+    .instance_size = sizeof(IDEDrive),
+    .class_init    = ide_drive_class_init,
 };
 
+static void ide_device_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *k = DEVICE_CLASS(klass);
+    k->init = ide_qdev_init;
+    k->bus_info = &ide_bus_info;
+}
+
 static TypeInfo ide_device_type_info = {
     .name = TYPE_IDE_DEVICE,
     .parent = TYPE_DEVICE,
     .instance_size = sizeof(IDEDevice),
     .abstract = true,
     .class_size = sizeof(IDEDeviceClass),
+    .class_init = ide_device_class_init,
 };
 
 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_hd_info);
+    type_register_static(&ide_cd_info);
+    type_register_static(&ide_drive_info);
     type_register_static(&ide_device_type_info);
 }
 device_init(ide_dev_register);
diff --git a/hw/ide/via.c b/hw/ide/via.c
index ef70864..b4ca6f2 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -215,6 +215,7 @@ void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
 
 static void via_ide_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = vt82c686b_ide_initfn;
@@ -223,17 +224,18 @@ static void via_ide_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIA_IDE;
     k->revision = 0x06;
     k->class_id = PCI_CLASS_STORAGE_IDE;
+    dc->no_user = 1;
 }
 
-static DeviceInfo via_ide_info = {
-    .name = "via-ide",
-    .size = sizeof(PCIIDEState),
-    .no_user = 1,
-    .class_init = via_ide_class_init,
+static TypeInfo via_ide_info = {
+    .name          = "via-ide",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIIDEState),
+    .class_init    = via_ide_class_init,
 };
 
 static void via_ide_register(void)
 {
-    pci_qdev_register(&via_ide_info);
+    type_register_static(&via_ide_info);
 }
 device_init(via_ide_register);
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index 130accf..6dbd649 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -525,16 +525,18 @@ static Property core_properties[] = {
 
 static void core_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = integratorcm_init;
+    dc->props = core_properties;
 }
 
-static DeviceInfo core_info = {
-    .name = "integrator_core",
-    .size = sizeof(integratorcm_state),
-    .props = core_properties,
-    .class_init = core_class_init,
+static TypeInfo core_info = {
+    .name          = "integrator_core",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(integratorcm_state),
+    .class_init    = core_class_init,
 };
 
 static void icp_pic_class_init(ObjectClass *klass, void *data)
@@ -544,16 +546,17 @@ static void icp_pic_class_init(ObjectClass *klass, void *data)
     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 TypeInfo icp_pic_info = {
+    .name          = "integrator_pic",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(icp_pic_state),
+    .class_init    = icp_pic_class_init,
 };
 
 static void integratorcp_register_devices(void)
 {
-    sysbus_qdev_register(&icp_pic_info);
-    sysbus_register_withprop(&core_info);
+    type_register_static(&icp_pic_info);
+    type_register_static(&core_info);
 }
 
 device_init(integratorcp_register_devices)
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index f062133..9e4a31f 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -74,14 +74,6 @@ static int hda_codec_dev_exit(DeviceState *qdev)
     return 0;
 }
 
-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_subclass(info, TYPE_HDA_CODEC_DEVICE);
-}
-
 HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad)
 {
     DeviceState *qdev;
@@ -1255,6 +1247,7 @@ static Property intel_hda_properties[] = {
 
 static void intel_hda_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = intel_hda_init;
@@ -1264,29 +1257,39 @@ static void intel_hda_class_init(ObjectClass *klass, void *data)
     k->device_id = 0x2668;
     k->revision = 1;
     k->class_id = PCI_CLASS_MULTIMEDIA_HD_AUDIO;
+    dc->desc = "Intel HD Audio Controller";
+    dc->reset = intel_hda_reset;
+    dc->vmsd = &vmstate_intel_hda;
+    dc->props = intel_hda_properties;
 }
 
-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 intel_hda_info = {
+    .name          = "intel-hda",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(IntelHDAState),
+    .class_init    = intel_hda_class_init,
 };
 
+static void hda_codec_device_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *k = DEVICE_CLASS(klass);
+    k->init = hda_codec_dev_init;
+    k->exit = hda_codec_dev_exit;
+    k->bus_info = &hda_codec_bus_info;
+}
+
 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),
+    .class_init = hda_codec_device_class_init,
 };
 
 static void intel_hda_register(void)
 {
-    pci_qdev_register(&intel_hda_info);
+    type_register_static(&intel_hda_info);
     type_register_static(&hda_codec_device_type_info);
 }
 device_init(intel_hda_register);
diff --git a/hw/intel-hda.h b/hw/intel-hda.h
index f523587..a1cca5b 100644
--- a/hw/intel-hda.h
+++ b/hw/intel-hda.h
@@ -48,7 +48,6 @@ struct HDACodecDevice {
 void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus,
                         hda_codec_response_func response,
                         hda_codec_xfer_func xfer);
-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);
diff --git a/hw/ioapic.c b/hw/ioapic.c
index 0939009..79549f8 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -238,20 +238,22 @@ static void ioapic_init(IOAPICCommonState *s, int instance_no)
 static void ioapic_class_init(ObjectClass *klass, void *data)
 {
     IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     k->init = ioapic_init;
+    dc->reset = ioapic_reset_common;
 }
 
-static DeviceInfo ioapic_info = {
-    .name = "ioapic",
-    .size = sizeof(IOAPICCommonState),
-    .reset = ioapic_reset_common,
-    .class_init = ioapic_class_init,
+static TypeInfo ioapic_info = {
+    .name          = "ioapic",
+    .parent        = TYPE_IOAPIC_COMMON,
+    .instance_size = sizeof(IOAPICCommonState),
+    .class_init    = ioapic_class_init,
 };
 
 static void ioapic_register_devices(void)
 {
-    ioapic_qdev_register(&ioapic_info);
+    type_register_static(&ioapic_info);
 }
 
 device_init(ioapic_register_devices)
diff --git a/hw/ioapic_common.c b/hw/ioapic_common.c
index 4bb7ea9..f932700 100644
--- a/hw/ioapic_common.c
+++ b/hw/ioapic_common.c
@@ -96,8 +96,11 @@ static const VMStateDescription vmstate_ioapic_common = {
 static void ioapic_common_class_init(ObjectClass *klass, void *data)
 {
     SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     sc->init = ioapic_init_common;
+    dc->vmsd = &vmstate_ioapic_common;
+    dc->no_user = 1;
 }
 
 static TypeInfo ioapic_common_type = {
@@ -109,13 +112,6 @@ static TypeInfo ioapic_common_type = {
     .abstract = true,
 };
 
-void ioapic_qdev_register(DeviceInfo *info)
-{
-    info->vmsd = &vmstate_ioapic_common;
-    info->no_user = 1;
-    sysbus_qdev_register_subclass(info, TYPE_IOAPIC_COMMON);
-}
-
 static void register_devices(void)
 {
     type_register_static(&ioapic_common_type);
diff --git a/hw/ioapic_internal.h b/hw/ioapic_internal.h
index 9dff1a7..e04c9f3 100644
--- a/hw/ioapic_internal.h
+++ b/hw/ioapic_internal.h
@@ -97,7 +97,6 @@ struct IOAPICCommonState {
     uint64_t ioredtbl[IOAPIC_NUM_PINS];
 };
 
-void ioapic_qdev_register(DeviceInfo *info);
 void ioapic_reset_common(DeviceState *dev);
 
 #endif /* !QEMU_IOAPIC_INTERNAL_H */
diff --git a/hw/ioh3420.c b/hw/ioh3420.c
index 6cfafb3..1c60123 100644
--- a/hw/ioh3420.c
+++ b/hw/ioh3420.c
@@ -213,6 +213,7 @@ static Property ioh3420_properties[] = {
 
 static void ioh3420_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->is_express = 1;
@@ -223,21 +224,22 @@ static void ioh3420_class_init(ObjectClass *klass, void *data)
     k->vendor_id = PCI_VENDOR_ID_INTEL;
     k->device_id = PCI_DEVICE_ID_IOH_EPORT;
     k->revision = PCI_DEVICE_ID_IOH_REV;
+    dc->desc = "Intel IOH device id 3420 PCIE Root Port";
+    dc->reset = ioh3420_reset;
+    dc->vmsd = &vmstate_ioh3420;
+    dc->props = ioh3420_properties;
 }
 
-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 TypeInfo ioh3420_info = {
+    .name          = "ioh3420",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIESlot),
+    .class_init    = ioh3420_class_init,
 };
 
 static void ioh3420_register(void)
 {
-    pci_qdev_register(&ioh3420_info);
+    type_register_static(&ioh3420_info);
 }
 
 device_init(ioh3420_register);
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 92d8882..a22c5c6 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -125,18 +125,6 @@ static int isa_qdev_init(DeviceState *qdev, DeviceInfo *base)
     return 0;
 }
 
-void isa_qdev_register_subclass(DeviceInfo *info, const char *parent)
-{
-    info->init = isa_qdev_init;
-    info->bus_info = &isa_bus_info;
-    qdev_register_subclass(info, parent);
-}
-
-void isa_qdev_register(DeviceInfo *info)
-{
-    isa_qdev_register_subclass(info, TYPE_ISA_DEVICE);
-}
-
 ISADevice *isa_create(ISABus *bus, const char *name)
 {
     DeviceState *dev;
@@ -191,30 +179,40 @@ static int isabus_bridge_init(SysBusDevice *dev)
 
 static void isabus_bridge_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = isabus_bridge_init;
+    dc->fw_name = "isa";
+    dc->no_user = 1;
 }
 
-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 isabus_bridge_info = {
+    .name          = "isabus-bridge",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SysBusDevice),
+    .class_init    = isabus_bridge_class_init,
 };
 
+static void isa_device_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *k = DEVICE_CLASS(klass);
+    k->init = isa_qdev_init;
+    k->bus_info = &isa_bus_info;
+}
+
 static TypeInfo isa_device_type_info = {
     .name = TYPE_ISA_DEVICE,
     .parent = TYPE_DEVICE,
     .instance_size = sizeof(ISADevice),
     .abstract = true,
     .class_size = sizeof(ISADeviceClass),
+    .class_init = isa_device_class_init,
 };
 
 static void isabus_register_devices(void)
 {
-    sysbus_register_withprop(&isabus_bridge_info);
+    type_register_static(&isabus_bridge_info);
     type_register_static(&isa_device_type_info);
 }
 
diff --git a/hw/isa.h b/hw/isa.h
index 9f5d158..40373fb 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -41,8 +41,6 @@ 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(DeviceInfo *info);
-void isa_qdev_register_subclass(DeviceInfo *info, const char *parent);
 MemoryRegion *isa_address_space(ISADevice *dev);
 ISADevice *isa_create(ISABus *bus, const char *name);
 ISADevice *isa_try_create(ISABus *bus, const char *name);
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index e2880be..6f017d4 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -779,6 +779,7 @@ static Property ivshmem_properties[] = {
 
 static void ivshmem_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = pci_ivshmem_init;
@@ -786,19 +787,20 @@ static void ivshmem_class_init(ObjectClass *klass, void *data)
     k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
     k->device_id = 0x1110;
     k->class_id = PCI_CLASS_MEMORY_RAM;
+    dc->reset = ivshmem_reset;
+    dc->props = ivshmem_properties;
 }
 
-static DeviceInfo ivshmem_info = {
-    .name = "ivshmem",
-    .size = sizeof(IVShmemState),
-    .reset = ivshmem_reset,
-    .props = ivshmem_properties,
-    .class_init = ivshmem_class_init,
+static TypeInfo ivshmem_info = {
+    .name          = "ivshmem",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(IVShmemState),
+    .class_init    = ivshmem_class_init,
 };
 
 static void ivshmem_register_devices(void)
 {
-    pci_qdev_register(&ivshmem_info);
+    type_register_static(&ivshmem_info);
 }
 
 device_init(ivshmem_register_devices)
diff --git a/hw/kvm/apic.c b/hw/kvm/apic.c
index bc80ae4..89e33b0 100644
--- a/hw/kvm/apic.c
+++ b/hw/kvm/apic.c
@@ -132,14 +132,15 @@ static void kvm_apic_class_init(ObjectClass *klass, void *data)
     k->external_nmi = kvm_apic_external_nmi;
 }
 
-static DeviceInfo kvm_apic_info = {
+static TypeInfo kvm_apic_info = {
     .name = "kvm-apic",
+    .parent = TYPE_APIC_COMMON,
     .class_init = kvm_apic_class_init,
 };
 
 static void kvm_apic_register_device(void)
 {
-    apic_qdev_register(&kvm_apic_info);
+    type_register_static(&kvm_apic_info);
 }
 
 device_init(kvm_apic_register_device)
diff --git a/hw/kvm/clock.c b/hw/kvm/clock.c
index b997d2a..d5a5386 100644
--- a/hw/kvm/clock.c
+++ b/hw/kvm/clock.c
@@ -94,17 +94,19 @@ static const VMStateDescription kvmclock_vmsd = {
 
 static void kvmclock_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = kvmclock_init;
+    dc->no_user = 1;
+    dc->vmsd = &kvmclock_vmsd;
 }
 
-static DeviceInfo kvmclock_info = {
-    .name = "kvmclock",
-    .size = sizeof(KVMClockState),
-    .vmsd = &kvmclock_vmsd,
-    .no_user = 1,
-    .class_init = kvmclock_class_init,
+static TypeInfo kvmclock_info = {
+    .name          = "kvmclock",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(KVMClockState),
+    .class_init    = kvmclock_class_init,
 };
 
 /* Note: Must be called after VCPU initialization. */
@@ -120,7 +122,7 @@ void kvmclock_create(void)
 static void kvmclock_register_device(void)
 {
     if (kvm_enabled()) {
-        sysbus_register_withprop(&kvmclock_info);
+    type_register_static(&kvmclock_info);
     }
 }
 
diff --git a/hw/kvm/i8259.c b/hw/kvm/i8259.c
index b34901c..297d64e 100644
--- a/hw/kvm/i8259.c
+++ b/hw/kvm/i8259.c
@@ -115,21 +115,23 @@ qemu_irq *kvm_i8259_init(ISABus *bus)
 static void kvm_i8259_class_init(ObjectClass *klass, void *data)
 {
     PICCommonClass *k = PIC_COMMON_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
+    dc->reset     = kvm_pic_reset;
     k->init       = kvm_pic_init;
     k->pre_save   = kvm_pic_get;
     k->post_load  = kvm_pic_put;
 }
 
-static DeviceInfo kvm_i8259_info = {
+static TypeInfo kvm_i8259_info = {
     .name  = "kvm-i8259",
-    .reset = kvm_pic_reset,
+    .parent = TYPE_PIC_COMMON,
     .class_init = kvm_i8259_class_init,
 };
 
 static void kvm_pic_register(void)
 {
-    pic_qdev_register(&kvm_i8259_info);
+    type_register_static(&kvm_i8259_info);
 }
 
 device_init(kvm_pic_register)
diff --git a/hw/kvm/ioapic.c b/hw/kvm/ioapic.c
index f8ea0cc..b316933 100644
--- a/hw/kvm/ioapic.c
+++ b/hw/kvm/ioapic.c
@@ -93,29 +93,33 @@ static void kvm_ioapic_init(IOAPICCommonState *s, int instance_no)
     qdev_init_gpio_in(&s->busdev.qdev, kvm_ioapic_set_irq, IOAPIC_NUM_PINS);
 }
 
+static Property kvm_ioapic_properties[] = {
+    DEFINE_PROP_UINT32("gsi_base", KVMIOAPICState, kvm_gsi_base, 0),
+    DEFINE_PROP_END_OF_LIST()
+};
+
 static void kvm_ioapic_class_init(ObjectClass *klass, void *data)
 {
     IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     k->init      = kvm_ioapic_init;
     k->pre_save  = kvm_ioapic_get;
     k->post_load = kvm_ioapic_put;
+    dc->reset    = kvm_ioapic_reset;
+    dc->props    = kvm_ioapic_properties;
 }
 
-static DeviceInfo kvm_ioapic_info = {
+static TypeInfo kvm_ioapic_info = {
     .name  = "kvm-ioapic",
-    .size = sizeof(KVMIOAPICState),
-    .reset = kvm_ioapic_reset,
+    .parent = TYPE_IOAPIC_COMMON,
+    .instance_size = sizeof(KVMIOAPICState),
     .class_init = kvm_ioapic_class_init,
-    .props = (Property[]) {
-        DEFINE_PROP_UINT32("gsi_base", KVMIOAPICState, kvm_gsi_base, 0),
-        DEFINE_PROP_END_OF_LIST()
-    },
 };
 
 static void kvm_ioapic_register_device(void)
 {
-    ioapic_qdev_register(&kvm_ioapic_info);
+    type_register_static(&kvm_ioapic_info);
 }
 
 device_init(kvm_ioapic_register_device)
diff --git a/hw/lan9118.c b/hw/lan9118.c
index 3925b04..78777c7 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -1245,23 +1245,25 @@ static Property lan9118_properties[] = {
 
 static void lan9118_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = lan9118_init1;
+    dc->reset = lan9118_reset;
+    dc->props = lan9118_properties;
+    dc->vmsd = &vmstate_lan9118;
 }
 
-static DeviceInfo lan9118_info = {
-    .name = "lan9118",
-    .size = sizeof(lan9118_state),
-    .reset = lan9118_reset,
-    .vmsd = &vmstate_lan9118,
-    .props = lan9118_properties,
-    .class_init = lan9118_class_init,
+static TypeInfo lan9118_info = {
+    .name          = "lan9118",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(lan9118_state),
+    .class_init    = lan9118_class_init,
 };
 
 static void lan9118_register_devices(void)
 {
-    sysbus_register_withprop(&lan9118_info);
+    type_register_static(&lan9118_info);
 }
 
 /* Legacy helper function.  Should go away when machine config files are
diff --git a/hw/lance.c b/hw/lance.c
index 969d766..519720b 100644
--- a/hw/lance.c
+++ b/hw/lance.c
@@ -145,23 +145,25 @@ static Property lance_properties[] = {
 
 static void lance_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = lance_init;
+    dc->fw_name = "ethernet";
+    dc->reset = lance_reset;
+    dc->vmsd = &vmstate_lance;
+    dc->props = lance_properties;
 }
 
-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 TypeInfo lance_info = {
+    .name          = "lance",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SysBusPCNetState),
+    .class_init    = lance_class_init,
 };
 
 static void lance_register_devices(void)
 {
-    sysbus_register_withprop(&lance_info);
+    type_register_static(&lance_info);
 }
 device_init(lance_register_devices)
diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c
index e25a409..023c644 100644
--- a/hw/lm32_juart.c
+++ b/hw/lm32_juart.c
@@ -136,22 +136,24 @@ static const VMStateDescription vmstate_lm32_juart = {
 
 static void lm32_juart_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = lm32_juart_init;
+    dc->reset = juart_reset;
+    dc->vmsd = &vmstate_lm32_juart;
 }
 
-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 TypeInfo lm32_juart_info = {
+    .name          = "lm32-juart",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(LM32JuartState),
+    .class_init    = lm32_juart_class_init,
 };
 
 static void lm32_juart_register(void)
 {
-    sysbus_register_withprop(&lm32_juart_info);
+    type_register_static(&lm32_juart_info);
 }
 
 device_init(lm32_juart_register)
diff --git a/hw/lm32_pic.c b/hw/lm32_pic.c
index b7b1886..7be6d0d 100644
--- a/hw/lm32_pic.c
+++ b/hw/lm32_pic.c
@@ -176,22 +176,24 @@ static const VMStateDescription vmstate_lm32_pic = {
 
 static void lm32_pic_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = lm32_pic_init;
+    dc->reset = pic_reset;
+    dc->vmsd = &vmstate_lm32_pic;
 }
 
-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 TypeInfo lm32_pic_info = {
+    .name          = "lm32-pic",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(LM32PicState),
+    .class_init    = lm32_pic_class_init,
 };
 
 static void lm32_pic_register(void)
 {
-    sysbus_register_withprop(&lm32_pic_info);
+    type_register_static(&lm32_pic_info);
 }
 
 device_init(lm32_pic_register)
diff --git a/hw/lm32_sys.c b/hw/lm32_sys.c
index c83809e..ba6f4ac 100644
--- a/hw/lm32_sys.c
+++ b/hw/lm32_sys.c
@@ -148,23 +148,25 @@ static Property lm32_sys_properties[] = {
 
 static void lm32_sys_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = lm32_sys_init;
+    dc->reset = sys_reset;
+    dc->vmsd = &vmstate_lm32_sys;
+    dc->props = lm32_sys_properties;
 }
 
-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 TypeInfo lm32_sys_info = {
+    .name          = "lm32-sys",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(LM32SysState),
+    .class_init    = lm32_sys_class_init,
 };
 
 static void lm32_sys_register(void)
 {
-    sysbus_register_withprop(&lm32_sys_info);
+    type_register_static(&lm32_sys_info);
 }
 
 device_init(lm32_sys_register)
diff --git a/hw/lm32_timer.c b/hw/lm32_timer.c
index 932c1f0..3cb4e0a 100644
--- a/hw/lm32_timer.c
+++ b/hw/lm32_timer.c
@@ -206,23 +206,25 @@ static Property lm32_timer_properties[] = {
 
 static void lm32_timer_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = lm32_timer_init;
+    dc->reset = timer_reset;
+    dc->vmsd = &vmstate_lm32_timer;
+    dc->props = lm32_timer_properties;
 }
 
-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 TypeInfo lm32_timer_info = {
+    .name          = "lm32-timer",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(LM32TimerState),
+    .class_init    = lm32_timer_class_init,
 };
 
 static void lm32_timer_register(void)
 {
-    sysbus_register_withprop(&lm32_timer_info);
+    type_register_static(&lm32_timer_info);
 }
 
 device_init(lm32_timer_register)
diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c
index ea7d00e..fc70490 100644
--- a/hw/lm32_uart.c
+++ b/hw/lm32_uart.c
@@ -273,22 +273,24 @@ static const VMStateDescription vmstate_lm32_uart = {
 
 static void lm32_uart_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = lm32_uart_init;
+    dc->reset = uart_reset;
+    dc->vmsd = &vmstate_lm32_uart;
 }
 
-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 TypeInfo lm32_uart_info = {
+    .name          = "lm32-uart",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(LM32UartState),
+    .class_init    = lm32_uart_class_init,
 };
 
 static void lm32_uart_register(void)
 {
-    sysbus_register_withprop(&lm32_uart_info);
+    type_register_static(&lm32_uart_info);
 }
 
 device_init(lm32_uart_register)
diff --git a/hw/lm832x.c b/hw/lm832x.c
index 84f81fe..895d306 100644
--- a/hw/lm832x.c
+++ b/hw/lm832x.c
@@ -496,24 +496,26 @@ void lm832x_key_event(DeviceState *dev, int key, int state)
 
 static void lm8323_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     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;
+    dc->vmsd = &vmstate_lm_kbd;
 }
 
-static DeviceInfo lm8323_info = {
-    .name = "lm8323",
-    .size = sizeof(LM823KbdState),
-    .vmsd = &vmstate_lm_kbd,
-    .class_init = lm8323_class_init,
+static TypeInfo lm8323_info = {
+    .name          = "lm8323",
+    .parent        = TYPE_I2C_SLAVE,
+    .instance_size = sizeof(LM823KbdState),
+    .class_init    = lm8323_class_init,
 };
 
 static void lm832x_register_devices(void)
 {
-    i2c_register_slave(&lm8323_info);
+    type_register_static(&lm8323_info);
 }
 
 device_init(lm832x_register_devices)
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 3571588..638332e 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -2122,6 +2122,7 @@ static int lsi_scsi_init(PCIDevice *dev)
 
 static void lsi_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = lsi_scsi_init;
@@ -2130,20 +2131,22 @@ static void lsi_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_LSI_53C895A;
     k->class_id = PCI_CLASS_STORAGE_SCSI;
     k->subsystem_id = 0x1000;
+    dc->alias = "lsi";
+    dc->reset = lsi_scsi_reset;
+    dc->vmsd = &vmstate_lsi_scsi;
 }
 
-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 TypeInfo lsi_info = {
+    .name          = "lsi53c895a",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(LSIState),
+    .class_init    = lsi_class_init,
 };
 
 static void lsi53c895a_register_devices(void)
 {
-    pci_qdev_register(&lsi_info);
+    type_register_static(&lsi_info);
+    type_register_static_alias(&lsi_info, "lsi");
 }
 
 device_init(lsi53c895a_register_devices);
diff --git a/hw/m48t59.c b/hw/m48t59.c
index 262cfb8..2a1e314 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -720,24 +720,28 @@ static int m48t59_init1(SysBusDevice *dev)
     return 0;
 }
 
+static Property m48t59_isa_properties[] = {
+    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),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void m48t59_init_class_isa1(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = m48t59_init_isa1;
+    dc->no_user = 1;
+    dc->reset = m48t59_reset_isa;
+    dc->props = m48t59_isa_properties;
 }
 
-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),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static TypeInfo m48t59_isa_info = {
+    .name          = "m48t59_isa",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(M48t59ISAState),
+    .class_init    = m48t59_init_class_isa1,
 };
 
 static Property m48t59_properties[] = {
@@ -749,23 +753,25 @@ static Property m48t59_properties[] = {
 
 static void m48t59_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = m48t59_init1;
+    dc->reset = m48t59_reset_sysbus;
+    dc->props = m48t59_properties;
 }
 
-static DeviceInfo m48t59_info = {
-    .name = "m48t59",
-    .size = sizeof(M48t59SysBusState),
-    .reset = m48t59_reset_sysbus,
-    .props = m48t59_properties,
-    .class_init = m48t59_class_init,
+static TypeInfo m48t59_info = {
+    .name          = "m48t59",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(M48t59SysBusState),
+    .class_init    = m48t59_class_init,
 };
 
 static void m48t59_register_devices(void)
 {
-    sysbus_register_withprop(&m48t59_info);
-    isa_qdev_register(&m48t59_isa_info);
+    type_register_static(&m48t59_info);
+    type_register_static(&m48t59_isa_info);
 }
 
 device_init(m48t59_register_devices)
diff --git a/hw/macio.c b/hw/macio.c
index ae9db08..3d648e9 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -90,15 +90,16 @@ static void macio_class_init(ObjectClass *klass, void *data)
     k->class_id = PCI_CLASS_OTHERS << 8;
 }
 
-static DeviceInfo macio_info = {
-    .name = "macio",
-    .size = sizeof(MacIOState),
-    .class_init = macio_class_init,
+static TypeInfo macio_info = {
+    .name          = "macio",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(MacIOState),
+    .class_init    = macio_class_init,
 };
 
 static void macio_register(void)
 {
-    pci_qdev_register(&macio_info);
+    type_register_static(&macio_info);
 }
 
 device_init(macio_register);
diff --git a/hw/marvell_88w8618_audio.c b/hw/marvell_88w8618_audio.c
index 355e492..b628f17 100644
--- a/hw/marvell_88w8618_audio.c
+++ b/hw/marvell_88w8618_audio.c
@@ -279,23 +279,25 @@ static Property mv88w8618_audio_properties[] = {
 
 static void mv88w8618_audio_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = mv88w8618_audio_init;
+    dc->reset = mv88w8618_audio_reset;
+    dc->vmsd = &mv88w8618_audio_vmsd;
+    dc->props = mv88w8618_audio_properties;
 }
 
-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 TypeInfo mv88w8618_audio_info = {
+    .name          = "mv88w8618_audio",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(mv88w8618_audio_state),
+    .class_init    = mv88w8618_audio_class_init,
 };
 
 static void mv88w8618_register_devices(void)
 {
-    sysbus_register_withprop(&mv88w8618_audio_info);
+    type_register_static(&mv88w8618_audio_info);
 }
 
 device_init(mv88w8618_register_devices)
diff --git a/hw/max111x.c b/hw/max111x.c
index db17842..9d61aa9 100644
--- a/hw/max111x.c
+++ b/hw/max111x.c
@@ -161,10 +161,11 @@ static void max1110_class_init(ObjectClass *klass, void *data)
     k->transfer = max111x_transfer;
 }
 
-static DeviceInfo max1110_info = {
-    .name = "max1110",
-    .size = sizeof(MAX111xState),
-    .class_init = max1110_class_init,
+static TypeInfo max1110_info = {
+    .name          = "max1110",
+    .parent        = TYPE_SSI_SLAVE,
+    .instance_size = sizeof(MAX111xState),
+    .class_init    = max1110_class_init,
 };
 
 static void max1111_class_init(ObjectClass *klass, void *data)
@@ -175,16 +176,17 @@ static void max1111_class_init(ObjectClass *klass, void *data)
     k->transfer = max111x_transfer;
 }
 
-static DeviceInfo max1111_info = {
-    .name = "max1111",
-    .size = sizeof(MAX111xState),
-    .class_init = max1111_class_init,
+static TypeInfo max1111_info = {
+    .name          = "max1111",
+    .parent        = TYPE_SSI_SLAVE,
+    .instance_size = sizeof(MAX111xState),
+    .class_init    = max1111_class_init,
 };
 
 static void max111x_register_devices(void)
 {
-    ssi_register_slave(&max1110_info);
-    ssi_register_slave(&max1111_info);
+    type_register_static(&max1110_info);
+    type_register_static(&max1111_info);
 }
 
 device_init(max111x_register_devices)
diff --git a/hw/max7310.c b/hw/max7310.c
index 0cc3219..3a6bb96 100644
--- a/hw/max7310.c
+++ b/hw/max7310.c
@@ -187,25 +187,27 @@ static int max7310_init(I2CSlave *i2c)
 
 static void max7310_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
 
     k->init = max7310_init;
     k->event = max7310_event;
     k->recv = max7310_rx;
     k->send = max7310_tx;
+    dc->reset = max7310_reset;
+    dc->vmsd = &vmstate_max7310;
 }
 
-static DeviceInfo max7310_info = {
-    .name = "max7310",
-    .size = sizeof(MAX7310State),
-    .vmsd = &vmstate_max7310,
-    .reset = max7310_reset,
-    .class_init = max7310_class_init,
+static TypeInfo max7310_info = {
+    .name          = "max7310",
+    .parent        = TYPE_I2C_SLAVE,
+    .instance_size = sizeof(MAX7310State),
+    .class_init    = max7310_class_init,
 };
 
 static void max7310_register_devices(void)
 {
-    i2c_register_slave(&max7310_info);
+    type_register_static(&max7310_info);
 }
 
 device_init(max7310_register_devices)
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index 685eb89..c1f4ef4 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -699,26 +699,30 @@ ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
     return dev;
 }
 
+static Property mc146818rtc_properties[] = {
+    DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void rtc_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = rtc_initfn;
+    dc->no_user = 1;
+    dc->vmsd = &vmstate_rtc;
+    dc->props = mc146818rtc_properties;
 }
 
-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(),
-    }
+static TypeInfo mc146818rtc_info = {
+    .name          = "mc146818rtc",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(RTCState),
+    .class_init    = rtc_class_initfn,
 };
 
 static void mc146818rtc_register(void)
 {
-    isa_qdev_register(&mc146818rtc_info);
+    type_register_static(&mc146818rtc_info);
 }
 device_init(mc146818rtc_register)
diff --git a/hw/milkymist-ac97.c b/hw/milkymist-ac97.c
index 7dce5bc..0881643 100644
--- a/hw/milkymist-ac97.c
+++ b/hw/milkymist-ac97.c
@@ -321,22 +321,24 @@ static const VMStateDescription vmstate_milkymist_ac97 = {
 
 static void milkymist_ac97_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = milkymist_ac97_init;
+    dc->reset = milkymist_ac97_reset;
+    dc->vmsd = &vmstate_milkymist_ac97;
 }
 
-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 TypeInfo milkymist_ac97_info = {
+    .name          = "milkymist-ac97",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MilkymistAC97State),
+    .class_init    = milkymist_ac97_class_init,
 };
 
 static void milkymist_ac97_register(void)
 {
-    sysbus_register_withprop(&milkymist_ac97_info);
+    type_register_static(&milkymist_ac97_info);
 }
 
 device_init(milkymist_ac97_register)
diff --git a/hw/milkymist-hpdmc.c b/hw/milkymist-hpdmc.c
index 46e8ae6..b5122af 100644
--- a/hw/milkymist-hpdmc.c
+++ b/hw/milkymist-hpdmc.c
@@ -147,22 +147,24 @@ static const VMStateDescription vmstate_milkymist_hpdmc = {
 
 static void milkymist_hpdmc_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = milkymist_hpdmc_init;
+    dc->reset = milkymist_hpdmc_reset;
+    dc->vmsd = &vmstate_milkymist_hpdmc;
 }
 
-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 TypeInfo milkymist_hpdmc_info = {
+    .name          = "milkymist-hpdmc",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MilkymistHpdmcState),
+    .class_init    = milkymist_hpdmc_class_init,
 };
 
 static void milkymist_hpdmc_register(void)
 {
-    sysbus_register_withprop(&milkymist_hpdmc_info);
+    type_register_static(&milkymist_hpdmc_info);
 }
 
 device_init(milkymist_hpdmc_register)
diff --git a/hw/milkymist-memcard.c b/hw/milkymist-memcard.c
index 97eb793..3c1c68a 100644
--- a/hw/milkymist-memcard.c
+++ b/hw/milkymist-memcard.c
@@ -280,22 +280,24 @@ static const VMStateDescription vmstate_milkymist_memcard = {
 
 static void milkymist_memcard_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = milkymist_memcard_init;
+    dc->reset = milkymist_memcard_reset;
+    dc->vmsd = &vmstate_milkymist_memcard;
 }
 
-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 TypeInfo milkymist_memcard_info = {
+    .name          = "milkymist-memcard",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MilkymistMemcardState),
+    .class_init    = milkymist_memcard_class_init,
 };
 
 static void milkymist_memcard_register(void)
 {
-    sysbus_register_withprop(&milkymist_memcard_info);
+    type_register_static(&milkymist_memcard_info);
 }
 
 device_init(milkymist_memcard_register)
diff --git a/hw/milkymist-minimac2.c b/hw/milkymist-minimac2.c
index 1ac6c6a..b9b553f 100644
--- a/hw/milkymist-minimac2.c
+++ b/hw/milkymist-minimac2.c
@@ -526,23 +526,25 @@ static Property milkymist_minimac2_properties[] = {
 
 static void milkymist_minimac2_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = milkymist_minimac2_init;
+    dc->reset = milkymist_minimac2_reset;
+    dc->vmsd = &vmstate_milkymist_minimac2;
+    dc->props = milkymist_minimac2_properties;
 }
 
-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 TypeInfo milkymist_minimac2_info = {
+    .name          = "milkymist-minimac2",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MilkymistMinimac2State),
+    .class_init    = milkymist_minimac2_class_init,
 };
 
 static void milkymist_minimac2_register(void)
 {
-    sysbus_register_withprop(&milkymist_minimac2_info);
+    type_register_static(&milkymist_minimac2_info);
 }
 
 device_init(milkymist_minimac2_register)
diff --git a/hw/milkymist-pfpu.c b/hw/milkymist-pfpu.c
index b6ade5a..1b73a46 100644
--- a/hw/milkymist-pfpu.c
+++ b/hw/milkymist-pfpu.c
@@ -521,22 +521,24 @@ static const VMStateDescription vmstate_milkymist_pfpu = {
 
 static void milkymist_pfpu_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = milkymist_pfpu_init;
+    dc->reset = milkymist_pfpu_reset;
+    dc->vmsd = &vmstate_milkymist_pfpu;
 }
 
-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 TypeInfo milkymist_pfpu_info = {
+    .name          = "milkymist-pfpu",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MilkymistPFPUState),
+    .class_init    = milkymist_pfpu_class_init,
 };
 
 static void milkymist_pfpu_register(void)
 {
-    sysbus_register_withprop(&milkymist_pfpu_info);
+    type_register_static(&milkymist_pfpu_info);
 }
 
 device_init(milkymist_pfpu_register)
diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c
index f4d2dad..5d496cb 100644
--- a/hw/milkymist-softusb.c
+++ b/hw/milkymist-softusb.c
@@ -307,23 +307,25 @@ static Property milkymist_softusb_properties[] = {
 
 static void milkymist_softusb_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = milkymist_softusb_init;
+    dc->reset = milkymist_softusb_reset;
+    dc->vmsd = &vmstate_milkymist_softusb;
+    dc->props = milkymist_softusb_properties;
 }
 
-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 TypeInfo milkymist_softusb_info = {
+    .name          = "milkymist-softusb",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MilkymistSoftUsbState),
+    .class_init    = milkymist_softusb_class_init,
 };
 
 static void milkymist_softusb_register(void)
 {
-    sysbus_register_withprop(&milkymist_softusb_info);
+    type_register_static(&milkymist_softusb_info);
 }
 
 device_init(milkymist_softusb_register)
diff --git a/hw/milkymist-sysctl.c b/hw/milkymist-sysctl.c
index 4b017fa..18171f6 100644
--- a/hw/milkymist-sysctl.c
+++ b/hw/milkymist-sysctl.c
@@ -306,23 +306,25 @@ static Property milkymist_sysctl_properties[] = {
 
 static void milkymist_sysctl_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = milkymist_sysctl_init;
+    dc->reset = milkymist_sysctl_reset;
+    dc->vmsd = &vmstate_milkymist_sysctl;
+    dc->props = milkymist_sysctl_properties;
 }
 
-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 TypeInfo milkymist_sysctl_info = {
+    .name          = "milkymist-sysctl",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MilkymistSysctlState),
+    .class_init    = milkymist_sysctl_class_init,
 };
 
 static void milkymist_sysctl_register(void)
 {
-    sysbus_register_withprop(&milkymist_sysctl_info);
+    type_register_static(&milkymist_sysctl_info);
 }
 
 device_init(milkymist_sysctl_register)
diff --git a/hw/milkymist-tmu2.c b/hw/milkymist-tmu2.c
index 4004a12..474eae0 100644
--- a/hw/milkymist-tmu2.c
+++ b/hw/milkymist-tmu2.c
@@ -467,22 +467,24 @@ static const VMStateDescription vmstate_milkymist_tmu2 = {
 
 static void milkymist_tmu2_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = milkymist_tmu2_init;
+    dc->reset = milkymist_tmu2_reset;
+    dc->vmsd = &vmstate_milkymist_tmu2;
 }
 
-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 TypeInfo milkymist_tmu2_info = {
+    .name          = "milkymist-tmu2",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MilkymistTMU2State),
+    .class_init    = milkymist_tmu2_class_init,
 };
 
 static void milkymist_tmu2_register(void)
 {
-    sysbus_register_withprop(&milkymist_tmu2_info);
+    type_register_static(&milkymist_tmu2_info);
 }
 
 device_init(milkymist_tmu2_register)
diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c
index 312976d..2999b79 100644
--- a/hw/milkymist-uart.c
+++ b/hw/milkymist-uart.c
@@ -220,22 +220,24 @@ static const VMStateDescription vmstate_milkymist_uart = {
 
 static void milkymist_uart_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = milkymist_uart_init;
+    dc->reset = milkymist_uart_reset;
+    dc->vmsd = &vmstate_milkymist_uart;
 }
 
-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 TypeInfo milkymist_uart_info = {
+    .name          = "milkymist-uart",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MilkymistUartState),
+    .class_init    = milkymist_uart_class_init,
 };
 
 static void milkymist_uart_register(void)
 {
-    sysbus_register_withprop(&milkymist_uart_info);
+    type_register_static(&milkymist_uart_info);
 }
 
 device_init(milkymist_uart_register)
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index 81d31fa..92ad02f 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -307,23 +307,25 @@ static Property milkymist_vgafb_properties[] = {
 
 static void milkymist_vgafb_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = milkymist_vgafb_init;
+    dc->reset = milkymist_vgafb_reset;
+    dc->vmsd = &vmstate_milkymist_vgafb;
+    dc->props = milkymist_vgafb_properties;
 }
 
-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 TypeInfo milkymist_vgafb_info = {
+    .name          = "milkymist-vgafb",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MilkymistVgafbState),
+    .class_init    = milkymist_vgafb_class_init,
 };
 
 static void milkymist_vgafb_register(void)
 {
-    sysbus_register_withprop(&milkymist_vgafb_info);
+    type_register_static(&milkymist_vgafb_info);
 }
 
 device_init(milkymist_vgafb_register)
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 64603ce..d232630 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -1014,13 +1014,11 @@ static void mips_malta_class_init(ObjectClass *klass, void *data)
     k->init = mips_malta_sysbus_device_init;
 }
 
-static DeviceInfo mips_malta_device = {
-    .name  = "mips-malta",
-    .size  = sizeof(MaltaState),
-    .class_init = mips_malta_class_init,
-    .props = (Property[]) {
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static TypeInfo mips_malta_device = {
+    .name          = "mips-malta",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MaltaState),
+    .class_init    = mips_malta_class_init,
 };
 
 static QEMUMachine mips_malta_machine = {
@@ -1033,7 +1031,7 @@ static QEMUMachine mips_malta_machine = {
 
 static void mips_malta_device_init(void)
 {
-    sysbus_qdev_register(&mips_malta_device);
+    type_register_static(&mips_malta_device);
 }
 
 static void mips_malta_machine_init(void)
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index 8cf9161..a0e6c9f 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -259,24 +259,26 @@ static Property mipsnet_properties[] = {
 
 static void mipsnet_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = mipsnet_sysbus_init;
+    dc->desc = "MIPS Simulator network device";
+    dc->reset = mipsnet_sysbus_reset;
+    dc->vmsd = &vmstate_mipsnet;
+    dc->props = mipsnet_properties;
 }
 
-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 TypeInfo mipsnet_info = {
+    .name          = "mipsnet",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MIPSnetState),
+    .class_init    = mipsnet_class_init,
 };
 
 static void mipsnet_register_devices(void)
 {
-    sysbus_register_withprop(&mipsnet_info);
+    type_register_static(&mipsnet_info);
 }
 
 device_init(mipsnet_register_devices)
diff --git a/hw/mpc8544_guts.c b/hw/mpc8544_guts.c
index ec6bb4f..28cd60d 100644
--- a/hw/mpc8544_guts.c
+++ b/hw/mpc8544_guts.c
@@ -128,14 +128,15 @@ static void mpc8544_guts_class_init(ObjectClass *klass, void *data)
     k->init = mpc8544_guts_initfn;
 }
 
-static DeviceInfo mpc8544_guts_info = {
-    .name = "mpc8544-guts",
-    .size = sizeof(GutsState),
-    .class_init = mpc8544_guts_class_init,
+static TypeInfo mpc8544_guts_info = {
+    .name          = "mpc8544-guts",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(GutsState),
+    .class_init    = mpc8544_guts_class_init,
 };
 
 static void mpc8544_guts_register(void)
 {
-    sysbus_register_withprop(&mpc8544_guts_info);
+    type_register_static(&mpc8544_guts_info);
 }
 device_init(mpc8544_guts_register);
diff --git a/hw/mst_fpga.c b/hw/mst_fpga.c
index 513bfa6..1729db0 100644
--- a/hw/mst_fpga.c
+++ b/hw/mst_fpga.c
@@ -240,21 +240,23 @@ static VMStateDescription vmstate_mst_fpga_regs = {
 
 static void mst_fpga_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = mst_fpga_init;
+    dc->desc = "Mainstone II FPGA";
+    dc->vmsd = &vmstate_mst_fpga_regs;
 }
 
-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 TypeInfo mst_fpga_info = {
+    .name          = "mainstone-fpga",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(mst_irq_state),
+    .class_init    = mst_fpga_class_init,
 };
 
 static void mst_fpga_register(void)
 {
-	sysbus_register_withprop(&mst_fpga_info);
+    type_register_static(&mst_fpga_info);
 }
 device_init(mst_fpga_register);
diff --git a/hw/musicpal.c b/hw/musicpal.c
index a2fc4bb..ac90924 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -419,17 +419,19 @@ static Property mv88w8618_eth_properties[] = {
 
 static void mv88w8618_eth_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = mv88w8618_eth_init;
+    dc->vmsd = &mv88w8618_eth_vmsd;
+    dc->props = mv88w8618_eth_properties;
 }
 
-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,
+static TypeInfo mv88w8618_eth_info = {
+    .name          = "mv88w8618_eth",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(mv88w8618_eth_state),
+    .class_init    = mv88w8618_eth_class_init,
 };
 
 /* LCD register offsets */
@@ -635,16 +637,18 @@ static const VMStateDescription musicpal_lcd_vmsd = {
 
 static void musicpal_lcd_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = musicpal_lcd_init;
+    dc->vmsd = &musicpal_lcd_vmsd;
 }
 
-static DeviceInfo musicpal_lcd_info = {
-    .name = "musicpal_lcd",
-    .size = sizeof(musicpal_lcd_state),
-    .vmsd = &musicpal_lcd_vmsd,
-    .class_init = musicpal_lcd_class_init,
+static TypeInfo musicpal_lcd_info = {
+    .name          = "musicpal_lcd",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(musicpal_lcd_state),
+    .class_init    = musicpal_lcd_class_init,
 };
 
 /* PIC register offsets */
@@ -751,17 +755,19 @@ static const VMStateDescription mv88w8618_pic_vmsd = {
 
 static void mv88w8618_pic_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = mv88w8618_pic_init;
+    dc->reset = mv88w8618_pic_reset;
+    dc->vmsd = &mv88w8618_pic_vmsd;
 }
 
-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,
+static TypeInfo mv88w8618_pic_info = {
+    .name          = "mv88w8618_pic",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(mv88w8618_pic_state),
+    .class_init    = mv88w8618_pic_class_init,
 };
 
 /* PIT register offsets */
@@ -926,17 +932,19 @@ static const VMStateDescription mv88w8618_pit_vmsd = {
 
 static void mv88w8618_pit_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = mv88w8618_pit_init;
+    dc->reset = mv88w8618_pit_reset;
+    dc->vmsd = &mv88w8618_pit_vmsd;
 }
 
-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,
+static TypeInfo mv88w8618_pit_info = {
+    .name          = "mv88w8618_pit",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(mv88w8618_pit_state),
+    .class_init    = mv88w8618_pit_class_init,
 };
 
 /* Flash config register offsets */
@@ -1005,16 +1013,18 @@ static const VMStateDescription mv88w8618_flashcfg_vmsd = {
 
 static void mv88w8618_flashcfg_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = mv88w8618_flashcfg_init;
+    dc->vmsd = &mv88w8618_flashcfg_vmsd;
 }
 
-static DeviceInfo mv88w8618_flashcfg_info = {
-    .name = "mv88w8618_flashcfg",
-    .size = sizeof(mv88w8618_flashcfg_state),
-    .vmsd = &mv88w8618_flashcfg_vmsd,
-    .class_init = mv88w8618_flashcfg_class_init,
+static TypeInfo mv88w8618_flashcfg_info = {
+    .name          = "mv88w8618_flashcfg",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(mv88w8618_flashcfg_state),
+    .class_init    = mv88w8618_flashcfg_class_init,
 };
 
 /* Misc register offsets */
@@ -1324,17 +1334,19 @@ static const VMStateDescription musicpal_gpio_vmsd = {
 
 static void musicpal_gpio_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = musicpal_gpio_init;
+    dc->reset = musicpal_gpio_reset;
+    dc->vmsd = &musicpal_gpio_vmsd;
 }
 
-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,
+static TypeInfo musicpal_gpio_info = {
+    .name          = "musicpal_gpio",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(musicpal_gpio_state),
+    .class_init    = musicpal_gpio_class_init,
 };
 
 /* Keyboard codes & masks */
@@ -1477,16 +1489,18 @@ static const VMStateDescription musicpal_key_vmsd = {
 
 static void musicpal_key_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = musicpal_key_init;
+    dc->vmsd = &musicpal_key_vmsd;
 }
 
-static DeviceInfo musicpal_key_info = {
-    .name = "musicpal_key",
-    .size = sizeof(musicpal_key_state),
-    .vmsd = &musicpal_key_vmsd,
-    .class_init = musicpal_key_class_init,
+static TypeInfo musicpal_key_info = {
+    .name          = "musicpal_key",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(musicpal_key_state),
+    .class_init    = musicpal_key_class_init,
 };
 
 static struct arm_boot_info musicpal_binfo = {
@@ -1660,22 +1674,23 @@ static void mv88w8618_wlan_class_init(ObjectClass *klass, void *data)
     sdc->init = mv88w8618_wlan_init;
 }
 
-static DeviceInfo mv88w8618_wlan_info = {
-    .name = "mv88w8618_wlan",
-    .size = sizeof(SysBusDevice),
-    .class_init = mv88w8618_wlan_class_init,
+static TypeInfo mv88w8618_wlan_info = {
+    .name          = "mv88w8618_wlan",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_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_qdev_register(&mv88w8618_wlan_info);
-    sysbus_register_withprop(&musicpal_lcd_info);
-    sysbus_register_withprop(&musicpal_gpio_info);
-    sysbus_register_withprop(&musicpal_key_info);
+    type_register_static(&mv88w8618_pic_info);
+    type_register_static(&mv88w8618_pit_info);
+    type_register_static(&mv88w8618_flashcfg_info);
+    type_register_static(&mv88w8618_eth_info);
+    type_register_static(&mv88w8618_wlan_info);
+    type_register_static(&musicpal_lcd_info);
+    type_register_static(&musicpal_gpio_info);
+    type_register_static(&musicpal_key_info);
 }
 
 device_init(musicpal_register_devices)
diff --git a/hw/nand.c b/hw/nand.c
index 6248731..5d947b1 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -426,23 +426,25 @@ static Property nand_properties[] = {
 
 static void nand_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = nand_device_init;
+    dc->reset = nand_reset;
+    dc->vmsd = &vmstate_nand;
+    dc->props = nand_properties;
 }
 
-static DeviceInfo nand_info = {
-    .name = "nand",
-    .size = sizeof(NANDFlashState),
-    .reset = nand_reset,
-    .vmsd = &vmstate_nand,
-    .props = nand_properties,
-    .class_init = nand_class_init,
+static TypeInfo nand_info = {
+    .name          = "nand",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(NANDFlashState),
+    .class_init    = nand_class_init,
 };
 
 static void nand_create_device(void)
 {
-    sysbus_register_withprop(&nand_info);
+    type_register_static(&nand_info);
 }
 
 /*
diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c
index 25a7a31..1352282 100644
--- a/hw/ne2000-isa.c
+++ b/hw/ne2000-isa.c
@@ -82,27 +82,31 @@ static int isa_ne2000_initfn(ISADevice *dev)
     return 0;
 }
 
+static Property ne2000_isa_properties[] = {
+    DEFINE_PROP_HEX32("iobase", ISANE2000State, iobase, 0x300),
+    DEFINE_PROP_UINT32("irq",   ISANE2000State, isairq, 9),
+    DEFINE_NIC_PROPERTIES(ISANE2000State, ne2000.c),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void isa_ne2000_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = isa_ne2000_initfn;
+    dc->props = ne2000_isa_properties;
 }
 
-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),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static TypeInfo ne2000_isa_info = {
+    .name          = "ne2k_isa",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(ISANE2000State),
+    .class_init    = isa_ne2000_class_initfn,
 };
 
 static void ne2000_isa_register_devices(void)
 {
-    isa_qdev_register(&ne2000_isa_info);
+    type_register_static(&ne2000_isa_info);
 }
 
 device_init(ne2000_isa_register_devices)
diff --git a/hw/ne2000.c b/hw/ne2000.c
index 138479a..080811e 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -793,6 +793,7 @@ static Property ne2000_properties[] = {
 
 static void ne2000_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = pci_ne2000_init;
@@ -800,19 +801,20 @@ static void ne2000_class_init(ObjectClass *klass, void *data)
     k->vendor_id = PCI_VENDOR_ID_REALTEK;
     k->device_id = PCI_DEVICE_ID_REALTEK_8029;
     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+    dc->vmsd = &vmstate_pci_ne2000;
+    dc->props = ne2000_properties;
 }
 
-static DeviceInfo ne2000_info = {
-    .name = "ne2k_pci",
-    .size = sizeof(PCINE2000State),
-    .vmsd = &vmstate_pci_ne2000,
-    .props = ne2000_properties,
-    .class_init = ne2000_class_init,
+static TypeInfo ne2000_info = {
+    .name          = "ne2k_pci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCINE2000State),
+    .class_init    = ne2000_class_init,
 };
 
 static void ne2000_register_devices(void)
 {
-    pci_qdev_register(&ne2000_info);
+    type_register_static(&ne2000_info);
 }
 
 device_init(ne2000_register_devices)
diff --git a/hw/omap_gpio.c b/hw/omap_gpio.c
index 97d2d93..9a9a8e1 100644
--- a/hw/omap_gpio.c
+++ b/hw/omap_gpio.c
@@ -739,17 +739,19 @@ static Property omap_gpio_properties[] = {
 
 static void omap_gpio_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = omap_gpio_init;
+    dc->reset = omap_gpif_reset;
+    dc->props = omap_gpio_properties;
 }
 
-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 TypeInfo omap_gpio_info = {
+    .name          = "omap-gpio",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(struct omap_gpif_s),
+    .class_init    = omap_gpio_class_init,
 };
 
 static Property omap2_gpio_properties[] = {
@@ -766,23 +768,25 @@ static Property omap2_gpio_properties[] = {
 
 static void omap2_gpio_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = omap2_gpio_init;
+    dc->reset = omap2_gpif_reset;
+    dc->props = omap2_gpio_properties;
 }
 
-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 TypeInfo omap2_gpio_info = {
+    .name          = "omap2-gpio",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(struct omap2_gpif_s),
+    .class_init    = omap2_gpio_class_init,
 };
 
 static void omap_gpio_register_device(void)
 {
-    sysbus_register_withprop(&omap_gpio_info);
-    sysbus_register_withprop(&omap2_gpio_info);
+    type_register_static(&omap_gpio_info);
+    type_register_static(&omap2_gpio_info);
 }
 
 device_init(omap_gpio_register_device)
diff --git a/hw/omap_intc.c b/hw/omap_intc.c
index 310fe2d..5aa98a8 100644
--- a/hw/omap_intc.c
+++ b/hw/omap_intc.c
@@ -381,17 +381,19 @@ static Property omap_intc_properties[] = {
 
 static void omap_intc_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = omap_intc_init;
+    dc->reset = omap_inth_reset;
+    dc->props = omap_intc_properties;
 }
 
-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 TypeInfo omap_intc_info = {
+    .name          = "omap-intc",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(struct omap_intr_handler_s),
+    .class_init    = omap_intc_class_init,
 };
 
 static uint64_t omap2_inth_read(void *opaque, target_phys_addr_t addr,
@@ -623,23 +625,25 @@ static Property omap2_intc_properties[] = {
 
 static void omap2_intc_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = omap2_intc_init;
+    dc->reset = omap_inth_reset;
+    dc->props = omap2_intc_properties;
 }
 
-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 TypeInfo omap2_intc_info = {
+    .name          = "omap2-intc",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(struct omap_intr_handler_s),
+    .class_init    = omap2_intc_class_init,
 };
 
 static void omap_intc_register_device(void)
 {
-    sysbus_register_withprop(&omap_intc_info);
-    sysbus_register_withprop(&omap2_intc_info);
+    type_register_static(&omap_intc_info);
+    type_register_static(&omap2_intc_info);
 }
 
 device_init(omap_intc_register_device)
diff --git a/hw/onenand.c b/hw/onenand.c
index e20d4d9..8744b04 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -813,22 +813,24 @@ static Property onenand_properties[] = {
 
 static void onenand_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = onenand_initfn;
+    dc->reset = onenand_system_reset;
+    dc->props = onenand_properties;
 }
 
-static DeviceInfo onenand_info = {
-    .name = "onenand",
-    .size = sizeof(OneNANDState),
-    .reset = onenand_system_reset,
-    .props = onenand_properties,
-    .class_init = onenand_class_init,
+static TypeInfo onenand_info = {
+    .name          = "onenand",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(OneNANDState),
+    .class_init    = onenand_class_init,
 };
 
 static void onenand_register_device(void)
 {
-    sysbus_register_withprop(&onenand_info);
+    type_register_static(&onenand_info);
 }
 
 void *onenand_raw_otp(DeviceState *onenand_device)
diff --git a/hw/opencores_eth.c b/hw/opencores_eth.c
index 1f45506..09f2757 100644
--- a/hw/opencores_eth.c
+++ b/hw/opencores_eth.c
@@ -734,23 +734,25 @@ static Property open_eth_properties[] = {
 
 static void open_eth_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = sysbus_open_eth_init;
+    dc->desc = "Opencores 10/100 Mbit Ethernet";
+    dc->reset = qdev_open_eth_reset;
+    dc->props = open_eth_properties;
 }
 
-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 TypeInfo open_eth_info = {
+    .name          = "open_eth",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(OpenEthState),
+    .class_init    = open_eth_class_init,
 };
 
 static void open_eth_register_devices(void)
 {
-    sysbus_register_withprop(&open_eth_info);
+    type_register_static(&open_eth_info);
 }
 
 device_init(open_eth_register_devices)
diff --git a/hw/parallel.c b/hw/parallel.c
index cadcffb..484d727 100644
--- a/hw/parallel.c
+++ b/hw/parallel.c
@@ -583,28 +583,32 @@ bool parallel_mm_init(MemoryRegion *address_space,
     return true;
 }
 
+static Property parallel_isa_properties[] = {
+    DEFINE_PROP_UINT32("index", ISAParallelState, index,   -1),
+    DEFINE_PROP_HEX32("iobase", ISAParallelState, iobase,  -1),
+    DEFINE_PROP_UINT32("irq",   ISAParallelState, isairq,  7),
+    DEFINE_PROP_CHR("chardev",  ISAParallelState, state.chr),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void parallel_isa_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = parallel_isa_initfn;
+    dc->props = parallel_isa_properties;
 }
 
-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),
-        DEFINE_PROP_CHR("chardev",  ISAParallelState, state.chr),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static TypeInfo parallel_isa_info = {
+    .name          = "isa-parallel",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(ISAParallelState),
+    .class_init    = parallel_isa_class_initfn,
 };
 
 static void parallel_register_devices(void)
 {
-    isa_qdev_register(&parallel_isa_info);
+    type_register_static(&parallel_isa_info);
 }
 
 device_init(parallel_register_devices)
diff --git a/hw/pc.c b/hw/pc.c
index 31608d3..7f3aa65 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -499,22 +499,24 @@ static int port92_initfn(ISADevice *dev)
 
 static void port92_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = port92_initfn;
+    dc->no_user = 1;
+    dc->reset = port92_reset;
+    dc->vmsd = &vmstate_port92_isa;
 }
 
-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 TypeInfo port92_info = {
+    .name          = "port92",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(Port92State),
+    .class_init    = port92_class_initfn,
 };
 
 static void port92_register(void)
 {
-    isa_qdev_register(&port92_info);
+    type_register_static(&port92_info);
 }
 device_init(port92_register)
 
diff --git a/hw/pci.c b/hw/pci.c
index 43dc1fb..8fd450c 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1521,17 +1521,6 @@ static int pci_unplug_device(DeviceState *qdev)
                              PCI_HOTPLUG_DISABLED);
 }
 
-void pci_qdev_register(DeviceInfo *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,
                                     const char *name)
 {
@@ -1995,12 +1984,22 @@ MemoryRegion *pci_address_space_io(PCIDevice *dev)
     return dev->bus->address_space_io;
 }
 
+static void pci_device_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *k = DEVICE_CLASS(klass);
+    k->init = pci_qdev_init;
+    k->unplug = pci_unplug_device;
+    k->exit = pci_unregister_device;
+    k->bus_info = &pci_bus_info;
+}
+
 static TypeInfo pci_device_type_info = {
     .name = TYPE_PCI_DEVICE,
     .parent = TYPE_DEVICE,
     .instance_size = sizeof(PCIDevice),
     .abstract = true,
     .class_size = sizeof(PCIDeviceClass),
+    .class_init = pci_device_class_init,
 };
 
 static void pci_register_devices(void)
diff --git a/hw/pci.h b/hw/pci.h
index 09b2324..33b0b18 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -464,8 +464,6 @@ pci_quad_test_and_set_mask(uint8_t *config, uint64_t mask)
     return val & mask;
 }
 
-void pci_qdev_register(DeviceInfo *info);
-
 PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction,
                                     const char *name);
 PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,
diff --git a/hw/pckbd.c b/hw/pckbd.c
index 2ebe1c5..b4c53be 100644
--- a/hw/pckbd.c
+++ b/hw/pckbd.c
@@ -499,20 +499,22 @@ static int i8042_initfn(ISADevice *dev)
 
 static void i8042_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = i8042_initfn;
+    dc->no_user = 1;
+    dc->vmsd = &vmstate_kbd_isa;
 }
 
-static DeviceInfo i8042_info = {
-    .name     = "i8042",
-    .size     = sizeof(ISAKBDState),
-    .vmsd     = &vmstate_kbd_isa,
-    .no_user  = 1,
-    .class_init          = i8042_class_initfn,
+static TypeInfo i8042_info = {
+    .name          = "i8042",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(ISAKBDState),
+    .class_init    = i8042_class_initfn,
 };
 
 static void i8042_register(void)
 {
-    isa_qdev_register(&i8042_info);
+    type_register_static(&i8042_info);
 }
 device_init(i8042_register)
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index be3bd79..439f32c 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -355,6 +355,7 @@ static Property pcnet_properties[] = {
 
 static void pcnet_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = pci_pcnet_init;
@@ -363,20 +364,21 @@ static void pcnet_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_AMD_LANCE;
     k->revision = 0x10;
     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+    dc->reset = pci_reset;
+    dc->vmsd = &vmstate_pci_pcnet;
+    dc->props = pcnet_properties;
 }
 
-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 TypeInfo pcnet_info = {
+    .name          = "pcnet",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIPCNetState),
+    .class_init    = pcnet_class_init,
 };
 
 static void pci_pcnet_register_devices(void)
 {
-    pci_qdev_register(&pcnet_info);
+    type_register_static(&pcnet_info);
 }
 
 device_init(pci_pcnet_register_devices)
diff --git a/hw/piix4.c b/hw/piix4.c
index 88be535..4e7a237 100644
--- a/hw/piix4.c
+++ b/hw/piix4.c
@@ -104,6 +104,7 @@ int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn)
 
 static void piix4_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->no_hotplug = 1;
@@ -111,19 +112,20 @@ static void piix4_class_init(ObjectClass *klass, void *data)
     k->vendor_id = PCI_VENDOR_ID_INTEL;
     k->device_id = PCI_DEVICE_ID_INTEL_82371AB_0;
     k->class_id = PCI_CLASS_BRIDGE_ISA;
+    dc->desc = "ISA bridge";
+    dc->no_user = 1;
+    dc->vmsd = &vmstate_piix4;
 }
 
-static DeviceInfo piix4_info = {
-    .name = "PIIX4",
-    .desc = "ISA bridge",
-    .size = sizeof(PIIX4State),
-    .vmsd = &vmstate_piix4,
-    .no_user = 1,
-    .class_init = piix4_class_init,
+static TypeInfo piix4_info = {
+    .name          = "PIIX4",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PIIX4State),
+    .class_init    = piix4_class_init,
 };
 
 static void piix4_register(void)
 {
-    pci_qdev_register(&piix4_info);
+    type_register_static(&piix4_info);
 }
 device_init(piix4_register);
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 8b01782..2bbfa4a 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -504,8 +504,12 @@ static int piix3_initfn(PCIDevice *dev)
 
 static void piix3_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
+    dc->desc        = "ISA bridge";
+    dc->vmsd        = &vmstate_piix3;
+    dc->no_user     = 1,
     k->no_hotplug   = 1;
     k->init         = piix3_initfn;
     k->config_write = piix3_write_config;
@@ -514,19 +518,21 @@ static void piix3_class_init(ObjectClass *klass, void *data)
     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 TypeInfo piix3_info = {
+    .name          = "PIIX3",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PIIX3State),
+    .class_init    = piix3_class_init,
 };
 
 static void piix3_xen_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
+    dc->desc        = "ISA bridge";
+    dc->vmsd        = &vmstate_piix3;
+    dc->no_user     = 1;
     k->no_hotplug   = 1;
     k->init         = piix3_initfn;
     k->config_write = piix3_write_config_xen;
@@ -535,17 +541,16 @@ static void piix3_xen_class_init(ObjectClass *klass, void *data)
     k->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 TypeInfo piix3_xen_info = {
+    .name          = "PIIX3-xen",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PIIX3State),
+    .class_init    = piix3_xen_class_init,
 };
 
 static void i440fx_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->no_hotplug = 1;
@@ -555,37 +560,40 @@ static void i440fx_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_INTEL_82441;
     k->revision = 0x02;
     k->class_id = PCI_CLASS_BRIDGE_HOST;
+    dc->desc = "Host bridge";
+    dc->no_user = 1;
+    dc->vmsd = &vmstate_i440fx;
 }
 
-static DeviceInfo i440fx_info = {
-    .name = "i440FX",
-    .desc = "Host bridge",
-    .size = sizeof(PCII440FXState),
-    .vmsd = &vmstate_i440fx,
-    .no_user = 1,
-    .class_init = i440fx_class_init,
+static TypeInfo i440fx_info = {
+    .name          = "i440FX",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCII440FXState),
+    .class_init    = i440fx_class_init,
 };
 
 static void i440fx_pcihost_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = i440fx_pcihost_initfn;
+    dc->fw_name = "pci";
+    dc->no_user = 1;
 }
 
-static DeviceInfo i440fx_pcihost_info = {
-    .name = "i440FX-pcihost",
-    .fw_name = "pci",
-    .size = sizeof(I440FXState),
-    .no_user = 1,
-    .class_init = i440fx_pcihost_class_init,
+static TypeInfo i440fx_pcihost_info = {
+    .name          = "i440FX-pcihost",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(I440FXState),
+    .class_init    = i440fx_pcihost_class_init,
 };
 
 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);
+    type_register_static(&i440fx_info);
+    type_register_static(&piix3_info);
+    type_register_static(&piix3_xen_info);
+    type_register_static(&i440fx_pcihost_info);
 }
 device_init(i440fx_register);
diff --git a/hw/pl011.c b/hw/pl011.c
index 088aa44..8db2248 100644
--- a/hw/pl011.c
+++ b/hw/pl011.c
@@ -295,10 +295,11 @@ static void pl011_arm_class_init(ObjectClass *klass, void *data)
     sdc->init = pl011_arm_init;
 }
 
-static DeviceInfo pl011_arm_info = {
-    .name = "pl011",
-    .size = sizeof(pl011_state),
-    .class_init = pl011_arm_class_init,
+static TypeInfo pl011_arm_info = {
+    .name          = "pl011",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl011_state),
+    .class_init    = pl011_arm_class_init,
 };
 
 static void pl011_luminary_class_init(ObjectClass *klass, void *data)
@@ -308,16 +309,17 @@ static void pl011_luminary_class_init(ObjectClass *klass, void *data)
     sdc->init = pl011_luminary_init;
 }
 
-static DeviceInfo pl011_luminary_info = {
-    .name = "pl011_luminary",
-    .size = sizeof(pl011_state),
-    .class_init = pl011_luminary_class_init,
+static TypeInfo pl011_luminary_info = {
+    .name          = "pl011_luminary",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl011_state),
+    .class_init    = pl011_luminary_class_init,
 };
 
 static void pl011_register_devices(void)
 {
-    sysbus_qdev_register(&pl011_arm_info);
-    sysbus_qdev_register(&pl011_luminary_info);
+    type_register_static(&pl011_arm_info);
+    type_register_static(&pl011_luminary_info);
 }
 
 device_init(pl011_register_devices)
diff --git a/hw/pl022.c b/hw/pl022.c
index 4f62712..30bd344 100644
--- a/hw/pl022.c
+++ b/hw/pl022.c
@@ -292,15 +292,16 @@ static void pl022_class_init(ObjectClass *klass, void *data)
     sdc->init = pl022_init;
 }
 
-static DeviceInfo pl022_info = {
-    .name = "pl022",
-    .size = sizeof(pl022_state),
-    .class_init = pl022_class_init,
+static TypeInfo pl022_info = {
+    .name          = "pl022",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl022_state),
+    .class_init    = pl022_class_init,
 };
 
 static void pl022_register_devices(void)
 {
-    sysbus_qdev_register(&pl022_info);
+    type_register_static(&pl022_info);
 }
 
 device_init(pl022_register_devices)
diff --git a/hw/pl031.c b/hw/pl031.c
index 4cb8528..8416a60 100644
--- a/hw/pl031.c
+++ b/hw/pl031.c
@@ -215,22 +215,24 @@ static int pl031_init(SysBusDevice *dev)
 
 static void pl031_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pl031_init;
+    dc->no_user = 1;
+    dc->vmsd = &vmstate_pl031;
 }
 
-static DeviceInfo pl031_info = {
-    .name = "pl031",
-    .size = sizeof(pl031_state),
-    .vmsd = &vmstate_pl031,
-    .no_user = 1,
-    .class_init = pl031_class_init,
+static TypeInfo pl031_info = {
+    .name          = "pl031",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl031_state),
+    .class_init    = pl031_class_init,
 };
 
 static void pl031_register_devices(void)
 {
-    sysbus_register_withprop(&pl031_info);
+    type_register_static(&pl031_info);
 }
 
 device_init(pl031_register_devices)
diff --git a/hw/pl041.c b/hw/pl041.c
index 0482851..6d99c9c 100644
--- a/hw/pl041.c
+++ b/hw/pl041.c
@@ -621,24 +621,26 @@ static Property pl041_device_properties[] = {
 
 static void pl041_device_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pl041_init;
+    dc->no_user = 1;
+    dc->reset = pl041_device_reset;
+    dc->vmsd = &vmstate_pl041;
+    dc->props = pl041_device_properties;
 }
 
-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 TypeInfo pl041_device_info = {
+    .name          = "pl041",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl041_state),
+    .class_init    = pl041_device_class_init,
 };
 
 static void pl041_register_device(void)
 {
-    sysbus_register_withprop(&pl041_device_info);
+    type_register_static(&pl041_device_info);
 }
 
 device_init(pl041_register_device)
diff --git a/hw/pl050.c b/hw/pl050.c
index 5f60508..b0094ac 100644
--- a/hw/pl050.c
+++ b/hw/pl050.c
@@ -159,36 +159,40 @@ static int pl050_init_mouse(SysBusDevice *dev)
 
 static void pl050_kbd_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pl050_init_keyboard;
+    dc->vmsd = &vmstate_pl050;
 }
 
-static DeviceInfo pl050_kbd_info = {
-    .name = "pl050_keyboard",
-    .size = sizeof(pl050_state),
-    .vmsd = &vmstate_pl050,
-    .class_init = pl050_kbd_class_init,
+static TypeInfo pl050_kbd_info = {
+    .name          = "pl050_keyboard",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl050_state),
+    .class_init    = pl050_kbd_class_init,
 };
 
 static void pl050_mouse_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pl050_init_mouse;
+    dc->vmsd = &vmstate_pl050;
 }
 
-static DeviceInfo pl050_mouse_info = {
-    .name = "pl050_mouse",
-    .size = sizeof(pl050_state),
-    .vmsd = &vmstate_pl050,
-    .class_init = pl050_mouse_class_init,
+static TypeInfo pl050_mouse_info = {
+    .name          = "pl050_mouse",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl050_state),
+    .class_init    = pl050_mouse_class_init,
 };
 
 static void pl050_register_devices(void)
 {
-    sysbus_register_withprop(&pl050_kbd_info);
-    sysbus_register_withprop(&pl050_mouse_info);
+    type_register_static(&pl050_kbd_info);
+    type_register_static(&pl050_mouse_info);
 }
 
 device_init(pl050_register_devices)
diff --git a/hw/pl061.c b/hw/pl061.c
index 9dc9406..3136c99 100644
--- a/hw/pl061.c
+++ b/hw/pl061.c
@@ -295,36 +295,40 @@ static int pl061_init_arm(SysBusDevice *dev)
 
 static void pl061_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pl061_init_arm;
+    dc->vmsd = &vmstate_pl061;
 }
 
-static DeviceInfo pl061_info = {
-    .name = "pl061",
-    .size = sizeof(pl061_state),
-    .vmsd = &vmstate_pl061,
-    .class_init = pl061_class_init,
+static TypeInfo pl061_info = {
+    .name          = "pl061",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl061_state),
+    .class_init    = pl061_class_init,
 };
 
 static void pl061_luminary_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pl061_init_luminary;
+    dc->vmsd = &vmstate_pl061;
 }
 
-static DeviceInfo pl061_luminary_info = {
-    .name = "pl061_luminary",
-    .size = sizeof(pl061_state),
-    .vmsd = &vmstate_pl061,
-    .class_init = pl061_luminary_class_init,
+static TypeInfo pl061_luminary_info = {
+    .name          = "pl061_luminary",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl061_state),
+    .class_init    = pl061_luminary_class_init,
 };
 
 static void pl061_register_devices(void)
 {
-    sysbus_register_withprop(&pl061_info);
-    sysbus_register_withprop(&pl061_luminary_info);
+    type_register_static(&pl061_info);
+    type_register_static(&pl061_luminary_info);
 }
 
 device_init(pl061_register_devices)
diff --git a/hw/pl080.c b/hw/pl080.c
index 727bfa1..4405d18 100644
--- a/hw/pl080.c
+++ b/hw/pl080.c
@@ -375,40 +375,44 @@ static int pl081_init(SysBusDevice *dev)
 
 static void pl080_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pl080_init;
+    dc->no_user = 1;
+    dc->vmsd = &vmstate_pl080;
 }
 
-static DeviceInfo pl080_info = {
-    .name = "pl080",
-    .size = sizeof(pl080_state),
-    .vmsd = &vmstate_pl080,
-    .no_user = 1,
-    .class_init = pl080_class_init,
+static TypeInfo pl080_info = {
+    .name          = "pl080",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl080_state),
+    .class_init    = pl080_class_init,
 };
 
 static void pl081_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pl081_init;
+    dc->no_user = 1;
+    dc->vmsd = &vmstate_pl080;
 }
 
-static DeviceInfo pl081_info = {
-    .name = "pl081",
-    .size = sizeof(pl080_state),
-    .vmsd = &vmstate_pl080,
-    .no_user = 1,
-    .class_init = pl081_class_init,
+static TypeInfo pl081_info = {
+    .name          = "pl081",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl080_state),
+    .class_init    = pl081_class_init,
 };
 
 /* The PL080 and PL081 are the same except for the number of channels
    they implement (8 and 2 respectively).  */
 static void pl080_register_devices(void)
 {
-    sysbus_register_withprop(&pl080_info);
-    sysbus_register_withprop(&pl081_info);
+    type_register_static(&pl080_info);
+    type_register_static(&pl081_info);
 }
 
 device_init(pl080_register_devices)
diff --git a/hw/pl110.c b/hw/pl110.c
index 58fb9d3..86e95a3 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -471,54 +471,60 @@ static int pl111_init(SysBusDevice *dev)
 
 static void pl110_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pl110_init;
+    dc->no_user = 1;
+    dc->vmsd = &vmstate_pl110;
 }
 
-static DeviceInfo pl110_info = {
-    .name = "pl110",
-    .size = sizeof(pl110_state),
-    .vmsd = &vmstate_pl110,
-    .no_user = 1,
-    .class_init = pl110_class_init,
+static TypeInfo pl110_info = {
+    .name          = "pl110",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl110_state),
+    .class_init    = pl110_class_init,
 };
 
 static void pl110_versatile_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pl110_versatile_init;
+    dc->no_user = 1;
+    dc->vmsd = &vmstate_pl110;
 }
 
-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 TypeInfo pl110_versatile_info = {
+    .name          = "pl110_versatile",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl110_state),
+    .class_init    = pl110_versatile_class_init,
 };
 
 static void pl111_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pl111_init;
+    dc->no_user = 1;
+    dc->vmsd = &vmstate_pl110;
 }
 
-static DeviceInfo pl111_info = {
-    .name = "pl111",
-    .size = sizeof(pl110_state),
-    .vmsd = &vmstate_pl110,
-    .no_user = 1,
-    .class_init = pl111_class_init,
+static TypeInfo pl111_info = {
+    .name          = "pl111",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl110_state),
+    .class_init    = pl111_class_init,
 };
 
 static void pl110_register_devices(void)
 {
-    sysbus_register_withprop(&pl110_info);
-    sysbus_register_withprop(&pl110_versatile_info);
-    sysbus_register_withprop(&pl111_info);
+    type_register_static(&pl110_info);
+    type_register_static(&pl110_versatile_info);
+    type_register_static(&pl111_info);
 }
 
 device_init(pl110_register_devices)
diff --git a/hw/pl181.c b/hw/pl181.c
index 973d3fc..ae636e2 100644
--- a/hw/pl181.c
+++ b/hw/pl181.c
@@ -490,22 +490,24 @@ static int pl181_init(SysBusDevice *dev)
 static void pl181_class_init(ObjectClass *klass, void *data)
 {
     SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *k = DEVICE_CLASS(klass);
 
     sdc->init = pl181_init;
+    k->vmsd = &vmstate_pl181;
+    k->reset = pl181_reset;
+    k->no_user = 1;
 }
 
-static DeviceInfo pl181_info = {
-    .name = "pl181",
-    .size = sizeof(pl181_state),
-    .class_init = pl181_class_init,
-    .vmsd = &vmstate_pl181,
-    .reset = pl181_reset,
-    .no_user = 1,
+static TypeInfo pl181_info = {
+    .name          = "pl181",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl181_state),
+    .class_init    = pl181_class_init,
 };
 
 static void pl181_register_devices(void)
 {
-    sysbus_qdev_register(&pl181_info);
+    type_register_static(&pl181_info);
 }
 
 device_init(pl181_register_devices)
diff --git a/hw/pl190.c b/hw/pl190.c
index 79322aa..956ab21 100644
--- a/hw/pl190.c
+++ b/hw/pl190.c
@@ -257,23 +257,25 @@ static const VMStateDescription vmstate_pl190 = {
 
 static void pl190_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pl190_init;
+    dc->no_user = 1;
+    dc->reset = pl190_reset;
+    dc->vmsd = &vmstate_pl190;
 }
 
-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 TypeInfo pl190_info = {
+    .name          = "pl190",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(pl190_state),
+    .class_init    = pl190_class_init,
 };
 
 static void pl190_register_devices(void)
 {
-    sysbus_register_withprop(&pl190_info);
+    type_register_static(&pl190_info);
 }
 
 device_init(pl190_register_devices)
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index 36fb9f9..d11f120 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -369,36 +369,40 @@ static int ppc4xx_pcihost_initfn(SysBusDevice *dev)
 static void ppc4xx_host_bridge_class_init(ObjectClass *klass, void *data)
 {
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
+    dc->desc        = "Host bridge";
     k->vendor_id    = PCI_VENDOR_ID_IBM;
     k->device_id    = PCI_DEVICE_ID_IBM_440GX;
     k->class_id     = PCI_CLASS_BRIDGE_OTHER;
 }
 
-static DeviceInfo ppc4xx_host_bridge_info = {
-    .name    = "ppc4xx-host-bridge",
-    .desc    = "Host bridge",
-    .size    = sizeof(PCIDevice),
-    .class_init = ppc4xx_host_bridge_class_init,
+static TypeInfo ppc4xx_host_bridge_info = {
+    .name          = "ppc4xx-host-bridge",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
+    .class_init    = ppc4xx_host_bridge_class_init,
 };
 
 static void ppc4xx_pcihost_class_init(ObjectClass *klass, void *data)
 {
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     k->init = ppc4xx_pcihost_initfn;
+    dc->vmsd = &vmstate_ppc4xx_pci;
 }
 
-static DeviceInfo ppc4xx_pcihost_info = {
-    .name    = "ppc4xx-pcihost",
-    .size    = sizeof(PPC4xxPCIState),
-    .vmsd    = &vmstate_ppc4xx_pci,
-    .class_init = ppc4xx_pcihost_class_init,
+static TypeInfo ppc4xx_pcihost_info = {
+    .name          = "ppc4xx-pcihost",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PPC4xxPCIState),
+    .class_init    = ppc4xx_pcihost_class_init,
 };
 
 static void ppc4xx_pci_register(void)
 {
-    sysbus_register_withprop(&ppc4xx_pcihost_info);
-    pci_qdev_register(&ppc4xx_host_bridge_info);
+    type_register_static(&ppc4xx_pcihost_info);
+    type_register_static(&ppc4xx_host_bridge_info);
 }
 device_init(ppc4xx_pci_register);
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 438a75d..eb43fb5 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -610,7 +610,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
     pcihost = DO_UPCAST(PCIHostState, busdev, sys);
     pcihost->address_space = get_system_memory();
     qdev_init_nofail(dev);
-    qdev_property_add_child(qdev_get_root(), "raven", dev, NULL);
+    object_property_add_child(object_get_root(), "raven", OBJECT(dev), NULL);
     pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
     if (pci_bus == NULL) {
         fprintf(stderr, "Couldn't create PCI host controller.\n");
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index f8c4f11..d5bce71 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -341,37 +341,41 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
 
 static void e500_host_bridge_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     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;
+    dc->desc = "Host bridge";
 }
 
-static DeviceInfo e500_host_bridge_info = {
-    .name = "e500-host-bridge",
-    .desc = "Host bridge",
-    .size = sizeof(PCIDevice),
-    .class_init = e500_host_bridge_class_init,
+static TypeInfo e500_host_bridge_info = {
+    .name          = "e500-host-bridge",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
+    .class_init    = e500_host_bridge_class_init,
 };
 
 static void e500_pcihost_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = e500_pcihost_initfn;
+    dc->vmsd = &vmstate_ppce500_pci;
 }
 
-static DeviceInfo e500_pcihost_info = {
-    .name = "e500-pcihost",
-    .size = sizeof(PPCE500PCIState),
-    .vmsd = &vmstate_ppce500_pci,
-    .class_init = e500_pcihost_class_init,
+static TypeInfo e500_pcihost_info = {
+    .name          = "e500-pcihost",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PPCE500PCIState),
+    .class_init    = e500_pcihost_class_init,
 };
 
 static void e500_pci_register(void)
 {
-    sysbus_register_withprop(&e500_pcihost_info);
-    pci_qdev_register(&e500_host_bridge_info);
+    type_register_static(&e500_pcihost_info);
+    type_register_static(&e500_host_bridge_info);
 }
 device_init(e500_pci_register);
diff --git a/hw/ppce500_spin.c b/hw/ppce500_spin.c
index cb5bc97..9d648ec 100644
--- a/hw/ppce500_spin.c
+++ b/hw/ppce500_spin.c
@@ -210,14 +210,15 @@ static void ppce500_spin_class_init(ObjectClass *klass, void *data)
     k->init = ppce500_spin_initfn;
 }
 
-static DeviceInfo ppce500_spin_info = {
-    .name = "e500-spin",
-    .size = sizeof(SpinState),
-    .class_init = ppce500_spin_class_init,
+static TypeInfo ppce500_spin_info = {
+    .name          = "e500-spin",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SpinState),
+    .class_init    = ppce500_spin_class_init,
 };
 
 static void ppce500_spin_register(void)
 {
-    sysbus_register_withprop(&ppce500_spin_info);
+    type_register_static(&ppce500_spin_info);
 }
 device_init(ppce500_spin_register);
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index b3b85b7..40b8bb0 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -137,42 +137,46 @@ static const VMStateDescription vmstate_raven = {
 static void raven_class_init(ObjectClass *klass, void *data)
 {
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     k->init = raven_init;
     k->vendor_id = PCI_VENDOR_ID_MOTOROLA;
     k->device_id = PCI_DEVICE_ID_MOTOROLA_RAVEN;
     k->revision = 0x00;
     k->class_id = PCI_CLASS_BRIDGE_HOST;
+    dc->desc = "PReP Host Bridge - Motorola Raven";
+    dc->vmsd = &vmstate_raven;
+    dc->no_user = 1;
 }
 
-static DeviceInfo raven_info = {
+static TypeInfo raven_info = {
     .name = "raven",
-    .desc = "PReP Host Bridge - Motorola Raven",
-    .size = sizeof(RavenPCIState),
-    .vmsd = &vmstate_raven,
-    .no_user = 1,
+    .parent = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(RavenPCIState),
     .class_init = raven_class_init,
 };
 
 static void raven_pcihost_class_init(ObjectClass *klass, void *data)
 {
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     k->init = raven_pcihost_init;
+    dc->fw_name = "pci";
+    dc->no_user = 1;
 }
 
-static DeviceInfo raven_pcihost_info = {
+static TypeInfo raven_pcihost_info = {
     .name = "raven-pcihost",
-    .fw_name = "pci",
-    .size = sizeof(PREPPCIState),
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PREPPCIState),
     .class_init = raven_pcihost_class_init,
-    .no_user = 1,
 };
 
 static void raven_register_devices(void)
 {
-    sysbus_register_withprop(&raven_pcihost_info);
-    pci_qdev_register(&raven_info);
+    type_register_static(&raven_pcihost_info);
+    type_register_static(&raven_info);
 }
 
 device_init(raven_register_devices)
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index fbc397f..244c614 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -1235,17 +1235,19 @@ static const VMStateDescription vmstate_pxa2xx_rtc_regs = {
 
 static void pxa2xx_rtc_sysbus_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pxa2xx_rtc_init;
+    dc->desc = "PXA2xx RTC Controller";
+    dc->vmsd = &vmstate_pxa2xx_rtc_regs;
 }
 
-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,
+static TypeInfo pxa2xx_rtc_sysbus_info = {
+    .name          = "pxa2xx_rtc",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PXA2xxRTCState),
+    .class_init    = pxa2xx_rtc_sysbus_class_init,
 };
 
 /* I2C Interface */
@@ -1489,10 +1491,11 @@ static void pxa2xx_i2c_slave_class_init(ObjectClass *klass, void *data)
     k->send = pxa2xx_i2c_tx;
 }
 
-static DeviceInfo pxa2xx_i2c_slave_info = {
-    .name = "pxa2xx-i2c-slave",
-    .size = sizeof(PXA2xxI2CSlaveState),
-    .class_init = pxa2xx_i2c_slave_class_init,
+static TypeInfo pxa2xx_i2c_slave_info = {
+    .name          = "pxa2xx-i2c-slave",
+    .parent        = TYPE_I2C_SLAVE,
+    .instance_size = sizeof(PXA2xxI2CSlaveState),
+    .class_init    = pxa2xx_i2c_slave_class_init,
 };
 
 PXA2xxI2CState *pxa2xx_i2c_init(target_phys_addr_t base,
@@ -1548,18 +1551,20 @@ static Property pxa2xx_i2c_properties[] = {
 
 static void pxa2xx_i2c_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pxa2xx_i2c_initfn;
+    dc->desc = "PXA2xx I2C Bus Controller";
+    dc->vmsd = &vmstate_pxa2xx_i2c;
+    dc->props = pxa2xx_i2c_properties;
 }
 
-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,
+static TypeInfo pxa2xx_i2c_info = {
+    .name          = "pxa2xx_i2c",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PXA2xxI2CState),
+    .class_init    = pxa2xx_i2c_class_init,
 };
 
 /* PXA Inter-IC Sound Controller */
@@ -2318,18 +2323,19 @@ static void pxa2xx_ssp_class_init(ObjectClass *klass, void *data)
     sdc->init = pxa2xx_ssp_init;
 }
 
-static DeviceInfo pxa2xx_ssp_info = {
-    .name = "pxa2xx-ssp",
-    .size = sizeof(PXA2xxSSPState),
-    .class_init = pxa2xx_ssp_class_init,
+static TypeInfo pxa2xx_ssp_info = {
+    .name          = "pxa2xx-ssp",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PXA2xxSSPState),
+    .class_init    = pxa2xx_ssp_class_init,
 };
 
 static void pxa2xx_register_devices(void)
 {
-    i2c_register_slave(&pxa2xx_i2c_slave_info);
-    sysbus_qdev_register(&pxa2xx_ssp_info);
-    sysbus_register_withprop(&pxa2xx_i2c_info);
-    sysbus_register_withprop(&pxa2xx_rtc_sysbus_info);
+    type_register_static(&pxa2xx_i2c_slave_info);
+    type_register_static(&pxa2xx_ssp_info);
+    type_register_static(&pxa2xx_i2c_info);
+    type_register_static(&pxa2xx_rtc_sysbus_info);
 }
 
 device_init(pxa2xx_register_devices)
diff --git a/hw/pxa2xx_dma.c b/hw/pxa2xx_dma.c
index 9ecec33..2d61565 100644
--- a/hw/pxa2xx_dma.c
+++ b/hw/pxa2xx_dma.c
@@ -550,22 +550,24 @@ static Property pxa2xx_dma_properties[] = {
 
 static void pxa2xx_dma_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pxa2xx_dma_init;
+    dc->desc = "PXA2xx DMA controller";
+    dc->vmsd = &vmstate_pxa2xx_dma;
+    dc->props = pxa2xx_dma_properties;
 }
 
-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 TypeInfo pxa2xx_dma_info = {
+    .name          = "pxa2xx-dma",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PXA2xxDMAState),
+    .class_init    = pxa2xx_dma_class_init,
 };
 
 static void pxa2xx_dma_register(void)
 {
-    sysbus_register_withprop(&pxa2xx_dma_info);
+    type_register_static(&pxa2xx_dma_info);
 }
 device_init(pxa2xx_dma_register);
diff --git a/hw/pxa2xx_gpio.c b/hw/pxa2xx_gpio.c
index 7a1333f..67fd17c 100644
--- a/hw/pxa2xx_gpio.c
+++ b/hw/pxa2xx_gpio.c
@@ -325,21 +325,23 @@ static Property pxa2xx_gpio_properties[] = {
 
 static void pxa2xx_gpio_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pxa2xx_gpio_initfn;
+    dc->desc = "PXA2xx GPIO controller";
+    dc->props = pxa2xx_gpio_properties;
 }
 
-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 TypeInfo pxa2xx_gpio_info = {
+    .name          = "pxa2xx-gpio",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PXA2xxGPIOInfo),
+    .class_init    = pxa2xx_gpio_class_init,
 };
 
 static void pxa2xx_gpio_register(void)
 {
-    sysbus_register_withprop(&pxa2xx_gpio_info);
+    type_register_static(&pxa2xx_gpio_info);
 }
 device_init(pxa2xx_gpio_register);
diff --git a/hw/pxa2xx_pic.c b/hw/pxa2xx_pic.c
index d318e83..ca85743 100644
--- a/hw/pxa2xx_pic.c
+++ b/hw/pxa2xx_pic.c
@@ -298,21 +298,23 @@ static int pxa2xx_pic_initfn(SysBusDevice *dev)
 
 static void pxa2xx_pic_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pxa2xx_pic_initfn;
+    dc->desc = "PXA2xx PIC";
+    dc->vmsd = &vmstate_pxa2xx_pic_regs;
 }
 
-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 TypeInfo pxa2xx_pic_info = {
+    .name          = "pxa2xx_pic",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PXA2xxPICState),
+    .class_init    = pxa2xx_pic_class_init,
 };
 
 static void pxa2xx_pic_register(void)
 {
-    sysbus_register_withprop(&pxa2xx_pic_info);
+    type_register_static(&pxa2xx_pic_info);
 }
 device_init(pxa2xx_pic_register);
diff --git a/hw/pxa2xx_timer.c b/hw/pxa2xx_timer.c
index cd78d41..9080075 100644
--- a/hw/pxa2xx_timer.c
+++ b/hw/pxa2xx_timer.c
@@ -486,18 +486,20 @@ static Property pxa25x_timer_dev_properties[] = {
 
 static void pxa25x_timer_dev_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pxa2xx_timer_init;
+    dc->desc = "PXA25x timer";
+    dc->vmsd = &vmstate_pxa2xx_timer_regs;
+    dc->props = pxa25x_timer_dev_properties;
 }
 
-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 TypeInfo pxa25x_timer_dev_info = {
+    .name          = "pxa25x-timer",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PXA2xxTimerInfo),
+    .class_init    = pxa25x_timer_dev_class_init,
 };
 
 static Property pxa27x_timer_dev_properties[] = {
@@ -509,23 +511,25 @@ static Property pxa27x_timer_dev_properties[] = {
 
 static void pxa27x_timer_dev_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = pxa2xx_timer_init;
+    dc->desc = "PXA27x timer";
+    dc->vmsd = &vmstate_pxa2xx_timer_regs;
+    dc->props = pxa27x_timer_dev_properties;
 }
 
-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 TypeInfo pxa27x_timer_dev_info = {
+    .name          = "pxa27x-timer",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PXA2xxTimerInfo),
+    .class_init    = pxa27x_timer_dev_class_init,
 };
 
 static void pxa2xx_timer_register(void)
 {
-    sysbus_register_withprop(&pxa25x_timer_dev_info);
-    sysbus_register_withprop(&pxa27x_timer_dev_info);
+    type_register_static(&pxa25x_timer_dev_info);
+    type_register_static(&pxa27x_timer_dev_info);
 };
 device_init(pxa2xx_timer_register);
diff --git a/hw/qdev.h b/hw/qdev.h
index 05ebf7e..54626ac 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -259,7 +259,6 @@ struct DeviceInfo {
     BusInfo *bus_info;
 };
 
-void qdev_register(DeviceInfo *info);
 void qdev_register_subclass(DeviceInfo *info, const char *parent);
 
 /* Register device properties.  */
diff --git a/hw/qxl.c b/hw/qxl.c
index 2f9470f..bc03c1d 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1826,6 +1826,7 @@ static Property qxl_properties[] = {
 
 static void qxl_primary_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->no_hotplug = 1;
@@ -1834,42 +1835,45 @@ static void qxl_primary_class_init(ObjectClass *klass, void *data)
     k->vendor_id = REDHAT_PCI_VENDOR_ID;
     k->device_id = QXL_DEVICE_ID_STABLE;
     k->class_id = PCI_CLASS_DISPLAY_VGA;
+    dc->desc = "Spice QXL GPU (primary, vga compatible)";
+    dc->reset = qxl_reset_handler;
+    dc->vmsd = &qxl_vmstate;
+    dc->props = qxl_properties;
 }
 
-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 TypeInfo qxl_primary_info = {
+    .name          = "qxl-vga",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIQXLDevice),
+    .class_init    = qxl_primary_class_init,
 };
 
 static void qxl_secondary_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     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;
+    dc->desc = "Spice QXL GPU (secondary)";
+    dc->reset = qxl_reset_handler;
+    dc->vmsd = &qxl_vmstate;
+    dc->props = qxl_properties;
 }
 
-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 TypeInfo qxl_secondary_info = {
+    .name          = "qxl",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIQXLDevice),
+    .class_init    = qxl_secondary_class_init,
 };
 
 static void qxl_register(void)
 {
-    pci_qdev_register(&qxl_primary_info);
-    pci_qdev_register(&qxl_secondary_info);
+    type_register_static(&qxl_primary_info);
+    type_register_static(&qxl_secondary_info);
 }
 
 device_init(qxl_register);
diff --git a/hw/realview.c b/hw/realview.c
index 42a0f20..821e627 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -89,15 +89,16 @@ static void realview_i2c_class_init(ObjectClass *klass, void *data)
     k->init = realview_i2c_init;
 }
 
-static DeviceInfo realview_i2c_info = {
-    .name = "realview_i2c",
-    .size = sizeof(RealViewI2CState),
-    .class_init = realview_i2c_class_init,
+static TypeInfo realview_i2c_info = {
+    .name          = "realview_i2c",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(RealViewI2CState),
+    .class_init    = realview_i2c_class_init,
 };
 
 static void realview_register_devices(void)
 {
-    sysbus_register_withprop(&realview_i2c_info);
+    type_register_static(&realview_i2c_info);
 }
 
 /* Board init.  */
diff --git a/hw/realview_gic.c b/hw/realview_gic.c
index 0ccf21a..4121502 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -53,15 +53,16 @@ static void realview_gic_class_init(ObjectClass *klass, void *data)
     sdc->init = realview_gic_init;
 }
 
-static DeviceInfo realview_gic_info = {
-    .name = "realview_gic",
-    .size = sizeof(RealViewGICState),
-    .class_init = realview_gic_class_init,
+static TypeInfo realview_gic_info = {
+    .name          = "realview_gic",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(RealViewGICState),
+    .class_init    = realview_gic_class_init,
 };
 
 static void realview_gic_register_devices(void)
 {
-    sysbus_qdev_register(&realview_gic_info);
+    type_register_static(&realview_gic_info);
 }
 
 device_init(realview_gic_register_devices)
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 15dec9b..1668390 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3501,6 +3501,7 @@ static Property rtl8139_properties[] = {
 
 static void rtl8139_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = pci_rtl8139_init;
@@ -3510,20 +3511,21 @@ static void rtl8139_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_REALTEK_8139;
     k->revision = RTL8139_PCI_REVID; /* >=0x20 is for 8139C+ */
     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+    dc->reset = rtl8139_reset;
+    dc->vmsd = &vmstate_rtl8139;
+    dc->props = rtl8139_properties;
 }
 
-static DeviceInfo rtl8139_info = {
-    .name = "rtl8139",
-    .size = sizeof(RTL8139State),
-    .reset = rtl8139_reset,
-    .vmsd = &vmstate_rtl8139,
-    .props = rtl8139_properties,
-    .class_init = rtl8139_class_init,
+static TypeInfo rtl8139_info = {
+    .name          = "rtl8139",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(RTL8139State),
+    .class_init    = rtl8139_class_init,
 };
 
 static void rtl8139_register_devices(void)
 {
-    pci_qdev_register(&rtl8139_info);
+    type_register_static(&rtl8139_info);
 }
 
 device_init(rtl8139_register_devices)
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 565941a..a0c610a 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -50,20 +50,6 @@ struct BusInfo s390_virtio_bus_info = {
     .size       = sizeof(VirtIOS390Bus),
 };
 
-typedef struct VirtIOS390DeviceClass
-{
-    DeviceClass parent_class;
-    int (*init)(VirtIOS390Device *dev);
-} 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;
 
 static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev);
@@ -351,65 +337,77 @@ static const VirtIOBindings virtio_s390_bindings = {
     .get_features = virtio_s390_get_features,
 };
 
+static Property s390_virtio_net_properties[] = {
+    DEFINE_NIC_PROPERTIES(VirtIOS390Device, nic),
+    DEFINE_PROP_UINT32("x-txtimer", VirtIOS390Device,
+                       net.txtimer, TX_TIMER_INTERVAL),
+    DEFINE_PROP_INT32("x-txburst", VirtIOS390Device,
+                      net.txburst, TX_BURST),
+    DEFINE_PROP_STRING("tx", VirtIOS390Device, net.tx),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void s390_virtio_net_class_init(ObjectClass *klass, void *data)
 {
-    VirtIOS390DeviceClass *dc = VIRTIO_S390_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
 
-    dc->init = s390_virtio_net_init;
+    k->init = s390_virtio_net_init;
+    dc->props = s390_virtio_net_properties;
+    dc->alias = "virtio-net";
 }
 
-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),
-        DEFINE_PROP_INT32("x-txburst", VirtIOS390Device,
-                          net.txburst, TX_BURST),
-        DEFINE_PROP_STRING("tx", VirtIOS390Device, net.tx),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static TypeInfo s390_virtio_net = {
+    .name          = "virtio-net-s390",
+    .parent        = TYPE_VIRTIO_S390_DEVICE,
+    .instance_size = sizeof(VirtIOS390Device),
+    .class_init    = s390_virtio_net_class_init,
+};
+
+static Property s390_virtio_blk_properties[] = {
+    DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, block),
+    DEFINE_PROP_STRING("serial", VirtIOS390Device, block_serial),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
 static void s390_virtio_blk_class_init(ObjectClass *klass, void *data)
 {
-    VirtIOS390DeviceClass *dc = VIRTIO_S390_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
 
-    dc->init = s390_virtio_blk_init;
+    k->init = s390_virtio_blk_init;
+    dc->props = s390_virtio_blk_properties;
+    dc->alias = "virtio-blk";
 }
 
-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 TypeInfo s390_virtio_blk = {
+    .name          = "virtio-blk-s390",
+    .parent        = TYPE_VIRTIO_S390_DEVICE,
+    .instance_size = sizeof(VirtIOS390Device),
+    .class_init    = s390_virtio_blk_class_init,
+};
+
+static Property s390_virtio_serial_properties[] = {
+    DEFINE_PROP_UINT32("max_ports", VirtIOS390Device,
+                       serial.max_virtserial_ports, 31),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
 static void s390_virtio_serial_class_init(ObjectClass *klass, void *data)
 {
-    VirtIOS390DeviceClass *dc = VIRTIO_S390_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
 
-    dc->init = s390_virtio_serial_init;
+    k->init = s390_virtio_serial_init;
+    dc->props = s390_virtio_serial_properties;
+    dc->alias = "virtio-serial";
 }
 
-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(),
-    },
+static TypeInfo s390_virtio_serial = {
+    .name          = "virtio-serial-s390",
+    .parent        = TYPE_VIRTIO_S390_DEVICE,
+    .instance_size = sizeof(VirtIOS390Device),
+    .class_init    = s390_virtio_serial_class_init,
 };
 
 static int s390_virtio_busdev_init(DeviceState *dev, DeviceInfo *info)
@@ -420,29 +418,29 @@ static int s390_virtio_busdev_init(DeviceState *dev, DeviceInfo *info)
     return _info->init(_dev);
 }
 
-static void s390_virtio_bus_register_withprop(DeviceInfo *info)
+static void virtio_s390_device_class_init(ObjectClass *klass, void *data)
 {
-    info->init = s390_virtio_busdev_init;
-    info->bus_info = &s390_virtio_bus_info;
-    info->unplug = qdev_simple_unplug_cb;
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
-    assert(info->size >= sizeof(VirtIOS390Device));
-    qdev_register_subclass(info, TYPE_VIRTIO_S390_DEVICE);
+    dc->init = s390_virtio_busdev_init;
+    dc->bus_info = &s390_virtio_bus_info;
+    dc->unplug = qdev_simple_unplug_cb;
 }
 
 static TypeInfo virtio_s390_device_info = {
     .name = TYPE_VIRTIO_S390_DEVICE,
     .parent = TYPE_DEVICE,
     .instance_size = sizeof(VirtIOS390Device),
+    .class_init = virtio_s390_device_class_init,
     .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);
+    type_register_static(&s390_virtio_serial);
+    type_register_static(&s390_virtio_blk);
+    type_register_static(&s390_virtio_net);
 }
 device_init(s390_virtio_register);
 
@@ -458,21 +456,23 @@ static int s390_virtio_bridge_init(SysBusDevice *dev)
 
 static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = s390_virtio_bridge_init;
+    dc->no_user = 1;
 }
 
-static DeviceInfo s390_virtio_bridge_info = {
-    .name = "s390-virtio-bridge",
-    .size = sizeof(SysBusDevice),
-    .no_user = 1,
-    .class_init = s390_virtio_bridge_class_init,
+static TypeInfo s390_virtio_bridge_info = {
+    .name          = "s390-virtio-bridge",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SysBusDevice),
+    .class_init    = s390_virtio_bridge_class_init,
 };
 
 static void s390_virtio_register_devices(void)
 {
-    sysbus_register_withprop(&s390_virtio_bridge_info);
+    type_register_static(&s390_virtio_bridge_info);
 }
 
 device_init(s390_virtio_register_devices)
diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h
index d02a907..b5e59b7 100644
--- a/hw/s390-virtio-bus.h
+++ b/hw/s390-virtio-bus.h
@@ -40,7 +40,22 @@
 #define VIRTIO_PARAM_CONFIG_CHANGED     0x1
 #define VIRTIO_PARAM_DEV_ADD            0x2
 
-typedef struct VirtIOS390Device {
+#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)
+
+typedef struct VirtIOS390Device VirtIOS390Device;
+
+typedef struct VirtIOS390DeviceClass {
+    DeviceClass qdev;
+    int (*init)(VirtIOS390Device *dev);
+} VirtIOS390DeviceClass;
+
+struct VirtIOS390Device {
     DeviceState qdev;
     ram_addr_t dev_offs;
     ram_addr_t feat_offs;
@@ -52,7 +67,7 @@ typedef struct VirtIOS390Device {
     uint32_t host_features;
     virtio_serial_conf serial;
     virtio_net_conf net;
-} VirtIOS390Device;
+};
 
 typedef struct VirtIOS390Bus {
     BusState bus;
diff --git a/hw/sb16.c b/hw/sb16.c
index 67357ce..ae25450 100644
--- a/hw/sb16.c
+++ b/hw/sb16.c
@@ -1391,30 +1391,34 @@ int SB16_init (ISABus *bus)
     return 0;
 }
 
+static Property sb16_properties[] = {
+    DEFINE_PROP_HEX32  ("version", SB16State, ver,  0x0405), /* 4.5 */
+    DEFINE_PROP_HEX32  ("iobase",  SB16State, port, 0x220),
+    DEFINE_PROP_UINT32 ("irq",     SB16State, irq,  5),
+    DEFINE_PROP_UINT32 ("dma",     SB16State, dma,  1),
+    DEFINE_PROP_UINT32 ("dma16",   SB16State, hdma, 5),
+    DEFINE_PROP_END_OF_LIST (),
+};
+
 static void sb16_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = sb16_initfn;
+    dc->desc = "Creative Sound Blaster 16";
+    dc->vmsd = &vmstate_sb16;
+    dc->props = sb16_properties;
 }
 
-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),
-        DEFINE_PROP_UINT32 ("dma",     SB16State, dma,  1),
-        DEFINE_PROP_UINT32 ("dma16",   SB16State, hdma, 5),
-        DEFINE_PROP_END_OF_LIST (),
-    },
+static TypeInfo sb16_info = {
+    .name          = "sb16",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof (SB16State),
+    .class_init    = sb16_class_initfn,
 };
 
 static void sb16_register (void)
 {
-    isa_qdev_register (&sb16_info);
+    type_register_static(&sb16_info);
 }
 device_init (sb16_register)
diff --git a/hw/sbi.c b/hw/sbi.c
index 0a062fc..847a4dd 100644
--- a/hw/sbi.c
+++ b/hw/sbi.c
@@ -133,22 +133,24 @@ static int sbi_init1(SysBusDevice *dev)
 
 static void sbi_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = sbi_init1;
+    dc->reset = sbi_reset;
+    dc->vmsd = &vmstate_sbi;
 }
 
-static DeviceInfo sbi_info = {
-    .name = "sbi",
-    .size = sizeof(SBIState),
-    .vmsd = &vmstate_sbi,
-    .reset = sbi_reset,
-    .class_init = sbi_class_init,
+static TypeInfo sbi_info = {
+    .name          = "sbi",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SBIState),
+    .class_init    = sbi_class_init,
 };
 
 static void sbi_register_devices(void)
 {
-    sysbus_register_withprop(&sbi_info);
+    type_register_static(&sbi_info);
 }
 
 device_init(sbi_register_devices)
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index d017ece..b75044f 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -183,15 +183,6 @@ static int scsi_qdev_exit(DeviceState *qdev)
     return 0;
 }
 
-void scsi_qdev_register(DeviceInfo *info)
-{
-    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 */
 SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
                                       int unit, bool removable, int bootindex)
@@ -1422,12 +1413,22 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun)
     return target_dev;
 }
 
+static void scsi_device_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *k = DEVICE_CLASS(klass);
+    k->bus_info = &scsi_bus_info;
+    k->init     = scsi_qdev_init;
+    k->unplug   = qdev_simple_unplug_cb;
+    k->exit     = scsi_qdev_exit;
+}
+
 static TypeInfo scsi_device_type_info = {
     .name = TYPE_SCSI_DEVICE,
     .parent = TYPE_DEVICE,
     .instance_size = sizeof(SCSIDevice),
     .abstract = true,
     .class_size = sizeof(SCSIDeviceClass),
+    .class_init = scsi_device_class_init,
 };
 
 static void scsi_register_devices(void)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 2be6b67..399e51e 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1712,108 +1712,124 @@ static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
     DEFINE_PROP_STRING("ver",  SCSIDiskState, version),         \
     DEFINE_PROP_STRING("serial",  SCSIDiskState, serial)
 
+static Property scsi_hd_properties[] = {
+    DEFINE_SCSI_DISK_PROPERTIES(),
+    DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     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;
+    dc->fw_name = "disk";
+    dc->desc = "virtual SCSI disk";
+    dc->reset = scsi_disk_reset;
+    dc->props = scsi_hd_properties;
 }
 
-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 TypeInfo scsi_hd_info = {
+    .name          = "scsi-hd",
+    .parent        = TYPE_SCSI_DEVICE,
+    .instance_size = sizeof(SCSIDiskState),
+    .class_init    = scsi_hd_class_initfn,
+};
+
+static Property scsi_cd_properties[] = {
+    DEFINE_SCSI_DISK_PROPERTIES(),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
 static void scsi_cd_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     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;
+    dc->fw_name = "disk";
+    dc->desc = "virtual SCSI CD-ROM";
+    dc->reset = scsi_disk_reset;
+    dc->props = scsi_cd_properties;
 }
 
-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(),
-    },
+static TypeInfo scsi_cd_info = {
+    .name          = "scsi-cd",
+    .parent        = TYPE_SCSI_DEVICE,
+    .instance_size = sizeof(SCSIDiskState),
+    .class_init    = scsi_cd_class_initfn,
 };
 
 #ifdef __linux__
+static Property scsi_block_properties[] = {
+    DEFINE_SCSI_DISK_PROPERTIES(),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void scsi_block_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
 
     sc->init         = scsi_block_initfn;
     sc->destroy      = scsi_destroy;
     sc->alloc_req    = scsi_block_new_request;
+    dc->fw_name = "disk";
+    dc->desc = "SCSI block device passthrough";
+    dc->reset = scsi_disk_reset;
+    dc->props = scsi_block_properties;
 }
 
-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(),
-    },
+static TypeInfo scsi_block_info = {
+    .name          = "scsi-block",
+    .parent        = TYPE_SCSI_DEVICE,
+    .instance_size = sizeof(SCSIDiskState),
+    .class_init    = scsi_block_class_initfn,
 };
 #endif
 
+static Property scsi_disk_properties[] = {
+    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)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     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;
+    dc->fw_name = "disk";
+    dc->desc = "virtual SCSI disk or CD-ROM (legacy)";
+    dc->reset = scsi_disk_reset;
+    dc->props = scsi_disk_properties;
 }
 
-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 TypeInfo scsi_disk_info = {
+    .name          = "scsi-disk",
+    .parent        = TYPE_SCSI_DEVICE,
+    .instance_size = sizeof(SCSIDiskState),
+    .class_init    = scsi_disk_class_initfn,
 };
 
 static void scsi_disk_register_devices(void)
 {
-    scsi_qdev_register(&scsi_hd_info);
-    scsi_qdev_register(&scsi_cd_info);
+    type_register_static(&scsi_hd_info);
+    type_register_static(&scsi_cd_info);
 #ifdef __linux__
-    scsi_qdev_register(&scsi_block_info);
+    type_register_static(&scsi_block_info);
 #endif
-    scsi_qdev_register(&scsi_disk_info);
+    type_register_static(&scsi_disk_info);
 }
 device_init(scsi_disk_register_devices)
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 5cf4005..4859212 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -457,31 +457,35 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
     return req;
 }
 
+static Property scsi_generic_properties[] = {
+    DEFINE_BLOCK_PROPERTIES(SCSIDevice, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
 
     sc->init         = scsi_generic_initfn;
     sc->destroy      = scsi_destroy;
     sc->alloc_req    = scsi_new_request;
+    dc->fw_name = "disk";
+    dc->desc = "pass through generic scsi device (/dev/sg*)";
+    dc->reset = scsi_generic_reset;
+    dc->props = scsi_generic_properties;
 }
 
-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(),
-    },
+static TypeInfo scsi_generic_info = {
+    .name          = "scsi-generic",
+    .parent        = TYPE_SCSI_DEVICE,
+    .instance_size = sizeof(SCSIDevice),
+    .class_init    = scsi_generic_class_initfn,
 };
 
 static void scsi_generic_register_devices(void)
 {
-    scsi_qdev_register(&scsi_generic_info);
+    type_register_static(&scsi_generic_info);
 }
 device_init(scsi_generic_register_devices)
 
diff --git a/hw/scsi.h b/hw/scsi.h
index 4290b20..dc72b6f 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -125,7 +125,6 @@ struct SCSIBus {
 };
 
 void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info);
-void scsi_qdev_register(DeviceInfo *info);
 
 static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
 {
diff --git a/hw/serial.c b/hw/serial.c
index 2644b13..82917e2 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -879,29 +879,33 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
     return s;
 }
 
+static Property serial_isa_properties[] = {
+    DEFINE_PROP_UINT32("index", ISASerialState, index,   -1),
+    DEFINE_PROP_HEX32("iobase", ISASerialState, iobase,  -1),
+    DEFINE_PROP_UINT32("irq",   ISASerialState, isairq,  -1),
+    DEFINE_PROP_CHR("chardev",  ISASerialState, state.chr),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void serial_isa_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = serial_isa_initfn;
+    dc->vmsd = &vmstate_isa_serial;
+    dc->props = serial_isa_properties;
 }
 
-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),
-        DEFINE_PROP_CHR("chardev",  ISASerialState, state.chr),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static TypeInfo serial_isa_info = {
+    .name          = "isa-serial",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(ISASerialState),
+    .class_init    = serial_isa_class_initfn,
 };
 
 static void serial_register_devices(void)
 {
-    isa_qdev_register(&serial_isa_info);
+    type_register_static(&serial_isa_info);
 }
 
 device_init(serial_register_devices)
diff --git a/hw/sga.c b/hw/sga.c
index d612cb6..b08e3c5 100644
--- a/hw/sga.c
+++ b/hw/sga.c
@@ -42,20 +42,22 @@ static int sga_initfn(ISADevice *dev)
 }
 static void sga_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = sga_initfn;
+    dc->desc = "Serial Graphics Adapter";
 }
 
-static DeviceInfo sga_info = {
-    .name    = "sga",
-    .desc    = "Serial Graphics Adapter",
-    .size    = sizeof(ISASGAState),
-    .class_init         = sga_class_initfn,
+static TypeInfo sga_info = {
+    .name          = "sga",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(ISASGAState),
+    .class_init    = sga_class_initfn,
 };
 
 static void sga_register(void)
 {
-      isa_qdev_register(&sga_info);
+    type_register_static(&sga_info);
 }
 
 device_init(sga_register);
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index a849176..4234d93 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -156,10 +156,11 @@ static void sh_pci_host_class_init(ObjectClass *klass, void *data)
     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 TypeInfo sh_pci_host_info = {
+    .name          = "sh_pci_host",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
+    .class_init    = sh_pci_host_class_init,
 };
 
 static void sh_pci_device_class_init(ObjectClass *klass, void *data)
@@ -169,16 +170,17 @@ static void sh_pci_device_class_init(ObjectClass *klass, void *data)
     sdc->init = sh_pci_device_init;
 }
 
-static DeviceInfo sh_pci_device_info = {
-    .name = "sh_pci",
-    .size = sizeof(SHPCIState),
-    .class_init = sh_pci_device_class_init,
+static TypeInfo sh_pci_device_info = {
+    .name          = "sh_pci",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SHPCIState),
+    .class_init    = sh_pci_device_class_init,
 };
 
 static void sh_pci_register_devices(void)
 {
-    sysbus_qdev_register(&sh_pci_device_info);
-    pci_qdev_register(&sh_pci_host_info);
+    type_register_static(&sh_pci_device_info);
+    type_register_static(&sh_pci_host_info);
 }
 
 device_init(sh_pci_register_devices)
diff --git a/hw/slavio_intctl.c b/hw/slavio_intctl.c
index 12ce342..e3701c7 100644
--- a/hw/slavio_intctl.c
+++ b/hw/slavio_intctl.c
@@ -448,22 +448,24 @@ static int slavio_intctl_init1(SysBusDevice *dev)
 
 static void slavio_intctl_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = slavio_intctl_init1;
+    dc->reset = slavio_intctl_reset;
+    dc->vmsd = &vmstate_intctl;
 }
 
-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 TypeInfo slavio_intctl_info = {
+    .name          = "slavio_intctl",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SLAVIO_INTCTLState),
+    .class_init    = slavio_intctl_class_init,
 };
 
 static void slavio_intctl_register_devices(void)
 {
-    sysbus_register_withprop(&slavio_intctl_info);
+    type_register_static(&slavio_intctl_info);
 }
 
 device_init(slavio_intctl_register_devices)
diff --git a/hw/slavio_misc.c b/hw/slavio_misc.c
index 39a5269..5a02518 100644
--- a/hw/slavio_misc.c
+++ b/hw/slavio_misc.c
@@ -470,17 +470,19 @@ static int slavio_misc_init1(SysBusDevice *dev)
 
 static void slavio_misc_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = slavio_misc_init1;
+    dc->reset = slavio_misc_reset;
+    dc->vmsd = &vmstate_misc;
 }
 
-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 TypeInfo slavio_misc_info = {
+    .name          = "slavio_misc",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MiscState),
+    .class_init    = slavio_misc_class_init,
 };
 
 static void apc_class_init(ObjectClass *klass, void *data)
@@ -490,16 +492,17 @@ static void apc_class_init(ObjectClass *klass, void *data)
     k->init = apc_init1;
 }
 
-static DeviceInfo apc_info = {
-    .name = "apc",
-    .size = sizeof(MiscState),
-    .class_init = apc_class_init,
+static TypeInfo apc_info = {
+    .name          = "apc",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(MiscState),
+    .class_init    = apc_class_init,
 };
 
 static void slavio_misc_register_devices(void)
 {
-    sysbus_register_withprop(&slavio_misc_info);
-    sysbus_register_withprop(&apc_info);
+    type_register_static(&slavio_misc_info);
+    type_register_static(&apc_info);
 }
 
 device_init(slavio_misc_register_devices)
diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c
index a3bebcd..3878f6f 100644
--- a/hw/slavio_timer.c
+++ b/hw/slavio_timer.c
@@ -411,23 +411,25 @@ static Property slavio_timer_properties[] = {
 
 static void slavio_timer_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = slavio_timer_init1;
+    dc->reset = slavio_timer_reset;
+    dc->vmsd = &vmstate_slavio_timer;
+    dc->props = slavio_timer_properties;
 }
 
-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 TypeInfo slavio_timer_info = {
+    .name          = "slavio_timer",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SLAVIO_TIMERState),
+    .class_init    = slavio_timer_class_init,
 };
 
 static void slavio_timer_register_devices(void)
 {
-    sysbus_register_withprop(&slavio_timer_info);
+    type_register_static(&slavio_timer_info);
 }
 
 device_init(slavio_timer_register_devices)
diff --git a/hw/smbus.c b/hw/smbus.c
index ed31a59..77626f3 100644
--- a/hw/smbus.c
+++ b/hw/smbus.c
@@ -207,12 +207,6 @@ static int smbus_device_init(I2CSlave *i2c)
     return sc->init(dev);
 }
 
-void smbus_register_device(DeviceInfo *info)
-{
-    assert(info->size >= sizeof(SMBusDevice));
-    i2c_register_slave_subclass(info, TYPE_SMBUS_DEVICE);
-}
-
 /* Master device commands.  */
 void smbus_quick_command(i2c_bus *bus, uint8_t addr, int read)
 {
diff --git a/hw/smbus.h b/hw/smbus.h
index 90fadee..6ed45bd 100644
--- a/hw/smbus.h
+++ b/hw/smbus.h
@@ -65,8 +65,6 @@ struct SMBusDevice {
     uint8_t command;
 };
 
-void smbus_register_device(DeviceInfo *info);
-
 /* Master device commands.  */
 void smbus_quick_command(i2c_bus *bus, uint8_t addr, int read);
 uint8_t smbus_receive_byte(i2c_bus *bus, uint8_t addr);
diff --git a/hw/smbus_eeprom.c b/hw/smbus_eeprom.c
index 401dff5..9d96cbe 100644
--- a/hw/smbus_eeprom.c
+++ b/hw/smbus_eeprom.c
@@ -104,8 +104,14 @@ static int smbus_eeprom_initfn(SMBusDevice *dev)
     return 0;
 }
 
+static Property smbus_eeprom_properties[] = {
+    DEFINE_PROP_PTR("data", SMBusEEPROMDevice, data),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(klass);
 
     sc->init = smbus_eeprom_initfn;
@@ -114,21 +120,19 @@ static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data)
     sc->receive_byte = eeprom_receive_byte;
     sc->write_data = eeprom_write_data;
     sc->read_data = eeprom_read_data;
+    dc->props = smbus_eeprom_properties;
 }
 
-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(),
-    },
+static TypeInfo smbus_eeprom_info = {
+    .name          = "smbus-eeprom",
+    .parent        = TYPE_SMBUS_DEVICE,
+    .instance_size = sizeof(SMBusEEPROMDevice),
+    .class_init    = smbus_eeprom_class_initfn,
 };
 
 static void smbus_eeprom_register_devices(void)
 {
-    smbus_register_device(&smbus_eeprom_info);
+    type_register_static(&smbus_eeprom_info);
 }
 
 device_init(smbus_eeprom_register_devices)
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index 4220880..1bf2901 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -765,23 +765,25 @@ static Property smc91c111_properties[] = {
 
 static void smc91c111_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = smc91c111_init1;
+    dc->reset = smc91c111_reset;
+    dc->vmsd = &vmstate_smc91c111;
+    dc->props = smc91c111_properties;
 }
 
-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 TypeInfo smc91c111_info = {
+    .name          = "smc91c111",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(smc91c111_state),
+    .class_init    = smc91c111_class_init,
 };
 
 static void smc91c111_register_devices(void)
 {
-    sysbus_register_withprop(&smc91c111_info);
+    type_register_static(&smc91c111_info);
 }
 
 /* Legacy helper function.  Should go away when machine config files are
diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c
index 0fb176a..79b3941 100644
--- a/hw/spapr_llan.c
+++ b/hw/spapr_llan.c
@@ -482,6 +482,7 @@ static Property spapr_vlan_properties[] = {
 
 static void spapr_vlan_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
 
     k->init = spapr_vlan_init;
@@ -490,13 +491,14 @@ static void spapr_vlan_class_init(ObjectClass *klass, void *data)
     k->dt_type = "network";
     k->dt_compatible = "IBM,l-lan";
     k->signal_mask = 0x1;
+    dc->props = spapr_vlan_properties;
 }
 
-static DeviceInfo spapr_vlan_info = {
-    .name = "spapr-vlan",
-    .size = sizeof(VIOsPAPRVLANDevice),
-    .props = spapr_vlan_properties,
-    .class_init = spapr_vlan_class_init,
+static TypeInfo spapr_vlan_info = {
+    .name          = "spapr-vlan",
+    .parent        = TYPE_VIO_SPAPR_DEVICE,
+    .instance_size = sizeof(VIOsPAPRVLANDevice),
+    .class_init    = spapr_vlan_class_init,
 };
 
 static void spapr_vlan_register(void)
@@ -507,6 +509,6 @@ static void spapr_vlan_register(void)
     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);
+    type_register_static(&spapr_vlan_info);
 }
 device_init(spapr_vlan_register);
diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c
index 2a82eae..ed2e4b3 100644
--- a/hw/spapr_pci.c
+++ b/hw/spapr_pci.c
@@ -221,10 +221,11 @@ static void spapr_main_pci_host_class_init(ObjectClass *klass, void *data)
     k->init = spapr_main_pci_host_init;
 }
 
-static DeviceInfo spapr_main_pci_host_info = {
-    .name = "spapr-pci-host-bridge-pci",
-    .size = sizeof(PCIDevice),
-    .class_init = spapr_main_pci_host_class_init,
+static TypeInfo spapr_main_pci_host_info = {
+    .name          = "spapr-pci-host-bridge-pci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
+    .class_init    = spapr_main_pci_host_class_init,
 };
 
 static void spapr_phb_class_init(ObjectClass *klass, void *data)
@@ -234,16 +235,17 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data)
     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 TypeInfo spapr_phb_info = {
+    .name          = "spapr-pci-host-bridge",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(sPAPRPHBState),
+    .class_init    = spapr_phb_class_init,
 };
 
 static void spapr_register_devices(void)
 {
-    sysbus_qdev_register(&spapr_phb_info);
-    pci_qdev_register(&spapr_main_pci_host_info);
+    type_register_static(&spapr_phb_info);
+    type_register_static(&spapr_main_pci_host_info);
 }
 
 device_init(spapr_register_devices)
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index dc2e9c9..d39a47b 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -680,15 +680,6 @@ static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo)
     return pc->init(dev);
 }
 
-void spapr_vio_bus_register_withprop(DeviceInfo *info)
-{
-    info->init = spapr_vio_busdev_init;
-    info->bus_info = &spapr_vio_bus_info;
-
-    assert(info->size >= sizeof(VIOsPAPRDevice));
-    qdev_register_subclass(info, TYPE_VIO_SPAPR_DEVICE);
-}
-
 static target_ulong h_vio_signal(CPUState *env, sPAPREnvironment *spapr,
                                  target_ulong opcode,
                                  target_ulong *args)
@@ -757,29 +748,39 @@ static int spapr_vio_bridge_init(SysBusDevice *dev)
 
 static void spapr_vio_bridge_class_init(ObjectClass *klass, void *data)
 {
-    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    sbc->init = spapr_vio_bridge_init;
+    k->init = spapr_vio_bridge_init;
+    dc->no_user = 1;
 }
 
-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_bridge_info = {
+    .name          = "spapr-vio-bridge",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SysBusDevice),
+    .class_init    = spapr_vio_bridge_class_init,
 };
 
+static void vio_spapr_device_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *k = DEVICE_CLASS(klass);
+    k->init = spapr_vio_busdev_init;
+    k->bus_info = &spapr_vio_bus_info;
+}
+
 static TypeInfo spapr_vio_type_info = {
     .name = TYPE_VIO_SPAPR_DEVICE,
     .parent = TYPE_DEVICE,
     .instance_size = sizeof(VIOsPAPRDevice),
     .abstract = true,
     .class_size = sizeof(VIOsPAPRDeviceClass),
+    .class_init = vio_spapr_device_class_init,
 };
 
 static void spapr_vio_register_devices(void)
 {
-    sysbus_register_withprop(&spapr_vio_bridge_info);
+    type_register_static(&spapr_vio_bridge_info);
     type_register_static(&spapr_vio_type_info);
 }
 
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index 7d1155a..d8527be 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -97,7 +97,6 @@ struct VIOsPAPRBus {
 
 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(DeviceInfo *info);
 extern int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt);
 extern int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus);
 
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index b83bb7f..9cfce19 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -954,6 +954,7 @@ static Property spapr_vscsi_properties[] = {
 
 static void spapr_vscsi_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
 
     k->init = spapr_vscsi_init;
@@ -962,17 +963,18 @@ static void spapr_vscsi_class_init(ObjectClass *klass, void *data)
     k->dt_type = "vscsi";
     k->dt_compatible = "IBM,v-scsi";
     k->signal_mask = 0x00000001;
+    dc->props = spapr_vscsi_properties;
 }
 
-static DeviceInfo spapr_vscsi_info = {
-    .name = "spapr-vscsi",
-    .size = sizeof(VSCSIState),
-    .props = spapr_vscsi_properties,
-    .class_init = spapr_vscsi_class_init,
+static TypeInfo spapr_vscsi_info = {
+    .name          = "spapr-vscsi",
+    .parent        = TYPE_VIO_SPAPR_DEVICE,
+    .instance_size = sizeof(VSCSIState),
+    .class_init    = spapr_vscsi_class_init,
 };
 
 static void spapr_vscsi_register(void)
 {
-    spapr_vio_bus_register_withprop(&spapr_vscsi_info);
+    type_register_static(&spapr_vscsi_info);
 }
 device_init(spapr_vscsi_register);
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index 1780ffe..a954e7d 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -143,19 +143,21 @@ static Property spapr_vty_properties[] = {
 
 static void spapr_vty_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
 
     k->init = spapr_vty_init;
     k->dt_name = "vty";
     k->dt_type = "serial";
     k->dt_compatible = "hvterm1";
+    dc->props = spapr_vty_properties;
 }
 
-static DeviceInfo spapr_vty_info = {
-    .name = "spapr-vty",
-    .size = sizeof(VIOsPAPRVTYDevice),
-    .props = spapr_vty_properties,
-    .class_init = spapr_vty_class_init,
+static TypeInfo spapr_vty_info = {
+    .name          = "spapr-vty",
+    .parent        = TYPE_VIO_SPAPR_DEVICE,
+    .instance_size = sizeof(VIOsPAPRVTYDevice),
+    .class_init    = spapr_vty_class_init,
 };
 
 VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
@@ -214,6 +216,6 @@ static void spapr_vty_register(void)
 {
     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);
+    type_register_static(&spapr_vty_info);
 }
 device_init(spapr_vty_register);
diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
index 582f2f0..f07cc6f 100644
--- a/hw/sparc32_dma.c
+++ b/hw/sparc32_dma.c
@@ -291,23 +291,25 @@ static Property sparc32_dma_properties[] = {
 
 static void sparc32_dma_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = sparc32_dma_init1;
+    dc->reset = dma_reset;
+    dc->vmsd = &vmstate_dma;
+    dc->props = sparc32_dma_properties;
 }
 
-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 TypeInfo sparc32_dma_info = {
+    .name          = "sparc32_dma",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(DMAState),
+    .class_init    = sparc32_dma_class_init,
 };
 
 static void sparc32_dma_register_devices(void)
 {
-    sysbus_register_withprop(&sparc32_dma_info);
+    type_register_static(&sparc32_dma_info);
 }
 
 device_init(sparc32_dma_register_devices)
diff --git a/hw/spitz.c b/hw/spitz.c
index 046efad..4e6540d 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -1031,17 +1031,19 @@ static Property sl_nand_properties[] = {
 
 static void sl_nand_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = sl_nand_init;
+    dc->vmsd = &vmstate_sl_nand_info;
+    dc->props = sl_nand_properties;
 }
 
-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 TypeInfo sl_nand_info = {
+    .name          = "sl-nand",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SLNANDState),
+    .class_init    = sl_nand_class_init,
 };
 
 static VMStateDescription vmstate_spitz_kbd = {
@@ -1064,17 +1066,19 @@ static Property spitz_keyboard_properties[] = {
 
 static void spitz_keyboard_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = spitz_keyboard_init;
+    dc->vmsd = &vmstate_spitz_kbd;
+    dc->props = spitz_keyboard_properties;
 }
 
-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 TypeInfo spitz_keyboard_info = {
+    .name          = "spitz-keyboard",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SpitzKeyboardState),
+    .class_init    = spitz_keyboard_class_init,
 };
 
 static const VMStateDescription vmstate_corgi_ssp_regs = {
@@ -1090,17 +1094,19 @@ static const VMStateDescription vmstate_corgi_ssp_regs = {
 
 static void corgi_ssp_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 
     k->init = corgi_ssp_init;
     k->transfer = corgi_ssp_transfer;
+    dc->vmsd = &vmstate_corgi_ssp_regs;
 }
 
-static DeviceInfo corgi_ssp_info = {
-    .name = "corgi-ssp",
-    .size = sizeof(CorgiSSPState),
-    .vmsd = &vmstate_corgi_ssp_regs,
-    .class_init = corgi_ssp_class_init,
+static TypeInfo corgi_ssp_info = {
+    .name          = "corgi-ssp",
+    .parent        = TYPE_SSI_SLAVE,
+    .instance_size = sizeof(CorgiSSPState),
+    .class_init    = corgi_ssp_class_init,
 };
 
 static const VMStateDescription vmstate_spitz_lcdtg_regs = {
@@ -1117,25 +1123,27 @@ static const VMStateDescription vmstate_spitz_lcdtg_regs = {
 
 static void spitz_lcdtg_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 
     k->init = spitz_lcdtg_init;
     k->transfer = spitz_lcdtg_transfer;
+    dc->vmsd = &vmstate_spitz_lcdtg_regs;
 }
 
-static DeviceInfo spitz_lcdtg_info = {
-    .name = "spitz-lcdtg",
-    .size = sizeof(SpitzLCDTG),
-    .vmsd = &vmstate_spitz_lcdtg_regs,
-    .class_init = spitz_lcdtg_class_init,
+static TypeInfo spitz_lcdtg_info = {
+    .name          = "spitz-lcdtg",
+    .parent        = TYPE_SSI_SLAVE,
+    .instance_size = sizeof(SpitzLCDTG),
+    .class_init    = spitz_lcdtg_class_init,
 };
 
 static void spitz_register_devices(void)
 {
-    ssi_register_slave(&corgi_ssp_info);
-    ssi_register_slave(&spitz_lcdtg_info);
-    sysbus_register_withprop(&spitz_keyboard_info);
-    sysbus_register_withprop(&sl_nand_info);
+    type_register_static(&corgi_ssp_info);
+    type_register_static(&spitz_lcdtg_info);
+    type_register_static(&spitz_keyboard_info);
+    type_register_static(&sl_nand_info);
 }
 
 device_init(spitz_register_devices)
diff --git a/hw/ssd0303.c b/hw/ssd0303.c
index acf027f..685602a 100644
--- a/hw/ssd0303.c
+++ b/hw/ssd0303.c
@@ -296,24 +296,26 @@ static int ssd0303_init(I2CSlave *i2c)
 
 static void ssd0303_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
 
     k->init = ssd0303_init;
     k->event = ssd0303_event;
     k->recv = ssd0303_recv;
     k->send = ssd0303_send;
+    dc->vmsd = &vmstate_ssd0303;
 }
 
-static DeviceInfo ssd0303_info = {
-    .name = "ssd0303",
-    .size = sizeof(ssd0303_state),
-    .vmsd = &vmstate_ssd0303,
-    .class_init = ssd0303_class_init,
+static TypeInfo ssd0303_info = {
+    .name          = "ssd0303",
+    .parent        = TYPE_I2C_SLAVE,
+    .instance_size = sizeof(ssd0303_state),
+    .class_init    = ssd0303_class_init,
 };
 
 static void ssd0303_register_devices(void)
 {
-    i2c_register_slave(&ssd0303_info);
+    type_register_static(&ssd0303_info);
 }
 
 device_init(ssd0303_register_devices)
diff --git a/hw/ssd0323.c b/hw/ssd0323.c
index 8e2fac8..3c43738 100644
--- a/hw/ssd0323.c
+++ b/hw/ssd0323.c
@@ -348,15 +348,16 @@ static void ssd0323_class_init(ObjectClass *klass, void *data)
     k->transfer = ssd0323_transfer;
 }
 
-static DeviceInfo ssd0323_info = {
-    .name = "ssd0323",
-    .size = sizeof(ssd0323_state),
-    .class_init = ssd0323_class_init,
+static TypeInfo ssd0323_info = {
+    .name          = "ssd0323",
+    .parent        = TYPE_SSI_SLAVE,
+    .instance_size = sizeof(ssd0323_state),
+    .class_init    = ssd0323_class_init,
 };
 
 static void ssd03232_register_devices(void)
 {
-    ssi_register_slave(&ssd0323_info);
+    type_register_static(&ssd0323_info);
 }
 
 device_init(ssd03232_register_devices)
diff --git a/hw/ssi-sd.c b/hw/ssi-sd.c
index 2738cf9..f2e6cec 100644
--- a/hw/ssi-sd.c
+++ b/hw/ssi-sd.c
@@ -252,15 +252,16 @@ static void ssi_sd_class_init(ObjectClass *klass, void *data)
     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 TypeInfo ssi_sd_info = {
+    .name          = "ssi-sd",
+    .parent        = TYPE_SSI_SLAVE,
+    .instance_size = sizeof(ssi_sd_state),
+    .class_init    = ssi_sd_class_init,
 };
 
 static void ssi_sd_register_devices(void)
 {
-    ssi_register_slave(&ssi_sd_info);
+    type_register_static(&ssi_sd_info);
 }
 
 device_init(ssi_sd_register_devices)
diff --git a/hw/ssi.c b/hw/ssi.c
index 99a0616..4282b8b 100644
--- a/hw/ssi.c
+++ b/hw/ssi.c
@@ -36,14 +36,21 @@ static int ssi_slave_init(DeviceState *dev, DeviceInfo *base_info)
     return ssc->init(s);
 }
 
-void ssi_register_slave(DeviceInfo *info)
+static void ssi_slave_class_init(ObjectClass *klass, void *data)
 {
-    assert(info->size >= sizeof(SSISlave));
-    info->init = ssi_slave_init;
-    info->bus_info = &ssi_bus_info;
-    qdev_register(info);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    dc->init = ssi_slave_init;
+    dc->bus_info = &ssi_bus_info;
 }
 
+static TypeInfo ssi_slave_info = {
+    .name = TYPE_SSI_SLAVE,
+    .parent = TYPE_DEVICE,
+    .class_init = ssi_slave_class_init,
+    .class_size = sizeof(SSISlaveClass),
+    .abstract = true,
+};
+
 DeviceState *ssi_create_slave(SSIBus *bus, const char *name)
 {
     DeviceState *dev;
@@ -72,3 +79,10 @@ uint32_t ssi_transfer(SSIBus *bus, uint32_t val)
     ssc = SSI_SLAVE_GET_CLASS(slave);
     return ssc->transfer(slave, val);
 }
+
+static void register_ssi_slave(void)
+{
+    type_register_static(&ssi_slave_info);
+}
+
+device_init(register_ssi_slave);
diff --git a/hw/ssi.h b/hw/ssi.h
index 97aefa7..06657d7 100644
--- a/hw/ssi.h
+++ b/hw/ssi.h
@@ -38,8 +38,6 @@ struct SSISlave {
 #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(DeviceInfo *info);
-
 DeviceState *ssi_create_slave(SSIBus *bus, const char *name);
 
 /* Master interface.  */
diff --git a/hw/stellaris.c b/hw/stellaris.c
index b91139e..31a65cf 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -1402,10 +1402,11 @@ static void stellaris_ssi_bus_class_init(ObjectClass *klass, void *data)
     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 TypeInfo stellaris_ssi_bus_info = {
+    .name          = "evb6965-ssi",
+    .parent        = TYPE_SSI_SLAVE,
+    .instance_size = sizeof(stellaris_ssi_bus_state),
+    .class_init    = stellaris_ssi_bus_class_init,
 };
 
 static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
@@ -1415,10 +1416,11 @@ static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
     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 TypeInfo stellaris_i2c_info = {
+    .name          = "stellaris-i2c",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(stellaris_i2c_state),
+    .class_init    = stellaris_i2c_class_init,
 };
 
 static void stellaris_gptm_class_init(ObjectClass *klass, void *data)
@@ -1428,10 +1430,11 @@ static void stellaris_gptm_class_init(ObjectClass *klass, void *data)
     sdc->init = stellaris_gptm_init;
 }
 
-static DeviceInfo stellaris_gptm_info = {
-    .name = "stellaris-gptm",
-    .size = sizeof(gptm_state),
-    .class_init = stellaris_gptm_class_init,
+static TypeInfo stellaris_gptm_info = {
+    .name          = "stellaris-gptm",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(gptm_state),
+    .class_init    = stellaris_gptm_class_init,
 };
 
 static void stellaris_adc_class_init(ObjectClass *klass, void *data)
@@ -1441,18 +1444,19 @@ static void stellaris_adc_class_init(ObjectClass *klass, void *data)
     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 TypeInfo stellaris_adc_info = {
+    .name          = "stellaris-adc",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(stellaris_adc_state),
+    .class_init    = stellaris_adc_class_init,
 };
 
 static void stellaris_register_devices(void)
 {
-    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);
+    type_register_static(&stellaris_i2c_info);
+    type_register_static(&stellaris_gptm_info);
+    type_register_static(&stellaris_adc_info);
+    type_register_static(&stellaris_ssi_bus_info);
 }
 
 device_init(stellaris_register_devices)
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index 3d3ef66..9b1be8d 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -427,21 +427,23 @@ static Property stellaris_enet_properties[] = {
 
 static void stellaris_enet_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = stellaris_enet_init;
+    dc->props = stellaris_enet_properties;
 }
 
-static DeviceInfo stellaris_enet_info = {
-    .name = "stellaris_enet",
-    .size = sizeof(stellaris_enet_state),
-    .props = stellaris_enet_properties,
-    .class_init = stellaris_enet_class_init,
+static TypeInfo stellaris_enet_info = {
+    .name          = "stellaris_enet",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(stellaris_enet_state),
+    .class_init    = stellaris_enet_class_init,
 };
 
 static void stellaris_enet_register_devices(void)
 {
-    sysbus_register_withprop(&stellaris_enet_info);
+    type_register_static(&stellaris_enet_info);
 }
 
 device_init(stellaris_enet_register_devices)
diff --git a/hw/strongarm.c b/hw/strongarm.c
index 15828bf..8d2e7eb 100644
--- a/hw/strongarm.c
+++ b/hw/strongarm.c
@@ -203,17 +203,19 @@ static VMStateDescription vmstate_strongarm_pic_regs = {
 
 static void strongarm_pic_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = strongarm_pic_initfn;
+    dc->desc = "StrongARM PIC";
+    dc->vmsd = &vmstate_strongarm_pic_regs;
 }
 
-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,
+static TypeInfo strongarm_pic_info = {
+    .name          = "strongarm_pic",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(StrongARMPICState),
+    .class_init    = strongarm_pic_class_init,
 };
 
 /* Real-Time Clock */
@@ -422,17 +424,19 @@ static const VMStateDescription vmstate_strongarm_rtc_regs = {
 
 static void strongarm_rtc_sysbus_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = strongarm_rtc_init;
+    dc->desc = "StrongARM RTC Controller";
+    dc->vmsd = &vmstate_strongarm_rtc_regs;
 }
 
-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,
+static TypeInfo strongarm_rtc_sysbus_info = {
+    .name          = "strongarm-rtc",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(StrongARMRTCState),
+    .class_init    = strongarm_rtc_sysbus_class_init,
 };
 
 /* GPIO */
@@ -662,16 +666,18 @@ static const VMStateDescription vmstate_strongarm_gpio_regs = {
 
 static void strongarm_gpio_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = strongarm_gpio_initfn;
+    dc->desc = "StrongARM GPIO controller";
 }
 
-static DeviceInfo strongarm_gpio_info = {
-    .name = "strongarm-gpio",
-    .desc = "StrongARM GPIO controller",
-    .size = sizeof(StrongARMGPIOInfo),
-    .class_init = strongarm_gpio_class_init,
+static TypeInfo strongarm_gpio_info = {
+    .name          = "strongarm-gpio",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(StrongARMGPIOInfo),
+    .class_init    = strongarm_gpio_class_init,
 };
 
 /* Peripheral Pin Controller */
@@ -826,16 +832,18 @@ static const VMStateDescription vmstate_strongarm_ppc_regs = {
 
 static void strongarm_ppc_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = strongarm_ppc_init;
+    dc->desc = "StrongARM PPC controller";
 }
 
-static DeviceInfo strongarm_ppc_info = {
-    .name = "strongarm-ppc",
-    .desc = "StrongARM PPC controller",
-    .size = sizeof(StrongARMPPCInfo),
-    .class_init = strongarm_ppc_class_init,
+static TypeInfo strongarm_ppc_info = {
+    .name          = "strongarm-ppc",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(StrongARMPPCInfo),
+    .class_init    = strongarm_ppc_class_init,
 };
 
 /* UART Ports */
@@ -1280,19 +1288,21 @@ static Property strongarm_uart_properties[] = {
 
 static void strongarm_uart_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = strongarm_uart_init;
+    dc->desc = "StrongARM UART controller";
+    dc->reset = strongarm_uart_reset;
+    dc->vmsd = &vmstate_strongarm_uart_regs;
+    dc->props = strongarm_uart_properties;
 }
 
-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,
+static TypeInfo strongarm_uart_info = {
+    .name          = "strongarm-uart",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(StrongARMUARTState),
+    .class_init    = strongarm_uart_class_init,
 };
 
 /* Synchronous Serial Ports */
@@ -1518,18 +1528,20 @@ static const VMStateDescription vmstate_strongarm_ssp_regs = {
 
 static void strongarm_ssp_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = strongarm_ssp_init;
+    dc->desc = "StrongARM SSP controller";
+    dc->reset = strongarm_ssp_reset;
+    dc->vmsd = &vmstate_strongarm_ssp_regs;
 }
 
-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,
+static TypeInfo strongarm_ssp_info = {
+    .name          = "strongarm-ssp",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(StrongARMSSPState),
+    .class_init    = strongarm_ssp_class_init,
 };
 
 /* Main CPU functions */
@@ -1599,11 +1611,11 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem,
 
 static void strongarm_register_devices(void)
 {
-    sysbus_register_withprop(&strongarm_pic_info);
-    sysbus_register_withprop(&strongarm_rtc_sysbus_info);
-    sysbus_register_withprop(&strongarm_gpio_info);
-    sysbus_register_withprop(&strongarm_ppc_info);
-    sysbus_register_withprop(&strongarm_uart_info);
-    sysbus_register_withprop(&strongarm_ssp_info);
+    type_register_static(&strongarm_pic_info);
+    type_register_static(&strongarm_rtc_sysbus_info);
+    type_register_static(&strongarm_gpio_info);
+    type_register_static(&strongarm_ppc_info);
+    type_register_static(&strongarm_uart_info);
+    type_register_static(&strongarm_ssp_info);
 }
 device_init(strongarm_register_devices)
diff --git a/hw/sun4c_intctl.c b/hw/sun4c_intctl.c
index 111d31b..081d6cc 100644
--- a/hw/sun4c_intctl.c
+++ b/hw/sun4c_intctl.c
@@ -208,22 +208,24 @@ static int sun4c_intctl_init1(SysBusDevice *dev)
 
 static void sun4c_intctl_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = sun4c_intctl_init1;
+    dc->reset = sun4c_intctl_reset;
+    dc->vmsd = &vmstate_sun4c_intctl;
 }
 
-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 TypeInfo sun4c_intctl_info = {
+    .name          = "sun4c_intctl",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(Sun4c_INTCTLState),
+    .class_init    = sun4c_intctl_class_init,
 };
 
 static void sun4c_intctl_register_devices(void)
 {
-    sysbus_register_withprop(&sun4c_intctl_info);
+    type_register_static(&sun4c_intctl_info);
 }
 
 device_init(sun4c_intctl_register_devices)
diff --git a/hw/sun4m.c b/hw/sun4m.c
index f2ff0bd..b79d14c 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -616,15 +616,16 @@ static void idreg_class_init(ObjectClass *klass, void *data)
     k->init = idreg_init1;
 }
 
-static DeviceInfo idreg_info = {
-    .name = "macio_idreg",
-    .size = sizeof(IDRegState),
-    .class_init = idreg_class_init,
+static TypeInfo idreg_info = {
+    .name          = "macio_idreg",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(IDRegState),
+    .class_init    = idreg_class_init,
 };
 
 static void idreg_register_devices(void)
 {
-    sysbus_register_withprop(&idreg_info);
+    type_register_static(&idreg_info);
 }
 
 device_init(idreg_register_devices);
@@ -664,15 +665,16 @@ static void afx_class_init(ObjectClass *klass, void *data)
     k->init = afx_init1;
 }
 
-static DeviceInfo afx_info = {
-    .name = "tcx_afx",
-    .size = sizeof(AFXState),
-    .class_init = afx_class_init,
+static TypeInfo afx_info = {
+    .name          = "tcx_afx",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(AFXState),
+    .class_init    = afx_class_init,
 };
 
 static void afx_register_devices(void)
 {
-    sysbus_register_withprop(&afx_info);
+    type_register_static(&afx_info);
 }
 
 device_init(afx_register_devices);
@@ -740,21 +742,23 @@ static Property prom_properties[] = {
 
 static void prom_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = prom_init1;
+    dc->props = prom_properties;
 }
 
-static DeviceInfo prom_info = {
-    .name = "openprom",
-    .size = sizeof(PROMState),
-    .props = prom_properties,
-    .class_init = prom_class_init,
+static TypeInfo prom_info = {
+    .name          = "openprom",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PROMState),
+    .class_init    = prom_class_init,
 };
 
 static void prom_register_devices(void)
 {
-    sysbus_register_withprop(&prom_info);
+    type_register_static(&prom_info);
 }
 
 device_init(prom_register_devices);
@@ -809,21 +813,23 @@ static Property ram_properties[] = {
 
 static void ram_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = ram_init1;
+    dc->props = ram_properties;
 }
 
-static DeviceInfo ram_info = {
-    .name = "memory",
-    .size = sizeof(RamDevice),
-    .props = ram_properties,
-    .class_init = ram_class_init,
+static TypeInfo ram_info = {
+    .name          = "memory",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(RamDevice),
+    .class_init    = ram_class_init,
 };
 
 static void ram_register_devices(void)
 {
-    sysbus_register_withprop(&ram_info);
+    type_register_static(&ram_info);
 }
 
 device_init(ram_register_devices);
diff --git a/hw/sun4m_iommu.c b/hw/sun4m_iommu.c
index 823bfac..727532c 100644
--- a/hw/sun4m_iommu.c
+++ b/hw/sun4m_iommu.c
@@ -364,23 +364,25 @@ static Property iommu_properties[] = {
 
 static void iommu_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = iommu_init1;
+    dc->reset = iommu_reset;
+    dc->vmsd = &vmstate_iommu;
+    dc->props = iommu_properties;
 }
 
-static DeviceInfo iommu_info = {
-    .name = "iommu",
-    .size = sizeof(IOMMUState),
-    .vmsd = &vmstate_iommu,
-    .reset = iommu_reset,
-    .props = iommu_properties,
-    .class_init = iommu_class_init,
+static TypeInfo iommu_info = {
+    .name          = "iommu",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(IOMMUState),
+    .class_init    = iommu_class_init,
 };
 
 static void iommu_register_devices(void)
 {
-    sysbus_register_withprop(&iommu_info);
+    type_register_static(&iommu_info);
 }
 
 device_init(iommu_register_devices)
diff --git a/hw/sun4u.c b/hw/sun4u.c
index f3bb226..79bbd49 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -573,15 +573,16 @@ static void ebus_class_init(ObjectClass *klass, void *data)
     k->class_id = PCI_CLASS_BRIDGE_OTHER;
 }
 
-static DeviceInfo ebus_info = {
-    .name = "ebus",
-    .size = sizeof(EbusState),
-    .class_init = ebus_class_init,
+static TypeInfo ebus_info = {
+    .name          = "ebus",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(EbusState),
+    .class_init    = ebus_class_init,
 };
 
 static void pci_ebus_register(void)
 {
-    pci_qdev_register(&ebus_info);
+    type_register_static(&ebus_info);
 }
 
 device_init(pci_ebus_register);
@@ -649,21 +650,23 @@ static Property prom_properties[] = {
 
 static void prom_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = prom_init1;
+    dc->props = prom_properties;
 }
 
-static DeviceInfo prom_info = {
-    .name = "openprom",
-    .size = sizeof(PROMState),
-    .props = prom_properties,
-    .class_init = prom_class_init,
+static TypeInfo prom_info = {
+    .name          = "openprom",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PROMState),
+    .class_init    = prom_class_init,
 };
 
 static void prom_register_devices(void)
 {
-    sysbus_register_withprop(&prom_info);
+    type_register_static(&prom_info);
 }
 
 device_init(prom_register_devices);
@@ -711,21 +714,23 @@ static Property ram_properties[] = {
 
 static void ram_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = ram_init1;
+    dc->props = ram_properties;
 }
 
-static DeviceInfo ram_info = {
-    .name = "memory",
-    .size = sizeof(RamDevice),
-    .props = ram_properties,
-    .class_init = ram_class_init,
+static TypeInfo ram_info = {
+    .name          = "memory",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(RamDevice),
+    .class_init    = ram_class_init,
 };
 
 static void ram_register_devices(void)
 {
-    sysbus_register_withprop(&ram_info);
+    type_register_static(&ram_info);
 }
 
 device_init(ram_register_devices);
diff --git a/hw/sysbus.c b/hw/sysbus.c
index 7d122f9..4870dbf 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -113,20 +113,6 @@ static int sysbus_device_init(DeviceState *dev, DeviceInfo *base)
     return sbc->init(sd);
 }
 
-void sysbus_qdev_register_subclass(DeviceInfo *info, const char *parent)
-{
-    info->init = sysbus_device_init;
-    info->bus_info = &system_bus_info;
-
-    assert(info->size >= sizeof(SysBusDevice));
-    qdev_register_subclass(info, parent);
-}
-
-void sysbus_qdev_register(DeviceInfo *info)
-{
-    sysbus_qdev_register_subclass(info, TYPE_SYS_BUS_DEVICE);
-}
-
 DeviceState *sysbus_create_varargs(const char *name,
                                    target_phys_addr_t addr, ...)
 {
@@ -254,12 +240,20 @@ MemoryRegion *sysbus_address_space(SysBusDevice *dev)
     return get_system_memory();
 }
 
+static void sysbus_device_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *k = DEVICE_CLASS(klass);
+    k->init = sysbus_device_init;
+    k->bus_info = &system_bus_info;
+}
+
 static TypeInfo sysbus_device_type_info = {
     .name = TYPE_SYS_BUS_DEVICE,
     .parent = TYPE_DEVICE,
     .instance_size = sizeof(SysBusDevice),
     .abstract = true,
     .class_size = sizeof(SysBusDeviceClass),
+    .class_init = sysbus_device_class_init,
 };
 
 static void sysbus_register(void)
diff --git a/hw/sysbus.h b/hw/sysbus.h
index a406077..22555cd 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -44,10 +44,6 @@ struct SysBusDevice {
 #define sysbus_from_qdev(dev) ((SysBusDevice *)(dev))
 #define FROM_SYSBUS(type, dev) DO_UPCAST(type, busdev, dev)
 
-#define sysbus_register_withprop(info) sysbus_qdev_register(info)
-void sysbus_qdev_register(DeviceInfo *info);
-void sysbus_qdev_register_subclass(DeviceInfo *info, const char *parent);
-
 void *sysbus_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 7743c05..f400f92 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -649,23 +649,25 @@ static Property tcx_properties[] = {
 
 static void tcx_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = tcx_init1;
+    dc->reset = tcx_reset;
+    dc->vmsd = &vmstate_tcx;
+    dc->props = tcx_properties;
 }
 
-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 TypeInfo tcx_info = {
+    .name          = "SUNW,tcx",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(TCXState),
+    .class_init    = tcx_class_init,
 };
 
 static void tcx_register_devices(void)
 {
-    sysbus_register_withprop(&tcx_info);
+    type_register_static(&tcx_info);
 }
 
 device_init(tcx_register_devices)
diff --git a/hw/tmp105.c b/hw/tmp105.c
index 12fe60d..a3bdd91 100644
--- a/hw/tmp105.c
+++ b/hw/tmp105.c
@@ -228,24 +228,26 @@ static int tmp105_init(I2CSlave *i2c)
 
 static void tmp105_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
 
     k->init = tmp105_init;
     k->event = tmp105_event;
     k->recv = tmp105_rx;
     k->send = tmp105_tx;
+    dc->vmsd = &vmstate_tmp105;
 }
 
-static DeviceInfo tmp105_info = {
-    .name = "tmp105",
-    .size = sizeof(TMP105State),
-    .vmsd = &vmstate_tmp105,
-    .class_init = tmp105_class_init,
+static TypeInfo tmp105_info = {
+    .name          = "tmp105",
+    .parent        = TYPE_I2C_SLAVE,
+    .instance_size = sizeof(TMP105State),
+    .class_init    = tmp105_class_init,
 };
 
 static void tmp105_register_devices(void)
 {
-    i2c_register_slave(&tmp105_info);
+    type_register_static(&tmp105_info);
 }
 
 device_init(tmp105_register_devices)
diff --git a/hw/tosa.c b/hw/tosa.c
index 9f112b1..c0d4017 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -269,11 +269,12 @@ static void tosa_dac_class_init(ObjectClass *klass, void *data)
     k->send = tosa_dac_send;
 }
 
-static DeviceInfo tosa_dac_info = {
-    .name = "tosa_dac",
-    .size = sizeof(TosaDACState),
-    .class_init = tosa_dac_class_init,
- };
+static TypeInfo tosa_dac_info = {
+    .name          = "tosa_dac",
+    .parent        = TYPE_I2C_SLAVE,
+    .instance_size = sizeof(TosaDACState),
+    .class_init    = tosa_dac_class_init,
+};
 
 static void tosa_ssp_class_init(ObjectClass *klass, void *data)
 {
@@ -283,16 +284,17 @@ static void tosa_ssp_class_init(ObjectClass *klass, void *data)
     k->transfer = tosa_ssp_tansfer;
 }
 
-static DeviceInfo tosa_ssp_info = {
-    .name = "tosa-ssp",
-    .size = sizeof(SSISlave),
-    .class_init = tosa_ssp_class_init,
+static TypeInfo tosa_ssp_info = {
+    .name          = "tosa-ssp",
+    .parent        = TYPE_SSI_SLAVE,
+    .instance_size = sizeof(SSISlave),
+    .class_init    = tosa_ssp_class_init,
 };
 
 static void tosa_register_devices(void)
 {
-    i2c_register_slave(&tosa_dac_info);
-    ssi_register_slave(&tosa_ssp_info);
+    type_register_static(&tosa_dac_info);
+    type_register_static(&tosa_ssp_info);
 }
 
 device_init(tosa_register_devices)
diff --git a/hw/tusb6010.c b/hw/tusb6010.c
index 8e11c54..0ade670 100644
--- a/hw/tusb6010.c
+++ b/hw/tusb6010.c
@@ -791,21 +791,23 @@ static int tusb6010_init(SysBusDevice *dev)
 
 static void tusb6010_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = tusb6010_init;
+    dc->reset = tusb6010_reset;
 }
 
-static DeviceInfo tusb6010_info = {
-    .name = "tusb6010",
-    .size = sizeof(TUSBState),
-    .reset = tusb6010_reset,
-    .class_init = tusb6010_class_init,
+static TypeInfo tusb6010_info = {
+    .name          = "tusb6010",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(TUSBState),
+    .class_init    = tusb6010_class_init,
 };
 
 static void tusb6010_register_device(void)
 {
-    sysbus_register_withprop(&tusb6010_info);
+    type_register_static(&tusb6010_info);
 }
 
 device_init(tusb6010_register_device)
diff --git a/hw/twl92230.c b/hw/twl92230.c
index ba4f8aa..03fdccc 100644
--- a/hw/twl92230.c
+++ b/hw/twl92230.c
@@ -859,24 +859,26 @@ static int twl92230_init(I2CSlave *i2c)
 
 static void twl92230_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
 
     sc->init = twl92230_init;
     sc->event = menelaus_event;
     sc->recv = menelaus_rx;
     sc->send = menelaus_tx;
+    dc->vmsd = &vmstate_menelaus;
 }
 
-static DeviceInfo twl92230_info = {
-    .name ="twl92230",
-    .size = sizeof(MenelausState),
-    .vmsd = &vmstate_menelaus,
-    .class_init = twl92230_class_init,
+static TypeInfo twl92230_info = {
+    .name          = "twl92230",
+    .parent        = TYPE_I2C_SLAVE,
+    .instance_size = sizeof(MenelausState),
+    .class_init    = twl92230_class_init,
 };
 
 static void twl92230_register_devices(void)
 {
-    i2c_register_slave(&twl92230_info);
+    type_register_static(&twl92230_info);
 }
 
 device_init(twl92230_register_devices)
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 9822353..17d86aa 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -350,9 +350,10 @@ static void unin_main_pci_host_class_init(ObjectClass *klass, void *data)
     k->class_id  = PCI_CLASS_BRIDGE_HOST;
 }
 
-static DeviceInfo unin_main_pci_host_info = {
+static TypeInfo unin_main_pci_host_info = {
     .name = "uni-north-pci",
-    .size = sizeof(PCIDevice),
+    .parent = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
     .class_init = unin_main_pci_host_class_init,
 };
 
@@ -367,9 +368,10 @@ static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data)
     k->class_id  = PCI_CLASS_BRIDGE_HOST;
 }
 
-static DeviceInfo u3_agp_pci_host_info = {
+static TypeInfo u3_agp_pci_host_info = {
     .name = "u3-agp",
-    .size = sizeof(PCIDevice),
+    .parent = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
     .class_init = u3_agp_pci_host_class_init,
 };
 
@@ -384,9 +386,10 @@ static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data)
     k->class_id  = PCI_CLASS_BRIDGE_HOST;
 }
 
-static DeviceInfo unin_agp_pci_host_info = {
+static TypeInfo unin_agp_pci_host_info = {
     .name = "uni-north-agp",
-    .size = sizeof(PCIDevice),
+    .parent = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
     .class_init = unin_agp_pci_host_class_init,
 };
 
@@ -401,9 +404,10 @@ static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data)
     k->class_id  = PCI_CLASS_BRIDGE_HOST;
 }
 
-static DeviceInfo unin_internal_pci_host_info = {
+static TypeInfo unin_internal_pci_host_info = {
     .name = "uni-north-internal-pci",
-    .size = sizeof(PCIDevice),
+    .parent = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
     .class_init = unin_internal_pci_host_class_init,
 };
 
@@ -414,10 +418,11 @@ static void pci_unin_main_class_init(ObjectClass *klass, void *data)
     sbc->init = pci_unin_main_init_device;
 }
 
-static DeviceInfo pci_unin_main_info = {
-    .name = "uni-north-pci-pcihost",
-    .size = sizeof(UNINState),
-    .class_init = pci_unin_main_class_init,
+static TypeInfo pci_unin_main_info = {
+    .name          = "uni-north-pci-pcihost",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(UNINState),
+    .class_init    = pci_unin_main_class_init,
 };
 
 static void pci_u3_agp_class_init(ObjectClass *klass, void *data)
@@ -427,10 +432,11 @@ static void pci_u3_agp_class_init(ObjectClass *klass, void *data)
     sbc->init = pci_u3_agp_init_device;
 }
 
-static DeviceInfo pci_u3_agp_info = {
-    .name = "u3-agp-pcihost",
-    .size = sizeof(UNINState),
-    .class_init = pci_u3_agp_class_init,
+static TypeInfo pci_u3_agp_info = {
+    .name          = "u3-agp-pcihost",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(UNINState),
+    .class_init    = pci_u3_agp_class_init,
 };
 
 static void pci_unin_agp_class_init(ObjectClass *klass, void *data)
@@ -440,10 +446,11 @@ static void pci_unin_agp_class_init(ObjectClass *klass, void *data)
     sbc->init = pci_unin_agp_init_device;
 }
 
-static DeviceInfo pci_unin_agp_info = {
-    .name = "uni-north-agp-pcihost",
-    .size = sizeof(UNINState),
-    .class_init = pci_unin_agp_class_init,
+static TypeInfo pci_unin_agp_info = {
+    .name          = "uni-north-agp-pcihost",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(UNINState),
+    .class_init    = pci_unin_agp_class_init,
 };
 
 static void pci_unin_internal_class_init(ObjectClass *klass, void *data)
@@ -453,23 +460,24 @@ static void pci_unin_internal_class_init(ObjectClass *klass, void *data)
     sbc->init = pci_unin_internal_init_device;
 }
 
-static DeviceInfo pci_unin_internal_info = {
-    .name = "uni-north-internal-pci-pcihost",
-    .size = sizeof(UNINState),
-    .class_init = pci_unin_internal_class_init,
+static TypeInfo pci_unin_internal_info = {
+    .name          = "uni-north-internal-pci-pcihost",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(UNINState),
+    .class_init    = pci_unin_internal_class_init,
 };
 
 static void unin_register_devices(void)
 {
-    pci_qdev_register(&unin_main_pci_host_info);
-    pci_qdev_register(&u3_agp_pci_host_info);
-    pci_qdev_register(&unin_agp_pci_host_info);
-    pci_qdev_register(&unin_internal_pci_host_info);
-
-    sysbus_register_withprop(&pci_unin_main_info);
-    sysbus_register_withprop(&pci_u3_agp_info);
-    sysbus_register_withprop(&pci_unin_agp_info);
-    sysbus_register_withprop(&pci_unin_internal_info);
+    type_register_static(&unin_main_pci_host_info);
+    type_register_static(&u3_agp_pci_host_info);
+    type_register_static(&unin_agp_pci_host_info);
+    type_register_static(&unin_internal_pci_host_info);
+
+    type_register_static(&pci_unin_main_info);
+    type_register_static(&pci_u3_agp_info);
+    type_register_static(&pci_unin_agp_info);
+    type_register_static(&pci_unin_internal_info);
 }
 
 device_init(unin_register_devices)
diff --git a/hw/usb-audio.c b/hw/usb-audio.c
index 561ae31..cd589b7 100644
--- a/hw/usb-audio.c
+++ b/hw/usb-audio.c
@@ -674,10 +674,20 @@ static const VMStateDescription vmstate_usb_audio = {
     .unmigratable = 1,
 };
 
+static Property usb_audio_properties[] = {
+    DEFINE_PROP_UINT32("debug", USBAudioState, debug, 0),
+    DEFINE_PROP_UINT32("buffer", USBAudioState, buffer,
+                       8 * USBAUDIO_PACKET_SIZE),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void usb_audio_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     USBDeviceClass *k = USB_DEVICE_CLASS(klass);
 
+    dc->vmsd          = &vmstate_usb_audio;
+    dc->props         = usb_audio_properties;
     k->product_desc   = "QEMU USB Audio Interface";
     k->usb_desc       = &desc_audio;
     k->init           = usb_audio_initfn;
@@ -689,22 +699,17 @@ static void usb_audio_class_init(ObjectClass *klass, void *data)
     k->set_interface  = usb_audio_set_interface;
 }
 
-static struct DeviceInfo usb_audio_info = {
-    .name      = "usb-audio",
-    .size      = sizeof(USBAudioState),
-    .vmsd      = &vmstate_usb_audio,
-    .class_init = usb_audio_class_init,
-    .props = (Property[]) {
-        DEFINE_PROP_UINT32("debug", USBAudioState, debug, 0),
-        DEFINE_PROP_UINT32("buffer", USBAudioState, buffer,
-                           8 * USBAUDIO_PACKET_SIZE),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static TypeInfo usb_audio_info = {
+    .name          = "usb-audio",
+    .parent        = TYPE_USB_DEVICE,
+    .instance_size = sizeof(USBAudioState),
+    .class_init    = usb_audio_class_init,
 };
 
 static void usb_audio_register_devices(void)
 {
-    usb_qdev_register(&usb_audio_info, "audio", NULL);
+    type_register_static(&usb_audio_info);
+    usb_legacy_register("usb-audio", "audio", NULL);
 }
 
 device_init(usb_audio_register_devices)
diff --git a/hw/usb-bt.c b/hw/usb-bt.c
index f497a44..90c3b0e 100644
--- a/hw/usb-bt.c
+++ b/hw/usb-bt.c
@@ -529,6 +529,7 @@ static const VMStateDescription vmstate_usb_bt = {
 
 static void usb_bt_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 
     uc->init           = usb_bt_initfn;
@@ -539,17 +540,18 @@ static void usb_bt_class_initfn(ObjectClass *klass, void *data)
     uc->handle_control = usb_bt_handle_control;
     uc->handle_data    = usb_bt_handle_data;
     uc->handle_destroy = usb_bt_handle_destroy;
+    dc->vmsd = &vmstate_usb_bt;
 }
 
-static struct DeviceInfo bt_info = {
-    .name      = "usb-bt-dongle",
-    .size      = sizeof(struct USBBtState),
-    .vmsd      = &vmstate_usb_bt,
-    .class_init= usb_bt_class_initfn,
+static TypeInfo bt_info = {
+    .name          = "usb-bt-dongle",
+    .parent        = TYPE_USB_DEVICE,
+    .instance_size = sizeof(struct USBBtState),
+    .class_init    = usb_bt_class_initfn,
 };
 
 static void usb_bt_register_devices(void)
 {
-    usb_qdev_register(&bt_info);
+    type_register_static(&bt_info);
 }
 device_init(usb_bt_register_devices)
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 6b0adfd..d07f844 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -220,15 +220,6 @@ void usb_legacy_register(const char *typename, const char *usbdevice_name,
     }
 }
 
-void usb_qdev_register(DeviceInfo *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);
-}
-
 USBDevice *usb_create(USBBus *bus, const char *name)
 {
     DeviceState *dev;
@@ -577,12 +568,22 @@ USBDevice *usbdevice_create(const char *cmdline)
     return f->usbdevice_init(params);
 }
 
+static void usb_device_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *k = DEVICE_CLASS(klass);
+    k->bus_info = &usb_bus_info;
+    k->init     = usb_qdev_init;
+    k->unplug   = qdev_simple_unplug_cb;
+    k->exit     = usb_qdev_exit;
+}
+
 static TypeInfo usb_device_type_info = {
     .name = TYPE_USB_DEVICE,
     .parent = TYPE_DEVICE,
     .instance_size = sizeof(USBDevice),
     .abstract = true,
     .class_size = sizeof(USBDeviceClass),
+    .class_init = usb_device_class_init,
 };
 
 static void usb_register_devices(void)
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index a261d7d..844f873 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -1184,14 +1184,6 @@ static int ccid_card_init(DeviceState *qdev, DeviceInfo *base)
     return ret;
 }
 
-void ccid_card_qdev_register(DeviceInfo *info)
-{
-    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)
 {
     USBCCIDState *s = DO_UPCAST(USBCCIDState, dev, dev);
@@ -1315,8 +1307,14 @@ static VMStateDescription ccid_vmstate = {
     }
 };
 
+static Property ccid_properties[] = {
+    DEFINE_PROP_UINT8("debug", USBCCIDState, debug, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void ccid_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 
     uc->init           = ccid_initfn;
@@ -1327,32 +1325,39 @@ static void ccid_class_initfn(ObjectClass *klass, void *data)
     uc->handle_control = ccid_handle_control;
     uc->handle_data    = ccid_handle_data;
     uc->handle_destroy = ccid_handle_destroy;
+    dc->desc = "CCID Rev 1.1 smartcard reader";
+    dc->vmsd = &ccid_vmstate;
+    dc->props = ccid_properties;
 }
 
-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(),
-    },
+static TypeInfo ccid_info = {
+    .name          = CCID_DEV_NAME,
+    .parent        = TYPE_USB_DEVICE,
+    .instance_size = sizeof(USBCCIDState),
+    .class_init    = ccid_class_initfn,
 };
 
+static void ccid_card_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *k = DEVICE_CLASS(klass);
+    k->bus_info = &ccid_bus_info;
+    k->init = ccid_card_init;
+    k->exit = ccid_card_exit;
+}
+
 static TypeInfo ccid_card_type_info = {
     .name = TYPE_CCID_CARD,
     .parent = TYPE_DEVICE,
     .instance_size = sizeof(CCIDCardState),
     .abstract = true,
     .class_size = sizeof(CCIDCardClass),
+    .class_init = ccid_card_class_init,
 };
 
 static void ccid_register_devices(void)
 {
     type_register_static(&ccid_card_type_info);
-    usb_qdev_register(&ccid_info);
+    type_register_static(&ccid_info);
     usb_legacy_register(CCID_DEV_NAME, "ccid", NULL);
 }
 device_init(ccid_register_devices)
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 8baff1d..75ef71e 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -2265,6 +2265,7 @@ static Property ehci_properties[] = {
 
 static void ehci_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = usb_ehci_initfn;
@@ -2272,18 +2273,20 @@ static void ehci_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_INTEL_82801D; /* ich4 */
     k->revision = 0x10;
     k->class_id = PCI_CLASS_SERIAL_USB;
+    dc->vmsd = &vmstate_ehci;
+    dc->props = ehci_properties;
 }
 
-static DeviceInfo ehci_info = {
-    .name = "usb-ehci",
-    .size = sizeof(EHCIState),
-    .vmsd = &vmstate_ehci,
-    .props = ehci_properties,
-    .class_init = ehci_class_init,
+static TypeInfo ehci_info = {
+    .name          = "usb-ehci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(EHCIState),
+    .class_init    = ehci_class_init,
 };
 
 static void ich9_ehci_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = usb_ehci_initfn;
@@ -2291,14 +2294,15 @@ static void ich9_ehci_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_INTEL_82801I_EHCI1;
     k->revision = 0x03;
     k->class_id = PCI_CLASS_SERIAL_USB;
+    dc->vmsd = &vmstate_ehci;
+    dc->props = ehci_properties;
 }
 
-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 TypeInfo ich9_ehci_info = {
+    .name          = "ich9-usb-ehci1",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(EHCIState),
+    .class_init    = ich9_ehci_class_init,
 };
 
 static int usb_ehci_initfn(PCIDevice *dev)
@@ -2374,8 +2378,8 @@ static int usb_ehci_initfn(PCIDevice *dev)
 
 static void ehci_register(void)
 {
-    pci_qdev_register(&ehci_info);
-    pci_qdev_register(&ich9_ehci_info);
+    type_register_static(&ehci_info);
+    type_register_static(&ich9_ehci_info);
 }
 device_init(ehci_register);
 
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 669aae4..3c4e45d 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -566,62 +566,68 @@ static void usb_hid_class_initfn(ObjectClass *klass, void *data)
 
 static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 
     usb_hid_class_initfn(klass, data);
     uc->init           = usb_tablet_initfn;
     uc->product_desc   = "QEMU USB Tablet";
     uc->usb_desc       = &desc_tablet;
+    dc->vmsd = &vmstate_usb_ptr;
 }
 
-static struct DeviceInfo usb_tablet_info = {
-    .name      = "usb-tablet",
-    .size      = sizeof(USBHIDState),
-    .vmsd      = &vmstate_usb_ptr,
-    .class_init= usb_tablet_class_initfn,
+static TypeInfo usb_tablet_info = {
+    .name          = "usb-tablet",
+    .parent        = TYPE_USB_DEVICE,
+    .instance_size = sizeof(USBHIDState),
+    .class_init    = usb_tablet_class_initfn,
 };
 
 static void usb_mouse_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 
     usb_hid_class_initfn(klass, data);
     uc->init           = usb_mouse_initfn;
     uc->product_desc   = "QEMU USB Mouse";
     uc->usb_desc       = &desc_mouse;
+    dc->vmsd = &vmstate_usb_ptr;
 }
 
-static struct DeviceInfo usb_mouse_info = {
-    .name      = "usb-mouse",
-    .size      = sizeof(USBHIDState),
-    .vmsd      = &vmstate_usb_ptr,
-    .class_init= usb_mouse_class_initfn,
+static TypeInfo usb_mouse_info = {
+    .name          = "usb-mouse",
+    .parent        = TYPE_USB_DEVICE,
+    .instance_size = sizeof(USBHIDState),
+    .class_init    = usb_mouse_class_initfn,
 };
 
 static void usb_keyboard_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 
     usb_hid_class_initfn(klass, data);
     uc->init           = usb_keyboard_initfn;
     uc->product_desc   = "QEMU USB Keyboard";
     uc->usb_desc       = &desc_keyboard;
+    dc->vmsd = &vmstate_usb_kbd;
 }
 
-static struct DeviceInfo usb_keyboard_info = {
-    .name      = "usb-kbd",
-    .size      = sizeof(USBHIDState),
-    .vmsd      = &vmstate_usb_kbd,
-    .class_init= usb_keyboard_class_initfn,
+static TypeInfo usb_keyboard_info = {
+    .name          = "usb-kbd",
+    .parent        = TYPE_USB_DEVICE,
+    .instance_size = sizeof(USBHIDState),
+    .class_init    = usb_keyboard_class_initfn,
 };
 
 static void usb_hid_register_devices(void)
 {
-    usb_qdev_register(&usb_tablet_info);
+    type_register_static(&usb_tablet_info);
     usb_legacy_register("usb-tablet", "tablet", NULL);
-    usb_qdev_register(&usb_mouse_info);
+    type_register_static(&usb_mouse_info);
     usb_legacy_register("usb-mouse", "mouse", NULL);
-    usb_qdev_register(&usb_keyboard_info);
+    type_register_static(&usb_keyboard_info);
     usb_legacy_register("usb-kbd", "keyboard", NULL);
 }
 device_init(usb_hid_register_devices)
diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index 3e33685..956b020 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -533,8 +533,9 @@ static const VMStateDescription vmstate_usb_hub = {
     }
 };
 
-static void  usb_hub_class_initfn(ObjectClass *klass, void *data)
+static void usb_hub_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 
     uc->init           = usb_hub_initfn;
@@ -545,18 +546,19 @@ static void  usb_hub_class_initfn(ObjectClass *klass, void *data)
     uc->handle_control = usb_hub_handle_control;
     uc->handle_data    = usb_hub_handle_data;
     uc->handle_destroy = usb_hub_handle_destroy;
+    dc->fw_name = "hub";
+    dc->vmsd = &vmstate_usb_hub;
 }
 
-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 TypeInfo hub_info = {
+    .name          = "usb-hub",
+    .parent        = TYPE_USB_DEVICE,
+    .instance_size = sizeof(USBHubState),
+    .class_init    = usb_hub_class_initfn,
 };
 
 static void usb_hub_register_devices(void)
 {
-    usb_qdev_register(&hub_info);
+    type_register_static(&hub_info);
 }
 device_init(usb_hub_register_devices)
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index 19d0d7b..6153376 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -636,8 +636,16 @@ static const VMStateDescription vmstate_usb_msd = {
     }
 };
 
+static Property msd_properties[] = {
+    DEFINE_BLOCK_PROPERTIES(MSDState, conf),
+    DEFINE_PROP_STRING("serial", MSDState, serial),
+    DEFINE_PROP_BIT("removable", MSDState, removable, 0, false),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void usb_msd_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 
     uc->init           = usb_msd_initfn;
@@ -649,25 +657,21 @@ static void usb_msd_class_initfn(ObjectClass *klass, void *data)
     uc->handle_reset   = usb_msd_handle_reset;
     uc->handle_control = usb_msd_handle_control;
     uc->handle_data    = usb_msd_handle_data;
+    dc->fw_name = "storage";
+    dc->vmsd = &vmstate_usb_msd;
+    dc->props = msd_properties;
 }
 
-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),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static TypeInfo msd_info = {
+    .name          = "usb-storage",
+    .parent        = TYPE_USB_DEVICE,
+    .instance_size = sizeof(MSDState),
+    .class_init    = usb_msd_class_initfn,
 };
 
 static void usb_msd_register_devices(void)
 {
-    usb_qdev_register(&msd_info);
+    type_register_static(&msd_info);
     usb_legacy_register("usb-storage", "disk", usb_msd_init);
 }
 device_init(usb_msd_register_devices)
diff --git a/hw/usb-net.c b/hw/usb-net.c
index 65eee95..e211141 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1385,8 +1385,14 @@ static const VMStateDescription vmstate_usb_net = {
     .unmigratable = 1,
 };
 
+static Property net_properties[] = {
+    DEFINE_NIC_PROPERTIES(USBNetState, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void usb_net_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 
     uc->init           = usb_net_initfn;
@@ -1397,23 +1403,21 @@ static void usb_net_class_initfn(ObjectClass *klass, void *data)
     uc->handle_control = usb_net_handle_control;
     uc->handle_data    = usb_net_handle_data;
     uc->handle_destroy = usb_net_handle_destroy;
+    dc->fw_name = "network";
+    dc->vmsd = &vmstate_usb_net;
+    dc->props = net_properties;
 }
 
-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 TypeInfo net_info = {
+    .name          = "usb-net",
+    .parent        = TYPE_USB_DEVICE,
+    .instance_size = sizeof(USBNetState),
+    .class_init    = usb_net_class_initfn,
 };
 
 static void usb_net_register_devices(void)
 {
-    usb_qdev_register(&net_info);
+    type_register_static(&net_info);
     usb_legacy_register("usb-net", "net", usb_net_init);
 }
 device_init(usb_net_register_devices)
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 3437da1..425030f 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1845,44 +1845,50 @@ static Property ohci_pci_properties[] = {
 
 static void ohci_pci_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     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;
+    dc->desc = "Apple USB Controller";
+    dc->props = ohci_pci_properties;
 }
 
-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 TypeInfo ohci_pci_info = {
+    .name          = "pci-ohci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(OHCIPCIState),
+    .class_init    = ohci_pci_class_init,
+};
+
+static Property ohci_sysbus_properties[] = {
+    DEFINE_PROP_UINT32("num-ports", OHCISysBusState, num_ports, 3),
+    DEFINE_PROP_TADDR("dma-offset", OHCISysBusState, dma_offset, 3),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
 static void ohci_sysbus_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
 
     sbc->init = ohci_init_pxa;
+    dc->desc = "OHCI USB Controller";
+    dc->props = ohci_sysbus_properties;
 }
 
-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(),
-    }
+static TypeInfo ohci_sysbus_info = {
+    .name          = "sysbus-ohci",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(OHCISysBusState),
+    .class_init    = ohci_sysbus_class_init,
 };
 
 static void ohci_register(void)
 {
-    pci_qdev_register(&ohci_pci_info);
-    sysbus_register_withprop(&ohci_sysbus_info);
+    type_register_static(&ohci_pci_info);
+    type_register_static(&ohci_sysbus_info);
 }
 device_init(ohci_register);
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
index 00b4985..c2cb6d2 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -570,8 +570,14 @@ static const VMStateDescription vmstate_usb_serial = {
     .unmigratable = 1,
 };
 
+static Property serial_properties[] = {
+    DEFINE_PROP_CHR("chardev", USBSerialState, cs),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void usb_serial_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 
     uc->init = usb_serial_initfn;
@@ -582,21 +588,25 @@ static void usb_serial_class_initfn(ObjectClass *klass, void *data)
     uc->handle_control = usb_serial_handle_control;
     uc->handle_data    = usb_serial_handle_data;
     uc->handle_destroy = usb_serial_handle_destroy;
+    dc->vmsd = &vmstate_usb_serial;
+    dc->props = serial_properties;
 }
 
-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 TypeInfo serial_info = {
+    .name          = "usb-serial",
+    .parent        = TYPE_USB_DEVICE,
+    .instance_size = sizeof(USBSerialState),
+    .class_init    = usb_serial_class_initfn,
+};
+
+static Property braille_properties[] = {
+    DEFINE_PROP_CHR("chardev", USBSerialState, cs),
+    DEFINE_PROP_END_OF_LIST(),
 };
 
 static void usb_braille_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 
     uc->init           = usb_serial_initfn;
@@ -607,24 +617,22 @@ static void usb_braille_class_initfn(ObjectClass *klass, void *data)
     uc->handle_control = usb_serial_handle_control;
     uc->handle_data    = usb_serial_handle_data;
     uc->handle_destroy = usb_serial_handle_destroy;
+    dc->vmsd = &vmstate_usb_serial;
+    dc->props = braille_properties;
 }
 
-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(),
-    },
+static TypeInfo braille_info = {
+    .name          = "usb-braille",
+    .parent        = TYPE_USB_DEVICE,
+    .instance_size = sizeof(USBSerialState),
+    .class_init    = usb_braille_class_initfn,
 };
 
 static void usb_serial_register_devices(void)
 {
-    usb_qdev_register(&serial_info);
+    type_register_static(&serial_info);
     usb_legacy_register("usb-serial", "serial", usb_serial_init);
-    usb_qdev_register(&braille_info);
+    type_register_static(&braille_info);
     usb_legacy_register("usb-braille", "braille", usb_braille_init);
 }
 device_init(usb_serial_register_devices)
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index e20d7c4..cddcc89 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1194,6 +1194,7 @@ static Property uhci_properties[] = {
 
 static void piix3_uhci_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = usb_uhci_common_initfn;
@@ -1202,18 +1203,20 @@ static void piix3_uhci_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_INTEL_82371SB_2;
     k->revision = 0x01;
     k->class_id = PCI_CLASS_SERIAL_USB;
+    dc->vmsd = &vmstate_uhci;
+    dc->props = uhci_properties;
 }
 
-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 TypeInfo piix3_uhci_info = {
+    .name          = "piix3-usb-uhci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(UHCIState),
+    .class_init    = piix3_uhci_class_init,
 };
 
 static void piix4_uhci_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = usb_uhci_common_initfn;
@@ -1222,18 +1225,20 @@ static void piix4_uhci_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_INTEL_82371AB_2;
     k->revision = 0x01;
     k->class_id = PCI_CLASS_SERIAL_USB;
+    dc->vmsd = &vmstate_uhci;
+    dc->props = uhci_properties;
 }
 
-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 TypeInfo piix4_uhci_info = {
+    .name          = "piix4-usb-uhci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(UHCIState),
+    .class_init    = piix4_uhci_class_init,
 };
 
 static void vt82c686b_uhci_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = usb_uhci_vt82c686b_initfn;
@@ -1242,18 +1247,20 @@ static void vt82c686b_uhci_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIA_UHCI;
     k->revision = 0x01;
     k->class_id = PCI_CLASS_SERIAL_USB;
+    dc->vmsd = &vmstate_uhci;
+    dc->props = uhci_properties;
 }
 
-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 TypeInfo vt82c686b_uhci_info = {
+    .name          = "vt82c686b-usb-uhci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(UHCIState),
+    .class_init    = vt82c686b_uhci_class_init,
 };
 
 static void ich9_uhci1_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = usb_uhci_common_initfn;
@@ -1261,18 +1268,20 @@ static void ich9_uhci1_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI1;
     k->revision = 0x03;
     k->class_id = PCI_CLASS_SERIAL_USB;
+    dc->vmsd = &vmstate_uhci;
+    dc->props = uhci_properties;
 }
 
-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 TypeInfo ich9_uhci1_info = {
+    .name          = "ich9-usb-uhci1",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(UHCIState),
+    .class_init    = ich9_uhci1_class_init,
 };
 
 static void ich9_uhci2_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = usb_uhci_common_initfn;
@@ -1280,18 +1289,20 @@ static void ich9_uhci2_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI2;
     k->revision = 0x03;
     k->class_id = PCI_CLASS_SERIAL_USB;
+    dc->vmsd = &vmstate_uhci;
+    dc->props = uhci_properties;
 }
 
-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 TypeInfo ich9_uhci2_info = {
+    .name          = "ich9-usb-uhci2",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(UHCIState),
+    .class_init    = ich9_uhci2_class_init,
 };
 
 static void ich9_uhci3_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = usb_uhci_common_initfn;
@@ -1299,24 +1310,25 @@ static void ich9_uhci3_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI3;
     k->revision = 0x03;
     k->class_id = PCI_CLASS_SERIAL_USB;
+    dc->vmsd = &vmstate_uhci;
+    dc->props = uhci_properties;
 }
 
-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 TypeInfo ich9_uhci3_info = {
+    .name          = "ich9-usb-uhci3",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(UHCIState),
+    .class_init    = ich9_uhci3_class_init,
 };
 
 static void uhci_register(void)
 {
-    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);
+    type_register_static(&piix3_uhci_info);
+    type_register_static(&piix4_uhci_info);
+    type_register_static(&vt82c686b_uhci_info);
+    type_register_static(&ich9_uhci1_info);
+    type_register_static(&ich9_uhci2_info);
+    type_register_static(&ich9_uhci3_info);
 }
 device_init(uhci_register);
 
diff --git a/hw/usb-wacom.c b/hw/usb-wacom.c
index 40bb199..14de14d 100644
--- a/hw/usb-wacom.c
+++ b/hw/usb-wacom.c
@@ -349,9 +349,10 @@ static const VMStateDescription vmstate_usb_wacom = {
     .unmigratable = 1,
 };
 
-static void usb_wacom_class_init(ObjectClass *class, void *data)
+static void usb_wacom_class_init(ObjectClass *klass, void *data)
 {
-    USBDeviceClass *uc = USB_DEVICE_CLASS(class);
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 
     uc->product_desc   = "QEMU PenPartner Tablet";
     uc->usb_desc       = &desc_wacom;
@@ -361,19 +362,20 @@ static void usb_wacom_class_init(ObjectClass *class, void *data)
     uc->handle_control = usb_wacom_handle_control;
     uc->handle_data    = usb_wacom_handle_data;
     uc->handle_destroy = usb_wacom_handle_destroy;
+    dc->desc = "QEMU PenPartner Tablet";
+    dc->vmsd = &vmstate_usb_wacom;
 }
 
-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 TypeInfo wacom_info = {
+    .name          = "usb-wacom-tablet",
+    .parent        = TYPE_USB_DEVICE,
+    .instance_size = sizeof(USBWacomState),
+    .class_init    = usb_wacom_class_init,
 };
 
 static void usb_wacom_register_devices(void)
 {
-    usb_qdev_register(&wacom_info);
+    type_register_static(&wacom_info);
     usb_legacy_register("usb-wacom-tablet", "wacom-tablet", NULL);
 }
 device_init(usb_wacom_register_devices)
diff --git a/hw/usb-xhci.c b/hw/usb-xhci.c
index fba2de3..37e887c 100644
--- a/hw/usb-xhci.c
+++ b/hw/usb-xhci.c
@@ -2724,10 +2724,18 @@ static const VMStateDescription vmstate_xhci = {
     .unmigratable = 1,
 };
 
+static Property xhci_properties[] = {
+    DEFINE_PROP_UINT32("msi", XHCIState, msi, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void xhci_class_init(ObjectClass *klass, void *data)
 {
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
+    dc->vmsd    = &vmstate_xhci;
+    dc->props   = xhci_properties;
     k->init         = usb_xhci_initfn;
     k->vendor_id    = PCI_VENDOR_ID_NEC;
     k->device_id    = PCI_DEVICE_ID_NEC_UPD720200;
@@ -2737,20 +2745,15 @@ static void xhci_class_init(ObjectClass *klass, void *data)
     k->config_write = xhci_write_config;
 }
 
-static DeviceInfo xhci_info = {
-    .name    = "nec-usb-xhci",
-    .alias   = "xhci",
-    .size    = sizeof(XHCIState),
-    .vmsd    = &vmstate_xhci,
-    .class_init   = xhci_class_init,
-    .props   = (Property[]) {
-        DEFINE_PROP_UINT32("msi", XHCIState, msi, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static TypeInfo xhci_info = {
+    .name          = "nec-usb-xhci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(XHCIState),
+    .class_init    = xhci_class_init,
 };
 
 static void xhci_register(void)
 {
-    pci_qdev_register(&xhci_info);
+    type_register_static(&xhci_info);
 }
 device_init(xhci_register);
diff --git a/hw/usb.h b/hw/usb.h
index b9b6742..13e7c8e 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -418,7 +418,6 @@ struct USBBusOps {
 
 void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host);
 USBBus *usb_bus_find(int busnr);
-void usb_qdev_register(DeviceInfo *info);
 void usb_legacy_register(const char *typename, const char *usbdevice_name,
                          USBDevice *(*usbdevice_init)(const char *params));
 USBDevice *usb_create(USBBus *bus, const char *name);
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index c2eb4dd..c4105e9 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -119,10 +119,11 @@ static void versatile_pci_host_class_init(ObjectClass *klass, void *data)
     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 TypeInfo versatile_pci_host_info = {
+    .name          = "versatile_pci_host",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
+    .class_init    = versatile_pci_host_class_init,
 };
 
 static void pci_vpb_class_init(ObjectClass *klass, void *data)
@@ -132,10 +133,11 @@ static void pci_vpb_class_init(ObjectClass *klass, void *data)
     sdc->init = pci_vpb_init;
 }
 
-static DeviceInfo pci_vpb_info = {
-    .name = "versatile_pci",
-    .size = sizeof(PCIVPBState),
-    .class_init = pci_vpb_class_init,
+static TypeInfo pci_vpb_info = {
+    .name          = "versatile_pci",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PCIVPBState),
+    .class_init    = pci_vpb_class_init,
 };
 
 static void pci_realview_class_init(ObjectClass *klass, void *data)
@@ -145,17 +147,18 @@ static void pci_realview_class_init(ObjectClass *klass, void *data)
     sdc->init = pci_realview_init;
 }
 
-static DeviceInfo pci_realview_info = {
-    .name = "realview_pci",
-    .size = sizeof(PCIVPBState),
-    .class_init = pci_realview_class_init,
+static TypeInfo pci_realview_info = {
+    .name          = "realview_pci",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PCIVPBState),
+    .class_init    = pci_realview_class_init,
 };
 
 static void versatile_pci_register_devices(void)
 {
-    sysbus_qdev_register(&pci_vpb_info);
-    sysbus_qdev_register(&pci_realview_info);
-    pci_qdev_register(&versatile_pci_host_info);
+    type_register_static(&pci_vpb_info);
+    type_register_static(&pci_realview_info);
+    type_register_static(&versatile_pci_host_info);
 }
 
 device_init(versatile_pci_register_devices)
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 3f7490c..6e28e78 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -367,22 +367,24 @@ machine_init(versatile_machine_init);
 
 static void vpb_sic_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = vpb_sic_init;
+    dc->no_user = 1;
+    dc->vmsd = &vmstate_vpb_sic;
 }
 
-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 TypeInfo vpb_sic_info = {
+    .name          = "versatilepb_sic",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(vpb_sic_state),
+    .class_init    = vpb_sic_class_init,
 };
 
 static void versatilepb_register_devices(void)
 {
-    sysbus_register_withprop(&vpb_sic_info);
+    type_register_static(&vpb_sic_info);
 }
 
 device_init(versatilepb_register_devices)
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index cb6af91..8d3ff0d 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -71,20 +71,22 @@ static int vga_initfn(ISADevice *dev)
 
 static void vga_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = vga_initfn;
+    dc->reset = vga_reset_isa;
+    dc->vmsd = &vmstate_vga_common;
 }
 
-static DeviceInfo vga_info = {
-    .name     = "isa-vga",
-    .size     = sizeof(ISAVGAState),
-    .vmsd     = &vmstate_vga_common,
-    .reset     = vga_reset_isa,
-    .class_init          = vga_class_initfn,
+static TypeInfo vga_info = {
+    .name          = "isa-vga",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(ISAVGAState),
+    .class_init    = vga_class_initfn,
 };
 
 static void vga_register(void)
 {
-    isa_qdev_register(&vga_info);
+    type_register_static(&vga_info);
 }
 device_init(vga_register)
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index ef9f8a5..974a7a9 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -77,6 +77,7 @@ DeviceState *pci_vga_init(PCIBus *bus)
 
 static void vga_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->no_hotplug = 1;
@@ -85,17 +86,18 @@ static void vga_class_init(ObjectClass *klass, void *data)
     k->vendor_id = PCI_VENDOR_ID_QEMU;
     k->device_id = PCI_DEVICE_ID_QEMU_VGA;
     k->class_id = PCI_CLASS_DISPLAY_VGA;
+    dc->vmsd = &vmstate_vga_pci;
 }
 
-static DeviceInfo vga_info = {
-    .name = "VGA",
-    .size = sizeof(PCIVGAState),
-    .vmsd = &vmstate_vga_pci,
-    .class_init = vga_class_init,
+static TypeInfo vga_info = {
+    .name          = "VGA",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIVGAState),
+    .class_init    = vga_class_init,
 };
 
 static void vga_register(void)
 {
-    pci_qdev_register(&vga_info);
+    type_register_static(&vga_info);
 }
 device_init(vga_register);
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 73c3935..4f2c3e4 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -131,6 +131,7 @@ static Property virtconsole_properties[] = {
 
 static void virtconsole_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
 
     k->is_console = true;
@@ -138,18 +139,19 @@ static void virtconsole_class_init(ObjectClass *klass, void *data)
     k->have_data = flush_buf;
     k->guest_open = guest_open;
     k->guest_close = guest_close;
+    dc->props = virtconsole_properties;
 }
 
-static DeviceInfo virtconsole_info = {
-    .name = "virtconsole",
-    .size = sizeof(VirtConsole),
-    .props = virtconsole_properties,
-    .class_init = virtconsole_class_init,
+static TypeInfo virtconsole_info = {
+    .name          = "virtconsole",
+    .parent        = TYPE_VIRTIO_SERIAL_PORT,
+    .instance_size = sizeof(VirtConsole),
+    .class_init    = virtconsole_class_init,
 };
 
 static void virtconsole_register(void)
 {
-    virtio_serial_port_qdev_register(&virtconsole_info);
+    type_register_static(&virtconsole_info);
 }
 device_init(virtconsole_register)
 
@@ -160,23 +162,25 @@ static Property virtserialport_properties[] = {
 
 static void virtserialport_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
 
     k->init = virtconsole_initfn;
     k->have_data = flush_buf;
     k->guest_open = guest_open;
     k->guest_close = guest_close;
+    dc->props = virtserialport_properties;
 }
 
-static DeviceInfo virtserialport_info = {
-    .name = "virtserialport",
-    .size = sizeof(VirtConsole),
-    .props = virtserialport_properties,
-    .class_init = virtserialport_class_init,
+static TypeInfo virtserialport_info = {
+    .name          = "virtserialport",
+    .parent        = TYPE_VIRTIO_SERIAL_PORT,
+    .instance_size = sizeof(VirtConsole),
+    .class_init    = virtserialport_class_init,
 };
 
 static void virtserialport_register(void)
 {
-    virtio_serial_port_qdev_register(&virtserialport_info);
+    type_register_static(&virtserialport_info);
 }
 device_init(virtserialport_register)
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 126fb08..bc96552 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -818,6 +818,7 @@ static Property virtio_blk_properties[] = {
 
 static void virtio_blk_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = virtio_blk_init_pci;
@@ -826,15 +827,16 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIRTIO_BLOCK;
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = PCI_CLASS_STORAGE_SCSI;
+    dc->alias = "virtio-blk";
+    dc->reset = virtio_pci_reset;
+    dc->props = virtio_blk_properties;
 }
 
-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 TypeInfo virtio_blk_info = {
+    .name          = "virtio-blk-pci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(VirtIOPCIProxy),
+    .class_init    = virtio_blk_class_init,
 };
 
 static Property virtio_net_properties[] = {
@@ -850,6 +852,7 @@ static Property virtio_net_properties[] = {
 
 static void virtio_net_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = virtio_net_init_pci;
@@ -859,15 +862,16 @@ static void virtio_net_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIRTIO_NET;
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
+    dc->alias = "virtio-net";
+    dc->reset = virtio_pci_reset;
+    dc->props = virtio_net_properties;
 }
 
-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 TypeInfo virtio_net_info = {
+    .name          = "virtio-net-pci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(VirtIOPCIProxy),
+    .class_init    = virtio_net_class_init,
 };
 
 static Property virtio_serial_properties[] = {
@@ -881,6 +885,7 @@ static Property virtio_serial_properties[] = {
 
 static void virtio_serial_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = virtio_serial_init_pci;
@@ -889,15 +894,16 @@ static void virtio_serial_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE;
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
+    dc->alias = "virtio-serial";
+    dc->reset = virtio_pci_reset;
+    dc->props = virtio_serial_properties;
 }
 
-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 TypeInfo virtio_serial_info = {
+    .name          = "virtio-serial-pci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(VirtIOPCIProxy),
+    .class_init    = virtio_serial_class_init,
 };
 
 static Property virtio_balloon_properties[] = {
@@ -907,6 +913,7 @@ static Property virtio_balloon_properties[] = {
 
 static void virtio_balloon_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = virtio_balloon_init_pci;
@@ -915,23 +922,28 @@ static void virtio_balloon_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIRTIO_BALLOON;
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = PCI_CLASS_MEMORY_RAM;
+    dc->alias = "virtio-balloon";
+    dc->reset = virtio_pci_reset;
+    dc->props = virtio_balloon_properties;
 }
 
-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 TypeInfo virtio_balloon_info = {
+    .name          = "virtio-balloon-pci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(VirtIOPCIProxy),
+    .class_init    = virtio_balloon_class_init,
 };
 
 static void virtio_pci_register_devices(void)
 {
-    pci_qdev_register(&virtio_blk_info);
-    pci_qdev_register(&virtio_net_info);
-    pci_qdev_register(&virtio_serial_info);
-    pci_qdev_register(&virtio_balloon_info);
+    type_register_static(&virtio_blk_info);
+    type_register_static_alias(&virtio_blk_info, "virtio-blk");
+    type_register_static(&virtio_net_info);
+    type_register_static_alias(&virtio_net_info, "virtio-net");
+    type_register_static(&virtio_serial_info);
+    type_register_static_alias(&virtio_serial_info, "virtio-serial");
+    type_register_static(&virtio_balloon_info);
+    type_register_static_alias(&virtio_balloon_info, "virtio-balloon");
 }
 
 device_init(virtio_pci_register_devices)
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 70f5d48..50a6d7f 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -837,15 +837,6 @@ static int virtser_port_qdev_exit(DeviceState *qdev)
     return 0;
 }
 
-void virtio_serial_port_qdev_register(DeviceInfo *info)
-{
-    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)
 {
     VirtIOSerial *vser;
@@ -940,12 +931,22 @@ void virtio_serial_exit(VirtIODevice *vdev)
     virtio_cleanup(vdev);
 }
 
+static void virtio_serial_port_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *k = DEVICE_CLASS(klass);
+    k->init = virtser_port_qdev_init;
+    k->bus_info = &virtser_bus_info;
+    k->exit = virtser_port_qdev_exit;
+    k->unplug = qdev_simple_unplug_cb;
+}
+
 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),
+    .class_init = virtio_serial_port_class_init,
 };
 
 static void virtio_serial_register_devices(void)
diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
index 6207c89..16e3982 100644
--- a/hw/virtio-serial.h
+++ b/hw/virtio-serial.h
@@ -176,12 +176,6 @@ struct VirtIOSerialPort {
 /* 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(DeviceInfo *info);
-
-/*
  * Open a connection to the port
  *   Returns 0 on success (always).
  */
diff --git a/hw/vmmouse.c b/hw/vmmouse.c
index da2ea32..3a178b0 100644
--- a/hw/vmmouse.c
+++ b/hw/vmmouse.c
@@ -269,27 +269,31 @@ static int vmmouse_initfn(ISADevice *dev)
     return 0;
 }
 
+static Property vmmouse_properties[] = {
+    DEFINE_PROP_PTR("ps2_mouse", VMMouseState, ps2_mouse),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void vmmouse_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = vmmouse_initfn;
+    dc->no_user = 1;
+    dc->reset = vmmouse_reset;
+    dc->vmsd = &vmstate_vmmouse;
+    dc->props = vmmouse_properties;
 }
 
-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(),
-    }
+static TypeInfo vmmouse_info = {
+    .name          = "vmmouse",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(VMMouseState),
+    .class_init    = vmmouse_class_initfn,
 };
 
 static void vmmouse_dev_register(void)
 {
-    isa_qdev_register(&vmmouse_info);
+    type_register_static(&vmmouse_info);
 }
 device_init(vmmouse_dev_register)
diff --git a/hw/vmport.c b/hw/vmport.c
index c4582d6..a2c45e1 100644
--- a/hw/vmport.c
+++ b/hw/vmport.c
@@ -146,19 +146,21 @@ static int vmport_initfn(ISADevice *dev)
 
 static void vmport_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = vmport_initfn;
+    dc->no_user = 1;
 }
 
-static DeviceInfo vmport_info = {
-    .name     = "vmport",
-    .size     = sizeof(VMPortState),
-    .no_user  = 1,
-    .class_init          = vmport_class_initfn,
+static TypeInfo vmport_info = {
+    .name          = "vmport",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(VMPortState),
+    .class_init    = vmport_class_initfn,
 };
 
 static void vmport_dev_register(void)
 {
-    isa_qdev_register(&vmport_info);
+    type_register_static(&vmport_info);
 }
 device_init(vmport_dev_register)
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index e7bbf7c..3f3eb21 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1201,6 +1201,7 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
 
 static void vmsvga_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->no_hotplug = 1;
@@ -1211,18 +1212,19 @@ static void vmsvga_class_init(ObjectClass *klass, void *data)
     k->class_id = PCI_CLASS_DISPLAY_VGA;
     k->subsystem_vendor_id = PCI_VENDOR_ID_VMWARE;
     k->subsystem_id = SVGA_PCI_DEVICE_ID;
+    dc->reset = vmsvga_reset;
+    dc->vmsd = &vmstate_vmware_vga;
 }
 
-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 TypeInfo vmsvga_info = {
+    .name          = "vmware-svga",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(struct pci_vmsvga_state_s),
+    .class_init    = vmsvga_class_init,
 };
 
 static void vmsvga_register(void)
 {
-    pci_qdev_register(&vmsvga_info);
+    type_register_static(&vmsvga_info);
 }
 device_init(vmsvga_register);
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index 72be4fd..aa0954f 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -348,6 +348,7 @@ void vt82c686b_ac97_init(PCIBus *bus, int devfn)
 
 static void via_ac97_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = vt82c686b_ac97_initfn;
@@ -355,18 +356,19 @@ static void via_ac97_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIA_AC97;
     k->revision = 0x50;
     k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+    dc->desc = "AC97";
 }
 
-static DeviceInfo via_ac97_info = {
-    .name = "VT82C686B_AC97",
-    .desc = "AC97",
-    .size = sizeof(VT686AC97State),
-    .class_init = via_ac97_class_init,
+static TypeInfo via_ac97_info = {
+    .name          = "VT82C686B_AC97",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(VT686AC97State),
+    .class_init    = via_ac97_class_init,
 };
 
 static void vt82c686b_ac97_register(void)
 {
-    pci_qdev_register(&via_ac97_info);
+    type_register_static(&via_ac97_info);
 }
 
 device_init(vt82c686b_ac97_register);
@@ -394,6 +396,7 @@ void vt82c686b_mc97_init(PCIBus *bus, int devfn)
 
 static void via_mc97_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = vt82c686b_mc97_initfn;
@@ -401,18 +404,19 @@ static void via_mc97_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIA_MC97;
     k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
     k->revision = 0x30;
+    dc->desc = "MC97";
 }
 
-static DeviceInfo via_mc97_info = {
-    .name = "VT82C686B_MC97",
-    .desc = "MC97",
-    .size = sizeof(VT686MC97State),
-    .class_init = via_mc97_class_init,
+static TypeInfo via_mc97_info = {
+    .name          = "VT82C686B_MC97",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(VT686MC97State),
+    .class_init    = via_mc97_class_init,
 };
 
 static void vt82c686b_mc97_register(void)
 {
-    pci_qdev_register(&via_mc97_info);
+    type_register_static(&via_mc97_info);
 }
 
 device_init(vt82c686b_mc97_register);
@@ -472,6 +476,7 @@ static Property via_pm_properties[] = {
 
 static void via_pm_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = vt82c686b_pm_initfn;
@@ -480,20 +485,21 @@ static void via_pm_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIA_ACPI;
     k->class_id = PCI_CLASS_BRIDGE_OTHER;
     k->revision = 0x40;
+    dc->desc = "PM";
+    dc->vmsd = &vmstate_acpi;
+    dc->props = via_pm_properties;
 }
 
-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 TypeInfo via_pm_info = {
+    .name          = "VT82C686B_PM",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(VT686PMState),
+    .class_init    = via_pm_class_init,
 };
 
 static void vt82c686b_pm_register(void)
 {
-    pci_qdev_register(&via_pm_info);
+    type_register_static(&via_pm_info);
 }
 
 device_init(vt82c686b_pm_register);
@@ -544,6 +550,7 @@ ISABus *vt82c686b_init(PCIBus *bus, int devfn)
 
 static void via_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = vt82c686b_initfn;
@@ -552,19 +559,20 @@ static void via_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIA_ISA_BRIDGE;
     k->class_id = PCI_CLASS_BRIDGE_ISA;
     k->revision = 0x40;
+    dc->desc = "ISA bridge";
+    dc->no_user = 1;
+    dc->vmsd = &vmstate_via;
 }
 
-static DeviceInfo via_info = {
-    .name = "VT82C686B",
-    .desc = "ISA bridge",
-    .size = sizeof(VT82C686BState),
-    .vmsd = &vmstate_via,
-    .no_user = 1,
-    .class_init = via_class_init,
+static TypeInfo via_info = {
+    .name          = "VT82C686B",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(VT82C686BState),
+    .class_init    = via_class_init,
 };
 
 static void vt82c686b_register(void)
 {
-    pci_qdev_register(&via_info);
+    type_register_static(&via_info);
 }
 device_init(vt82c686b_register);
diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c
index a6ceff8..41325f0 100644
--- a/hw/wdt_i6300esb.c
+++ b/hw/wdt_i6300esb.c
@@ -427,6 +427,7 @@ static WatchdogTimerModel model = {
 
 static void i6300esb_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->config_read = i6300esb_config_read;
@@ -436,20 +437,21 @@ static void i6300esb_class_init(ObjectClass *klass, void *data)
     k->vendor_id = PCI_VENDOR_ID_INTEL;
     k->device_id = PCI_DEVICE_ID_INTEL_ESB_9;
     k->class_id = PCI_CLASS_SYSTEM_OTHER;
+    dc->reset = i6300esb_reset;
+    dc->vmsd = &vmstate_i6300esb;
 }
 
-static DeviceInfo i6300esb_info = {
-    .name = "i6300esb",
-    .size = sizeof(I6300State),
-    .vmsd = &vmstate_i6300esb,
-    .reset = i6300esb_reset,
-    .class_init = i6300esb_class_init,
+static TypeInfo i6300esb_info = {
+    .name          = "i6300esb",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(I6300State),
+    .class_init    = i6300esb_class_init,
 };
 
 static void i6300esb_register_devices(void)
 {
     watchdog_add_model(&model);
-    pci_qdev_register(&i6300esb_info);
+    type_register_static(&i6300esb_info);
 }
 
 device_init(i6300esb_register_devices);
diff --git a/hw/wdt_ib700.c b/hw/wdt_ib700.c
index 6deb0de..8faa231 100644
--- a/hw/wdt_ib700.c
+++ b/hw/wdt_ib700.c
@@ -122,22 +122,24 @@ static WatchdogTimerModel model = {
 
 static void wdt_ib700_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
     ic->init = wdt_ib700_init;
+    dc->reset = wdt_ib700_reset;
+    dc->vmsd = &vmstate_ib700;
 }
 
-static DeviceInfo wdt_ib700_info = {
-    .name  = "ib700",
-    .size  = sizeof(IB700State),
-    .vmsd  = &vmstate_ib700,
-    .reset = wdt_ib700_reset,
-    .class_init       = wdt_ib700_class_init,
+static TypeInfo wdt_ib700_info = {
+    .name          = "ib700",
+    .parent        = TYPE_ISA_DEVICE,
+    .instance_size = sizeof(IB700State),
+    .class_init    = wdt_ib700_class_init,
 };
 
 static void wdt_ib700_register_devices(void)
 {
     watchdog_add_model(&model);
-    isa_qdev_register(&wdt_ib700_info);
+    type_register_static(&wdt_ib700_info);
 }
 
 device_init(wdt_ib700_register_devices);
diff --git a/hw/wm8750.c b/hw/wm8750.c
index 33bce0d..18afa4c 100644
--- a/hw/wm8750.c
+++ b/hw/wm8750.c
@@ -691,24 +691,26 @@ void wm8750_set_bclk_in(void *opaque, int new_hz)
 
 static void wm8750_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
 
     sc->init = wm8750_init;
     sc->event = wm8750_event;
     sc->recv = wm8750_rx;
     sc->send = wm8750_tx;
+    dc->vmsd = &vmstate_wm8750;
 }
 
-static DeviceInfo wm8750_info = {
-    .name = "wm8750",
-    .size = sizeof(WM8750State),
-    .vmsd = &vmstate_wm8750,
-    .class_init = wm8750_class_init,
+static TypeInfo wm8750_info = {
+    .name          = "wm8750",
+    .parent        = TYPE_I2C_SLAVE,
+    .instance_size = sizeof(WM8750State),
+    .class_init    = wm8750_class_init,
 };
 
 static void wm8750_register_devices(void)
 {
-    i2c_register_slave(&wm8750_info);
+    type_register_static(&wm8750_info);
 }
 
 device_init(wm8750_register_devices)
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index 40687fb..e757102 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -374,6 +374,7 @@ static void platform_reset(DeviceState *dev)
 
 static void xen_platform_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = xen_platform_initfn;
@@ -383,20 +384,21 @@ static void xen_platform_class_init(ObjectClass *klass, void *data)
     k->subsystem_vendor_id = PCI_VENDOR_ID_XEN;
     k->subsystem_id = PCI_DEVICE_ID_XEN_PLATFORM;
     k->revision = 1;
+    dc->desc = "XEN platform pci device";
+    dc->reset = platform_reset;
+    dc->vmsd = &vmstate_xen_platform;
 }
 
-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 TypeInfo xen_platform_info = {
+    .name          = "xen-platform",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIXenPlatformState),
+    .class_init    = xen_platform_class_init,
 };
 
 static void xen_platform_register(void)
 {
-    pci_qdev_register(&xen_platform_info);
+    type_register_static(&xen_platform_info);
 }
 
 device_init(xen_platform_register);
diff --git a/hw/xgmac.c b/hw/xgmac.c
index 73840c9..d395b1c 100644
--- a/hw/xgmac.c
+++ b/hw/xgmac.c
@@ -403,26 +403,31 @@ static int xgmac_enet_init(SysBusDevice *dev)
     return 0;
 }
 
+static Property xgmac_properties[] = {
+    DEFINE_NIC_PROPERTIES(struct XgmacState, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void xgmac_enet_class_init(ObjectClass *klass, void *data)
 {
     SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+    DeviceClass *dc = DEVICE_CLASS(klass);
 
     sbc->init = xgmac_enet_init;
+    dc->vmsd = &vmstate_xgmac;
+    dc->props = xgmac_properties;
 }
 
-static DeviceInfo xgmac_enet_info = {
-    .name  = "xgmac",
-    .size  = sizeof(struct XgmacState),
-    .vmsd = &vmstate_xgmac,
-    .class_init = xgmac_enet_class_init,
-    .props = (Property[]) {
-        DEFINE_NIC_PROPERTIES(struct XgmacState, conf),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+static TypeInfo xgmac_enet_info = {
+    .name          = "xgmac",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(struct XgmacState),
+    .class_init    = xgmac_enet_class_init,
 };
+
 static void xgmac_enet_register(void)
 {
-    sysbus_register_withprop(&xgmac_enet_info);
+    type_register_static(&xgmac_enet_info);
 }
 
 device_init(xgmac_enet_register)
diff --git a/hw/xilinx_axidma.c b/hw/xilinx_axidma.c
index 0fbe415..e8a5312 100644
--- a/hw/xilinx_axidma.c
+++ b/hw/xilinx_axidma.c
@@ -494,21 +494,23 @@ static Property axidma_properties[] = {
 
 static void axidma_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = xilinx_axidma_init;
+    dc->props = axidma_properties;
 }
 
-static DeviceInfo axidma_info = {
-    .name = "xilinx,axidma",
-    .size = sizeof(struct XilinxAXIDMA),
-    .props = axidma_properties,
-    .class_init = axidma_class_init,
+static TypeInfo axidma_info = {
+    .name          = "xilinx,axidma",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(struct XilinxAXIDMA),
+    .class_init    = axidma_class_init,
 };
 
 static void xilinx_axidma_register(void)
 {
-    sysbus_register_withprop(&axidma_info);
+    type_register_static(&axidma_info);
 }
 
 device_init(xilinx_axidma_register)
diff --git a/hw/xilinx_axienet.c b/hw/xilinx_axienet.c
index c7dbe00..1ce2db4 100644
--- a/hw/xilinx_axienet.c
+++ b/hw/xilinx_axienet.c
@@ -881,20 +881,22 @@ static Property xilinx_enet_properties[] = {
 
 static void xilinx_enet_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = xilinx_enet_init;
+    dc->props = xilinx_enet_properties;
 }
 
-static DeviceInfo xilinx_enet_info = {
-    .name = "xilinx,axienet",
-    .size = sizeof(struct XilinxAXIEnet),
-    .props = xilinx_enet_properties,
-    .class_init = xilinx_enet_class_init,
+static TypeInfo xilinx_enet_info = {
+    .name          = "xilinx,axienet",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(struct XilinxAXIEnet),
+    .class_init    = xilinx_enet_class_init,
 };
 static void xilinx_enet_register(void)
 {
-    sysbus_register_withprop(&xilinx_enet_info);
+    type_register_static(&xilinx_enet_info);
 }
 
 device_init(xilinx_enet_register)
diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c
index dc7c0c8..499feef 100644
--- a/hw/xilinx_ethlite.c
+++ b/hw/xilinx_ethlite.c
@@ -235,21 +235,23 @@ static Property xilinx_ethlite_properties[] = {
 
 static void xilinx_ethlite_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = xilinx_ethlite_init;
+    dc->props = xilinx_ethlite_properties;
 }
 
-static DeviceInfo xilinx_ethlite_info = {
-    .name = "xilinx,ethlite",
-    .size = sizeof(struct xlx_ethlite),
-    .props = xilinx_ethlite_properties,
-    .class_init = xilinx_ethlite_class_init,
+static TypeInfo xilinx_ethlite_info = {
+    .name          = "xilinx,ethlite",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(struct xlx_ethlite),
+    .class_init    = xilinx_ethlite_class_init,
 };
 
 static void xilinx_ethlite_register(void)
 {
-    sysbus_register_withprop(&xilinx_ethlite_info);
+    type_register_static(&xilinx_ethlite_info);
 }
 
 device_init(xilinx_ethlite_register)
diff --git a/hw/xilinx_intc.c b/hw/xilinx_intc.c
index c26b4ea..73eed6d 100644
--- a/hw/xilinx_intc.c
+++ b/hw/xilinx_intc.c
@@ -168,21 +168,23 @@ static Property xilinx_intc_properties[] = {
 
 static void xilinx_intc_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = xilinx_intc_init;
+    dc->props = xilinx_intc_properties;
 }
 
-static DeviceInfo xilinx_intc_info = {
-    .name = "xilinx,intc",
-    .size = sizeof(struct xlx_pic),
-    .props = xilinx_intc_properties,
-    .class_init = xilinx_intc_class_init,
+static TypeInfo xilinx_intc_info = {
+    .name          = "xilinx,intc",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(struct xlx_pic),
+    .class_init    = xilinx_intc_class_init,
 };
 
 static void xilinx_intc_register(void)
 {
-    sysbus_register_withprop(&xilinx_intc_info);
+    type_register_static(&xilinx_intc_info);
 }
 
 device_init(xilinx_intc_register)
diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c
index 0755e1b..c8236d2 100644
--- a/hw/xilinx_timer.c
+++ b/hw/xilinx_timer.c
@@ -227,21 +227,23 @@ static Property xilinx_timer_properties[] = {
 
 static void xilinx_timer_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = xilinx_timer_init;
+    dc->props = xilinx_timer_properties;
 }
 
-static DeviceInfo xilinx_timer_info = {
-    .name = "xilinx,timer",
-    .size = sizeof(struct timerblock),
-    .props = xilinx_timer_properties,
-    .class_init = xilinx_timer_class_init,
+static TypeInfo xilinx_timer_info = {
+    .name          = "xilinx,timer",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(struct timerblock),
+    .class_init    = xilinx_timer_class_init,
 };
 
 static void xilinx_timer_register(void)
 {
-    sysbus_register_withprop(&xilinx_timer_info);
+    type_register_static(&xilinx_timer_info);
 }
 
 device_init(xilinx_timer_register)
diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c
index 8baabc7..1491bba 100644
--- a/hw/xilinx_uartlite.c
+++ b/hw/xilinx_uartlite.c
@@ -218,15 +218,16 @@ static void xilinx_uartlite_class_init(ObjectClass *klass, void *data)
     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 TypeInfo xilinx_uartlite_info = {
+    .name          = "xilinx,uartlite",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof (struct xlx_uartlite),
+    .class_init    = xilinx_uartlite_class_init,
 };
 
 static void xilinx_uart_register(void)
 {
-    sysbus_qdev_register(&xilinx_uartlite_info);
+    type_register_static(&xilinx_uartlite_info);
 }
 
 device_init(xilinx_uart_register)
diff --git a/hw/xio3130_downstream.c b/hw/xio3130_downstream.c
index 6d625cb..07e4fc1 100644
--- a/hw/xio3130_downstream.c
+++ b/hw/xio3130_downstream.c
@@ -179,6 +179,7 @@ static Property xio3130_downstream_properties[] = {
 
 static void xio3130_downstream_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->is_express = 1;
@@ -189,21 +190,22 @@ static void xio3130_downstream_class_init(ObjectClass *klass, void *data)
     k->vendor_id = PCI_VENDOR_ID_TI;
     k->device_id = PCI_DEVICE_ID_TI_XIO3130D;
     k->revision = XIO3130_REVISION;
+    dc->desc = "TI X3130 Downstream Port of PCI Express Switch";
+    dc->reset = xio3130_downstream_reset;
+    dc->vmsd = &vmstate_xio3130_downstream;
+    dc->props = xio3130_downstream_properties;
 }
 
-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 TypeInfo xio3130_downstream_info = {
+    .name          = "xio3130-downstream",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIESlot),
+    .class_init    = xio3130_downstream_class_init,
 };
 
 static void xio3130_downstream_register(void)
 {
-    pci_qdev_register(&xio3130_downstream_info);
+    type_register_static(&xio3130_downstream_info);
 }
 
 device_init(xio3130_downstream_register);
diff --git a/hw/xio3130_upstream.c b/hw/xio3130_upstream.c
index ec4c5e3..7887c92 100644
--- a/hw/xio3130_upstream.c
+++ b/hw/xio3130_upstream.c
@@ -153,6 +153,7 @@ static Property xio3130_upstream_properties[] = {
 
 static void xio3130_upstream_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->is_express = 1;
@@ -163,21 +164,22 @@ static void xio3130_upstream_class_init(ObjectClass *klass, void *data)
     k->vendor_id = PCI_VENDOR_ID_TI;
     k->device_id = PCI_DEVICE_ID_TI_XIO3130U;
     k->revision = XIO3130_REVISION;
+    dc->desc = "TI X3130 Upstream Port of PCI Express Switch";
+    dc->reset = xio3130_upstream_reset;
+    dc->vmsd = &vmstate_xio3130_upstream;
+    dc->props = xio3130_upstream_properties;
 }
 
-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 TypeInfo xio3130_upstream_info = {
+    .name          = "x3130-upstream",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIEPort),
+    .class_init    = xio3130_upstream_class_init,
 };
 
 static void xio3130_upstream_register(void)
 {
-    pci_qdev_register(&xio3130_upstream_info);
+    type_register_static(&xio3130_upstream_info);
 }
 
 device_init(xio3130_upstream_register);
diff --git a/hw/z2.c b/hw/z2.c
index b12f974..654ac55 100644
--- a/hw/z2.c
+++ b/hw/z2.c
@@ -176,17 +176,19 @@ static VMStateDescription vmstate_zipit_lcd_state = {
 
 static void zipit_lcd_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
 
     k->init = zipit_lcd_init;
     k->transfer = zipit_lcd_transfer;
+    dc->vmsd = &vmstate_zipit_lcd_state;
 }
 
-static DeviceInfo zipit_lcd_info = {
-    .name = "zipit-lcd",
-    .size = sizeof(ZipitLCD),
-    .vmsd = &vmstate_zipit_lcd_state,
-    .class_init = zipit_lcd_class_init,
+static TypeInfo zipit_lcd_info = {
+    .name          = "zipit-lcd",
+    .parent        = TYPE_SSI_SLAVE,
+    .instance_size = sizeof(ZipitLCD),
+    .class_init    = zipit_lcd_class_init,
 };
 
 typedef struct {
@@ -275,19 +277,21 @@ static VMStateDescription vmstate_aer915_state = {
 
 static void aer915_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
 
     k->init = aer915_init;
     k->event = aer915_event;
     k->recv = aer915_recv;
     k->send = aer915_send;
+    dc->vmsd = &vmstate_aer915_state;
 }
 
-static DeviceInfo aer915_info = {
-    .name = "aer915",
-    .size = sizeof(AER915State),
-    .vmsd = &vmstate_aer915_state,
-    .class_init = aer915_class_init,
+static TypeInfo aer915_info = {
+    .name          = "aer915",
+    .parent        = TYPE_I2C_SLAVE,
+    .instance_size = sizeof(AER915State),
+    .class_init    = aer915_class_init,
 };
 
 static void z2_init(ram_addr_t ram_size,
@@ -340,8 +344,8 @@ static void z2_init(ram_addr_t ram_size,
         NULL,
         qdev_get_gpio_in(cpu->gpio, Z2_GPIO_SD_DETECT));
 
-    ssi_register_slave(&zipit_lcd_info);
-    i2c_register_slave(&aer915_info);
+    type_register_static(&zipit_lcd_info);
+    type_register_static(&aer915_info);
     z2_lcd = ssi_create_slave(cpu->ssp[1], "zipit-lcd");
     bus = pxa2xx_i2c_bus(cpu->i2c[0]);
     i2c_create_slave(bus, "aer915", 0x55);
diff --git a/hw/zaurus.c b/hw/zaurus.c
index b14240c..055df9b 100644
--- a/hw/zaurus.c
+++ b/hw/zaurus.c
@@ -227,23 +227,25 @@ static Property scoop_sysbus_properties[] = {
 
 static void scoop_sysbus_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
     k->init = scoop_init;
+    dc->desc = "Scoop2 Sharp custom ASIC";
+    dc->vmsd = &vmstate_scoop_regs;
+    dc->props = scoop_sysbus_properties;
 }
 
-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 TypeInfo scoop_sysbus_info = {
+    .name          = "scoop",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(ScoopInfo),
+    .class_init    = scoop_sysbus_class_init,
 };
 
 static void scoop_register(void)
 {
-    sysbus_register_withprop(&scoop_sysbus_info);
+    type_register_static(&scoop_sysbus_info);
 }
 device_init(scoop_register);
 
diff --git a/usb-linux.c b/usb-linux.c
index a337db5..e7fc9ec 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -1402,8 +1402,19 @@ static const VMStateDescription vmstate_usb_host = {
     .unmigratable = 1,
 };
 
+static Property usb_host_dev_properties[] = {
+    DEFINE_PROP_UINT32("hostbus",  USBHostDevice, match.bus_num,    0),
+    DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr,       0),
+    DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
+    DEFINE_PROP_HEX32("vendorid",  USBHostDevice, match.vendor_id,  0),
+    DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
+    DEFINE_PROP_UINT32("isobufs",  USBHostDevice, iso_urb_count,    4),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void usb_host_class_initfn(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
 
     uc->init           = usb_host_initfn;
@@ -1414,27 +1425,20 @@ static void usb_host_class_initfn(ObjectClass *klass, void *data)
     uc->handle_control = usb_host_handle_control;
     uc->handle_reset   = usb_host_handle_reset;
     uc->handle_destroy = usb_host_handle_destroy;
+    dc->vmsd = &vmstate_usb_host;
+    dc->props = usb_host_dev_properties;
 }
 
-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),
-        DEFINE_PROP_HEX32("vendorid",  USBHostDevice, match.vendor_id,  0),
-        DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
-        DEFINE_PROP_UINT32("isobufs",  USBHostDevice, iso_urb_count,    4),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+static TypeInfo usb_host_dev_info = {
+    .name          = "usb-host",
+    .parent        = TYPE_USB_DEVICE,
+    .instance_size = sizeof(USBHostDevice),
+    .class_init    = usb_host_class_initfn,
 };
 
 static void usb_host_register_devices(void)
 {
-    usb_qdev_register(&usb_host_dev_info);
+    type_register_static(&usb_host_dev_info);
     usb_legacy_register("usb-host", "host", usb_host_device_open);
 }
 device_init(usb_host_register_devices)
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 09/23] qdev: kill of DeviceInfo
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (5 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 08/23] qdev: register all types natively through QEMU Object Model Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-31 13:34   ` Andreas Färber
  2012-02-01 19:46   ` Peter Maydell
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 10/23] qdev: remove baked in notion of aliases Anthony Liguori
                   ` (14 subsequent siblings)
  21 siblings, 2 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

It is no longer used in the tree since everything is done natively through
QEMU Object Model.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/i2c.c               |    2 +-
 hw/ide/qdev.c          |    2 +-
 hw/intel-hda.c         |    2 +-
 hw/isa-bus.c           |    2 +-
 hw/pci.c               |    2 +-
 hw/qdev.c              |   70 +-----------------------------------------------
 hw/qdev.h              |   33 +----------------------
 hw/s390-virtio-bus.c   |    2 +-
 hw/scsi-bus.c          |    2 +-
 hw/spapr_vio.c         |    2 +-
 hw/ssi.c               |    2 +-
 hw/sysbus.c            |    2 +-
 hw/usb-bus.c           |    2 +-
 hw/usb-ccid.c          |    2 +-
 hw/virtio-serial-bus.c |    2 +-
 15 files changed, 15 insertions(+), 114 deletions(-)

diff --git a/hw/i2c.c b/hw/i2c.c
index e21a666..8ae4aaa 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -196,7 +196,7 @@ const VMStateDescription vmstate_i2c_slave = {
     }
 };
 
-static int i2c_slave_qdev_init(DeviceState *dev, DeviceInfo *base)
+static int i2c_slave_qdev_init(DeviceState *dev)
 {
     I2CSlave *s = I2C_SLAVE_FROM_QDEV(dev);
     I2CSlaveClass *sc = I2C_SLAVE_GET_CLASS(s);
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 1335615..1640616 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -53,7 +53,7 @@ static char *idebus_get_fw_dev_path(DeviceState *dev)
     return strdup(path);
 }
 
-static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base)
+static int ide_qdev_init(DeviceState *qdev)
 {
     IDEDevice *dev = IDE_DEVICE(qdev);
     IDEDeviceClass *dc = IDE_DEVICE_GET_CLASS(dev);
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 9e4a31f..83c42d5 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -47,7 +47,7 @@ void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus,
     bus->xfer = xfer;
 }
 
-static int hda_codec_dev_init(DeviceState *qdev, DeviceInfo *base)
+static int hda_codec_dev_init(DeviceState *qdev)
 {
     HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, qdev->parent_bus);
     HDACodecDevice *dev = DO_UPCAST(HDACodecDevice, qdev, qdev);
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index a22c5c6..d03f828 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -110,7 +110,7 @@ void isa_register_portio_list(ISADevice *dev, uint16_t start,
     portio_list_add(piolist, isabus->address_space_io, start);
 }
 
-static int isa_qdev_init(DeviceState *qdev, DeviceInfo *base)
+static int isa_qdev_init(DeviceState *qdev)
 {
     ISADevice *dev = ISA_DEVICE(qdev);
     ISADeviceClass *klass = ISA_DEVICE_GET_CLASS(dev);
diff --git a/hw/pci.c b/hw/pci.c
index 8fd450c..1df05ae 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1453,7 +1453,7 @@ PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn)
     return bus->devices[devfn];
 }
 
-static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
+static int pci_qdev_init(DeviceState *qdev)
 {
     PCIDevice *pci_dev = (PCIDevice *)qdev;
     PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
diff --git a/hw/qdev.c b/hw/qdev.c
index ea917ad..84fb112 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -43,49 +43,6 @@ 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);
-    DeviceInfo *info = data;
-
-    if (info->fw_name) {
-        dc->fw_name = info->fw_name;
-    }
-    if (info->alias) {
-        dc->alias = info->alias;
-    }
-    if (info->desc) {
-        dc->desc = info->desc;
-    }
-    if (info->props) {
-        dc->props = info->props;
-    }
-    if (info->no_user) {
-        dc->no_user = info->no_user;
-    }
-    if (info->reset) {
-        dc->reset = info->reset;
-    }
-    if (info->vmsd) {
-        dc->vmsd = info->vmsd;
-    }
-    if (info->init) {
-        dc->init = info->init;
-    }
-    if (info->unplug) {
-        dc->unplug = info->unplug;
-    }
-    if (info->exit) {
-        dc->exit = info->exit;
-    }
-    if (info->bus_info) {
-        dc->bus_info = info->bus_info;
-    }
-    if (info->class_init) {
-        info->class_init(klass, data);
-    }
-}
-
 const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
 {
     DeviceClass *dc = DEVICE_GET_CLASS(dev);
@@ -117,30 +74,6 @@ const char *qdev_fw_name(DeviceState *dev)
     return object_get_typename(OBJECT(dev));
 }
 
-static void qdev_do_register_subclass(DeviceInfo *info, const char *parent,
-                                      const char *name)
-{
-    TypeInfo type_info = {};
-
-    assert(info->size >= sizeof(DeviceState));
-
-    type_info.name = name;
-    type_info.parent = parent;
-    type_info.instance_size = info->size;
-    type_info.class_init = qdev_subclass_init;
-    type_info.class_data = info;
-
-    type_register_static(&type_info);
-}
-
-void qdev_register_subclass(DeviceInfo *info, const char *parent)
-{
-    qdev_do_register_subclass(info, parent, info->name);
-    if (info->alias) {
-        qdev_do_register_subclass(info, parent, info->alias);
-    }
-}
-
 bool qdev_exists(const char *name)
 {
     return !!object_class_by_name(name);
@@ -406,8 +339,7 @@ int qdev_init(DeviceState *dev)
 
     assert(dev->state == DEV_STATE_CREATED);
 
-    /* FIXME hopefully this doesn't break anything */
-    rc = dc->init(dev, NULL);
+    rc = dc->init(dev);
     if (rc < 0) {
         qdev_free(dev);
         return rc;
diff --git a/hw/qdev.h b/hw/qdev.h
index 54626ac..29f6daa 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -14,8 +14,6 @@ typedef struct PropertyInfo PropertyInfo;
 
 typedef struct CompatProperty CompatProperty;
 
-typedef struct DeviceInfo DeviceInfo;
-
 typedef struct BusState BusState;
 
 typedef struct BusInfo BusInfo;
@@ -72,7 +70,7 @@ typedef struct DeviceProperty
 #define DEVICE_CLASS(klass) OBJECT_CLASS_CHECK(DeviceClass, (klass), TYPE_DEVICE)
 #define DEVICE_GET_CLASS(obj) OBJECT_GET_CLASS(DeviceClass, (obj), TYPE_DEVICE)
 
-typedef int (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
+typedef int (*qdev_initfn)(DeviceState *dev);
 typedef int (*qdev_event)(DeviceState *dev);
 typedef void (*qdev_resetfn)(DeviceState *dev);
 
@@ -232,35 +230,6 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
 
 /*** Device API.  ***/
 
-struct DeviceInfo {
-    const char *name;
-    const char *fw_name;
-    const char *alias;
-    const char *desc;
-    size_t size;
-    Property *props;
-    int no_user;
-
-    /* callbacks */
-    qdev_resetfn reset;
-
-    /* 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;
-    qdev_event exit;
-    BusInfo *bus_info;
-};
-
-void qdev_register_subclass(DeviceInfo *info, const char *parent);
-
 /* Register device properties.  */
 /* GPIO inputs also double as IRQ sinks.  */
 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n);
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index a0c610a..4e1e888 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -410,7 +410,7 @@ static TypeInfo s390_virtio_serial = {
     .class_init    = s390_virtio_serial_class_init,
 };
 
-static int s390_virtio_busdev_init(DeviceState *dev, DeviceInfo *info)
+static int s390_virtio_busdev_init(DeviceState *dev)
 {
     VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
     VirtIOS390DeviceClass *_info = VIRTIO_S390_DEVICE_GET_CLASS(dev);
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index b75044f..0ee50a8 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -115,7 +115,7 @@ static void scsi_dma_restart_cb(void *opaque, int running, RunState state)
     }
 }
 
-static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
+static int scsi_qdev_init(DeviceState *qdev)
 {
     SCSIDevice *dev = SCSI_DEVICE(qdev);
     SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index d39a47b..64f0009 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -649,7 +649,7 @@ static int spapr_vio_check_reg(VIOsPAPRDevice *sdev)
     return 0;
 }
 
-static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo)
+static int spapr_vio_busdev_init(DeviceState *qdev)
 {
     VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
     VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
diff --git a/hw/ssi.c b/hw/ssi.c
index 4282b8b..ead446c 100644
--- a/hw/ssi.c
+++ b/hw/ssi.c
@@ -21,7 +21,7 @@ static struct BusInfo ssi_bus_info = {
     .size = sizeof(SSIBus),
 };
 
-static int ssi_slave_init(DeviceState *dev, DeviceInfo *base_info)
+static int ssi_slave_init(DeviceState *dev)
 {
     SSISlave *s = SSI_SLAVE(dev);
     SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(s);
diff --git a/hw/sysbus.c b/hw/sysbus.c
index 4870dbf..282060a 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -105,7 +105,7 @@ void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size)
     }
 }
 
-static int sysbus_device_init(DeviceState *dev, DeviceInfo *base)
+static int sysbus_device_init(DeviceState *dev)
 {
     SysBusDevice *sd = SYS_BUS_DEVICE(dev);
     SysBusDeviceClass *sbc = SYS_BUS_DEVICE_GET_CLASS(sd);
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index d07f844..b753834 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -156,7 +156,7 @@ void usb_device_set_interface(USBDevice *dev, int interface,
     }
 }
 
-static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
+static int usb_qdev_init(DeviceState *qdev)
 {
     USBDevice *dev = USB_DEVICE(qdev);
     int rc;
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index 844f873..881da30 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -1161,7 +1161,7 @@ static int ccid_card_exit(DeviceState *qdev)
     return ret;
 }
 
-static int ccid_card_init(DeviceState *qdev, DeviceInfo *base)
+static int ccid_card_init(DeviceState *qdev)
 {
     CCIDCardState *card = CCID_CARD(qdev);
     USBCCIDState *s =
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 50a6d7f..6117629 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -748,7 +748,7 @@ static void remove_port(VirtIOSerial *vser, uint32_t port_id)
     send_control_event(port, VIRTIO_CONSOLE_PORT_REMOVE, 1);
 }
 
-static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
+static int virtser_port_qdev_init(DeviceState *qdev)
 {
     VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
     VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 10/23] qdev: remove baked in notion of aliases
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (6 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 09/23] qdev: kill of DeviceInfo Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-31  7:44   ` Paolo Bonzini
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 11/23] qom: allow object_class_foreach to take additional parameters to refine search Anthony Liguori
                   ` (13 subsequent siblings)
  21 siblings, 1 reply; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

Limit them to the device_add functionality.  Device aliases were a hack based
on the fact that virtio was modeled the wrong way.  The mechanism for aliasing
is very limited in that only one alias can exist for any device.

We have to support it for the purposes of compatibility but we only need to
support it in device_add so restrict it to that piece of code.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/ide/ich.c         |    2 -
 hw/lsi53c895a.c      |    2 -
 hw/qdev.c            |   95 ++++++++++++++++++++++++++++++++++++++++++++++---
 hw/qdev.h            |    1 -
 hw/s390-virtio-bus.c |    3 --
 hw/virtio-pci.c      |    8 ----
 6 files changed, 89 insertions(+), 22 deletions(-)

diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 0e819f6..5cdaa99 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -158,7 +158,6 @@ static void ich_ahci_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_INTEL_82801IR;
     k->revision = 0x02;
     k->class_id = PCI_CLASS_STORAGE_SATA;
-    dc->alias = "ahci";
     dc->vmsd = &vmstate_ahci;
 }
 
@@ -172,6 +171,5 @@ static TypeInfo ich_ahci_info = {
 static void ich_ahci_register(void)
 {
     type_register_static(&ich_ahci_info);
-    type_register_static_alias(&ich_ahci_info, "ahci");
 }
 device_init(ich_ahci_register);
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 638332e..9a7ffe3 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -2131,7 +2131,6 @@ static void lsi_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_LSI_53C895A;
     k->class_id = PCI_CLASS_STORAGE_SCSI;
     k->subsystem_id = 0x1000;
-    dc->alias = "lsi";
     dc->reset = lsi_scsi_reset;
     dc->vmsd = &vmstate_lsi_scsi;
 }
@@ -2146,7 +2145,6 @@ static TypeInfo lsi_info = {
 static void lsi53c895a_register_devices(void)
 {
     type_register_static(&lsi_info);
-    type_register_static_alias(&lsi_info, "lsi");
 }
 
 device_init(lsi53c895a_register_devices);
diff --git a/hw/qdev.c b/hw/qdev.c
index 84fb112..636b6b4 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -61,14 +61,50 @@ Property *qdev_get_props(DeviceState *dev)
     return dc->props;
 }
 
+/*
+ * Aliases were a bad idea from the start.  Let's keep them
+ * from spreading further.
+ */
+static const char *qdev_class_get_alias(DeviceClass *dc)
+{
+    const char *typename = object_class_get_name(OBJECT_CLASS(dc));
+
+    if (strcmp(typename, "virtio-blk-pci") == 0) {
+        return "virtio-blk";
+    } else if (strcmp(typename, "virtio-net-pci") == 0) {
+        return "virtio-net";
+    } else if (strcmp(typename, "virtio-serial-pci") == 0) {
+        return "virtio-serial";
+    } else if (strcmp(typename, "virtio-balloon-pci") == 0) {
+        return "virtio-balloon";
+    } else if (strcmp(typename, "virtio-blk-s390") == 0) {
+        return "virtio-blk";
+    } else if (strcmp(typename, "virtio-net-s390") == 0) {
+        return "virtio-net";
+    } else if (strcmp(typename, "virtio-serial-s390") == 0) {
+        return "virtio-serial";
+    } else if (strcmp(typename, "lsi53c895a") == 0) {
+        return "lsi";
+    } else if (strcmp(typename, "ich9-ahci") == 0) {
+        return "ahci";
+    }
+
+    return NULL;
+}
+
+static bool qdev_class_has_alias(DeviceClass *dc)
+{
+    return (qdev_class_get_alias(dc) != NULL);
+}
+
 const char *qdev_fw_name(DeviceState *dev)
 {
     DeviceClass *dc = DEVICE_GET_CLASS(dev);
 
     if (dc->fw_name) {
         return dc->fw_name;
-    } else if (dc->alias) {
-        return dc->alias;
+    } else if (qdev_class_has_alias(dc)) {
+        return qdev_class_get_alias(dc);
     }
 
     return object_get_typename(OBJECT(dev));
@@ -161,8 +197,8 @@ static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
     if (dc->bus_info) {
         error_printf(", bus %s", dc->bus_info->name);
     }
-    if (dc->alias) {
-        error_printf(", alias \"%s\"", dc->alias);
+    if (qdev_class_has_alias(dc)) {
+        error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
     }
     if (dc->desc) {
         error_printf(", desc \"%s\"", dc->desc);
@@ -188,6 +224,27 @@ static int set_property(const char *name, const char *value, void *opaque)
     return 0;
 }
 
+static const char *find_typename_by_alias(const char *alias)
+{
+    /* I don't think s390 aliasing could have ever worked... */
+
+    if (strcmp(alias, "virtio-blk") == 0) {
+        return "virtio-blk-pci";
+    } else if (strcmp(alias, "virtio-net") == 0) {
+        return "virtio-net-pci";
+    } else if (strcmp(alias, "virtio-serial") == 0) {
+        return "virtio-serial-pci";
+    } else if (strcmp(alias, "virtio-balloon") == 0) {
+        return "virtio-balloon-pci";
+    } else if (strcmp(alias, "lsi") == 0) {
+        return "lsi53c895a";
+    } else if (strcmp(alias, "ahci") == 0) {
+        return "ich9-ahci";
+    }
+
+    return NULL;
+}
+
 int qdev_device_help(QemuOpts *opts)
 {
     const char *driver;
@@ -208,6 +265,15 @@ int qdev_device_help(QemuOpts *opts)
 
     klass = object_class_by_name(driver);
     if (!klass) {
+        const char *typename = find_typename_by_alias(driver);
+
+        if (typename) {
+            driver = typename;
+            klass = object_class_by_name(driver);
+        }
+    }
+
+    if (!klass) {
         return 0;
     }
     info = DEVICE_CLASS(klass);
@@ -263,6 +329,7 @@ static DeviceState *qdev_get_peripheral_anon(void)
 
 DeviceState *qdev_device_add(QemuOpts *opts)
 {
+    ObjectClass *obj;
     DeviceClass *k;
     const char *driver, *path, *id;
     DeviceState *qdev;
@@ -275,7 +342,22 @@ DeviceState *qdev_device_add(QemuOpts *opts)
     }
 
     /* find driver */
-    k = DEVICE_CLASS(object_class_by_name(driver));
+    obj = object_class_by_name(driver);
+    if (!obj) {
+        const char *typename = find_typename_by_alias(driver);
+
+        if (typename) {
+            driver = typename;
+            obj = object_class_by_name(driver);
+        }
+    }
+
+    if (!obj) {
+        qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "device type");
+        return NULL;
+    }
+
+    k = DEVICE_CLASS(obj);
 
     /* find bus */
     path = qemu_opt_get(opts, "bus");
@@ -753,7 +835,8 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
     QTAILQ_FOREACH(dev, &bus->children, sibling) {
         DeviceClass *dc = DEVICE_GET_CLASS(dev);
 
-        if (dc->alias && strcmp(dc->alias, elem) == 0) {
+        if (qdev_class_has_alias(dc) &&
+            strcmp(qdev_class_get_alias(dc), elem) == 0) {
             return dev;
         }
     }
diff --git a/hw/qdev.h b/hw/qdev.h
index 29f6daa..5aea4bf 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -78,7 +78,6 @@ typedef struct DeviceClass {
     ObjectClass parent_class;
 
     const char *fw_name;
-    const char *alias;
     const char *desc;
     Property *props;
     int no_user;
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 4e1e888..b66ef68 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -354,7 +354,6 @@ static void s390_virtio_net_class_init(ObjectClass *klass, void *data)
 
     k->init = s390_virtio_net_init;
     dc->props = s390_virtio_net_properties;
-    dc->alias = "virtio-net";
 }
 
 static TypeInfo s390_virtio_net = {
@@ -377,7 +376,6 @@ static void s390_virtio_blk_class_init(ObjectClass *klass, void *data)
 
     k->init = s390_virtio_blk_init;
     dc->props = s390_virtio_blk_properties;
-    dc->alias = "virtio-blk";
 }
 
 static TypeInfo s390_virtio_blk = {
@@ -400,7 +398,6 @@ static void s390_virtio_serial_class_init(ObjectClass *klass, void *data)
 
     k->init = s390_virtio_serial_init;
     dc->props = s390_virtio_serial_properties;
-    dc->alias = "virtio-serial";
 }
 
 static TypeInfo s390_virtio_serial = {
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index bc96552..93fff54 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -827,7 +827,6 @@ static void virtio_blk_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIRTIO_BLOCK;
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = PCI_CLASS_STORAGE_SCSI;
-    dc->alias = "virtio-blk";
     dc->reset = virtio_pci_reset;
     dc->props = virtio_blk_properties;
 }
@@ -862,7 +861,6 @@ static void virtio_net_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIRTIO_NET;
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = PCI_CLASS_NETWORK_ETHERNET;
-    dc->alias = "virtio-net";
     dc->reset = virtio_pci_reset;
     dc->props = virtio_net_properties;
 }
@@ -894,7 +892,6 @@ static void virtio_serial_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE;
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
-    dc->alias = "virtio-serial";
     dc->reset = virtio_pci_reset;
     dc->props = virtio_serial_properties;
 }
@@ -922,7 +919,6 @@ static void virtio_balloon_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_VIRTIO_BALLOON;
     k->revision = VIRTIO_PCI_ABI_VERSION;
     k->class_id = PCI_CLASS_MEMORY_RAM;
-    dc->alias = "virtio-balloon";
     dc->reset = virtio_pci_reset;
     dc->props = virtio_balloon_properties;
 }
@@ -937,13 +933,9 @@ static TypeInfo virtio_balloon_info = {
 static void virtio_pci_register_devices(void)
 {
     type_register_static(&virtio_blk_info);
-    type_register_static_alias(&virtio_blk_info, "virtio-blk");
     type_register_static(&virtio_net_info);
-    type_register_static_alias(&virtio_net_info, "virtio-net");
     type_register_static(&virtio_serial_info);
-    type_register_static_alias(&virtio_serial_info, "virtio-serial");
     type_register_static(&virtio_balloon_info);
-    type_register_static_alias(&virtio_balloon_info, "virtio-balloon");
 }
 
 device_init(virtio_pci_register_devices)
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 11/23] qom: allow object_class_foreach to take additional parameters to refine search
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (7 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 10/23] qdev: remove baked in notion of aliases Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-31 13:42   ` Andreas Färber
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 12/23] qom: add new command to search for types Anthony Liguori
                   ` (12 subsequent siblings)
  21 siblings, 1 reply; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/qdev.c             |    4 ++--
 include/qemu/object.h |    1 +
 qom/object.c          |   18 ++++++++++++++++--
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 636b6b4..a7980c5 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -255,7 +255,7 @@ int qdev_device_help(QemuOpts *opts)
     driver = qemu_opt_get(opts, "driver");
     if (driver && !strcmp(driver, "?")) {
         bool show_no_user = false;
-        object_class_foreach(qdev_print_devinfo, &show_no_user);
+        object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, &show_no_user);
         return 1;
     }
 
@@ -1077,7 +1077,7 @@ void do_info_qtree(Monitor *mon)
 
 void do_info_qdm(Monitor *mon)
 {
-    object_class_foreach(qdev_print_devinfo, NULL);
+    object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, NULL);
 }
 
 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
diff --git a/include/qemu/object.h b/include/qemu/object.h
index ba37850..adbcfb1 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -431,6 +431,7 @@ 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),
+                          const char *implements_type, bool include_abstract,
                           void *opaque);
 
 #endif
diff --git a/qom/object.c b/qom/object.c
index a12895f..3dabb1a 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -467,6 +467,8 @@ ObjectClass *object_class_by_name(const char *typename)
 typedef struct OCFData
 {
     void (*fn)(ObjectClass *klass, void *opaque);
+    const char *implements_type;
+    bool include_abstract;
     void *opaque;
 } OCFData;
 
@@ -475,16 +477,28 @@ static void object_class_foreach_tramp(gpointer key, gpointer value,
 {
     OCFData *data = opaque;
     TypeImpl *type = value;
+    ObjectClass *k;
 
     type_class_init(type);
+    k = type->class;
 
-    data->fn(value, type->class);
+    if (!data->include_abstract && type->abstract) {
+        return;
+    }
+
+    if (data->implements_type && 
+        !object_class_dynamic_cast(k, data->implements_type)) {
+        return;
+    }
+
+    data->fn(k, data->opaque);
 }
 
 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
+                          const char *implements_type, bool include_abstract,
                           void *opaque)
 {
-    OCFData data = { fn, opaque };
+    OCFData data = { fn, implements_type, include_abstract, opaque };
 
     g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
 }
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 12/23] qom: add new command to search for types
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (8 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 11/23] qom: allow object_class_foreach to take additional parameters to refine search Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 13/23] qdev: split out common init to instance_init Anthony Liguori
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

This adds a command that allows searching for types that implement a property.
This allows you to do things like search for all available PCIDevices.  In the
future, we'll also have a standard interface for things with a BlockDriverState
property that a PCIDevice could implement.

This will enable search queries like, "any type that implements the BlockDevice
interface" which would allow management tools to present available block devices
without having to hard code device names.  Since an object can implement
multiple interfaces, one device could act both as a BlockDevice and a
NetworkDevice.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 qapi-schema.json |   33 +++++++++++++++++++++++++++++++++
 qerror.c         |    2 +-
 qmp-commands.hx  |    5 +++++
 qmp.c            |   27 +++++++++++++++++++++++++++
 4 files changed, 66 insertions(+), 1 deletions(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index 80debe6..56a4123 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1549,3 +1549,36 @@
 # Since: 1.1
 ##
 { 'command': 'block_job_cancel', 'data': { 'device': 'str' } }
+
+##
+# @ObjectTypeInfo:
+#
+# This structure describes a search result from @qom-list-types
+#
+# @name: the type name found in the search
+#
+# Since: 1.1
+#
+# Notes: This command is experimental and may change syntax in future releases.
+##
+{ 'type': 'ObjectTypeInfo',
+  'data': { 'name': 'str' } }
+
+##
+# @qom-list-types:
+#
+# This command will return a list of types given search parameters
+#
+# @implements: if specified, only return types that implement this type name
+#
+# @abstract: if true, include abstract types in the results
+#
+# Returns: a list of @ObjectTypeInfo or an empty list if no results are found
+#
+# Since: 1.1
+#
+# Notes: This command is experimental and may change syntax in future releases.
+##
+{ 'command': 'qom-list-types',
+  'data': { '*implements': 'str', '*abstract': 'bool' },
+  'returns': [ 'ObjectTypeInfo' ] }
diff --git a/qerror.c b/qerror.c
index 637eca7..3d179c8 100644
--- a/qerror.c
+++ b/qerror.c
@@ -161,7 +161,7 @@ static const QErrorStringTable qerror_table[] = {
     },
     {
         .error_fmt = QERR_INVALID_PARAMETER_TYPE,
-        .desc      = "Invalid parameter type, expected: %(expected)",
+        .desc      = "Invalid parameter type for '%(name)', expected: %(expected)",
     },
     {
         .error_fmt = QERR_INVALID_PARAMETER_VALUE,
diff --git a/qmp-commands.hx b/qmp-commands.hx
index bd6b641..b5e2ab8 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2042,3 +2042,8 @@ EQMP
         .args_type  = "password:s",
         .mhandler.cmd_new = qmp_marshal_input_change_vnc_password,
     },
+    {
+        .name       = "qom-list-types",
+        .args_type  = "implements:s?,abstract:b?",
+        .mhandler.cmd_new = qmp_marshal_input_qom_list_types,
+    },
diff --git a/qmp.c b/qmp.c
index 1222b6c..75049ed 100644
--- a/qmp.c
+++ b/qmp.c
@@ -395,3 +395,30 @@ void qmp_change(const char *device, const char *target,
         qmp_change_blockdev(device, target, has_arg, arg, err);
     }
 }
+
+static void qom_list_types_tramp(ObjectClass *klass, void *data)
+{
+    ObjectTypeInfoList *e, **pret = data;
+    ObjectTypeInfo *info;
+
+    info = g_malloc0(sizeof(*info));
+    info->name = g_strdup(object_class_get_name(klass));
+
+    e = g_malloc0(sizeof(*e));
+    e->value = info;
+    e->next = *pret;
+    *pret = e;
+}
+
+ObjectTypeInfoList *qmp_qom_list_types(bool has_implements,
+                                       const char *implements,
+                                       bool has_abstract,
+                                       bool abstract,
+                                       Error **errp)
+{
+    ObjectTypeInfoList *ret = NULL;
+
+    object_class_foreach(qom_list_types_tramp, implements, abstract, &ret);
+
+    return ret;
+}
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 13/23] qdev: split out common init to instance_init
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (9 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 12/23] qom: add new command to search for types Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 14/23] qdev: refactor away qdev_create_from_info Anthony Liguori
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

This gets us closer to being able to object_new() a qdev type and have a
functioning object verses having to call qdev_create().

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

diff --git a/hw/qdev.c b/hw/qdev.c
index a7980c5..491f45e 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -124,31 +124,22 @@ static DeviceState *qdev_create_from_info(BusState *bus, const char *typename)
     Property *prop;
 
     dev = DEVICE(object_new(typename));
+
     dev->parent_bus = bus;
-    qdev_prop_set_defaults(dev, qdev_get_props(dev));
     qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
-    qdev_prop_set_globals(dev);
-    QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
+
     if (qdev_hotplug) {
         assert(bus->allow_hotplug);
-        dev->hotplugged = 1;
-        qdev_hot_added = true;
     }
-    dev->instance_id_alias = -1;
-    QTAILQ_INIT(&dev->properties);
-    dev->state = DEV_STATE_CREATED;
 
-    for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
-        qdev_property_add_legacy(dev, prop, NULL);
-        qdev_property_add_static(dev, prop, NULL);
-    }
+    QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
 
     for (prop = qdev_get_bus_info(dev)->props; prop && prop->name; prop++) {
         qdev_property_add_legacy(dev, prop, NULL);
         qdev_property_add_static(dev, prop, NULL);
     }
 
-    qdev_property_add_str(dev, "type", qdev_get_type, NULL, NULL);
+    qdev_prop_set_globals(dev);
 
     return dev;
 }
@@ -1649,6 +1640,29 @@ void qdev_machine_init(void)
     qdev_get_peripheral();
 }
 
+static void device_initfn(Object *obj)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop;
+
+    if (qdev_hotplug) {
+        dev->hotplugged = 1;
+        qdev_hot_added = true;
+    }
+
+    dev->instance_id_alias = -1;
+    QTAILQ_INIT(&dev->properties);
+    dev->state = DEV_STATE_CREATED;
+
+    qdev_prop_set_defaults(dev, qdev_get_props(dev));
+    for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
+        qdev_property_add_legacy(dev, prop, NULL);
+        qdev_property_add_static(dev, prop, NULL);
+    }
+
+    qdev_property_add_str(dev, "type", qdev_get_type, NULL, NULL);
+}
+
 void device_reset(DeviceState *dev)
 {
     DeviceClass *klass = DEVICE_GET_CLASS(dev);
@@ -1662,6 +1676,7 @@ static TypeInfo device_type_info = {
     .name = TYPE_DEVICE,
     .parent = TYPE_OBJECT,
     .instance_size = sizeof(DeviceState),
+    .instance_init = device_initfn,
     .abstract = true,
     .class_size = sizeof(DeviceClass),
 };
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 14/23] qdev: refactor away qdev_create_from_info
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (10 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 13/23] qdev: split out common init to instance_init Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 15/23] qdev: split out UI portions into a new function Anthony Liguori
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

Note that the FIXME gets fixed in series 4/4.  We need to convert BusState to
QOM before we can make parent_bus a link.

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

diff --git a/hw/qdev.c b/hw/qdev.c
index 491f45e..5c8dc53 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -118,30 +118,22 @@ bool qdev_exists(const char *name)
 static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
                                      Error **errp);
 
-static DeviceState *qdev_create_from_info(BusState *bus, const char *typename)
+void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
 {
-    DeviceState *dev;
     Property *prop;
 
-    dev = DEVICE(object_new(typename));
-
-    dev->parent_bus = bus;
-    qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
-
     if (qdev_hotplug) {
         assert(bus->allow_hotplug);
     }
 
+    dev->parent_bus = bus;
     QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
 
+    qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
     for (prop = qdev_get_bus_info(dev)->props; prop && prop->name; prop++) {
         qdev_property_add_legacy(dev, prop, NULL);
         qdev_property_add_static(dev, prop, NULL);
     }
-
-    qdev_prop_set_globals(dev);
-
-    return dev;
 }
 
 /* Create a new device.  This only initializes the device state structure
@@ -166,11 +158,21 @@ DeviceState *qdev_create(BusState *bus, const char *name)
 
 DeviceState *qdev_try_create(BusState *bus, const char *name)
 {
+    DeviceState *dev;
+
+    dev = DEVICE(object_new(name));
+    if (!dev) {
+        return NULL;
+    }
+
     if (!bus) {
         bus = sysbus_get_default();
     }
 
-    return qdev_create_from_info(bus, name);
+    qdev_set_parent_bus(dev, bus);
+    qdev_prop_set_globals(dev);
+
+    return dev;
 }
 
 static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
@@ -375,8 +377,15 @@ DeviceState *qdev_device_add(QemuOpts *opts)
         return NULL;
     }
 
+    if (!bus) {
+        bus = sysbus_get_default();
+    }
+
     /* create device, set properties */
-    qdev = qdev_create_from_info(bus, driver);
+    qdev = DEVICE(object_new(driver));
+    qdev_set_parent_bus(qdev, bus);
+    qdev_prop_set_globals(qdev);
+
     id = qemu_opts_id(opts);
     if (id) {
         qdev->id = id;
diff --git a/hw/qdev.h b/hw/qdev.h
index 5aea4bf..e611804 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -636,4 +636,7 @@ BusInfo *qdev_get_bus_info(DeviceState *dev);
 
 Property *qdev_get_props(DeviceState *dev);
 
+/* FIXME: make this a link<> */
+void qdev_set_parent_bus(DeviceState *dev, BusState *bus);
+
 #endif
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 15/23] qdev: split out UI portions into a new function
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (11 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 14/23] qdev: refactor away qdev_create_from_info Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 16/23] qdev: nuke qdev_init_chardev() Anthony Liguori
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

qdev-monitor.c deals with the -device, device_add, and info qdm/qtree
interfaces.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 Makefile.objs     |    2 +-
 hw/qdev-monitor.c |  587 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/qdev.c         |  574 +---------------------------------------------------
 hw/qdev.h         |    2 +
 4 files changed, 591 insertions(+), 574 deletions(-)
 create mode 100644 hw/qdev-monitor.c

diff --git a/Makefile.objs b/Makefile.objs
index b942625..1a26349 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -113,7 +113,7 @@ common-obj-y += bt-hci-csr.o
 common-obj-y += buffered_file.o migration.o migration-tcp.o
 common-obj-y += qemu-char.o #aio.o
 common-obj-y += msmouse.o ps2.o
-common-obj-y += qdev.o qdev-properties.o
+common-obj-y += qdev.o qdev-properties.o qdev-monitor.o
 common-obj-y += block-migration.o iohandler.o
 common-obj-y += pflib.o
 common-obj-y += bitmap.o bitops.o
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
new file mode 100644
index 0000000..3894574
--- /dev/null
+++ b/hw/qdev-monitor.c
@@ -0,0 +1,587 @@
+/*
+ *  Dynamic device configuration and creation.
+ *
+ *  Copyright (c) 2009 CodeSourcery
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qdev.h"
+#include "monitor.h"
+
+/*
+ * Aliases were a bad idea from the start.  Let's keep them
+ * from spreading further.
+ */
+static const char *qdev_class_get_alias(DeviceClass *dc)
+{
+    const char *typename = object_class_get_name(OBJECT_CLASS(dc));
+
+    if (strcmp(typename, "virtio-blk-pci") == 0) {
+        return "virtio-blk";
+    } else if (strcmp(typename, "virtio-net-pci") == 0) {
+        return "virtio-net";
+    } else if (strcmp(typename, "virtio-serial-pci") == 0) {
+        return "virtio-serial";
+    } else if (strcmp(typename, "virtio-balloon-pci") == 0) {
+        return "virtio-balloon";
+    } else if (strcmp(typename, "virtio-blk-s390") == 0) {
+        return "virtio-blk";
+    } else if (strcmp(typename, "virtio-net-s390") == 0) {
+        return "virtio-net";
+    } else if (strcmp(typename, "virtio-serial-s390") == 0) {
+        return "virtio-serial";
+    } else if (strcmp(typename, "lsi53c895a") == 0) {
+        return "lsi";
+    } else if (strcmp(typename, "ich9-ahci") == 0) {
+        return "ahci";
+    }
+
+    return NULL;
+}
+
+static bool qdev_class_has_alias(DeviceClass *dc)
+{
+    return (qdev_class_get_alias(dc) != NULL);
+}
+
+static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
+{
+    DeviceClass *dc;
+    bool *show_no_user = opaque;
+
+    dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
+
+    if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
+        return;
+    }
+
+    error_printf("name \"%s\"", object_class_get_name(klass));
+    if (dc->bus_info) {
+        error_printf(", bus %s", dc->bus_info->name);
+    }
+    if (qdev_class_has_alias(dc)) {
+        error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
+    }
+    if (dc->desc) {
+        error_printf(", desc \"%s\"", dc->desc);
+    }
+    if (dc->no_user) {
+        error_printf(", no-user");
+    }
+    error_printf("\n");
+}
+
+static int set_property(const char *name, const char *value, void *opaque)
+{
+    DeviceState *dev = opaque;
+
+    if (strcmp(name, "driver") == 0)
+        return 0;
+    if (strcmp(name, "bus") == 0)
+        return 0;
+
+    if (qdev_prop_parse(dev, name, value) == -1) {
+        return -1;
+    }
+    return 0;
+}
+
+static const char *find_typename_by_alias(const char *alias)
+{
+    /* I don't think s390 aliasing could have ever worked... */
+
+    if (strcmp(alias, "virtio-blk") == 0) {
+        return "virtio-blk-pci";
+    } else if (strcmp(alias, "virtio-net") == 0) {
+        return "virtio-net-pci";
+    } else if (strcmp(alias, "virtio-serial") == 0) {
+        return "virtio-serial-pci";
+    } else if (strcmp(alias, "virtio-balloon") == 0) {
+        return "virtio-balloon-pci";
+    } else if (strcmp(alias, "lsi") == 0) {
+        return "lsi53c895a";
+    } else if (strcmp(alias, "ahci") == 0) {
+        return "ich9-ahci";
+    }
+
+    return NULL;
+}
+
+int qdev_device_help(QemuOpts *opts)
+{
+    const char *driver;
+    Property *prop;
+    ObjectClass *klass;
+    DeviceClass *info;
+
+    driver = qemu_opt_get(opts, "driver");
+    if (driver && !strcmp(driver, "?")) {
+        bool show_no_user = false;
+        object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, &show_no_user);
+        return 1;
+    }
+
+    if (!driver || !qemu_opt_get(opts, "?")) {
+        return 0;
+    }
+
+    klass = object_class_by_name(driver);
+    if (!klass) {
+        const char *typename = find_typename_by_alias(driver);
+
+        if (typename) {
+            driver = typename;
+            klass = object_class_by_name(driver);
+        }
+    }
+
+    if (!klass) {
+        return 0;
+    }
+    info = DEVICE_CLASS(klass);
+
+    for (prop = info->props; prop && prop->name; prop++) {
+        /*
+         * TODO Properties without a parser are just for dirty hacks.
+         * qdev_prop_ptr is the only such PropertyInfo.  It's marked
+         * for removal.  This conditional should be removed along with
+         * it.
+         */
+        if (!prop->info->parse) {
+            continue;           /* no way to set it, don't show */
+        }
+        error_printf("%s.%s=%s\n", driver, prop->name,
+                     prop->info->legacy_name ?: prop->info->name);
+    }
+    for (prop = info->bus_info->props; prop && prop->name; prop++) {
+        if (!prop->info->parse) {
+            continue;           /* no way to set it, don't show */
+        }
+        error_printf("%s.%s=%s\n", driver, prop->name,
+                     prop->info->legacy_name ?: prop->info->name);
+    }
+    return 1;
+}
+
+static DeviceState *qdev_get_peripheral(void)
+{
+    static DeviceState *dev;
+
+    if (dev == NULL) {
+        dev = qdev_create(NULL, "container");
+        qdev_property_add_child(qdev_get_root(), "peripheral", dev, NULL);
+        qdev_init_nofail(dev);
+    }
+
+    return dev;
+}
+
+static DeviceState *qdev_get_peripheral_anon(void)
+{
+    static DeviceState *dev;
+
+    if (dev == NULL) {
+        dev = qdev_create(NULL, "container");
+        qdev_property_add_child(qdev_get_root(), "peripheral-anon", dev, NULL);
+        qdev_init_nofail(dev);
+    }
+
+    return dev;
+}
+
+static void qbus_list_bus(DeviceState *dev)
+{
+    BusState *child;
+    const char *sep = " ";
+
+    error_printf("child busses at \"%s\":",
+                 dev->id ? dev->id : object_get_typename(OBJECT(dev)));
+    QLIST_FOREACH(child, &dev->child_bus, sibling) {
+        error_printf("%s\"%s\"", sep, child->name);
+        sep = ", ";
+    }
+    error_printf("\n");
+}
+
+static void qbus_list_dev(BusState *bus)
+{
+    DeviceState *dev;
+    const char *sep = " ";
+
+    error_printf("devices at \"%s\":", bus->name);
+    QTAILQ_FOREACH(dev, &bus->children, sibling) {
+        error_printf("%s\"%s\"", sep, object_get_typename(OBJECT(dev)));
+        if (dev->id)
+            error_printf("/\"%s\"", dev->id);
+        sep = ", ";
+    }
+    error_printf("\n");
+}
+
+static BusState *qbus_find_bus(DeviceState *dev, char *elem)
+{
+    BusState *child;
+
+    QLIST_FOREACH(child, &dev->child_bus, sibling) {
+        if (strcmp(child->name, elem) == 0) {
+            return child;
+        }
+    }
+    return NULL;
+}
+
+static DeviceState *qbus_find_dev(BusState *bus, char *elem)
+{
+    DeviceState *dev;
+
+    /*
+     * try to match in order:
+     *   (1) instance id, if present
+     *   (2) driver name
+     *   (3) driver alias, if present
+     */
+    QTAILQ_FOREACH(dev, &bus->children, sibling) {
+        if (dev->id  &&  strcmp(dev->id, elem) == 0) {
+            return dev;
+        }
+    }
+    QTAILQ_FOREACH(dev, &bus->children, sibling) {
+        if (strcmp(object_get_typename(OBJECT(dev)), elem) == 0) {
+            return dev;
+        }
+    }
+    QTAILQ_FOREACH(dev, &bus->children, sibling) {
+        DeviceClass *dc = DEVICE_GET_CLASS(dev);
+
+        if (qdev_class_has_alias(dc) &&
+            strcmp(qdev_class_get_alias(dc), elem) == 0) {
+            return dev;
+        }
+    }
+    return NULL;
+}
+
+static BusState *qbus_find_recursive(BusState *bus, const char *name,
+                                     const BusInfo *info)
+{
+    DeviceState *dev;
+    BusState *child, *ret;
+    int match = 1;
+
+    if (name && (strcmp(bus->name, name) != 0)) {
+        match = 0;
+    }
+    if (info && (bus->info != info)) {
+        match = 0;
+    }
+    if (match) {
+        return bus;
+    }
+
+    QTAILQ_FOREACH(dev, &bus->children, sibling) {
+        QLIST_FOREACH(child, &dev->child_bus, sibling) {
+            ret = qbus_find_recursive(child, name, info);
+            if (ret) {
+                return ret;
+            }
+        }
+    }
+    return NULL;
+}
+
+static BusState *qbus_find(const char *path)
+{
+    DeviceState *dev;
+    BusState *bus;
+    char elem[128];
+    int pos, len;
+
+    /* find start element */
+    if (path[0] == '/') {
+        bus = sysbus_get_default();
+        pos = 0;
+    } else {
+        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
+            assert(!path[0]);
+            elem[0] = len = 0;
+        }
+        bus = qbus_find_recursive(sysbus_get_default(), elem, NULL);
+        if (!bus) {
+            qerror_report(QERR_BUS_NOT_FOUND, elem);
+            return NULL;
+        }
+        pos = len;
+    }
+
+    for (;;) {
+        assert(path[pos] == '/' || !path[pos]);
+        while (path[pos] == '/') {
+            pos++;
+        }
+        if (path[pos] == '\0') {
+            return bus;
+        }
+
+        /* find device */
+        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
+            assert(0);
+            elem[0] = len = 0;
+        }
+        pos += len;
+        dev = qbus_find_dev(bus, elem);
+        if (!dev) {
+            qerror_report(QERR_DEVICE_NOT_FOUND, elem);
+            if (!monitor_cur_is_qmp()) {
+                qbus_list_dev(bus);
+            }
+            return NULL;
+        }
+
+        assert(path[pos] == '/' || !path[pos]);
+        while (path[pos] == '/') {
+            pos++;
+        }
+        if (path[pos] == '\0') {
+            /* last specified element is a device.  If it has exactly
+             * one child bus accept it nevertheless */
+            switch (dev->num_child_bus) {
+            case 0:
+                qerror_report(QERR_DEVICE_NO_BUS, elem);
+                return NULL;
+            case 1:
+                return QLIST_FIRST(&dev->child_bus);
+            default:
+                qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
+                if (!monitor_cur_is_qmp()) {
+                    qbus_list_bus(dev);
+                }
+                return NULL;
+            }
+        }
+
+        /* find bus */
+        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
+            assert(0);
+            elem[0] = len = 0;
+        }
+        pos += len;
+        bus = qbus_find_bus(dev, elem);
+        if (!bus) {
+            qerror_report(QERR_BUS_NOT_FOUND, elem);
+            if (!monitor_cur_is_qmp()) {
+                qbus_list_bus(dev);
+            }
+            return NULL;
+        }
+    }
+}
+
+DeviceState *qdev_device_add(QemuOpts *opts)
+{
+    ObjectClass *obj;
+    DeviceClass *k;
+    const char *driver, *path, *id;
+    DeviceState *qdev;
+    BusState *bus;
+
+    driver = qemu_opt_get(opts, "driver");
+    if (!driver) {
+        qerror_report(QERR_MISSING_PARAMETER, "driver");
+        return NULL;
+    }
+
+    /* find driver */
+    obj = object_class_by_name(driver);
+    if (!obj) {
+        const char *typename = find_typename_by_alias(driver);
+
+        if (typename) {
+            driver = typename;
+            obj = object_class_by_name(driver);
+        }
+    }
+
+    if (!obj) {
+        qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "device type");
+        return NULL;
+    }
+
+    k = DEVICE_CLASS(obj);
+
+    /* find bus */
+    path = qemu_opt_get(opts, "bus");
+    if (path != NULL) {
+        bus = qbus_find(path);
+        if (!bus) {
+            return NULL;
+        }
+        if (bus->info != k->bus_info) {
+            qerror_report(QERR_BAD_BUS_FOR_DEVICE,
+                           driver, bus->info->name);
+            return NULL;
+        }
+    } else {
+        bus = qbus_find_recursive(sysbus_get_default(), NULL, k->bus_info);
+        if (!bus) {
+            qerror_report(QERR_NO_BUS_FOR_DEVICE,
+                          driver, k->bus_info->name);
+            return NULL;
+        }
+    }
+    if (qdev_hotplug && !bus->allow_hotplug) {
+        qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
+        return NULL;
+    }
+
+    if (!bus) {
+        bus = sysbus_get_default();
+    }
+
+    /* create device, set properties */
+    qdev = DEVICE(object_new(driver));
+    qdev_set_parent_bus(qdev, bus);
+    qdev_prop_set_globals(qdev);
+
+    id = qemu_opts_id(opts);
+    if (id) {
+        qdev->id = id;
+        qdev_property_add_child(qdev_get_peripheral(), qdev->id, qdev, NULL);
+    } else {
+        static int anon_count;
+        gchar *name = g_strdup_printf("device[%d]", anon_count++);
+        qdev_property_add_child(qdev_get_peripheral_anon(), name,
+                                qdev, NULL);
+        g_free(name);
+    }        
+    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
+        qdev_free(qdev);
+        return NULL;
+    }
+    if (qdev_init(qdev) < 0) {
+        qerror_report(QERR_DEVICE_INIT_FAILED, driver);
+        return NULL;
+    }
+    qdev->opts = opts;
+    return qdev;
+}
+
+
+#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
+static void qbus_print(Monitor *mon, BusState *bus, int indent);
+
+static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
+                             const char *prefix, int indent)
+{
+    char buf[64];
+
+    if (!props)
+        return;
+    while (props->name) {
+        /*
+         * TODO Properties without a print method are just for dirty
+         * hacks.  qdev_prop_ptr is the only such PropertyInfo.  It's
+         * marked for removal.  The test props->info->print should be
+         * removed along with it.
+         */
+        if (props->info->print) {
+            props->info->print(dev, props, buf, sizeof(buf));
+            qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
+        }
+        props++;
+    }
+}
+
+static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
+{
+    BusState *child;
+    qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
+                dev->id ? dev->id : "");
+    indent += 2;
+    if (dev->num_gpio_in) {
+        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
+    }
+    if (dev->num_gpio_out) {
+        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
+    }
+    qdev_print_props(mon, dev, qdev_get_props(dev), "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);
+    QLIST_FOREACH(child, &dev->child_bus, sibling) {
+        qbus_print(mon, child, indent);
+    }
+}
+
+static void qbus_print(Monitor *mon, BusState *bus, int indent)
+{
+    struct DeviceState *dev;
+
+    qdev_printf("bus: %s\n", bus->name);
+    indent += 2;
+    qdev_printf("type %s\n", bus->info->name);
+    QTAILQ_FOREACH(dev, &bus->children, sibling) {
+        qdev_print(mon, dev, indent);
+    }
+}
+#undef qdev_printf
+
+void do_info_qtree(Monitor *mon)
+{
+    if (sysbus_get_default())
+        qbus_print(mon, sysbus_get_default(), 0);
+}
+
+void do_info_qdm(Monitor *mon)
+{
+    object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, NULL);
+}
+
+int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+    QemuOpts *opts;
+
+    opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
+    if (!opts) {
+        return -1;
+    }
+    if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
+        qemu_opts_del(opts);
+        return 0;
+    }
+    if (!qdev_device_add(opts)) {
+        qemu_opts_del(opts);
+        return -1;
+    }
+    return 0;
+}
+
+int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+    const char *id = qdict_get_str(qdict, "id");
+    DeviceState *dev;
+
+    dev = qdev_find_recursive(sysbus_get_default(), id);
+    if (NULL == dev) {
+        qerror_report(QERR_DEVICE_NOT_FOUND, id);
+        return -1;
+    }
+    return qdev_unplug(dev);
+}
+
+void qdev_machine_init(void)
+{
+    qdev_get_peripheral_anon();
+    qdev_get_peripheral();
+}
diff --git a/hw/qdev.c b/hw/qdev.c
index 5c8dc53..e82165d 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -28,9 +28,8 @@
 #include "net.h"
 #include "qdev.h"
 #include "sysemu.h"
-#include "monitor.h"
 
-static int qdev_hotplug = 0;
+int qdev_hotplug = 0;
 static bool qdev_hot_added = false;
 static bool qdev_hot_removed = false;
 
@@ -38,10 +37,6 @@ static bool qdev_hot_removed = false;
 static BusState *main_system_bus;
 static void main_system_bus_create(void);
 
-static BusState *qbus_find_recursive(BusState *bus, const char *name,
-                                     const BusInfo *info);
-static BusState *qbus_find(const char *path);
-
 /* Register a new device type.  */
 const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
 {
@@ -61,50 +56,12 @@ Property *qdev_get_props(DeviceState *dev)
     return dc->props;
 }
 
-/*
- * Aliases were a bad idea from the start.  Let's keep them
- * from spreading further.
- */
-static const char *qdev_class_get_alias(DeviceClass *dc)
-{
-    const char *typename = object_class_get_name(OBJECT_CLASS(dc));
-
-    if (strcmp(typename, "virtio-blk-pci") == 0) {
-        return "virtio-blk";
-    } else if (strcmp(typename, "virtio-net-pci") == 0) {
-        return "virtio-net";
-    } else if (strcmp(typename, "virtio-serial-pci") == 0) {
-        return "virtio-serial";
-    } else if (strcmp(typename, "virtio-balloon-pci") == 0) {
-        return "virtio-balloon";
-    } else if (strcmp(typename, "virtio-blk-s390") == 0) {
-        return "virtio-blk";
-    } else if (strcmp(typename, "virtio-net-s390") == 0) {
-        return "virtio-net";
-    } else if (strcmp(typename, "virtio-serial-s390") == 0) {
-        return "virtio-serial";
-    } else if (strcmp(typename, "lsi53c895a") == 0) {
-        return "lsi";
-    } else if (strcmp(typename, "ich9-ahci") == 0) {
-        return "ahci";
-    }
-
-    return NULL;
-}
-
-static bool qdev_class_has_alias(DeviceClass *dc)
-{
-    return (qdev_class_get_alias(dc) != NULL);
-}
-
 const char *qdev_fw_name(DeviceState *dev)
 {
     DeviceClass *dc = DEVICE_GET_CLASS(dev);
 
     if (dc->fw_name) {
         return dc->fw_name;
-    } else if (qdev_class_has_alias(dc)) {
-        return qdev_class_get_alias(dc);
     }
 
     return object_get_typename(OBJECT(dev));
@@ -175,240 +132,6 @@ DeviceState *qdev_try_create(BusState *bus, const char *name)
     return dev;
 }
 
-static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
-{
-    DeviceClass *dc;
-    bool *show_no_user = opaque;
-
-    dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
-
-    if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
-        return;
-    }
-
-    error_printf("name \"%s\"", object_class_get_name(klass));
-    if (dc->bus_info) {
-        error_printf(", bus %s", dc->bus_info->name);
-    }
-    if (qdev_class_has_alias(dc)) {
-        error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
-    }
-    if (dc->desc) {
-        error_printf(", desc \"%s\"", dc->desc);
-    }
-    if (dc->no_user) {
-        error_printf(", no-user");
-    }
-    error_printf("\n");
-}
-
-static int set_property(const char *name, const char *value, void *opaque)
-{
-    DeviceState *dev = opaque;
-
-    if (strcmp(name, "driver") == 0)
-        return 0;
-    if (strcmp(name, "bus") == 0)
-        return 0;
-
-    if (qdev_prop_parse(dev, name, value) == -1) {
-        return -1;
-    }
-    return 0;
-}
-
-static const char *find_typename_by_alias(const char *alias)
-{
-    /* I don't think s390 aliasing could have ever worked... */
-
-    if (strcmp(alias, "virtio-blk") == 0) {
-        return "virtio-blk-pci";
-    } else if (strcmp(alias, "virtio-net") == 0) {
-        return "virtio-net-pci";
-    } else if (strcmp(alias, "virtio-serial") == 0) {
-        return "virtio-serial-pci";
-    } else if (strcmp(alias, "virtio-balloon") == 0) {
-        return "virtio-balloon-pci";
-    } else if (strcmp(alias, "lsi") == 0) {
-        return "lsi53c895a";
-    } else if (strcmp(alias, "ahci") == 0) {
-        return "ich9-ahci";
-    }
-
-    return NULL;
-}
-
-int qdev_device_help(QemuOpts *opts)
-{
-    const char *driver;
-    Property *prop;
-    ObjectClass *klass;
-    DeviceClass *info;
-
-    driver = qemu_opt_get(opts, "driver");
-    if (driver && !strcmp(driver, "?")) {
-        bool show_no_user = false;
-        object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, &show_no_user);
-        return 1;
-    }
-
-    if (!driver || !qemu_opt_get(opts, "?")) {
-        return 0;
-    }
-
-    klass = object_class_by_name(driver);
-    if (!klass) {
-        const char *typename = find_typename_by_alias(driver);
-
-        if (typename) {
-            driver = typename;
-            klass = object_class_by_name(driver);
-        }
-    }
-
-    if (!klass) {
-        return 0;
-    }
-    info = DEVICE_CLASS(klass);
-
-    for (prop = info->props; prop && prop->name; prop++) {
-        /*
-         * TODO Properties without a parser are just for dirty hacks.
-         * qdev_prop_ptr is the only such PropertyInfo.  It's marked
-         * for removal.  This conditional should be removed along with
-         * it.
-         */
-        if (!prop->info->parse) {
-            continue;           /* no way to set it, don't show */
-        }
-        error_printf("%s.%s=%s\n", driver, prop->name,
-                     prop->info->legacy_name ?: prop->info->name);
-    }
-    for (prop = info->bus_info->props; prop && prop->name; prop++) {
-        if (!prop->info->parse) {
-            continue;           /* no way to set it, don't show */
-        }
-        error_printf("%s.%s=%s\n", driver, prop->name,
-                     prop->info->legacy_name ?: prop->info->name);
-    }
-    return 1;
-}
-
-static DeviceState *qdev_get_peripheral(void)
-{
-    static DeviceState *dev;
-
-    if (dev == NULL) {
-        dev = qdev_create(NULL, "container");
-        qdev_property_add_child(qdev_get_root(), "peripheral", dev, NULL);
-        qdev_init_nofail(dev);
-    }
-
-    return dev;
-}
-
-static DeviceState *qdev_get_peripheral_anon(void)
-{
-    static DeviceState *dev;
-
-    if (dev == NULL) {
-        dev = qdev_create(NULL, "container");
-        qdev_property_add_child(qdev_get_root(), "peripheral-anon", dev, NULL);
-        qdev_init_nofail(dev);
-    }
-
-    return dev;
-}
-
-DeviceState *qdev_device_add(QemuOpts *opts)
-{
-    ObjectClass *obj;
-    DeviceClass *k;
-    const char *driver, *path, *id;
-    DeviceState *qdev;
-    BusState *bus;
-
-    driver = qemu_opt_get(opts, "driver");
-    if (!driver) {
-        qerror_report(QERR_MISSING_PARAMETER, "driver");
-        return NULL;
-    }
-
-    /* find driver */
-    obj = object_class_by_name(driver);
-    if (!obj) {
-        const char *typename = find_typename_by_alias(driver);
-
-        if (typename) {
-            driver = typename;
-            obj = object_class_by_name(driver);
-        }
-    }
-
-    if (!obj) {
-        qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "device type");
-        return NULL;
-    }
-
-    k = DEVICE_CLASS(obj);
-
-    /* find bus */
-    path = qemu_opt_get(opts, "bus");
-    if (path != NULL) {
-        bus = qbus_find(path);
-        if (!bus) {
-            return NULL;
-        }
-        if (bus->info != k->bus_info) {
-            qerror_report(QERR_BAD_BUS_FOR_DEVICE,
-                           driver, bus->info->name);
-            return NULL;
-        }
-    } else {
-        bus = qbus_find_recursive(main_system_bus, NULL, k->bus_info);
-        if (!bus) {
-            qerror_report(QERR_NO_BUS_FOR_DEVICE,
-                          driver, k->bus_info->name);
-            return NULL;
-        }
-    }
-    if (qdev_hotplug && !bus->allow_hotplug) {
-        qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
-        return NULL;
-    }
-
-    if (!bus) {
-        bus = sysbus_get_default();
-    }
-
-    /* create device, set properties */
-    qdev = DEVICE(object_new(driver));
-    qdev_set_parent_bus(qdev, bus);
-    qdev_prop_set_globals(qdev);
-
-    id = qemu_opts_id(opts);
-    if (id) {
-        qdev->id = id;
-        qdev_property_add_child(qdev_get_peripheral(), qdev->id, qdev, NULL);
-    } else {
-        static int anon_count;
-        gchar *name = g_strdup_printf("device[%d]", anon_count++);
-        qdev_property_add_child(qdev_get_peripheral_anon(), name,
-                                qdev, NULL);
-        g_free(name);
-    }        
-    if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
-        qdev_free(qdev);
-        return NULL;
-    }
-    if (qdev_init(qdev) < 0) {
-        qerror_report(QERR_DEVICE_INIT_FAILED, driver);
-        return NULL;
-    }
-    qdev->opts = opts;
-    return qdev;
-}
-
 /* Initialize a device.  Device properties should be set before calling
    this function.  IRQs and MMIO regions should be connected/mapped after
    calling this function.
@@ -725,34 +448,6 @@ int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
     return 0;
 }
 
-static BusState *qbus_find_recursive(BusState *bus, const char *name,
-                                     const BusInfo *info)
-{
-    DeviceState *dev;
-    BusState *child, *ret;
-    int match = 1;
-
-    if (name && (strcmp(bus->name, name) != 0)) {
-        match = 0;
-    }
-    if (info && (bus->info != info)) {
-        match = 0;
-    }
-    if (match) {
-        return bus;
-    }
-
-    QTAILQ_FOREACH(dev, &bus->children, sibling) {
-        QLIST_FOREACH(child, &dev->child_bus, sibling) {
-            ret = qbus_find_recursive(child, name, info);
-            if (ret) {
-                return ret;
-            }
-        }
-    }
-    return NULL;
-}
-
 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
 {
     DeviceState *dev, *ret;
@@ -771,165 +466,6 @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id)
     return NULL;
 }
 
-static void qbus_list_bus(DeviceState *dev)
-{
-    BusState *child;
-    const char *sep = " ";
-
-    error_printf("child busses at \"%s\":",
-                 dev->id ? dev->id : object_get_typename(OBJECT(dev)));
-    QLIST_FOREACH(child, &dev->child_bus, sibling) {
-        error_printf("%s\"%s\"", sep, child->name);
-        sep = ", ";
-    }
-    error_printf("\n");
-}
-
-static void qbus_list_dev(BusState *bus)
-{
-    DeviceState *dev;
-    const char *sep = " ";
-
-    error_printf("devices at \"%s\":", bus->name);
-    QTAILQ_FOREACH(dev, &bus->children, sibling) {
-        error_printf("%s\"%s\"", sep, object_get_typename(OBJECT(dev)));
-        if (dev->id)
-            error_printf("/\"%s\"", dev->id);
-        sep = ", ";
-    }
-    error_printf("\n");
-}
-
-static BusState *qbus_find_bus(DeviceState *dev, char *elem)
-{
-    BusState *child;
-
-    QLIST_FOREACH(child, &dev->child_bus, sibling) {
-        if (strcmp(child->name, elem) == 0) {
-            return child;
-        }
-    }
-    return NULL;
-}
-
-static DeviceState *qbus_find_dev(BusState *bus, char *elem)
-{
-    DeviceState *dev;
-
-    /*
-     * try to match in order:
-     *   (1) instance id, if present
-     *   (2) driver name
-     *   (3) driver alias, if present
-     */
-    QTAILQ_FOREACH(dev, &bus->children, sibling) {
-        if (dev->id  &&  strcmp(dev->id, elem) == 0) {
-            return dev;
-        }
-    }
-    QTAILQ_FOREACH(dev, &bus->children, sibling) {
-        if (strcmp(object_get_typename(OBJECT(dev)), elem) == 0) {
-            return dev;
-        }
-    }
-    QTAILQ_FOREACH(dev, &bus->children, sibling) {
-        DeviceClass *dc = DEVICE_GET_CLASS(dev);
-
-        if (qdev_class_has_alias(dc) &&
-            strcmp(qdev_class_get_alias(dc), elem) == 0) {
-            return dev;
-        }
-    }
-    return NULL;
-}
-
-static BusState *qbus_find(const char *path)
-{
-    DeviceState *dev;
-    BusState *bus;
-    char elem[128];
-    int pos, len;
-
-    /* find start element */
-    if (path[0] == '/') {
-        bus = main_system_bus;
-        pos = 0;
-    } else {
-        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
-            assert(!path[0]);
-            elem[0] = len = 0;
-        }
-        bus = qbus_find_recursive(main_system_bus, elem, NULL);
-        if (!bus) {
-            qerror_report(QERR_BUS_NOT_FOUND, elem);
-            return NULL;
-        }
-        pos = len;
-    }
-
-    for (;;) {
-        assert(path[pos] == '/' || !path[pos]);
-        while (path[pos] == '/') {
-            pos++;
-        }
-        if (path[pos] == '\0') {
-            return bus;
-        }
-
-        /* find device */
-        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
-            assert(0);
-            elem[0] = len = 0;
-        }
-        pos += len;
-        dev = qbus_find_dev(bus, elem);
-        if (!dev) {
-            qerror_report(QERR_DEVICE_NOT_FOUND, elem);
-            if (!monitor_cur_is_qmp()) {
-                qbus_list_dev(bus);
-            }
-            return NULL;
-        }
-
-        assert(path[pos] == '/' || !path[pos]);
-        while (path[pos] == '/') {
-            pos++;
-        }
-        if (path[pos] == '\0') {
-            /* last specified element is a device.  If it has exactly
-             * one child bus accept it nevertheless */
-            switch (dev->num_child_bus) {
-            case 0:
-                qerror_report(QERR_DEVICE_NO_BUS, elem);
-                return NULL;
-            case 1:
-                return QLIST_FIRST(&dev->child_bus);
-            default:
-                qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
-                if (!monitor_cur_is_qmp()) {
-                    qbus_list_bus(dev);
-                }
-                return NULL;
-            }
-        }
-
-        /* find bus */
-        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
-            assert(0);
-            elem[0] = len = 0;
-        }
-        pos += len;
-        bus = qbus_find_bus(dev, elem);
-        if (!bus) {
-            qerror_report(QERR_BUS_NOT_FOUND, elem);
-            if (!monitor_cur_is_qmp()) {
-                qbus_list_bus(dev);
-            }
-            return NULL;
-        }
-    }
-}
-
 void qbus_create_inplace(BusState *bus, BusInfo *info,
                          DeviceState *parent, const char *name)
 {
@@ -1010,108 +546,6 @@ void qbus_free(BusState *bus)
     }
 }
 
-#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
-static void qbus_print(Monitor *mon, BusState *bus, int indent);
-
-static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
-                             const char *prefix, int indent)
-{
-    char buf[64];
-
-    if (!props)
-        return;
-    while (props->name) {
-        /*
-         * TODO Properties without a print method are just for dirty
-         * hacks.  qdev_prop_ptr is the only such PropertyInfo.  It's
-         * marked for removal.  The test props->info->print should be
-         * removed along with it.
-         */
-        if (props->info->print) {
-            props->info->print(dev, props, buf, sizeof(buf));
-            qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
-        }
-        props++;
-    }
-}
-
-static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
-{
-    BusState *child;
-    qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
-                dev->id ? dev->id : "");
-    indent += 2;
-    if (dev->num_gpio_in) {
-        qdev_printf("gpio-in %d\n", dev->num_gpio_in);
-    }
-    if (dev->num_gpio_out) {
-        qdev_printf("gpio-out %d\n", dev->num_gpio_out);
-    }
-    qdev_print_props(mon, dev, qdev_get_props(dev), "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);
-    QLIST_FOREACH(child, &dev->child_bus, sibling) {
-        qbus_print(mon, child, indent);
-    }
-}
-
-static void qbus_print(Monitor *mon, BusState *bus, int indent)
-{
-    struct DeviceState *dev;
-
-    qdev_printf("bus: %s\n", bus->name);
-    indent += 2;
-    qdev_printf("type %s\n", bus->info->name);
-    QTAILQ_FOREACH(dev, &bus->children, sibling) {
-        qdev_print(mon, dev, indent);
-    }
-}
-#undef qdev_printf
-
-void do_info_qtree(Monitor *mon)
-{
-    if (main_system_bus)
-        qbus_print(mon, main_system_bus, 0);
-}
-
-void do_info_qdm(Monitor *mon)
-{
-    object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, NULL);
-}
-
-int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
-{
-    QemuOpts *opts;
-
-    opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
-    if (!opts) {
-        return -1;
-    }
-    if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
-        qemu_opts_del(opts);
-        return 0;
-    }
-    if (!qdev_device_add(opts)) {
-        qemu_opts_del(opts);
-        return -1;
-    }
-    return 0;
-}
-
-int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
-{
-    const char *id = qdict_get_str(qdict, "id");
-    DeviceState *dev;
-
-    dev = qdev_find_recursive(main_system_bus, id);
-    if (NULL == dev) {
-        qerror_report(QERR_DEVICE_NOT_FOUND, id);
-        return -1;
-    }
-    return qdev_unplug(dev);
-}
-
 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
 {
     int l = 0;
@@ -1643,12 +1077,6 @@ void qdev_property_add_str(DeviceState *dev, const char *name,
                       prop, errp);
 }
 
-void qdev_machine_init(void)
-{
-    qdev_get_peripheral_anon();
-    qdev_get_peripheral();
-}
-
 static void device_initfn(Object *obj)
 {
     DeviceState *dev = DEVICE(obj);
diff --git a/hw/qdev.h b/hw/qdev.h
index e611804..9535e57 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -639,4 +639,6 @@ Property *qdev_get_props(DeviceState *dev);
 /* FIXME: make this a link<> */
 void qdev_set_parent_bus(DeviceState *dev, BusState *bus);
 
+extern int qdev_hotplug;
+
 #endif
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 16/23] qdev: nuke qdev_init_chardev()
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (12 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 15/23] qdev: split out UI portions into a new function Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 17/23] qom: move properties from qdev to object Anthony Liguori
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

I'm sure the intentions were good here, but there's no reason this should be in
qdev.  Move it to qemu-char where it belongs.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/etraxfs_ser.c     |    2 +-
 hw/lm32_juart.c      |    2 +-
 hw/lm32_uart.c       |    2 +-
 hw/milkymist-uart.c  |    2 +-
 hw/pl011.c           |    2 +-
 hw/qdev.c            |    9 ---------
 hw/qdev.h            |    2 --
 hw/xilinx_uartlite.c |    2 +-
 qemu-char.c          |   10 ++++++++++
 qemu-char.h          |    2 ++
 10 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
index b8acd43..567cb8c 100644
--- a/hw/etraxfs_ser.c
+++ b/hw/etraxfs_ser.c
@@ -216,7 +216,7 @@ static int etraxfs_ser_init(SysBusDevice *dev)
     memory_region_init_io(&s->mmio, &ser_ops, s, "etraxfs-serial", R_MAX * 4);
     sysbus_init_mmio(dev, &s->mmio);
 
-    s->chr = qdev_init_chardev(&dev->qdev);
+    s->chr = qemu_char_get_next_serial();
     if (s->chr)
         qemu_chr_add_handlers(s->chr,
                       serial_can_receive, serial_receive,
diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c
index 023c644..38dd282 100644
--- a/hw/lm32_juart.c
+++ b/hw/lm32_juart.c
@@ -114,7 +114,7 @@ static int lm32_juart_init(SysBusDevice *dev)
 {
     LM32JuartState *s = FROM_SYSBUS(typeof(*s), dev);
 
-    s->chr = qdev_init_chardev(&dev->qdev);
+    s->chr = qemu_char_get_next_serial();
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, juart_can_rx, juart_rx, juart_event, s);
     }
diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c
index fc70490..630ccb7 100644
--- a/hw/lm32_uart.c
+++ b/hw/lm32_uart.c
@@ -252,7 +252,7 @@ static int lm32_uart_init(SysBusDevice *dev)
     memory_region_init_io(&s->iomem, &uart_ops, s, "uart", R_MAX * 4);
     sysbus_init_mmio(dev, &s->iomem);
 
-    s->chr = qdev_init_chardev(&dev->qdev);
+    s->chr = qemu_char_get_next_serial();
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
     }
diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c
index 2999b79..f9a229c 100644
--- a/hw/milkymist-uart.c
+++ b/hw/milkymist-uart.c
@@ -199,7 +199,7 @@ static int milkymist_uart_init(SysBusDevice *dev)
             "milkymist-uart", R_MAX * 4);
     sysbus_init_mmio(dev, &s->regs_region);
 
-    s->chr = qdev_init_chardev(&dev->qdev);
+    s->chr = qemu_char_get_next_serial();
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
     }
diff --git a/hw/pl011.c b/hw/pl011.c
index 8db2248..752cbf9 100644
--- a/hw/pl011.c
+++ b/hw/pl011.c
@@ -264,7 +264,7 @@ static int pl011_init(SysBusDevice *dev, const unsigned char *id)
     sysbus_init_mmio(dev, &s->iomem);
     sysbus_init_irq(dev, &s->irq);
     s->id = id;
-    s->chr = qdev_init_chardev(&dev->qdev);
+    s->chr = qemu_char_get_next_serial();
 
     s->read_trigger = 1;
     s->ifl = 0x12;
diff --git a/hw/qdev.c b/hw/qdev.c
index e82165d..0692a21 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -336,15 +336,6 @@ bool qdev_machine_modified(void)
     return qdev_hot_added || qdev_hot_removed;
 }
 
-/* Get a character (serial) device interface.  */
-CharDriverState *qdev_init_chardev(DeviceState *dev)
-{
-    static int next_serial;
-
-    /* FIXME: This function needs to go away: use chardev properties!  */
-    return serial_hds[next_serial++];
-}
-
 BusState *qdev_get_parent_bus(DeviceState *dev)
 {
     return dev->parent_bus;
diff --git a/hw/qdev.h b/hw/qdev.h
index 9535e57..d1f0e19 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -234,8 +234,6 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n);
 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n);
 
-CharDriverState *qdev_init_chardev(DeviceState *dev);
-
 BusState *qdev_get_parent_bus(DeviceState *dev);
 
 /*** BUS API. ***/
diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c
index 1491bba..1c2b908 100644
--- a/hw/xilinx_uartlite.c
+++ b/hw/xilinx_uartlite.c
@@ -205,7 +205,7 @@ static int xilinx_uartlite_init(SysBusDevice *dev)
     memory_region_init_io(&s->mmio, &uart_ops, s, "xilinx-uartlite", R_MAX * 4);
     sysbus_init_mmio(dev, &s->mmio);
 
-    s->chr = qdev_init_chardev(&dev->qdev);
+    s->chr = qemu_char_get_next_serial();
     if (s->chr)
         qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
     return 0;
diff --git a/qemu-char.c b/qemu-char.c
index 27abcb9..b1d80dd 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2903,3 +2903,13 @@ CharDriverState *qemu_chr_find(const char *name)
     }
     return NULL;
 }
+
+/* Get a character (serial) device interface.  */
+CharDriverState *qemu_char_get_next_serial(void)
+{
+    static int next_serial;
+
+    /* FIXME: This function needs to go away: use chardev properties!  */
+    return serial_hds[next_serial++];
+}
+
diff --git a/qemu-char.h b/qemu-char.h
index 8ca1e2d..486644b 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -248,4 +248,6 @@ void qemu_chr_close_mem(CharDriverState *chr);
 QString *qemu_chr_mem_to_qs(CharDriverState *chr);
 size_t qemu_chr_mem_osize(const CharDriverState *chr);
 
+CharDriverState *qemu_char_get_next_serial(void);
+
 #endif
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 17/23] qom: move properties from qdev to object
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (13 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 16/23] qdev: nuke qdev_init_chardev() Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-31  7:46   ` Paolo Bonzini
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 18/23] qom: accept any compatible type when setting a link property Anthony Liguori
                   ` (6 subsequent siblings)
  21 siblings, 1 reply; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

This is mostly code movement although not entirely.  This makes properties part
of the Object base class which means that we can now start using Object in a
meaningful way outside of qdev.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 hw/mc146818rtc.c      |    8 +-
 hw/pc_piix.c          |    6 +-
 hw/piix_pci.c         |    4 +-
 hw/qdev-addr.c        |    6 +-
 hw/qdev-monitor.c     |   21 ++-
 hw/qdev-properties.c  |   53 ++++--
 hw/qdev.c             |  490 ++-----------------------------------------------
 hw/qdev.h             |  277 +---------------------------
 include/qemu/object.h |  223 ++++++++++++++++++++++-
 qapi-schema.json      |   22 +-
 qmp.c                 |   34 ++--
 qom/object.c          |  457 +++++++++++++++++++++++++++++++++++++++++++++
 12 files changed, 785 insertions(+), 816 deletions(-)

diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index c1f4ef4..346a95e 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -626,10 +626,10 @@ static void visit_type_int32(Visitor *v, int *value, const char *name, Error **e
     visit_type_int(v, &val, name, errp);
 }
 
-static void rtc_get_date(DeviceState *dev, Visitor *v, void *opaque,
+static void rtc_get_date(Object *obj, Visitor *v, void *opaque,
                          const char *name, Error **errp)
 {
-    ISADevice *isa = ISA_DEVICE(dev);
+    ISADevice *isa = ISA_DEVICE(obj);
     RTCState *s = DO_UPCAST(RTCState, dev, isa);
 
     visit_start_struct(v, NULL, "struct tm", name, 0, errp);
@@ -676,8 +676,8 @@ static int rtc_initfn(ISADevice *dev)
     qdev_set_legacy_instance_id(&dev->qdev, base, 2);
     qemu_register_reset(rtc_reset, s);
 
-    qdev_property_add(&s->dev.qdev, "date", "struct tm",
-                      rtc_get_date, NULL, NULL, s, NULL);
+    object_property_add(OBJECT(s), "date", "struct tm",
+                        rtc_get_date, NULL, NULL, s, NULL);
 
     return 0;
 }
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index a285ad2..c06f1b5 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -229,7 +229,7 @@ static void pc_init1(MemoryRegion *system_memory,
 
     dev = pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL);
     if (dev) {
-        qdev_property_add_child(qdev_get_root(), "vga", dev, NULL);
+        object_property_add_child(object_get_root(), "vga", OBJECT(dev), NULL);
     }
 
     if (xen_enabled()) {
@@ -267,8 +267,8 @@ static void pc_init1(MemoryRegion *system_memory,
          * For now, let's "fix" this by making judicious use of paths.  This
          * is not generally the right way to do this.
          */
-        qdev_property_add_child(qdev_resolve_path("/i440fx/piix3", NULL),
-                                "rtc", (DeviceState *)rtc_state, NULL);
+        object_property_add_child(object_resolve_path("/i440fx/piix3", NULL),
+                                  "rtc", (Object *)rtc_state, NULL);
     } else {
         for(i = 0; i < MAX_IDE_BUS; i++) {
             ISADevice *dev;
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 2bbfa4a..1906427 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -277,7 +277,7 @@ static PCIBus *i440fx_common_init(const char *device_name,
                     address_space_io, 0);
     s->bus = b;
     qdev_init_nofail(dev);
-    qdev_property_add_child(qdev_get_root(), "i440fx", dev, NULL);
+    object_property_add_child(object_get_root(), "i440fx", OBJECT(dev), NULL);
 
     d = pci_create_simple(b, 0, device_name);
     *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
@@ -316,7 +316,7 @@ static PCIBus *i440fx_common_init(const char *device_name,
         pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
                 PIIX_NUM_PIRQS);
     }
-    qdev_property_add_child(dev, "piix3", &piix3->dev.qdev, NULL);
+    object_property_add_child(OBJECT(dev), "piix3", OBJECT(piix3), NULL);
     piix3->pic = pic;
     *isa_bus = DO_UPCAST(ISABus, qbus,
                          qdev_get_child_bus(&piix3->dev.qdev, "isa.0"));
diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
index 5ddda2d..5976dcd 100644
--- a/hw/qdev-addr.c
+++ b/hw/qdev-addr.c
@@ -18,9 +18,10 @@ static int print_taddr(DeviceState *dev, Property *prop, char *dest, size_t len)
     return snprintf(dest, len, "0x" TARGET_FMT_plx, *ptr);
 }
 
-static void get_taddr(DeviceState *dev, Visitor *v, void *opaque,
+static void get_taddr(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop);
     int64_t value;
@@ -29,9 +30,10 @@ static void get_taddr(DeviceState *dev, Visitor *v, void *opaque,
     visit_type_int(v, &value, name, errp);
 }
 
-static void set_taddr(DeviceState *dev, Visitor *v, void *opaque,
+static void set_taddr(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop);
     Error *local_err = NULL;
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 3894574..46946fe 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -175,30 +175,32 @@ int qdev_device_help(QemuOpts *opts)
     return 1;
 }
 
-static DeviceState *qdev_get_peripheral(void)
+static Object *qdev_get_peripheral(void)
 {
     static DeviceState *dev;
 
     if (dev == NULL) {
         dev = qdev_create(NULL, "container");
-        qdev_property_add_child(qdev_get_root(), "peripheral", dev, NULL);
+        object_property_add_child(object_get_root(), "peripheral",
+                                  OBJECT(dev), NULL);
         qdev_init_nofail(dev);
     }
 
-    return dev;
+    return OBJECT(dev);
 }
 
-static DeviceState *qdev_get_peripheral_anon(void)
+static Object *qdev_get_peripheral_anon(void)
 {
     static DeviceState *dev;
 
     if (dev == NULL) {
         dev = qdev_create(NULL, "container");
-        qdev_property_add_child(qdev_get_root(), "peripheral-anon", dev, NULL);
+        object_property_add_child(object_get_root(), "peripheral-anon",
+                                  OBJECT(dev), NULL);
         qdev_init_nofail(dev);
     }
 
-    return dev;
+    return OBJECT(dev);
 }
 
 static void qbus_list_bus(DeviceState *dev)
@@ -457,12 +459,13 @@ DeviceState *qdev_device_add(QemuOpts *opts)
     id = qemu_opts_id(opts);
     if (id) {
         qdev->id = id;
-        qdev_property_add_child(qdev_get_peripheral(), qdev->id, qdev, NULL);
+        object_property_add_child(qdev_get_peripheral(), qdev->id,
+                                  OBJECT(qdev), NULL);
     } else {
         static int anon_count;
         gchar *name = g_strdup_printf("device[%d]", anon_count++);
-        qdev_property_add_child(qdev_get_peripheral_anon(), name,
-                                qdev, NULL);
+        object_property_add_child(qdev_get_peripheral_anon(), name,
+                                  OBJECT(qdev), NULL);
         g_free(name);
     }        
     if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 724dce5..d34df30 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -55,9 +55,10 @@ static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
     return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
 }
 
-static void get_bit(DeviceState *dev, Visitor *v, void *opaque,
+static void get_bit(Object *obj, Visitor *v, void *opaque,
                     const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint32_t *p = qdev_get_prop_ptr(dev, prop);
     bool value = (*p & qdev_get_prop_mask(prop)) != 0;
@@ -65,9 +66,10 @@ static void get_bit(DeviceState *dev, Visitor *v, void *opaque,
     visit_type_bool(v, &value, name, errp);
 }
 
-static void set_bit(DeviceState *dev, Visitor *v, void *opaque,
+static void set_bit(Object *obj, Visitor *v, void *opaque,
                     const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     Error *local_err = NULL;
     bool value;
@@ -118,9 +120,10 @@ static int print_uint8(DeviceState *dev, Property *prop, char *dest, size_t len)
     return snprintf(dest, len, "%" PRIu8, *ptr);
 }
 
-static void get_int8(DeviceState *dev, Visitor *v, void *opaque,
+static void get_int8(Object *obj, Visitor *v, void *opaque,
                      const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int8_t *ptr = qdev_get_prop_ptr(dev, prop);
     int64_t value;
@@ -129,9 +132,10 @@ static void get_int8(DeviceState *dev, Visitor *v, void *opaque,
     visit_type_int(v, &value, name, errp);
 }
 
-static void set_int8(DeviceState *dev, Visitor *v, void *opaque,
-                      const char *name, Error **errp)
+static void set_int8(Object *obj, Visitor *v, void *opaque,
+                     const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int8_t *ptr = qdev_get_prop_ptr(dev, prop);
     Error *local_err = NULL;
@@ -224,9 +228,10 @@ static int print_uint16(DeviceState *dev, Property *prop, char *dest, size_t len
     return snprintf(dest, len, "%" PRIu16, *ptr);
 }
 
-static void get_int16(DeviceState *dev, Visitor *v, void *opaque,
+static void get_int16(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int16_t *ptr = qdev_get_prop_ptr(dev, prop);
     int64_t value;
@@ -235,9 +240,10 @@ static void get_int16(DeviceState *dev, Visitor *v, void *opaque,
     visit_type_int(v, &value, name, errp);
 }
 
-static void set_int16(DeviceState *dev, Visitor *v, void *opaque,
+static void set_int16(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int16_t *ptr = qdev_get_prop_ptr(dev, prop);
     Error *local_err = NULL;
@@ -296,9 +302,10 @@ static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len
     return snprintf(dest, len, "%" PRIu32, *ptr);
 }
 
-static void get_int32(DeviceState *dev, Visitor *v, void *opaque,
+static void get_int32(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
     int64_t value;
@@ -307,9 +314,10 @@ static void get_int32(DeviceState *dev, Visitor *v, void *opaque,
     visit_type_int(v, &value, name, errp);
 }
 
-static void set_int32(DeviceState *dev, Visitor *v, void *opaque,
+static void set_int32(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int32_t *ptr = qdev_get_prop_ptr(dev, prop);
     Error *local_err = NULL;
@@ -433,18 +441,20 @@ static int print_uint64(DeviceState *dev, Property *prop, char *dest, size_t len
     return snprintf(dest, len, "%" PRIu64, *ptr);
 }
 
-static void get_int64(DeviceState *dev, Visitor *v, void *opaque,
+static void get_int64(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int64_t *ptr = qdev_get_prop_ptr(dev, prop);
 
     visit_type_int(v, ptr, name, errp);
 }
 
-static void set_int64(DeviceState *dev, Visitor *v, void *opaque,
+static void set_int64(Object *obj, Visitor *v, void *opaque,
                       const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     int64_t *ptr = qdev_get_prop_ptr(dev, prop);
 
@@ -523,9 +533,10 @@ static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len
     return snprintf(dest, len, "\"%s\"", *ptr);
 }
 
-static void get_string(DeviceState *dev, Visitor *v, void *opaque,
+static void get_string(Object *obj, Visitor *v, void *opaque,
                        const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     char **ptr = qdev_get_prop_ptr(dev, prop);
 
@@ -537,9 +548,10 @@ static void get_string(DeviceState *dev, Visitor *v, void *opaque,
     }
 }
 
-static void set_string(DeviceState *dev, Visitor *v, void *opaque,
+static void set_string(Object *obj, Visitor *v, void *opaque,
                        const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     char **ptr = qdev_get_prop_ptr(dev, prop);
     Error *local_err = NULL;
@@ -609,9 +621,10 @@ static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t len)
                     *ptr ? bdrv_get_device_name(*ptr) : "<null>");
 }
 
-static void get_generic(DeviceState *dev, Visitor *v, void *opaque,
+static void get_generic(Object *obj, Visitor *v, void *opaque,
                        const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     void **ptr = qdev_get_prop_ptr(dev, prop);
     char buffer[1024];
@@ -624,9 +637,10 @@ static void get_generic(DeviceState *dev, Visitor *v, void *opaque,
     visit_type_str(v, &p, name, errp);
 }
 
-static void set_generic(DeviceState *dev, Visitor *v, void *opaque,
+static void set_generic(Object *obj, Visitor *v, void *opaque,
                         const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     Error *local_err = NULL;
     char *str;
@@ -774,9 +788,10 @@ static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
     }
 }
 
-static void get_vlan(DeviceState *dev, Visitor *v, void *opaque,
+static void get_vlan(Object *obj, Visitor *v, void *opaque,
                      const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     VLANState **ptr = qdev_get_prop_ptr(dev, prop);
     int64_t id;
@@ -785,9 +800,10 @@ static void get_vlan(DeviceState *dev, Visitor *v, void *opaque,
     visit_type_int(v, &id, name, errp);
 }
 
-static void set_vlan(DeviceState *dev, Visitor *v, void *opaque,
+static void set_vlan(Object *obj, Visitor *v, void *opaque,
                      const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     VLANState **ptr = qdev_get_prop_ptr(dev, prop);
     Error *local_err = NULL;
@@ -922,9 +938,10 @@ static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t
     }
 }
 
-static void get_pci_devfn(DeviceState *dev, Visitor *v, void *opaque,
+static void get_pci_devfn(Object *obj, Visitor *v, void *opaque,
                           const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
     char buffer[32];
diff --git a/hw/qdev.c b/hw/qdev.c
index 0692a21..91dbbc7 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -243,46 +243,6 @@ void qdev_init_nofail(DeviceState *dev)
     }
 }
 
-static void qdev_property_del_all(DeviceState *dev)
-{
-    while (!QTAILQ_EMPTY(&dev->properties)) {
-        DeviceProperty *prop = QTAILQ_FIRST(&dev->properties);
-
-        QTAILQ_REMOVE(&dev->properties, prop, node);
-
-        if (prop->release) {
-            prop->release(dev, prop->name, prop->opaque);
-        }
-
-        g_free(prop->name);
-        g_free(prop->type);
-        g_free(prop);
-    }
-}
-
-static void qdev_property_del_child(DeviceState *dev, DeviceState *child, Error **errp)
-{
-    DeviceProperty *prop;
-
-    QTAILQ_FOREACH(prop, &dev->properties, node) {
-        if (strstart(prop->type, "child<", NULL) && prop->opaque == child) {
-            break;
-        }
-    }
-
-    g_assert(prop != NULL);
-
-    QTAILQ_REMOVE(&dev->properties, prop, node);
-
-    if (prop->release) {
-        prop->release(dev, prop->name, prop->opaque);
-    }
-
-    g_free(prop->name);
-    g_free(prop->type);
-    g_free(prop);
-}
-
 /* Unlink device from bus and free the structure.  */
 void qdev_free(DeviceState *dev)
 {
@@ -290,8 +250,6 @@ void qdev_free(DeviceState *dev)
     Property *prop;
     DeviceClass *dc = DEVICE_GET_CLASS(dev);
 
-    qdev_property_del_all(dev);
-
     if (dev->state == DEV_STATE_INITIALIZED) {
         while (dev->num_child_bus) {
             bus = QLIST_FIRST(&dev->child_bus);
@@ -313,12 +271,6 @@ void qdev_free(DeviceState *dev)
             prop->info->free(dev, prop);
         }
     }
-    if (dev->parent) {
-        qdev_property_del_child(dev->parent, dev, NULL);
-    }
-    if (dev->ref != 0) {
-        qerror_report(QERR_DEVICE_IN_USE, dev->id?:"");
-    }
     object_delete(OBJECT(dev));
 }
 
@@ -569,106 +521,19 @@ char* qdev_get_fw_dev_path(DeviceState *dev)
     return strdup(path);
 }
 
-char *qdev_get_type(DeviceState *dev, Error **errp)
-{
-    return g_strdup(object_get_typename(OBJECT(dev)));
-}
-
-void qdev_ref(DeviceState *dev)
+static char *qdev_get_type(Object *obj, Error **errp)
 {
-    dev->ref++;
-}
-
-void qdev_unref(DeviceState *dev)
-{
-    g_assert(dev->ref > 0);
-    dev->ref--;
-}
-
-void qdev_property_add(DeviceState *dev, const char *name, const char *type,
-                       DevicePropertyAccessor *get, DevicePropertyAccessor *set,
-                       DevicePropertyRelease *release,
-                       void *opaque, Error **errp)
-{
-    DeviceProperty *prop = g_malloc0(sizeof(*prop));
-
-    prop->name = g_strdup(name);
-    prop->type = g_strdup(type);
-
-    prop->get = get;
-    prop->set = set;
-    prop->release = release;
-    prop->opaque = opaque;
-
-    QTAILQ_INSERT_TAIL(&dev->properties, prop, node);
-}
-
-static DeviceProperty *qdev_property_find(DeviceState *dev, const char *name)
-{
-    DeviceProperty *prop;
-
-    QTAILQ_FOREACH(prop, &dev->properties, node) {
-        if (strcmp(prop->name, name) == 0) {
-            return prop;
-        }
-    }
-
-    return NULL;
-}
-
-void qdev_property_get(DeviceState *dev, Visitor *v, const char *name,
-                       Error **errp)
-{
-    DeviceProperty *prop = qdev_property_find(dev, name);
-
-    if (prop == NULL) {
-        error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
-        return;
-    }
-
-    if (!prop->get) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-    } else {
-        prop->get(dev, v, prop->opaque, name, errp);
-    }
-}
-
-void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
-                       Error **errp)
-{
-    DeviceProperty *prop = qdev_property_find(dev, name);
-
-    if (prop == NULL) {
-        error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
-        return;
-    }
-
-    if (!prop->set) {
-        error_set(errp, QERR_PERMISSION_DENIED);
-    } else {
-        prop->set(dev, v, prop->opaque, name, errp);
-    }
-}
-
-const char *qdev_property_get_type(DeviceState *dev, const char *name, Error **errp)
-{
-    DeviceProperty *prop = qdev_property_find(dev, name);
-
-    if (prop == NULL) {
-        error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
-        return NULL;
-    }
-
-    return prop->type;
+    return g_strdup(object_get_typename(obj));
 }
 
 /**
  * Legacy property handling
  */
 
-static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
+static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
                                      const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
 
     char buffer[1024];
@@ -678,9 +543,10 @@ static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
     visit_type_str(v, &ptr, name, errp);
 }
 
-static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
+static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque,
                                      const char *name, Error **errp)
 {
+    DeviceState *dev = DEVICE(obj);
     Property *prop = opaque;
     Error *local_err = NULL;
     char *ptr = NULL;
@@ -720,11 +586,11 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
     type = g_strdup_printf("legacy<%s>",
                            prop->info->legacy_name ?: prop->info->name);
 
-    qdev_property_add(dev, name, type,
-                      prop->info->print ? qdev_get_legacy_property : NULL,
-                      prop->info->parse ? qdev_set_legacy_property : NULL,
-                      NULL,
-                      prop, errp);
+    object_property_add(OBJECT(dev), name, type,
+                        prop->info->print ? qdev_get_legacy_property : NULL,
+                        prop->info->parse ? qdev_set_legacy_property : NULL,
+                        NULL,
+                        prop, errp);
 
     g_free(type);
     g_free(name);
@@ -739,333 +605,10 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
 void qdev_property_add_static(DeviceState *dev, Property *prop,
                               Error **errp)
 {
-    qdev_property_add(dev, prop->name, prop->info->name,
-                      prop->info->get, prop->info->set,
-                      NULL,
-                      prop, errp);
-}
-
-DeviceState *qdev_get_root(void)
-{
-    static DeviceState *qdev_root;
-
-    if (!qdev_root) {
-        qdev_root = qdev_create(NULL, "container");
-        qdev_init_nofail(qdev_root);
-    }
-
-    return qdev_root;
-}
-
-static void qdev_get_child_property(DeviceState *dev, Visitor *v, void *opaque,
-                                    const char *name, Error **errp)
-{
-    DeviceState *child = opaque;
-    gchar *path;
-
-    path = qdev_get_canonical_path(child);
-    visit_type_str(v, &path, name, errp);
-    g_free(path);
-}
-
-static void qdev_release_child_property(DeviceState *dev, const char *name,
-                                        void *opaque)
-{
-    DeviceState *child = opaque;
-
-    qdev_unref(child);
-}
-
-void qdev_property_add_child(DeviceState *dev, const char *name,
-                             DeviceState *child, Error **errp)
-{
-    gchar *type;
-
-    type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
-
-    qdev_property_add(dev, name, type, qdev_get_child_property,
-                      NULL, qdev_release_child_property,
-                      child, errp);
-
-    qdev_ref(child);
-    g_assert(child->parent == NULL);
-    child->parent = dev;
-
-    g_free(type);
-}
-
-static void qdev_get_link_property(DeviceState *dev, Visitor *v, void *opaque,
-                                   const char *name, Error **errp)
-{
-    DeviceState **child = opaque;
-    gchar *path;
-
-    if (*child) {
-        path = qdev_get_canonical_path(*child);
-        visit_type_str(v, &path, name, errp);
-        g_free(path);
-    } else {
-        path = (gchar *)"";
-        visit_type_str(v, &path, name, errp);
-    }
-}
-
-static void qdev_set_link_property(DeviceState *dev, Visitor *v, void *opaque,
-                                   const char *name, Error **errp)
-{
-    DeviceState **child = opaque;
-    bool ambiguous = false;
-    const char *type;
-    char *path;
-
-    type = qdev_property_get_type(dev, name, NULL);
-
-    visit_type_str(v, &path, name, errp);
-
-    if (*child) {
-        qdev_unref(*child);
-    }
-
-    if (strcmp(path, "") != 0) {
-        DeviceState *target;
-
-        target = qdev_resolve_path(path, &ambiguous);
-        if (target) {
-            gchar *target_type;
-
-            target_type = g_strdup_printf("link<%s>", object_get_typename(OBJECT(target)));
-            if (strcmp(target_type, type) == 0) {
-                *child = target;
-                qdev_ref(target);
-            } else {
-                error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
-            }
-
-            g_free(target_type);
-        } else {
-            error_set(errp, QERR_DEVICE_NOT_FOUND, path);
-        }
-    } else {
-        *child = NULL;
-    }
-
-    g_free(path);
-}
-
-void qdev_property_add_link(DeviceState *dev, const char *name,
-                            const char *type, DeviceState **child,
-                            Error **errp)
-{
-    gchar *full_type;
-
-    full_type = g_strdup_printf("link<%s>", type);
-
-    qdev_property_add(dev, name, full_type,
-                      qdev_get_link_property,
-                      qdev_set_link_property,
-                      NULL, child, errp);
-
-    g_free(full_type);
-}
-
-gchar *qdev_get_canonical_path(DeviceState *dev)
-{
-    DeviceState *root = qdev_get_root();
-    char *newpath = NULL, *path = NULL;
-
-    while (dev != root) {
-        DeviceProperty *prop = NULL;
-
-        g_assert(dev->parent != NULL);
-
-        QTAILQ_FOREACH(prop, &dev->parent->properties, node) {
-            if (!strstart(prop->type, "child<", NULL)) {
-                continue;
-            }
-
-            if (prop->opaque == dev) {
-                if (path) {
-                    newpath = g_strdup_printf("%s/%s", prop->name, path);
-                    g_free(path);
-                    path = newpath;
-                } else {
-                    path = g_strdup(prop->name);
-                }
-                break;
-            }
-        }
-
-        g_assert(prop != NULL);
-
-        dev = dev->parent;
-    }
-
-    newpath = g_strdup_printf("/%s", path);
-    g_free(path);
-
-    return newpath;
-}
-
-static DeviceState *qdev_resolve_abs_path(DeviceState *parent,
-                                          gchar **parts,
-                                          int index)
-{
-    DeviceProperty *prop;
-    DeviceState *child;
-
-    if (parts[index] == NULL) {
-        return parent;
-    }
-
-    if (strcmp(parts[index], "") == 0) {
-        return qdev_resolve_abs_path(parent, parts, index + 1);
-    }
-
-    prop = qdev_property_find(parent, parts[index]);
-    if (prop == NULL) {
-        return NULL;
-    }
-
-    child = NULL;
-    if (strstart(prop->type, "link<", NULL)) {
-        DeviceState **pchild = prop->opaque;
-        if (*pchild) {
-            child = *pchild;
-        }
-    } else if (strstart(prop->type, "child<", NULL)) {
-        child = prop->opaque;
-    }
-
-    if (!child) {
-        return NULL;
-    }
-
-    return qdev_resolve_abs_path(child, parts, index + 1);
-}
-
-static DeviceState *qdev_resolve_partial_path(DeviceState *parent,
-                                              gchar **parts,
-                                              bool *ambiguous)
-{
-    DeviceState *dev;
-    DeviceProperty *prop;
-
-    dev = qdev_resolve_abs_path(parent, parts, 0);
-
-    QTAILQ_FOREACH(prop, &parent->properties, node) {
-        DeviceState *found;
-
-        if (!strstart(prop->type, "child<", NULL)) {
-            continue;
-        }
-
-        found = qdev_resolve_partial_path(prop->opaque, parts, ambiguous);
-        if (found) {
-            if (dev) {
-                if (ambiguous) {
-                    *ambiguous = true;
-                }
-                return NULL;
-            }
-            dev = found;
-        }
-
-        if (ambiguous && *ambiguous) {
-            return NULL;
-        }
-    }
-
-    return dev;
-}
-
-DeviceState *qdev_resolve_path(const char *path, bool *ambiguous)
-{
-    bool partial_path = true;
-    DeviceState *dev;
-    gchar **parts;
-
-    parts = g_strsplit(path, "/", 0);
-    if (parts == NULL || parts[0] == NULL) {
-        g_strfreev(parts);
-        return qdev_get_root();
-    }
-
-    if (strcmp(parts[0], "") == 0) {
-        partial_path = false;
-    }
-
-    if (partial_path) {
-        if (ambiguous) {
-            *ambiguous = false;
-        }
-        dev = qdev_resolve_partial_path(qdev_get_root(), parts, ambiguous);
-    } else {
-        dev = qdev_resolve_abs_path(qdev_get_root(), parts, 1);
-    }
-
-    g_strfreev(parts);
-
-    return dev;
-}
-
-typedef struct StringProperty
-{
-    char *(*get)(DeviceState *, Error **);
-    void (*set)(DeviceState *, const char *, Error **);
-} StringProperty;
-
-static void qdev_property_get_str(DeviceState *dev, Visitor *v, void *opaque,
-                                  const char *name, Error **errp)
-{
-    StringProperty *prop = opaque;
-    char *value;
-
-    value = prop->get(dev, errp);
-    if (value) {
-        visit_type_str(v, &value, name, errp);
-        g_free(value);
-    }
-}
-
-static void qdev_property_set_str(DeviceState *dev, Visitor *v, void *opaque,
-                                  const char *name, Error **errp)
-{
-    StringProperty *prop = opaque;
-    char *value;
-    Error *local_err = NULL;
-
-    visit_type_str(v, &value, name, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    prop->set(dev, value, errp);
-    g_free(value);
-}
-
-static void qdev_property_release_str(DeviceState *dev, const char *name,
-                                      void *opaque)
-{
-    StringProperty *prop = opaque;
-    g_free(prop);
-}
-
-void qdev_property_add_str(DeviceState *dev, const char *name,
-                           char *(*get)(DeviceState *, Error **),
-                           void (*set)(DeviceState *, const char *, Error **),
-                           Error **errp)
-{
-    StringProperty *prop = g_malloc0(sizeof(*prop));
-
-    prop->get = get;
-    prop->set = set;
-
-    qdev_property_add(dev, name, "string",
-                      get ? qdev_property_get_str : NULL,
-                      set ? qdev_property_set_str : NULL,
-                      qdev_property_release_str,
-                      prop, errp);
+    object_property_add(OBJECT(dev), prop->name, prop->info->name,
+                        prop->info->get, prop->info->set,
+                        NULL,
+                        prop, errp);
 }
 
 static void device_initfn(Object *obj)
@@ -1079,7 +622,6 @@ static void device_initfn(Object *obj)
     }
 
     dev->instance_id_alias = -1;
-    QTAILQ_INIT(&dev->properties);
     dev->state = DEV_STATE_CREATED;
 
     qdev_prop_set_defaults(dev, qdev_get_props(dev));
@@ -1088,7 +630,7 @@ static void device_initfn(Object *obj)
         qdev_property_add_static(dev, prop, NULL);
     }
 
-    qdev_property_add_str(dev, "type", qdev_get_type, NULL, NULL);
+    object_property_add_str(OBJECT(dev), "type", qdev_get_type, NULL, NULL);
 }
 
 void device_reset(DeviceState *dev)
diff --git a/hw/qdev.h b/hw/qdev.h
index d1f0e19..1d9143f 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -27,44 +27,6 @@ enum {
     DEV_NVECTORS_UNSPECIFIED = -1,
 };
 
-/**
- * @DevicePropertyAccessor - called when trying to get/set a property
- *
- * @dev the device that owns the property
- * @v the visitor that contains the property data
- * @opaque the device property opaque
- * @name the name of the property
- * @errp a pointer to an Error that is filled if getting/setting fails.
- */
-typedef void (DevicePropertyAccessor)(DeviceState *dev,
-                                      Visitor *v,
-                                      void *opaque,
-                                      const char *name,
-                                      Error **errp);
-
-/**
- * @DevicePropertyRelease - called when a property is removed from a device
- *
- * @dev the device that owns the property
- * @name the name of the property
- * @opaque the opaque registered with the property
- */
-typedef void (DevicePropertyRelease)(DeviceState *dev,
-                                     const char *name,
-                                     void *opaque);
-
-typedef struct DeviceProperty
-{
-    gchar *name;
-    gchar *type;
-    DevicePropertyAccessor *get;
-    DevicePropertyAccessor *set;
-    DevicePropertyRelease *release;
-    void *opaque;
-
-    QTAILQ_ENTRY(DeviceProperty) node;
-} 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)
@@ -114,18 +76,6 @@ struct DeviceState {
     QTAILQ_ENTRY(DeviceState) sibling;
     int instance_id_alias;
     int alias_required_for_version;
-
-    /**
-     * This tracks the number of references between devices.  See @qdev_ref for
-     * more information.
-     */
-    uint32_t ref;
-
-    QTAILQ_HEAD(, DeviceProperty) properties;
-
-    /* Do not, under any circumstance, use this parent link below anywhere
-     * outside of qdev.c.  You have been warned. */
-    DeviceState *parent;
 };
 
 typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent);
@@ -194,8 +144,8 @@ struct PropertyInfo {
     int (*parse)(DeviceState *dev, Property *prop, const char *str);
     int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
     void (*free)(DeviceState *dev, Property *prop);
-    DevicePropertyAccessor *get;
-    DevicePropertyAccessor *set;
+    ObjectPropertyAccessor *get;
+    ObjectPropertyAccessor *set;
 };
 
 typedef struct GlobalProperty {
@@ -383,235 +333,12 @@ char *qdev_get_fw_dev_path(DeviceState *dev);
 extern struct BusInfo system_bus_info;
 
 /**
- * @qdev_ref
- *
- * Increase the reference count of a device.  A device cannot be freed as long
- * as its reference count is greater than zero.
- *
- * @dev - the device
- */
-void qdev_ref(DeviceState *dev);
-
-/**
- * @qdef_unref
- *
- * Decrease the reference count of a device.  A device cannot be freed as long
- * as its reference count is greater than zero.
- *
- * @dev - the device
- */
-void qdev_unref(DeviceState *dev);
-
-/**
- * @qdev_property_add - add a new property to a device
- *
- * @dev - the device to add a property to
- *
- * @name - the name of the property.  This can contain any character except for
- *         a forward slash.  In general, you should use hyphens '-' instead of
- *         underscores '_' when naming properties.
- *
- * @type - the type name of the property.  This namespace is pretty loosely
- *         defined.  Sub namespaces are constructed by using a prefix and then
- *         to angle brackets.  For instance, the type 'virtio-net-pci' in the
- *         'link' namespace would be 'link<virtio-net-pci>'.
- *
- * @get - the getter to be called to read a property.  If this is NULL, then
- *        the property cannot be read.
- *
- * @set - the setter to be called to write a property.  If this is NULL,
- *        then the property cannot be written.
- *
- * @release - called when the property is removed from the device.  This is
- *            meant to allow a property to free its opaque upon device
- *            destruction.  This may be NULL.
- *
- * @opaque - an opaque pointer to pass to the callbacks for the property
- *
- * @errp - returns an error if this function fails
- */
-void qdev_property_add(DeviceState *dev, const char *name, const char *type,
-                       DevicePropertyAccessor *get, DevicePropertyAccessor *set,
-                       DevicePropertyRelease *release,
-                       void *opaque, Error **errp);
-
-/**
- * @qdev_property_get - reads a property from a device
- *
- * @dev - the device
- *
- * @v - the visitor that will receive the property value.  This should be an
- *      Output visitor and the data will be written with @name as the name.
- *
- * @name - the name of the property
- *
- * @errp - returns an error if this function fails
- */
-void qdev_property_get(DeviceState *dev, Visitor *v, const char *name,
-                       Error **errp);
-
-/**
- * @qdev_property_set - writes a property to a device
- *
- * @dev - the device
- *
- * @v - the visitor that will be used to write the property value.  This should
- *      be an Input visitor and the data will be first read with @name as the
- *      name and then written as the property value.
- *
- * @name - the name of the property
- *
- * @errp - returns an error if this function fails
- */
-void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
-                       Error **errp);
-
-/**
- * @qdev_property_get_type - returns the type of a property
- *
- * @dev - the device
- *
- * @name - the name of the property
- *
- * @errp - returns an error if this function fails
- *
- * Returns:
- *   The type name of the property.
- */
-const char *qdev_property_get_type(DeviceState *dev, const char *name,
-                                   Error **errp);
-
-/**
  * @qdev_property_add_static - add a @Property to a device referencing a
  * field in a struct.
  */
 void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp);
 
 /**
- * @qdev_get_root - returns the root device of the composition tree
- *
- * Returns:
- *   The root of the composition tree.
- */
-DeviceState *qdev_get_root(void);
-
-/**
- * @qdev_get_canonical_path - returns the canonical path for a device.  This
- * is the path within the composition tree starting from the root.
- *
- * Returns:
- *   The canonical path in the composition tree.
- */
-gchar *qdev_get_canonical_path(DeviceState *dev);
-
-/**
- * @qdev_resolve_path - resolves a path returning a device
- *
- * There are two types of supported paths--absolute paths and partial paths.
- * 
- * Absolute paths are derived from the root device and can follow child<> or
- * link<> properties.  Since they can follow link<> properties, they can be
- * arbitrarily long.  Absolute paths look like absolute filenames and are
- * prefixed with a leading slash.
- * 
- * Partial paths look like relative filenames.  They do not begin with a
- * prefix.  The matching rules for partial paths are subtle but designed to make
- * specifying devices easy.  At each level of the composition tree, the partial
- * path is matched as an absolute path.  The first match is not returned.  At
- * least two matches are searched for.  A successful result is only returned if
- * only one match is founded.  If more than one match is found, a flag is
- * return to indicate that the match was ambiguous.
- *
- * @path - the path to resolve
- *
- * @ambiguous - returns true if the path resolution failed because of an
- *              ambiguous match
- *
- * Returns:
- *   The matched device or NULL on path lookup failure.
- */
-DeviceState *qdev_resolve_path(const char *path, bool *ambiguous);
-
-/**
- * @qdev_property_add_child - Add a child property to a device
- *
- * Child properties form the composition tree.  All devices need to be a child
- * of another device.  Devices can only be a child of one device.
- *
- * There is no way for a child to determine what its parent is.  It is not
- * a bidirectional relationship.  This is by design.
- *
- * @dev - the device to add a property to
- *
- * @name - the name of the property
- *
- * @child - the child device
- *
- * @errp - if an error occurs, a pointer to an area to store the area
- */
-void qdev_property_add_child(DeviceState *dev, const char *name,
-                             DeviceState *child, Error **errp);
-
-/**
- * @qdev_property_add_link - Add a link property to a device
- *
- * Links establish relationships between devices.  Links are unidirectional
- * although two links can be combined to form a bidirectional relationship
- * between devices.
- *
- * Links form the graph in the device model.
- *
- * @dev - the device to add a property to
- *
- * @name - the name of the property
- *
- * @type - the qdev type of the link
- *
- * @child - a pointer to where the link device reference is stored
- *
- * @errp - if an error occurs, a pointer to an area to store the area
- */
-void qdev_property_add_link(DeviceState *dev, const char *name,
-                            const char *type, DeviceState **child,
-                            Error **errp);
-
-/**
- * @qdev_property_add_str
- *
- * Add a string property using getters/setters.  This function will add a
- * property of type 'string'.
- *
- * @dev - the device to add a property to
- *
- * @name - the name of the property
- *
- * @get - the getter or NULL if the property is write-only.  This function must
- *        return a string to be freed by @g_free().
- *
- * @set - the setter or NULL if the property is read-only
- *
- * @errp - if an error occurs, a pointer to an area to store the error
- */
-void qdev_property_add_str(DeviceState *dev, const char *name,
-                           char *(*get)(DeviceState *, Error **),
-                           void (*set)(DeviceState *, const char *, Error **),
-                           Error **errp);
-
-/**
- * @qdev_get_type
- *
- * Returns the string representation of the type of this object.
- *
- * @dev - the device
- *
- * @errp - if an error occurs, a pointer to an area to store the error
- *
- * Returns: a string representing the type.  This must be freed by the caller
- *          with g_free().
- */
-char *qdev_get_type(DeviceState *dev, Error **errp);
-
-/**
  * @qdev_machine_init
  *
  * Initialize platform devices before machine init.  This is a hack until full
diff --git a/include/qemu/object.h b/include/qemu/object.h
index adbcfb1..b77584c 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -17,6 +17,10 @@
 #include <glib.h>
 #include <stdint.h>
 #include <stdbool.h>
+#include "qemu-queue.h"
+
+struct Visitor;
+struct Error;
 
 struct TypeImpl;
 typedef struct TypeImpl *Type;
@@ -114,6 +118,47 @@ typedef struct InterfaceInfo InterfaceInfo;
  * to one of its #Interface types and vice versa.
  */
 
+
+/**
+ * ObjectPropertyAccessor:
+ * @obj: the object that owns the property
+ * @v: the visitor that contains the property data
+ * @opaque: the object property opaque
+ * @name: the name of the property
+ * @errp: a pointer to an Error that is filled if getting/setting fails.
+ *
+ * Called when trying to get/set a property.
+ */
+typedef void (ObjectPropertyAccessor)(Object *obj,
+                                      struct Visitor *v,
+                                      void *opaque,
+                                      const char *name,
+                                      struct Error **errp);
+
+/**
+ * ObjectPropertyRelease:
+ * @obj: the object that owns the property
+ * @name: the name of the property
+ * @opaque: the opaque registered with the property
+ *
+ * Called when a property is removed from a object.
+ */
+typedef void (ObjectPropertyRelease)(Object *obj,
+                                     const char *name,
+                                     void *opaque);
+
+typedef struct ObjectProperty
+{
+    gchar *name;
+    gchar *type;
+    ObjectPropertyAccessor *get;
+    ObjectPropertyAccessor *set;
+    ObjectPropertyRelease *release;
+    void *opaque;
+
+    QTAILQ_ENTRY(ObjectProperty) node;
+} ObjectProperty;
+
 /**
  * ObjectClass:
  *
@@ -145,8 +190,10 @@ struct Object
 {
     /*< private >*/
     ObjectClass *class;
-
     GSList *interfaces;
+    QTAILQ_HEAD(, ObjectProperty) properties;
+    uint32_t ref;
+    Object *parent;
 };
 
 /**
@@ -433,5 +480,179 @@ ObjectClass *object_class_by_name(const char *typename);
 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
                           const char *implements_type, bool include_abstract,
                           void *opaque);
+/**
+ * object_ref:
+ * @obj: the object
+ *
+ * Increase the reference count of a object.  A object cannot be freed as long
+ * as its reference count is greater than zero.
+ */
+void object_ref(Object *obj);
+
+/**
+ * qdef_unref:
+ * @obj: the object
+ *
+ * Decrease the reference count of a object.  A object cannot be freed as long
+ * as its reference count is greater than zero.
+ */
+void object_unref(Object *obj);
+
+/**
+ * object_property_add:
+ * @obj: the object to add a property to
+ * @name: the name of the property.  This can contain any character except for
+ *  a forward slash.  In general, you should use hyphens '-' instead of
+ *  underscores '_' when naming properties.
+ * @type: the type name of the property.  This namespace is pretty loosely
+ *   defined.  Sub namespaces are constructed by using a prefix and then
+ *   to angle brackets.  For instance, the type 'virtio-net-pci' in the
+ *   'link' namespace would be 'link<virtio-net-pci>'.
+ * @get: The getter to be called to read a property.  If this is NULL, then
+ *   the property cannot be read.
+ * @set: the setter to be called to write a property.  If this is NULL,
+ *   then the property cannot be written.
+ * @release: called when the property is removed from the object.  This is
+ *   meant to allow a property to free its opaque upon object
+ *   destruction.  This may be NULL.
+ * @opaque: an opaque pointer to pass to the callbacks for the property
+ * @errp: returns an error if this function fails
+ */
+void object_property_add(Object *obj, const char *name, const char *type,
+                         ObjectPropertyAccessor *get,
+                         ObjectPropertyAccessor *set,
+                         ObjectPropertyRelease *release,
+                         void *opaque, struct Error **errp);
+
+void object_property_del(Object *obj, const char *name, Error **errp);
+
+/**
+ * object_property_get:
+ * @obj: the object
+ * @v: the visitor that will receive the property value.  This should be an
+ *   Output visitor and the data will be written with @name as the name.
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Reads a property from a object.
+ */
+void object_property_get(Object *obj, struct Visitor *v, const char *name,
+                         struct Error **errp);
+
+/**
+ * object_property_set:
+ * @obj: the object
+ * @v: the visitor that will be used to write the property value.  This should
+ *   be an Input visitor and the data will be first read with @name as the
+ *   name and then written as the property value.
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes a property to a object.
+ */
+void object_property_set(Object *obj, struct Visitor *v, const char *name,
+                         struct Error **errp);
+
+/**
+ * @object_property_get_type:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns:  The type name of the property.
+ */
+const char *object_property_get_type(Object *obj, const char *name,
+                                     struct Error **errp);
+
+/**
+ * object_get_root:
+ *
+ * Returns: the root object of the composition tree
+ */
+Object *object_get_root(void);
+
+/**
+ * object_get_canonical_path:
+ *
+ * Returns: The canonical path for a object.  This is the path within the
+ * composition tree starting from the root.
+ */
+gchar *object_get_canonical_path(Object *obj);
+
+/**
+ * object_resolve_path:
+ * @path: the path to resolve
+ * @ambiguous: returns true if the path resolution failed because of an
+ *   ambiguous match
+ *
+ * There are two types of supported paths--absolute paths and partial paths.
+ * 
+ * Absolute paths are derived from the root object and can follow child<> or
+ * link<> properties.  Since they can follow link<> properties, they can be
+ * arbitrarily long.  Absolute paths look like absolute filenames and are
+ * prefixed with a leading slash.
+ * 
+ * Partial paths look like relative filenames.  They do not begin with a
+ * prefix.  The matching rules for partial paths are subtle but designed to make
+ * specifying objects easy.  At each level of the composition tree, the partial
+ * path is matched as an absolute path.  The first match is not returned.  At
+ * least two matches are searched for.  A successful result is only returned if
+ * only one match is founded.  If more than one match is found, a flag is
+ * return to indicate that the match was ambiguous.
+ *
+ * Returns: The matched object or NULL on path lookup failure.
+ */
+Object *object_resolve_path(const char *path, bool *ambiguous);
+
+/**
+ * object_property_add_child:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @child: the child object
+ * @errp: if an error occurs, a pointer to an area to store the area
+ *
+ * Child properties form the composition tree.  All objects need to be a child
+ * of another object.  Objects can only be a child of one object.
+ *
+ * There is no way for a child to determine what its parent is.  It is not
+ * a bidirectional relationship.  This is by design.
+ */
+void object_property_add_child(Object *obj, const char *name,
+                               Object *child, struct Error **errp);
+
+/**
+ * object_property_add_link:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @type: the qobj type of the link
+ * @child: a pointer to where the link object reference is stored
+ * @errp: if an error occurs, a pointer to an area to store the area
+ *
+ * Links establish relationships between objects.  Links are unidirectional
+ * although two links can be combined to form a bidirectional relationship
+ * between objects.
+ *
+ * Links form the graph in the object model.
+ */
+void object_property_add_link(Object *obj, const char *name,
+                              const char *type, Object **child,
+                              struct Error **errp);
+
+/**
+ * object_property_add_str:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @get: the getter or NULL if the property is write-only.  This function must
+ *   return a string to be freed by g_free().
+ * @set: the setter or NULL if the property is read-only
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add a string property using getters/setters.  This function will add a
+ * property of type 'string'.
+ */
+void object_property_add_str(Object *obj, const char *name,
+                             char *(*get)(Object *, struct Error **),
+                             void (*set)(Object *, const char *, struct Error **),
+                             struct Error **errp);
 
 #endif
diff --git a/qapi-schema.json b/qapi-schema.json
index 56a4123..d02ee86 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1228,20 +1228,20 @@
 #
 # Notes: This type is experimental.  Its syntax may change in future releases.
 ##
-{ 'type': 'DevicePropertyInfo',
+{ 'type': 'ObjectPropertyInfo',
   'data': { 'name': 'str', 'type': 'str' } }
 
 ##
 # @qom-list:
 #
-# This command will list any properties of a device given a path in the device
+# This command will list any properties of a object given a path in the object
 # model.
 #
-# @path: the path within the device model.  See @qom-get for a description of
+# @path: the path within the object model.  See @qom-get for a description of
 #        this parameter.
 #
-# Returns: a list of @DevicePropertyInfo that describe the properties of the
-#          device.
+# Returns: a list of @ObjectPropertyInfo that describe the properties of the
+#          object.
 #
 # Since: 1.1
 #
@@ -1250,25 +1250,25 @@
 ##
 { 'command': 'qom-list',
   'data': { 'path': 'str' },
-  'returns': [ 'DevicePropertyInfo' ] }
+  'returns': [ 'ObjectPropertyInfo' ] }
 
 ##
 # @qom-get:
 #
-# This command will get a property from a device model path and return the
+# This command will get a property from a object model path and return the
 # value.
 #
-# @path: The path within the device model.  There are two forms of supported
+# @path: The path within the object model.  There are two forms of supported
 #        paths--absolute and partial paths.
 #
-#        Absolute paths are derived from the root device and can follow child<>
+#        Absolute paths are derived from the root object and can follow child<>
 #        or link<> properties.  Since they can follow link<> properties, they
 #        can be arbitrarily long.  Absolute paths look like absolute filenames
 #        and are prefixed  with a leading slash.
 #
 #        Partial paths look like relative filenames.  They do not begin
 #        with a prefix.  The matching rules for partial paths are subtle but
-#        designed to make specifying devices easy.  At each level of the
+#        designed to make specifying objects easy.  At each level of the
 #        composition tree, the partial path is matched as an absolute path.
 #        The first match is not returned.  At least two matches are searched
 #        for.  A successful result is only returned if only one match is
@@ -1294,7 +1294,7 @@
 ##
 # @qom-set:
 #
-# This command will set a property from a device model path.
+# This command will set a property from a object model path.
 #
 # @path: see @qom-get for a description of this parameter
 #
diff --git a/qmp.c b/qmp.c
index 75049ed..45052cc 100644
--- a/qmp.c
+++ b/qmp.c
@@ -164,23 +164,23 @@ void qmp_cont(Error **errp)
     vm_start();
 }
 
-DevicePropertyInfoList *qmp_qom_list(const char *path, Error **errp)
+ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
 {
-    DeviceState *dev;
+    Object *obj;
     bool ambiguous = false;
-    DevicePropertyInfoList *props = NULL;
-    DeviceProperty *prop;
+    ObjectPropertyInfoList *props = NULL;
+    ObjectProperty *prop;
 
-    dev = qdev_resolve_path(path, &ambiguous);
-    if (dev == NULL) {
+    obj = object_resolve_path(path, &ambiguous);
+    if (obj == NULL) {
         error_set(errp, QERR_DEVICE_NOT_FOUND, path);
         return NULL;
     }
 
-    QTAILQ_FOREACH(prop, &dev->properties, node) {
-        DevicePropertyInfoList *entry = g_malloc0(sizeof(*entry));
+    QTAILQ_FOREACH(prop, &obj->properties, node) {
+        ObjectPropertyInfoList *entry = g_malloc0(sizeof(*entry));
 
-        entry->value = g_malloc0(sizeof(DevicePropertyInfo));
+        entry->value = g_malloc0(sizeof(ObjectPropertyInfo));
         entry->next = props;
         props = entry;
 
@@ -199,16 +199,16 @@ int qmp_qom_set(Monitor *mon, const QDict *qdict, QObject **ret)
     QObject *value = qdict_get(qdict, "value");
     Error *local_err = NULL;
     QmpInputVisitor *mi;
-    DeviceState *dev;
+    Object *obj;
 
-    dev = qdev_resolve_path(path, NULL);
-    if (!dev) {
+    obj = object_resolve_path(path, NULL);
+    if (!obj) {
         error_set(&local_err, QERR_DEVICE_NOT_FOUND, path);
         goto out;
     }
 
     mi = qmp_input_visitor_new(value);
-    qdev_property_set(dev, qmp_input_get_visitor(mi), property, &local_err);
+    object_property_set(obj, qmp_input_get_visitor(mi), property, &local_err);
 
     qmp_input_visitor_cleanup(mi);
 
@@ -228,16 +228,16 @@ int qmp_qom_get(Monitor *mon, const QDict *qdict, QObject **ret)
     const char *property = qdict_get_str(qdict, "property");
     Error *local_err = NULL;
     QmpOutputVisitor *mo;
-    DeviceState *dev;
+    Object *obj;
 
-    dev = qdev_resolve_path(path, NULL);
-    if (!dev) {
+    obj = object_resolve_path(path, NULL);
+    if (!obj) {
         error_set(&local_err, QERR_DEVICE_NOT_FOUND, path);
         goto out;
     }
 
     mo = qmp_output_visitor_new();
-    qdev_property_get(dev, qmp_output_get_visitor(mo), property, &local_err);
+    object_property_get(obj, qmp_output_get_visitor(mo), property, &local_err);
     if (!local_err) {
         *ret = qmp_output_get_qobject(mo);
     }
diff --git a/qom/object.c b/qom/object.c
index 3dabb1a..3133a62 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -12,6 +12,9 @@
 
 #include "qemu/object.h"
 #include "qemu-common.h"
+#include "qapi/qapi-visit-core.h"
+#include "hw/qdev.h"
+// FIXME remove above
 
 #define MAX_INTERFACES 32
 
@@ -258,6 +261,7 @@ void object_initialize_with_type(void *data, TypeImpl *type)
 
     memset(obj, 0, type->instance_size);
     obj->class = type->class;
+    QTAILQ_INIT(&obj->properties);
     object_init_with_type(obj, type);
 }
 
@@ -268,6 +272,38 @@ void object_initialize(void *data, const char *typename)
     object_initialize_with_type(data, type);
 }
 
+static void object_property_del_all(Object *obj)
+{
+    while (!QTAILQ_EMPTY(&obj->properties)) {
+        ObjectProperty *prop = QTAILQ_FIRST(&obj->properties);
+
+        QTAILQ_REMOVE(&obj->properties, prop, node);
+
+        if (prop->release) {
+            prop->release(obj, prop->name, prop->opaque);
+        }
+
+        g_free(prop->name);
+        g_free(prop->type);
+        g_free(prop);
+    }
+}
+
+static void object_property_del_child(Object *obj, Object *child, Error **errp)
+{
+    while (!QTAILQ_EMPTY(&obj->properties)) {
+        ObjectProperty *prop = QTAILQ_FIRST(&obj->properties);
+
+        if (!strstart(prop->type, "child<", NULL)) {
+            continue;
+        }
+
+        if (prop->opaque == child) {
+            object_property_del(obj, prop->name, errp);
+        }
+    }
+}
+
 static void object_deinit(Object *obj, TypeImpl *type)
 {
     if (type->instance_finalize) {
@@ -283,6 +319,9 @@ static void object_deinit(Object *obj, TypeImpl *type)
     if (type_has_parent(type)) {
         object_deinit(obj, type_get_parent(type));
     }
+    if (obj->parent) {
+        object_property_del_child(obj->parent, obj, NULL);
+    }
 }
 
 void object_finalize(void *data)
@@ -291,6 +330,7 @@ void object_finalize(void *data)
     TypeImpl *ti = obj->class->type;
 
     object_deinit(obj, ti);
+    object_property_del_all(obj);
 }
 
 Object *object_new_with_type(Type type)
@@ -502,3 +542,420 @@ void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
 
     g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
 }
+
+void object_ref(Object *obj)
+{
+    obj->ref++;
+}
+
+void object_unref(Object *obj)
+{
+    g_assert(obj->ref > 0);
+    obj->ref--;
+}
+
+void object_property_add(Object *obj, const char *name, const char *type,
+                         ObjectPropertyAccessor *get,
+                         ObjectPropertyAccessor *set,
+                         ObjectPropertyRelease *release,
+                         void *opaque, Error **errp)
+{
+    ObjectProperty *prop = g_malloc0(sizeof(*prop));
+
+    prop->name = g_strdup(name);
+    prop->type = g_strdup(type);
+
+    prop->get = get;
+    prop->set = set;
+    prop->release = release;
+    prop->opaque = opaque;
+
+    QTAILQ_INSERT_TAIL(&obj->properties, prop, node);
+}
+
+static ObjectProperty *object_property_find(Object *obj, const char *name)
+{
+    ObjectProperty *prop;
+
+    QTAILQ_FOREACH(prop, &obj->properties, node) {
+        if (strcmp(prop->name, name) == 0) {
+            return prop;
+        }
+    }
+
+    return NULL;
+}
+
+void object_property_del(Object *obj, const char *name, Error **errp)
+{
+    ObjectProperty *prop = object_property_find(obj, name);
+
+    QTAILQ_REMOVE(&obj->properties, prop, node);
+
+    prop->release(obj, prop->name, prop->opaque);
+
+    g_free(prop->name);
+    g_free(prop->type);
+    g_free(prop);
+}
+
+void object_property_get(Object *obj, Visitor *v, const char *name,
+                         Error **errp)
+{
+    ObjectProperty *prop = object_property_find(obj, name);
+
+    if (prop == NULL) {
+        error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
+        return;
+    }
+
+    if (!prop->get) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+    } else {
+        prop->get(obj, v, prop->opaque, name, errp);
+    }
+}
+
+void object_property_set(Object *obj, Visitor *v, const char *name,
+                         Error **errp)
+{
+    ObjectProperty *prop = object_property_find(obj, name);
+
+    if (prop == NULL) {
+        error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
+        return;
+    }
+
+    if (!prop->set) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+    } else {
+        prop->set(obj, v, prop->opaque, name, errp);
+    }
+}
+
+const char *object_property_get_type(Object *obj, const char *name, Error **errp)
+{
+    ObjectProperty *prop = object_property_find(obj, name);
+
+    if (prop == NULL) {
+        error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
+        return NULL;
+    }
+
+    return prop->type;
+}
+
+Object *object_get_root(void)
+{
+    static DeviceState *object_root;
+
+    if (!object_root) {
+        object_root = qdev_create(NULL, "container");
+        qdev_init_nofail(object_root);
+    }
+
+    return OBJECT(object_root);
+}
+
+static void object_get_child_property(Object *obj, Visitor *v, void *opaque,
+                                      const char *name, Error **errp)
+{
+    Object *child = opaque;
+    gchar *path;
+
+    path = object_get_canonical_path(child);
+    visit_type_str(v, &path, name, errp);
+    g_free(path);
+}
+
+void object_property_add_child(Object *obj, const char *name,
+                               Object *child, Error **errp)
+{
+    gchar *type;
+
+    type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
+
+    object_property_add(obj, name, type, object_get_child_property,
+                        NULL, NULL, child, errp);
+
+    object_ref(child);
+    g_assert(child->parent == NULL);
+    child->parent = obj;
+
+    g_free(type);
+}
+
+static void object_get_link_property(Object *obj, Visitor *v, void *opaque,
+                                     const char *name, Error **errp)
+{
+    Object **child = opaque;
+    gchar *path;
+
+    if (*child) {
+        path = object_get_canonical_path(*child);
+        visit_type_str(v, &path, name, errp);
+        g_free(path);
+    } else {
+        path = (gchar *)"";
+        visit_type_str(v, &path, name, errp);
+    }
+}
+
+static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
+                                     const char *name, Error **errp)
+{
+    Object **child = opaque;
+    bool ambiguous = false;
+    const char *type;
+    char *path;
+
+    type = object_property_get_type(obj, name, NULL);
+
+    visit_type_str(v, &path, name, errp);
+
+    if (*child) {
+        object_unref(*child);
+    }
+
+    if (strcmp(path, "") != 0) {
+        Object *target;
+
+        target = object_resolve_path(path, &ambiguous);
+        if (target) {
+            gchar *target_type;
+
+            target_type = g_strdup_printf("link<%s>",
+                                          object_get_typename(OBJECT(target)));
+            if (strcmp(target_type, type) == 0) {
+                *child = target;
+                object_ref(target);
+            } else {
+                error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
+            }
+
+            g_free(target_type);
+        } else {
+            error_set(errp, QERR_DEVICE_NOT_FOUND, path);
+        }
+    } else {
+        *child = NULL;
+    }
+
+    g_free(path);
+}
+
+void object_property_add_link(Object *obj, const char *name,
+                              const char *type, Object **child,
+                              Error **errp)
+{
+    gchar *full_type;
+
+    full_type = g_strdup_printf("link<%s>", type);
+
+    object_property_add(obj, name, full_type,
+                        object_get_link_property,
+                        object_set_link_property,
+                        NULL, child, errp);
+
+    g_free(full_type);
+}
+
+gchar *object_get_canonical_path(Object *obj)
+{
+    Object *root = object_get_root();
+    char *newpath = NULL, *path = NULL;
+
+    while (obj != root) {
+        ObjectProperty *prop = NULL;
+
+        g_assert(obj->parent != NULL);
+
+        QTAILQ_FOREACH(prop, &obj->parent->properties, node) {
+            if (!strstart(prop->type, "child<", NULL)) {
+                continue;
+            }
+
+            if (prop->opaque == obj) {
+                if (path) {
+                    newpath = g_strdup_printf("%s/%s", prop->name, path);
+                    g_free(path);
+                    path = newpath;
+                } else {
+                    path = g_strdup(prop->name);
+                }
+                break;
+            }
+        }
+
+        g_assert(prop != NULL);
+
+        obj = obj->parent;
+    }
+
+    newpath = g_strdup_printf("/%s", path);
+    g_free(path);
+
+    return newpath;
+}
+
+static Object *object_resolve_abs_path(Object *parent,
+                                          gchar **parts,
+                                          int index)
+{
+    ObjectProperty *prop;
+    Object *child;
+
+    if (parts[index] == NULL) {
+        return parent;
+    }
+
+    if (strcmp(parts[index], "") == 0) {
+        return object_resolve_abs_path(parent, parts, index + 1);
+    }
+
+    prop = object_property_find(parent, parts[index]);
+    if (prop == NULL) {
+        return NULL;
+    }
+
+    child = NULL;
+    if (strstart(prop->type, "link<", NULL)) {
+        Object **pchild = prop->opaque;
+        if (*pchild) {
+            child = *pchild;
+        }
+    } else if (strstart(prop->type, "child<", NULL)) {
+        child = prop->opaque;
+    }
+
+    if (!child) {
+        return NULL;
+    }
+
+    return object_resolve_abs_path(child, parts, index + 1);
+}
+
+static Object *object_resolve_partial_path(Object *parent,
+                                              gchar **parts,
+                                              bool *ambiguous)
+{
+    Object *obj;
+    ObjectProperty *prop;
+
+    obj = object_resolve_abs_path(parent, parts, 0);
+
+    QTAILQ_FOREACH(prop, &parent->properties, node) {
+        Object *found;
+
+        if (!strstart(prop->type, "child<", NULL)) {
+            continue;
+        }
+
+        found = object_resolve_partial_path(prop->opaque, parts, ambiguous);
+        if (found) {
+            if (obj) {
+                if (ambiguous) {
+                    *ambiguous = true;
+                }
+                return NULL;
+            }
+            obj = found;
+        }
+
+        if (ambiguous && *ambiguous) {
+            return NULL;
+        }
+    }
+
+    return obj;
+}
+
+Object *object_resolve_path(const char *path, bool *ambiguous)
+{
+    bool partial_path = true;
+    Object *obj;
+    gchar **parts;
+
+    parts = g_strsplit(path, "/", 0);
+    if (parts == NULL || parts[0] == NULL) {
+        g_strfreev(parts);
+        return object_get_root();
+    }
+
+    if (strcmp(parts[0], "") == 0) {
+        partial_path = false;
+    }
+
+    if (partial_path) {
+        if (ambiguous) {
+            *ambiguous = false;
+        }
+        obj = object_resolve_partial_path(object_get_root(), parts, ambiguous);
+    } else {
+        obj = object_resolve_abs_path(object_get_root(), parts, 1);
+    }
+
+    g_strfreev(parts);
+
+    return obj;
+}
+
+typedef struct StringProperty
+{
+    char *(*get)(Object *, Error **);
+    void (*set)(Object *, const char *, Error **);
+} StringProperty;
+
+static void object_property_get_str(Object *obj, Visitor *v, void *opaque,
+                                    const char *name, Error **errp)
+{
+    StringProperty *prop = opaque;
+    char *value;
+
+    value = prop->get(obj, errp);
+    if (value) {
+        visit_type_str(v, &value, name, errp);
+        g_free(value);
+    }
+}
+
+static void object_property_set_str(Object *obj, Visitor *v, void *opaque,
+                                  const char *name, Error **errp)
+{
+    StringProperty *prop = opaque;
+    char *value;
+    Error *local_err = NULL;
+
+    visit_type_str(v, &value, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    prop->set(obj, value, errp);
+    g_free(value);
+}
+
+static void object_property_release_str(Object *obj, const char *name,
+                                      void *opaque)
+{
+    StringProperty *prop = opaque;
+    g_free(prop);
+}
+
+void object_property_add_str(Object *obj, const char *name,
+                           char *(*get)(Object *, Error **),
+                           void (*set)(Object *, const char *, Error **),
+                           Error **errp)
+{
+    StringProperty *prop = g_malloc0(sizeof(*prop));
+
+    prop->get = get;
+    prop->set = set;
+
+    object_property_add(obj, name, "string",
+                        get ? object_property_get_str : NULL,
+                        set ? object_property_set_str : NULL,
+                        object_property_release_str,
+                        prop, errp);
+}
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 18/23] qom: accept any compatible type when setting a link property
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (14 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 17/23] qom: move properties from qdev to object Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 19/23] qdev: implement cleanup logic in finalize Anthony Liguori
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

Links had limited utility before as they only allowed a concrete type to be
specified.  Now we can support abstract types and interfaces which means it's
now possible to have a link<PCIDevice>.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 qom/object.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/qom/object.c b/qom/object.c
index 3133a62..4c3ff83 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -724,11 +724,12 @@ static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
         if (target) {
             gchar *target_type;
 
-            target_type = g_strdup_printf("link<%s>",
-                                          object_get_typename(OBJECT(target)));
-            if (strcmp(target_type, type) == 0) {
-                *child = target;
+            target_type = g_strdup(&type[5]);
+            target_type[strlen(target_type) - 2] = 0;
+
+            if (object_dynamic_cast(target, target_type)) {
                 object_ref(target);
+                *child = target;
             } else {
                 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
             }
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 19/23] qdev: implement cleanup logic in finalize
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (15 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 18/23] qom: accept any compatible type when setting a link property Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 20/23] info qdm: do not require a parent_bus to be set Anthony Liguori
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

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

diff --git a/hw/qdev.c b/hw/qdev.c
index 91dbbc7..f04f0fa 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -246,31 +246,6 @@ void qdev_init_nofail(DeviceState *dev)
 /* Unlink device from bus and free the structure.  */
 void qdev_free(DeviceState *dev)
 {
-    BusState *bus;
-    Property *prop;
-    DeviceClass *dc = DEVICE_GET_CLASS(dev);
-
-    if (dev->state == DEV_STATE_INITIALIZED) {
-        while (dev->num_child_bus) {
-            bus = QLIST_FIRST(&dev->child_bus);
-            qbus_free(bus);
-        }
-        if (qdev_get_vmsd(dev)) {
-            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
-        }
-        if (dc->exit) {
-            dc->exit(dev);
-        }
-        if (dev->opts) {
-            qemu_opts_del(dev->opts);
-        }
-    }
-    QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
-    for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
-        if (prop->info->free) {
-            prop->info->free(dev, prop);
-        }
-    }
     object_delete(OBJECT(dev));
 }
 
@@ -633,6 +608,37 @@ static void device_initfn(Object *obj)
     object_property_add_str(OBJECT(dev), "type", qdev_get_type, NULL, NULL);
 }
 
+/* Unlink device from bus and free the structure.  */
+static void device_finalize(Object *obj)
+{
+    DeviceState *dev = DEVICE(obj);
+    BusState *bus;
+    Property *prop;
+    DeviceClass *dc = DEVICE_GET_CLASS(dev);
+
+    if (dev->state == DEV_STATE_INITIALIZED) {
+        while (dev->num_child_bus) {
+            bus = QLIST_FIRST(&dev->child_bus);
+            qbus_free(bus);
+        }
+        if (qdev_get_vmsd(dev)) {
+            vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
+        }
+        if (dc->exit) {
+            dc->exit(dev);
+        }
+        if (dev->opts) {
+            qemu_opts_del(dev->opts);
+        }
+    }
+    QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
+    for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
+        if (prop->info->free) {
+            prop->info->free(dev, prop);
+        }
+    }
+}
+
 void device_reset(DeviceState *dev)
 {
     DeviceClass *klass = DEVICE_GET_CLASS(dev);
@@ -647,6 +653,7 @@ static TypeInfo device_type_info = {
     .parent = TYPE_OBJECT,
     .instance_size = sizeof(DeviceState),
     .instance_init = device_initfn,
+    .instance_finalize = device_finalize,
     .abstract = true,
     .class_size = sizeof(DeviceClass),
 };
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 20/23] info qdm: do not require a parent_bus to be set
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (16 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 19/23] qdev: implement cleanup logic in finalize Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 21/23] object: sure up reference counting Anthony Liguori
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

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

diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 46946fe..66a6d55 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -165,12 +165,14 @@ int qdev_device_help(QemuOpts *opts)
         error_printf("%s.%s=%s\n", driver, prop->name,
                      prop->info->legacy_name ?: prop->info->name);
     }
-    for (prop = info->bus_info->props; prop && prop->name; prop++) {
-        if (!prop->info->parse) {
-            continue;           /* no way to set it, don't show */
+    if (info->bus_info) {
+        for (prop = info->bus_info->props; prop && prop->name; prop++) {
+            if (!prop->info->parse) {
+                continue;           /* no way to set it, don't show */
+            }
+            error_printf("%s.%s=%s\n", driver, prop->name,
+                         prop->info->legacy_name ?: prop->info->name);
         }
-        error_printf("%s.%s=%s\n", driver, prop->name,
-                     prop->info->legacy_name ?: prop->info->name);
     }
     return 1;
 }
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 21/23] object: sure up reference counting
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (17 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 20/23] info qdm: do not require a parent_bus to be set Anthony Liguori
@ 2012-01-30 21:08 ` Anthony Liguori
  2012-01-31  7:49   ` Paolo Bonzini
  2012-02-01 19:47   ` Peter Maydell
  2012-01-30 21:09 ` [Qemu-devel] [PATCH 22/23] container: make a decendent of Object Anthony Liguori
                   ` (2 subsequent siblings)
  21 siblings, 2 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

Now we have the following behavior:

1) object_new() returns an object with ref = 1
2) object_initialize() does not increase the reference count (ref may be 0).
3) object_deref() will finalize the object when ref = 0.  it does not free the
   memory associated with the object.
4) both link and child properties correctly set the reference count.

The expected usage is the following:

1) child devices should generally be created via object_initialize() using
   memory from the parent device.  Adding the object as a child property will
   take ownership of the object and tie the child's life cycle to the parent.

2) If a child device is created via qdev_create() or some other form of
   object_new(), there must be an object_delete() call in the parent device's
   finalize function.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 qom/object.c |   20 ++++++++++++++++++--
 1 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/qom/object.c b/qom/object.c
index 4c3ff83..1941adb 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -331,6 +331,8 @@ void object_finalize(void *data)
 
     object_deinit(obj, ti);
     object_property_del_all(obj);
+
+    g_assert(obj->ref == 0);
 }
 
 Object *object_new_with_type(Type type)
@@ -341,6 +343,7 @@ Object *object_new_with_type(Type type)
 
     obj = g_malloc(type->instance_size);
     object_initialize_with_type(obj, type);
+    object_ref(obj);
 
     return obj;
 }
@@ -354,7 +357,8 @@ Object *object_new(const char *typename)
 
 void object_delete(Object *obj)
 {
-    object_finalize(obj);
+    object_unref(obj);
+    g_assert(obj->ref == 0);
     g_free(obj);
 }
 
@@ -552,6 +556,10 @@ void object_unref(Object *obj)
 {
     g_assert(obj->ref > 0);
     obj->ref--;
+
+    if (obj->ref == 0) {
+        object_finalize(obj);
+    }
 }
 
 void object_property_add(Object *obj, const char *name, const char *type,
@@ -668,6 +676,14 @@ static void object_get_child_property(Object *obj, Visitor *v, void *opaque,
     g_free(path);
 }
 
+static void object_finalize_child_property(Object *obj, const char *name,
+                                           void *opaque)
+{
+    Object *child = opaque;
+
+    object_unref(child);
+}
+
 void object_property_add_child(Object *obj, const char *name,
                                Object *child, Error **errp)
 {
@@ -676,7 +692,7 @@ void object_property_add_child(Object *obj, const char *name,
     type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
 
     object_property_add(obj, name, type, object_get_child_property,
-                        NULL, NULL, child, errp);
+                        NULL, object_finalize_child_property, child, errp);
 
     object_ref(child);
     g_assert(child->parent == NULL);
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 22/23] container: make a decendent of Object
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (18 preceding siblings ...)
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 21/23] object: sure up reference counting Anthony Liguori
@ 2012-01-30 21:09 ` Anthony Liguori
  2012-01-31  7:50   ` Paolo Bonzini
  2012-02-01 19:48   ` Peter Maydell
  2012-01-30 21:09 ` [Qemu-devel] [PATCH 23/23] not-for-upstream: fix device_del Anthony Liguori
  2012-01-30 21:16 ` [Qemu-devel] [PATCH 00/23] qom: use Type system to register all devices Anthony Liguori
  21 siblings, 2 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 Makefile.objs     |    2 +-
 hw/container.c    |   29 -----------------------------
 hw/qdev-monitor.c |   14 ++++++--------
 qom/Makefile      |    2 +-
 qom/container.c   |   15 +++++++++++++++
 qom/object.c      |    9 ++++-----
 6 files changed, 27 insertions(+), 44 deletions(-)
 delete mode 100644 hw/container.c
 create mode 100644 qom/container.c

diff --git a/Makefile.objs b/Makefile.objs
index 1a26349..ec35320 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -286,7 +286,7 @@ hw-obj-$(CONFIG_LSI_SCSI_PCI) += lsi53c895a.o
 hw-obj-$(CONFIG_ESP) += esp.o
 
 hw-obj-y += dma-helpers.o sysbus.o isa-bus.o
-hw-obj-y += qdev-addr.o container.o
+hw-obj-y += qdev-addr.o
 
 # VGA
 hw-obj-$(CONFIG_VGA_PCI) += vga-pci.o
diff --git a/hw/container.c b/hw/container.c
deleted file mode 100644
index 1e97031..0000000
--- a/hw/container.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "sysbus.h"
-
-static int container_initfn(SysBusDevice *dev)
-{
-    return 0;
-}
-
-static void container_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
-    k->init = container_initfn;
-    dc->no_user = 1;
-}
-
-static TypeInfo container_info = {
-    .name          = "container",
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(SysBusDevice),
-    .class_init    = container_class_init,
-};
-
-static void container_init(void)
-{
-    type_register_static(&container_info);
-}
-
-device_init(container_init);
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 66a6d55..b8d8a9e 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -179,30 +179,28 @@ int qdev_device_help(QemuOpts *opts)
 
 static Object *qdev_get_peripheral(void)
 {
-    static DeviceState *dev;
+    static Object *dev;
 
     if (dev == NULL) {
-        dev = qdev_create(NULL, "container");
+        dev = object_new("container");
         object_property_add_child(object_get_root(), "peripheral",
                                   OBJECT(dev), NULL);
-        qdev_init_nofail(dev);
     }
 
-    return OBJECT(dev);
+    return dev;
 }
 
 static Object *qdev_get_peripheral_anon(void)
 {
-    static DeviceState *dev;
+    static Object *dev;
 
     if (dev == NULL) {
-        dev = qdev_create(NULL, "container");
+        dev = object_new("container");
         object_property_add_child(object_get_root(), "peripheral-anon",
                                   OBJECT(dev), NULL);
-        qdev_init_nofail(dev);
     }
 
-    return OBJECT(dev);
+    return dev;
 }
 
 static void qbus_list_bus(DeviceState *dev)
diff --git a/qom/Makefile b/qom/Makefile
index a3c7892..f33f0be 100644
--- a/qom/Makefile
+++ b/qom/Makefile
@@ -1 +1 @@
-qom-y = object.o
+qom-y = object.o container.o
diff --git a/qom/container.c b/qom/container.c
new file mode 100644
index 0000000..39d7b1e
--- /dev/null
+++ b/qom/container.c
@@ -0,0 +1,15 @@
+#include "qemu/object.h"
+#include "module.h"
+
+static TypeInfo container_info = {
+    .name          = "container",
+    .instance_size = sizeof(Object),
+    .parent        = TYPE_OBJECT,
+};
+
+static void container_init(void)
+{
+    type_register_static(&container_info);
+}
+
+device_init(container_init);
diff --git a/qom/object.c b/qom/object.c
index 1941adb..3c3c8f9 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -655,14 +655,13 @@ const char *object_property_get_type(Object *obj, const char *name, Error **errp
 
 Object *object_get_root(void)
 {
-    static DeviceState *object_root;
+    static Object *root;
 
-    if (!object_root) {
-        object_root = qdev_create(NULL, "container");
-        qdev_init_nofail(object_root);
+    if (!root) {
+        root = object_new("container");
     }
 
-    return OBJECT(object_root);
+    return root;
 }
 
 static void object_get_child_property(Object *obj, Visitor *v, void *opaque,
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 23/23] not-for-upstream: fix device_del
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (19 preceding siblings ...)
  2012-01-30 21:09 ` [Qemu-devel] [PATCH 22/23] container: make a decendent of Object Anthony Liguori
@ 2012-01-30 21:09 ` Anthony Liguori
  2012-01-30 21:16 ` [Qemu-devel] [PATCH 00/23] qom: use Type system to register all devices Anthony Liguori
  21 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:09 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Anthony Liguori, Peter Maydell

This needs to be carefully merged back but I'm not 100% confident the problem is
solved by this commit.
---
 hw/pci.c              |    1 +
 hw/qdev.c             |    1 +
 include/qemu/object.h |    4 +++-
 qom/object.c          |   13 ++++++++++---
 4 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 1df05ae..5f4f80e 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1517,6 +1517,7 @@ static int pci_unplug_device(DeviceState *qdev)
         qerror_report(QERR_DEVICE_NO_HOTPLUG, object_get_typename(OBJECT(dev)));
         return -1;
     }
+    object_unparent(OBJECT(dev));
     return dev->bus->hotplug(dev->bus->hotplug_qdev, dev,
                              PCI_HOTPLUG_DISABLED);
 }
diff --git a/hw/qdev.c b/hw/qdev.c
index f04f0fa..e3b53b7 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -222,6 +222,7 @@ void qbus_reset_all_fn(void *opaque)
 int qdev_simple_unplug_cb(DeviceState *dev)
 {
     /* just zap it */
+    object_unparent(OBJECT(dev));
     qdev_free(dev);
     return 0;
 }
diff --git a/include/qemu/object.h b/include/qemu/object.h
index b77584c..947cf29 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -524,7 +524,9 @@ void object_property_add(Object *obj, const char *name, const char *type,
                          ObjectPropertyRelease *release,
                          void *opaque, struct Error **errp);
 
-void object_property_del(Object *obj, const char *name, Error **errp);
+void object_property_del(Object *obj, const char *name, struct Error **errp);
+
+void object_unparent(Object *obj);
 
 /**
  * object_property_get:
diff --git a/qom/object.c b/qom/object.c
index 3c3c8f9..cd517f6 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -304,6 +304,13 @@ static void object_property_del_child(Object *obj, Object *child, Error **errp)
     }
 }
 
+void object_unparent(Object *obj)
+{
+    if (obj->parent) {
+        object_property_del_child(obj->parent, obj, NULL);
+    }
+}
+
 static void object_deinit(Object *obj, TypeImpl *type)
 {
     if (type->instance_finalize) {
@@ -319,9 +326,8 @@ static void object_deinit(Object *obj, TypeImpl *type)
     if (type_has_parent(type)) {
         object_deinit(obj, type_get_parent(type));
     }
-    if (obj->parent) {
-        object_property_del_child(obj->parent, obj, NULL);
-    }
+
+    object_unparent(obj);
 }
 
 void object_finalize(void *data)
@@ -557,6 +563,7 @@ void object_unref(Object *obj)
     g_assert(obj->ref > 0);
     obj->ref--;
 
+    /* parent always holds a reference to its children */
     if (obj->ref == 0) {
         object_finalize(obj);
     }
-- 
1.7.4.1

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

* [Qemu-devel] [PATCH 00/23] qom: use Type system to register all devices
  2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
                   ` (20 preceding siblings ...)
  2012-01-30 21:09 ` [Qemu-devel] [PATCH 23/23] not-for-upstream: fix device_del Anthony Liguori
@ 2012-01-30 21:16 ` Anthony Liguori
  2012-01-30 22:46   ` Anthony Liguori
  2012-02-01 19:55   ` Peter Maydell
  21 siblings, 2 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 21:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Andreas Faerber, Peter Maydell

(Sorry for not posting this correctly, I didn't want to spam the list with a 
second submission)

This is the 3rd QOM series.  I decided to post this even though there's a known 
issue with device_del as I wanted to give people more time to review what's 
going on here.

The goal of this series is to make DeviceState a first class QOM base class. 
The result is that you can object_new(TYPE_E1000) and have a functioning device. 
  qdev_create() and qdev_free() are now trivialized as QOM wrappers.

Patch 8/23 is an automated touch everything patch.  I decided to leave it as one 
big patch because this is entirely programmatic.  There's no intelligence in 
this patch so I think it's easier to review quickly as one big change.

The other notable feature of this series it that properties have been moved to 
the Object base class.  This means that other subsystems can begin using QOM.

This is the last touch every file in the tree series.

  b/Makefile.objs              |    4
  b/hw/9pfs/virtio-9p-device.c |   16
  b/hw/a9mpcore.c              |   40 -
  b/hw/ac97.c                  |   18
  b/hw/acpi_piix4.c            |   20
  b/hw/ads7846.c               |   11
  b/hw/alpha_typhoon.c         |   14
  b/hw/apb_pci.c               |   41 -
  b/hw/apic.c                  |   10
  b/hw/apic_common.c           |   15
  b/hw/apic_internal.h         |    1
  b/hw/applesmc.c              |   28 -
  b/hw/arm11mpcore.c           |   28 -
  b/hw/arm_l2x0.c              |   24
  b/hw/arm_mptimer.c           |   28 -
  b/hw/arm_sysctl.c            |   18
  b/hw/arm_timer.c             |   35 -
  b/hw/armv7m.c                |   14
  b/hw/armv7m_nvic.c           |   32 -
  b/hw/bitbang_i2c.c           |   14
  b/hw/bonito.c                |   32 -
  b/hw/ccid-card-emulated.c    |   35 -
  b/hw/ccid-card-passthru.c    |   28 -
  b/hw/ccid.h                  |    1
  b/hw/cirrus_vga.c            |   30 -
  b/hw/cs4231.c                |   18
  b/hw/cs4231a.c               |   30 -
  b/hw/debugcon.c              |   26
  b/hw/dec_pci.c               |   40 -
  b/hw/ds1225y.c               |   16
  b/hw/ds1338.c                |   11
  b/hw/e1000.c                 |   20
  b/hw/eccmemctl.c             |   18
  b/hw/eepro100.c              |   83 +--
  b/hw/empty_slot.c            |   11
  b/hw/es1370.c                |   16
  b/hw/escc.c                  |   18
  b/hw/esp.c                   |   18
  b/hw/etraxfs_eth.c           |   14
  b/hw/etraxfs_pic.c           |   14
  b/hw/etraxfs_ser.c           |   16
  b/hw/etraxfs_timer.c         |   11
  b/hw/fdc.c                   |   76 +-
  b/hw/fw_cfg.c                |   20
  b/hw/g364fb.c                |   20
  b/hw/grackle_pci.c           |   26
  b/hw/grlib_apbuart.c         |   14
  b/hw/grlib_gptimer.c         |   16
  b/hw/grlib_irqmp.c           |   16
  b/hw/gt64xxx.c               |   22
  b/hw/gus.c                   |   32 -
  b/hw/hda-audio.c             |   36 -
  b/hw/highbank.c              |   18
  b/hw/hpet.c                  |   20
  b/hw/i2c.c                   |   23
  b/hw/i2c.h                   |    3
  b/hw/i82374.c                |   22
  b/hw/i82378.c                |   22
  b/hw/i8254.c                 |   30 -
  b/hw/i8259.c                 |   11
  b/hw/i8259_common.c          |   13
  b/hw/i8259_internal.h        |    1
  b/hw/ide/ahci.c              |   24
  b/hw/ide/cmd646.c            |   14
  b/hw/ide/ich.c               |   15
  b/hw/ide/isa.c               |   30 -
  b/hw/ide/piix.c              |   44 -
  b/hw/ide/qdev.c              |   95 ++-
  b/hw/ide/via.c               |   14
  b/hw/integratorcp.c          |   25
  b/hw/intel-hda.c             |   39 -
  b/hw/intel-hda.h             |    1
  b/hw/ioapic.c                |   14
  b/hw/ioapic_common.c         |   10
  b/hw/ioapic_internal.h       |    1
  b/hw/ioh3420.c               |   20
  b/hw/isa-bus.c               |   38 -
  b/hw/isa.h                   |    2
  b/hw/ivshmem.c               |   16
  b/hw/kvm/apic.c              |    5
  b/hw/kvm/clock.c             |   16
  b/hw/kvm/i8259.c             |    8
  b/hw/kvm/ioapic.c            |   20
  b/hw/lan9118.c               |   18
  b/hw/lance.c                 |   20
  b/hw/lm32_juart.c            |   18
  b/hw/lm32_pic.c              |   16
  b/hw/lm32_sys.c              |   18
  b/hw/lm32_timer.c            |   18
  b/hw/lm32_uart.c             |   18
  b/hw/lm832x.c                |   14
  b/hw/lsi53c895a.c            |   17
  b/hw/m48t59.c                |   46 -
  b/hw/macio.c                 |   11
  b/hw/marvell_88w8618_audio.c |   18
  b/hw/max111x.c               |   22
  b/hw/max7310.c               |   16
  b/hw/mc146818rtc.c           |   34 -
  b/hw/milkymist-ac97.c        |   16
  b/hw/milkymist-hpdmc.c       |   16
  b/hw/milkymist-memcard.c     |   16
  b/hw/milkymist-minimac2.c    |   18
  b/hw/milkymist-pfpu.c        |   16
  b/hw/milkymist-softusb.c     |   18
  b/hw/milkymist-sysctl.c      |   18
  b/hw/milkymist-tmu2.c        |   16
  b/hw/milkymist-uart.c        |   18
  b/hw/milkymist-vgafb.c       |   18
  b/hw/mips_malta.c            |   14
  b/hw/mipsnet.c               |   20
  b/hw/mpc8544_guts.c          |   11
  b/hw/mst_fpga.c              |   16
  b/hw/musicpal.c              |  117 ++--
  b/hw/nand.c                  |   18
  b/hw/ne2000-isa.c            |   26
  b/hw/ne2000.c                |   16
  b/hw/omap_gpio.c             |   32 -
  b/hw/omap_intc.c             |   32 -
  b/hw/onenand.c               |   16
  b/hw/opencores_eth.c         |   18
  b/hw/parallel.c              |   28 -
  b/hw/pc.c                    |   18
  b/hw/pc_piix.c               |    6
  b/hw/pci.c                   |   41 -
  b/hw/pci.h                   |    2
  b/hw/pckbd.c                 |   16
  b/hw/pcnet-pci.c             |   18
  b/hw/piix4.c                 |   18
  b/hw/piix_pci.c              |   74 +-
  b/hw/pl011.c                 |   24
  b/hw/pl022.c                 |   11
  b/hw/pl031.c                 |   16
  b/hw/pl041.c                 |   20
  b/hw/pl050.c                 |   28 -
  b/hw/pl061.c                 |   28 -
  b/hw/pl080.c                 |   32 -
  b/hw/pl110.c                 |   48 +
  b/hw/pl181.c                 |   18
  b/hw/pl190.c                 |   18
  b/hw/ppc4xx_pci.c            |   28 -
  b/hw/ppc_prep.c              |    2
  b/hw/ppce500_pci.c           |   28 -
  b/hw/ppce500_spin.c          |   11
  b/hw/prep_pci.c              |   26
  b/hw/pxa2xx.c                |   56 +-
  b/hw/pxa2xx_dma.c            |   18
  b/hw/pxa2xx_gpio.c           |   16
  b/hw/pxa2xx_pic.c            |   16
  b/hw/pxa2xx_timer.c          |   36 -
  b/hw/qdev-addr.c             |    6
  b/hw/qdev-monitor.c          |  590 ++++++++++++++++++++++
  b/hw/qdev-properties.c       |   57 +-
  b/hw/qdev.c                  | 1144 +++----------------------------------------
  b/hw/qdev.h                  |  367 +------------
  b/hw/qxl.c                   |   40 -
  b/hw/realview.c              |   11
  b/hw/realview_gic.c          |   11
  b/hw/rtl8139.c               |   18
  b/hw/s390-virtio-bus.c       |  137 ++---
  b/hw/s390-virtio-bus.h       |   19
  b/hw/sb16.c                  |   34 -
  b/hw/sbi.c                   |   16
  b/hw/scsi-bus.c              |   21
  b/hw/scsi-disk.c             |  116 ++--
  b/hw/scsi-generic.c          |   28 -
  b/hw/scsi.h                  |    1
  b/hw/serial.c                |   30 -
  b/hw/sga.c                   |   14
  b/hw/sh_pci.c                |   22
  b/hw/slavio_intctl.c         |   16
  b/hw/slavio_misc.c           |   27 -
  b/hw/slavio_timer.c          |   18
  b/hw/smbus.c                 |    6
  b/hw/smbus.h                 |    2
  b/hw/smbus_eeprom.c          |   22
  b/hw/smc91c111.c             |   18
  b/hw/spapr_llan.c            |   14
  b/hw/spapr_pci.c             |   22
  b/hw/spapr_vio.c             |   37 -
  b/hw/spapr_vio.h             |    1
  b/hw/spapr_vscsi.c           |   14
  b/hw/spapr_vty.c             |   14
  b/hw/sparc32_dma.c           |   18
  b/hw/spitz.c                 |   60 +-
  b/hw/ssd0303.c               |   14
  b/hw/ssd0323.c               |   11
  b/hw/ssi-sd.c                |   11
  b/hw/ssi.c                   |   26
  b/hw/ssi.h                   |    2
  b/hw/stellaris.c             |   44 -
  b/hw/stellaris_enet.c        |   14
  b/hw/strongarm.c             |   98 ++-
  b/hw/sun4c_intctl.c          |   16
  b/hw/sun4m.c                 |   50 +
  b/hw/sun4m_iommu.c           |   18
  b/hw/sun4u.c                 |   39 -
  b/hw/sysbus.c                |   24
  b/hw/sysbus.h                |    4
  b/hw/tcx.c                   |   18
  b/hw/tmp105.c                |   14
  b/hw/tosa.c                  |   24
  b/hw/tusb6010.c              |   14
  b/hw/twl92230.c              |   14
  b/hw/unin_pci.c              |   74 +-
  b/hw/usb-audio.c             |   29 -
  b/hw/usb-bt.c                |   14
  b/hw/usb-bus.c               |   25
  b/hw/usb-ccid.c              |   46 -
  b/hw/usb-ehci.c              |   32 -
  b/hw/usb-hid.c               |   72 +-
  b/hw/usb-hub.c               |   18
  b/hw/usb-msd.c               |   31 -
  b/hw/usb-net.c               |   27 -
  b/hw/usb-ohci.c              |   42 -
  b/hw/usb-serial.c            |   50 +
  b/hw/usb-uhci.c              |   96 ++-
  b/hw/usb-wacom.c             |   21
  b/hw/usb-xhci.c              |   25
  b/hw/usb.h                   |    5
  b/hw/versatile_pci.c         |   33 -
  b/hw/versatilepb.c           |   16
  b/hw/vga-isa.c               |   16
  b/hw/vga-pci.c               |   14
  b/hw/virtio-console.c        |   28 -
  b/hw/virtio-pci.c            |   68 +-
  b/hw/virtio-serial-bus.c     |   21
  b/hw/virtio-serial.h         |    6
  b/hw/vmmouse.c               |   28 -
  b/hw/vmport.c                |   14
  b/hw/vmware_vga.c            |   16
  b/hw/vt82c686.c              |   64 +-
  b/hw/wdt_i6300esb.c          |   16
  b/hw/wdt_ib700.c             |   16
  b/hw/wm8750.c                |   14
  b/hw/xen_platform.c          |   18
  b/hw/xgmac.c                 |   25
  b/hw/xilinx_axidma.c         |   14
  b/hw/xilinx_axienet.c        |   14
  b/hw/xilinx_ethlite.c        |   14
  b/hw/xilinx_intc.c           |   14
  b/hw/xilinx_timer.c          |   14
  b/hw/xilinx_uartlite.c       |   13
  b/hw/xio3130_downstream.c    |   20
  b/hw/xio3130_upstream.c      |   20
  b/hw/z2.c                    |   28 -
  b/hw/zaurus.c                |   18
  b/include/qemu/object.h      |  226 ++++++++
  b/qapi-schema.json           |   55 +-
  b/qemu-char.c                |   10
  b/qemu-char.h                |    2
  b/qerror.c                   |    2
  b/qmp-commands.hx            |    5
  b/qmp.c                      |   61 +-
  b/qom/Makefile               |    2
  b/qom/container.c            |   15
  b/qom/object.c               |  500 ++++++++++++++++++
  b/usb-linux.c                |   35 -
  hw/container.c               |   27 -
  258 files changed, 4817 insertions(+), 4058 deletions(-)

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

* Re: [Qemu-devel] [PATCH 08/23] qdev: register all types natively through QEMU Object Model
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 08/23] qdev: register all types natively through QEMU Object Model Anthony Liguori
@ 2012-01-30 22:29   ` Peter Maydell
  2012-01-30 22:43     ` Anthony Liguori
  0 siblings, 1 reply; 45+ messages in thread
From: Peter Maydell @ 2012-01-30 22:29 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, Andreas Faerber, qemu-devel

On 30 January 2012 21:08, Anthony Liguori <aliguori@us.ibm.com> wrote:
> This was done in a mostly automated fashion.  I did it in three steps and then
> rebased it into a single step which avoids repeatedly touching every file in
> the tree.
>
> The first step was a sed-based addition of the parent type to the subclass
> registration functions.
>
> The second step was another sed-based removal of subclass registration functions
> while also adding virtual functions from the base class into a class_init
> function as appropriate.
>
> Finally, a python script was used to convert the DeviceInfo structures and
> qdev_register_subclass functions to TypeInfo structures, class_init functions,
> and type_register_static calls.

Can you document this process in enough detail so that those of us with
trees/branches not yet upstream can use it to ease the process of
rebasing after this lands, please?

Thanks
-- PMM

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

* Re: [Qemu-devel] [PATCH 03/23] qdev: make DeviceInfo private
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 03/23] qdev: make DeviceInfo private Anthony Liguori
@ 2012-01-30 22:31   ` Andreas Färber
  0 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2012-01-30 22:31 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, qemu-devel, Peter Maydell

Am 30.01.2012 22:08, schrieb Anthony Liguori:
> Introduce accessors and remove any code that directly accesses DeviceInfo
> members.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

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

/-F

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

* Re: [Qemu-devel] [PATCH 08/23] qdev: register all types natively through QEMU Object Model
  2012-01-30 22:29   ` Peter Maydell
@ 2012-01-30 22:43     ` Anthony Liguori
  0 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 22:43 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Paolo Bonzini, Andreas Faerber, qemu-devel

On 01/30/2012 04:29 PM, Peter Maydell wrote:
> On 30 January 2012 21:08, Anthony Liguori<aliguori@us.ibm.com>  wrote:
>> This was done in a mostly automated fashion.  I did it in three steps and then
>> rebased it into a single step which avoids repeatedly touching every file in
>> the tree.
>>
>> The first step was a sed-based addition of the parent type to the subclass
>> registration functions.
>>
>> The second step was another sed-based removal of subclass registration functions
>> while also adding virtual functions from the base class into a class_init
>> function as appropriate.
>>
>> Finally, a python script was used to convert the DeviceInfo structures and
>> qdev_register_subclass functions to TypeInfo structures, class_init functions,
>> and type_register_static calls.
>
> Can you document this process in enough detail so that those of us with
> trees/branches not yet upstream can use it to ease the process of
> rebasing after this lands, please?

Replace DeviceInfo with TypeInfo, mapping:

TypeInfo::name = DeviceInfo::name
TypeInfo::parent = subclass argument to qdev_register_subclass
TypeInfo::instance_size = DeviceInfo::size
TypeInfo::class_init = DeviceInfo::class_init

Any remaining DeviceInfo members being initialized should be moved to the 
class_init function as assignment to DeviceClass.  Use DEVICE_CLASS() to case 
the ObjectClass in the argument to DeviceClass *dc and then assign the members.

Replace qdev_register_subclass calls with type_register_static.

Regards,

Anthony Liguori

>
> Thanks
> -- PMM
>

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

* Re: [Qemu-devel] [PATCH 00/23] qom: use Type system to register all devices
  2012-01-30 21:16 ` [Qemu-devel] [PATCH 00/23] qom: use Type system to register all devices Anthony Liguori
@ 2012-01-30 22:46   ` Anthony Liguori
  2012-02-01 19:55   ` Peter Maydell
  1 sibling, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-01-30 22:46 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, Andreas Faerber, qemu-devel, Peter Maydell

On 01/30/2012 03:16 PM, Anthony Liguori wrote:
> (Sorry for not posting this correctly, I didn't want to spam the list with a
> second submission)
>
> This is the 3rd QOM series. I decided to post this even though there's a known
> issue with device_del as I wanted to give people more time to review what's
> going on here.

I think the "lingering issue with device_del" is that my broken battery is 
causing my laptop to overheat...  So I'll fold patch 23 into the right spot and 
repost tomorrow.

Could use another set of eyes to walk through the reference counting stuff 
though.  It's a bit nastier than I would like it to be.  I really dislike the 
notion of having an object_unparent in the unplug path.

Regards,

Anthony Liguori

>
> The goal of this series is to make DeviceState a first class QOM base class. The
> result is that you can object_new(TYPE_E1000) and have a functioning device.
> qdev_create() and qdev_free() are now trivialized as QOM wrappers.
>
> Patch 8/23 is an automated touch everything patch. I decided to leave it as one
> big patch because this is entirely programmatic. There's no intelligence in this
> patch so I think it's easier to review quickly as one big change.
>
> The other notable feature of this series it that properties have been moved to
> the Object base class. This means that other subsystems can begin using QOM.
>
> This is the last touch every file in the tree series.
>
> b/Makefile.objs | 4
> b/hw/9pfs/virtio-9p-device.c | 16
> b/hw/a9mpcore.c | 40 -
> b/hw/ac97.c | 18
> b/hw/acpi_piix4.c | 20
> b/hw/ads7846.c | 11
> b/hw/alpha_typhoon.c | 14
> b/hw/apb_pci.c | 41 -
> b/hw/apic.c | 10
> b/hw/apic_common.c | 15
> b/hw/apic_internal.h | 1
> b/hw/applesmc.c | 28 -
> b/hw/arm11mpcore.c | 28 -
> b/hw/arm_l2x0.c | 24
> b/hw/arm_mptimer.c | 28 -
> b/hw/arm_sysctl.c | 18
> b/hw/arm_timer.c | 35 -
> b/hw/armv7m.c | 14
> b/hw/armv7m_nvic.c | 32 -
> b/hw/bitbang_i2c.c | 14
> b/hw/bonito.c | 32 -
> b/hw/ccid-card-emulated.c | 35 -
> b/hw/ccid-card-passthru.c | 28 -
> b/hw/ccid.h | 1
> b/hw/cirrus_vga.c | 30 -
> b/hw/cs4231.c | 18
> b/hw/cs4231a.c | 30 -
> b/hw/debugcon.c | 26
> b/hw/dec_pci.c | 40 -
> b/hw/ds1225y.c | 16
> b/hw/ds1338.c | 11
> b/hw/e1000.c | 20
> b/hw/eccmemctl.c | 18
> b/hw/eepro100.c | 83 +--
> b/hw/empty_slot.c | 11
> b/hw/es1370.c | 16
> b/hw/escc.c | 18
> b/hw/esp.c | 18
> b/hw/etraxfs_eth.c | 14
> b/hw/etraxfs_pic.c | 14
> b/hw/etraxfs_ser.c | 16
> b/hw/etraxfs_timer.c | 11
> b/hw/fdc.c | 76 +-
> b/hw/fw_cfg.c | 20
> b/hw/g364fb.c | 20
> b/hw/grackle_pci.c | 26
> b/hw/grlib_apbuart.c | 14
> b/hw/grlib_gptimer.c | 16
> b/hw/grlib_irqmp.c | 16
> b/hw/gt64xxx.c | 22
> b/hw/gus.c | 32 -
> b/hw/hda-audio.c | 36 -
> b/hw/highbank.c | 18
> b/hw/hpet.c | 20
> b/hw/i2c.c | 23
> b/hw/i2c.h | 3
> b/hw/i82374.c | 22
> b/hw/i82378.c | 22
> b/hw/i8254.c | 30 -
> b/hw/i8259.c | 11
> b/hw/i8259_common.c | 13
> b/hw/i8259_internal.h | 1
> b/hw/ide/ahci.c | 24
> b/hw/ide/cmd646.c | 14
> b/hw/ide/ich.c | 15
> b/hw/ide/isa.c | 30 -
> b/hw/ide/piix.c | 44 -
> b/hw/ide/qdev.c | 95 ++-
> b/hw/ide/via.c | 14
> b/hw/integratorcp.c | 25
> b/hw/intel-hda.c | 39 -
> b/hw/intel-hda.h | 1
> b/hw/ioapic.c | 14
> b/hw/ioapic_common.c | 10
> b/hw/ioapic_internal.h | 1
> b/hw/ioh3420.c | 20
> b/hw/isa-bus.c | 38 -
> b/hw/isa.h | 2
> b/hw/ivshmem.c | 16
> b/hw/kvm/apic.c | 5
> b/hw/kvm/clock.c | 16
> b/hw/kvm/i8259.c | 8
> b/hw/kvm/ioapic.c | 20
> b/hw/lan9118.c | 18
> b/hw/lance.c | 20
> b/hw/lm32_juart.c | 18
> b/hw/lm32_pic.c | 16
> b/hw/lm32_sys.c | 18
> b/hw/lm32_timer.c | 18
> b/hw/lm32_uart.c | 18
> b/hw/lm832x.c | 14
> b/hw/lsi53c895a.c | 17
> b/hw/m48t59.c | 46 -
> b/hw/macio.c | 11
> b/hw/marvell_88w8618_audio.c | 18
> b/hw/max111x.c | 22
> b/hw/max7310.c | 16
> b/hw/mc146818rtc.c | 34 -
> b/hw/milkymist-ac97.c | 16
> b/hw/milkymist-hpdmc.c | 16
> b/hw/milkymist-memcard.c | 16
> b/hw/milkymist-minimac2.c | 18
> b/hw/milkymist-pfpu.c | 16
> b/hw/milkymist-softusb.c | 18
> b/hw/milkymist-sysctl.c | 18
> b/hw/milkymist-tmu2.c | 16
> b/hw/milkymist-uart.c | 18
> b/hw/milkymist-vgafb.c | 18
> b/hw/mips_malta.c | 14
> b/hw/mipsnet.c | 20
> b/hw/mpc8544_guts.c | 11
> b/hw/mst_fpga.c | 16
> b/hw/musicpal.c | 117 ++--
> b/hw/nand.c | 18
> b/hw/ne2000-isa.c | 26
> b/hw/ne2000.c | 16
> b/hw/omap_gpio.c | 32 -
> b/hw/omap_intc.c | 32 -
> b/hw/onenand.c | 16
> b/hw/opencores_eth.c | 18
> b/hw/parallel.c | 28 -
> b/hw/pc.c | 18
> b/hw/pc_piix.c | 6
> b/hw/pci.c | 41 -
> b/hw/pci.h | 2
> b/hw/pckbd.c | 16
> b/hw/pcnet-pci.c | 18
> b/hw/piix4.c | 18
> b/hw/piix_pci.c | 74 +-
> b/hw/pl011.c | 24
> b/hw/pl022.c | 11
> b/hw/pl031.c | 16
> b/hw/pl041.c | 20
> b/hw/pl050.c | 28 -
> b/hw/pl061.c | 28 -
> b/hw/pl080.c | 32 -
> b/hw/pl110.c | 48 +
> b/hw/pl181.c | 18
> b/hw/pl190.c | 18
> b/hw/ppc4xx_pci.c | 28 -
> b/hw/ppc_prep.c | 2
> b/hw/ppce500_pci.c | 28 -
> b/hw/ppce500_spin.c | 11
> b/hw/prep_pci.c | 26
> b/hw/pxa2xx.c | 56 +-
> b/hw/pxa2xx_dma.c | 18
> b/hw/pxa2xx_gpio.c | 16
> b/hw/pxa2xx_pic.c | 16
> b/hw/pxa2xx_timer.c | 36 -
> b/hw/qdev-addr.c | 6
> b/hw/qdev-monitor.c | 590 ++++++++++++++++++++++
> b/hw/qdev-properties.c | 57 +-
> b/hw/qdev.c | 1144 +++----------------------------------------
> b/hw/qdev.h | 367 +------------
> b/hw/qxl.c | 40 -
> b/hw/realview.c | 11
> b/hw/realview_gic.c | 11
> b/hw/rtl8139.c | 18
> b/hw/s390-virtio-bus.c | 137 ++---
> b/hw/s390-virtio-bus.h | 19
> b/hw/sb16.c | 34 -
> b/hw/sbi.c | 16
> b/hw/scsi-bus.c | 21
> b/hw/scsi-disk.c | 116 ++--
> b/hw/scsi-generic.c | 28 -
> b/hw/scsi.h | 1
> b/hw/serial.c | 30 -
> b/hw/sga.c | 14
> b/hw/sh_pci.c | 22
> b/hw/slavio_intctl.c | 16
> b/hw/slavio_misc.c | 27 -
> b/hw/slavio_timer.c | 18
> b/hw/smbus.c | 6
> b/hw/smbus.h | 2
> b/hw/smbus_eeprom.c | 22
> b/hw/smc91c111.c | 18
> b/hw/spapr_llan.c | 14
> b/hw/spapr_pci.c | 22
> b/hw/spapr_vio.c | 37 -
> b/hw/spapr_vio.h | 1
> b/hw/spapr_vscsi.c | 14
> b/hw/spapr_vty.c | 14
> b/hw/sparc32_dma.c | 18
> b/hw/spitz.c | 60 +-
> b/hw/ssd0303.c | 14
> b/hw/ssd0323.c | 11
> b/hw/ssi-sd.c | 11
> b/hw/ssi.c | 26
> b/hw/ssi.h | 2
> b/hw/stellaris.c | 44 -
> b/hw/stellaris_enet.c | 14
> b/hw/strongarm.c | 98 ++-
> b/hw/sun4c_intctl.c | 16
> b/hw/sun4m.c | 50 +
> b/hw/sun4m_iommu.c | 18
> b/hw/sun4u.c | 39 -
> b/hw/sysbus.c | 24
> b/hw/sysbus.h | 4
> b/hw/tcx.c | 18
> b/hw/tmp105.c | 14
> b/hw/tosa.c | 24
> b/hw/tusb6010.c | 14
> b/hw/twl92230.c | 14
> b/hw/unin_pci.c | 74 +-
> b/hw/usb-audio.c | 29 -
> b/hw/usb-bt.c | 14
> b/hw/usb-bus.c | 25
> b/hw/usb-ccid.c | 46 -
> b/hw/usb-ehci.c | 32 -
> b/hw/usb-hid.c | 72 +-
> b/hw/usb-hub.c | 18
> b/hw/usb-msd.c | 31 -
> b/hw/usb-net.c | 27 -
> b/hw/usb-ohci.c | 42 -
> b/hw/usb-serial.c | 50 +
> b/hw/usb-uhci.c | 96 ++-
> b/hw/usb-wacom.c | 21
> b/hw/usb-xhci.c | 25
> b/hw/usb.h | 5
> b/hw/versatile_pci.c | 33 -
> b/hw/versatilepb.c | 16
> b/hw/vga-isa.c | 16
> b/hw/vga-pci.c | 14
> b/hw/virtio-console.c | 28 -
> b/hw/virtio-pci.c | 68 +-
> b/hw/virtio-serial-bus.c | 21
> b/hw/virtio-serial.h | 6
> b/hw/vmmouse.c | 28 -
> b/hw/vmport.c | 14
> b/hw/vmware_vga.c | 16
> b/hw/vt82c686.c | 64 +-
> b/hw/wdt_i6300esb.c | 16
> b/hw/wdt_ib700.c | 16
> b/hw/wm8750.c | 14
> b/hw/xen_platform.c | 18
> b/hw/xgmac.c | 25
> b/hw/xilinx_axidma.c | 14
> b/hw/xilinx_axienet.c | 14
> b/hw/xilinx_ethlite.c | 14
> b/hw/xilinx_intc.c | 14
> b/hw/xilinx_timer.c | 14
> b/hw/xilinx_uartlite.c | 13
> b/hw/xio3130_downstream.c | 20
> b/hw/xio3130_upstream.c | 20
> b/hw/z2.c | 28 -
> b/hw/zaurus.c | 18
> b/include/qemu/object.h | 226 ++++++++
> b/qapi-schema.json | 55 +-
> b/qemu-char.c | 10
> b/qemu-char.h | 2
> b/qerror.c | 2
> b/qmp-commands.hx | 5
> b/qmp.c | 61 +-
> b/qom/Makefile | 2
> b/qom/container.c | 15
> b/qom/object.c | 500 ++++++++++++++++++
> b/usb-linux.c | 35 -
> hw/container.c | 27 -
> 258 files changed, 4817 insertions(+), 4058 deletions(-)
>
>

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

* Re: [Qemu-devel] [PATCH 10/23] qdev: remove baked in notion of aliases
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 10/23] qdev: remove baked in notion of aliases Anthony Liguori
@ 2012-01-31  7:44   ` Paolo Bonzini
  0 siblings, 0 replies; 45+ messages in thread
From: Paolo Bonzini @ 2012-01-31  7:44 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Peter Maydell, Andreas Faerber, qemu-devel

On 01/30/2012 10:08 PM, Anthony Liguori wrote:
> +/*
> + * Aliases were a bad idea from the start.  Let's keep them
> + * from spreading further.
> + */
> +static const char *qdev_class_get_alias(DeviceClass *dc)
> +{
> +    const char *typename = object_class_get_name(OBJECT_CLASS(dc));
> +
> +    if (strcmp(typename, "virtio-blk-pci") == 0) {
> +        return "virtio-blk";
> +    } else if (strcmp(typename, "virtio-net-pci") == 0) {
> +        return "virtio-net";
> +    } else if (strcmp(typename, "virtio-serial-pci") == 0) {
> +        return "virtio-serial";
> +    } else if (strcmp(typename, "virtio-balloon-pci") == 0) {
> +        return "virtio-balloon";
> +    } else if (strcmp(typename, "virtio-blk-s390") == 0) {
> +        return "virtio-blk";
> +    } else if (strcmp(typename, "virtio-net-s390") == 0) {
> +        return "virtio-net";
> +    } else if (strcmp(typename, "virtio-serial-s390") == 0) {
> +        return "virtio-serial";
> +    } else if (strcmp(typename, "lsi53c895a") == 0) {
> +        return "lsi";
> +    } else if (strcmp(typename, "ich9-ahci") == 0) {
> +        return "ahci";
> +    }
> +
> +    return NULL;
> +}
> +
> +static bool qdev_class_has_alias(DeviceClass *dc)
> +{
> +    return (qdev_class_get_alias(dc) != NULL);
> +}
> +
>   const char *qdev_fw_name(DeviceState *dev)
>   {
>       DeviceClass *dc = DEVICE_GET_CLASS(dev);
>
>       if (dc->fw_name) {
>           return dc->fw_name;
> -    } else if (dc->alias) {
> -        return dc->alias;
> +    } else if (qdev_class_has_alias(dc)) {
> +        return qdev_class_get_alias(dc);
>       }
>
>       return object_get_typename(OBJECT(dev));
> @@ -161,8 +197,8 @@ static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
>       if (dc->bus_info) {
>           error_printf(", bus %s", dc->bus_info->name);
>       }
> -    if (dc->alias) {
> -        error_printf(", alias \"%s\"", dc->alias);
> +    if (qdev_class_has_alias(dc)) {
> +        error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
>       }
>       if (dc->desc) {
>           error_printf(", desc \"%s\"", dc->desc);
> @@ -188,6 +224,27 @@ static int set_property(const char *name, const char *value, void *opaque)
>       return 0;
>   }
>
> +static const char *find_typename_by_alias(const char *alias)
> +{
> +    /* I don't think s390 aliasing could have ever worked... */

Yes, because s390 doesn't have PCI.

> +    if (strcmp(alias, "virtio-blk") == 0) {
> +        return "virtio-blk-pci";
> +    } else if (strcmp(alias, "virtio-net") == 0) {
> +        return "virtio-net-pci";
> +    } else if (strcmp(alias, "virtio-serial") == 0) {
> +        return "virtio-serial-pci";
> +    } else if (strcmp(alias, "virtio-balloon") == 0) {
> +        return "virtio-balloon-pci";
> +    } else if (strcmp(alias, "lsi") == 0) {
> +        return "lsi53c895a";
> +    } else if (strcmp(alias, "ahci") == 0) {
> +        return "ich9-ahci";
> +    }
> +
> +    return NULL;
> +}
> +


Please change this to a table so that you can have:

     if (object_class_by_name(table[i].name) &&
         strcmp(alias, table[i].alias) == 0) {
         return table[i].name;
     }

and for the other direction

     if (object_class_by_name(table[i].name) &&
         strcmp(name, table[i].name) == 0) {
         return table[i].alias;
     }

Paolo

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

* Re: [Qemu-devel] [PATCH 17/23] qom: move properties from qdev to object
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 17/23] qom: move properties from qdev to object Anthony Liguori
@ 2012-01-31  7:46   ` Paolo Bonzini
  2012-02-01 20:01     ` Anthony Liguori
  0 siblings, 1 reply; 45+ messages in thread
From: Paolo Bonzini @ 2012-01-31  7:46 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Peter Maydell, Andreas Faerber, qemu-devel

On 01/30/2012 10:08 PM, Anthony Liguori wrote:
> This is mostly code movement although not entirely.  This makes properties part
> of the Object base class which means that we can now start using Object in a
> meaningful way outside of qdev.

Can we move them to an intermediate base class?  I would like to use QOM 
refcounting for other objects, such as SCSIRequest, so it is important 
to have Object as a pretty light-weight class.  Also (and perhaps more 
importantly), interface implementations are Objects too and they do not 
need properties.

I cannot think of any better name than IntrospectableObject, which is 
quite a mouthful.  I suppose that we could have the base class but still 
pass the objects to the function as Object * and use the OBJECT macro. 
Nothing of this is in a hot path anyway.

Paolo

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

* Re: [Qemu-devel] [PATCH 21/23] object: sure up reference counting
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 21/23] object: sure up reference counting Anthony Liguori
@ 2012-01-31  7:49   ` Paolo Bonzini
  2012-02-01 19:47   ` Peter Maydell
  1 sibling, 0 replies; 45+ messages in thread
From: Paolo Bonzini @ 2012-01-31  7:49 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Peter Maydell, Andreas Faerber, qemu-devel

On 01/30/2012 10:08 PM, Anthony Liguori wrote:
> Now we have the following behavior:
>
> 1) object_new() returns an object with ref = 1
> 2) object_initialize() does not increase the reference count (ref may be 0).
> 3) object_deref() will finalize the object when ref = 0.  it does not free the
>     memory associated with the object.
> 4) both link and child properties correctly set the reference count.
>
> The expected usage is the following:
>
> 1) child devices should generally be created via object_initialize() using
>     memory from the parent device.  Adding the object as a child property will
>     take ownership of the object and tie the child's life cycle to the parent.
>
> 2) If a child device is created via qdev_create() or some other form of
>     object_new(), there must be an object_delete() call in the parent device's
>     finalize function.

We might want to fix this by adding a special "created as child" 
refcount value, so that the object_delete can still be automatic. 
Adding floating references as they have them in GObject is also 
possible.  I agree that it can be left for later, though.

Paolo

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

* Re: [Qemu-devel] [PATCH 22/23] container: make a decendent of Object
  2012-01-30 21:09 ` [Qemu-devel] [PATCH 22/23] container: make a decendent of Object Anthony Liguori
@ 2012-01-31  7:50   ` Paolo Bonzini
  2012-01-31  9:21     ` Andreas Färber
  2012-02-01 19:48   ` Peter Maydell
  1 sibling, 1 reply; 45+ messages in thread
From: Paolo Bonzini @ 2012-01-31  7:50 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Peter Maydell, Andreas Faerber, qemu-devel

On 01/30/2012 10:09 PM, Anthony Liguori wrote:
> diff --git a/qom/container.c b/qom/container.c
> new file mode 100644
> index 0000000..39d7b1e
> --- /dev/null
> +++ b/qom/container.c
> @@ -0,0 +1,15 @@
> +#include "qemu/object.h"
> +#include "module.h"
> +
> +static TypeInfo container_info = {
> +    .name          = "container",
> +    .instance_size = sizeof(Object),
> +    .parent        = TYPE_OBJECT,
> +};
> +

License header, please.  (GPLv2+ or LGPLv2+?)

Paolo

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

* Re: [Qemu-devel] [PATCH 22/23] container: make a decendent of Object
  2012-01-31  7:50   ` Paolo Bonzini
@ 2012-01-31  9:21     ` Andreas Färber
  2012-01-31  9:31       ` Paolo Bonzini
  0 siblings, 1 reply; 45+ messages in thread
From: Andreas Färber @ 2012-01-31  9:21 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, qemu-devel, Peter Maydell

Am 31.01.2012 08:50, schrieb Paolo Bonzini:
> On 01/30/2012 10:09 PM, Anthony Liguori wrote:
>> diff --git a/qom/container.c b/qom/container.c
>> new file mode 100644
>> index 0000000..39d7b1e
>> --- /dev/null
>> +++ b/qom/container.c
>> @@ -0,0 +1,15 @@
>> +#include "qemu/object.h"
>> +#include "module.h"
>> +
>> +static TypeInfo container_info = {
>> +    .name          = "container",
>> +    .instance_size = sizeof(Object),
>> +    .parent        = TYPE_OBJECT,
>> +};
>> +
> 
> License header, please.  (GPLv2+ or LGPLv2+?)

Given that object.c is GPLv2+, I've sticked with that license myself;
but was that choice of license intentional? Effectively means we can't
really have any liberally-licensed device emulation. (But same holds for
MemoryAPI.)

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

* Re: [Qemu-devel] [PATCH 22/23] container: make a decendent of Object
  2012-01-31  9:21     ` Andreas Färber
@ 2012-01-31  9:31       ` Paolo Bonzini
  0 siblings, 0 replies; 45+ messages in thread
From: Paolo Bonzini @ 2012-01-31  9:31 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Peter Maydell, qemu-devel

On 01/31/2012 10:21 AM, Andreas Färber wrote:
>> >
>> >  License header, please.  (GPLv2+ or LGPLv2+?)
> Given that object.c is GPLv2+, I've sticked with that license myself;
> but was that choice of license intentional? Effectively means we can't
> really have any liberally-licensed device emulation. (But same holds for
> MemoryAPI.)

Actually you can.  It's the combination that cannot be released 
liberally, but that's already the case without QOM or MemoryRegion.

If somebody wishes to port such a module to a proprietary platform 
(which doesn't have QOM or other GPL bits), they can.

Paolo

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

* Re: [Qemu-devel] [PATCH 09/23] qdev: kill of DeviceInfo
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 09/23] qdev: kill of DeviceInfo Anthony Liguori
@ 2012-01-31 13:34   ` Andreas Färber
  2012-02-01 19:46   ` Peter Maydell
  1 sibling, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2012-01-31 13:34 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, qemu-devel, Peter Maydell

Am 30.01.2012 22:08, schrieb Anthony Liguori:
> It is no longer used in the tree since everything is done natively through
> QEMU Object Model.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

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

* Re: [Qemu-devel] [PATCH 11/23] qom: allow object_class_foreach to take additional parameters to refine search
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 11/23] qom: allow object_class_foreach to take additional parameters to refine search Anthony Liguori
@ 2012-01-31 13:42   ` Andreas Färber
  0 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2012-01-31 13:42 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, qemu-devel, Peter Maydell

$subject is a bit long.

Am 30.01.2012 22:08, schrieb Anthony Liguori:
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

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

However...

> diff --git a/hw/qdev.c b/hw/qdev.c
> index 636b6b4..a7980c5 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -255,7 +255,7 @@ int qdev_device_help(QemuOpts *opts)
>      driver = qemu_opt_get(opts, "driver");
>      if (driver && !strcmp(driver, "?")) {
>          bool show_no_user = false;
> -        object_class_foreach(qdev_print_devinfo, &show_no_user);
> +        object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, &show_no_user);
>          return 1;
>      }
>  
> @@ -1077,7 +1077,7 @@ void do_info_qtree(Monitor *mon)
>  
>  void do_info_qdm(Monitor *mon)
>  {
> -    object_class_foreach(qdev_print_devinfo, NULL);
> +    object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, NULL);
>  }
>  
>  int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)

If you reordered this patch before 07/23 then you could apply it right
away, unbreaking object_class_foreach().

Andreas

> diff --git a/include/qemu/object.h b/include/qemu/object.h
> index ba37850..adbcfb1 100644
> --- a/include/qemu/object.h
> +++ b/include/qemu/object.h
> @@ -431,6 +431,7 @@ 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),
> +                          const char *implements_type, bool include_abstract,
>                            void *opaque);
>  
>  #endif
> diff --git a/qom/object.c b/qom/object.c
> index a12895f..3dabb1a 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -467,6 +467,8 @@ ObjectClass *object_class_by_name(const char *typename)
>  typedef struct OCFData
>  {
>      void (*fn)(ObjectClass *klass, void *opaque);
> +    const char *implements_type;
> +    bool include_abstract;
>      void *opaque;
>  } OCFData;
>  
> @@ -475,16 +477,28 @@ static void object_class_foreach_tramp(gpointer key, gpointer value,
>  {
>      OCFData *data = opaque;
>      TypeImpl *type = value;
> +    ObjectClass *k;
>  
>      type_class_init(type);
> +    k = type->class;
>  
> -    data->fn(value, type->class);
> +    if (!data->include_abstract && type->abstract) {
> +        return;
> +    }
> +
> +    if (data->implements_type && 
> +        !object_class_dynamic_cast(k, data->implements_type)) {
> +        return;
> +    }
> +
> +    data->fn(k, data->opaque);
>  }
>  
>  void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
> +                          const char *implements_type, bool include_abstract,
>                            void *opaque)
>  {
> -    OCFData data = { fn, opaque };
> +    OCFData data = { fn, implements_type, include_abstract, opaque };
>  
>      g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);
>  }

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

* Re: [Qemu-devel] [PATCH 07/23] qdev: kill off DeviceInfo list
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 07/23] qdev: kill off DeviceInfo list Anthony Liguori
@ 2012-01-31 13:51   ` Andreas Färber
  0 siblings, 0 replies; 45+ messages in thread
From: Andreas Färber @ 2012-01-31 13:51 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, qemu-devel, Peter Maydell

Am 30.01.2012 22:08, schrieb Anthony Liguori:
> Teach the various bits of code that need to walk through available devices to
> do so via QOM.
> 
> Signed-off-by: Anthony Liguori

(Email missing.)

NACK. This introduces broken code, see below.

>  bool qdev_exists(const char *name)
>  {
> -    return !!qdev_find_info(NULL, name);
> +    return !!object_class_by_name(name);
>  }

Minor nit: I'd find object_class_by_name(name) != NULL easier to read
than double negation.

> @@ -245,17 +213,28 @@ DeviceState *qdev_try_create(BusState *bus, const char *name)
>      return qdev_create_from_info(bus, name);
>  }
>  
> -static void qdev_print_devinfo(DeviceInfo *info)
> +static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
>  {
> -    error_printf("name \"%s\", bus %s",
> -                 info->name, info->bus_info->name);
> -    if (info->alias) {
> -        error_printf(", alias \"%s\"", info->alias);
> +    DeviceClass *dc;
> +    bool *show_no_user = opaque;

Due to this...

> +
> +    dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);

...and this, ...

> +
> +    if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
> +        return;
>      }
> -    if (info->desc) {
> -        error_printf(", desc \"%s\"", info->desc);
> +
> +    error_printf("name \"%s\"", object_class_get_name(klass));
> +    if (dc->bus_info) {
> +        error_printf(", bus %s", dc->bus_info->name);
>      }
> -    if (info->no_user) {
> +    if (dc->alias) {
> +        error_printf(", alias \"%s\"", dc->alias);
> +    }
> +    if (dc->desc) {
> +        error_printf(", desc \"%s\"", dc->desc);
> +    }
> +    if (dc->no_user) {
>          error_printf(", no-user");
>      }
>      error_printf("\n");
> @@ -279,17 +258,14 @@ static int set_property(const char *name, const char *value, void *opaque)
>  int qdev_device_help(QemuOpts *opts)
>  {
>      const char *driver;
> -    DeviceInfo *info;
>      Property *prop;
> +    ObjectClass *klass;
> +    DeviceClass *info;
>  
>      driver = qemu_opt_get(opts, "driver");
>      if (driver && !strcmp(driver, "?")) {
> -        for (info = device_info_list; info != NULL; info = info->next) {
> -            if (info->no_user) {
> -                continue;       /* not available, don't show */
> -            }
> -            qdev_print_devinfo(info);
> -        }
> +        bool show_no_user = false;
> +        object_class_foreach(qdev_print_devinfo, &show_no_user);

This...

>          return 1;
>      }
>  
> @@ -297,10 +273,11 @@ int qdev_device_help(QemuOpts *opts)
>          return 0;
>      }
>  
> -    info = qdev_find_info(NULL, driver);
> -    if (!info) {
> +    klass = object_class_by_name(driver);
> +    if (!klass) {
>          return 0;
>      }
> +    info = DEVICE_CLASS(klass);
>  
>      for (prop = info->props; prop && prop->name; prop++) {
>          /*
> @@ -312,14 +289,14 @@ int qdev_device_help(QemuOpts *opts)
>          if (!prop->info->parse) {
>              continue;           /* no way to set it, don't show */
>          }
> -        error_printf("%s.%s=%s\n", info->name, prop->name,
> +        error_printf("%s.%s=%s\n", driver, prop->name,
>                       prop->info->legacy_name ?: prop->info->name);
>      }
>      for (prop = info->bus_info->props; prop && prop->name; prop++) {
>          if (!prop->info->parse) {
>              continue;           /* no way to set it, don't show */
>          }
> -        error_printf("%s.%s=%s\n", info->name, prop->name,
> +        error_printf("%s.%s=%s\n", driver, prop->name,
>                       prop->info->legacy_name ?: prop->info->name);
>      }
>      return 1;
> @@ -1085,11 +1062,7 @@ void do_info_qtree(Monitor *mon)
>  
>  void do_info_qdm(Monitor *mon)
>  {
> -    DeviceInfo *info;
> -
> -    for (info = device_info_list; info != NULL; info = info->next) {
> -        qdev_print_devinfo(info);
> -    }
> +    object_class_foreach(qdev_print_devinfo, NULL);

...and this is broken, as pointed out before:

http://patchwork.ozlabs.org/patch/138396/

Easiest would be to reorder 11/23 before this one so that we don't
introduce a broken, bloated user of foreach in the first place.

Otherwise looking good.

Andreas

>  }
>  
>  int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)

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

* Re: [Qemu-devel] [PATCH 09/23] qdev: kill of DeviceInfo
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 09/23] qdev: kill of DeviceInfo Anthony Liguori
  2012-01-31 13:34   ` Andreas Färber
@ 2012-02-01 19:46   ` Peter Maydell
  2012-02-01 19:56     ` Anthony Liguori
  1 sibling, 1 reply; 45+ messages in thread
From: Peter Maydell @ 2012-02-01 19:46 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, Andreas Faerber, qemu-devel

On 30 January 2012 21:08, Anthony Liguori <aliguori@us.ibm.com> wrote:
> Subject: [PATCH 09/23] qdev: kill of DeviceInfo

"kill off".

-- PMM

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

* Re: [Qemu-devel] [PATCH 21/23] object: sure up reference counting
  2012-01-30 21:08 ` [Qemu-devel] [PATCH 21/23] object: sure up reference counting Anthony Liguori
  2012-01-31  7:49   ` Paolo Bonzini
@ 2012-02-01 19:47   ` Peter Maydell
  2012-02-01 19:55     ` Anthony Liguori
  1 sibling, 1 reply; 45+ messages in thread
From: Peter Maydell @ 2012-02-01 19:47 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, Andreas Faerber, qemu-devel

Subject: [PATCH 21/23] object: sure up reference counting

On 30 January 2012 21:08, Anthony Liguori <aliguori@us.ibm.com> wrote:
> Subject: [PATCH 21/23] object: sure up reference counting

"shore up", apparently, although I found that sufficiently
unlikely in this context that it might be better to reword
completely :-)

-- PMM

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

* Re: [Qemu-devel] [PATCH 22/23] container: make a decendent of Object
  2012-01-30 21:09 ` [Qemu-devel] [PATCH 22/23] container: make a decendent of Object Anthony Liguori
  2012-01-31  7:50   ` Paolo Bonzini
@ 2012-02-01 19:48   ` Peter Maydell
  1 sibling, 0 replies; 45+ messages in thread
From: Peter Maydell @ 2012-02-01 19:48 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, Andreas Faerber, qemu-devel

On 30 January 2012 21:09, Anthony Liguori <aliguori@us.ibm.com> wrote:
> Subject: [PATCH 22/23] container: make a decendent of Object

"descendant".

-- PMM

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

* Re: [Qemu-devel] [PATCH 00/23] qom: use Type system to register all devices
  2012-01-30 21:16 ` [Qemu-devel] [PATCH 00/23] qom: use Type system to register all devices Anthony Liguori
  2012-01-30 22:46   ` Anthony Liguori
@ 2012-02-01 19:55   ` Peter Maydell
  2012-02-01 20:10     ` Anthony Liguori
  1 sibling, 1 reply; 45+ messages in thread
From: Peter Maydell @ 2012-02-01 19:55 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, Andreas Faerber, qemu-devel

On 30 January 2012 21:16, Anthony Liguori <aliguori@us.ibm.com> wrote:
> Patch 8/23 is an automated touch everything patch.

It's kind of awkward having a patch series that is both long (number
of patches) and wide (patches that require touching/conversion of
every device in the tree), because the length means it needs a long
review time on the list, and the width means it's going to conflict
with lots of other changes (and especially newly arriving device
models).

-- PMM

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

* Re: [Qemu-devel] [PATCH 21/23] object: sure up reference counting
  2012-02-01 19:47   ` Peter Maydell
@ 2012-02-01 19:55     ` Anthony Liguori
  0 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-02-01 19:55 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Paolo Bonzini, Anthony Liguori, Andreas Faerber, qemu-devel

On 02/01/2012 01:47 PM, Peter Maydell wrote:
> Subject: [PATCH 21/23] object: sure up reference counting
>
> On 30 January 2012 21:08, Anthony Liguori<aliguori@us.ibm.com>  wrote:
>> Subject: [PATCH 21/23] object: sure up reference counting
>
> "shore up", apparently, although I found that sufficiently
> unlikely in this context that it might be better to reword
> completely :-)

After a few weeks of repetitive code conversion and rebasing the same series a 
million and a half times, I'm surprised I'm not speaking entirely in tongues :-)

Regards,

Anthony Liguori

>
> -- PMM
>

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

* Re: [Qemu-devel] [PATCH 09/23] qdev: kill of DeviceInfo
  2012-02-01 19:46   ` Peter Maydell
@ 2012-02-01 19:56     ` Anthony Liguori
  0 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-02-01 19:56 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Paolo Bonzini, Anthony Liguori, Andreas Faerber, qemu-devel

On 02/01/2012 01:46 PM, Peter Maydell wrote:
> On 30 January 2012 21:08, Anthony Liguori<aliguori@us.ibm.com>  wrote:
>> Subject: [PATCH 09/23] qdev: kill of DeviceInfo
>
> "kill off".

Tanks!

Regards,

Anthony Liguori

>
> -- PMM
>

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

* Re: [Qemu-devel] [PATCH 17/23] qom: move properties from qdev to object
  2012-01-31  7:46   ` Paolo Bonzini
@ 2012-02-01 20:01     ` Anthony Liguori
  2012-02-01 20:33       ` Paolo Bonzini
  0 siblings, 1 reply; 45+ messages in thread
From: Anthony Liguori @ 2012-02-01 20:01 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Peter Maydell, Anthony Liguori, Andreas Faerber, qemu-devel

On 01/31/2012 01:46 AM, Paolo Bonzini wrote:
> On 01/30/2012 10:08 PM, Anthony Liguori wrote:
>> This is mostly code movement although not entirely. This makes properties part
>> of the Object base class which means that we can now start using Object in a
>> meaningful way outside of qdev.
>
> Can we move them to an intermediate base class? I would like to use QOM
> refcounting for other objects, such as SCSIRequest, so it is important to have
> Object as a pretty light-weight class. Also (and perhaps more importantly),
> interface implementations are Objects too and they do not need properties.
>
> I cannot think of any better name than IntrospectableObject, which is quite a
> mouthful. I suppose that we could have the base class but still pass the objects
> to the function as Object * and use the OBJECT macro. Nothing of this is in a
> hot path anyway.

I'm just not sure how I feel about this.

The overhead of properties are small in terms of object size.  It's just 
sizeof(void *).

I think that read-only properties could be interesting for SCSIRequest.  For 
instance, I can imagine having SCSIRequest is-a BlockRequest and having an error 
property associated with it.  That would provide a nice way to have an info io 
operation that returned a list of failed I/O requests or something like that.

Regards,

Anthony Liguori

>
> Paolo
>

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

* Re: [Qemu-devel] [PATCH 00/23] qom: use Type system to register all devices
  2012-02-01 19:55   ` Peter Maydell
@ 2012-02-01 20:10     ` Anthony Liguori
  0 siblings, 0 replies; 45+ messages in thread
From: Anthony Liguori @ 2012-02-01 20:10 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Paolo Bonzini, Andreas Faerber, qemu-devel

On 02/01/2012 01:55 PM, Peter Maydell wrote:
> On 30 January 2012 21:16, Anthony Liguori<aliguori@us.ibm.com>  wrote:
>> Patch 8/23 is an automated touch everything patch.
>
> It's kind of awkward having a patch series that is both long (number
> of patches) and wide (patches that require touching/conversion of
> every device in the tree), because the length means it needs a long
> review time on the list, and the width means it's going to conflict
> with lots of other changes (and especially newly arriving device
> models).

I could certainly split this into three parts.

But patches 0-8 aren't terribly meaningful outside of the context of patch 9.

And patch 9 by itself leaves the old infrastructure around which means that you 
would potentially need more patches like patch 9 in a future series.

So I don't think this series could really be trimmed by anything more than a 
couple patches and I don't see a huge advantage in doing that.

This sort of changes are the exception, not the common thing.  Once this series 
is merged, things will go back to normal patch series wise.

Regards,

Anthony Liguori

>
> -- PMM
>

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

* Re: [Qemu-devel] [PATCH 17/23] qom: move properties from qdev to object
  2012-02-01 20:01     ` Anthony Liguori
@ 2012-02-01 20:33       ` Paolo Bonzini
  0 siblings, 0 replies; 45+ messages in thread
From: Paolo Bonzini @ 2012-02-01 20:33 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Peter Maydell, Anthony Liguori, Andreas Faerber, qemu-devel

On 02/01/2012 09:01 PM, Anthony Liguori wrote:
> I think that read-only properties could be interesting for SCSIRequest.
> For instance, I can imagine having SCSIRequest is-a BlockRequest and
> having an error property associated with it.  That would provide a nice
> way to have an info io operation that returned a list of failed I/O
> requests or something like that.

SCSIRequests can have a BlockRequest as a child; not all SCSIRequests 
have I/O attached to them, but I see the general concept.  I'm not sure 
we'll be able to optimize enough, but we can certainly try...

Paolo

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

end of thread, other threads:[~2012-02-01 20:33 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-30 21:08 [Qemu-devel] [PATCH 01/23] usb-hid: simplify class initialization a bit Anthony Liguori
2012-01-30 21:08 ` [Qemu-devel] [PATCH 03/23] qdev: make DeviceInfo private Anthony Liguori
2012-01-30 22:31   ` Andreas Färber
2012-01-30 21:08 ` [Qemu-devel] [PATCH 04/23] qdev: remove info from class Anthony Liguori
2012-01-30 21:08 ` [Qemu-devel] [PATCH 05/23] qdev: allow classes to overload qdev functions Anthony Liguori
2012-01-30 21:08 ` [Qemu-devel] [PATCH 06/23] qdev: refactor device creation to allow bus_info to be set only in class Anthony Liguori
2012-01-30 21:08 ` [Qemu-devel] [PATCH 07/23] qdev: kill off DeviceInfo list Anthony Liguori
2012-01-31 13:51   ` Andreas Färber
2012-01-30 21:08 ` [Qemu-devel] [PATCH 08/23] qdev: register all types natively through QEMU Object Model Anthony Liguori
2012-01-30 22:29   ` Peter Maydell
2012-01-30 22:43     ` Anthony Liguori
2012-01-30 21:08 ` [Qemu-devel] [PATCH 09/23] qdev: kill of DeviceInfo Anthony Liguori
2012-01-31 13:34   ` Andreas Färber
2012-02-01 19:46   ` Peter Maydell
2012-02-01 19:56     ` Anthony Liguori
2012-01-30 21:08 ` [Qemu-devel] [PATCH 10/23] qdev: remove baked in notion of aliases Anthony Liguori
2012-01-31  7:44   ` Paolo Bonzini
2012-01-30 21:08 ` [Qemu-devel] [PATCH 11/23] qom: allow object_class_foreach to take additional parameters to refine search Anthony Liguori
2012-01-31 13:42   ` Andreas Färber
2012-01-30 21:08 ` [Qemu-devel] [PATCH 12/23] qom: add new command to search for types Anthony Liguori
2012-01-30 21:08 ` [Qemu-devel] [PATCH 13/23] qdev: split out common init to instance_init Anthony Liguori
2012-01-30 21:08 ` [Qemu-devel] [PATCH 14/23] qdev: refactor away qdev_create_from_info Anthony Liguori
2012-01-30 21:08 ` [Qemu-devel] [PATCH 15/23] qdev: split out UI portions into a new function Anthony Liguori
2012-01-30 21:08 ` [Qemu-devel] [PATCH 16/23] qdev: nuke qdev_init_chardev() Anthony Liguori
2012-01-30 21:08 ` [Qemu-devel] [PATCH 17/23] qom: move properties from qdev to object Anthony Liguori
2012-01-31  7:46   ` Paolo Bonzini
2012-02-01 20:01     ` Anthony Liguori
2012-02-01 20:33       ` Paolo Bonzini
2012-01-30 21:08 ` [Qemu-devel] [PATCH 18/23] qom: accept any compatible type when setting a link property Anthony Liguori
2012-01-30 21:08 ` [Qemu-devel] [PATCH 19/23] qdev: implement cleanup logic in finalize Anthony Liguori
2012-01-30 21:08 ` [Qemu-devel] [PATCH 20/23] info qdm: do not require a parent_bus to be set Anthony Liguori
2012-01-30 21:08 ` [Qemu-devel] [PATCH 21/23] object: sure up reference counting Anthony Liguori
2012-01-31  7:49   ` Paolo Bonzini
2012-02-01 19:47   ` Peter Maydell
2012-02-01 19:55     ` Anthony Liguori
2012-01-30 21:09 ` [Qemu-devel] [PATCH 22/23] container: make a decendent of Object Anthony Liguori
2012-01-31  7:50   ` Paolo Bonzini
2012-01-31  9:21     ` Andreas Färber
2012-01-31  9:31       ` Paolo Bonzini
2012-02-01 19:48   ` Peter Maydell
2012-01-30 21:09 ` [Qemu-devel] [PATCH 23/23] not-for-upstream: fix device_del Anthony Liguori
2012-01-30 21:16 ` [Qemu-devel] [PATCH 00/23] qom: use Type system to register all devices Anthony Liguori
2012-01-30 22:46   ` Anthony Liguori
2012-02-01 19:55   ` Peter Maydell
2012-02-01 20:10     ` Anthony Liguori

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).