The previous commit vacated the qdev_new()/qdev_try_new() names.
Reintroduce them with the signature we actually want:

  DeviceState *qdev_new(Object *parent, const char *id,
                        const char *type);

which is the qdev-layer, heap-allocated dual of
object_initialize_child(): the returned device is created and
immediately added to the QOM composition tree as a child of @parent
under @id.

Refcount contract: the initial reference is transferred to the
child<> property of @parent, so on return the caller does not hold a
reference.  Pair with qdev_realize() (not qdev_realize_and_unref()),
matching object_initialize_child()'s convention.

qdev_new_orphan() remains for callers that set the parent themselves
before realize (notably qdev_device_add(), which parents under
/machine/peripheral via qdev_set_id()).  Later patches convert the
remaining orphan callers subsystem by subsystem.

Suggested-by: Markus Armbruster <[email protected]>
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
AI-used-for: code (refactoring)
Signed-off-by: Alexander Graf <[email protected]>
---
 hw/core/qdev.c         | 20 ++++++++++++++++++++
 include/hw/core/qdev.h | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 8a8d206a02..947ba7db80 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -145,6 +145,26 @@ bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, 
Error **errp)
     return true;
 }
 
+DeviceState *qdev_new(Object *parent, const char *id, const char *type)
+{
+    return DEVICE(object_new_child(parent, id, type));
+}
+
+DeviceState *qdev_try_new(Object *parent, const char *id, const char *type)
+{
+    ObjectClass *oc = module_object_class_by_name(type);
+    Object *obj;
+
+    if (!oc) {
+        return NULL;
+    }
+    obj = object_new_with_class(oc);
+    g_assert(id[0] && !strchr(id, '/'));
+    object_property_add_child(parent, id, obj);
+    object_unref(obj);
+    return DEVICE(obj);
+}
+
 DeviceState *qdev_new_orphan(const char *name)
 {
     return DEVICE(object_new(name));
diff --git a/include/hw/core/qdev.h b/include/hw/core/qdev.h
index 839c1b4147..e692a1d48e 100644
--- a/include/hw/core/qdev.h
+++ b/include/hw/core/qdev.h
@@ -406,6 +406,40 @@ struct BusState {
 
 /*** Board API.  This should go away once we have a machine config file.  ***/
 
+/**
+ * qdev_new: Create a device and parent it in the QOM composition tree
+ * @parent: the QOM parent (usually the machine or containing device)
+ * @id: child<> property name; the device's canonical QOM path becomes
+ *      @parent's path plus "/" plus @id
+ * @type: device type to create (we assert() that this type exists)
+ *
+ * Heap-allocated counterpart to object_initialize_child().  This
+ * allocates and initializes the device state and immediately adds it
+ * as a child of @parent, ready for the caller to set properties and
+ * then realize.
+ *
+ * The reference count of the returned device is 1, held by @parent's
+ * child<> property.  The caller therefore does not hold a reference
+ * and pairs this with qdev_realize() (NOT qdev_realize_and_unref()).
+ *
+ * Return: a derived DeviceState, owned by @parent.
+ */
+DeviceState *qdev_new(Object *parent, const char *id, const char *type);
+
+/**
+ * qdev_try_new: Try to create a parented device on the heap
+ * @parent: the QOM parent
+ * @id: child<> property name
+ * @type: device type to create
+ *
+ * This is like qdev_new(), except it returns %NULL when @type does
+ * not exist, rather than asserting.
+ *
+ * Return: a derived DeviceState owned by @parent, or NULL if @type
+ * does not exist.
+ */
+DeviceState *qdev_try_new(Object *parent, const char *id, const char *type);
+
 /**
  * qdev_new_orphan: Create a device on the heap
  * @name: device type to create (we assert() that this type exists)
-- 
2.47.1


Reply via email to