mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 15:23:53 -06:00
qom: add new dynamic property infrastructure based on Visitors (v2)
qdev properties are settable only during construction and static to classes. This isn't flexible enough for QOM. This patch introduces a property interface for qdev that provides dynamic properties that are tied to objects, instead of classes. These properties are Visitor based instead of string based too. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
85ed303bfe
commit
44677ded43
4 changed files with 224 additions and 0 deletions
97
hw/qdev.c
97
hw/qdev.c
|
@ -98,6 +98,7 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
|
|||
qdev_hot_added = true;
|
||||
}
|
||||
dev->instance_id_alias = -1;
|
||||
QTAILQ_INIT(&dev->properties);
|
||||
dev->state = DEV_STATE_CREATED;
|
||||
return dev;
|
||||
}
|
||||
|
@ -395,12 +396,31 @@ void qdev_init_nofail(DeviceState *dev)
|
|||
}
|
||||
}
|
||||
|
||||
static void qdev_property_del_all(DeviceState *dev)
|
||||
{
|
||||
while (!QTAILQ_EMPTY(&dev->properties)) {
|
||||
DeviceProperty *prop = QTAILQ_FIRST(&dev->properties);
|
||||
|
||||
QTAILQ_REMOVE(&dev->properties, prop, node);
|
||||
|
||||
if (prop->release) {
|
||||
prop->release(dev, prop->name, prop->opaque);
|
||||
}
|
||||
|
||||
g_free(prop->name);
|
||||
g_free(prop->type);
|
||||
g_free(prop);
|
||||
}
|
||||
}
|
||||
|
||||
/* Unlink device from bus and free the structure. */
|
||||
void qdev_free(DeviceState *dev)
|
||||
{
|
||||
BusState *bus;
|
||||
Property *prop;
|
||||
|
||||
qdev_property_del_all(dev);
|
||||
|
||||
if (dev->state == DEV_STATE_INITIALIZED) {
|
||||
while (dev->num_child_bus) {
|
||||
bus = QLIST_FIRST(&dev->child_bus);
|
||||
|
@ -978,3 +998,80 @@ void qdev_unref(DeviceState *dev)
|
|||
g_assert(dev->ref > 0);
|
||||
dev->ref--;
|
||||
}
|
||||
|
||||
void qdev_property_add(DeviceState *dev, const char *name, const char *type,
|
||||
DevicePropertyAccessor *get, DevicePropertyAccessor *set,
|
||||
DevicePropertyRelease *release,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
DeviceProperty *prop = g_malloc0(sizeof(*prop));
|
||||
|
||||
prop->name = g_strdup(name);
|
||||
prop->type = g_strdup(type);
|
||||
|
||||
prop->get = get;
|
||||
prop->set = set;
|
||||
prop->release = release;
|
||||
prop->opaque = opaque;
|
||||
|
||||
QTAILQ_INSERT_TAIL(&dev->properties, prop, node);
|
||||
}
|
||||
|
||||
static DeviceProperty *qdev_property_find(DeviceState *dev, const char *name)
|
||||
{
|
||||
DeviceProperty *prop;
|
||||
|
||||
QTAILQ_FOREACH(prop, &dev->properties, node) {
|
||||
if (strcmp(prop->name, name) == 0) {
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void qdev_property_get(DeviceState *dev, Visitor *v, const char *name,
|
||||
Error **errp)
|
||||
{
|
||||
DeviceProperty *prop = qdev_property_find(dev, name);
|
||||
|
||||
if (prop == NULL) {
|
||||
error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prop->get) {
|
||||
error_set(errp, QERR_PERMISSION_DENIED);
|
||||
} else {
|
||||
prop->get(dev, v, prop->opaque, name, errp);
|
||||
}
|
||||
}
|
||||
|
||||
void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
|
||||
Error **errp)
|
||||
{
|
||||
DeviceProperty *prop = qdev_property_find(dev, name);
|
||||
|
||||
if (prop == NULL) {
|
||||
error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prop->set) {
|
||||
error_set(errp, QERR_PERMISSION_DENIED);
|
||||
} else {
|
||||
prop->set(dev, prop->opaque, v, name, errp);
|
||||
}
|
||||
}
|
||||
|
||||
const char *qdev_property_get_type(DeviceState *dev, const char *name, Error **errp)
|
||||
{
|
||||
DeviceProperty *prop = qdev_property_find(dev, name);
|
||||
|
||||
if (prop == NULL) {
|
||||
error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return prop->type;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue