diff mbox

[v3,029/197] Start integration of qom w/qdev.

Message ID 1323721273-32404-30-git-send-email-aliguori@us.ibm.com
State New
Headers show

Commit Message

Anthony Liguori Dec. 12, 2011, 8:18 p.m. UTC
---
 hw/object.c |   14 ++++++++++----
 hw/object.h |   16 +++++++++++++---
 hw/qdev.c   |   30 ++++++++++++++++++++++++++++--
 3 files changed, 51 insertions(+), 9 deletions(-)
diff mbox

Patch

diff --git a/hw/object.c b/hw/object.c
index be61677..520591a 100644
--- a/hw/object.c
+++ b/hw/object.c
@@ -17,7 +17,7 @@ 
 typedef struct InterfaceImpl
 {
     const char *parent;
-    void (*interface_initfn)(ObjectClass *class);
+    void (*interface_initfn)(ObjectClass *class, void *data);
     Type type;
 } InterfaceImpl;
 
@@ -33,8 +33,10 @@  typedef struct TypeImpl
     void (*base_init)(ObjectClass *klass);
     void (*base_finalize)(ObjectClass *klass);
 
-    void (*class_init)(ObjectClass *klass);
-    void (*class_finalize)(ObjectClass *klass);
+    void (*class_init)(ObjectClass *klass, void *data);
+    void (*class_finalize)(ObjectClass *klass, void *data);
+
+    void *class_data;
 
     void (*instance_init)(Object *obj);
     void (*instance_finalize)(Object *obj);
@@ -61,6 +63,8 @@  Type type_register_static(const TypeInfo *info)
 
     assert(info->name != NULL);
 
+    printf("Added type %s -> %s\n", info->name, info->parent);
+
     ti->name = info->name;
     ti->parent = info->parent;
     ti->type = type;
@@ -73,6 +77,7 @@  Type type_register_static(const TypeInfo *info)
 
     ti->class_init = info->class_init;
     ti->class_finalize = info->class_finalize;
+    ti->class_data = info->class_data;
 
     ti->instance_init = info->instance_init;
     ti->instance_finalize = info->instance_finalize;
@@ -114,6 +119,7 @@  static Type type_register_anonymous(const TypeInfo *info)
 
     ti->class_init = info->class_init;
     ti->class_finalize = info->class_finalize;
+    ti->class_data = info->class_data;
 
     ti->instance_init = info->instance_init;
     ti->instance_finalize = info->instance_finalize;
@@ -237,7 +243,7 @@  static void type_class_init(TypeImpl *ti)
     }
 
     if (ti->class_init) {
-        ti->class_init(ti->class);
+        ti->class_init(ti->class, ti->class_data);
     }
 }
 
diff --git a/hw/object.h b/hw/object.h
index 834e89e..b02709e 100644
--- a/hw/object.h
+++ b/hw/object.h
@@ -27,6 +27,8 @@  typedef struct InterfaceClass InterfaceClass;
 typedef struct Interface Interface;
 typedef struct InterfaceInfo InterfaceInfo;
 
+#define TYPE_OBJECT NULL
+
 /**
  * @ObjectClass:
  *
@@ -183,7 +185,7 @@  struct TypeInfo
      * 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.
      */
-    void (*class_init)(ObjectClass *klass);
+    void (*class_init)(ObjectClass *klass, void *data);
 
     /**
      * @class_finalize
@@ -191,7 +193,15 @@  struct TypeInfo
      * This function is called during class destruction and is meant to release
      * and dynamic parameters allocated by @class_init.
      */
-    void (*class_finalize)(ObjectClass *klass);
+    void (*class_finalize)(ObjectClass *klass, void *data);
+
+    /**
+     * @class_data
+     *
+     * Data to pass to the @class_init and @class_finalize functions.  This can
+     * be useful when building dynamic classes.
+     */
+    void *class_data;
 
     /**
      * Interfaces
@@ -306,7 +316,7 @@  struct InterfaceInfo
      * initialize any default virtual functions for a class and/or override
      * virtual functions in a parent class.
      */
-    void (*interface_initfn)(ObjectClass *class);
+    void (*interface_initfn)(ObjectClass *class, void *data);
 };
 
 #define TYPE_INTERFACE "interface"
diff --git a/hw/qdev.c b/hw/qdev.c
index 83913c7..7a5aa9f 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -44,12 +44,23 @@  static BusState *qbus_find_recursive(BusState *bus, const char *name,
                                      const BusInfo *info);
 static BusState *qbus_find(const char *path);
 
+#define TYPE_DEVICE "device"
+#define DEVICE(obj) OBJECT_CHECK(DeviceState, (obj), TYPE_DEVICE)
+
 /* Register a new device type.  */
 void qdev_register(DeviceInfo *info)
 {
+    TypeInfo type_info = {};
+
     assert(info->size >= sizeof(DeviceState));
     assert(!info->next);
 
+    type_info.name = info->name;
+    type_info.parent = TYPE_DEVICE;
+    type_info.instance_size = info->size;
+
+    type_register_static(&type_info);
+
     info->next = device_info_list;
     device_info_list = info;
 }
@@ -86,7 +97,7 @@  static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
     Property *prop;
 
     assert(bus->info == info->bus_info);
-    dev = g_malloc0(info->size);
+    dev = DEVICE(object_new(info->name));
     dev->info = info;
     dev->parent_bus = bus;
     qdev_prop_set_defaults(dev, dev->info->props);
@@ -484,7 +495,7 @@  void qdev_free(DeviceState *dev)
             prop->info->free(dev, prop);
         }
     }
-    g_free(dev);
+    object_delete(OBJECT(dev));
 }
 
 void qdev_machine_creation_done(void)
@@ -1515,3 +1526,18 @@  void qdev_property_add_str(DeviceState *dev, const char *name,
                       qdev_property_release_str,
                       prop, errp);
 }
+
+static TypeInfo device_type_info = {
+    .name = TYPE_DEVICE,
+    .parent = TYPE_OBJECT,
+    .instance_size = sizeof(DeviceState),
+    .abstract = true,
+    .class_size = sizeof(DeviceClass),
+};
+
+static void init_qdev(void)
+{
+    type_register_static(&device_type_info);
+}
+
+device_init(init_qdev);