qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 18/21] qdev: convert busses to QEMU Object Model


From: Paolo Bonzini
Subject: [Qemu-devel] [PATCH 18/21] qdev: convert busses to QEMU Object Model
Date: Wed, 2 May 2012 13:31:10 +0200

From: Anthony Liguori <address@hidden>

This is far less interesting than it sounds.  We simply add an Object to each
BusState and then register the types appropriately.  Most of the interesting
refactoring will follow in the next patches.

Since we're changing fundamental type names (BusInfo -> BusClass), it all needs
to convert at once.  Fortunately, not a lot of code is affected.

Signed-off-by: Anthony Liguori <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
---
 hw/i2c.c                      |   15 ++++++----
 hw/ide/internal.h             |    3 ++
 hw/ide/qdev.c                 |   21 ++++++++++----
 hw/intel-hda.c                |   12 ++++----
 hw/intel-hda.h                |    3 ++
 hw/isa-bus.c                  |   23 ++++++++++-----
 hw/isa.h                      |    3 ++
 hw/pci-hotplug.c              |    6 +---
 hw/pci.c                      |   27 ++++++++++++------
 hw/pci_bridge.c               |    2 +-
 hw/pci_internals.h            |    3 +-
 hw/qdev-monitor.c             |   33 ++++++++++++++--------
 hw/qdev.c                     |   62 ++++++++++++++++++++++++++++++-----------
 hw/qdev.h                     |   37 ++++++++++++------------
 hw/s390-virtio-bus.c          |   12 ++++----
 hw/s390-virtio-bus.h          |    3 ++
 hw/scsi-bus.c                 |   23 ++++++++++-----
 hw/scsi.h                     |    3 ++
 hw/spapr_vio.c                |   12 ++++----
 hw/spapr_vio.h                |    3 ++
 hw/ssi.c                      |   15 ++++++----
 hw/sysbus.c                   |   27 ++++++++++++------
 hw/sysbus.h                   |    3 ++
 hw/usb.h                      |    3 ++
 hw/usb/bus.c                  |   25 +++++++++++------
 hw/usb/dev-smartcard-reader.c |   15 ++++++----
 hw/virtio-serial-bus.c        |   23 +++++++++++----
 27 files changed, 280 insertions(+), 137 deletions(-)

diff --git a/hw/i2c.c b/hw/i2c.c
index af5979e..cd8fa31 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -22,9 +22,13 @@ static Property i2c_props[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static struct BusInfo i2c_bus_info = {
-    .name = "I2C",
-    .size = sizeof(i2c_bus),
+#define TYPE_I2C_BUS "i2c-bus"
+#define I2C_BUS(obj) OBJECT_CHECK(i2c_bus, (obj), TYPE_I2C_BUS)
+
+static TypeInfo i2c_bus_info = {
+    .name = TYPE_I2C_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(i2c_bus),
 };
 
 static void i2c_bus_pre_save(void *opaque)
@@ -62,7 +66,7 @@ i2c_bus *i2c_init_bus(DeviceState *parent, const char *name)
 {
     i2c_bus *bus;
 
-    bus = FROM_QBUS(i2c_bus, qbus_create(&i2c_bus_info, parent, name));
+    bus = FROM_QBUS(i2c_bus, qbus_create(TYPE_I2C_BUS, parent, name));
     vmstate_register(NULL, -1, &vmstate_i2c_bus, bus);
     return bus;
 }
@@ -219,7 +223,7 @@ 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;
+    k->bus_type = TYPE_I2C_BUS;
     k->props = i2c_props;
 }
 
@@ -234,6 +238,7 @@ static TypeInfo i2c_slave_type_info = {
 
 static void i2c_slave_register_types(void)
 {
+    type_register_static(&i2c_bus_info);
     type_register_static(&i2c_slave_type_info);
 }
 
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index f8a027d..1a02f57 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -25,6 +25,9 @@ typedef struct IDEState IDEState;
 typedef struct IDEDMA IDEDMA;
 typedef struct IDEDMAOps IDEDMAOps;
 
+#define TYPE_IDE_BUS "IDE"
+#define IDE_BUS(obj) OBJECT_CHECK(IDEBus, (obj), TYPE_IDE_BUS)
+
 /* Bits of HD_STATUS */
 #define ERR_STAT               0x01
 #define INDEX_STAT             0x02
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index a91e878..24c3101 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -32,15 +32,23 @@ static Property ide_props[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static struct BusInfo ide_bus_info = {
-    .name  = "IDE",
-    .size  = sizeof(IDEBus),
-    .get_fw_dev_path = idebus_get_fw_dev_path,
+static void ide_bus_class_init(ObjectClass *klass, void *data)
+{
+    BusClass *k = BUS_CLASS(klass);
+
+    k->get_fw_dev_path = idebus_get_fw_dev_path;
+}
+
+static TypeInfo ide_bus_info = {
+    .name = TYPE_IDE_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(IDEBus),
+    .class_init = ide_bus_class_init,
 };
 
 void ide_bus_new(IDEBus *idebus, DeviceState *dev, int bus_id)
 {
-    qbus_create_inplace(&idebus->qbus, &ide_bus_info, dev, NULL);
+    qbus_create_inplace(&idebus->qbus, TYPE_IDE_BUS, dev, NULL);
     idebus->bus_id = bus_id;
 }
 
@@ -249,7 +257,7 @@ 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;
+    k->bus_type = TYPE_IDE_BUS;
     k->props = ide_props;
 }
 
@@ -264,6 +272,7 @@ static TypeInfo ide_device_type_info = {
 
 static void ide_register_types(void)
 {
+    type_register_static(&ide_bus_info);
     type_register_static(&ide_hd_info);
     type_register_static(&ide_cd_info);
     type_register_static(&ide_drive_info);
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index e2bd41e..63bdb27 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -34,16 +34,17 @@ static Property hda_props[] = {
     DEFINE_PROP_END_OF_LIST()
 };
 
-static struct BusInfo hda_codec_bus_info = {
-    .name      = "HDA",
-    .size      = sizeof(HDACodecBus),
+static TypeInfo hda_codec_bus_info = {
+    .name = TYPE_HDA_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(HDACodecBus),
 };
 
 void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus,
                         hda_codec_response_func response,
                         hda_codec_xfer_func xfer)
 {
-    qbus_create_inplace(&bus->qbus, &hda_codec_bus_info, dev, NULL);
+    qbus_create_inplace(&bus->qbus, TYPE_HDA_BUS, dev, NULL);
     bus->response = response;
     bus->xfer = xfer;
 }
@@ -1276,7 +1277,7 @@ 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;
+    k->bus_type = TYPE_HDA_BUS;
     k->props = hda_props;
 }
 
@@ -1291,6 +1292,7 @@ static TypeInfo hda_codec_device_type_info = {
 
 static void intel_hda_register_types(void)
 {
+    type_register_static(&hda_codec_bus_info);
     type_register_static(&intel_hda_info);
     type_register_static(&hda_codec_device_type_info);
 }
diff --git a/hw/intel-hda.h b/hw/intel-hda.h
index a1cca5b..22e0968 100644
--- a/hw/intel-hda.h
+++ b/hw/intel-hda.h
@@ -14,6 +14,9 @@
 #define HDA_CODEC_DEVICE_GET_CLASS(obj) \
      OBJECT_GET_CLASS(HDACodecDeviceClass, (obj), TYPE_HDA_CODEC_DEVICE)
 
+#define TYPE_HDA_BUS "HDA"
+#define HDA_BUS(obj) OBJECT_CHECK(HDACodecBus, (obj), TYPE_HDA_BUS)
+
 typedef struct HDACodecBus HDACodecBus;
 typedef struct HDACodecDevice HDACodecDevice;
 
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 5a43f03..89223ae 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -28,11 +28,19 @@ target_phys_addr_t isa_mem_base = 0;
 static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent);
 static char *isabus_get_fw_dev_path(DeviceState *dev);
 
-static struct BusInfo isa_bus_info = {
-    .name      = "ISA",
-    .size      = sizeof(ISABus),
-    .print_dev = isabus_dev_print,
-    .get_fw_dev_path = isabus_get_fw_dev_path,
+static void isa_bus_class_init(ObjectClass *klass, void *data)
+{
+    BusClass *k = BUS_CLASS(klass);
+
+    k->print_dev = isabus_dev_print;
+    k->get_fw_dev_path = isabus_get_fw_dev_path;
+}
+
+static TypeInfo isa_bus_info = {
+    .name = TYPE_ISA_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(ISABus),
+    .class_init = isa_bus_class_init,
 };
 
 ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io)
@@ -46,7 +54,7 @@ ISABus *isa_bus_new(DeviceState *dev, MemoryRegion 
*address_space_io)
         qdev_init_nofail(dev);
     }
 
-    isabus = FROM_QBUS(ISABus, qbus_create(&isa_bus_info, dev, NULL));
+    isabus = FROM_QBUS(ISABus, qbus_create(TYPE_ISA_BUS, dev, NULL));
     isabus->address_space_io = address_space_io;
     return isabus;
 }
@@ -198,7 +206,7 @@ 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;
+    k->bus_type = TYPE_ISA_BUS;
 }
 
 static TypeInfo isa_device_type_info = {
@@ -212,6 +220,7 @@ static TypeInfo isa_device_type_info = {
 
 static void isabus_register_types(void)
 {
+    type_register_static(&isa_bus_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 f7bc4b5..f7ddf23 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -19,6 +19,9 @@ typedef struct ISADevice ISADevice;
 #define ISA_DEVICE_GET_CLASS(obj) \
      OBJECT_GET_CLASS(ISADeviceClass, (obj), TYPE_ISA_DEVICE)
 
+#define TYPE_ISA_BUS "ISA"
+#define ISA_BUS(obj) OBJECT_CHECK(ISABus, (obj), TYPE_ISA_BUS)
+
 typedef struct ISADeviceClass {
     DeviceClass parent_class;
     int (*init)(ISADevice *dev);
diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index c55d8b9..e77fea0 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -76,11 +76,7 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
     SCSIBus *scsibus;
     SCSIDevice *scsidev;
 
-    scsibus = DO_UPCAST(SCSIBus, qbus, QLIST_FIRST(&adapter->child_bus));
-    if (!scsibus || strcmp(scsibus->qbus.info->name, "SCSI") != 0) {
-        error_report("Device is not a SCSI adapter");
-        return -1;
-    }
+    scsibus = SCSI_BUS(QLIST_FIRST(&adapter->child_bus));
 
     /*
      * drive_init() tries to find a default for dinfo->unit.  Doesn't
diff --git a/hw/pci.c b/hw/pci.c
index 6319f4d..57dea56 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -55,13 +55,21 @@ static Property pci_props[] = {
     DEFINE_PROP_END_OF_LIST()
 };
 
-struct BusInfo pci_bus_info = {
-    .name       = "PCI",
-    .size       = sizeof(PCIBus),
-    .print_dev  = pcibus_dev_print,
-    .get_dev_path = pcibus_get_dev_path,
-    .get_fw_dev_path = pcibus_get_fw_dev_path,
-    .reset      = pcibus_reset,
+static void pci_bus_class_init(ObjectClass *klass, void *data)
+{
+    BusClass *k = BUS_CLASS(klass);
+
+    k->print_dev = pcibus_dev_print;
+    k->get_dev_path = pcibus_get_dev_path;
+    k->get_fw_dev_path = pcibus_get_fw_dev_path;
+    k->reset = pcibus_reset;
+}
+
+static TypeInfo pci_bus_info = {
+    .name = TYPE_PCI_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(PCIBus),
+    .class_init = pci_bus_class_init,
 };
 
 static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
@@ -266,7 +274,7 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
                          MemoryRegion *address_space_io,
                          uint8_t devfn_min)
 {
-    qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
+    qbus_create_inplace(&bus->qbus, TYPE_PCI_BUS, parent, name);
     assert(PCI_FUNC(devfn_min) == 0);
     bus->devfn_min = devfn_min;
     bus->address_space_mem = address_space_mem;
@@ -2002,7 +2010,7 @@ static void pci_device_class_init(ObjectClass *klass, 
void *data)
     k->init = pci_qdev_init;
     k->unplug = pci_unplug_device;
     k->exit = pci_unregister_device;
-    k->bus_info = &pci_bus_info;
+    k->bus_type = TYPE_PCI_BUS;
     k->props = pci_props;
 }
 
@@ -2017,6 +2025,7 @@ static TypeInfo pci_device_type_info = {
 
 static void pci_register_types(void)
 {
+    type_register_static(&pci_bus_info);
     type_register_static(&pci_device_type_info);
 }
 
diff --git a/hw/pci_bridge.c b/hw/pci_bridge.c
index 866f0b6..253e034 100644
--- a/hw/pci_bridge.c
+++ b/hw/pci_bridge.c
@@ -324,7 +324,7 @@ int pci_bridge_initfn(PCIDevice *dev)
            br->bus_name = dev->qdev.id;
     }
 
-    qbus_create_inplace(&sec_bus->qbus, &pci_bus_info, &dev->qdev,
+    qbus_create_inplace(&sec_bus->qbus, TYPE_PCI_BUS, &dev->qdev,
                         br->bus_name);
     sec_bus->parent_dev = dev;
     sec_bus->map_irq = br->map_irq;
diff --git a/hw/pci_internals.h b/hw/pci_internals.h
index 96690b7..399c6d4 100644
--- a/hw/pci_internals.h
+++ b/hw/pci_internals.h
@@ -12,7 +12,8 @@
  * Use accessor function in pci.h, pci_bridge.h
  */
 
-extern struct BusInfo pci_bus_info;
+#define TYPE_PCI_BUS "PCI"
+#define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
 
 struct PCIBus {
     BusState qbus;
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 6f2d83e..703d895 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -75,8 +75,8 @@ static void qdev_print_devinfo(ObjectClass *klass, void 
*opaque)
     }
 
     error_printf("name \"%s\"", object_class_get_name(klass));
-    if (dc->bus_info) {
-        error_printf(", bus %s", dc->bus_info->name);
+    if (dc->bus_type) {
+        error_printf(", bus %s", dc->bus_type);
     }
     if (qdev_class_has_alias(dc)) {
         error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
@@ -262,7 +262,7 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
 }
 
 static BusState *qbus_find_recursive(BusState *bus, const char *name,
-                                     const BusInfo *info)
+                                     const char *bus_typename)
 {
     DeviceState *dev;
     BusState *child, *ret;
@@ -271,7 +271,8 @@ static BusState *qbus_find_recursive(BusState *bus, const 
char *name,
     if (name && (strcmp(bus->name, name) != 0)) {
         match = 0;
     }
-    if (info && (bus->info != info)) {
+    if (bus_typename &&
+        (strcmp(object_get_typename(OBJECT(bus)), bus_typename) != 0)) {
         match = 0;
     }
     if (match) {
@@ -280,7 +281,7 @@ static BusState *qbus_find_recursive(BusState *bus, const 
char *name,
 
     QTAILQ_FOREACH(dev, &bus->children, sibling) {
         QLIST_FOREACH(child, &dev->child_bus, sibling) {
-            ret = qbus_find_recursive(child, name, info);
+            ret = qbus_find_recursive(child, name, bus_typename);
             if (ret) {
                 return ret;
             }
@@ -415,16 +416,16 @@ DeviceState *qdev_device_add(QemuOpts *opts)
         if (!bus) {
             return NULL;
         }
-        if (bus->info != k->bus_info) {
+        if (strcmp(object_get_typename(OBJECT(bus)), k->bus_type) != 0) {
             qerror_report(QERR_BAD_BUS_FOR_DEVICE,
-                           driver, bus->info->name);
+                          driver, object_get_typename(OBJECT(bus)));
             return NULL;
         }
     } else {
-        bus = qbus_find_recursive(sysbus_get_default(), NULL, k->bus_info);
+        bus = qbus_find_recursive(sysbus_get_default(), NULL, k->bus_type);
         if (!bus) {
             qerror_report(QERR_NO_BUS_FOR_DEVICE,
-                          driver, k->bus_info->name);
+                          driver, k->bus_type);
             return NULL;
         }
     }
@@ -497,6 +498,15 @@ static void qdev_print_props(Monitor *mon, DeviceState 
*dev, Property *props,
     }
 }
 
+static void bus_print_dev(BusState *bus, Monitor *mon, DeviceState *dev, int 
indent)
+{
+    BusClass *bc = BUS_GET_CLASS(bus);
+
+    if (bc->print_dev) {
+        bc->print_dev(mon, dev, indent);
+    }
+}
+
 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
 {
     ObjectClass *class;
@@ -515,8 +525,7 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int 
indent)
         qdev_print_props(mon, dev, DEVICE_CLASS(class)->props, indent);
         class = object_class_get_parent(class);
     } while (class != object_class_by_name(TYPE_DEVICE));
-    if (dev->parent_bus->info->print_dev)
-        dev->parent_bus->info->print_dev(mon, dev, indent);
+    bus_print_dev(dev->parent_bus, mon, dev, indent + 2);
     QLIST_FOREACH(child, &dev->child_bus, sibling) {
         qbus_print(mon, child, indent);
     }
@@ -528,7 +537,7 @@ static void qbus_print(Monitor *mon, BusState *bus, int 
indent)
 
     qdev_printf("bus: %s\n", bus->name);
     indent += 2;
-    qdev_printf("type %s\n", bus->info->name);
+    qdev_printf("type %s\n", object_get_typename(OBJECT(bus)));
     QTAILQ_FOREACH(dev, &bus->children, sibling) {
         qdev_print(mon, dev, indent);
     }
diff --git a/hw/qdev.c b/hw/qdev.c
index 7816a37..b97ba00 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -81,7 +81,7 @@ DeviceState *qdev_create(BusState *bus, const char *name)
     if (!dev) {
         if (bus) {
             hw_error("Unknown device '%s' for bus '%s'\n", name,
-                     bus->info->name);
+                     object_get_typename(OBJECT(bus)));
         } else {
             hw_error("Unknown device '%s' for default sysbus\n", name);
         }
@@ -186,8 +186,9 @@ static int qdev_reset_one(DeviceState *dev, void *opaque)
 
 static int qbus_reset_one(BusState *bus, void *opaque)
 {
-    if (bus->info->reset) {
-        return bus->info->reset(bus);
+    BusClass *bc = BUS_GET_CLASS(bus);
+    if (bc->reset) {
+        return bc->reset(bus);
     }
     return 0;
 }
@@ -370,13 +371,13 @@ DeviceState *qdev_find_recursive(BusState *bus, const 
char *id)
     return NULL;
 }
 
-void qbus_create_inplace(BusState *bus, BusInfo *info,
-                         DeviceState *parent, const char *name)
+/* FIXME move this logic into instance_init */
+static void do_qbus_create_inplace(BusState *bus, const char *typename,
+                                   DeviceState *parent, const char *name)
 {
     char *buf;
     int i,len;
 
-    bus->info = info;
     bus->parent = parent;
 
     if (name) {
@@ -390,9 +391,9 @@ void qbus_create_inplace(BusState *bus, BusInfo *info,
         bus->name = buf;
     } else {
         /* no id -> use lowercase bus type for bus name */
-        len = strlen(info->name) + 16;
+        len = strlen(typename) + 16;
         buf = g_malloc(len);
-        len = snprintf(buf, len, "%s.%d", info->name,
+        len = snprintf(buf, len, "%s.%d", typename,
                        parent ? parent->num_child_bus : 0);
         for (i = 0; i < len; i++)
             buf[i] = qemu_tolower(buf[i]);
@@ -410,13 +411,20 @@ void qbus_create_inplace(BusState *bus, BusInfo *info,
     }
 }
 
-BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
+void qbus_create_inplace(BusState *bus, const char *typename,
+                         DeviceState *parent, const char *name)
+{
+    object_initialize(bus, typename);
+    do_qbus_create_inplace(bus, typename, parent, name);
+}
+
+BusState *qbus_create(const char *typename, DeviceState *parent, const char 
*name)
 {
     BusState *bus;
 
-    bus = g_malloc0(info->size);
+    bus = BUS(object_new(typename));
     bus->qdev_allocated = 1;
-    qbus_create_inplace(bus, info, parent, name);
+    do_qbus_create_inplace(bus, typename, parent, name);
     return bus;
 }
 
@@ -440,6 +448,17 @@ void qbus_free(BusState *bus)
     }
 }
 
+static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev)
+{
+    BusClass *bc = BUS_GET_CLASS(bus);
+
+    if (bc->get_fw_dev_path) {
+        return bc->get_fw_dev_path(dev);
+    }
+
+    return NULL;
+}
+
 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
 {
     int l = 0;
@@ -447,8 +466,8 @@ static int qdev_get_fw_dev_path_helper(DeviceState *dev, 
char *p, int size)
     if (dev && dev->parent_bus) {
         char *d;
         l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
-        if (dev->parent_bus->info->get_fw_dev_path) {
-            d = dev->parent_bus->info->get_fw_dev_path(dev);
+        d = bus_get_fw_dev_path(dev->parent_bus, dev);
+        if (d) {
             l += snprintf(p + l, size - l, "%s", d);
             g_free(d);
         } else {
@@ -474,15 +493,15 @@ char* qdev_get_fw_dev_path(DeviceState *dev)
 
 char *qdev_get_dev_path(DeviceState *dev)
 {
-    BusInfo *businfo;
+    BusClass *bc;
 
     if (!dev || !dev->parent_bus) {
         return NULL;
     }
 
-    businfo = dev->parent_bus->info;
-    if (businfo->get_dev_path) {
-        return businfo->get_dev_path(dev);
+    bc = BUS_GET_CLASS(dev->parent_bus);
+    if (bc->get_dev_path) {
+        return bc->get_dev_path(dev);
     }
 
     return NULL;
@@ -700,8 +719,17 @@ static TypeInfo device_type_info = {
     .class_size = sizeof(DeviceClass),
 };
 
+static TypeInfo bus_info = {
+    .name = TYPE_BUS,
+    .parent = TYPE_OBJECT,
+    .instance_size = sizeof(BusState),
+    .abstract = true,
+    .class_size = sizeof(BusClass),
+};
+
 static void qdev_register_types(void)
 {
+    type_register_static(&bus_info);
     type_register_static(&device_type_info);
 }
 
diff --git a/hw/qdev.h b/hw/qdev.h
index 2e82a2f..3c54a6f 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -17,7 +17,7 @@ typedef struct CompatProperty CompatProperty;
 
 typedef struct BusState BusState;
 
-typedef struct BusInfo BusInfo;
+typedef struct BusClass BusClass;
 
 enum DevState {
     DEV_STATE_CREATED = 1,
@@ -55,7 +55,7 @@ typedef struct DeviceClass {
     qdev_initfn init;
     qdev_event unplug;
     qdev_event exit;
-    BusInfo *bus_info;
+    const char *bus_type;
 } DeviceClass;
 
 /* This structure should not be accessed directly.  We declare it here
@@ -79,28 +79,30 @@ struct DeviceState {
     int alias_required_for_version;
 };
 
-typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent);
-typedef char *(*bus_get_dev_path)(DeviceState *dev);
 /*
  * This callback is used to create Open Firmware device path in accordance with
  * OF spec http://forthworks.com/standards/of1275.pdf. Indicidual bus bindings
  * can be found here http://playground.sun.com/1275/bindings/.
  */
-typedef char *(*bus_get_fw_dev_path)(DeviceState *dev);
-typedef int (qbus_resetfn)(BusState *bus);
 
-struct BusInfo {
-    const char *name;
-    size_t size;
-    bus_dev_printfn print_dev;
-    bus_get_dev_path get_dev_path;
-    bus_get_fw_dev_path get_fw_dev_path;
-    qbus_resetfn *reset;
+#define TYPE_BUS "bus"
+#define BUS(obj) OBJECT_CHECK(BusState, (obj), TYPE_BUS)
+#define BUS_CLASS(klass) OBJECT_CLASS_CHECK(BusClass, (klass), TYPE_BUS)
+#define BUS_GET_CLASS(obj) OBJECT_GET_CLASS(BusClass, (obj), TYPE_BUS)
+
+struct BusClass {
+    ObjectClass parent_class;
+
+    /* FIXME first arg should be BusState */
+    void (*print_dev)(Monitor *mon, DeviceState *dev, int indent);
+    char *(*get_dev_path)(DeviceState *dev);
+    char *(*get_fw_dev_path)(DeviceState *dev);
+    int (*reset)(BusState *bus);
 };
 
 struct BusState {
+    Object obj;
     DeviceState *parent;
-    BusInfo *info;
     const char *name;
     int allow_hotplug;
     int qdev_allocated;
@@ -176,9 +178,9 @@ DeviceState *qdev_find_recursive(BusState *bus, const char 
*id);
 typedef int (qbus_walkerfn)(BusState *bus, void *opaque);
 typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque);
 
-void qbus_create_inplace(BusState *bus, BusInfo *info,
+void qbus_create_inplace(BusState *bus, const char *typename,
                          DeviceState *parent, const char *name);
-BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name);
+BusState *qbus_create(const char *typename, DeviceState *parent, const char 
*name);
 /* Returns > 0 if either devfn or busfn skip walk somewhere in cursion,
  *         < 0 if either devfn or busfn terminate walk somewhere in cursion,
  *           0 otherwise. */
@@ -319,9 +321,6 @@ void error_set_from_qdev_prop_error(Error **errp, int ret, 
DeviceState *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;
-
 /**
  * @qdev_property_add_static - add a @Property to a device referencing a
  * field in a struct.
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index be1f5f1..d259050 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -45,9 +45,10 @@
 
 #define VIRTIO_EXT_CODE   0x2603
 
-struct BusInfo s390_virtio_bus_info = {
-    .name       = "s390-virtio",
-    .size       = sizeof(VirtIOS390Bus),
+static TypeInfo s390_virtio_bus_info = {
+    .name = TYPE_S390_VIRTIO_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(VirtIOS390Bus),
 };
 
 static const VirtIOBindings virtio_s390_bindings;
@@ -69,7 +70,7 @@ VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size)
 
     /* Create bus on bridge device */
 
-    _bus = qbus_create(&s390_virtio_bus_info, dev, "s390-virtio");
+    _bus = qbus_create(TYPE_S390_VIRTIO_BUS, dev, "s390-virtio");
     bus = DO_UPCAST(VirtIOS390Bus, bus, _bus);
 
     bus->dev_page = *ram_size;
@@ -432,7 +433,7 @@ static void virtio_s390_device_class_init(ObjectClass 
*klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->init = s390_virtio_busdev_init;
-    dc->bus_info = &s390_virtio_bus_info;
+    dc->bus_type = TYPE_S390_VIRTIO_BUS;
     dc->unplug = qdev_simple_unplug_cb;
 }
 
@@ -493,6 +494,7 @@ static TypeInfo s390_virtio_bridge_info = {
 
 static void s390_virtio_register_types(void)
 {
+    type_register_static(&s390_virtio_bus_info);
     type_register_static(&virtio_s390_device_info);
     type_register_static(&s390_virtio_serial);
     type_register_static(&s390_virtio_blk);
diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h
index 0e60bc0..31df679 100644
--- a/hw/s390-virtio-bus.h
+++ b/hw/s390-virtio-bus.h
@@ -49,6 +49,10 @@
 #define VIRTIO_S390_DEVICE_GET_CLASS(obj) \
      OBJECT_GET_CLASS(VirtIOS390DeviceClass, (obj), TYPE_VIRTIO_S390_DEVICE)
 
+#define TYPE_S390_VIRTIO_BUS "s390-virtio-bus"
+#define S390_VIRTIO_BUS(obj) \
+     OBJECT_CHECK(VirtIOS390Bus, (obj), TYPE_S390_VIRTIO_BUS)
+
 typedef struct VirtIOS390Device VirtIOS390Device;
 
 typedef struct VirtIOS390DeviceClass {
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 0dba3aa..004f852 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -19,11 +19,19 @@ static Property scsi_props[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static struct BusInfo scsi_bus_info = {
-    .name  = "SCSI",
-    .size  = sizeof(SCSIBus),
-    .get_dev_path = scsibus_get_dev_path,
-    .get_fw_dev_path = scsibus_get_fw_dev_path,
+static void scsi_bus_class_init(ObjectClass *klass, void *data)
+{
+    BusClass *k = BUS_CLASS(klass);
+
+    k->get_dev_path = scsibus_get_dev_path;
+    k->get_fw_dev_path = scsibus_get_fw_dev_path;
+}
+
+static TypeInfo scsi_bus_info = {
+    .name = TYPE_SCSI_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(SCSIBus),
+    .class_init = scsi_bus_class_init,
 };
 static int next_scsi_bus;
 
@@ -66,7 +74,7 @@ static void scsi_device_unit_attention_reported(SCSIDevice *s)
 /* Create a scsi bus, and attach devices to it.  */
 void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info)
 {
-    qbus_create_inplace(&bus->qbus, &scsi_bus_info, host, NULL);
+    qbus_create_inplace(&bus->qbus, TYPE_SCSI_BUS, host, NULL);
     bus->busnr = next_scsi_bus++;
     bus->info = info;
     bus->qbus.allow_hotplug = 1;
@@ -1572,7 +1580,7 @@ const VMStateDescription vmstate_scsi_device = {
 static void scsi_device_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *k = DEVICE_CLASS(klass);
-    k->bus_info = &scsi_bus_info;
+    k->bus_type = TYPE_SCSI_BUS;
     k->init     = scsi_qdev_init;
     k->unplug   = qdev_simple_unplug_cb;
     k->exit     = scsi_qdev_exit;
@@ -1590,6 +1598,7 @@ static TypeInfo scsi_device_type_info = {
 
 static void scsi_register_types(void)
 {
+    type_register_static(&scsi_bus_info);
     type_register_static(&scsi_device_type_info);
 }
 
diff --git a/hw/scsi.h b/hw/scsi.h
index 2eb66f7..76f06d4 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -136,6 +136,9 @@ struct SCSIBusInfo {
     void *(*load_request)(QEMUFile *f, SCSIRequest *req);
 };
 
+#define TYPE_SCSI_BUS "SCSI"
+#define SCSI_BUS(obj) OBJECT_CHECK(SCSIBus, (obj), TYPE_SCSI_BUS)
+
 struct SCSIBus {
     BusState qbus;
     int busnr;
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 2c9ff8b..7c5493e 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -54,9 +54,10 @@ static Property spapr_vio_props[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static struct BusInfo spapr_vio_bus_info = {
-    .name       = "spapr-vio",
-    .size       = sizeof(VIOsPAPRBus),
+static TypeInfo spapr_vio_bus_info = {
+    .name = TYPE_SPAPR_VIO_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(VIOsPAPRBus),
 };
 
 VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
@@ -730,7 +731,7 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
 
     /* Create bus on bridge device */
 
-    qbus = qbus_create(&spapr_vio_bus_info, dev, "spapr-vio");
+    qbus = qbus_create(TYPE_SPAPR_VIO_BUS, dev, "spapr-vio");
     bus = DO_UPCAST(VIOsPAPRBus, bus, qbus);
 
     /* hcall-vio */
@@ -781,7 +782,7 @@ static void vio_spapr_device_class_init(ObjectClass *klass, 
void *data)
     DeviceClass *k = DEVICE_CLASS(klass);
     k->init = spapr_vio_busdev_init;
     k->reset = spapr_vio_busdev_reset;
-    k->bus_info = &spapr_vio_bus_info;
+    k->bus_type = TYPE_SPAPR_VIO_BUS;
     k->props = spapr_vio_props;
 }
 
@@ -796,6 +797,7 @@ static TypeInfo spapr_vio_type_info = {
 
 static void spapr_vio_register_types(void)
 {
+    type_register_static(&spapr_vio_bus_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 10ab359..c449a13 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -42,6 +42,9 @@ enum VIOsPAPR_TCEAccess {
 #define VIO_SPAPR_DEVICE_GET_CLASS(obj) \
      OBJECT_GET_CLASS(VIOsPAPRDeviceClass, (obj), TYPE_VIO_SPAPR_DEVICE)
 
+#define TYPE_SPAPR_VIO_BUS "spapr-vio-bus"
+#define SPAPR_VIO_BUS(obj) OBJECT_CHECK(VIOsPAPRBus, (obj), TYPE_SPAPR_VIO_BUS)
+
 struct VIOsPAPRDevice;
 
 typedef struct VIOsPAPR_RTCE {
diff --git a/hw/ssi.c b/hw/ssi.c
index 8f2d9bc..d645691 100644
--- a/hw/ssi.c
+++ b/hw/ssi.c
@@ -16,9 +16,13 @@ struct SSIBus {
     BusState qbus;
 };
 
-static struct BusInfo ssi_bus_info = {
-    .name = "SSI",
-    .size = sizeof(SSIBus),
+#define TYPE_SSI_BUS "SSI"
+#define SSI_BUS(obj) OBJECT_CHECK(SSIBus, (obj), TYPE_SSI_BUS)
+
+static TypeInfo ssi_bus_info = {
+    .name = TYPE_SSI_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(SSIBus),
 };
 
 static int ssi_slave_init(DeviceState *dev)
@@ -40,7 +44,7 @@ static void ssi_slave_class_init(ObjectClass *klass, void 
*data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     dc->init = ssi_slave_init;
-    dc->bus_info = &ssi_bus_info;
+    dc->bus_type = TYPE_SSI_BUS;
 }
 
 static TypeInfo ssi_slave_info = {
@@ -62,7 +66,7 @@ DeviceState *ssi_create_slave(SSIBus *bus, const char *name)
 SSIBus *ssi_create_bus(DeviceState *parent, const char *name)
 {
     BusState *bus;
-    bus = qbus_create(&ssi_bus_info, parent, name);
+    bus = qbus_create(TYPE_SSI_BUS, parent, name);
     return FROM_QBUS(SSIBus, bus);
 }
 
@@ -82,6 +86,7 @@ uint32_t ssi_transfer(SSIBus *bus, uint32_t val)
 
 static void ssi_slave_register_types(void)
 {
+    type_register_static(&ssi_bus_info);
     type_register_static(&ssi_slave_info);
 }
 
diff --git a/hw/sysbus.c b/hw/sysbus.c
index fe5c421..f10a7d1 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -24,11 +24,19 @@
 static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent);
 static char *sysbus_get_fw_dev_path(DeviceState *dev);
 
-struct BusInfo system_bus_info = {
-    .name       = "System",
-    .size       = sizeof(BusState),
-    .print_dev  = sysbus_dev_print,
-    .get_fw_dev_path = sysbus_get_fw_dev_path,
+static void system_bus_class_init(ObjectClass *klass, void *data)
+{
+    BusClass *k = BUS_CLASS(klass);
+
+    k->print_dev = sysbus_dev_print;
+    k->get_fw_dev_path = sysbus_get_fw_dev_path;
+}
+
+static TypeInfo system_bus_info = {
+    .name = TYPE_SYSTEM_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(BusState),
+    .class_init = system_bus_class_init,
 };
 
 void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
@@ -244,7 +252,7 @@ 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;
+    k->bus_type = TYPE_SYSTEM_BUS;
 }
 
 static TypeInfo sysbus_device_type_info = {
@@ -263,10 +271,10 @@ static void main_system_bus_create(void)
 {
     /* assign main_system_bus before qbus_create_inplace()
      * in order to make "if (bus != sysbus_get_default())" work */
-    main_system_bus = g_malloc0(system_bus_info.size);
-    main_system_bus->qdev_allocated = 1;
-    qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
+    main_system_bus = g_malloc0(system_bus_info.instance_size);
+    qbus_create_inplace(main_system_bus, TYPE_SYSTEM_BUS, NULL,
                         "main-system-bus");
+    main_system_bus->qdev_allocated = 1;
 }
 
 BusState *sysbus_get_default(void)
@@ -279,6 +287,7 @@ BusState *sysbus_get_default(void)
 
 static void sysbus_register_types(void)
 {
+    type_register_static(&system_bus_info);
     type_register_static(&sysbus_device_type_info);
 }
 
diff --git a/hw/sysbus.h b/hw/sysbus.h
index 22555cd..acfbcfb 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -10,6 +10,9 @@
 #define QDEV_MAX_PIO 32
 #define QDEV_MAX_IRQ 512
 
+#define TYPE_SYSTEM_BUS "System"
+#define SYSTEM_BUS(obj) OBJECT_CHECK(IDEBus, (obj), TYPE_IDE_BUS)
+
 typedef struct SysBusDevice SysBusDevice;
 
 #define TYPE_SYS_BUS_DEVICE "sys-bus-device"
diff --git a/hw/usb.h b/hw/usb.h
index ae7ccda..2a56fe5 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -421,6 +421,9 @@ void musb_set_size(MUSBState *s, int epnum, int size, int 
is_tx);
 
 /* usb-bus.c */
 
+#define TYPE_USB_BUS "usb-bus"
+#define USB_BUS(obj) OBJECT_CHECK(USBBus, (obj), TYPE_USB_BUS)
+
 struct USBBus {
     BusState qbus;
     USBBusOps *ops;
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 8b08f93..4ea6ce5 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -18,12 +18,20 @@ static Property usb_props[] = {
     DEFINE_PROP_END_OF_LIST()
 };
 
-static struct BusInfo usb_bus_info = {
-    .name      = "USB",
-    .size      = sizeof(USBBus),
-    .print_dev = usb_bus_dev_print,
-    .get_dev_path = usb_get_dev_path,
-    .get_fw_dev_path = usb_get_fw_dev_path,
+static void usb_bus_class_init(ObjectClass *klass, void *data)
+{
+    BusClass *k = BUS_CLASS(klass);
+
+    k->print_dev = usb_bus_dev_print;
+    k->get_dev_path = usb_get_dev_path;
+    k->get_fw_dev_path = usb_get_fw_dev_path;
+}
+
+static TypeInfo usb_bus_info = {
+    .name = TYPE_USB_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(USBBus),
+    .class_init = usb_bus_class_init,
 };
 
 static int next_usb_bus = 0;
@@ -47,7 +55,7 @@ const VMStateDescription vmstate_usb_device = {
 
 void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host)
 {
-    qbus_create_inplace(&bus->qbus, &usb_bus_info, host, NULL);
+    qbus_create_inplace(&bus->qbus, TYPE_USB_BUS, host, NULL);
     bus->ops = ops;
     bus->busnr = next_usb_bus++;
     bus->qbus.allow_hotplug = 1; /* Yes, we can */
@@ -577,7 +585,7 @@ USBDevice *usbdevice_create(const char *cmdline)
 static void usb_device_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *k = DEVICE_CLASS(klass);
-    k->bus_info = &usb_bus_info;
+    k->bus_type = TYPE_USB_BUS;
     k->init     = usb_qdev_init;
     k->unplug   = qdev_simple_unplug_cb;
     k->exit     = usb_qdev_exit;
@@ -595,6 +603,7 @@ static TypeInfo usb_device_type_info = {
 
 static void usb_register_types(void)
 {
+    type_register_static(&usb_bus_info);
     type_register_static(&usb_device_type_info);
 }
 
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index a4ab6e5..d8a77d7 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -1060,9 +1060,13 @@ static Property ccid_props[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
-static struct BusInfo ccid_bus_info = {
-    .name = "ccid-bus",
-    .size = sizeof(CCIDBus),
+#define TYPE_CCID_BUS "ccid-bus"
+#define CCID_BUS(obj) OBJECT_CHECK(CCIDBus, (obj), TYPE_CCID_BUS)
+
+static TypeInfo ccid_bus_info = {
+    .name = TYPE_CCID_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(CCIDBus),
 };
 
 void ccid_card_send_apdu_to_guest(CCIDCardState *card,
@@ -1192,7 +1196,7 @@ static int ccid_initfn(USBDevice *dev)
 
     usb_desc_create_serial(dev);
     usb_desc_init(dev);
-    qbus_create_inplace(&s->bus.qbus, &ccid_bus_info, &dev->qdev, NULL);
+    qbus_create_inplace(&s->bus.qbus, TYPE_CCID_BUS, &dev->qdev, NULL);
     s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP);
     s->bus.qbus.allow_hotplug = 1;
     s->card = NULL;
@@ -1343,7 +1347,7 @@ static TypeInfo ccid_info = {
 static void ccid_card_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *k = DEVICE_CLASS(klass);
-    k->bus_info = &ccid_bus_info;
+    k->bus_type = TYPE_CCID_BUS;
     k->init = ccid_card_init;
     k->exit = ccid_card_exit;
     k->props = ccid_props;
@@ -1360,6 +1364,7 @@ static TypeInfo ccid_card_type_info = {
 
 static void ccid_register_types(void)
 {
+    type_register_static(&ccid_bus_info);
     type_register_static(&ccid_card_type_info);
     type_register_static(&ccid_info);
     usb_legacy_register(CCID_DEV_NAME, "ccid", NULL);
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 1d85d80..fc3f46f 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -730,10 +730,21 @@ static Property virtser_props[] = {
     DEFINE_PROP_END_OF_LIST()
 };
 
-static struct BusInfo virtser_bus_info = {
-    .name      = "virtio-serial-bus",
-    .size      = sizeof(VirtIOSerialBus),
-    .print_dev = virtser_bus_dev_print,
+#define TYPE_VIRTIO_SERIAL_BUS "virtio-serial-bus"
+#define VIRTIO_SERIAL_BUS(obj) \
+      OBJECT_CHECK(VirtIOSerialBus, (obj), TYPE_VIRTIO_SERIAL_BUS)
+
+static void virtser_bus_class_init(ObjectClass *klass, void *data)
+{
+    BusClass *k = BUS_CLASS(klass);
+    k->print_dev = virtser_bus_dev_print;
+}
+
+static TypeInfo virtser_bus_info = {
+    .name = TYPE_VIRTIO_SERIAL_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(VirtIOSerialBus),
+    .class_init = virtser_bus_class_init,
 };
 
 static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
@@ -901,7 +911,7 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, 
virtio_serial_conf *conf)
     vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
 
     /* Spawn a new virtio-serial bus on which the ports will ride as devices */
-    qbus_create_inplace(&vser->bus.qbus, &virtser_bus_info, dev, NULL);
+    qbus_create_inplace(&vser->bus.qbus, TYPE_VIRTIO_SERIAL_BUS, dev, NULL);
     vser->bus.qbus.allow_hotplug = 1;
     vser->bus.vser = vser;
     QTAILQ_INIT(&vser->ports);
@@ -977,7 +987,7 @@ 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->bus_type = TYPE_VIRTIO_SERIAL_BUS;
     k->exit = virtser_port_qdev_exit;
     k->unplug = qdev_simple_unplug_cb;
     k->props = virtser_props;
@@ -994,6 +1004,7 @@ static TypeInfo virtio_serial_port_type_info = {
 
 static void virtio_serial_register_types(void)
 {
+    type_register_static(&virtser_bus_info);
     type_register_static(&virtio_serial_port_type_info);
 }
 
-- 
1.7.9.3





reply via email to

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