diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2011-12-12 14:29:27 -0600 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2011-12-15 09:20:47 -0600 |
commit | a5296ca9df745d8af319282ab5d85439c211bb10 (patch) | |
tree | 3360250f1e139192aecdcfbe0ad6f1732ef9ef3a /hw | |
parent | 44677ded43f1dec44fabfe52f3a4f6eb28134f95 (diff) |
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 <aliguori@us.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/qdev.c | 86 | ||||
-rw-r--r-- | hw/qdev.h | 7 |
2 files changed, 93 insertions, 0 deletions
@@ -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); +} @@ -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 |