All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches
@ 2012-05-02 11:30 Paolo Bonzini
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 01/21] qom: documentation addition Paolo Bonzini
                   ` (22 more replies)
  0 siblings, 23 replies; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

Here is Anthony's qbus conversion, with the qdev_add_properties changes
replaced by my bus property changes.

I left out the removal of bus methods; I'm not sure I agree with all of
them (though I may just give up :)) and anyway they can be left to 1.2.

Following Andreas's remark, I moved all TYPE_* definitions for buses
to the same file that defines the struct, and added typecasting macros.

I'm still a bit weary of putting this in this late, but I'll defer to
others on this too.

Anthony Liguori (6):
  qdev: fix adding of ptr properties
  qdev: use wrapper for qdev_get_path
  qdev: convert busses to QEMU Object Model
  qdev: connect busses with their parent devices
  qbus: make child devices links
  qbus: initialize in standard way

Paolo Bonzini (15):
  qom: documentation addition
  qom: add object_class_get_parent
  qom: add class_base_init
  qom: make Object a type
  qom: assert that public types have a non-NULL parent field
  qdev: push "type" property up to Object
  qdev: fix -device foo,?
  qdev: use object_property_print in info qtree
  qdev: move bus properties to a separate global
  qdev: do not propagate properties to subclasses
  qdev: move bus properties to abstract superclasses
  pc: add back PCI.rombar compat property
  qdev: clean up global properties
  qdev: remove qdev_prop_set_defaults
  qdev: move sysbus initialization to sysbus.c

 exec.c                        |    4 +-
 hw/acpi_piix4.c               |   10 +-
 hw/i2c.c                      |   30 +++--
 hw/ide/internal.h             |    3 +
 hw/ide/qdev.c                 |   31 +++--
 hw/intel-hda.c                |   37 ++---
 hw/intel-hda.h                |    3 +
 hw/isa-bus.c                  |   23 +++-
 hw/isa.h                      |    3 +
 hw/lsi53c895a.c               |    5 +-
 hw/pc_piix.c                  |    9 +-
 hw/pci-hotplug.c              |    6 +-
 hw/pci.c                      |   49 ++++---
 hw/pci_bridge.c               |    2 +-
 hw/pci_internals.h            |    3 +-
 hw/qdev-monitor.c             |  105 ++++++++-------
 hw/qdev-properties.c          |   62 +++------
 hw/qdev.c                     |  298 +++++++++++++++++++++++++++--------------
 hw/qdev.h                     |   56 ++++----
 hw/s390-virtio-bus.c          |   37 ++---
 hw/s390-virtio-bus.h          |    3 +
 hw/scsi-bus.c                 |   54 +++++---
 hw/scsi.h                     |    3 +
 hw/spapr_pci.c                |    7 +-
 hw/spapr_vio.c                |   49 ++++---
 hw/spapr_vio.h                |    3 +
 hw/spapr_vty.c                |    6 +-
 hw/ssi.c                      |   29 ++--
 hw/sysbus.c                   |   45 ++++++-
 hw/sysbus.h                   |    3 +
 hw/usb.h                      |    3 +
 hw/usb/bus.c                  |   45 ++++---
 hw/usb/desc.c                 |    5 +-
 hw/usb/dev-smartcard-reader.c |   25 ++--
 hw/virtio-scsi.c              |    6 +-
 hw/virtio-serial-bus.c        |   35 +++--
 include/qemu/object.h         |   27 +++-
 qom/object.c                  |  105 +++++++++++----
 savevm.c                      |   12 +-
 39 files changed, 783 insertions(+), 458 deletions(-)

-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 01/21] qom: documentation addition
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
@ 2012-05-02 11:30 ` Paolo Bonzini
  2012-05-02 11:59   ` Andreas Färber
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 02/21] qom: add object_class_get_parent Paolo Bonzini
                   ` (21 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/object.h |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/include/qemu/object.h b/include/qemu/object.h
index ca1649c..d315dfa 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -555,6 +555,12 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *klass,
  */
 const char *object_class_get_name(ObjectClass *klass);
 
+/**
+ * object_class_by_name:
+ * @typename: The QOM typename to obtain the class for.
+ *
+ * Returns: The class for @typename.
+ */
 ObjectClass *object_class_by_name(const char *typename);
 
 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 02/21] qom: add object_class_get_parent
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 01/21] qom: documentation addition Paolo Bonzini
@ 2012-05-02 11:30 ` Paolo Bonzini
  2012-05-02 12:21   ` Andreas Färber
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 03/21] qom: add class_base_init Paolo Bonzini
                   ` (20 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

This simple bit of functionality was missing and we'll need it soon,
so add it.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/object.h |    8 ++++++++
 qom/object.c          |   13 +++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/include/qemu/object.h b/include/qemu/object.h
index d315dfa..063c817 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -548,6 +548,14 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *klass,
                                        const char *typename);
 
 /**
+ * object_class_get_parent:
+ * @klass: The class to obtain the parent for.
+ *
+ * Returns: The parent for @klass.
+ */
+ObjectClass *object_class_get_parent(ObjectClass *klass);
+
+/**
  * object_class_get_name:
  * @klass: The class to obtain the QOM typename for.
  *
diff --git a/qom/object.c b/qom/object.c
index e721fc2..3e9fed7 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -545,6 +545,19 @@ ObjectClass *object_class_by_name(const char *typename)
     return type->class;
 }
 
+ObjectClass *object_class_get_parent(ObjectClass *class)
+{
+    TypeImpl *type = type_get_parent(class->type);
+
+    if (!type) {
+        return NULL;
+    }
+
+    type_initialize(type);
+
+    return type->class;
+}
+
 typedef struct OCFData
 {
     void (*fn)(ObjectClass *klass, void *opaque);
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 03/21] qom: add class_base_init
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 01/21] qom: documentation addition Paolo Bonzini
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 02/21] qom: add object_class_get_parent Paolo Bonzini
@ 2012-05-02 11:30 ` Paolo Bonzini
  2012-05-14 21:34   ` Andreas Färber
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 04/21] qom: make Object a type Paolo Bonzini
                   ` (19 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

The class_base_init TypeInfo callback was present in one of the early
QOM versions but removed (on my request...) before committing.  We
will need it soon, add it.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/object.h |   10 ++++++++--
 qom/object.c          |    9 +++++++++
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/include/qemu/object.h b/include/qemu/object.h
index 063c817..597a2f6 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -291,10 +291,15 @@ struct Object
  *   has occurred to allow a class to set its default virtual method pointers.
  *   This is also the function to use to override virtual methods from a parent
  *   class.
+ * @class_base_init: This function is called for all base classes after all
+ *   parent class initialization has occurred, but before the class itself
+ *   is initialized.  This is the function to use to undo the effects of
+ *   memcpy from the parent class to the descendents.
  * @class_finalize: This function is called during class destruction and is
  *   meant to release and dynamic parameters allocated by @class_init.
- * @class_data: Data to pass to the @class_init and @class_finalize functions.
- *   This can be useful when building dynamic classes.
+ * @class_data: Data to pass to the @class_init, @class_base_init and
+ *   @class_finalize functions.  This can be useful when building dynamic
+ *   classes.
  * @interfaces: The list of interfaces associated with this type.  This
  *   should point to a static array that's terminated with a zero filled
  *   element.
@@ -312,6 +317,7 @@ struct TypeInfo
     size_t class_size;
 
     void (*class_init)(ObjectClass *klass, void *data);
+    void (*class_base_init)(ObjectClass *klass, void *data);
     void (*class_finalize)(ObjectClass *klass, void *data);
     void *class_data;
 
diff --git a/qom/object.c b/qom/object.c
index 3e9fed7..e66d3ab 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -45,6 +45,7 @@ struct TypeImpl
     size_t instance_size;
 
     void (*class_init)(ObjectClass *klass, void *data);
+    void (*class_base_init)(ObjectClass *klass, void *data);
     void (*class_finalize)(ObjectClass *klass, void *data);
 
     void *class_data;
@@ -112,6 +113,7 @@ TypeImpl *type_register(const TypeInfo *info)
     ti->instance_size = info->instance_size;
 
     ti->class_init = info->class_init;
+    ti->class_base_init = info->class_base_init;
     ti->class_finalize = info->class_finalize;
     ti->class_data = info->class_data;
 
@@ -232,6 +234,13 @@ static void type_initialize(TypeImpl *ti)
         memcpy((void *)ti->class + sizeof(ObjectClass),
                (void *)parent->class + sizeof(ObjectClass),
                parent->class_size - sizeof(ObjectClass));
+
+        while (parent) {
+            if (parent->class_base_init) {
+                parent->class_base_init(ti->class, ti->class_data);
+            }
+            parent = type_get_parent(parent);
+        }
     }
 
     memset((void *)ti->class + class_size, 0, ti->class_size - class_size);
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 04/21] qom: make Object a type
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (2 preceding siblings ...)
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 03/21] qom: add class_base_init Paolo Bonzini
@ 2012-05-02 11:30 ` Paolo Bonzini
  2012-05-16  8:16   ` Andreas Färber
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 05/21] qom: assert that public types have a non-NULL parent field Paolo Bonzini
                   ` (18 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

Right now the base Object class has a special NULL type.  Change this so
that we will be able to add class_init and class_base_init callbacks.
To do this, remove some special casing of ObjectClass that is not really
necessary.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/object.h |    2 +-
 qom/object.c          |   59 +++++++++++++++++++++++++------------------------
 2 files changed, 31 insertions(+), 30 deletions(-)

diff --git a/include/qemu/object.h b/include/qemu/object.h
index 597a2f6..9c49d99 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -33,7 +33,7 @@ typedef struct TypeInfo TypeInfo;
 typedef struct InterfaceClass InterfaceClass;
 typedef struct InterfaceInfo InterfaceInfo;
 
-#define TYPE_OBJECT NULL
+#define TYPE_OBJECT "object"
 
 /**
  * SECTION:object.h
diff --git a/qom/object.c b/qom/object.c
index e66d3ab..88ec417 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -210,7 +210,7 @@ static void type_class_interface_init(TypeImpl *ti, InterfaceImpl *iface)
 
 static void type_initialize(TypeImpl *ti)
 {
-    size_t class_size = sizeof(ObjectClass);
+    TypeImpl *parent;
     int i;
 
     if (ti->class) {
@@ -221,30 +221,24 @@ static void type_initialize(TypeImpl *ti)
     ti->instance_size = type_object_get_size(ti);
 
     ti->class = g_malloc0(ti->class_size);
-    ti->class->type = ti;
-
-    if (type_has_parent(ti)) {
-        TypeImpl *parent = type_get_parent(ti);
 
+    parent = type_get_parent(ti);
+    if (parent) {
         type_initialize(parent);
 
-        class_size = parent->class_size;
         g_assert(parent->class_size <= ti->class_size);
+        memcpy(ti->class, parent->class, parent->class_size);
+    }
 
-        memcpy((void *)ti->class + sizeof(ObjectClass),
-               (void *)parent->class + sizeof(ObjectClass),
-               parent->class_size - sizeof(ObjectClass));
+    ti->class->type = ti;
 
-        while (parent) {
-            if (parent->class_base_init) {
-                parent->class_base_init(ti->class, ti->class_data);
-            }
-            parent = type_get_parent(parent);
+    while (parent) {
+        if (parent->class_base_init) {
+            parent->class_base_init(ti->class, ti->class_data);
         }
+        parent = type_get_parent(parent);
     }
 
-    memset((void *)ti->class + class_size, 0, ti->class_size - class_size);
-
     for (i = 0; i < ti->num_interfaces; i++) {
         type_class_interface_init(ti, &ti->interfaces[i]);
     }
@@ -467,19 +461,6 @@ Object *object_dynamic_cast(Object *obj, const char *typename)
 }
 
 
-static void register_types(void)
-{
-    static TypeInfo interface_info = {
-        .name = TYPE_INTERFACE,
-        .instance_size = sizeof(Interface),
-        .abstract = true,
-    };
-
-    type_interface = type_register_static(&interface_info);
-}
-
-type_init(register_types)
-
 Object *object_dynamic_cast_assert(Object *obj, const char *typename)
 {
     Object *inst;
@@ -1216,3 +1197,23 @@ void object_property_add_str(Object *obj, const char *name,
                         property_release_str,
                         prop, errp);
 }
+
+static void register_types(void)
+{
+    static TypeInfo interface_info = {
+        .name = TYPE_INTERFACE,
+        .instance_size = sizeof(Interface),
+        .abstract = true,
+    };
+
+    static TypeInfo object_info = {
+        .name = TYPE_OBJECT,
+        .instance_size = sizeof(Object),
+        .abstract = true,
+    };
+
+    type_interface = type_register_static(&interface_info);
+    type_register_static(&object_info);
+}
+
+type_init(register_types)
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 05/21] qom: assert that public types have a non-NULL parent field
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (3 preceding siblings ...)
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 04/21] qom: make Object a type Paolo Bonzini
@ 2012-05-02 11:30 ` Paolo Bonzini
  2012-05-02 12:35   ` Andreas Färber
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 06/21] qdev: push "type" property up to Object Paolo Bonzini
                   ` (17 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

This protects against unwanted effects of changing TYPE_OBJECT from
NULL to a string.  Suggested by Andreas Faerber.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/object.h |    1 -
 qom/object.c          |   14 ++++++++++----
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/include/qemu/object.h b/include/qemu/object.h
index 9c49d99..ec2b382 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -527,7 +527,6 @@ const char *object_get_typename(Object *obj);
  */
 Type type_register_static(const TypeInfo *info);
 
-#define type_register_static_alias(info, name) do { } while (0)
 
 /**
  * type_register:
diff --git a/qom/object.c b/qom/object.c
index 88ec417..e536ece 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -95,7 +95,7 @@ static TypeImpl *type_table_lookup(const char *name)
     return g_hash_table_lookup(type_table_get(), name);
 }
 
-TypeImpl *type_register(const TypeInfo *info)
+static TypeImpl *type_register_internal(const TypeInfo *info)
 {
     TypeImpl *ti = g_malloc0(sizeof(*ti));
 
@@ -137,6 +137,12 @@ TypeImpl *type_register(const TypeInfo *info)
     return ti;
 }
 
+TypeImpl *type_register(const TypeInfo *info)
+{
+    assert(info->parent);
+    return type_register_internal(info);
+}
+
 TypeImpl *type_register_static(const TypeInfo *info)
 {
     return type_register(info);
@@ -204,7 +210,7 @@ static void type_class_interface_init(TypeImpl *ti, InterfaceImpl *iface)
     char *name = g_strdup_printf("<%s::%s>", ti->name, iface->parent);
 
     info.name = name;
-    iface->type = type_register(&info);
+    iface->type = type_register_internal(&info);
     g_free(name);
 }
 
@@ -1212,8 +1218,8 @@ static void register_types(void)
         .abstract = true,
     };
 
-    type_interface = type_register_static(&interface_info);
-    type_register_static(&object_info);
+    type_interface = type_register_internal(&interface_info);
+    type_register_internal(&object_info);
 }
 
 type_init(register_types)
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 06/21] qdev: push "type" property up to Object
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (4 preceding siblings ...)
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 05/21] qom: assert that public types have a non-NULL parent field Paolo Bonzini
@ 2012-05-02 11:30 ` Paolo Bonzini
  2012-05-23 17:06   ` Andreas Färber
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 07/21] qdev: fix -device foo,? Paolo Bonzini
                   ` (16 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

Now that Object is a type, add an instance_init function and push
the "type" property from qdev to there.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev.c    |    6 ------
 qom/object.c |   11 +++++++++++
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 0bcde20..94fb32e 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -515,11 +515,6 @@ char* qdev_get_fw_dev_path(DeviceState *dev)
     return strdup(path);
 }
 
-static char *qdev_get_type(Object *obj, Error **errp)
-{
-    return g_strdup(object_get_typename(obj));
-}
-
 /**
  * Legacy property handling
  */
@@ -635,7 +630,6 @@ static void device_initfn(Object *obj)
         qdev_property_add_static(dev, prop, NULL);
     }
 
-    object_property_add_str(OBJECT(dev), "type", qdev_get_type, NULL, NULL);
     qdev_prop_set_defaults(dev, qdev_get_props(dev));
 }
 
diff --git a/qom/object.c b/qom/object.c
index e536ece..464fc8f 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1204,6 +1204,16 @@ void object_property_add_str(Object *obj, const char *name,
                         prop, errp);
 }
 
+static char *qdev_get_type(Object *obj, Error **errp)
+{
+    return g_strdup(object_get_typename(obj));
+}
+
+static void object_instance_init(Object *obj)
+{
+    object_property_add_str(obj, "type", qdev_get_type, NULL, NULL);
+}
+
 static void register_types(void)
 {
     static TypeInfo interface_info = {
@@ -1215,6 +1225,7 @@ static void register_types(void)
     static TypeInfo object_info = {
         .name = TYPE_OBJECT,
         .instance_size = sizeof(Object),
+        .instance_init = object_instance_init,
         .abstract = true,
     };
 
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 07/21] qdev: fix -device foo,?
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (5 preceding siblings ...)
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 06/21] qdev: push "type" property up to Object Paolo Bonzini
@ 2012-05-02 11:30 ` Paolo Bonzini
  2012-05-11 14:03   ` Andreas Färber
  2012-05-14 20:11   ` Anthony Liguori
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 08/21] qdev: use object_property_print in info qtree Paolo Bonzini
                   ` (15 subsequent siblings)
  22 siblings, 2 replies; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

Since most property types do not have a parse property now, this was
broken.  Fix it by looking at the setter instead.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev-monitor.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index dc4e4e1..41b9e2c 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -158,7 +158,7 @@ int qdev_device_help(QemuOpts *opts)
          * for removal.  This conditional should be removed along with
          * it.
          */
