From a5296ca9df745d8af319282ab5d85439c211bb10 Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Mon, 12 Dec 2011 14:29:27 -0600 Subject: [PATCH] qom: register legacy properties as new style properties (v2) Expose all legacy properties through the new QOM property mechanism. The qdev property types are exposed through the 'legacy<>' namespace. They are always visited as strings since they do their own string parsing. Signed-off-by: Anthony Liguori --- hw/qdev.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 7 +++++ 2 files changed, 93 insertions(+) diff --git a/hw/qdev.c b/hw/qdev.c index 94f14c1f1c..6f77af91ef 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -83,6 +83,7 @@ static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name) static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info) { DeviceState *dev; + Property *prop; assert(bus->info == info->bus_info); dev = g_malloc0(info->size); @@ -100,6 +101,15 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info) dev->instance_id_alias = -1; QTAILQ_INIT(&dev->properties); dev->state = DEV_STATE_CREATED; + + for (prop = dev->info->props; prop && prop->name; prop++) { + qdev_property_add_legacy(dev, prop, NULL); + } + + for (prop = dev->info->bus_info->props; prop && prop->name; prop++) { + qdev_property_add_legacy(dev, prop, NULL); + } + return dev; } @@ -1075,3 +1085,79 @@ const char *qdev_property_get_type(DeviceState *dev, const char *name, Error **e return prop->type; } + +/** + * Legacy property handling + */ + +static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + Property *prop = opaque; + + if (prop->info->print) { + char buffer[1024]; + char *ptr = buffer; + + prop->info->print(dev, prop, buffer, sizeof(buffer)); + visit_type_str(v, &ptr, name, errp); + } else { + error_set(errp, QERR_PERMISSION_DENIED); + } +} + +static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque, + const char *name, Error **errp) +{ + Property *prop = opaque; + + if (dev->state != DEV_STATE_CREATED) { + error_set(errp, QERR_PERMISSION_DENIED); + return; + } + + if (prop->info->parse) { + Error *local_err = NULL; + char *ptr = NULL; + + visit_type_str(v, &ptr, name, &local_err); + if (!local_err) { + int ret; + ret = prop->info->parse(dev, prop, ptr); + if (ret != 0) { + error_set(errp, QERR_INVALID_PARAMETER_VALUE, + name, prop->info->name); + } + g_free(ptr); + } else { + error_propagate(errp, local_err); + } + } else { + error_set(errp, QERR_PERMISSION_DENIED); + } +} + +/** + * @qdev_add_legacy_property - adds a legacy property + * + * Do not use this is new code! Properties added through this interface will + * be given types in the "legacy<>" type namespace. + * + * Legacy properties are always processed as strings. The format of the string + * depends on the property type. + */ +void qdev_property_add_legacy(DeviceState *dev, Property *prop, + Error **errp) +{ + gchar *type; + + type = g_strdup_printf("legacy<%s>", prop->info->name); + + qdev_property_add(dev, prop->name, type, + qdev_get_legacy_property, + qdev_set_legacy_property, + NULL, + prop, errp); + + g_free(type); +} diff --git a/hw/qdev.h b/hw/qdev.h index 2df3bb7032..3b629d4fbd 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -475,4 +475,11 @@ void qdev_property_set(DeviceState *dev, Visitor *v, const char *name, const char *qdev_property_get_type(DeviceState *dev, const char *name, Error **errp); +/** + * @qdev_property_add_legacy - add a legacy @Property to a device + * + * DO NOT USE THIS IN NEW CODE! + */ +void qdev_property_add_legacy(DeviceState *dev, Property *prop, Error **errp); + #endif