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