-        if (!prop->info->parse) {
+        if (!prop->info->set) {
             continue;           /* no way to set it, don't show */
         }
         error_printf("%s.%s=%s\n", driver, prop->name,
@@ -166,7 +166,7 @@ int qdev_device_help(QemuOpts *opts)
     }
     if (info->bus_info) {
         for (prop = info->bus_info->props; prop && prop->name; prop++) {
-            if (!prop->info->parse) {
+            if (!prop->info->set) {
                 continue;           /* no way to set it, don't show */
             }
             error_printf("%s.%s=%s\n", driver, prop->name,
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 08/21] qdev: use object_property_print in info qtree
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (6 preceding siblings ...)
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 07/21] qdev: fix -device foo,? Paolo Bonzini
@ 2012-05-02 11:31 ` Paolo Bonzini
  2012-05-11 14:20   ` Andreas Färber
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 09/21] qdev: move bus properties to a separate global Paolo Bonzini
                   ` (14 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

Otherwise, non-string properties without a legacy counterpart are missed.
Also fix error propagation in object_property_print itself.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev-monitor.c |    2 +-
 qom/object.c      |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 41b9e2c..eed781d 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -493,7 +493,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
         if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
             value = object_property_get_str(OBJECT(dev), legacy_name, &err);
         } else {
-            value = object_property_get_str(OBJECT(dev), props->name, &err);
+            value = object_property_print(OBJECT(dev), props->name, &err);
         }
         g_free(legacy_name);
 
diff --git a/qom/object.c b/qom/object.c
index 464fc8f..b4f6c1d 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -839,7 +839,7 @@ char *object_property_print(Object *obj, const char *name,
     char *string;
 
     mo = string_output_visitor_new();
-    object_property_get(obj, string_output_get_visitor(mo), name, NULL);
+    object_property_get(obj, string_output_get_visitor(mo), name, errp);
     string = string_output_get_string(mo);
     string_output_visitor_cleanup(mo);
     return string;
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 09/21] qdev: move bus properties to a separate global
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (7 preceding siblings ...)
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 08/21] qdev: use object_property_print in info qtree Paolo Bonzini
@ 2012-05-02 11:31 ` Paolo Bonzini
  2012-05-23 23:39   ` Andreas Färber
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 10/21] qdev: do not propagate properties to subclasses Paolo Bonzini
                   ` (13 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

Simple code movement in order to simplify future refactoring.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/i2c.c                      |   10 ++++++----
 hw/ide/qdev.c                 |   10 ++++++----
 hw/intel-hda.c                |   10 ++++++----
 hw/pci.c                      |   22 ++++++++++++----------
 hw/scsi-bus.c                 |   14 ++++++++------
 hw/spapr_vio.c                |   10 ++++++----
 hw/usb/bus.c                  |   15 +++++++++------
 hw/usb/dev-smartcard-reader.c |   10 ++++++----
 hw/virtio-serial-bus.c        |   12 +++++++-----
 9 files changed, 66 insertions(+), 47 deletions(-)

diff --git a/hw/i2c.c b/hw/i2c.c
index 23dfccb..cb10b1d 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -17,13 +17,15 @@ struct i2c_bus
     uint8_t saved_address;
 };
 
+static Property i2c_props[] = {
+    DEFINE_PROP_UINT8("address", struct I2CSlave, address, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static struct BusInfo i2c_bus_info = {
     .name = "I2C",
     .size = sizeof(i2c_bus),
-    .props = (Property[]) {
-        DEFINE_PROP_UINT8("address", struct I2CSlave, address, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+    .props = i2c_props,
 };
 
 static void i2c_bus_pre_save(void *opaque)
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index a46578d..b67df3d 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -27,14 +27,16 @@
 
 static char *idebus_get_fw_dev_path(DeviceState *dev);
 
+static Property ide_props[] = {
+    DEFINE_PROP_UINT32("unit", IDEDevice, unit, -1),
+    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,
-    .props = (Property[]) {
-        DEFINE_PROP_UINT32("unit", IDEDevice, unit, -1),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+    .props = ide_props,
 };
 
 void ide_bus_new(IDEBus *idebus, DeviceState *dev, int bus_id)
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index bb11af2..0994f6b 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -29,13 +29,15 @@
 /* --------------------------------------------------------------------- */
 /* hda bus                                                               */
 
+static Property hda_props[] = {
+    DEFINE_PROP_UINT32("cad", HDACodecDevice, cad, -1),
+    DEFINE_PROP_END_OF_LIST()
+};
+
 static struct BusInfo hda_codec_bus_info = {
     .name      = "HDA",
     .size      = sizeof(HDACodecBus),
-    .props     = (Property[]) {
-        DEFINE_PROP_UINT32("cad", HDACodecDevice, cad, -1),
-        DEFINE_PROP_END_OF_LIST()
-    }
+    .props     = hda_props,
 };
 
 void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus,
diff --git a/hw/pci.c b/hw/pci.c
index b706e69..403651f 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -44,6 +44,17 @@ static char *pcibus_get_dev_path(DeviceState *dev);
 static char *pcibus_get_fw_dev_path(DeviceState *dev);
 static int pcibus_reset(BusState *qbus);
 
+static Property pci_props[] = {
+    DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
+    DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
+    DEFINE_PROP_UINT32("rombar",  PCIDevice, rom_bar, 1),
+    DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present,
+                    QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false),
+    DEFINE_PROP_BIT("command_serr_enable", PCIDevice, cap_present,
+                    QEMU_PCI_CAP_SERR_BITNR, true),
+    DEFINE_PROP_END_OF_LIST()
+};
+
 struct BusInfo pci_bus_info = {
     .name       = "PCI",
     .size       = sizeof(PCIBus),
@@ -51,16 +62,7 @@ struct BusInfo pci_bus_info = {
     .get_dev_path = pcibus_get_dev_path,
     .get_fw_dev_path = pcibus_get_fw_dev_path,
     .reset      = pcibus_reset,
-    .props      = (Property[]) {
-        DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
-        DEFINE_PROP_STRING("romfile", PCIDevice, romfile),
-        DEFINE_PROP_UINT32("rombar",  PCIDevice, rom_bar, 1),
-        DEFINE_PROP_BIT("multifunction", PCIDevice, cap_present,
-                        QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false),
-        DEFINE_PROP_BIT("command_serr_enable", PCIDevice, cap_present,
-                        QEMU_PCI_CAP_SERR_BITNR, true),
-        DEFINE_PROP_END_OF_LIST()
-    }
+    .props      = pci_props,
 };
 
 static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index dbdb99c..7f9eb53 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -12,17 +12,19 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev);
 static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
 static void scsi_req_dequeue(SCSIRequest *req);
 
+static Property scsi_props[] = {
+    DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0),
+    DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1),
+    DEFINE_PROP_UINT32("lun", SCSIDevice, lun, -1),
+    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,
-    .props = (Property[]) {
-        DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0),
-        DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1),
-        DEFINE_PROP_UINT32("lun", SCSIDevice, lun, -1),
-        DEFINE_PROP_END_OF_LIST(),
-    },
+    .props = scsi_props,
 };
 static int next_scsi_bus;
 
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index fccf48b..cd7a9a3 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -49,13 +49,15 @@
     do { } while (0)
 #endif
 
+static Property spapr_vio_props[] = {
+    DEFINE_PROP_UINT32("irq", VIOsPAPRDevice, vio_irq_num, 0), \
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static struct BusInfo spapr_vio_bus_info = {
     .name       = "spapr-vio",
     .size       = sizeof(VIOsPAPRBus),
-    .props = (Property[]) {
-        DEFINE_PROP_UINT32("irq", VIOsPAPRDevice, vio_irq_num, 0), \
-        DEFINE_PROP_END_OF_LIST(),
-    },
+    .props      = spapr_vio_props,
 };
 
 VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 2068640..3faf4cb 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -11,19 +11,22 @@ static char *usb_get_dev_path(DeviceState *dev);
 static char *usb_get_fw_dev_path(DeviceState *qdev);
 static int usb_qdev_exit(DeviceState *qdev);
 
+static Property usb_props[] = {
+    DEFINE_PROP_STRING("port", USBDevice, port_path),
+    DEFINE_PROP_BIT("full-path", USBDevice, flags,
+                    USB_DEV_FLAG_FULL_PATH, true),
+    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,
-    .props      = (Property[]) {
-        DEFINE_PROP_STRING("port", USBDevice, port_path),
-        DEFINE_PROP_BIT("full-path", USBDevice, flags,
-                        USB_DEV_FLAG_FULL_PATH, true),
-        DEFINE_PROP_END_OF_LIST()
-    },
+    .props     = usb_props,
 };
+
 static int next_usb_bus = 0;
 static QTAILQ_HEAD(, USBBus) busses = QTAILQ_HEAD_INITIALIZER(busses);
 
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index 3b7604e..357b7e8 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -1055,13 +1055,15 @@ static Answer *ccid_peek_next_answer(USBCCIDState *s)
         : &s->pending_answers[s->pending_answers_start % PENDING_ANSWERS_NUM];
 }
 
+static Property ccid_props[] = {
+    DEFINE_PROP_UINT32("slot", struct CCIDCardState, slot, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static struct BusInfo ccid_bus_info = {
     .name = "ccid-bus",
     .size = sizeof(CCIDBus),
-    .props = (Property[]) {
-        DEFINE_PROP_UINT32("slot", struct CCIDCardState, slot, 0),
-        DEFINE_PROP_END_OF_LIST(),
-    }
+    .props = ccid_props,
 };
 
 void ccid_card_send_apdu_to_guest(CCIDCardState *card,
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index ffbdfc2..004f443 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -724,15 +724,17 @@ static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
 
 static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
 
+static Property virtser_props[] = {
+    DEFINE_PROP_UINT32("nr", VirtIOSerialPort, id, VIRTIO_CONSOLE_BAD_ID),
+    DEFINE_PROP_STRING("name", VirtIOSerialPort, name),
+    DEFINE_PROP_END_OF_LIST()
+};
+
 static struct BusInfo virtser_bus_info = {
     .name      = "virtio-serial-bus",
     .size      = sizeof(VirtIOSerialBus),
     .print_dev = virtser_bus_dev_print,
-    .props      = (Property[]) {
-        DEFINE_PROP_UINT32("nr", VirtIOSerialPort, id, VIRTIO_CONSOLE_BAD_ID),
-        DEFINE_PROP_STRING("name", VirtIOSerialPort, name),
-        DEFINE_PROP_END_OF_LIST()
-    }
+    .props     = virtser_props,
 };
 
 static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 10/21] qdev: do not propagate properties to subclasses
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (8 preceding siblings ...)
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 09/21] qdev: move bus properties to a separate global Paolo Bonzini
@ 2012-05-02 11:31 ` Paolo Bonzini
  2012-05-23 23:46   ` Andreas Färber
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 11/21] qdev: move bus properties to abstract superclasses Paolo Bonzini
                   ` (12 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

As soon as we'll look up properties along the inheritance chain, we
will have duplicates if class A defines some properties and its
subclass B does not define any, because class_b->props will be
left equal to class_a->props.

The solution here is to reintroduce the class_base_init TypeInfo
callback, that was present in one of the early QOM versions but
removed (on my request...) before committing.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/hw/qdev.c b/hw/qdev.c
index 94fb32e..67d7770 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -658,6 +658,16 @@ static void device_finalize(Object *obj)
     QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
 }
 
+static void device_class_base_init(ObjectClass *class, void *data)
+{
+    DeviceClass *klass = DEVICE_CLASS(class);
+
+    /* We explicitly look up properties in the superclasses,
+     * so do not propagate them to the subclasses.
+     */
+    klass->props = NULL;
+}
+
 void device_reset(DeviceState *dev)
 {
     DeviceClass *klass = DEVICE_GET_CLASS(dev);
@@ -684,6 +694,7 @@ static TypeInfo device_type_info = {
     .instance_size = sizeof(DeviceState),
     .instance_init = device_initfn,
     .instance_finalize = device_finalize,
+    .class_base_init = device_class_base_init,
     .abstract = true,
     .class_size = sizeof(DeviceClass),
 };
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 11/21] qdev: move bus properties to abstract superclasses
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (9 preceding siblings ...)
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 10/21] qdev: do not propagate properties to subclasses Paolo Bonzini
@ 2012-05-02 11:31 ` Paolo Bonzini
  2012-05-02 12:29   ` Anthony Liguori
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 12/21] pc: add back PCI.rombar compat property Paolo Bonzini
                   ` (11 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

In qdev, each bus in practice identified an abstract superclass, but
this was mostly hidden.  In QOM, instead, these abstract classes are
explicit so we can move bus properties there.

All bus property walks are removed, and all device property walks
are changed to look along the class hierarchy instead.

This breaks global bus properties, an obscure feature when used
with the command-line which is actually useful and used when used by
backwards-compatible machine types.  So this patch also adjust the
global bus properties in hw/pc_piix.c to refer to the abstract class.

Globals and other properties must be modified in the same patch to
avoid complications related to initialization ordering.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/i2c.c                      |    2 +-
 hw/ide/qdev.c                 |    2 +-
 hw/intel-hda.c                |    2 +-
 hw/pc_piix.c                  |    5 +++--
 hw/pci.c                      |    2 +-
 hw/qdev-monitor.c             |   41 ++++++++++++++++++-----------------------
 hw/qdev-properties.c          |   40 ++++++++++++++++++++++------------------
 hw/qdev.c                     |   36 ++++++++++--------------------------
 hw/qdev.h                     |    5 -----
 hw/scsi-bus.c                 |    2 +-
 hw/spapr_vio.c                |    2 +-
 hw/usb/bus.c                  |    2 +-
 hw/usb/dev-smartcard-reader.c |    2 +-
 hw/virtio-serial-bus.c        |    2 +-
 14 files changed, 62 insertions(+), 83 deletions(-)

diff --git a/hw/i2c.c b/hw/i2c.c
index cb10b1d..af5979e 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -25,7 +25,6 @@ static Property i2c_props[] = {
 static struct BusInfo i2c_bus_info = {
     .name = "I2C",
     .size = sizeof(i2c_bus),
-    .props = i2c_props,
 };
 
 static void i2c_bus_pre_save(void *opaque)
@@ -221,6 +220,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->props = i2c_props;
 }
 
 static TypeInfo i2c_slave_type_info = {
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index b67df3d..a91e878 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -36,7 +36,6 @@ static struct BusInfo ide_bus_info = {
     .name  = "IDE",
     .size  = sizeof(IDEBus),
     .get_fw_dev_path = idebus_get_fw_dev_path,
-    .props = ide_props,
 };
 
 void ide_bus_new(IDEBus *idebus, DeviceState *dev, int bus_id)
@@ -251,6 +250,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->props = ide_props;
 }
 
 static TypeInfo ide_device_type_info = {
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 0994f6b..e2bd41e 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -37,7 +37,6 @@ static Property hda_props[] = {
 static struct BusInfo hda_codec_bus_info = {
     .name      = "HDA",
     .size      = sizeof(HDACodecBus),
-    .props     = hda_props,
 };
 
 void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus,
@@ -1278,6 +1277,7 @@ static void hda_codec_device_class_init(ObjectClass *klass, void *data)
     k->init = hda_codec_dev_init;
     k->exit = hda_codec_dev_exit;
     k->bus_info = &hda_codec_bus_info;
+    k->props = hda_props;
 }
 
 static TypeInfo hda_codec_device_type_info = {
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 6a75718..ef6afb1 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -29,6 +29,7 @@
 #include "apic.h"
 #include "pci.h"
 #include "pci_ids.h"
+#include "usb.h"
 #include "net.h"
 #include "boards.h"
 #include "ide.h"
@@ -378,7 +379,7 @@ static QEMUMachine pc_machine_v1_1 = {
             .property = "vapic",\
             .value    = "off",\
         },{\
-            .driver   = "USB",\
+            .driver   = TYPE_USB_DEVICE,\
             .property = "full-path",\
             .value    = "no",\
         }
@@ -451,7 +452,7 @@ static QEMUMachine pc_machine_v0_14 = {
 #define PC_COMPAT_0_13 \
         PC_COMPAT_0_14,\
         {\
-            .driver   = "PCI",\
+            .driver   = TYPE_PCI_DEVICE,\
             .property = "command_serr_enable",\
             .value    = "off",\
         },{\
diff --git a/hw/pci.c b/hw/pci.c
index 403651f..6319f4d 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -62,7 +62,6 @@ struct BusInfo pci_bus_info = {
     .get_dev_path = pcibus_get_dev_path,
     .get_fw_dev_path = pcibus_get_fw_dev_path,
     .reset      = pcibus_reset,
-    .props      = pci_props,
 };
 
 static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
@@ -2004,6 +2003,7 @@ static void pci_device_class_init(ObjectClass *klass, void *data)
     k->unplug = pci_unplug_device;
     k->exit = pci_unregister_device;
     k->bus_info = &pci_bus_info;
+    k->props = pci_props;
 }
 
 static TypeInfo pci_device_type_info = {
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index eed781d..d9c6adc 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -123,7 +123,6 @@ 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, "?")) {
@@ -149,30 +148,22 @@ int qdev_device_help(QemuOpts *opts)
     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->set) {
-            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);
-    }
-    if (info->bus_info) {
-        for (prop = info->bus_info->props; prop && prop->name; prop++) {
+    do {
+        for (prop = DEVICE_CLASS(klass)->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->set) {
                 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);
         }
-    }
+        klass = object_class_get_parent(klass);
+    } while (klass != object_class_by_name(TYPE_DEVICE));
     return 1;
 }
 
@@ -482,7 +473,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
 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)
+                             int indent)
 {
     if (!props)
         return;
@@ -501,7 +492,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
             error_free(err);
             continue;
         }
-        qdev_printf("%s-prop: %s = %s\n", prefix, props->name,
+        qdev_printf("%s = %s\n", props->name,
                     value && *value ? value : "<null>");
         g_free(value);
     }
@@ -509,6 +500,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
 
 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
 {
+    ObjectClass *class;
     BusState *child;
     qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
                 dev->id ? dev->id : "");
@@ -519,8 +511,11 @@ 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_props(dev), "dev", indent);
-    qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
+    class = object_get_class(OBJECT(dev));
+    do {
+        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);
     QLIST_FOREACH(child, &dev->child_bus, sibling) {
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 98dd06a..572b83c 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -939,17 +939,18 @@ static Property *qdev_prop_walk(Property *props, const char *name)
 
 static Property *qdev_prop_find(DeviceState *dev, const char *name)
 {
+    ObjectClass *class;
     Property *prop;
 
     /* device properties */
-    prop = qdev_prop_walk(qdev_get_props(dev), name);
-    if (prop)
-        return prop;
-
-    /* bus properties */
-    prop = qdev_prop_walk(dev->parent_bus->info->props, name);
-    if (prop)
-        return prop;
+    class = object_get_class(OBJECT(dev));
+    do {
+        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
+        if (prop) {
+            return prop;
+        }
+        class = object_class_get_parent(class);
+    } while (class != object_class_by_name(TYPE_DEVICE));
 
     return NULL;
 }
@@ -1169,17 +1170,20 @@ void qdev_prop_register_global_list(GlobalProperty *props)
 
 void qdev_prop_set_globals(DeviceState *dev)
 {
-    GlobalProperty *prop;
-
-    QTAILQ_FOREACH(prop, &global_props, next) {
-        if (strcmp(object_get_typename(OBJECT(dev)), prop->driver) != 0 &&
-            strcmp(qdev_get_bus_info(dev)->name, prop->driver) != 0) {
-            continue;
-        }
-        if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
-            exit(1);
+    ObjectClass *class = object_get_class(OBJECT(dev));
+
+    do {
+        GlobalProperty *prop;
+        QTAILQ_FOREACH(prop, &global_props, next) {
+            if (strcmp(object_class_get_name(class), prop->driver) != 0) {
+                continue;
+            }
+            if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
+                exit(1);
+            }
         }
-    }
+        class = object_class_get_parent(class);
+    } while (class);
 }
 
 static int qdev_add_one_global(QemuOpts *opts, void *opaque)
diff --git a/hw/qdev.c b/hw/qdev.c
index 67d7770..98efc8b 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -45,18 +45,6 @@ const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
     return dc->vmsd;
 }
 
