diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/mc146818rtc.c | 8 | ||||
-rw-r--r-- | hw/pc_piix.c | 6 | ||||
-rw-r--r-- | hw/pci.c | 1 | ||||
-rw-r--r-- | hw/piix_pci.c | 4 | ||||
-rw-r--r-- | hw/ppc_prep.c | 2 | ||||
-rw-r--r-- | hw/qdev-addr.c | 6 | ||||
-rw-r--r-- | hw/qdev-monitor.c | 21 | ||||
-rw-r--r-- | hw/qdev-properties.c | 53 | ||||
-rw-r--r-- | hw/qdev.c | 491 | ||||
-rw-r--r-- | hw/qdev.h | 277 |
10 files changed, 81 insertions, 788 deletions
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index cbbf1f06e0..4a43225707 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -628,10 +628,10 @@ static void visit_type_int32(Visitor *v, int *value, const char *name, Error **e visit_type_int(v, &val, name, errp); } -static void rtc_get_date(DeviceState *dev, Visitor *v, void *opaque, +static void rtc_get_date(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { - ISADevice *isa = ISA_DEVICE(dev); + ISADevice *isa = ISA_DEVICE(obj); RTCState *s = DO_UPCAST(RTCState, dev, isa); visit_start_struct(v, NULL, "struct tm", name, 0, errp); @@ -686,8 +686,8 @@ static int rtc_initfn(ISADevice *dev) qdev_set_legacy_instance_id(&dev->qdev, base, 2); qemu_register_reset(rtc_reset, s); - qdev_property_add(&s->dev.qdev, "date", "struct tm", - rtc_get_date, NULL, NULL, s, NULL); + object_property_add(OBJECT(s), "date", "struct tm", + rtc_get_date, NULL, NULL, s, NULL); return 0; } diff --git a/hw/pc_piix.c b/hw/pc_piix.c index a285ad25f8..c06f1b544e 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -229,7 +229,7 @@ static void pc_init1(MemoryRegion *system_memory, dev = pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL); if (dev) { - qdev_property_add_child(qdev_get_root(), "vga", dev, NULL); + object_property_add_child(object_get_root(), "vga", OBJECT(dev), NULL); } if (xen_enabled()) { @@ -267,8 +267,8 @@ static void pc_init1(MemoryRegion *system_memory, * For now, let's "fix" this by making judicious use of paths. This * is not generally the right way to do this. */ - qdev_property_add_child(qdev_resolve_path("/i440fx/piix3", NULL), - "rtc", (DeviceState *)rtc_state, NULL); + object_property_add_child(object_resolve_path("/i440fx/piix3", NULL), + "rtc", (Object *)rtc_state, NULL); } else { for(i = 0; i < MAX_IDE_BUS; i++) { ISADevice *dev; @@ -1517,6 +1517,7 @@ static int pci_unplug_device(DeviceState *qdev) qerror_report(QERR_DEVICE_NO_HOTPLUG, object_get_typename(OBJECT(dev))); return -1; } + object_unparent(OBJECT(dev)); return dev->bus->hotplug(dev->bus->hotplug_qdev, dev, PCI_HOTPLUG_DISABLED); } diff --git a/hw/piix_pci.c b/hw/piix_pci.c index 2bbfa4af00..190642733f 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -277,7 +277,7 @@ static PCIBus *i440fx_common_init(const char *device_name, address_space_io, 0); s->bus = b; qdev_init_nofail(dev); - qdev_property_add_child(qdev_get_root(), "i440fx", dev, NULL); + object_property_add_child(object_get_root(), "i440fx", OBJECT(dev), NULL); d = pci_create_simple(b, 0, device_name); *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d); @@ -316,7 +316,7 @@ static PCIBus *i440fx_common_init(const char *device_name, pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, PIIX_NUM_PIRQS); } - qdev_property_add_child(dev, "piix3", &piix3->dev.qdev, NULL); + object_property_add_child(OBJECT(dev), "piix3", OBJECT(piix3), NULL); piix3->pic = pic; *isa_bus = DO_UPCAST(ISABus, qbus, qdev_get_child_bus(&piix3->dev.qdev, "isa.0")); diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c index ff9594e8fe..eb43fb5849 100644 --- a/hw/ppc_prep.c +++ b/hw/ppc_prep.c @@ -610,7 +610,7 @@ static void ppc_prep_init (ram_addr_t ram_size, pcihost = DO_UPCAST(PCIHostState, busdev, sys); pcihost->address_space = get_system_memory(); qdev_init_nofail(dev); - qdev_property_add_child(qdev_get_root(), "raven", DEVICE(dev), NULL); + object_property_add_child(object_get_root(), "raven", OBJECT(dev), NULL); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0"); if (pci_bus == NULL) { fprintf(stderr, "Couldn't create PCI host controller.\n"); diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c index 5ddda2d0f4..5976dcdf47 100644 --- a/hw/qdev-addr.c +++ b/hw/qdev-addr.c @@ -18,9 +18,10 @@ static int print_taddr(DeviceState *dev, Property *prop, char *dest, size_t len) return snprintf(dest, len, "0x" TARGET_FMT_plx, *ptr); } -static void get_taddr(DeviceState *dev, Visitor *v, void *opaque, +static void get_taddr(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop); int64_t value; @@ -29,9 +30,10 @@ static void get_taddr(DeviceState *dev, Visitor *v, void *opaque, visit_type_int(v, &value, name, errp); } -static void set_taddr(DeviceState *dev, Visitor *v, void *opaque, +static void set_taddr(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop); Error *local_err = NULL; diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c index 841e1ad913..a6f0e16397 100644 --- a/hw/qdev-monitor.c +++ b/hw/qdev-monitor.c @@ -173,30 +173,32 @@ int qdev_device_help(QemuOpts *opts) return 1; } -static DeviceState *qdev_get_peripheral(void) +static Object *qdev_get_peripheral(void) { static DeviceState *dev; if (dev == NULL) { dev = qdev_create(NULL, "container"); - qdev_property_add_child(qdev_get_root(), "peripheral", dev, NULL); + object_property_add_child(object_get_root(), "peripheral", + OBJECT(dev), NULL); qdev_init_nofail(dev); } - return dev; + return OBJECT(dev); } -static DeviceState *qdev_get_peripheral_anon(void) +static Object *qdev_get_peripheral_anon(void) { static DeviceState *dev; if (dev == NULL) { dev = qdev_create(NULL, "container"); - qdev_property_add_child(qdev_get_root(), "peripheral-anon", dev, NULL); + object_property_add_child(object_get_root(), "peripheral-anon", + OBJECT(dev), NULL); qdev_init_nofail(dev); } - return dev; + return OBJECT(dev); } static void qbus_list_bus(DeviceState *dev) @@ -455,12 +457,13 @@ DeviceState *qdev_device_add(QemuOpts *opts) id = qemu_opts_id(opts); if (id) { qdev->id = id; - qdev_property_add_child(qdev_get_peripheral(), qdev->id, qdev, NULL); + object_property_add_child(qdev_get_peripheral(), qdev->id, + OBJECT(qdev), NULL); } else { static int anon_count; gchar *name = g_strdup_printf("device[%d]", anon_count++); - qdev_property_add_child(qdev_get_peripheral_anon(), name, - qdev, NULL); + object_property_add_child(qdev_get_peripheral_anon(), name, + OBJECT(qdev), NULL); g_free(name); } if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) { diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index 2e3ef702ea..c4583a14d7 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -55,9 +55,10 @@ static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len) return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off"); } -static void get_bit(DeviceState *dev, Visitor *v, void *opaque, +static void get_bit(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; uint32_t *p = qdev_get_prop_ptr(dev, prop); bool value = (*p & qdev_get_prop_mask(prop)) != 0; @@ -65,9 +66,10 @@ static void get_bit(DeviceState *dev, Visitor *v, void *opaque, visit_type_bool(v, &value, name, errp); } -static void set_bit(DeviceState *dev, Visitor *v, void *opaque, +static void set_bit(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; Error *local_err = NULL; bool value; @@ -118,9 +120,10 @@ static int print_uint8(DeviceState *dev, Property *prop, char *dest, size_t len) return snprintf(dest, len, "%" PRIu8, *ptr); } -static void get_int8(DeviceState *dev, Visitor *v, void *opaque, +static void get_int8(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; int8_t *ptr = qdev_get_prop_ptr(dev, prop); int64_t value; @@ -129,9 +132,10 @@ static void get_int8(DeviceState *dev, Visitor *v, void *opaque, visit_type_int(v, &value, name, errp); } -static void set_int8(DeviceState *dev, Visitor *v, void *opaque, - const char *name, Error **errp) +static void set_int8(Object *obj, Visitor *v, void *opaque, + const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; int8_t *ptr = qdev_get_prop_ptr(dev, prop); Error *local_err = NULL; @@ -224,9 +228,10 @@ static int print_uint16(DeviceState *dev, Property *prop, char *dest, size_t len return snprintf(dest, len, "%" PRIu16, *ptr); } -static void get_int16(DeviceState *dev, Visitor *v, void *opaque, +static void get_int16(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; int16_t *ptr = qdev_get_prop_ptr(dev, prop); int64_t value; @@ -235,9 +240,10 @@ static void get_int16(DeviceState *dev, Visitor *v, void *opaque, visit_type_int(v, &value, name, errp); } -static void set_int16(DeviceState *dev, Visitor *v, void *opaque, +static void set_int16(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; int16_t *ptr = qdev_get_prop_ptr(dev, prop); Error *local_err = NULL; @@ -296,9 +302,10 @@ static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len return snprintf(dest, len, "%" PRIu32, *ptr); } -static void get_int32(DeviceState *dev, Visitor *v, void *opaque, +static void get_int32(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; int32_t *ptr = qdev_get_prop_ptr(dev, prop); int64_t value; @@ -307,9 +314,10 @@ static void get_int32(DeviceState *dev, Visitor *v, void *opaque, visit_type_int(v, &value, name, errp); } -static void set_int32(DeviceState *dev, Visitor *v, void *opaque, +static void set_int32(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; int32_t *ptr = qdev_get_prop_ptr(dev, prop); Error *local_err = NULL; @@ -433,18 +441,20 @@ static int print_uint64(DeviceState *dev, Property *prop, char *dest, size_t len return snprintf(dest, len, "%" PRIu64, *ptr); } -static void get_int64(DeviceState *dev, Visitor *v, void *opaque, +static void get_int64(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; int64_t *ptr = qdev_get_prop_ptr(dev, prop); visit_type_int(v, ptr, name, errp); } -static void set_int64(DeviceState *dev, Visitor *v, void *opaque, +static void set_int64(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; int64_t *ptr = qdev_get_prop_ptr(dev, prop); @@ -523,9 +533,10 @@ static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len return snprintf(dest, len, "\"%s\"", *ptr); } -static void get_string(DeviceState *dev, Visitor *v, void *opaque, +static void get_string(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; char **ptr = qdev_get_prop_ptr(dev, prop); @@ -537,9 +548,10 @@ static void get_string(DeviceState *dev, Visitor *v, void *opaque, } } -static void set_string(DeviceState *dev, Visitor *v, void *opaque, +static void set_string(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; char **ptr = qdev_get_prop_ptr(dev, prop); Error *local_err = NULL; @@ -609,9 +621,10 @@ static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t len) *ptr ? bdrv_get_device_name(*ptr) : "<null>"); } -static void get_generic(DeviceState *dev, Visitor *v, void *opaque, +static void get_generic(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; void **ptr = qdev_get_prop_ptr(dev, prop); char buffer[1024]; @@ -624,9 +637,10 @@ static void get_generic(DeviceState *dev, Visitor *v, void *opaque, visit_type_str(v, &p, name, errp); } -static void set_generic(DeviceState *dev, Visitor *v, void *opaque, +static void set_generic(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; Error *local_err = NULL; char *str; @@ -774,9 +788,10 @@ static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len) } } -static void get_vlan(DeviceState *dev, Visitor *v, void *opaque, +static void get_vlan(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; VLANState **ptr = qdev_get_prop_ptr(dev, prop); int64_t id; @@ -785,9 +800,10 @@ static void get_vlan(DeviceState *dev, Visitor *v, void *opaque, visit_type_int(v, &id, name, errp); } -static void set_vlan(DeviceState *dev, Visitor *v, void *opaque, +static void set_vlan(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; VLANState **ptr = qdev_get_prop_ptr(dev, prop); Error *local_err = NULL; @@ -971,9 +987,10 @@ static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t } } -static void get_pci_devfn(DeviceState *dev, Visitor *v, void *opaque, +static void get_pci_devfn(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; uint32_t *ptr = qdev_get_prop_ptr(dev, prop); char buffer[32]; @@ -222,6 +222,7 @@ void qbus_reset_all_fn(void *opaque) int qdev_simple_unplug_cb(DeviceState *dev) { /* just zap it */ + object_unparent(OBJECT(dev)); qdev_free(dev); return 0; } @@ -243,46 +244,6 @@ 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); - } -} - -static void qdev_property_del_child(DeviceState *dev, DeviceState *child, Error **errp) -{ - DeviceProperty *prop; - - QTAILQ_FOREACH(prop, &dev->properties, node) { - if (strstart(prop->type, "child<", NULL) && prop->opaque == child) { - break; - } - } - - g_assert(prop != NULL); - - 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) { @@ -290,8 +251,6 @@ void qdev_free(DeviceState *dev) Property *prop; DeviceClass *dc = DEVICE_GET_CLASS(dev); - qdev_property_del_all(dev); - if (dev->state == DEV_STATE_INITIALIZED) { while (dev->num_child_bus) { bus = QLIST_FIRST(&dev->child_bus); @@ -313,12 +272,6 @@ void qdev_free(DeviceState *dev) prop->info->free(dev, prop); } } - if (dev->parent) { - qdev_property_del_child(dev->parent, dev, NULL); - } - if (dev->ref != 0) { - qerror_report(QERR_DEVICE_IN_USE, dev->id?:""); - } object_delete(OBJECT(dev)); } @@ -569,106 +522,19 @@ char* qdev_get_fw_dev_path(DeviceState *dev) return strdup(path); } -char *qdev_get_type(DeviceState *dev, Error **errp) -{ - return g_strdup(object_get_typename(OBJECT(dev))); -} - -void qdev_ref(DeviceState *dev) +static char *qdev_get_type(Object *obj, Error **errp) { - dev->ref++; -} - -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, v, prop->opaque, 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; + return g_strdup(object_get_typename(obj)); } /** * Legacy property handling */ -static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque, +static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; char buffer[1024]; @@ -678,9 +544,10 @@ static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque, visit_type_str(v, &ptr, name, errp); } -static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque, +static void qdev_set_legacy_property(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { + DeviceState *dev = DEVICE(obj); Property *prop = opaque; Error *local_err = NULL; char *ptr = NULL; @@ -720,11 +587,11 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop, type = g_strdup_printf("legacy<%s>", prop->info->legacy_name ?: prop->info->name); - qdev_property_add(dev, name, type, - prop->info->print ? qdev_get_legacy_property : NULL, - prop->info->parse ? qdev_set_legacy_property : NULL, - NULL, - prop, errp); + object_property_add(OBJECT(dev), name, type, + prop->info->print ? qdev_get_legacy_property : NULL, + prop->info->parse ? qdev_set_legacy_property : NULL, + NULL, + prop, errp); g_free(type); g_free(name); @@ -739,333 +606,10 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop, void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp) { - qdev_property_add(dev, prop->name, prop->info->name, - prop->info->get, prop->info->set, - NULL, - prop, errp); -} - -DeviceState *qdev_get_root(void) -{ - static DeviceState *qdev_root; - - if (!qdev_root) { - qdev_root = qdev_create(NULL, "container"); - qdev_init_nofail(qdev_root); - } - - return qdev_root; -} - -static void qdev_get_child_property(DeviceState *dev, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - DeviceState *child = opaque; - gchar *path; - - path = qdev_get_canonical_path(child); - visit_type_str(v, &path, name, errp); - g_free(path); -} - -static void qdev_release_child_property(DeviceState *dev, const char *name, - void *opaque) -{ - DeviceState *child = opaque; - - qdev_unref(child); -} - -void qdev_property_add_child(DeviceState *dev, const char *name, - DeviceState *child, Error **errp) -{ - gchar *type; - - type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child))); - - qdev_property_add(dev, name, type, qdev_get_child_property, - NULL, qdev_release_child_property, - child, errp); - - qdev_ref(child); - g_assert(child->parent == NULL); - child->parent = dev; - - g_free(type); -} - -static void qdev_get_link_property(DeviceState *dev, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - DeviceState **child = opaque; - gchar *path; - - if (*child) { - path = qdev_get_canonical_path(*child); - visit_type_str(v, &path, name, errp); - g_free(path); - } else { - path = (gchar *)""; - visit_type_str(v, &path, name, errp); - } -} - -static void qdev_set_link_property(DeviceState *dev, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - DeviceState **child = opaque; - bool ambiguous = false; - const char *type; - char *path; - - type = qdev_property_get_type(dev, name, NULL); - - visit_type_str(v, &path, name, errp); - - if (*child) { - qdev_unref(*child); - } - - if (strcmp(path, "") != 0) { - DeviceState *target; - - target = qdev_resolve_path(path, &ambiguous); - if (target) { - gchar *target_type; - - target_type = g_strdup_printf("link<%s>", object_get_typename(OBJECT(target))); - if (strcmp(target_type, type) == 0) { - *child = target; - qdev_ref(target); - } else { - error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type); - } - - g_free(target_type); - } else { - error_set(errp, QERR_DEVICE_NOT_FOUND, path); - } - } else { - *child = NULL; - } - - g_free(path); -} - -void qdev_property_add_link(DeviceState *dev, const char *name, - const char *type, DeviceState **child, - Error **errp) -{ - gchar *full_type; - - full_type = g_strdup_printf("link<%s>", type); - - qdev_property_add(dev, name, full_type, - qdev_get_link_property, - qdev_set_link_property, - NULL, child, errp); - - g_free(full_type); -} - -gchar *qdev_get_canonical_path(DeviceState *dev) -{ - DeviceState *root = qdev_get_root(); - char *newpath = NULL, *path = NULL; - - while (dev != root) { - DeviceProperty *prop = NULL; - - g_assert(dev->parent != NULL); - - QTAILQ_FOREACH(prop, &dev->parent->properties, node) { - if (!strstart(prop->type, "child<", NULL)) { - continue; - } - - if (prop->opaque == dev) { - if (path) { - newpath = g_strdup_printf("%s/%s", prop->name, path); - g_free(path); - path = newpath; - } else { - path = g_strdup(prop->name); - } - break; - } - } - - g_assert(prop != NULL); - - dev = dev->parent; - } - - newpath = g_strdup_printf("/%s", path); - g_free(path); - - return newpath; -} - -static DeviceState *qdev_resolve_abs_path(DeviceState *parent, - gchar **parts, - int index) -{ - DeviceProperty *prop; - DeviceState *child; - - if (parts[index] == NULL) { - return parent; - } - - if (strcmp(parts[index], "") == 0) { - return qdev_resolve_abs_path(parent, parts, index + 1); - } - - prop = qdev_property_find(parent, parts[index]); - if (prop == NULL) { - return NULL; - } - - child = NULL; - if (strstart(prop->type, "link<", NULL)) { - DeviceState **pchild = prop->opaque; - if (*pchild) { - child = *pchild; - } - } else if (strstart(prop->type, "child<", NULL)) { - child = prop->opaque; - } - - if (!child) { - return NULL; - } - - return qdev_resolve_abs_path(child, parts, index + 1); -} - -static DeviceState *qdev_resolve_partial_path(DeviceState *parent, - gchar **parts, - bool *ambiguous) -{ - DeviceState *dev; - DeviceProperty *prop; - - dev = qdev_resolve_abs_path(parent, parts, 0); - - QTAILQ_FOREACH(prop, &parent->properties, node) { - DeviceState *found; - - if (!strstart(prop->type, "child<", NULL)) { - continue; - } - - found = qdev_resolve_partial_path(prop->opaque, parts, ambiguous); - if (found) { - if (dev) { - if (ambiguous) { - *ambiguous = true; - } - return NULL; - } - dev = found; - } - - if (ambiguous && *ambiguous) { - return NULL; - } - } - - return dev; -} - -DeviceState *qdev_resolve_path(const char *path, bool *ambiguous) -{ - bool partial_path = true; - DeviceState *dev; - gchar **parts; - - parts = g_strsplit(path, "/", 0); - if (parts == NULL || parts[0] == NULL) { - g_strfreev(parts); - return qdev_get_root(); - } - - if (strcmp(parts[0], "") == 0) { - partial_path = false; - } - - if (partial_path) { - if (ambiguous) { - *ambiguous = false; - } - dev = qdev_resolve_partial_path(qdev_get_root(), parts, ambiguous); - } else { - dev = qdev_resolve_abs_path(qdev_get_root(), parts, 1); - } - - g_strfreev(parts); - - return dev; -} - -typedef struct StringProperty -{ - char *(*get)(DeviceState *, Error **); - void (*set)(DeviceState *, const char *, Error **); -} StringProperty; - -static void qdev_property_get_str(DeviceState *dev, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - StringProperty *prop = opaque; - char *value; - - value = prop->get(dev, errp); - if (value) { - visit_type_str(v, &value, name, errp); - g_free(value); - } -} - -static void qdev_property_set_str(DeviceState *dev, Visitor *v, void *opaque, - const char *name, Error **errp) -{ - StringProperty *prop = opaque; - char *value; - Error *local_err = NULL; - - visit_type_str(v, &value, name, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - - prop->set(dev, value, errp); - g_free(value); -} - -static void qdev_property_release_str(DeviceState *dev, const char *name, - void *opaque) -{ - StringProperty *prop = opaque; - g_free(prop); -} - -void qdev_property_add_str(DeviceState *dev, const char *name, - char *(*get)(DeviceState *, Error **), - void (*set)(DeviceState *, const char *, Error **), - Error **errp) -{ - StringProperty *prop = g_malloc0(sizeof(*prop)); - - prop->get = get; - prop->set = set; - - qdev_property_add(dev, name, "string", - get ? qdev_property_get_str : NULL, - set ? qdev_property_set_str : NULL, - qdev_property_release_str, - prop, errp); + object_property_add(OBJECT(dev), prop->name, prop->info->name, + prop->info->get, prop->info->set, + NULL, + prop, errp); } static void device_initfn(Object *obj) @@ -1079,7 +623,6 @@ static void device_initfn(Object *obj) } dev->instance_id_alias = -1; - QTAILQ_INIT(&dev->properties); dev->state = DEV_STATE_CREATED; qdev_prop_set_defaults(dev, qdev_get_props(dev)); @@ -1088,7 +631,7 @@ static void device_initfn(Object *obj) qdev_property_add_static(dev, prop, NULL); } - qdev_property_add_str(dev, "type", qdev_get_type, NULL, NULL); + object_property_add_str(OBJECT(dev), "type", qdev_get_type, NULL, NULL); } void device_reset(DeviceState *dev) @@ -27,44 +27,6 @@ enum { DEV_NVECTORS_UNSPECIFIED = -1, }; -/** - * @DevicePropertyAccessor - called when trying to get/set a property - * - * @dev the device that owns the property - * @v the visitor that contains the property data - * @opaque the device property opaque - * @name the name of the property - * @errp a pointer to an Error that is filled if getting/setting fails. - */ -typedef void (DevicePropertyAccessor)(DeviceState *dev, - Visitor *v, - void *opaque, - const char *name, - Error **errp); - -/** - * @DevicePropertyRelease - called when a property is removed from a device - * - * @dev the device that owns the property - * @name the name of the property - * @opaque the opaque registered with the property - */ -typedef void (DevicePropertyRelease)(DeviceState *dev, - const char *name, - void *opaque); - -typedef struct DeviceProperty -{ - gchar *name; - gchar *type; - DevicePropertyAccessor *get; - DevicePropertyAccessor *set; - DevicePropertyRelease *release; - void *opaque; - - QTAILQ_ENTRY(DeviceProperty) node; -} DeviceProperty; - #define TYPE_DEVICE "device" #define DEVICE(obj) OBJECT_CHECK(DeviceState, (obj), TYPE_DEVICE) #define DEVICE_CLASS(klass) OBJECT_CLASS_CHECK(DeviceClass, (klass), TYPE_DEVICE) @@ -114,18 +76,6 @@ struct DeviceState { QTAILQ_ENTRY(DeviceState) sibling; int instance_id_alias; int alias_required_for_version; - - /** - * This tracks the number of references between devices. See @qdev_ref for - * more information. - */ - uint32_t ref; - - QTAILQ_HEAD(, DeviceProperty) properties; - - /* Do not, under any circumstance, use this parent link below anywhere - * outside of qdev.c. You have been warned. */ - DeviceState *parent; }; typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent); @@ -195,8 +145,8 @@ struct PropertyInfo { int (*parse)(DeviceState *dev, Property *prop, const char *str); int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len); void (*free)(DeviceState *dev, Property *prop); - DevicePropertyAccessor *get; - DevicePropertyAccessor *set; + ObjectPropertyAccessor *get; + ObjectPropertyAccessor *set; }; typedef struct GlobalProperty { @@ -390,235 +340,12 @@ char *qdev_get_fw_dev_path(DeviceState *dev); extern struct BusInfo system_bus_info; /** - * @qdev_ref - * - * Increase the reference count of a device. A device cannot be freed as long - * as its reference count is greater than zero. - * - * @dev - the device - */ -void qdev_ref(DeviceState *dev); - -/** - * @qdef_unref - * - * Decrease the reference count of a device. A device cannot be freed as long - * as its reference count is greater than zero. - * - * @dev - the device - */ -void qdev_unref(DeviceState *dev); - -/** - * @qdev_property_add - add a new property to a device - * - * @dev - the device to add a property to - * - * @name - the name of the property. This can contain any character except for - * a forward slash. In general, you should use hyphens '-' instead of - * underscores '_' when naming properties. - * - * @type - the type name of the property. This namespace is pretty loosely - * defined. Sub namespaces are constructed by using a prefix and then - * to angle brackets. For instance, the type 'virtio-net-pci' in the - * 'link' namespace would be 'link<virtio-net-pci>'. - * - * @get - the getter to be called to read a property. If this is NULL, then - * the property cannot be read. - * - * @set - the setter to be called to write a property. If this is NULL, - * then the property cannot be written. - * - * @release - called when the property is removed from the device. This is - * meant to allow a property to free its opaque upon device - * destruction. This may be NULL. - * - * @opaque - an opaque pointer to pass to the callbacks for the property - * - * @errp - returns an error if this function fails - */ -void qdev_property_add(DeviceState *dev, const char *name, const char *type, - DevicePropertyAccessor *get, DevicePropertyAccessor *set, - DevicePropertyRelease *release, - void *opaque, Error **errp); - -/** - * @qdev_property_get - reads a property from a device - * - * @dev - the device - * - * @v - the visitor that will receive the property value. This should be an - * Output visitor and the data will be written with @name as the name. - * - * @name - the name of the property - * - * @errp - returns an error if this function fails - */ -void qdev_property_get(DeviceState *dev, Visitor *v, const char *name, - Error **errp); - -/** - * @qdev_property_set - writes a property to a device - * - * @dev - the device - * - * @v - the visitor that will be used to write the property value. This should - * be an Input visitor and the data will be first read with @name as the - * name and then written as the property value. - * - * @name - the name of the property - * - * @errp - returns an error if this function fails - */ -void qdev_property_set(DeviceState *dev, Visitor *v, const char *name, - Error **errp); - -/** - * @qdev_property_get_type - returns the type of a property - * - * @dev - the device - * - * @name - the name of the property - * - * @errp - returns an error if this function fails - * - * Returns: - * The type name of the property. - */ -const char *qdev_property_get_type(DeviceState *dev, const char *name, - Error **errp); - -/** * @qdev_property_add_static - add a @Property to a device referencing a * field in a struct. */ void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp); /** - * @qdev_get_root - returns the root device of the composition tree - * - * Returns: - * The root of the composition tree. - */ -DeviceState *qdev_get_root(void); - -/** - * @qdev_get_canonical_path - returns the canonical path for a device. This - * is the path within the composition tree starting from the root. - * - * Returns: - * The canonical path in the composition tree. - */ -gchar *qdev_get_canonical_path(DeviceState *dev); - -/** - * @qdev_resolve_path - resolves a path returning a device - * - * There are two types of supported paths--absolute paths and partial paths. - * - * Absolute paths are derived from the root device and can follow child<> or - * link<> properties. Since they can follow link<> properties, they can be - * arbitrarily long. Absolute paths look like absolute filenames and are - * prefixed with a leading slash. - * - * Partial paths look like relative filenames. They do not begin with a - * prefix. The matching rules for partial paths are subtle but designed to make - * specifying devices easy. At each level of the composition tree, the partial - * path is matched as an absolute path. The first match is not returned. At - * least two matches are searched for. A successful result is only returned if - * only one match is founded. If more than one match is found, a flag is - * return to indicate that the match was ambiguous. - * - * @path - the path to resolve - * - * @ambiguous - returns true if the path resolution failed because of an - * ambiguous match - * - * Returns: - * The matched device or NULL on path lookup failure. - */ -DeviceState *qdev_resolve_path(const char *path, bool *ambiguous); - -/** - * @qdev_property_add_child - Add a child property to a device - * - * Child properties form the composition tree. All devices need to be a child - * of another device. Devices can only be a child of one device. - * - * There is no way for a child to determine what its parent is. It is not - * a bidirectional relationship. This is by design. - * - * @dev - the device to add a property to - * - * @name - the name of the property - * - * @child - the child device - * - * @errp - if an error occurs, a pointer to an area to store the area - */ -void qdev_property_add_child(DeviceState *dev, const char *name, - DeviceState *child, Error **errp); - -/** - * @qdev_property_add_link - Add a link property to a device - * - * Links establish relationships between devices. Links are unidirectional - * although two links can be combined to form a bidirectional relationship - * between devices. - * - * Links form the graph in the device model. - * - * @dev - the device to add a property to - * - * @name - the name of the property - * - * @type - the qdev type of the link - * - * @child - a pointer to where the link device reference is stored - * - * @errp - if an error occurs, a pointer to an area to store the area - */ -void qdev_property_add_link(DeviceState *dev, const char *name, - const char *type, DeviceState **child, - Error **errp); - -/** - * @qdev_property_add_str - * - * Add a string property using getters/setters. This function will add a - * property of type 'string'. - * - * @dev - the device to add a property to - * - * @name - the name of the property - * - * @get - the getter or NULL if the property is write-only. This function must - * return a string to be freed by @g_free(). - * - * @set - the setter or NULL if the property is read-only - * - * @errp - if an error occurs, a pointer to an area to store the error - */ -void qdev_property_add_str(DeviceState *dev, const char *name, - char *(*get)(DeviceState *, Error **), - void (*set)(DeviceState *, const char *, Error **), - Error **errp); - -/** - * @qdev_get_type - * - * Returns the string representation of the type of this object. - * - * @dev - the device - * - * @errp - if an error occurs, a pointer to an area to store the error - * - * Returns: a string representing the type. This must be freed by the caller - * with g_free(). - */ -char *qdev_get_type(DeviceState *dev, Error **errp); - -/** * @qdev_machine_init * * Initialize platform devices before machine init. This is a hack until full |