* being inside the device struct.
*/
.offset = (uintptr_t)elem - (uintptr_t)obj,
+ .link_type = parent_prop->link_type,
};
}
qobject_unref(values);
}
+void qlist_append_link(QList *qlist, Object *obj)
+{
+ g_autofree char *path = object_get_canonical_path(obj);
+ qlist_append_str(qlist, path);
+}
+
static GPtrArray *global_props(void)
{
static GPtrArray *gp;
OBJ_PROP_LINK_STRONG);
}
+/*
+ * The logic in these get_link() and set_link() functions is similar
+ * to that used for single-element link properties in the
+ * object_get_link_property() and object_set_link_property() functions.
+ * The difference is largely in how we get the expected type of the
+ * link: for us it is in the Property struct, and for a single link
+ * property it is part of the property name on the object.
+ */
+static void get_link(Object *obj, Visitor *v, const char *name, void *opaque,
+ Error **errp)
+{
+ const Property *prop = opaque;
+ Object **targetp = object_field_prop_ptr(obj, prop);
+ g_autofree char *path = NULL;
+
+ if (*targetp) {
+ path = object_get_canonical_path(*targetp);
+ visit_type_str(v, name, &path, errp);
+ } else {
+ path = g_strdup("");
+ visit_type_str(v, name, &path, errp);
+ }
+}
+
+static void set_link(Object *obj, Visitor *v, const char *name, void *opaque,
+ Error **errp)
+{
+ const Property *prop = opaque;
+ Object **targetp = object_field_prop_ptr(obj, prop);
+ g_autofree char *path = NULL;
+ Object *new_target, *old_target = *targetp;
+
+ ERRP_GUARD();
+
+ /* Get the path to the object we want to set the link to */
+ if (!visit_type_str(v, name, &path, errp)) {
+ return;
+ }
+
+ /* Now get the pointer to the actual object */
+ if (*path) {
+ new_target = object_resolve_and_typecheck(path, prop->name,
+ prop->link_type, errp);
+ if (!new_target) {
+ return;
+ }
+ } else {
+ new_target = NULL;
+ }
+
+ /*
+ * Our link properties are always OBJ_PROP_LINK_STRONG and
+ * have the allow_set_link_before_realize check.
+ */
+ qdev_prop_allow_set_link_before_realize(obj, prop->name, new_target, errp);
+ if (*errp) {
+ return;
+ }
+
+ *targetp = new_target;
+ object_ref(new_target);
+ object_unref(old_target);
+}
+
const PropertyInfo qdev_prop_link = {
.type = "link",
.create = create_link_property,
+ /*
+ * Since we have a create method, the get and set are used
+ * only in get_prop_array() and set_prop_array() for the case
+ * where we have an array of link properties.
+ */
+ .get = get_link,
+ .set = set_link,
};
void qdev_property_add_static(DeviceState *dev, const Property *prop)
DEFINE_PROP(_name, _state, _field, qdev_prop_link, _ptr_type, \
.link_type = _type)
+/**
+ * DEFINE_PROP_LINK_ARRAY:
+ * @_name: name of the array
+ * @_state: name of the device state structure type
+ * @_field: uint32_t field in @_state to hold the array length
+ * @_arrayfield: field in @_state (of type '@_arraytype *') which
+ * will point to the array
+ * @_linktype: QOM type name of the link type
+ * @_arraytype: C type of the array elements
+ *
+ * Define device properties for a variable-length array _name of links
+ * (i.e. this is the array version of DEFINE_PROP_LINK).
+ *
+ * The array is represented as a list of QStrings in the visitor interface,
+ * where each string is the QOM path of the object to be linked.
+ */
+#define DEFINE_PROP_LINK_ARRAY(_name, _state, _field, _arrayfield, \
+ _linktype, _arraytype) \
+ DEFINE_PROP(_name, _state, _field, qdev_prop_array, uint32_t, \
+ .set_default = true, \
+ .defval.u = 0, \
+ .arrayinfo = &qdev_prop_link, \
+ .arrayfieldsize = sizeof(_arraytype), \
+ .arrayoffset = offsetof(_state, _arrayfield), \
+ .link_type = _linktype)
+
#define DEFINE_PROP_UINT8(_n, _s, _f, _d) \
DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
#define DEFINE_PROP_UINT16(_n, _s, _f, _d) \
/* Takes ownership of @values */
void qdev_prop_set_array(DeviceState *dev, const char *name, QList *values);
+/**
+ * qlist_append_link: Add a QOM object to a QList of link properties
+ * @qlist: list to append to
+ * @obj: object to append
+ *
+ * This is a helper function for constructing a QList to pass to
+ * qdev_prop_set_array() when the qdev property array is an array of
+ * link properties (i.e. one defined with DEFINE_PROP_LINK_ARRAY).
+ *
+ * The object is encoded into the list as a QString which is the
+ * canonical path of the object; this is the same encoding that
+ * object_set_link_property() and object_get_link_property() use.
+ */
+void qlist_append_link(QList *qlist, Object *obj);
+
void *object_field_prop_ptr(Object *obj, const Property *prop);
void qdev_prop_register_global(GlobalProperty *prop);