-BusInfo *qdev_get_bus_info(DeviceState *dev)
-{
-    DeviceClass *dc = DEVICE_GET_CLASS(dev);
-    return dc->bus_info;
-}
-
-Property *qdev_get_props(DeviceState *dev)
-{
-    DeviceClass *dc = DEVICE_GET_CLASS(dev);
-    return dc->props;
-}
-
 const char *qdev_fw_name(DeviceState *dev)
 {
     DeviceClass *dc = DEVICE_GET_CLASS(dev);
@@ -78,20 +66,12 @@ static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
 
 void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
 {
-    Property *prop;
-
     if (qdev_hotplug) {
         assert(bus->allow_hotplug);
     }
 
     dev->parent_bus = bus;
     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_prop_set_defaults(dev, dev->parent_bus->info->props);
 }
 
 /* Create a new device.  This only initializes the device state structure
@@ -615,6 +595,7 @@ void qdev_property_add_static(DeviceState *dev, Property *prop,
 static void device_initfn(Object *obj)
 {
     DeviceState *dev = DEVICE(obj);
+    ObjectClass *class;
     Property *prop;
 
     if (qdev_hotplug) {
@@ -625,12 +606,15 @@ static void device_initfn(Object *obj)
     dev->instance_id_alias = -1;
     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);
-    }
-
-    qdev_prop_set_defaults(dev, qdev_get_props(dev));
+    class = object_get_class(OBJECT(dev));
+    do {
+        for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
+            qdev_property_add_legacy(dev, prop, NULL);
+            qdev_property_add_static(dev, prop, NULL);
+        }
+        qdev_prop_set_defaults(dev, DEVICE_CLASS(class)->props);
+        class = object_class_get_parent(class);
+    } while (class != object_class_by_name(TYPE_DEVICE));
 }
 
 /* Unlink device from bus and free the structure.  */
diff --git a/hw/qdev.h b/hw/qdev.h
index 4e90119..4d6458f 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -96,7 +96,6 @@ struct BusInfo {
     bus_get_dev_path get_dev_path;
     bus_get_fw_dev_path get_fw_dev_path;
     qbus_resetfn *reset;
-    Property *props;
 };
 
 struct BusState {
@@ -349,10 +348,6 @@ 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);
-
 Object *qdev_get_machine(void);
 
 /* FIXME: make this a link<> */
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 7f9eb53..d7054da 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -24,7 +24,6 @@ static struct BusInfo scsi_bus_info = {
     .size  = sizeof(SCSIBus),
     .get_dev_path = scsibus_get_dev_path,
     .get_fw_dev_path = scsibus_get_fw_dev_path,
-    .props = scsi_props,
 };
 static int next_scsi_bus;
 
@@ -1579,6 +1578,7 @@ static void scsi_device_class_init(ObjectClass *klass, void *data)
     k->init     = scsi_qdev_init;
     k->unplug   = qdev_simple_unplug_cb;
     k->exit     = scsi_qdev_exit;
+    k->props    = scsi_props;
 }
 
 static TypeInfo scsi_device_type_info = {
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index cd7a9a3..2c9ff8b 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -57,7 +57,6 @@ static Property spapr_vio_props[] = {
 static struct BusInfo spapr_vio_bus_info = {
     .name       = "spapr-vio",
     .size       = sizeof(VIOsPAPRBus),
-    .props      = spapr_vio_props,
 };
 
 VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
@@ -783,6 +782,7 @@ static void vio_spapr_device_class_init(ObjectClass *klass, void *data)
     k->init = spapr_vio_busdev_init;
     k->reset = spapr_vio_busdev_reset;
     k->bus_info = &spapr_vio_bus_info;
+    k->props = spapr_vio_props;
 }
 
 static TypeInfo spapr_vio_type_info = {
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 3faf4cb..64887d5 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -24,7 +24,6 @@ static struct BusInfo usb_bus_info = {
     .print_dev = usb_bus_dev_print,
     .get_dev_path = usb_get_dev_path,
     .get_fw_dev_path = usb_get_fw_dev_path,
-    .props     = usb_props,
 };
 
 static int next_usb_bus = 0;
@@ -583,6 +582,7 @@ static void usb_device_class_init(ObjectClass *klass, void *data)
     k->init     = usb_qdev_init;
     k->unplug   = qdev_simple_unplug_cb;
     k->exit     = usb_qdev_exit;
+    k->props    = usb_props;
 }
 
 static TypeInfo usb_device_type_info = {
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index 357b7e8..a4ab6e5 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -1063,7 +1063,6 @@ static Property ccid_props[] = {
 static struct BusInfo ccid_bus_info = {
     .name = "ccid-bus",
     .size = sizeof(CCIDBus),
-    .props = ccid_props,
 };
 
 void ccid_card_send_apdu_to_guest(CCIDCardState *card,
@@ -1347,6 +1346,7 @@ static void ccid_card_class_init(ObjectClass *klass, void *data)
     k->bus_info = &ccid_bus_info;
     k->init = ccid_card_init;
     k->exit = ccid_card_exit;
+    k->props = ccid_props;
 }
 
 static TypeInfo ccid_card_type_info = {
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 004f443..1d85d80 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -734,7 +734,6 @@ static struct BusInfo virtser_bus_info = {
     .name      = "virtio-serial-bus",
     .size      = sizeof(VirtIOSerialBus),
     .print_dev = virtser_bus_dev_print,
-    .props     = virtser_props,
 };
 
 static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
@@ -981,6 +980,7 @@ static void virtio_serial_port_class_init(ObjectClass *klass, void *data)
     k->bus_info = &virtser_bus_info;
     k->exit = virtser_port_qdev_exit;
     k->unplug = qdev_simple_unplug_cb;
+    k->props = virtser_props;
 }
 
 static TypeInfo virtio_serial_port_type_info = {
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 12/21] pc: add back PCI.rombar compat property
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (10 preceding siblings ...)
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 11/21] qdev: move bus properties to abstract superclasses Paolo Bonzini
@ 2012-05-02 11:31 ` Paolo Bonzini
  2012-05-02 11:38   ` Michael S. Tsirkin
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 13/21] qdev: clean up global properties Paolo Bonzini
                   ` (10 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, Michael S. Tsirkin, liwp, afaerber

This was erroneously dropped in d6c730086cbf24382eb8cff25551798769edfd84.

Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/pc_piix.c |    4 ++++
 1 file changed, 4 insertions(+)

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index ef6afb1..15a62ef 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -523,6 +523,10 @@ static QEMUMachine pc_machine_v0_12 = {
             .driver   = "virtio-blk-pci",\
             .property = "vectors",\
             .value    = stringify(0),\
+        },{\
+            .driver   = TYPE_PCI_DEVICE,\
+            .property = "rombar",\
+            .value    = stringify(0),\
         }
 
 static QEMUMachine pc_machine_v0_11 = {
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 13/21] qdev: clean up global properties
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (11 preceding siblings ...)
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 12/21] pc: add back PCI.rombar compat property Paolo Bonzini
@ 2012-05-02 11:31 ` Paolo Bonzini
  2012-05-24 16:27   ` Andreas Färber
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 14/21] qdev: remove qdev_prop_set_defaults Paolo Bonzini
                   ` (9 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

Now that global properties do not depend on buses anymore, set
them directly in the device instance_init function.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev-monitor.c |    1 -
 hw/qdev.c         |    2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index d9c6adc..6f2d83e 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -440,7 +440,6 @@ DeviceState *qdev_device_add(QemuOpts *opts)
     /* 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) {
diff --git a/hw/qdev.c b/hw/qdev.c
index 98efc8b..7288b8e 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -111,7 +111,6 @@ DeviceState *qdev_try_create(BusState *bus, const char *type)
     }
 
     qdev_set_parent_bus(dev, bus);
-    qdev_prop_set_globals(dev);
 
     return dev;
 }
@@ -615,6 +614,7 @@ static void device_initfn(Object *obj)
         qdev_prop_set_defaults(dev, DEVICE_CLASS(class)->props);
         class = object_class_get_parent(class);
     } while (class != object_class_by_name(TYPE_DEVICE));
+    qdev_prop_set_globals(dev);
 }
 
 /* Unlink device from bus and free the structure.  */
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 14/21] qdev: remove qdev_prop_set_defaults
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (12 preceding siblings ...)
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 13/21] qdev: clean up global properties Paolo Bonzini
@ 2012-05-02 11:31 ` Paolo Bonzini
  2012-05-02 12:30   ` Anthony Liguori
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 15/21] qdev: fix adding of ptr properties Paolo Bonzini
                   ` (8 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

Instead, qdev_property_add_static can set the default.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev-properties.c |   22 ----------------------
 hw/qdev.c            |   26 +++++++++++++++++++++++---
 hw/qdev.h            |    1 -
 3 files changed, 23 insertions(+), 26 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 572b83c..244646c 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -1130,28 +1130,6 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
     *ptr = value;
 }
 
-void qdev_prop_set_defaults(DeviceState *dev, Property *props)
-{
-    Object *obj = OBJECT(dev);
-    if (!props)
-        return;
-    for (; props->name; props++) {
-        Error *errp = NULL;
-        if (props->qtype == QTYPE_NONE) {
-            continue;
-        }
-        if (props->qtype == QTYPE_QBOOL) {
-            object_property_set_bool(obj, props->defval, props->name, &errp);
-        } else if (props->info->enum_table) {
-            object_property_set_str(obj, props->info->enum_table[props->defval],
-                                    props->name, &errp);
-        } else if (props->qtype == QTYPE_QINT) {
-            object_property_set_int(obj, props->defval, props->name, &errp);
-        }
-        assert_no_error(errp);
-    }
-}
-
 static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
 
 static void qdev_prop_register_global(GlobalProperty *prop)
diff --git a/hw/qdev.c b/hw/qdev.c
index 7288b8e..f953c51 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -576,6 +576,9 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
 void qdev_property_add_static(DeviceState *dev, Property *prop,
                               Error **errp)
 {
+    Error *local_err = NULL;
+    Object *obj = OBJECT(dev);
+
     /*
      * TODO qdev_prop_ptr does not have getters or setters.  It must
      * go now that it can be replaced with links.  The test should be
@@ -585,10 +588,28 @@ void qdev_property_add_static(DeviceState *dev, Property *prop,
         return;
     }
 
-    object_property_add(OBJECT(dev), prop->name, prop->info->name,
+    object_property_add(obj, prop->name, prop->info->name,
                         prop->info->get, prop->info->set,
                         prop->info->release,
-                        prop, errp);
+                        prop, &local_err);
+
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (prop->qtype == QTYPE_NONE) {
+        return;
+    }
+
+    if (prop->qtype == QTYPE_QBOOL) {
+        object_property_set_bool(obj, prop->defval, prop->name, &local_err);
+    } else if (prop->info->enum_table) {
+        object_property_set_str(obj, prop->info->enum_table[prop->defval],
+                                prop->name, &local_err);
+    } else if (prop->qtype == QTYPE_QINT) {
+        object_property_set_int(obj, prop->defval, prop->name, &local_err);
+    }
+    assert_no_error(local_err);
 }
 
 static void device_initfn(Object *obj)
@@ -611,7 +632,6 @@ static void device_initfn(Object *obj)
             qdev_property_add_legacy(dev, prop, NULL);
             qdev_property_add_static(dev, prop, NULL);
         }
-        qdev_prop_set_defaults(dev, DEVICE_CLASS(class)->props);
         class = object_class_get_parent(class);
     } while (class != object_class_by_name(TYPE_DEVICE));
     qdev_prop_set_globals(dev);
diff --git a/hw/qdev.h b/hw/qdev.h
index 4d6458f..23147df 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -311,7 +311,6 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
 void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
 /* FIXME: Remove opaque pointer properties.  */
 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
-void qdev_prop_set_defaults(DeviceState *dev, Property *props);
 
 void qdev_prop_register_global_list(GlobalProperty *props);
 void qdev_prop_set_globals(DeviceState *dev);
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 15/21] qdev: fix adding of ptr properties
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (13 preceding siblings ...)
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 14/21] qdev: remove qdev_prop_set_defaults Paolo Bonzini
@ 2012-05-02 11:31 ` Paolo Bonzini
  2012-05-12 12:34   ` Andreas Färber
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 16/21] qdev: use wrapper for qdev_get_path Paolo Bonzini
                   ` (7 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

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

ptr properties have neither a get/set or a print/parse which means that when
they're added they aren't treated as static or legacy properties.

Just assume properties like this are legacy properties and treat them as such.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index f953c51..7f18590 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -550,9 +550,12 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
 {
     gchar *name, *type;
 
-    if (!prop->info->print && !prop->info->parse) {
+    /* Register pointer properties as legacy properties */
+    if (!prop->info->print && !prop->info->parse &&
+        (prop->info->set || prop->info->get)) {
         return;
     }
+
     name = g_strdup_printf("legacy-%s", prop->name);
     type = g_strdup_printf("legacy<%s>",
                            prop->info->legacy_name ?: prop->info->name);
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 16/21] qdev: use wrapper for qdev_get_path
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (14 preceding siblings ...)
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 15/21] qdev: fix adding of ptr properties Paolo Bonzini
@ 2012-05-02 11:31 ` Paolo Bonzini
  2012-05-24 16:31   ` Andreas Färber
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 17/21] qdev: move sysbus initialization to sysbus.c Paolo Bonzini
                   ` (6 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

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

This makes it easier to remove it from BusInfo.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
        Anthony's patch used BUS_CLASS so it broke bisectability; fixed here.

 exec.c        |    4 ++--
 hw/qdev.c     |   16 ++++++++++++++++
 hw/qdev.h     |    2 ++
 hw/scsi-bus.c |    4 +---
 hw/usb/bus.c  |    5 ++---
 hw/usb/desc.c |    5 +++--
 savevm.c      |   12 ++++++------
 7 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/exec.c b/exec.c
index 0607c9b..e3523d2 100644
--- a/exec.c
+++ b/exec.c
@@ -2583,8 +2583,8 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
     assert(new_block);
     assert(!new_block->idstr[0]);
 
-    if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
-        char *id = dev->parent_bus->info->get_dev_path(dev);
+    if (dev) {
+        char *id = qdev_get_dev_path(dev);
         if (id) {
             snprintf(new_block->idstr, sizeof(new_block->idstr), "%s/", id);
             g_free(id);
diff --git a/hw/qdev.c b/hw/qdev.c
index 7f18590..7b2802d 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -494,6 +494,22 @@ char* qdev_get_fw_dev_path(DeviceState *dev)
     return strdup(path);
 }
 
+char *qdev_get_dev_path(DeviceState *dev)
+{
+    BusInfo *businfo;
+
+    if (!dev || !dev->parent_bus) {
+        return NULL;
+    }
+
+    businfo = dev->parent_bus->info;
+    if (businfo->get_dev_path) {
+        return businfo->get_dev_path(dev);
+    }
+
+    return NULL;
+}
+
 /**
  * Legacy property handling
  */
diff --git a/hw/qdev.h b/hw/qdev.h
index 23147df..2e82a2f 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -354,4 +354,6 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus);
 
 extern int qdev_hotplug;
 
+char *qdev_get_dev_path(DeviceState *dev);
+
 #endif
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index d7054da..0dba3aa 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -1434,9 +1434,7 @@ static char *scsibus_get_dev_path(DeviceState *dev)
     char *id = NULL;
     char *path;
 
-    if (hba && hba->parent_bus && hba->parent_bus->info->get_dev_path) {
-        id = hba->parent_bus->info->get_dev_path(hba);
-    }
+    id = qdev_get_dev_path(hba);
     if (id) {
         path = g_strdup_printf("%s/%d:%d:%d", id, d->channel, d->id, d->lun);
     } else {
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 64887d5..8b08f93 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -467,9 +467,8 @@ static char *usb_get_dev_path(DeviceState *qdev)
     DeviceState *hcd = qdev->parent_bus->parent;
     char *id = NULL;
 
-    if ((dev->flags & (1 << USB_DEV_FLAG_FULL_PATH)) &&
-        hcd && hcd->parent_bus && hcd->parent_bus->info->get_dev_path) {
-        id = hcd->parent_bus->info->get_dev_path(hcd);
+    if (dev->flags & (1 << USB_DEV_FLAG_FULL_PATH)) {
+        id = qdev_get_dev_path(hcd);
     }
     if (id) {
         char *ret = g_strdup_printf("%s/%s", id, dev->port->path);
diff --git a/hw/usb/desc.c b/hw/usb/desc.c
index e8a3c6a..0a9d3c9 100644
--- a/hw/usb/desc.c
+++ b/hw/usb/desc.c
@@ -432,12 +432,13 @@ void usb_desc_create_serial(USBDevice *dev)
     const USBDesc *desc = usb_device_get_usb_desc(dev);
     int index = desc->id.iSerialNumber;
     char serial[64];
+    char *path;
     int dst;
 
     assert(index != 0 && desc->str[index] != NULL);
     dst = snprintf(serial, sizeof(serial), "%s", desc->str[index]);
-    if (hcd && hcd->parent_bus && hcd->parent_bus->info->get_dev_path) {
-        char *path = hcd->parent_bus->info->get_dev_path(hcd);
+    path = qdev_get_dev_path(hcd);
+    if (path) {
         dst += snprintf(serial+dst, sizeof(serial)-dst, "-%s", path);
     }
     dst += snprintf(serial+dst, sizeof(serial)-dst, "-%s", dev->port->path);
diff --git a/savevm.c b/savevm.c
index 2d18bab..818ddfc 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1248,8 +1248,8 @@ int register_savevm_live(DeviceState *dev,
         se->is_ram = 1;
     }
 
-    if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
-        char *id = dev->parent_bus->info->get_dev_path(dev);
+    if (dev) {
+        char *id = qdev_get_dev_path(dev);
         if (id) {
             pstrcpy(se->idstr, sizeof(se->idstr), id);
             pstrcat(se->idstr, sizeof(se->idstr), "/");
@@ -1292,8 +1292,8 @@ void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque)
     SaveStateEntry *se, *new_se;
     char id[256] = "";
 
-    if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
-        char *path = dev->parent_bus->info->get_dev_path(dev);
+    if (dev) {
+        char *path = qdev_get_dev_path(dev);
         if (path) {
             pstrcpy(id, sizeof(id), path);
             pstrcat(id, sizeof(id), "/");
@@ -1334,8 +1334,8 @@ int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
     se->alias_id = alias_id;
     se->no_migrate = vmsd->unmigratable;
 
-    if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
-        char *id = dev->parent_bus->info->get_dev_path(dev);
+    if (dev) {
+        char *id = qdev_get_dev_path(dev);
         if (id) {
             pstrcpy(se->idstr, sizeof(se->idstr), id);
             pstrcat(se->idstr, sizeof(se->idstr), "/");
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 17/21] qdev: move sysbus initialization to sysbus.c
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (15 preceding siblings ...)
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 16/21] qdev: use wrapper for qdev_get_path Paolo Bonzini
@ 2012-05-02 11:31 ` Paolo Bonzini
  2012-05-24 16:32   ` Andreas Färber
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 18/21] qdev: convert busses to QEMU Object Model Paolo Bonzini
                   ` (5 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

TYPE_SYSTEM_BUS will be local to hw/sysbus.c, so move existing references
to main_system_bus and system_bus_info there.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev.c   |   26 ++------------------------
 hw/sysbus.c |   21 +++++++++++++++++++++
 2 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 7b2802d..7816a37 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -34,10 +34,6 @@ int qdev_hotplug = 0;
 static bool qdev_hot_added = false;
 static bool qdev_hot_removed = false;
 
-/* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
-static BusState *main_system_bus;
-static void main_system_bus_create(void);
-
 /* Register a new device type.  */
 const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
 {
@@ -188,14 +184,6 @@ static int qdev_reset_one(DeviceState *dev, void *opaque)
     return 0;
 }
 
-BusState *sysbus_get_default(void)
-{
-    if (!main_system_bus) {
-        main_system_bus_create();
-    }
-    return main_system_bus;
-}
-
 static int qbus_reset_one(BusState *bus, void *opaque)
 {
     if (bus->info->reset) {
@@ -415,7 +403,7 @@ void qbus_create_inplace(BusState *bus, BusInfo *info,
     if (parent) {
         QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
         parent->num_child_bus++;
-    } else if (bus != main_system_bus) {
+    } else if (bus != sysbus_get_default()) {
         /* TODO: once all bus devices are qdevified,
            only reset handler for main_system_bus should be registered here. */
         qemu_register_reset(qbus_reset_all_fn, bus);
@@ -432,16 +420,6 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
     return bus;
 }
 
-static void main_system_bus_create(void)
-{
-    /* assign main_system_bus before qbus_create_inplace()
-     * in order to make "if (bus != main_system_bus)" 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");
-}
-
 void qbus_free(BusState *bus)
 {
     DeviceState *dev;
@@ -453,7 +431,7 @@ void qbus_free(BusState *bus)
         QLIST_REMOVE(bus, sibling);
         bus->parent->num_child_bus--;
     } else {
-        assert(bus != main_system_bus); /* main_system_bus is never freed */
+        assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
         qemu_unregister_reset(qbus_reset_all_fn, bus);
     }
     g_free((void*)bus->name);
diff --git a/hw/sysbus.c b/hw/sysbus.c
index db4efcc..fe5c421 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -256,6 +256,27 @@ static TypeInfo sysbus_device_type_info = {
     .class_init = sysbus_device_class_init,
 };
 
+/* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
+static BusState *main_system_bus;
+
+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");
+}
+
+BusState *sysbus_get_default(void)
+{
+    if (!main_system_bus) {
+        main_system_bus_create();
+    }
+    return main_system_bus;
+}
+
 static void sysbus_register_types(void)
 {
     type_register_static(&sysbus_device_type_info);
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 18/21] qdev: convert busses to QEMU Object Model
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (16 preceding siblings ...)
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 17/21] qdev: move sysbus initialization to sysbus.c Paolo Bonzini
@ 2012-05-02 11:31 ` Paolo Bonzini
  2012-05-24 16:48   ` Andreas Färber
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 19/21] qdev: connect busses with their parent devices Paolo Bonzini
                   ` (4 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

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

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 <aliguori@us.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 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

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

* [Qemu-devel] [PATCH 19/21] qdev: connect busses with their parent devices
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (17 preceding siblings ...)
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 18/21] qdev: convert busses to QEMU Object Model Paolo Bonzini
@ 2012-05-02 11:31 ` Paolo Bonzini
  2012-05-24 16:49   ` Andreas Färber
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 20/21] qbus: make child devices links Paolo Bonzini
                   ` (3 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

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

This makes sysbus part of the root hierarchy and all busses children of their
respective parent DeviceState.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev.c   |    4 ++++
 hw/sysbus.c |    3 +++
 2 files changed, 7 insertions(+)

diff --git a/hw/qdev.c b/hw/qdev.c
index b97ba00..decbcb1 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -404,6 +404,7 @@ static void do_qbus_create_inplace(BusState *bus, const char *typename,
     if (parent) {
         QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
         parent->num_child_bus++;
+        object_property_add_child(OBJECT(parent), bus->name, OBJECT(bus), NULL);
     } else if (bus != sysbus_get_default()) {
         /* TODO: once all bus devices are qdevified,
            only reset handler for main_system_bus should be registered here. */
@@ -651,6 +652,9 @@ static void device_initfn(Object *obj)
         class = object_class_get_parent(class);
     } while (class != object_class_by_name(TYPE_DEVICE));
     qdev_prop_set_globals(dev);
+
+    object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
+                             (Object **)&dev->parent_bus, NULL);
 }
 
 /* Unlink device from bus and free the structure.  */
diff --git a/hw/sysbus.c b/hw/sysbus.c
index f10a7d1..417fbd4 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -275,6 +275,9 @@ static void main_system_bus_create(void)
     qbus_create_inplace(main_system_bus, TYPE_SYSTEM_BUS, NULL,
                         "main-system-bus");
     main_system_bus->qdev_allocated = 1;
+    object_property_add_child(container_get(qdev_get_machine(),
+                                            "/unattached"),
+                              "sysbus", OBJECT(main_system_bus), NULL);
 }
 
 BusState *sysbus_get_default(void)
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 20/21] qbus: make child devices links
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (18 preceding siblings ...)
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 19/21] qdev: connect busses with their parent devices Paolo Bonzini
@ 2012-05-02 11:31 ` Paolo Bonzini
  2012-05-24 16:51   ` Andreas Färber
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 21/21] qbus: initialize in standard way Paolo Bonzini
                   ` (2 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

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

Make qbus children show up as link<> properties.  There is no stable addressing
for qbus children so we use an unstable naming convention.

This is okay in QOM though because the composition name is expected to be what's
stable.

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

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/acpi_piix4.c      |   10 ++++----
 hw/i2c.c             |    5 ++--
 hw/intel-hda.c       |   15 +++++++-----
 hw/lsi53c895a.c      |    5 ++--
 hw/qdev-monitor.c    |   26 ++++++++++++--------
 hw/qdev.c            |   64 +++++++++++++++++++++++++++++++++++++++++---------
 hw/qdev.h            |   11 +++++++--
 hw/s390-virtio-bus.c |   25 ++++++++++----------
 hw/scsi-bus.c        |   13 ++++++----
 hw/spapr_pci.c       |    7 +++---
 hw/spapr_vio.c       |   27 +++++++++++----------
 hw/spapr_vty.c       |    6 +++--
 hw/ssi.c             |   14 ++++++-----
 hw/virtio-scsi.c     |    6 ++---
 qom/object.c         |   11 +++++++--
 15 files changed, 161 insertions(+), 84 deletions(-)

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 585da4e..03daf9a 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -284,7 +284,7 @@ static const VMStateDescription vmstate_acpi = {
 
 static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots)
 {
-    DeviceState *qdev, *next;
+    BusChild *kid, *next;
     BusState *bus = qdev_get_parent_bus(&s->dev.qdev);
     int slot = ffs(slots) - 1;
     bool slot_free = true;
@@ -292,7 +292,8 @@ static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots)
     /* Mark request as complete */
     s->pci0_status.down &= ~(1U << slot);
 
-    QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
+    QTAILQ_FOREACH_SAFE(kid, &bus->children, sibling, next) {
+        DeviceState *qdev = kid->child;
         PCIDevice *dev = PCI_DEVICE(qdev);
         PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
         if (PCI_SLOT(dev->devfn) == slot) {
@@ -312,7 +313,7 @@ static void piix4_update_hotplug(PIIX4PMState *s)
 {
     PCIDevice *dev = &s->dev;
     BusState *bus = qdev_get_parent_bus(&dev->qdev);
-    DeviceState *qdev, *next;
+    BusChild *kid, *next;
 
     /* Execute any pending removes during reset */
     while (s->pci0_status.down) {
@@ -322,7 +323,8 @@ static void piix4_update_hotplug(PIIX4PMState *s)
     s->pci0_hotplug_enable = ~0;
     s->pci0_slot_device_present = 0;
 
-    QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
+    QTAILQ_FOREACH_SAFE(kid, &bus->children, sibling, next) {
+        DeviceState *qdev = kid->child;
         PCIDevice *pdev = PCI_DEVICE(qdev);
         PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pdev);
         int slot = PCI_SLOT(pdev->devfn);
diff --git a/hw/i2c.c b/hw/i2c.c
index cd8fa31..47219f5 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -86,11 +86,12 @@ int i2c_bus_busy(i2c_bus *bus)
 /* TODO: Make this handle multiple masters.  */
 int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv)
 {
-    DeviceState *qdev;
+    BusChild *kid;
     I2CSlave *slave = NULL;
     I2CSlaveClass *sc;
 
-    QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) {
+    QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
+        DeviceState *qdev = kid->child;
         I2CSlave *candidate = I2C_SLAVE_FROM_QDEV(qdev);
         if (candidate->address == address) {
             slave = candidate;
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 63bdb27..fb585b5 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -78,10 +78,11 @@ static int hda_codec_dev_exit(DeviceState *qdev)
 
 HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad)
 {
-    DeviceState *qdev;
+    BusChild *kid;
     HDACodecDevice *cdev;
 
-    QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) {
+    QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
+        DeviceState *qdev = kid->child;
         cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
         if (cdev->cad == cad) {
             return cdev;
@@ -483,10 +484,11 @@ static void intel_hda_parse_bdl(IntelHDAState *d, IntelHDAStream *st)
 
 static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool running, bool output)
 {
-    DeviceState *qdev;
+    BusChild *kid;
     HDACodecDevice *cdev;
 
-    QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
+    QTAILQ_FOREACH(kid, &d->codecs.qbus.children, sibling) {
+        DeviceState *qdev = kid->child;
         HDACodecDeviceClass *cdc;
 
         cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
@@ -1105,15 +1107,16 @@ static const MemoryRegionOps intel_hda_mmio_ops = {
 
 static void intel_hda_reset(DeviceState *dev)
 {
+    BusChild *kid;
     IntelHDAState *d = DO_UPCAST(IntelHDAState, pci.qdev, dev);
-    DeviceState *qdev;
     HDACodecDevice *cdev;
 
     intel_hda_regs_reset(d);
     d->wall_base_ns = qemu_get_clock_ns(vm_clock);
 
     /* reset codecs */
-    QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
+    QTAILQ_FOREACH(kid, &d->codecs.qbus.children, sibling) {
+        DeviceState *qdev = kid->child;
         cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
         device_reset(DEVICE(cdev));
         d->state_sts |= (1 << cdev->cad);
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index f022a02..2fe141d 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -1677,9 +1677,10 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
         }
         if (val & LSI_SCNTL1_RST) {
             if (!(s->sstat0 & LSI_SSTAT0_RST)) {
-                DeviceState *dev;
+                BusChild *kid;
 
-                QTAILQ_FOREACH(dev, &s->bus.qbus.children, sibling) {
+                QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
+                    DeviceState *dev = kid->child;
                     device_reset(dev);
                 }
                 s->sstat0 |= LSI_SSTAT0_RST;
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 703d895..e57220e 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -205,11 +205,12 @@ static void qbus_list_bus(DeviceState *dev)
 
 static void qbus_list_dev(BusState *bus)
 {
-    DeviceState *dev;
+    BusChild *kid;
     const char *sep = " ";
 
     error_printf("devices at \"%s\":", bus->name);
-    QTAILQ_FOREACH(dev, &bus->children, sibling) {
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        DeviceState *dev = kid->child;
         error_printf("%s\"%s\"", sep, object_get_typename(OBJECT(dev)));
         if (dev->id)
             error_printf("/\"%s\"", dev->id);
@@ -232,7 +233,7 @@ static BusState *qbus_find_bus(DeviceState *dev, char *elem)
 
 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
 {
-    DeviceState *dev;
+    BusChild *kid;
 
     /*
      * try to match in order:
@@ -240,17 +241,20 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
      *   (2) driver name
      *   (3) driver alias, if present
      */
-    QTAILQ_FOREACH(dev, &bus->children, sibling) {
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        DeviceState *dev = kid->child;
         if (dev->id  &&  strcmp(dev->id, elem) == 0) {
             return dev;
         }
     }
-    QTAILQ_FOREACH(dev, &bus->children, sibling) {
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        DeviceState *dev = kid->child;
         if (strcmp(object_get_typename(OBJECT(dev)), elem) == 0) {
             return dev;
         }
     }
-    QTAILQ_FOREACH(dev, &bus->children, sibling) {
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        DeviceState *dev = kid->child;
         DeviceClass *dc = DEVICE_GET_CLASS(dev);
 
         if (qdev_class_has_alias(dc) &&
@@ -264,7 +268,7 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
 static BusState *qbus_find_recursive(BusState *bus, const char *name,
                                      const char *bus_typename)
 {
-    DeviceState *dev;
+    BusChild *kid;
     BusState *child, *ret;
     int match = 1;
 
@@ -279,7 +283,8 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name,
         return bus;
     }
 
-    QTAILQ_FOREACH(dev, &bus->children, sibling) {
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        DeviceState *dev = kid->child;
         QLIST_FOREACH(child, &dev->child_bus, sibling) {
             ret = qbus_find_recursive(child, name, bus_typename);
             if (ret) {
@@ -533,12 +538,13 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
 
 static void qbus_print(Monitor *mon, BusState *bus, int indent)
 {
-    struct DeviceState *dev;
+    BusChild *kid;
 
     qdev_printf("bus: %s\n", bus->name);
     indent += 2;
     qdev_printf("type %s\n", object_get_typename(OBJECT(bus)));
-    QTAILQ_FOREACH(dev, &bus->children, sibling) {
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        DeviceState *dev = kid->child;
         qdev_print(mon, dev, indent);
     }
 }
diff --git a/hw/qdev.c b/hw/qdev.c
index decbcb1..6965da0 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -60,14 +60,48 @@ bool qdev_exists(const char *name)
 static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
                                      Error **errp);
 
-void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
+static void bus_remove_child(BusState *bus, DeviceState *child)
 {
+    BusChild *kid;
+
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        if (kid->child == child) {
+            char name[32];
+
+            snprintf(name, sizeof(name), "child[%d]", kid->index);
+            QTAILQ_REMOVE(&bus->children, kid, sibling);
+            object_property_del(OBJECT(bus), name, NULL);
+            g_free(kid);
+            return;
+        }
+    }
+}
+
+static void bus_add_child(BusState *bus, DeviceState *child)
+{
+    char name[32];
+    BusChild *kid = g_malloc0(sizeof(*kid));
+
     if (qdev_hotplug) {
         assert(bus->allow_hotplug);
     }
 
+    kid->index = bus->max_index++;
+    kid->child = child;
+
+    QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
+
+    snprintf(name, sizeof(name), "child[%d]", kid->index);
+    object_property_add_link(OBJECT(bus), name,
+                             object_get_typename(OBJECT(child)),
+                             (Object **)&kid->child,
+                             NULL);
+}
+
+void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
+{
     dev->parent_bus = bus;
-    QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
+    bus_add_child(bus, dev);
 }
 
 /* Create a new device.  This only initializes the device state structure
@@ -310,7 +344,7 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
                        qbus_walkerfn *busfn, void *opaque)
 {
-    DeviceState *dev;
+    BusChild *kid;
     int err;
 
     if (busfn) {
@@ -320,8 +354,8 @@ int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
         }
     }
 
-    QTAILQ_FOREACH(dev, &bus->children, sibling) {
-        err = qdev_walk_children(dev, devfn, busfn, opaque);
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        err = qdev_walk_children(kid->child, devfn, busfn, opaque);
         if (err < 0) {
             return err;
         }
@@ -355,12 +389,17 @@ int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
 
 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
 {
-    DeviceState *dev, *ret;
+    BusChild *kid;
+    DeviceState *ret;
     BusState *child;
 
-    QTAILQ_FOREACH(dev, &bus->children, sibling) {
-        if (dev->id && strcmp(dev->id, id) == 0)
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        DeviceState *dev = kid->child;
+
+        if (dev->id && strcmp(dev->id, id) == 0) {
             return dev;
+        }
+
         QLIST_FOREACH(child, &dev->child_bus, sibling) {
             ret = qdev_find_recursive(child, id);
             if (ret) {
@@ -431,9 +470,10 @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam
 
 void qbus_free(BusState *bus)
 {
-    DeviceState *dev;
+    BusChild *kid;
 
-    while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
+    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
+        DeviceState *dev = kid->child;
         qdev_free(dev);
     }
     if (bus->parent) {
@@ -679,7 +719,9 @@ static void device_finalize(Object *obj)
             qemu_opts_del(dev->opts);
         }
     }
-    QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
+    if (dev->parent_bus) {
+        bus_remove_child(dev->parent_bus, dev);
+    }
 }
 
 static void device_class_base_init(ObjectClass *class, void *data)
diff --git a/hw/qdev.h b/hw/qdev.h
index 3c54a6f..7deb2cb 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -74,7 +74,6 @@ struct DeviceState {
     qemu_irq *gpio_in;
     QLIST_HEAD(, BusState) child_bus;
     int num_child_bus;
-    QTAILQ_ENTRY(DeviceState) sibling;
     int instance_id_alias;
     int alias_required_for_version;
 };
@@ -100,13 +99,20 @@ struct BusClass {
     int (*reset)(BusState *bus);
 };
 
+typedef struct BusChild {
+    DeviceState *child;
+    int index;
+    QTAILQ_ENTRY(BusChild) sibling;
+} BusChild;
+
 struct BusState {
     Object obj;
     DeviceState *parent;
     const char *name;
     int allow_hotplug;
     int qdev_allocated;
-    QTAILQ_HEAD(ChildrenHead, DeviceState) children;
+    int max_index;
+    QTAILQ_HEAD(ChildrenHead, BusChild) children;
     QLIST_ENTRY(BusState) sibling;
 };
 
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index d259050..6831b12 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -291,20 +291,20 @@ VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
                                              ram_addr_t mem,
                                              int *vq_num)
 {
-    VirtIOS390Device *_dev;
-    DeviceState *dev;
+    BusChild *kid;
     int i;
 
-    QTAILQ_FOREACH(dev, &bus->bus.children, sibling) {
-        _dev = (VirtIOS390Device *)dev;
+    QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
+        VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
+
         for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
-            if (!virtio_queue_get_addr(_dev->vdev, i))
+            if (!virtio_queue_get_addr(dev->vdev, i))
                 break;
-            if (virtio_queue_get_addr(_dev->vdev, i) == mem) {
+            if (virtio_queue_get_addr(dev->vdev, i) == mem) {
                 if (vq_num) {
                     *vq_num = i;
                 }
-                return _dev;
+                return dev;
             }
         }
     }
@@ -315,13 +315,12 @@ VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
 /* Find a device by device descriptor location */
 VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem)
 {
-    VirtIOS390Device *_dev;
-    DeviceState *dev;
+    BusChild *kid;
 
-    QTAILQ_FOREACH(dev, &bus->bus.children, sibling) {
-        _dev = (VirtIOS390Device *)dev;
-        if (_dev->dev_offs == mem) {
-            return _dev;
+    QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
+        VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
+        if (dev->dev_offs == mem) {
+            return dev;
         }
     }
 
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 004f852..3dbe335 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -303,7 +303,7 @@ static void store_lun(uint8_t *outbuf, int lun)
 
 static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
 {
-    DeviceState *qdev;
+    BusChild *kid;
     int i, len, n;
     int channel, id;
     bool found_lun0;
@@ -318,7 +318,8 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
     id = r->req.dev->id;
     found_lun0 = false;
     n = 0;
-    QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) {
+    QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) {
+        DeviceState *qdev = kid->child;
         SCSIDevice *dev = SCSI_DEVICE(qdev);
 
         if (dev->channel == channel && dev->id == id) {
@@ -340,7 +341,8 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
     memset(r->buf, 0, len);
     stl_be_p(&r->buf, n);
     i = found_lun0 ? 8 : 16;
-    QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) {
+    QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) {
+        DeviceState *qdev = kid->child;
         SCSIDevice *dev = SCSI_DEVICE(qdev);
 
         if (dev->channel == channel && dev->id == id) {
@@ -1465,10 +1467,11 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev)
 
 SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun)
 {
-    DeviceState *qdev;
+    BusChild *kid;
     SCSIDevice *target_dev = NULL;
 
-    QTAILQ_FOREACH_REVERSE(qdev, &bus->qbus.children, ChildrenHead, sibling) {
+    QTAILQ_FOREACH_REVERSE(kid, &bus->qbus.children, ChildrenHead, sibling) {
+        DeviceState *qdev = kid->child;
         SCSIDevice *dev = SCSI_DEVICE(qdev);
 
         if (dev->channel == channel && dev->id == id) {
diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c
index a564c00..fcc6d58 100644
--- a/hw/spapr_pci.c
+++ b/hw/spapr_pci.c
@@ -35,17 +35,18 @@
 static PCIDevice *find_dev(sPAPREnvironment *spapr,
                            uint64_t buid, uint32_t config_addr)
 {
-    DeviceState *qdev;
     int devfn = (config_addr >> 8) & 0xFF;
     sPAPRPHBState *phb;
 
     QLIST_FOREACH(phb, &spapr->phbs, list) {
+        BusChild *kid;
+
         if (phb->buid != buid) {
             continue;
         }
 
-        QTAILQ_FOREACH(qdev, &phb->host_state.bus->qbus.children, sibling) {
-            PCIDevice *dev = (PCIDevice *)qdev;
+        QTAILQ_FOREACH(kid, &phb->host_state.bus->qbus.children, sibling) {
+            PCIDevice *dev = (PCIDevice *)kid->child;
             if (dev->devfn == devfn) {
                 return dev;
             }
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 7c5493e..2c9256e 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -62,11 +62,11 @@ static TypeInfo spapr_vio_bus_info = {
 
 VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
 {
-    DeviceState *qdev;
+    BusChild *kid;
     VIOsPAPRDevice *dev = NULL;
 
-    QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
-        dev = (VIOsPAPRDevice *)qdev;
+    QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
+        dev = (VIOsPAPRDevice *)kid->child;
         if (dev->reg == reg) {
             return dev;
         }
@@ -606,7 +606,7 @@ static void rtas_quiesce(sPAPREnvironment *spapr, uint32_t token,
                          uint32_t nret, target_ulong rets)
 {
     VIOsPAPRBus *bus = spapr->vio_bus;
-    DeviceState *qdev;
+    BusChild *kid;
     VIOsPAPRDevice *dev = NULL;
 
     if (nargs != 0) {
@@ -614,8 +614,8 @@ static void rtas_quiesce(sPAPREnvironment *spapr, uint32_t token,
         return;
     }
 
-    QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
-        dev = (VIOsPAPRDevice *)qdev;
+    QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
+        dev = (VIOsPAPRDevice *)kid->child;
         spapr_vio_quiesce_one(dev);
     }
 
@@ -625,7 +625,7 @@ static void rtas_quiesce(sPAPREnvironment *spapr, uint32_t token,
 static int spapr_vio_check_reg(VIOsPAPRDevice *sdev)
 {
     VIOsPAPRDevice *other_sdev;
-    DeviceState *qdev;
+    BusChild *kid;
     VIOsPAPRBus *sbus;
 
     sbus = DO_UPCAST(VIOsPAPRBus, bus, sdev->qdev.parent_bus);
@@ -635,13 +635,13 @@ static int spapr_vio_check_reg(VIOsPAPRDevice *sdev)
      * other mechanism). We have to open code this because we have to check
      * for matches with devices other than us.
      */
-    QTAILQ_FOREACH(qdev, &sbus->bus.children, sibling) {
-        other_sdev = DO_UPCAST(VIOsPAPRDevice, qdev, qdev);
+    QTAILQ_FOREACH(kid, &sbus->bus.children, sibling) {
+        other_sdev = DO_UPCAST(VIOsPAPRDevice, qdev, kid->child);
 
         if (other_sdev != sdev && other_sdev->reg == sdev->reg) {
             fprintf(stderr, "vio: %s and %s devices conflict at address %#x\n",
                     object_get_typename(OBJECT(sdev)),
-                    object_get_typename(OBJECT(qdev)),
+                    object_get_typename(OBJECT(other_sdev)),
                     sdev->reg);
             return -EEXIST;
         }
@@ -826,19 +826,20 @@ static int compare_reg(const void *p1, const void *p2)
 int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt)
 {
     DeviceState *qdev, **qdevs;
+    BusChild *kid;
     int i, num, ret = 0;
 
     /* Count qdevs on the bus list */
     num = 0;
-    QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
+    QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
         num++;
     }
 
     /* Copy out into an array of pointers */
     qdevs = g_malloc(sizeof(qdev) * num);
     num = 0;
-    QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
-        qdevs[num++] = qdev;
+    QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
+        qdevs[num++] = kid->child;
     }
 
     /* Sort the array */
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index a30c040..cfdc500 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -161,7 +161,7 @@ static TypeInfo spapr_vty_info = {
 VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
 {
     VIOsPAPRDevice *sdev, *selected;
-    DeviceState *iter;
+    BusChild *kid;
 
     /*
      * To avoid the console bouncing around we want one VTY to be
@@ -170,7 +170,9 @@ VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
      */
 
     selected = NULL;
-    QTAILQ_FOREACH(iter, &bus->bus.children, sibling) {
+    QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
+        DeviceState *iter = kid->child;
+
         /* Only look at VTY devices */
         if (!object_dynamic_cast(OBJECT(iter), "spapr-vty")) {
             continue;
diff --git a/hw/ssi.c b/hw/ssi.c
index d645691..19e5ae1 100644
--- a/hw/ssi.c
+++ b/hw/ssi.c
@@ -30,10 +30,11 @@ static int ssi_slave_init(DeviceState *dev)
     SSISlave *s = SSI_SLAVE(dev);
     SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(s);
     SSIBus *bus;
+    BusChild *kid;
 
     bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev));
-    if (QTAILQ_FIRST(&bus->qbus.children) != dev
-        || QTAILQ_NEXT(dev, sibling) != NULL) {
+    kid = QTAILQ_FIRST(&bus->qbus.children);
+    if (kid->child != dev || QTAILQ_NEXT(kid, sibling) != NULL) {
         hw_error("Too many devices on SSI bus");
     }
 
@@ -72,14 +73,15 @@ SSIBus *ssi_create_bus(DeviceState *parent, const char *name)
 
 uint32_t ssi_transfer(SSIBus *bus, uint32_t val)
 {
-    DeviceState *dev;
+    BusChild *kid;
     SSISlave *slave;
     SSISlaveClass *ssc;
-    dev = QTAILQ_FIRST(&bus->qbus.children);
-    if (!dev) {
+
+    kid = QTAILQ_FIRST(&bus->qbus.children);
+    if (!kid) {
         return 0;
     }
-    slave = SSI_SLAVE(dev);
+    slave = SSI_SLAVE(kid->child);
     ssc = SSI_SLAVE_GET_CLASS(slave);
     return ssc->transfer(slave, val);
 }
diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c
index e8328f4..970b691 100644
--- a/hw/virtio-scsi.c
+++ b/hw/virtio-scsi.c
@@ -275,7 +275,7 @@ static void virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
 {
     SCSIDevice *d = virtio_scsi_device_find(s, req->req.tmf->lun);
     SCSIRequest *r, *next;
-    DeviceState *qdev;
+    BusChild *kid;
     int target;
 
     /* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE".  */
@@ -346,8 +346,8 @@ static void virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
     case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:
         target = req->req.tmf->lun[1];
         s->resetting++;
-        QTAILQ_FOREACH(qdev, &s->bus.qbus.children, sibling) {
-             d = DO_UPCAST(SCSIDevice, qdev, qdev);
+        QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
+             d = DO_UPCAST(SCSIDevice, qdev, kid->child);
              if (d->channel == 0 && d->id == target) {
                 qdev_reset_all(&d->qdev);
              }
diff --git a/qom/object.c b/qom/object.c
index b4f6c1d..6359486 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -662,9 +662,16 @@ void object_property_del(Object *obj, const char *name, Error **errp)
 {
     ObjectProperty *prop = object_property_find(obj, name);
 
-    QTAILQ_REMOVE(&obj->properties, prop, node);
+    if (prop == NULL) {
+        error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name);
+        return;
+    }
+
+    if (prop->release) {
+        prop->release(obj, name, prop->opaque);
+    }
 
-    prop->release(obj, prop->name, prop->opaque);
+    QTAILQ_REMOVE(&obj->properties, prop, node);
 
     g_free(prop->name);
     g_free(prop->type);
-- 
1.7.9.3

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

* [Qemu-devel] [PATCH 21/21] qbus: initialize in standard way
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (19 preceding siblings ...)
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 20/21] qbus: make child devices links Paolo Bonzini
@ 2012-05-02 11:31 ` Paolo Bonzini
  2012-05-24 16:52   ` Andreas Färber
  2012-05-04 16:15 ` [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
  2012-05-23 15:43 ` Paolo Bonzini
  22 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, aliguori, liwp, afaerber

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

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/qdev.c |   84 +++++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 51 insertions(+), 33 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 6965da0..9aaa1d3 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -410,40 +410,35 @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id)
     return NULL;
 }
 
-/* FIXME move this logic into instance_init */
-static void do_qbus_create_inplace(BusState *bus, const char *typename,
-                                   DeviceState *parent, const char *name)
+static void qbus_realize(BusState *bus)
 {
+    const char *typename = object_get_typename(OBJECT(bus));
     char *buf;
     int i,len;
 
-    bus->parent = parent;
-
-    if (name) {
+    if (bus->name) {
         /* use supplied name */
-        bus->name = g_strdup(name);
-    } else if (parent && parent->id) {
+    } else if (bus->parent && bus->parent->id) {
         /* parent device has id -> use it for bus name */
-        len = strlen(parent->id) + 16;
+        len = strlen(bus->parent->id) + 16;
         buf = g_malloc(len);
-        snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
+        snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
         bus->name = buf;
     } else {
         /* no id -> use lowercase bus type for bus name */
         len = strlen(typename) + 16;
         buf = g_malloc(len);
         len = snprintf(buf, len, "%s.%d", typename,
-                       parent ? parent->num_child_bus : 0);
+                       bus->parent ? bus->parent->num_child_bus : 0);
         for (i = 0; i < len; i++)
             buf[i] = qemu_tolower(buf[i]);
         bus->name = buf;
     }
 
-    QTAILQ_INIT(&bus->children);
-    if (parent) {
-        QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
-        parent->num_child_bus++;
-        object_property_add_child(OBJECT(parent), bus->name, OBJECT(bus), NULL);
+    if (bus->parent) {
+        QLIST_INSERT_HEAD(&bus->parent->child_bus, bus, sibling);
+        bus->parent->num_child_bus++;
+        object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus), NULL);
     } else if (bus != sysbus_get_default()) {
         /* TODO: once all bus devices are qdevified,
            only reset handler for main_system_bus should be registered here. */
@@ -455,7 +450,10 @@ 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);
+
+    bus->parent = parent;
+    bus->name = name ? g_strdup(name) : NULL;
+    qbus_realize(bus);
 }
 
 BusState *qbus_create(const char *typename, DeviceState *parent, const char *name)
@@ -464,28 +462,20 @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam
 
     bus = BUS(object_new(typename));
     bus->qdev_allocated = 1;
-    do_qbus_create_inplace(bus, typename, parent, name);
+
+    bus->parent = parent;
+    bus->name = name ? g_strdup(name) : NULL;
+    qbus_realize(bus);
+
     return bus;
 }
 
 void qbus_free(BusState *bus)
 {
-    BusChild *kid;
-
-    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
-        DeviceState *dev = kid->child;
-        qdev_free(dev);
-    }
-    if (bus->parent) {
-        QLIST_REMOVE(bus, sibling);
-        bus->parent->num_child_bus--;
-    } else {
-        assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
-        qemu_unregister_reset(qbus_reset_all_fn, bus);
-    }
-    g_free((void*)bus->name);
     if (bus->qdev_allocated) {
-        g_free(bus);
+        object_delete(OBJECT(bus));
+    } else {
+        object_finalize(OBJECT(bus));
     }
 }
 
@@ -765,12 +755,40 @@ static TypeInfo device_type_info = {
     .class_size = sizeof(DeviceClass),
 };
 
+static void qbus_initfn(Object *obj)
+{
+    BusState *bus = BUS(obj);
+
+    QTAILQ_INIT(&bus->children);
+}
+
+static void qbus_finalize(Object *obj)
+{
+    BusState *bus = BUS(obj);
+    BusChild *kid;
+
+    while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) {
+        DeviceState *dev = kid->child;
+        qdev_free(dev);
+    }
+    if (bus->parent) {
+        QLIST_REMOVE(bus, sibling);
+        bus->parent->num_child_bus--;
+    } else {
+        assert(bus != sysbus_get_default()); /* main_system_bus is never freed */
+        qemu_unregister_reset(qbus_reset_all_fn, bus);
+    }
+    g_free((char *)bus->name);
+}
+
 static TypeInfo bus_info = {
     .name = TYPE_BUS,
     .parent = TYPE_OBJECT,
     .instance_size = sizeof(BusState),
     .abstract = true,
     .class_size = sizeof(BusClass),
+    .instance_init = qbus_initfn,
+    .instance_finalize = qbus_finalize,
 };
 
 static void qdev_register_types(void)
-- 
1.7.9.3

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

* Re: [Qemu-devel] [PATCH 12/21] pc: add back PCI.rombar compat property
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 12/21] pc: add back PCI.rombar compat property Paolo Bonzini
@ 2012-05-02 11:38   ` Michael S. Tsirkin
  2012-05-02 11:41     ` Paolo Bonzini
  0 siblings, 1 reply; 64+ messages in thread
From: Michael S. Tsirkin @ 2012-05-02 11:38 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, aliguori, qemu-devel, afaerber, liwp

On Wed, May 02, 2012 at 01:31:04PM +0200, Paolo Bonzini wrote:
> This was erroneously dropped in d6c730086cbf24382eb8cff25551798769edfd84.
> 
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Yes I think it's a mistake, however we had:
-        },{
-            .driver   = "PCI",
-            .property = "rombar",
-            .value    = stringify(0),
-        },{

and not TYPE_PCI_DEVICE.

So let's put it back the way it was?

> ---
>  hw/pc_piix.c |    4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/hw/pc_piix.c b/hw/pc_piix.c
> index ef6afb1..15a62ef 100644
> --- a/hw/pc_piix.c
> +++ b/hw/pc_piix.c
> @@ -523,6 +523,10 @@ static QEMUMachine pc_machine_v0_12 = {
>              .driver   = "virtio-blk-pci",\
>              .property = "vectors",\
>              .value    = stringify(0),\
> +        },{\
> +            .driver   = TYPE_PCI_DEVICE,\
> +            .property = "rombar",\
> +            .value    = stringify(0),\
>          }
>  
>  static QEMUMachine pc_machine_v0_11 = {
> -- 
> 1.7.9.3
> 

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

* Re: [Qemu-devel] [PATCH 12/21] pc: add back PCI.rombar compat property
  2012-05-02 11:38   ` Michael S. Tsirkin
@ 2012-05-02 11:41     ` Paolo Bonzini
  2012-05-02 11:44       ` Michael S. Tsirkin
  0 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 11:41 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: peter.maydell, aliguori, qemu-devel, afaerber, liwp

Il 02/05/2012 13:38, Michael S. Tsirkin ha scritto:
> On Wed, May 02, 2012 at 01:31:04PM +0200, Paolo Bonzini wrote:
>> This was erroneously dropped in d6c730086cbf24382eb8cff25551798769edfd84.
>>
>> Cc: Michael S. Tsirkin <mst@redhat.com>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> 
> Yes I think it's a mistake, however we had:
> -        },{
> -            .driver   = "PCI",
> -            .property = "rombar",
> -            .value    = stringify(0),
> -        },{
> 
> and not TYPE_PCI_DEVICE.

PCI->TYPE_PCI_DEVICE is required by earlier patches in the series.

Paolo

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

* Re: [Qemu-devel] [PATCH 12/21] pc: add back PCI.rombar compat property
  2012-05-02 11:41     ` Paolo Bonzini
@ 2012-05-02 11:44       ` Michael S. Tsirkin
  0 siblings, 0 replies; 64+ messages in thread
From: Michael S. Tsirkin @ 2012-05-02 11:44 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: liwp, peter.maydell, aliguori, qemu-devel, afaerber

On Wed, May 02, 2012 at 01:41:30PM +0200, Paolo Bonzini wrote:
> Il 02/05/2012 13:38, Michael S. Tsirkin ha scritto:
> > On Wed, May 02, 2012 at 01:31:04PM +0200, Paolo Bonzini wrote:
> >> This was erroneously dropped in d6c730086cbf24382eb8cff25551798769edfd84.
> >>
> >> Cc: Michael S. Tsirkin <mst@redhat.com>
> >> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> > 
> > Yes I think it's a mistake, however we had:
> > -        },{
> > -            .driver   = "PCI",
> > -            .property = "rombar",
> > -            .value    = stringify(0),
> > -        },{
> > 
> > and not TYPE_PCI_DEVICE.
> 
> PCI->TYPE_PCI_DEVICE is required by earlier patches in the series.
> 
> Paolo

Haven't received them yet.
Ideally bugfixes come first in the series.

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

* Re: [Qemu-devel] [PATCH 01/21] qom: documentation addition
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 01/21] qom: documentation addition Paolo Bonzini
@ 2012-05-02 11:59   ` Andreas Färber
  2012-05-11  2:08     ` Andreas Färber
  0 siblings, 1 reply; 64+ messages in thread
