diff options
Diffstat (limited to 'hw/core/qdev-properties-system.c')
-rw-r--r-- | hw/core/qdev-properties-system.c | 84 |
1 files changed, 50 insertions, 34 deletions
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index e55afe6bf2..6d45d327a5 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -160,55 +160,71 @@ PropertyInfo qdev_prop_drive = { /* --- character device --- */ -static void parse_chr(DeviceState *dev, const char *str, void **ptr, - const char *propname, Error **errp) +static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque, + Error **errp) { - CharDriverState *chr = qemu_chr_find(str); - if (chr == NULL) { - error_setg(errp, "Property '%s.%s' can't find value '%s'", - object_get_typename(OBJECT(dev)), propname, str); - return; - } - if (qemu_chr_fe_claim(chr) != 0) { - error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", - object_get_typename(OBJECT(dev)), propname, str); - return; - } - *ptr = chr; + DeviceState *dev = DEVICE(obj); + CharBackend *be = qdev_get_prop_ptr(dev, opaque); + char *p; + + p = g_strdup(be->chr && be->chr->label ? be->chr->label : ""); + visit_type_str(v, name, &p, errp); + g_free(p); } -static void release_chr(Object *obj, const char *name, void *opaque) +static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque, + Error **errp) { DeviceState *dev = DEVICE(obj); + Error *local_err = NULL; Property *prop = opaque; - CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); - CharDriverState *chr = *ptr; + CharBackend *be = qdev_get_prop_ptr(dev, prop); + CharDriverState *s; + char *str; - if (chr) { - qemu_chr_add_handlers(chr, NULL, NULL, NULL, NULL); - qemu_chr_fe_release(chr); + if (dev->realized) { + qdev_prop_set_after_realize(dev, name, errp); + return; } -} + visit_type_str(v, name, &str, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } -static char *print_chr(void *ptr) -{ - CharDriverState *chr = ptr; - const char *val = chr->label ? chr->label : ""; + if (!*str) { + g_free(str); + be->chr = NULL; + return; + } - return g_strdup(val); -} + s = qemu_chr_find(str); + g_free(str); + if (s == NULL) { + error_setg(errp, "Property '%s.%s' can't find value '%s'", + object_get_typename(obj), prop->name, str); + return; + } + if (qemu_chr_fe_claim(s) != 0) { + error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", + object_get_typename(obj), prop->name, str); + return; + } -static void get_chr(Object *obj, Visitor *v, const char *name, void *opaque, - Error **errp) -{ - get_pointer(obj, v, opaque, print_chr, name, errp); + qemu_chr_fe_init(be, s, errp); } -static void set_chr(Object *obj, Visitor *v, const char *name, void *opaque, - Error **errp) +static void release_chr(Object *obj, const char *name, void *opaque) { - set_pointer(obj, v, opaque, parse_chr, name, errp); + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + CharBackend *be = qdev_get_prop_ptr(dev, prop); + + if (be->chr) { + qemu_chr_fe_set_handlers(be, NULL, NULL, NULL, NULL, NULL); + qemu_chr_fe_release(be->chr); + } } PropertyInfo qdev_prop_chr = { |