diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2024-12-18 07:42:40 -0600 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2024-12-19 19:33:37 +0100 |
commit | cb9f4b28ee115f14f336a4a87c593fa1685e42df (patch) | |
tree | 62989ff2f6bfad05b86c9cc44b1713cf34289111 | |
parent | 588611972f774cacf2e15c73e3d61b54929c0528 (diff) | |
download | qemu-cb9f4b28ee115f14f336a4a87c593fa1685e42df.zip qemu-cb9f4b28ee115f14f336a4a87c593fa1685e42df.tar.gz qemu-cb9f4b28ee115f14f336a4a87c593fa1685e42df.tar.bz2 |
hw/core: Introduce device_class_set_props_n
Record the size of the array in DeviceClass.props_count_.
Iterate with known count in qdev_prop_walk.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Lei Yang <leiyang@redhat.com>
Link: https://lore.kernel.org/r/20241218134251.4724-14-richard.henderson@linaro.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | hw/core/qdev-properties.c | 39 | ||||
-rw-r--r-- | hw/core/qdev.c | 1 | ||||
-rw-r--r-- | include/hw/qdev-core.h | 18 | ||||
-rw-r--r-- | system/qdev-monitor.c | 15 |
4 files changed, 55 insertions, 18 deletions
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index de618a9..31e3072 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -749,16 +749,13 @@ const PropertyInfo qdev_prop_array = { /* --- public helpers --- */ -static const Property *qdev_prop_walk(const Property *props, const char *name) +static const Property *qdev_prop_walk(DeviceClass *cls, const char *name) { - if (!props) { - return NULL; - } - while (props->name) { - if (strcmp(props->name, name) == 0) { - return props; + for (int i = 0, n = cls->props_count_; i < n; ++i) { + const Property *prop = &cls->props_[i]; + if (strcmp(prop->name, name) == 0) { + return prop; } - props++; } return NULL; } @@ -771,7 +768,7 @@ static const Property *qdev_prop_find(DeviceState *dev, const char *name) /* device properties */ class = object_get_class(OBJECT(dev)); do { - prop = qdev_prop_walk(DEVICE_CLASS(class)->props_, name); + prop = qdev_prop_walk(DEVICE_CLASS(class), name); if (prop) { return prop; } @@ -1064,9 +1061,31 @@ static void qdev_class_add_legacy_property(DeviceClass *dc, const Property *prop void (device_class_set_props)(DeviceClass *dc, const Property *props) { const Property *prop; + size_t n; + + dc->props_ = props; + for (prop = props, n = 0; prop && prop->name; prop++, n++) { + qdev_class_add_legacy_property(dc, prop); + qdev_class_add_property(dc, prop->name, prop); + } + + /* We used a hole in DeviceClass because that's still a lot. */ + assert(n <= UINT16_MAX); + dc->props_count_ = n; +} + +void device_class_set_props_n(DeviceClass *dc, const Property *props, size_t n) +{ + /* We used a hole in DeviceClass because that's still a lot. */ + assert(n <= UINT16_MAX); + assert(n != 0); dc->props_ = props; - for (prop = props; prop && prop->name; prop++) { + dc->props_count_ = n; + + for (size_t i = 0; i < n; ++i) { + const Property *prop = &props[i]; + assert(prop->name); qdev_class_add_legacy_property(dc, prop); qdev_class_add_property(dc, prop->name, prop); } diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 5f13111..57c1d9d 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -703,6 +703,7 @@ static void device_class_base_init(ObjectClass *class, void *data) * so do not propagate them to the subclasses. */ klass->props_ = NULL; + klass->props_count_ = 0; } static void device_unparent(Object *obj) diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index cbce3cf..e9b4891 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -139,6 +139,12 @@ struct DeviceClass { const Property *props_; /** + * @props_count_: number of elements in @props_; should only be + * assigned by using device_class_set_props(). + */ + uint16_t props_count_; + + /** * @user_creatable: Can user instantiate with -device / device_add? * * All devices should support instantiation with device_add, and @@ -961,6 +967,18 @@ void device_class_set_props(DeviceClass *dc, const Property *props); } while (0) /** + * device_class_set_props_n(): add a set of properties to an device + * @dc: the parent DeviceClass all devices inherit + * @props: an array of properties, not terminated by DEFINE_PROP_END_OF_LIST. + * @n: ARRAY_SIZE(@props) + * + * This will add a set of properties to the object. It will fault if + * you attempt to add an existing property defined by a parent class. + * To modify an inherited property you need to use???? + */ +void device_class_set_props_n(DeviceClass *dc, const Property *props, size_t n); + +/** * device_class_set_parent_realize() - set up for chaining realize fns * @dc: The device class * @dev_realize: the device realize function diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c index 03ae610..6831fff 100644 --- a/system/qdev-monitor.c +++ b/system/qdev-monitor.c @@ -752,19 +752,18 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp) #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__) -static void qdev_print_props(Monitor *mon, DeviceState *dev, const Property *props, +static void qdev_print_props(Monitor *mon, DeviceState *dev, DeviceClass *dc, int indent) { - if (!props) - return; - for (; props->name; props++) { + for (int i = 0, n = dc->props_count_; i < n; ++i) { + const Property *prop = &dc->props_[i]; char *value; - char *legacy_name = g_strdup_printf("legacy-%s", props->name); + char *legacy_name = g_strdup_printf("legacy-%s", prop->name); if (object_property_get_type(OBJECT(dev), legacy_name, NULL)) { value = object_property_get_str(OBJECT(dev), legacy_name, NULL); } else { - value = object_property_print(OBJECT(dev), props->name, true, + value = object_property_print(OBJECT(dev), prop->name, true, NULL); } g_free(legacy_name); @@ -772,7 +771,7 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, const Property *pro if (!value) { continue; } - qdev_printf("%s = %s\n", props->name, + qdev_printf("%s = %s\n", prop->name, *value ? value : "<null>"); g_free(value); } @@ -812,7 +811,7 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int indent) } class = object_get_class(OBJECT(dev)); do { - qdev_print_props(mon, dev, DEVICE_CLASS(class)->props_, indent); + qdev_print_props(mon, dev, DEVICE_CLASS(class), indent); class = object_class_get_parent(class); } while (class != object_class_by_name(TYPE_DEVICE)); bus_print_dev(dev->parent_bus, mon, dev, indent); |