From: Andreas Färber @ 2012-05-02 11:59 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, aliguori, qemu-devel, liwp

Am 02.05.2012 13:30, schrieb Paolo Bonzini:
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  include/qemu/object.h |    6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/include/qemu/object.h b/include/qemu/object.h
> index ca1649c..d315dfa 100644
> --- a/include/qemu/object.h
> +++ b/include/qemu/object.h
> @@ -555,6 +555,12 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *klass,
>   */
>  const char *object_class_get_name(ObjectClass *klass);
>  
> +/**
> + * object_class_by_name:
> + * @typename: The QOM typename to obtain the class for.
> + *
> + * Returns: The class for @typename.

...or NULL if not found.

> + */
>  ObjectClass *object_class_by_name(const char *typename);
>  
>  void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),

This is certainly a good fit for 1.1. :)

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

* Re: [Qemu-devel] [PATCH 02/21] qom: add object_class_get_parent
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 02/21] qom: add object_class_get_parent Paolo Bonzini
@ 2012-05-02 12:21   ` Andreas Färber
  2012-05-11  2:25     ` Andreas Färber
  0 siblings, 1 reply; 64+ messages in thread
From: Andreas Färber @ 2012-05-02 12:21 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, aliguori, qemu-devel, liwp

Am 02.05.2012 13:30, schrieb Paolo Bonzini:
> This simple bit of functionality was missing and we'll need it soon,
> so add it.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  include/qemu/object.h |    8 ++++++++
>  qom/object.c          |   13 +++++++++++++
>  2 files changed, 21 insertions(+)
> 
> diff --git a/include/qemu/object.h b/include/qemu/object.h
> index d315dfa..063c817 100644
> --- a/include/qemu/object.h
> +++ b/include/qemu/object.h
> @@ -548,6 +548,14 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *klass,
>                                         const char *typename);
>  
>  /**
> + * object_class_get_parent:
> + * @klass: The class to obtain the parent for.
> + *
> + * Returns: The parent for @klass.

Here too we should indicate that this may return NULL (rather than
aborting). Other than that looks good.

Andreas

> + */
> +ObjectClass *object_class_get_parent(ObjectClass *klass);
> +
> +/**
>   * object_class_get_name:
>   * @klass: The class to obtain the QOM typename for.
>   *
[snip]

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

* Re: [Qemu-devel] [PATCH 11/21] qdev: move bus properties to abstract superclasses
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 11/21] qdev: move bus properties to abstract superclasses Paolo Bonzini
@ 2012-05-02 12:29   ` Anthony Liguori
  2012-05-02 13:21     ` Paolo Bonzini
  0 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2012-05-02 12:29 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, qemu-devel, afaerber, liwp

On 05/02/2012 06:31 AM, Paolo Bonzini wrote:
> In qdev, each bus in practice identified an abstract superclass, but
> this was mostly hidden.  In QOM, instead, these abstract classes are
> explicit so we can move bus properties there.
>
> All bus property walks are removed, and all device property walks
> are changed to look along the class hierarchy instead.
>
> This breaks global bus properties, an obscure feature when used
> with the command-line which is actually useful and used when used by
> backwards-compatible machine types.  So this patch also adjust the
> global bus properties in hw/pc_piix.c to refer to the abstract class.
>
> Globals and other properties must be modified in the same patch to
> avoid complications related to initialization ordering.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> ---
>   hw/i2c.c                      |    2 +-
>   hw/ide/qdev.c                 |    2 +-
>   hw/intel-hda.c                |    2 +-
>   hw/pc_piix.c                  |    5 +++--
>   hw/pci.c                      |    2 +-
>   hw/qdev-monitor.c             |   41 ++++++++++++++++++-----------------------
>   hw/qdev-properties.c          |   40 ++++++++++++++++++++++------------------
>   hw/qdev.c                     |   36 ++++++++++--------------------------
>   hw/qdev.h                     |    5 -----
>   hw/scsi-bus.c                 |    2 +-
>   hw/spapr_vio.c                |    2 +-
>   hw/usb/bus.c                  |    2 +-
>   hw/usb/dev-smartcard-reader.c |    2 +-
>   hw/virtio-serial-bus.c        |    2 +-
>   14 files changed, 62 insertions(+), 83 deletions(-)
>
> diff --git a/hw/i2c.c b/hw/i2c.c
> index cb10b1d..af5979e 100644
> --- a/hw/i2c.c
> +++ b/hw/i2c.c
> @@ -25,7 +25,6 @@ static Property i2c_props[] = {
>   static struct BusInfo i2c_bus_info = {
>       .name = "I2C",
>       .size = sizeof(i2c_bus),
> -    .props = i2c_props,
>   };
>
>   static void i2c_bus_pre_save(void *opaque)
> @@ -221,6 +220,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->props = i2c_props;
>   }
>
>   static TypeInfo i2c_slave_type_info = {
> diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
> index b67df3d..a91e878 100644
> --- a/hw/ide/qdev.c
> +++ b/hw/ide/qdev.c
> @@ -36,7 +36,6 @@ static struct BusInfo ide_bus_info = {
>       .name  = "IDE",
>       .size  = sizeof(IDEBus),
>       .get_fw_dev_path = idebus_get_fw_dev_path,
> -    .props = ide_props,
>   };
>
>   void ide_bus_new(IDEBus *idebus, DeviceState *dev, int bus_id)
> @@ -251,6 +250,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->props = ide_props;
>   }
>
>   static TypeInfo ide_device_type_info = {
> diff --git a/hw/intel-hda.c b/hw/intel-hda.c
> index 0994f6b..e2bd41e 100644
> --- a/hw/intel-hda.c
> +++ b/hw/intel-hda.c
> @@ -37,7 +37,6 @@ static Property hda_props[] = {
>   static struct BusInfo hda_codec_bus_info = {
>       .name      = "HDA",
>       .size      = sizeof(HDACodecBus),
> -    .props     = hda_props,
>   };
>
>   void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus,
> @@ -1278,6 +1277,7 @@ static void hda_codec_device_class_init(ObjectClass *klass, void *data)
>       k->init = hda_codec_dev_init;
>       k->exit = hda_codec_dev_exit;
>       k->bus_info =&hda_codec_bus_info;
> +    k->props = hda_props;
>   }
>
>   static TypeInfo hda_codec_device_type_info = {
> diff --git a/hw/pc_piix.c b/hw/pc_piix.c
> index 6a75718..ef6afb1 100644
> --- a/hw/pc_piix.c
> +++ b/hw/pc_piix.c
> @@ -29,6 +29,7 @@
>   #include "apic.h"
>   #include "pci.h"
>   #include "pci_ids.h"
> +#include "usb.h"
>   #include "net.h"
>   #include "boards.h"
>   #include "ide.h"
> @@ -378,7 +379,7 @@ static QEMUMachine pc_machine_v1_1 = {
>               .property = "vapic",\
>               .value    = "off",\
>           },{\
> -            .driver   = "USB",\
> +            .driver   = TYPE_USB_DEVICE,\
>               .property = "full-path",\
>               .value    = "no",\
>           }
> @@ -451,7 +452,7 @@ static QEMUMachine pc_machine_v0_14 = {
>   #define PC_COMPAT_0_13 \
>           PC_COMPAT_0_14,\
>           {\
> -            .driver   = "PCI",\
> +            .driver   = TYPE_PCI_DEVICE,\
>               .property = "command_serr_enable",\
>               .value    = "off",\
>           },{\
> diff --git a/hw/pci.c b/hw/pci.c
> index 403651f..6319f4d 100644
> --- a/hw/pci.c
> +++ b/hw/pci.c
> @@ -62,7 +62,6 @@ struct BusInfo pci_bus_info = {
>       .get_dev_path = pcibus_get_dev_path,
>       .get_fw_dev_path = pcibus_get_fw_dev_path,
>       .reset      = pcibus_reset,
> -    .props      = pci_props,
>   };
>
>   static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
> @@ -2004,6 +2003,7 @@ static void pci_device_class_init(ObjectClass *klass, void *data)
>       k->unplug = pci_unplug_device;
>       k->exit = pci_unregister_device;
>       k->bus_info =&pci_bus_info;
> +    k->props = pci_props;
>   }
>
>   static TypeInfo pci_device_type_info = {
> diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
> index eed781d..d9c6adc 100644
> --- a/hw/qdev-monitor.c
> +++ b/hw/qdev-monitor.c
> @@ -123,7 +123,6 @@ 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, "?")) {
> @@ -149,30 +148,22 @@ int qdev_device_help(QemuOpts *opts)
>       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->set) {
> -            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);
> -    }
> -    if (info->bus_info) {
> -        for (prop = info->bus_info->props; prop&&  prop->name; prop++) {
> +    do {
> +        for (prop = DEVICE_CLASS(klass)->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->set) {
>                   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);
>           }
> -    }
> +        klass = object_class_get_parent(klass);
> +    } while (klass != object_class_by_name(TYPE_DEVICE));
>       return 1;
>   }
>
> @@ -482,7 +473,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
>   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)
> +                             int indent)
>   {
>       if (!props)
>           return;
> @@ -501,7 +492,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
>               error_free(err);
>               continue;
>           }
> -        qdev_printf("%s-prop: %s = %s\n", prefix, props->name,
> +        qdev_printf("%s = %s\n", props->name,
>                       value&&  *value ? value : "<null>");
>           g_free(value);
>       }
> @@ -509,6 +500,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
>
>   static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
>   {
> +    ObjectClass *class;
>       BusState *child;
>       qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
>                   dev->id ? dev->id : "");
> @@ -519,8 +511,11 @@ 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_props(dev), "dev", indent);
> -    qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
> +    class = object_get_class(OBJECT(dev));
> +    do {
> +        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);
>       QLIST_FOREACH(child,&dev->child_bus, sibling) {
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index 98dd06a..572b83c 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -939,17 +939,18 @@ static Property *qdev_prop_walk(Property *props, const char *name)
>
>   static Property *qdev_prop_find(DeviceState *dev, const char *name)
>   {
> +    ObjectClass *class;
>       Property *prop;
>
>       /* device properties */
> -    prop = qdev_prop_walk(qdev_get_props(dev), name);
> -    if (prop)
> -        return prop;
> -
> -    /* bus properties */
> -    prop = qdev_prop_walk(dev->parent_bus->info->props, name);
> -    if (prop)
> -        return prop;
> +    class = object_get_class(OBJECT(dev));
> +    do {
> +        prop = qdev_prop_walk(DEVICE_CLASS(class)->props, name);
> +        if (prop) {
> +            return prop;
> +        }
> +        class = object_class_get_parent(class);
> +    } while (class != object_class_by_name(TYPE_DEVICE));
>
>       return NULL;
>   }
> @@ -1169,17 +1170,20 @@ void qdev_prop_register_global_list(GlobalProperty *props)
>
>   void qdev_prop_set_globals(DeviceState *dev)
>   {
> -    GlobalProperty *prop;
> -
> -    QTAILQ_FOREACH(prop,&global_props, next) {
> -        if (strcmp(object_get_typename(OBJECT(dev)), prop->driver) != 0&&
> -            strcmp(qdev_get_bus_info(dev)->name, prop->driver) != 0) {
> -            continue;
> -        }
> -        if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
> -            exit(1);
> +    ObjectClass *class = object_get_class(OBJECT(dev));
> +
> +    do {
> +        GlobalProperty *prop;
> +        QTAILQ_FOREACH(prop,&global_props, next) {
> +            if (strcmp(object_class_get_name(class), prop->driver) != 0) {
> +                continue;
> +            }
> +            if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
> +                exit(1);
> +            }
>           }
> -    }
> +        class = object_class_get_parent(class);
> +    } while (class);
>   }
>
>   static int qdev_add_one_global(QemuOpts *opts, void *opaque)
> diff --git a/hw/qdev.c b/hw/qdev.c
> index 67d7770..98efc8b 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -45,18 +45,6 @@ const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
>       return dc->vmsd;
>   }
>
> -BusInfo *qdev_get_bus_info(DeviceState *dev)
> -{
> -    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> -    return dc->bus_info;
> -}
> -
> -Property *qdev_get_props(DeviceState *dev)
> -{
> -    DeviceClass *dc = DEVICE_GET_CLASS(dev);
> -    return dc->props;
> -}
> -
>   const char *qdev_fw_name(DeviceState *dev)
>   {
>       DeviceClass *dc = DEVICE_GET_CLASS(dev);
> @@ -78,20 +66,12 @@ static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
>
>   void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
>   {
> -    Property *prop;
> -
>       if (qdev_hotplug) {
>           assert(bus->allow_hotplug);
>       }
>
>       dev->parent_bus = bus;
>       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_prop_set_defaults(dev, dev->parent_bus->info->props);
>   }
>
>   /* Create a new device.  This only initializes the device state structure
> @@ -615,6 +595,7 @@ void qdev_property_add_static(DeviceState *dev, Property *prop,
>   static void device_initfn(Object *obj)
>   {
>       DeviceState *dev = DEVICE(obj);
> +    ObjectClass *class;
>       Property *prop;
>
>       if (qdev_hotplug) {
> @@ -625,12 +606,15 @@ static void device_initfn(Object *obj)
>       dev->instance_id_alias = -1;
>       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);
> -    }
> -
> -    qdev_prop_set_defaults(dev, qdev_get_props(dev));
> +    class = object_get_class(OBJECT(dev));
> +    do {
> +        for (prop = DEVICE_CLASS(class)->props; prop&&  prop->name; prop++) {
> +            qdev_property_add_legacy(dev, prop, NULL);
> +            qdev_property_add_static(dev, prop, NULL);
> +        }
> +        qdev_prop_set_defaults(dev, DEVICE_CLASS(class)->props);
> +        class = object_class_get_parent(class);
> +    } while (class != object_class_by_name(TYPE_DEVICE));
>   }


This little bit of magic is a bit too magical for my taste.

Polymorphism relies on the idea that a subclass overloads base class 
members/methods.  From the base classes perspective, it's unaware if a subclass 
has overloaded something (that's allowed to be overloaded).

This code doesn't get the current class *as* the base class but rather gets the 
non-overloaded form of the base class.  This isn't really something that most OO 
systems allow and I think it could lead to major ugliness in the future.

I much prefer moving property installation to a function call that is invoked 
during base class init.

Regards,

Anthony Liguori

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

* Re: [Qemu-devel] [PATCH 14/21] qdev: remove qdev_prop_set_defaults
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 14/21] qdev: remove qdev_prop_set_defaults Paolo Bonzini
@ 2012-05-02 12:30   ` Anthony Liguori
  2012-05-24 16:30     ` Andreas Färber
  0 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2012-05-02 12:30 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, qemu-devel, afaerber, liwp

On 05/02/2012 06:31 AM, Paolo Bonzini wrote:
> Instead, qdev_property_add_static can set the default.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>

Great idea!

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

Regards,

Anthony Liguori

> ---
>   hw/qdev-properties.c |   22 ----------------------
>   hw/qdev.c            |   26 +++++++++++++++++++++++---
>   hw/qdev.h            |    1 -
>   3 files changed, 23 insertions(+), 26 deletions(-)
>
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index 572b83c..244646c 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -1130,28 +1130,6 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
>       *ptr = value;
>   }
>
> -void qdev_prop_set_defaults(DeviceState *dev, Property *props)
> -{
> -    Object *obj = OBJECT(dev);
> -    if (!props)
> -        return;
> -    for (; props->name; props++) {
> -        Error *errp = NULL;
> -        if (props->qtype == QTYPE_NONE) {
> -            continue;
> -        }
> -        if (props->qtype == QTYPE_QBOOL) {
> -            object_property_set_bool(obj, props->defval, props->name,&errp);
> -        } else if (props->info->enum_table) {
> -            object_property_set_str(obj, props->info->enum_table[props->defval],
> -                                    props->name,&errp);
> -        } else if (props->qtype == QTYPE_QINT) {
> -            object_property_set_int(obj, props->defval, props->name,&errp);
> -        }
> -        assert_no_error(errp);
> -    }
> -}
> -
>   static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
>
>   static void qdev_prop_register_global(GlobalProperty *prop)
> diff --git a/hw/qdev.c b/hw/qdev.c
> index 7288b8e..f953c51 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -576,6 +576,9 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
>   void qdev_property_add_static(DeviceState *dev, Property *prop,
>                                 Error **errp)
>   {
> +    Error *local_err = NULL;
> +    Object *obj = OBJECT(dev);
> +
>       /*
>        * TODO qdev_prop_ptr does not have getters or setters.  It must
>        * go now that it can be replaced with links.  The test should be
> @@ -585,10 +588,28 @@ void qdev_property_add_static(DeviceState *dev, Property *prop,
>           return;
>       }
>
> -    object_property_add(OBJECT(dev), prop->name, prop->info->name,
> +    object_property_add(obj, prop->name, prop->info->name,
>                           prop->info->get, prop->info->set,
>                           prop->info->release,
> -                        prop, errp);
> +                        prop,&local_err);
> +
> +    if (local_err) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +    if (prop->qtype == QTYPE_NONE) {
> +        return;
> +    }
> +
> +    if (prop->qtype == QTYPE_QBOOL) {
> +        object_property_set_bool(obj, prop->defval, prop->name,&local_err);
> +    } else if (prop->info->enum_table) {
> +        object_property_set_str(obj, prop->info->enum_table[prop->defval],
> +                                prop->name,&local_err);
> +    } else if (prop->qtype == QTYPE_QINT) {
> +        object_property_set_int(obj, prop->defval, prop->name,&local_err);
> +    }
> +    assert_no_error(local_err);
>   }
>
>   static void device_initfn(Object *obj)
> @@ -611,7 +632,6 @@ static void device_initfn(Object *obj)
>               qdev_property_add_legacy(dev, prop, NULL);
>               qdev_property_add_static(dev, prop, NULL);
>           }
> -        qdev_prop_set_defaults(dev, DEVICE_CLASS(class)->props);
>           class = object_class_get_parent(class);
>       } while (class != object_class_by_name(TYPE_DEVICE));
>       qdev_prop_set_globals(dev);
> diff --git a/hw/qdev.h b/hw/qdev.h
> index 4d6458f..23147df 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -311,7 +311,6 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
>   void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
>   /* FIXME: Remove opaque pointer properties.  */
>   void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
> -void qdev_prop_set_defaults(DeviceState *dev, Property *props);
>
>   void qdev_prop_register_global_list(GlobalProperty *props);
>   void qdev_prop_set_globals(DeviceState *dev);

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

* Re: [Qemu-devel] [PATCH 05/21] qom: assert that public types have a non-NULL parent field
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 05/21] qom: assert that public types have a non-NULL parent field Paolo Bonzini
@ 2012-05-02 12:35   ` Andreas Färber
  2012-05-23 17:01     ` Andreas Färber
  0 siblings, 1 reply; 64+ messages in thread
From: Andreas Färber @ 2012-05-02 12:35 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, aliguori, qemu-devel, liwp

Am 02.05.2012 13:30, schrieb Paolo Bonzini:
> This protects against unwanted effects of changing TYPE_OBJECT from
> NULL to a string.  Suggested by Andreas Faerber.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  include/qemu/object.h |    1 -
>  qom/object.c          |   14 ++++++++++----
>  2 files changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/include/qemu/object.h b/include/qemu/object.h
> index 9c49d99..ec2b382 100644
> --- a/include/qemu/object.h
> +++ b/include/qemu/object.h
> @@ -527,7 +527,6 @@ const char *object_get_typename(Object *obj);
>   */
>  Type type_register_static(const TypeInfo *info);
>  
> -#define type_register_static_alias(info, name) do { } while (0)

Unrelated removal of unused code?

Other than that

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

Thanks,
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] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 11/21] qdev: move bus properties to abstract superclasses
  2012-05-02 12:29   ` Anthony Liguori
@ 2012-05-02 13:21     ` Paolo Bonzini
  2012-05-02 20:00       ` Anthony Liguori
  0 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 13:21 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: peter maydell, qemu-devel, afaerber, liwp


> This little bit of magic is a bit too magical for my taste.
> 
> Polymorphism relies on the idea that a subclass overloads base class
> members/methods.  From the base classes perspective, it's unaware if
> a subclass has overloaded something (that's allowed to be overloaded).
> 
> This code doesn't get the current class *as* the base class but rather gets the
> non-overloaded form of the base class.  This isn't really something
> that most OO systems allow and I think it could lead to major ugliness in the
> future.

Not really, in fact this kind of class-side data is really bread and butter
of all dynamic languages, and it's how most of them implement polymorphism.
They have an associative array (method names -> method bytecode for example)
in each class on the hierarchy, and walk the hierarchy for each function call.
Doing method lookups like that is not something we can do in C of course, but
for data it's perfectly fine IMHO.

> I much prefer moving property installation to a function call that is
> invoked during base class init.

That leaves you without the possibility to inspect static property info,
unless you do the gross-ish hack of calling object_new and immediately
freeing the object.

Paolo

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

* Re: [Qemu-devel] [PATCH 11/21] qdev: move bus properties to abstract superclasses
  2012-05-02 13:21     ` Paolo Bonzini
@ 2012-05-02 20:00       ` Anthony Liguori
  2012-05-02 21:50         ` Paolo Bonzini
  0 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2012-05-02 20:00 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter maydell, qemu-devel, afaerber, liwp

On 05/02/2012 08:21 AM, Paolo Bonzini wrote:
>
>> This little bit of magic is a bit too magical for my taste.
>>
>> Polymorphism relies on the idea that a subclass overloads base class
>> members/methods.  From the base classes perspective, it's unaware if
>> a subclass has overloaded something (that's allowed to be overloaded).
>>
>> This code doesn't get the current class *as* the base class but rather gets the
>> non-overloaded form of the base class.  This isn't really something
>> that most OO systems allow and I think it could lead to major ugliness in the
>> future.
>
> Not really, in fact this kind of class-side data is really bread and butter
> of all dynamic languages, and it's how most of them implement polymorphism.
> They have an associative array (method names ->  method bytecode for example)
> in each class on the hierarchy, and walk the hierarchy for each function call.

I'm not aware of any language that does this.

Many languages today have an associative array in the object.  It's filled out 
from a class definition during instantiation.  This is what allows monkey patching.

Classes are first class objects and can contain members, but I don't know of any 
system where you actively look at the same field in a super class for each class 
in the hierarchy.  That's really trippy.

If we move properties to Object, I'd rather just stick a property pointer in 
TypeInfo and call it a day.  I'm not thrilled about it, but I feel a lot better 
about it the above.

Regards,

Anthony Liguori

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

* Re: [Qemu-devel] [PATCH 11/21] qdev: move bus properties to abstract superclasses
  2012-05-02 20:00       ` Anthony Liguori
@ 2012-05-02 21:50         ` Paolo Bonzini
  2012-05-03 12:45           ` Anthony Liguori
  0 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-02 21:50 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: liwp, peter maydell, qemu-devel, afaerber

Il 02/05/2012 22:00, Anthony Liguori ha scritto:
>>
>> Not really, in fact this kind of class-side data is really bread and
>> butter
>> of all dynamic languages, and it's how most of them implement
>> polymorphism.
>> They have an associative array (method names ->  method bytecode for
>> example)
>> in each class on the hierarchy, and walk the hierarchy for each
>> function call.
> 
> I'm not aware of any language that does this.

Python:

    class A:
        def a(self):
            return "a"

    class B(A):
        def b(self):
            return "b"

    B.__dict__
    # {'__module__': '__main__', 'b': <function b at 0x7f9308aab668>, '__doc__': None}

    print(B().b())
    # b

    B.__dict__["a"]
    # Traceback (most recent call last):
    #   File "<stdin>", line 1, in <module>
    # KeyError: 'a'

    print(B().a())
    # a

Smalltalk:

    'abc' class
    # String

    String methodDictionary includesKey: #==
    # false

    Object methodDictionary includesKey: #=
    # true


Ruby too:

     class A
       def a() end
    end
    class B < A
      def b() end
    end
    B.instance_methods
    # [:b, :a, :nil?, :===, :=~, ...]
    B.instance_methods(include_super=false)
    # [:b]

but I don't know exactly how to access the dictionary here.

> Many languages today have an associative array in the object.  It's
> filled out from a class definition during instantiation.  This is what
> allows monkey patching.

That's just Javascript as far as I know.  Python has an associative array
in the object _and_ one in the class, and they aren't exactly the same
thing:

    class A:
        def a(self):
            return "a"

    A.__dict__
    {'a': <function a at 0x7f67c8dc1578>, '__module__': '__main__', '__doc__': None}

    x = A()
    x.__dict__
    # {}

    x.a()
    # 'a'

    x.__dict__["a"] = lambda self: self
    x.__dict__
    # {'a': <function <lambda> at 0x7f67c8dc1500>}

    x.a()
    # Traceback (most recent call last):
    #   File "<stdin>", line 1, in <module>
    # TypeError: <lambda>() takes exactly 1 argument (0 given)

    x.a('look, no implicit self anymore!')
    'look, no implicit self anymore!'

    y = A()
    y.a()
    # 'a'

Ruby has an associative array in the object and one in the class, and they
work as expected:

    class A
      def a() end
    end

    x = A.new
    # <A:0x000000027e0db8>
    x.a
    # nil
    x.define_singleton_method("a") { puts "i'm special" }
    x.a
    # i'm special
    # nil
    x.singleton_methods
    # [:a]

    y = A.new
    y.a
    # nil
    y.singleton_methods
    # []

> Classes are first class objects and can contain members, but I don't
> know of any system where you actively look at the same field in a
> super class for each class in the hierarchy. That's really trippy.

Just because it's new to you.  Smalltalk has been doing that for 30-odd
years.

Of course the VM has a lot of caching going on, but it's entirely
internal.

> If we move properties to Object, I'd rather just stick a property
> pointer in TypeInfo and call it a day. I'm not thrilled about it, but
> I feel a lot better about it the above.

What if we add declarative links or children, for example?  Adding more
junk to TypeInfo is not the solution.

Paolo

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

* Re: [Qemu-devel] [PATCH 11/21] qdev: move bus properties to abstract superclasses
  2012-05-02 21:50         ` Paolo Bonzini
@ 2012-05-03 12:45           ` Anthony Liguori
  2012-05-03 12:56             ` Paolo Bonzini
  0 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2012-05-03 12:45 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: liwp, peter maydell, qemu-devel, afaerber

On 05/02/2012 04:50 PM, Paolo Bonzini wrote:
> Il 02/05/2012 22:00, Anthony Liguori ha scritto:
>
>> Classes are first class objects and can contain members, but I don't
>> know of any system where you actively look at the same field in a
>> super class for each class in the hierarchy. That's really trippy.
>
> Just because it's new to you.  Smalltalk has been doing that for 30-odd
> years.

Ok, I've played around quite a bit with Python now and you are right.  But I 
still don't like what you're proposing.  I have two main reasons:

1) I think it's too clever.  I understand you disagree and this wouldn't be a 
sticking point for me but nonetheless, I want to register that compliant :-)

2) If you do introspection in this method, it means that *all* properties have 
to be registered as static properties to be introspected.  That's a blocker for 
me.  We're always going to need to do the object_new() + enumerate + 
object_delete() trick in order to introspect non-static properties.

> Of course the VM has a lot of caching going on, but it's entirely
> internal.
>
>> If we move properties to Object, I'd rather just stick a property
>> pointer in TypeInfo and call it a day. I'm not thrilled about it, but
>> I feel a lot better about it the above.
>
> What if we add declarative links or children, for example?  Adding more
> junk to TypeInfo is not the solution.

Yes, I dislike this too.  It was a suggestion of a lesser evil although in 
retrospect, it's not much less of an evil.

Regards,

Anthony Liguori

>
> Paolo
>

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

* Re: [Qemu-devel] [PATCH 11/21] qdev: move bus properties to abstract superclasses
  2012-05-03 12:45           ` Anthony Liguori
@ 2012-05-03 12:56             ` Paolo Bonzini
  0 siblings, 0 replies; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-03 12:56 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: liwp, peter maydell, qemu-devel, afaerber

Il 03/05/2012 14:45, Anthony Liguori ha scritto:
> On 05/02/2012 04:50 PM, Paolo Bonzini wrote:
>> Il 02/05/2012 22:00, Anthony Liguori ha scritto:
>>
>>> Classes are first class objects and can contain members, but I don't
>>> know of any system where you actively look at the same field in a
>>> super class for each class in the hierarchy. That's really trippy.
>>
>> Just because it's new to you.  Smalltalk has been doing that for 30-odd
>> years.
> 
> Ok, I've played around quite a bit with Python now and you are right. 
> But I still don't like what you're proposing.  I have two main reasons:
> 
> 1) I think it's too clever.  I understand you disagree and this wouldn't
> be a sticking point for me but nonetheless, I want to register that
> compliant :-)

Fair. :)

> 2) If you do introspection in this method, it means that *all*
> properties have to be registered as static properties to be
> introspected.  That's a blocker for me.  We're always going to need to
> do the object_new() + enumerate + object_delete() trick in order to
> introspect non-static properties.

Enumeration without some assistance from the class is impossible anyway
if you go with lazily-created properties for "big" arrays (such as those
you find in interrupt controllers).

Paolo

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

* Re: [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (20 preceding siblings ...)
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 21/21] qbus: initialize in standard way Paolo Bonzini
@ 2012-05-04 16:15 ` Paolo Bonzini
  2012-05-23 15:43 ` Paolo Bonzini
  22 siblings, 0 replies; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-04 16:15 UTC (permalink / raw)
  Cc: peter.maydell, aliguori, qemu-devel, afaerber, liwp

Il 02/05/2012 13:30, Paolo Bonzini ha scritto:
> Here is Anthony's qbus conversion, with the qdev_add_properties changes
> replaced by my bus property changes.
> 
> I left out the removal of bus methods; I'm not sure I agree with all of
> them (though I may just give up :)) and anyway they can be left to 1.2.
> 
> Following Andreas's remark, I moved all TYPE_* definitions for buses
> to the same file that defines the struct, and added typecasting macros.
> 
> I'm still a bit weary of putting this in this late, but I'll defer to
> others on this too.
> 
> Anthony Liguori (6):
>   qdev: fix adding of ptr properties
>   qdev: use wrapper for qdev_get_path
>   qdev: convert busses to QEMU Object Model
>   qdev: connect busses with their parent devices
>   qbus: make child devices links
>   qbus: initialize in standard way
> 
> Paolo Bonzini (15):
>   qom: documentation addition
>   qom: add object_class_get_parent
>   qom: add class_base_init
>   qom: make Object a type
>   qom: assert that public types have a non-NULL parent field
>   qdev: push "type" property up to Object
>   qdev: fix -device foo,?
>   qdev: use object_property_print in info qtree
>   qdev: move bus properties to a separate global
>   qdev: do not propagate properties to subclasses
>   qdev: move bus properties to abstract superclasses
>   pc: add back PCI.rombar compat property
>   qdev: clean up global properties
>   qdev: remove qdev_prop_set_defaults
>   qdev: move sysbus initialization to sysbus.c

Guys, I'll let you decide what to do about this.  If anyone wnts to pick
up the reviews and resubmit in my place, that would be nice.

In any case, patches 7-8 should be blockers for rc1.

Paolo

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

* Re: [Qemu-devel] [PATCH 01/21] qom: documentation addition
  2012-05-02 11:59   ` Andreas Färber
@ 2012-05-11  2:08     ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-11  2:08 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, aliguori, qemu-devel, liwp

Am 02.05.2012 13:59, schrieb Andreas Färber:
> Am 02.05.2012 13:30, schrieb Paolo Bonzini:
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>  include/qemu/object.h |    6 ++++++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/include/qemu/object.h b/include/qemu/object.h
>> index ca1649c..d315dfa 100644
>> --- a/include/qemu/object.h
>> +++ b/include/qemu/object.h
>> @@ -555,6 +555,12 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *klass,
>>   */
>>  const char *object_class_get_name(ObjectClass *klass);
>>  
>> +/**
>> + * object_class_by_name:
>> + * @typename: The QOM typename to obtain the class for.
>> + *
>> + * Returns: The class for @typename.
> 
> ...or NULL if not found.
> 
>> + */
>>  ObjectClass *object_class_by_name(const char *typename);
>>  
>>  void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),

Thanks, applied to qom-next (with the suggested addition, using %NULL,
and extended subject):
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

If there's no protest, I'd also queue this for a 1.1-rc2 PULL.

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

* Re: [Qemu-devel] [PATCH 02/21] qom: add object_class_get_parent
  2012-05-02 12:21   ` Andreas Färber
@ 2012-05-11  2:25     ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-11  2:25 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, aliguori, qemu-devel, liwp

Am 02.05.2012 14:21, schrieb Andreas Färber:
> Am 02.05.2012 13:30, schrieb Paolo Bonzini:
>> This simple bit of functionality was missing and we'll need it soon,
>> so add it.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>  include/qemu/object.h |    8 ++++++++
>>  qom/object.c          |   13 +++++++++++++
>>  2 files changed, 21 insertions(+)
>>
>> diff --git a/include/qemu/object.h b/include/qemu/object.h
>> index d315dfa..063c817 100644
>> --- a/include/qemu/object.h
>> +++ b/include/qemu/object.h
>> @@ -548,6 +548,14 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *klass,
>>                                         const char *typename);
>>  
>>  /**
>> + * object_class_get_parent:
>> + * @klass: The class to obtain the parent for.
>> + *
>> + * Returns: The parent for @klass.
> 
> Here too we should indicate that this may return NULL (rather than
> aborting). Other than that looks good.

Thanks, applied to qom-next (with extended documentation):
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

I added Anthony's Reviewed-by from v1, since v2 only split off
documentation on my request.

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

* Re: [Qemu-devel] [PATCH 07/21] qdev: fix -device foo,?
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 07/21] qdev: fix -device foo,? Paolo Bonzini
@ 2012-05-11 14:03   ` Andreas Färber
  2012-05-14 20:11   ` Anthony Liguori
  1 sibling, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-11 14:03 UTC (permalink / raw)
  To: Paolo Bonzini, aliguori; +Cc: peter.maydell, qemu-devel, liwp

Am 02.05.2012 13:30, schrieb Paolo Bonzini:
> Since most property types do not have a parse property now, this was
> broken.  Fix it by looking at the setter instead.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Acked-by: Andreas Färber <afaerber@suse.de>

I'm guessing Anthony has this one in his 1.1-rc2 queue already; I'm
applying it to qom-1.1 and qom-next branches:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-1.1
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

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

* Re: [Qemu-devel] [PATCH 08/21] qdev: use object_property_print in info qtree
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 08/21] qdev: use object_property_print in info qtree Paolo Bonzini
@ 2012-05-11 14:20   ` Andreas Färber
  2012-05-11 14:45     ` Paolo Bonzini
  0 siblings, 1 reply; 64+ messages in thread
From: Andreas Färber @ 2012-05-11 14:20 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, aliguori, qemu-devel, liwp

Am 02.05.2012 13:31, schrieb Paolo Bonzini:
> Otherwise, non-string properties without a legacy counterpart are missed.
> Also fix error propagation in object_property_print itself.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/qdev-monitor.c |    2 +-
>  qom/object.c      |    2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
> index 41b9e2c..eed781d 100644
> --- a/hw/qdev-monitor.c
> +++ b/hw/qdev-monitor.c
> @@ -493,7 +493,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
>          if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) {
>              value = object_property_get_str(OBJECT(dev), legacy_name, &err);
>          } else {
> -            value = object_property_get_str(OBJECT(dev), props->name, &err);
> +            value = object_property_print(OBJECT(dev), props->name, &err);
>          }
>          g_free(legacy_name);
>  
> diff --git a/qom/object.c b/qom/object.c
> index 464fc8f..b4f6c1d 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -839,7 +839,7 @@ char *object_property_print(Object *obj, const char *name,
>      char *string;

char *string = NULL;

>  
>      mo = string_output_visitor_new();
> -    object_property_get(obj, string_output_get_visitor(mo), name, NULL);
> +    object_property_get(obj, string_output_get_visitor(mo), name, errp);

If we do error checking we should be consequent and do:

if (!error_is_set(errp)) {

>      string = string_output_get_string(mo);

}

>      string_output_visitor_cleanup(mo);
>      return string;

Otherwise looks good and a 1.1 candidate.

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

* Re: [Qemu-devel] [PATCH 08/21] qdev: use object_property_print in info qtree
  2012-05-11 14:20   ` Andreas Färber
@ 2012-05-11 14:45     ` Paolo Bonzini
  2012-05-12  0:23       ` Andreas Färber
  0 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-11 14:45 UTC (permalink / raw)
  To: Andreas Färber; +Cc: peter.maydell, aliguori, qemu-devel, liwp

Il 11/05/2012 16:20, Andreas Färber ha scritto:
> char *string = NULL;
> 
>> >  
>> >      mo = string_output_visitor_new();
>> > -    object_property_get(obj, string_output_get_visitor(mo), name, NULL);
>> > +    object_property_get(obj, string_output_get_visitor(mo), name, errp);
> If we do error checking we should be consequent and do:
> 
> if (!error_is_set(errp)) {
> 
>> >      string = string_output_get_string(mo);
> }
> 
>> >      string_output_visitor_cleanup(mo);

Or just say that it is part of the string_output_visitor interface that
in case of an error the returned string is NULL.

Paolo

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

* Re: [Qemu-devel] [PATCH 08/21] qdev: use object_property_print in info qtree
  2012-05-11 14:45     ` Paolo Bonzini
@ 2012-05-12  0:23       ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-12  0:23 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, aliguori, qemu-devel, liwp

Am 11.05.2012 16:45, schrieb Paolo Bonzini:
> Il 11/05/2012 16:20, Andreas Färber ha scritto:
>> char *string = NULL;
>>
>>>>  
>>>>      mo = string_output_visitor_new();
>>>> -    object_property_get(obj, string_output_get_visitor(mo), name, NULL);
>>>> +    object_property_get(obj, string_output_get_visitor(mo), name, errp);
>> If we do error checking we should be consequent and do:
>>
>> if (!error_is_set(errp)) {
>>
>>>>      string = string_output_get_string(mo);
>> }
>>
>>>>      string_output_visitor_cleanup(mo);
> 
> Or just say that it is part of the string_output_visitor interface that
> in case of an error the returned string is NULL.

I see it now: The StringOutputVisitor is allocated with g_malloc0(), so
that it's initially NULL. get_string_output() would thus simply pass
through NULL and doesn't need special error handling.

Thanks, applied to qom-1.1 and qom-next:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-1.1
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

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

* Re: [Qemu-devel] [PATCH 15/21] qdev: fix adding of ptr properties
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 15/21] qdev: fix adding of ptr properties Paolo Bonzini
@ 2012-05-12 12:34   ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-12 12:34 UTC (permalink / raw)
  To: Paolo Bonzini, Anthony Liguori; +Cc: peter.maydell, qemu-devel, liwp

Am 02.05.2012 13:31, schrieb Paolo Bonzini:
> From: Anthony Liguori <aliguori@us.ibm.com>
> 
> ptr properties have neither a get/set or a print/parse which means that when
> they're added they aren't treated as static or legacy properties.
> 
> Just assume properties like this are legacy properties and treat them as such.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Thanks, applied to qom-1.1 and qom-next:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-1.1
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

Anthony, if you have this locally already,

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

* Re: [Qemu-devel] [PATCH 07/21] qdev: fix -device foo,?
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 07/21] qdev: fix -device foo,? Paolo Bonzini
  2012-05-11 14:03   ` Andreas Färber
@ 2012-05-14 20:11   ` Anthony Liguori
  1 sibling, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2012-05-14 20:11 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, qemu-devel, afaerber, liwp

On 05/02/2012 06:30 AM, Paolo Bonzini wrote:
> Since most property types do not have a parse property now, this was
> broken.  Fix it by looking at the setter instead.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>

Applied.  Thanks.

Regards,

Anthony Liguori

> ---
>   hw/qdev-monitor.c |    4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
> index dc4e4e1..41b9e2c 100644
> --- a/hw/qdev-monitor.c
> +++ b/hw/qdev-monitor.c
> @@ -158,7 +158,7 @@ int qdev_device_help(QemuOpts *opts)
>            * for removal.  This conditional should be removed along with
>            * it.
>            */
> -        if (!prop->info->parse) {
> +        if (!prop->info->set) {
>               continue;           /* no way to set it, don't show */
>           }
>           error_printf("%s.%s=%s\n", driver, prop->name,
> @@ -166,7 +166,7 @@ int qdev_device_help(QemuOpts *opts)
>       }
>       if (info->bus_info) {
>           for (prop = info->bus_info->props; prop&&  prop->name; prop++) {
> -            if (!prop->info->parse) {
> +            if (!prop->info->set) {
>                   continue;           /* no way to set it, don't show */
>               }
>               error_printf("%s.%s=%s\n", driver, prop->name,

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

* Re: [Qemu-devel] [PATCH 03/21] qom: add class_base_init
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 03/21] qom: add class_base_init Paolo Bonzini
@ 2012-05-14 21:34   ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-14 21:34 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, aliguori, qemu-devel, liwp

Am 02.05.2012 13:30, schrieb Paolo Bonzini:
> The class_base_init TypeInfo callback was present in one of the early
> QOM versions but removed (on my request...) before committing.  We
> will need it soon, add it.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Anthony had added a Reviewed-by to v1.

Thanks, applied to qom-next:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

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

* Re: [Qemu-devel] [PATCH 04/21] qom: make Object a type
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 04/21] qom: make Object a type Paolo Bonzini
@ 2012-05-16  8:16   ` Andreas Färber
  2012-05-23 16:53     ` Andreas Färber
  0 siblings, 1 reply; 64+ messages in thread
From: Andreas Färber @ 2012-05-16  8:16 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: liwp, Paolo Bonzini, qemu-devel, peter.maydell

Am 02.05.2012 13:30, schrieb Paolo Bonzini:
> Right now the base Object class has a special NULL type.  Change this so
> that we will be able to add class_init and class_base_init callbacks.
> To do this, remove some special casing of ObjectClass that is not really
> necessary.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Anthony, you had Reviewed-by an earlier version of this patch but then
did it differently in your series. Should I apply this to qom-next or is
there some issue with it? The issue of unintended NULL .parent that I
raised is being addressed with a followup patch.

Thanks,
Andreas

> ---
>  include/qemu/object.h |    2 +-
>  qom/object.c          |   59 +++++++++++++++++++++++++------------------------
>  2 files changed, 31 insertions(+), 30 deletions(-)
> 
> diff --git a/include/qemu/object.h b/include/qemu/object.h
> index 597a2f6..9c49d99 100644
> --- a/include/qemu/object.h
> +++ b/include/qemu/object.h
> @@ -33,7 +33,7 @@ typedef struct TypeInfo TypeInfo;
>  typedef struct InterfaceClass InterfaceClass;
>  typedef struct InterfaceInfo InterfaceInfo;
>  
> -#define TYPE_OBJECT NULL
> +#define TYPE_OBJECT "object"
>  
>  /**
>   * SECTION:object.h
> diff --git a/qom/object.c b/qom/object.c
> index e66d3ab..88ec417 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -210,7 +210,7 @@ static void type_class_interface_init(TypeImpl *ti, InterfaceImpl *iface)
>  
>  static void type_initialize(TypeImpl *ti)
>  {
> -    size_t class_size = sizeof(ObjectClass);
> +    TypeImpl *parent;
>      int i;
>  
>      if (ti->class) {
> @@ -221,30 +221,24 @@ static void type_initialize(TypeImpl *ti)
>      ti->instance_size = type_object_get_size(ti);
>  
>      ti->class = g_malloc0(ti->class_size);
> -    ti->class->type = ti;
> -
> -    if (type_has_parent(ti)) {
> -        TypeImpl *parent = type_get_parent(ti);
>  
> +    parent = type_get_parent(ti);
> +    if (parent) {
>          type_initialize(parent);
>  
> -        class_size = parent->class_size;
>          g_assert(parent->class_size <= ti->class_size);
> +        memcpy(ti->class, parent->class, parent->class_size);
> +    }
>  
> -        memcpy((void *)ti->class + sizeof(ObjectClass),
> -               (void *)parent->class + sizeof(ObjectClass),
> -               parent->class_size - sizeof(ObjectClass));
> +    ti->class->type = ti;
>  
> -        while (parent) {
> -            if (parent->class_base_init) {
> -                parent->class_base_init(ti->class, ti->class_data);
> -            }
> -            parent = type_get_parent(parent);
> +    while (parent) {
> +        if (parent->class_base_init) {
> +            parent->class_base_init(ti->class, ti->class_data);
>          }
> +        parent = type_get_parent(parent);
>      }
>  
> -    memset((void *)ti->class + class_size, 0, ti->class_size - class_size);
> -
>      for (i = 0; i < ti->num_interfaces; i++) {
>          type_class_interface_init(ti, &ti->interfaces[i]);
>      }
> @@ -467,19 +461,6 @@ Object *object_dynamic_cast(Object *obj, const char *typename)
>  }
>  
>  
> -static void register_types(void)
> -{
> -    static TypeInfo interface_info = {
> -        .name = TYPE_INTERFACE,
> -        .instance_size = sizeof(Interface),
> -        .abstract = true,
> -    };
> -
> -    type_interface = type_register_static(&interface_info);
> -}
> -
> -type_init(register_types)
> -
>  Object *object_dynamic_cast_assert(Object *obj, const char *typename)
>  {
>      Object *inst;
> @@ -1216,3 +1197,23 @@ void object_property_add_str(Object *obj, const char *name,
>                          property_release_str,
>                          prop, errp);
>  }
> +
> +static void register_types(void)
> +{
> +    static TypeInfo interface_info = {
> +        .name = TYPE_INTERFACE,
> +        .instance_size = sizeof(Interface),
> +        .abstract = true,
> +    };
> +
> +    static TypeInfo object_info = {
> +        .name = TYPE_OBJECT,
> +        .instance_size = sizeof(Object),
> +        .abstract = true,
> +    };
> +
> +    type_interface = type_register_static(&interface_info);
> +    type_register_static(&object_info);
> +}
> +
> +type_init(register_types)


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

* Re: [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches
  2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
                   ` (21 preceding siblings ...)
  2012-05-04 16:15 ` [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
@ 2012-05-23 15:43 ` Paolo Bonzini
  22 siblings, 0 replies; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-23 15:43 UTC (permalink / raw)
  Cc: peter.maydell, aliguori, qemu-devel, afaerber, liwp

Il 02/05/2012 13:30, Paolo Bonzini ha scritto:
> Anthony Liguori (6):
>   qdev: fix adding of ptr properties
>   qdev: use wrapper for qdev_get_path
>   qdev: convert busses to QEMU Object Model
>   qdev: connect busses with their parent devices
>   qbus: make child devices links
>   qbus: initialize in standard way
> 
> Paolo Bonzini (15):
>   qom: documentation addition
>   qom: add object_class_get_parent
>   qom: add class_base_init
>   qom: make Object a type
>   qom: assert that public types have a non-NULL parent field
>   qdev: push "type" property up to Object
>   qdev: fix -device foo,?
>   qdev: use object_property_print in info qtree
>   qdev: move bus properties to a separate global
>   qdev: do not propagate properties to subclasses
>   qdev: move bus properties to abstract superclasses
>   pc: add back PCI.rombar compat property
>   qdev: clean up global properties
>   qdev: remove qdev_prop_set_defaults
>   qdev: move sysbus initialization to sysbus.c

I rebased and pushed this to qdev-props-4 in my github repo.  Feel free
to pull --rebase it to qom-next.  I'll shortly send realize patches too.

Paolo

>  exec.c                        |    4 +-
>  hw/acpi_piix4.c               |   10 +-
>  hw/i2c.c                      |   30 +++--
>  hw/ide/internal.h             |    3 +
>  hw/ide/qdev.c                 |   31 +++--
>  hw/intel-hda.c                |   37 ++---
>  hw/intel-hda.h                |    3 +
>  hw/isa-bus.c                  |   23 +++-
>  hw/isa.h                      |    3 +
>  hw/lsi53c895a.c               |    5 +-
>  hw/pc_piix.c                  |    9 +-
>  hw/pci-hotplug.c              |    6 +-
>  hw/pci.c                      |   49 ++++---
>  hw/pci_bridge.c               |    2 +-
>  hw/pci_internals.h            |    3 +-
>  hw/qdev-monitor.c             |  105 ++++++++-------
>  hw/qdev-properties.c          |   62 +++------
>  hw/qdev.c                     |  298 +++++++++++++++++++++++++++--------------
>  hw/qdev.h                     |   56 ++++----
>  hw/s390-virtio-bus.c          |   37 ++---
>  hw/s390-virtio-bus.h          |    3 +
>  hw/scsi-bus.c                 |   54 +++++---
>  hw/scsi.h                     |    3 +
>  hw/spapr_pci.c                |    7 +-
>  hw/spapr_vio.c                |   49 ++++---
>  hw/spapr_vio.h                |    3 +
>  hw/spapr_vty.c                |    6 +-
>  hw/ssi.c                      |   29 ++--
>  hw/sysbus.c                   |   45 ++++++-
>  hw/sysbus.h                   |    3 +
>  hw/usb.h                      |    3 +
>  hw/usb/bus.c                  |   45 ++++---
>  hw/usb/desc.c                 |    5 +-
>  hw/usb/dev-smartcard-reader.c |   25 ++--
>  hw/virtio-scsi.c              |    6 +-
>  hw/virtio-serial-bus.c        |   35 +++--
>  include/qemu/object.h         |   27 +++-
>  qom/object.c                  |  105 +++++++++++----
>  savevm.c                      |   12 +-
>  39 files changed, 783 insertions(+), 458 deletions(-)
> 

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

* Re: [Qemu-devel] [PATCH 04/21] qom: make Object a type
  2012-05-16  8:16   ` Andreas Färber
@ 2012-05-23 16:53     ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-23 16:53 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: peter.maydell, Paolo Bonzini, liwp, qemu-devel

Am 16.05.2012 10:16, schrieb Andreas Färber:
> Am 02.05.2012 13:30, schrieb Paolo Bonzini:
>> Right now the base Object class has a special NULL type.  Change this so
>> that we will be able to add class_init and class_base_init callbacks.
>> To do this, remove some special casing of ObjectClass that is not really
>> necessary.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> 
> Anthony, you had Reviewed-by an earlier version of this patch but then
> did it differently in your series. Should I apply this to qom-next or is
> there some issue with it? The issue of unintended NULL .parent that I
> raised is being addressed with a followup patch.

Anthony agreed to this version on IRC so I've applied this to qom-next:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

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

* Re: [Qemu-devel] [PATCH 05/21] qom: assert that public types have a non-NULL parent field
  2012-05-02 12:35   ` Andreas Färber
@ 2012-05-23 17:01     ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-23 17:01 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, aliguori, qemu-devel, liwp

Am 02.05.2012 14:35, schrieb Andreas Färber:
> Am 02.05.2012 13:30, schrieb Paolo Bonzini:
>> This protects against unwanted effects of changing TYPE_OBJECT from
>> NULL to a string.  Suggested by Andreas Faerber.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>  include/qemu/object.h |    1 -
>>  qom/object.c          |   14 ++++++++++----
>>  2 files changed, 10 insertions(+), 5 deletions(-)
>>
>> diff --git a/include/qemu/object.h b/include/qemu/object.h
>> index 9c49d99..ec2b382 100644
>> --- a/include/qemu/object.h
>> +++ b/include/qemu/object.h
>> @@ -527,7 +527,6 @@ const char *object_get_typename(Object *obj);
>>   */
>>  Type type_register_static(const TypeInfo *info);
>>  
>> -#define type_register_static_alias(info, name) do { } while (0)
> 
> Unrelated removal of unused code?
> 
> Other than that
> 
> Reviewed-by: Andreas Färber <afaerber@suse.de>

Split in two and applied to qom-next:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

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

* Re: [Qemu-devel] [PATCH 06/21] qdev: push "type" property up to Object
  2012-05-02 11:30 ` [Qemu-devel] [PATCH 06/21] qdev: push "type" property up to Object Paolo Bonzini
@ 2012-05-23 17:06   ` Andreas Färber
  2012-05-23 17:18     ` Paolo Bonzini
  0 siblings, 1 reply; 64+ messages in thread
From: Andreas Färber @ 2012-05-23 17:06 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Blue Swirl, peter.maydell, aliguori, qemu-devel, liwp

Am 02.05.2012 13:30, schrieb Paolo Bonzini:
> Now that Object is a type, add an instance_init function and push
> the "type" property from qdev to there.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

The rebased version from qdev-props-4 breaks and hangs `make check`:

GTESTER check-qtest-sparc
qemu-system-sparc: Insufficient permission to perform this operation

Paolo, can you please investigate?

Thanks,
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] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 06/21] qdev: push "type" property up to Object
  2012-05-23 17:06   ` Andreas Färber
@ 2012-05-23 17:18     ` Paolo Bonzini
  2012-05-23 17:40       ` Andreas Färber
  0 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-23 17:18 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Blue Swirl, peter.maydell, aliguori, qemu-devel, liwp

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

Il 23/05/2012 19:06, Andreas Färber ha scritto:
> Am 02.05.2012 13:30, schrieb Paolo Bonzini:
>> Now that Object is a type, add an instance_init function and push
>> the "type" property from qdev to there.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> 
> The rebased version from qdev-props-4 breaks and hangs `make check`:
> 
> GTESTER check-qtest-sparc
> qemu-system-sparc: Insufficient permission to perform this operation
> 
> Paolo, can you please investigate?

Please try this patch (untested; please add my signed-off-by if you end
up committing it).

There is also a "type" property in arm_l2x0.c, but it seems unused.

Paolo


[-- Attachment #2: m48t59.patch --]
[-- Type: text/x-patch, Size: 4687 bytes --]

diff --git a/hw/m48t59.c b/hw/m48t59.c
index 24dcbfa..3cc2178 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -65,7 +65,7 @@ struct M48t59State {
     /* NVRAM storage */
     uint8_t *buffer;
     /* Model parameters */
-    uint32_t type; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
+    uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
     /* NVRAM storage */
     uint16_t addr;
     uint8_t  lock;
@@ -197,9 +197,9 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
 	NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, addr, val);
 
     /* check for NVRAM access */
-    if ((NVRAM->type == 2 && addr < 0x7f8) ||
-        (NVRAM->type == 8 && addr < 0x1ff8) ||
-        (NVRAM->type == 59 && addr < 0x1ff0))
+    if ((NVRAM->model == 2 && addr < 0x7f8) ||
+        (NVRAM->model == 8 && addr < 0x1ff8) ||
+        (NVRAM->model == 59 && addr < 0x1ff0))
         goto do_write;
 
     /* TOD access */
@@ -334,7 +334,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val)
 	tmp = from_bcd(val);
 	if (tmp >= 0 && tmp <= 99) {
 	    get_time(NVRAM, &tm);
-            if (NVRAM->type == 8)
+            if (NVRAM->model == 8)
                 tm.tm_year = from_bcd(val) + 68; // Base year is 1968
             else
                 tm.tm_year = from_bcd(val);
@@ -362,9 +362,9 @@ uint32_t m48t59_read (void *opaque, uint32_t addr)
     uint32_t retval = 0xFF;
 
     /* check for NVRAM access */
-    if ((NVRAM->type == 2 && addr < 0x078f) ||
-        (NVRAM->type == 8 && addr < 0x1ff8) ||
-        (NVRAM->type == 59 && addr < 0x1ff0))
+    if ((NVRAM->model == 2 && addr < 0x078f) ||
+        (NVRAM->model == 8 && addr < 0x1ff8) ||
+        (NVRAM->model == 59 && addr < 0x1ff0))
         goto do_read;
 
     /* TOD access */
@@ -439,7 +439,7 @@ uint32_t m48t59_read (void *opaque, uint32_t addr)
     case 0x07FF:
         /* year */
         get_time(NVRAM, &tm);
-        if (NVRAM->type == 8)
+        if (NVRAM->model == 8)
             retval = to_bcd(tm.tm_year - 68); // Base year is 1968
         else
             retval = to_bcd(tm.tm_year);
@@ -633,7 +633,7 @@ static const MemoryRegionOps m48t59_io_ops = {
 
 /* Initialisation routine */
 M48t59State *m48t59_init(qemu_irq IRQ, target_phys_addr_t mem_base,
-                         uint32_t io_base, uint16_t size, int type)
+                         uint32_t io_base, uint16_t size, int model)
 {
     DeviceState *dev;
     SysBusDevice *s;
@@ -641,7 +641,7 @@ M48t59State *m48t59_init(qemu_irq IRQ, target_phys_addr_t mem_base,
     M48t59State *state;
 
     dev = qdev_create(NULL, "m48t59");
-    qdev_prop_set_uint32(dev, "type", type);
+    qdev_prop_set_uint32(dev, "model", model);
     qdev_prop_set_uint32(dev, "size", size);
     qdev_prop_set_uint32(dev, "io_base", io_base);
     qdev_init_nofail(dev);
@@ -661,14 +661,14 @@ M48t59State *m48t59_init(qemu_irq IRQ, target_phys_addr_t mem_base,
 }
 
 M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
-                             int type)
+                             int model)
 {
     M48t59ISAState *d;
     ISADevice *dev;
     M48t59State *s;
 
     dev = isa_create(bus, "m48t59_isa");
-    qdev_prop_set_uint32(&dev->qdev, "type", type);
+    qdev_prop_set_uint32(&dev->qdev, "model", model);
     qdev_prop_set_uint32(&dev->qdev, "size", size);
     qdev_prop_set_uint32(&dev->qdev, "io_base", io_base);
     qdev_init_nofail(&dev->qdev);
@@ -686,7 +686,7 @@ M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size,
 static void m48t59_init_common(M48t59State *s)
 {
     s->buffer = g_malloc0(s->size);
-    if (s->type == 59) {
+    if (s->model == 59) {
         s->alrm_timer = qemu_new_timer_ns(rtc_clock, &alarm_cb, s);
         s->wd_timer = qemu_new_timer_ns(vm_clock, &watchdog_cb, s);
     }
@@ -722,7 +722,7 @@ static int m48t59_init1(SysBusDevice *dev)
 
 static Property m48t59_isa_properties[] = {
     DEFINE_PROP_UINT32("size",    M48t59ISAState, state.size,    -1),
-    DEFINE_PROP_UINT32("type",    M48t59ISAState, state.type,    -1),
+    DEFINE_PROP_UINT32("model",   M48t59ISAState, state.model,    -1),
     DEFINE_PROP_HEX32( "io_base", M48t59ISAState, state.io_base,  0),
     DEFINE_PROP_END_OF_LIST(),
 };
@@ -746,7 +746,7 @@ static TypeInfo m48t59_isa_info = {
 
 static Property m48t59_properties[] = {
     DEFINE_PROP_UINT32("size",    M48t59SysBusState, state.size,    -1),
-    DEFINE_PROP_UINT32("type",    M48t59SysBusState, state.type,    -1),
+    DEFINE_PROP_UINT32("model",   M48t59SysBusState, state.model,    -1),
     DEFINE_PROP_HEX32( "io_base", M48t59SysBusState, state.io_base,  0),
     DEFINE_PROP_END_OF_LIST(),
 };

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

* Re: [Qemu-devel] [PATCH 06/21] qdev: push "type" property up to Object
  2012-05-23 17:18     ` Paolo Bonzini
@ 2012-05-23 17:40       ` Andreas Färber
  2012-05-23 18:00         ` Paolo Bonzini
  0 siblings, 1 reply; 64+ messages in thread
From: Andreas Färber @ 2012-05-23 17:40 UTC (permalink / raw)
  To: Paolo Bonzini, peter.maydell; +Cc: Blue Swirl, aliguori, qemu-devel

Am 23.05.2012 19:18, schrieb Paolo Bonzini:
> Il 23/05/2012 19:06, Andreas Färber ha scritto:
>> Am 02.05.2012 13:30, schrieb Paolo Bonzini:
>>> Now that Object is a type, add an instance_init function and push
>>> the "type" property from qdev to there.
>>>
>>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>>
>> The rebased version from qdev-props-4 breaks and hangs `make check`:
>>
>> GTESTER check-qtest-sparc
>> qemu-system-sparc: Insufficient permission to perform this operation
>>
>> Paolo, can you please investigate?
> 
> Please try this patch (untested; please add my signed-off-by if you end
> up committing it).

Tested make check and PReP. I added some braces missing in the original
code to please checkpatch.pl and applied both to qom-next:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

Paolo, please let me know if you're okay with my commit messages, then I
can override the author to be you as well (same for preceding one).

BTW note that I usually update subjects to start with a capital letter
to visually separate the lowercase topic from the actual summary. ;)

> There is also a "type" property in arm_l2x0.c, but it seems unused.

Peter, can we drop that property? I'd insert such a patch before then.

Thanks,
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] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 06/21] qdev: push "type" property up to Object
  2012-05-23 17:40       ` Andreas Färber
@ 2012-05-23 18:00         ` Paolo Bonzini
  0 siblings, 0 replies; 64+ messages in thread
From: Paolo Bonzini @ 2012-05-23 18:00 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Blue Swirl, peter.maydell, aliguori, qemu-devel

Il 23/05/2012 19:40, Andreas Färber ha scritto:
> Paolo, please let me know if you're okay with my commit messages, then I
> can override the author to be you as well (same for preceding one).

Don't worry, you have carte blanche. :)

Paolo

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

* Re: [Qemu-devel] [PATCH 09/21] qdev: move bus properties to a separate global
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 09/21] qdev: move bus properties to a separate global Paolo Bonzini
@ 2012-05-23 23:39   ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-23 23:39 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, aliguori, qemu-devel

Am 02.05.2012 13:31, schrieb Paolo Bonzini:
> Simple code movement in order to simplify future refactoring.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Thanks, re-verified all movements on qdev-props-4 and applied to qom-next:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

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

* Re: [Qemu-devel] [PATCH 10/21] qdev: do not propagate properties to subclasses
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 10/21] qdev: do not propagate properties to subclasses Paolo Bonzini
@ 2012-05-23 23:46   ` Andreas Färber
  2012-05-24  1:34     ` Andreas Färber
  0 siblings, 1 reply; 64+ messages in thread
From: Andreas Färber @ 2012-05-23 23:46 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, aliguori, qemu-devel

Am 02.05.2012 13:31, schrieb Paolo Bonzini:
> As soon as we'll look up properties along the inheritance chain, we
> will have duplicates if class A defines some properties and its
> subclass B does not define any, because class_b->props will be
> left equal to class_a->props.
> 
> The solution here is to reintroduce the class_base_init TypeInfo
> callback, that was present in one of the early QOM versions but
> removed (on my request...) before committing.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

This breaks `make check` once again:

GTESTER check-qtest-i386
qemu-system-i386: Property '.id' not found

Andreas

> ---
>  hw/qdev.c |   11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/hw/qdev.c b/hw/qdev.c
> index 94fb32e..67d7770 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -658,6 +658,16 @@ static void device_finalize(Object *obj)
>      QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
>  }
>  
> +static void device_class_base_init(ObjectClass *class, void *data)
> +{
> +    DeviceClass *klass = DEVICE_CLASS(class);
> +
> +    /* We explicitly look up properties in the superclasses,
> +     * so do not propagate them to the subclasses.
> +     */
> +    klass->props = NULL;
> +}
> +
>  void device_reset(DeviceState *dev)
>  {
>      DeviceClass *klass = DEVICE_GET_CLASS(dev);
> @@ -684,6 +694,7 @@ static TypeInfo device_type_info = {
>      .instance_size = sizeof(DeviceState),
>      .instance_init = device_initfn,
>      .instance_finalize = device_finalize,
> +    .class_base_init = device_class_base_init,
>      .abstract = true,
>      .class_size = sizeof(DeviceClass),
>  };

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

* Re: [Qemu-devel] [PATCH 10/21] qdev: do not propagate properties to subclasses
  2012-05-23 23:46   ` Andreas Färber
@ 2012-05-24  1:34     ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-24  1:34 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, aliguori, qemu-devel

Am 24.05.2012 01:46, schrieb Andreas Färber:
> Am 02.05.2012 13:31, schrieb Paolo Bonzini:
>> As soon as we'll look up properties along the inheritance chain, we
>> will have duplicates if class A defines some properties and its
>> subclass B does not define any, because class_b->props will be
>> left equal to class_a->props.
>>
>> The solution here is to reintroduce the class_base_init TypeInfo
>> callback, that was present in one of the early QOM versions but
>> removed (on my request...) before committing.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> 
> This breaks `make check` once again:
> 
> GTESTER check-qtest-i386
> qemu-system-i386: Property '.id' not found

This was caused by the APIC 'id' property (dot in error message is
misleading). IIUC it's because it's defined for the base class. Solved
by squashing into the following commit. Applied to qom-next:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

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

* Re: [Qemu-devel] [PATCH 13/21] qdev: clean up global properties
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 13/21] qdev: clean up global properties Paolo Bonzini
@ 2012-05-24 16:27   ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-24 16:27 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, aliguori, qemu-devel

Am 02.05.2012 13:31, schrieb Paolo Bonzini:
> Now that global properties do not depend on buses anymore, set
> them directly in the device instance_init function.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Thanks, applied to qom-next:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

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

* Re: [Qemu-devel] [PATCH 14/21] qdev: remove qdev_prop_set_defaults
  2012-05-02 12:30   ` Anthony Liguori
@ 2012-05-24 16:30     ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-24 16:30 UTC (permalink / raw)
  To: Anthony Liguori, Paolo Bonzini; +Cc: peter.maydell, qemu-devel, liwp

Am 02.05.2012 14:30, schrieb Anthony Liguori:
> On 05/02/2012 06:31 AM, Paolo Bonzini wrote:
>> Instead, qdev_property_add_static can set the default.
>>
>> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> 
> Great idea!
> 
> Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>

Thanks, applied to qom-next:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

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

* Re: [Qemu-devel] [PATCH 16/21] qdev: use wrapper for qdev_get_path
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 16/21] qdev: use wrapper for qdev_get_path Paolo Bonzini
@ 2012-05-24 16:31   ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-24 16:31 UTC (permalink / raw)
  To: Paolo Bonzini, aliguori; +Cc: peter.maydell, qemu-devel

Am 02.05.2012 13:31, schrieb Paolo Bonzini:
> From: Anthony Liguori <aliguori@us.ibm.com>
> 
> This makes it easier to remove it from BusInfo.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Thanks, applied to qom-next:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

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

* Re: [Qemu-devel] [PATCH 17/21] qdev: move sysbus initialization to sysbus.c
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 17/21] qdev: move sysbus initialization to sysbus.c Paolo Bonzini
@ 2012-05-24 16:32   ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-24 16:32 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: peter.maydell, aliguori, qemu-devel

Am 02.05.2012 13:31, schrieb Paolo Bonzini:
> TYPE_SYSTEM_BUS will be local to hw/sysbus.c, so move existing references
> to main_system_bus and system_bus_info there.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Thanks, applied to qom-next:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

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

* Re: [Qemu-devel] [PATCH 18/21] qdev: convert busses to QEMU Object Model
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 18/21] qdev: convert busses to QEMU Object Model Paolo Bonzini
@ 2012-05-24 16:48   ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-24 16:48 UTC (permalink / raw)
  To: Paolo Bonzini, Anthony Liguori; +Cc: peter.maydell, qemu-devel

Am 02.05.2012 13:31, schrieb Paolo Bonzini:
> From: Anthony Liguori <aliguori@us.ibm.com>
> 
> 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 <aliguori@us.ibm.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Thanks, I applied this to qom-next with two changes:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

First, I enforced all new TypeInfos to be static const rather than just
static. If someone has time to fix up all the static ones in the code
base to not set bad examples that would be appreciated - they needed to
be writable originally while transitioning from qdev to QOM.

Second, I applied the following patch on top, backporting
object_delete() / object_finalize() from "qbus: initialize in standard
way", since we introduce object_new() usage here:

diff --git a/hw/pci.c b/hw/pci.c
index c5d3100..b2afcf6 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -295,7 +295,7 @@ PCIBus *pci_bus_new(DeviceState *parent, const char
*name,
     PCIBus *bus;

     bus = g_malloc0(sizeof(*bus));
-    bus->qbus.qdev_allocated = 1;
+    bus->qbus.glib_allocated = true;
     pci_bus_new_inplace(bus, parent, name, address_space_mem,
                         address_space_io, devfn_min);
     return bus;
diff --git a/hw/qdev.c b/hw/qdev.c
index 63baa0a..63012b5 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -423,7 +423,7 @@ BusState *qbus_create(const char *typename,
DeviceState *parent, const char *nam
     BusState *bus;

     bus = BUS(object_new(typename));
-    bus->qdev_allocated = 1;
+    bus->qom_allocated = true;
     do_qbus_create_inplace(bus, typename, parent, name);
     return bus;
 }
@@ -443,8 +443,13 @@ void qbus_free(BusState *bus)
         qemu_unregister_reset(qbus_reset_all_fn, bus);
     }
     g_free((void*)bus->name);
-    if (bus->qdev_allocated) {
-        g_free(bus);
+    if (bus->qom_allocated) {
+        object_delete(OBJECT(bus));
+    } else {
+        object_finalize(OBJECT(bus));
+        if (bus->glib_allocated) {
+            g_free(bus);
+        }
     }
 }

diff --git a/hw/qdev.h b/hw/qdev.h
index 0da4b74..f3dd004 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -100,12 +100,19 @@ struct BusClass {
     int (*reset)(BusState *bus);
 };

+/**
+ * BusState:
+ * @qom_allocated: Indicates whether the object was allocated by QOM.
+ * @glib_allocated: Indicates whether the object was initialized in-place
+ * yet is expected to be freed with g_free().
+ */
 struct BusState {
     Object obj;
     DeviceState *parent;
     const char *name;
     int allow_hotplug;
-    int qdev_allocated;
+    bool qom_allocated;
+    bool glib_allocated;
     QTAILQ_HEAD(ChildrenHead, DeviceState) children;
     QLIST_ENTRY(BusState) sibling;
 };
diff --git a/hw/sysbus.c b/hw/sysbus.c
index 369ee44..2347f51 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -274,7 +274,7 @@ static void main_system_bus_create(void)
     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;
+    main_system_bus->glib_allocated = true;
 }

 BusState *sysbus_get_default(void)


I admit that qom_allocated vs. glib_allocated is slightly ugly but it is
more correct. If memory serves me correctly there was talk of
hotplugging PCI host controllers on pseries for passthrough or
something, so properly cleaning up seems worth the additional ~four bytes.
Fix-ups welcome - maybe use an enum or, better, fix the PCIBus
allocation scheme so that we can drop glib_allocated (SysBus is asserted
not to be freed).

Regards,
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 related	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 19/21] qdev: connect busses with their parent devices
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 19/21] qdev: connect busses with their parent devices Paolo Bonzini
@ 2012-05-24 16:49   ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-24 16:49 UTC (permalink / raw)
  To: Paolo Bonzini, aliguori; +Cc: peter.maydell, qemu-devel

Am 02.05.2012 13:31, schrieb Paolo Bonzini:
> From: Anthony Liguori <aliguori@us.ibm.com>
> 
> This makes sysbus part of the root hierarchy and all busses children of their
> respective parent DeviceState.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Thanks, applied to qom-next:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

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

* Re: [Qemu-devel] [PATCH 20/21] qbus: make child devices links
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 20/21] qbus: make child devices links Paolo Bonzini
@ 2012-05-24 16:51   ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-24 16:51 UTC (permalink / raw)
  To: Paolo Bonzini, Anthony Liguori; +Cc: peter.maydell, qemu-devel

Am 02.05.2012 13:31, schrieb Paolo Bonzini:
> From: Anthony Liguori <aliguori@us.ibm.com>
> 
> Make qbus children show up as link<> properties.  There is no stable addressing
> for qbus children so we use an unstable naming convention.
> 
> This is okay in QOM though because the composition name is expected to be what's
> stable.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Thanks, applied to qom-next:
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

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

* Re: [Qemu-devel] [PATCH 21/21] qbus: initialize in standard way
  2012-05-02 11:31 ` [Qemu-devel] [PATCH 21/21] qbus: initialize in standard way Paolo Bonzini
@ 2012-05-24 16:52   ` Andreas Färber
  0 siblings, 0 replies; 64+ messages in thread
From: Andreas Färber @ 2012-05-24 16:52 UTC (permalink / raw)
  To: Paolo Bonzini, Anthony Liguori; +Cc: peter.maydell, qemu-devel

Am 02.05.2012 13:31, schrieb Paolo Bonzini:
> From: Anthony Liguori <aliguori@us.ibm.com>
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Thanks, applied to qom-next (extending the commit message):
http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/qom-next

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

end of thread, other threads:[~2012-05-24 16:53 UTC | newest]

Thread overview: 64+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-02 11:30 [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
2012-05-02 11:30 ` [Qemu-devel] [PATCH 01/21] qom: documentation addition Paolo Bonzini
2012-05-02 11:59   ` Andreas Färber
2012-05-11  2:08     ` Andreas Färber
2012-05-02 11:30 ` [Qemu-devel] [PATCH 02/21] qom: add object_class_get_parent Paolo Bonzini
2012-05-02 12:21   ` Andreas Färber
2012-05-11  2:25     ` Andreas Färber
2012-05-02 11:30 ` [Qemu-devel] [PATCH 03/21] qom: add class_base_init Paolo Bonzini
2012-05-14 21:34   ` Andreas Färber
2012-05-02 11:30 ` [Qemu-devel] [PATCH 04/21] qom: make Object a type Paolo Bonzini
2012-05-16  8:16   ` Andreas Färber
2012-05-23 16:53     ` Andreas Färber
2012-05-02 11:30 ` [Qemu-devel] [PATCH 05/21] qom: assert that public types have a non-NULL parent field Paolo Bonzini
2012-05-02 12:35   ` Andreas Färber
2012-05-23 17:01     ` Andreas Färber
2012-05-02 11:30 ` [Qemu-devel] [PATCH 06/21] qdev: push "type" property up to Object Paolo Bonzini
2012-05-23 17:06   ` Andreas Färber
2012-05-23 17:18     ` Paolo Bonzini
2012-05-23 17:40       ` Andreas Färber
2012-05-23 18:00         ` Paolo Bonzini
2012-05-02 11:30 ` [Qemu-devel] [PATCH 07/21] qdev: fix -device foo,? Paolo Bonzini
2012-05-11 14:03   ` Andreas Färber
2012-05-14 20:11   ` Anthony Liguori
2012-05-02 11:31 ` [Qemu-devel] [PATCH 08/21] qdev: use object_property_print in info qtree Paolo Bonzini
2012-05-11 14:20   ` Andreas Färber
2012-05-11 14:45     ` Paolo Bonzini
2012-05-12  0:23       ` Andreas Färber
2012-05-02 11:31 ` [Qemu-devel] [PATCH 09/21] qdev: move bus properties to a separate global Paolo Bonzini
2012-05-23 23:39   ` Andreas Färber
2012-05-02 11:31 ` [Qemu-devel] [PATCH 10/21] qdev: do not propagate properties to subclasses Paolo Bonzini
2012-05-23 23:46   ` Andreas Färber
2012-05-24  1:34     ` Andreas Färber
2012-05-02 11:31 ` [Qemu-devel] [PATCH 11/21] qdev: move bus properties to abstract superclasses Paolo Bonzini
2012-05-02 12:29   ` Anthony Liguori
2012-05-02 13:21     ` Paolo Bonzini
2012-05-02 20:00       ` Anthony Liguori
2012-05-02 21:50         ` Paolo Bonzini
2012-05-03 12:45           ` Anthony Liguori
2012-05-03 12:56             ` Paolo Bonzini
2012-05-02 11:31 ` [Qemu-devel] [PATCH 12/21] pc: add back PCI.rombar compat property Paolo Bonzini
2012-05-02 11:38   ` Michael S. Tsirkin
2012-05-02 11:41     ` Paolo Bonzini
2012-05-02 11:44       ` Michael S. Tsirkin
2012-05-02 11:31 ` [Qemu-devel] [PATCH 13/21] qdev: clean up global properties Paolo Bonzini
2012-05-24 16:27   ` Andreas Färber
2012-05-02 11:31 ` [Qemu-devel] [PATCH 14/21] qdev: remove qdev_prop_set_defaults Paolo Bonzini
2012-05-02 12:30   ` Anthony Liguori
2012-05-24 16:30     ` Andreas Färber
2012-05-02 11:31 ` [Qemu-devel] [PATCH 15/21] qdev: fix adding of ptr properties Paolo Bonzini
2012-05-12 12:34   ` Andreas Färber
2012-05-02 11:31 ` [Qemu-devel] [PATCH 16/21] qdev: use wrapper for qdev_get_path Paolo Bonzini
2012-05-24 16:31   ` Andreas Färber
2012-05-02 11:31 ` [Qemu-devel] [PATCH 17/21] qdev: move sysbus initialization to sysbus.c Paolo Bonzini
2012-05-24 16:32   ` Andreas Färber
2012-05-02 11:31 ` [Qemu-devel] [PATCH 18/21] qdev: convert busses to QEMU Object Model Paolo Bonzini
2012-05-24 16:48   ` Andreas Färber
2012-05-02 11:31 ` [Qemu-devel] [PATCH 19/21] qdev: connect busses with their parent devices Paolo Bonzini
2012-05-24 16:49   ` Andreas Färber
2012-05-02 11:31 ` [Qemu-devel] [PATCH 20/21] qbus: make child devices links Paolo Bonzini
2012-05-24 16:51   ` Andreas Färber
2012-05-02 11:31 ` [Qemu-devel] [PATCH 21/21] qbus: initialize in standard way Paolo Bonzini
2012-05-24 16:52   ` Andreas Färber
2012-05-04 16:15 ` [Qemu-devel] [PATCH 00/21] qbus QOM conversion, rebased on top of my patches Paolo Bonzini
2012-05-23 15:43 ` Paolo Bonzini

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