2 * Dynamic device configuration and creation.
4 * Copyright (c) 2009 CodeSourcery
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 /* The theory here is that it should be possible to create a machine without
21 knowledge of specific devices. Historically board init routines have
22 passed a bunch of arguments to each device, requiring the board know
23 exactly which device it is dealing with. This file provides an abstract
24 API for device configuration and initialization. Devices will generally
25 inherit from a particular bus (e.g. PCI or I2C) rather than
33 static int qdev_hotplug = 0;
34 static bool qdev_hot_added = false;
35 static bool qdev_hot_removed = false;
37 /* This is a nasty hack to allow passing a NULL bus to qdev_create. */
38 static BusState *main_system_bus;
39 static void main_system_bus_create(void);
41 DeviceInfo *device_info_list;
43 static BusState *qbus_find_recursive(BusState *bus, const char *name,
45 static BusState *qbus_find(const char *path);
47 /* Register a new device type. */
48 void qdev_register(DeviceInfo *info)
50 assert(info->size >= sizeof(DeviceState));
53 info->next = device_info_list;
54 device_info_list = info;
57 static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
61 /* first check device names */
62 for (info = device_info_list; info != NULL; info = info->next) {
63 if (bus_info && info->bus_info != bus_info)
65 if (strcmp(info->name, name) != 0)
70 /* failing that check the aliases */
71 for (info = device_info_list; info != NULL; info = info->next) {
72 if (bus_info && info->bus_info != bus_info)
76 if (strcmp(info->alias, name) != 0)
83 static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
88 assert(bus->info == info->bus_info);
89 dev = g_malloc0(info->size);
91 dev->parent_bus = bus;
92 qdev_prop_set_defaults(dev, dev->info->props);
93 qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
94 qdev_prop_set_globals(dev);
95 QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
97 assert(bus->allow_hotplug);
99 qdev_hot_added = true;
101 dev->instance_id_alias = -1;
102 QTAILQ_INIT(&dev->properties);
103 dev->state = DEV_STATE_CREATED;
105 for (prop = dev->info->props; prop && prop->name; prop++) {
106 qdev_property_add_legacy(dev, prop, NULL);
109 for (prop = dev->info->bus_info->props; prop && prop->name; prop++) {
110 qdev_property_add_legacy(dev, prop, NULL);
113 qdev_property_add_str(dev, "type", qdev_get_type, NULL, NULL);
118 /* Create a new device. This only initializes the device state structure
119 and allows properties to be set. qdev_init should be called to
120 initialize the actual device emulation. */
121 DeviceState *qdev_create(BusState *bus, const char *name)
125 dev = qdev_try_create(bus, name);
128 hw_error("Unknown device '%s' for bus '%s'\n", name,
131 hw_error("Unknown device '%s' for default sysbus\n", name);
138 DeviceState *qdev_try_create(BusState *bus, const char *name)
143 bus = sysbus_get_default();
146 info = qdev_find_info(bus->info, name);
151 return qdev_create_from_info(bus, info);
154 static void qdev_print_devinfo(DeviceInfo *info)
156 error_printf("name \"%s\", bus %s",
157 info->name, info->bus_info->name);
159 error_printf(", alias \"%s\"", info->alias);
162 error_printf(", desc \"%s\"", info->desc);
165 error_printf(", no-user");
170 static int set_property(const char *name, const char *value, void *opaque)
172 DeviceState *dev = opaque;
174 if (strcmp(name, "driver") == 0)
176 if (strcmp(name, "bus") == 0)
179 if (qdev_prop_parse(dev, name, value) == -1) {
185 int qdev_device_help(QemuOpts *opts)
191 driver = qemu_opt_get(opts, "driver");
192 if (driver && !strcmp(driver, "?")) {
193 for (info = device_info_list; info != NULL; info = info->next) {
195 continue; /* not available, don't show */
197 qdev_print_devinfo(info);
202 if (!driver || !qemu_opt_get(opts, "?")) {
206 info = qdev_find_info(NULL, driver);
211 for (prop = info->props; prop && prop->name; prop++) {
213 * TODO Properties without a parser are just for dirty hacks.
214 * qdev_prop_ptr is the only such PropertyInfo. It's marked
215 * for removal. This conditional should be removed along with
218 if (!prop->info->parse) {
219 continue; /* no way to set it, don't show */
221 error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
223 for (prop = info->bus_info->props; prop && prop->name; prop++) {
224 if (!prop->info->parse) {
225 continue; /* no way to set it, don't show */
227 error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
232 static DeviceState *qdev_get_peripheral(void)
234 static DeviceState *dev;
237 dev = qdev_create(NULL, "container");
238 qdev_property_add_child(qdev_get_root(), "peripheral", dev, NULL);
239 qdev_init_nofail(dev);
245 static DeviceState *qdev_get_peripheral_anon(void)
247 static DeviceState *dev;
250 dev = qdev_create(NULL, "container");
251 qdev_property_add_child(qdev_get_root(), "peripheral-anon", dev, NULL);
252 qdev_init_nofail(dev);
258 DeviceState *qdev_device_add(QemuOpts *opts)
260 const char *driver, *path, *id;
265 driver = qemu_opt_get(opts, "driver");
267 qerror_report(QERR_MISSING_PARAMETER, "driver");
272 info = qdev_find_info(NULL, driver);
273 if (!info || info->no_user) {
274 qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
275 error_printf_unless_qmp("Try with argument '?' for a list.\n");
280 path = qemu_opt_get(opts, "bus");
282 bus = qbus_find(path);
286 if (bus->info != info->bus_info) {
287 qerror_report(QERR_BAD_BUS_FOR_DEVICE,
288 driver, bus->info->name);
292 bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
294 qerror_report(QERR_NO_BUS_FOR_DEVICE,
295 info->name, info->bus_info->name);
299 if (qdev_hotplug && !bus->allow_hotplug) {
300 qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
304 /* create device, set properties */
305 qdev = qdev_create_from_info(bus, info);
306 id = qemu_opts_id(opts);
309 qdev_property_add_child(qdev_get_peripheral(), qdev->id, qdev, NULL);
311 static int anon_count;
312 gchar *name = g_strdup_printf("device[%d]", anon_count++);
313 qdev_property_add_child(qdev_get_peripheral_anon(), name,
317 if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
321 if (qdev_init(qdev) < 0) {
322 qerror_report(QERR_DEVICE_INIT_FAILED, driver);
329 /* Initialize a device. Device properties should be set before calling
330 this function. IRQs and MMIO regions should be connected/mapped after
331 calling this function.
332 On failure, destroy the device and return negative value.
333 Return 0 on success. */
334 int qdev_init(DeviceState *dev)
338 assert(dev->state == DEV_STATE_CREATED);
339 rc = dev->info->init(dev, dev->info);
344 if (dev->info->vmsd) {
345 vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,
346 dev->instance_id_alias,
347 dev->alias_required_for_version);
349 dev->state = DEV_STATE_INITIALIZED;
350 if (dev->hotplugged && dev->info->reset) {
351 dev->info->reset(dev);
356 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
357 int required_for_version)
359 assert(dev->state == DEV_STATE_CREATED);
360 dev->instance_id_alias = alias_id;
361 dev->alias_required_for_version = required_for_version;
364 int qdev_unplug(DeviceState *dev)
366 if (!dev->parent_bus->allow_hotplug) {
367 qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
370 assert(dev->info->unplug != NULL);
373 qerror_report(QERR_DEVICE_IN_USE, dev->id?:"");
377 qdev_hot_removed = true;
379 return dev->info->unplug(dev);
382 static int qdev_reset_one(DeviceState *dev, void *opaque)
384 if (dev->info->reset) {
385 dev->info->reset(dev);
391 BusState *sysbus_get_default(void)
393 if (!main_system_bus) {
394 main_system_bus_create();
396 return main_system_bus;
399 static int qbus_reset_one(BusState *bus, void *opaque)
401 if (bus->info->reset) {
402 return bus->info->reset(bus);
407 void qdev_reset_all(DeviceState *dev)
409 qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
412 void qbus_reset_all_fn(void *opaque)
414 BusState *bus = opaque;
415 qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
418 /* can be used as ->unplug() callback for the simple cases */
419 int qdev_simple_unplug_cb(DeviceState *dev)
427 /* Like qdev_init(), but terminate program via error_report() instead of
428 returning an error value. This is okay during machine creation.
429 Don't use for hotplug, because there callers need to recover from
430 failure. Exception: if you know the device's init() callback can't
431 fail, then qdev_init_nofail() can't fail either, and is therefore
432 usable even then. But relying on the device implementation that
433 way is somewhat unclean, and best avoided. */
434 void qdev_init_nofail(DeviceState *dev)
436 DeviceInfo *info = dev->info;
438 if (qdev_init(dev) < 0) {
439 error_report("Initialization of device %s failed", info->name);
444 static void qdev_property_del_all(DeviceState *dev)
446 while (!QTAILQ_EMPTY(&dev->properties)) {
447 DeviceProperty *prop = QTAILQ_FIRST(&dev->properties);
449 QTAILQ_REMOVE(&dev->properties, prop, node);
452 prop->release(dev, prop->name, prop->opaque);
461 /* Unlink device from bus and free the structure. */
462 void qdev_free(DeviceState *dev)
467 qdev_property_del_all(dev);
469 if (dev->state == DEV_STATE_INITIALIZED) {
470 while (dev->num_child_bus) {
471 bus = QLIST_FIRST(&dev->child_bus);
475 vmstate_unregister(dev, dev->info->vmsd, dev);
477 dev->info->exit(dev);
479 qemu_opts_del(dev->opts);
481 QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
482 for (prop = dev->info->props; prop && prop->name; prop++) {
483 if (prop->info->free) {
484 prop->info->free(dev, prop);
490 void qdev_machine_creation_done(void)
493 * ok, initial machine setup is done, starting from now we can
494 * only create hotpluggable devices
499 bool qdev_machine_modified(void)
501 return qdev_hot_added || qdev_hot_removed;
504 /* Get a character (serial) device interface. */
505 CharDriverState *qdev_init_chardev(DeviceState *dev)
507 static int next_serial;
509 /* FIXME: This function needs to go away: use chardev properties! */
510 return serial_hds[next_serial++];
513 BusState *qdev_get_parent_bus(DeviceState *dev)
515 return dev->parent_bus;
518 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
520 assert(dev->num_gpio_in == 0);
521 dev->num_gpio_in = n;
522 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
525 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
527 assert(dev->num_gpio_out == 0);
528 dev->num_gpio_out = n;
529 dev->gpio_out = pins;
532 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
534 assert(n >= 0 && n < dev->num_gpio_in);
535 return dev->gpio_in[n];
538 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
540 assert(n >= 0 && n < dev->num_gpio_out);
541 dev->gpio_out[n] = pin;
544 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
546 qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
548 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
550 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
551 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
552 qdev_prop_exists(dev, "vectors")) {
553 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
555 nd->instantiated = 1;
558 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
562 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
563 if (strcmp(name, bus->name) == 0) {
570 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
571 qbus_walkerfn *busfn, void *opaque)
577 err = busfn(bus, opaque);
583 QTAILQ_FOREACH(dev, &bus->children, sibling) {
584 err = qdev_walk_children(dev, devfn, busfn, opaque);
593 int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
594 qbus_walkerfn *busfn, void *opaque)
600 err = devfn(dev, opaque);
606 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
607 err = qbus_walk_children(bus, devfn, busfn, opaque);
616 static BusState *qbus_find_recursive(BusState *bus, const char *name,
620 BusState *child, *ret;
623 if (name && (strcmp(bus->name, name) != 0)) {
626 if (info && (bus->info != info)) {
633 QTAILQ_FOREACH(dev, &bus->children, sibling) {
634 QLIST_FOREACH(child, &dev->child_bus, sibling) {
635 ret = qbus_find_recursive(child, name, info);
644 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
646 DeviceState *dev, *ret;
649 QTAILQ_FOREACH(dev, &bus->children, sibling) {
650 if (dev->id && strcmp(dev->id, id) == 0)
652 QLIST_FOREACH(child, &dev->child_bus, sibling) {
653 ret = qdev_find_recursive(child, id);
662 static void qbus_list_bus(DeviceState *dev)
665 const char *sep = " ";
667 error_printf("child busses at \"%s\":",
668 dev->id ? dev->id : dev->info->name);
669 QLIST_FOREACH(child, &dev->child_bus, sibling) {
670 error_printf("%s\"%s\"", sep, child->name);
676 static void qbus_list_dev(BusState *bus)
679 const char *sep = " ";
681 error_printf("devices at \"%s\":", bus->name);
682 QTAILQ_FOREACH(dev, &bus->children, sibling) {
683 error_printf("%s\"%s\"", sep, dev->info->name);
685 error_printf("/\"%s\"", dev->id);
691 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
695 QLIST_FOREACH(child, &dev->child_bus, sibling) {
696 if (strcmp(child->name, elem) == 0) {
703 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
708 * try to match in order:
709 * (1) instance id, if present
711 * (3) driver alias, if present
713 QTAILQ_FOREACH(dev, &bus->children, sibling) {
714 if (dev->id && strcmp(dev->id, elem) == 0) {
718 QTAILQ_FOREACH(dev, &bus->children, sibling) {
719 if (strcmp(dev->info->name, elem) == 0) {
723 QTAILQ_FOREACH(dev, &bus->children, sibling) {
724 if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
731 static BusState *qbus_find(const char *path)
738 /* find start element */
739 if (path[0] == '/') {
740 bus = main_system_bus;
743 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
747 bus = qbus_find_recursive(main_system_bus, elem, NULL);
749 qerror_report(QERR_BUS_NOT_FOUND, elem);
756 assert(path[pos] == '/' || !path[pos]);
757 while (path[pos] == '/') {
760 if (path[pos] == '\0') {
765 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
770 dev = qbus_find_dev(bus, elem);
772 qerror_report(QERR_DEVICE_NOT_FOUND, elem);
773 if (!monitor_cur_is_qmp()) {
779 assert(path[pos] == '/' || !path[pos]);
780 while (path[pos] == '/') {
783 if (path[pos] == '\0') {
784 /* last specified element is a device. If it has exactly
785 * one child bus accept it nevertheless */
786 switch (dev->num_child_bus) {
788 qerror_report(QERR_DEVICE_NO_BUS, elem);
791 return QLIST_FIRST(&dev->child_bus);
793 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
794 if (!monitor_cur_is_qmp()) {
802 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
807 bus = qbus_find_bus(dev, elem);
809 qerror_report(QERR_BUS_NOT_FOUND, elem);
810 if (!monitor_cur_is_qmp()) {
818 void qbus_create_inplace(BusState *bus, BusInfo *info,
819 DeviceState *parent, const char *name)
825 bus->parent = parent;
828 /* use supplied name */
829 bus->name = g_strdup(name);
830 } else if (parent && parent->id) {
831 /* parent device has id -> use it for bus name */
832 len = strlen(parent->id) + 16;
834 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
837 /* no id -> use lowercase bus type for bus name */
838 len = strlen(info->name) + 16;
840 len = snprintf(buf, len, "%s.%d", info->name,
841 parent ? parent->num_child_bus : 0);
842 for (i = 0; i < len; i++)
843 buf[i] = qemu_tolower(buf[i]);
847 QTAILQ_INIT(&bus->children);
849 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
850 parent->num_child_bus++;
851 } else if (bus != main_system_bus) {
852 /* TODO: once all bus devices are qdevified,
853 only reset handler for main_system_bus should be registered here. */
854 qemu_register_reset(qbus_reset_all_fn, bus);
858 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
862 bus = g_malloc0(info->size);
863 bus->qdev_allocated = 1;
864 qbus_create_inplace(bus, info, parent, name);
868 static void main_system_bus_create(void)
870 /* assign main_system_bus before qbus_create_inplace()
871 * in order to make "if (bus != main_system_bus)" work */
872 main_system_bus = g_malloc0(system_bus_info.size);
873 main_system_bus->qdev_allocated = 1;
874 qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
878 void qbus_free(BusState *bus)
882 while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
886 QLIST_REMOVE(bus, sibling);
887 bus->parent->num_child_bus--;
889 assert(bus != main_system_bus); /* main_system_bus is never freed */
890 qemu_unregister_reset(qbus_reset_all_fn, bus);
892 g_free((void*)bus->name);
893 if (bus->qdev_allocated) {
898 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
899 static void qbus_print(Monitor *mon, BusState *bus, int indent);
901 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
902 const char *prefix, int indent)
908 while (props->name) {
910 * TODO Properties without a print method are just for dirty
911 * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
912 * marked for removal. The test props->info->print should be
913 * removed along with it.
915 if (props->info->print) {
916 props->info->print(dev, props, buf, sizeof(buf));
917 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
923 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
926 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
927 dev->id ? dev->id : "");
929 if (dev->num_gpio_in) {
930 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
932 if (dev->num_gpio_out) {
933 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
935 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
936 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
937 if (dev->parent_bus->info->print_dev)
938 dev->parent_bus->info->print_dev(mon, dev, indent);
939 QLIST_FOREACH(child, &dev->child_bus, sibling) {
940 qbus_print(mon, child, indent);
944 static void qbus_print(Monitor *mon, BusState *bus, int indent)
946 struct DeviceState *dev;
948 qdev_printf("bus: %s\n", bus->name);
950 qdev_printf("type %s\n", bus->info->name);
951 QTAILQ_FOREACH(dev, &bus->children, sibling) {
952 qdev_print(mon, dev, indent);
957 void do_info_qtree(Monitor *mon)
960 qbus_print(mon, main_system_bus, 0);
963 void do_info_qdm(Monitor *mon)
967 for (info = device_info_list; info != NULL; info = info->next) {
968 qdev_print_devinfo(info);
972 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
976 opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
980 if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
984 if (!qdev_device_add(opts)) {
991 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
993 const char *id = qdict_get_str(qdict, "id");
996 dev = qdev_find_recursive(main_system_bus, id);
998 qerror_report(QERR_DEVICE_NOT_FOUND, id);
1001 return qdev_unplug(dev);
1004 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
1008 if (dev && dev->parent_bus) {
1010 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
1011 if (dev->parent_bus->info->get_fw_dev_path) {
1012 d = dev->parent_bus->info->get_fw_dev_path(dev);
1013 l += snprintf(p + l, size - l, "%s", d);
1016 l += snprintf(p + l, size - l, "%s", dev->info->name);
1019 l += snprintf(p + l , size - l, "/");
1024 char* qdev_get_fw_dev_path(DeviceState *dev)
1029 l = qdev_get_fw_dev_path_helper(dev, path, 128);
1033 return strdup(path);
1036 char *qdev_get_type(DeviceState *dev, Error **errp)
1038 return g_strdup(dev->info->name);
1041 void qdev_ref(DeviceState *dev)
1046 void qdev_unref(DeviceState *dev)
1048 g_assert(dev->ref > 0);
1052 void qdev_property_add(DeviceState *dev, const char *name, const char *type,
1053 DevicePropertyAccessor *get, DevicePropertyAccessor *set,
1054 DevicePropertyRelease *release,
1055 void *opaque, Error **errp)
1057 DeviceProperty *prop = g_malloc0(sizeof(*prop));
1059 prop->name = g_strdup(name);
1060 prop->type = g_strdup(type);
1064 prop->release = release;
1065 prop->opaque = opaque;
1067 QTAILQ_INSERT_TAIL(&dev->properties, prop, node);
1070 static DeviceProperty *qdev_property_find(DeviceState *dev, const char *name)
1072 DeviceProperty *prop;
1074 QTAILQ_FOREACH(prop, &dev->properties, node) {
1075 if (strcmp(prop->name, name) == 0) {
1083 void qdev_property_get(DeviceState *dev, Visitor *v, const char *name,
1086 DeviceProperty *prop = qdev_property_find(dev, name);
1089 error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1094 error_set(errp, QERR_PERMISSION_DENIED);
1096 prop->get(dev, v, prop->opaque, name, errp);
1100 void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
1103 DeviceProperty *prop = qdev_property_find(dev, name);
1106 error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1111 error_set(errp, QERR_PERMISSION_DENIED);
1113 prop->set(dev, prop->opaque, v, name, errp);
1117 const char *qdev_property_get_type(DeviceState *dev, const char *name, Error **errp)
1119 DeviceProperty *prop = qdev_property_find(dev, name);
1122 error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1130 * Legacy property handling
1133 static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1134 const char *name, Error **errp)
1136 Property *prop = opaque;
1138 if (prop->info->print) {
1142 prop->info->print(dev, prop, buffer, sizeof(buffer));
1143 visit_type_str(v, &ptr, name, errp);
1145 error_set(errp, QERR_PERMISSION_DENIED);
1149 static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1150 const char *name, Error **errp)
1152 Property *prop = opaque;
1154 if (dev->state != DEV_STATE_CREATED) {
1155 error_set(errp, QERR_PERMISSION_DENIED);
1159 if (prop->info->parse) {
1160 Error *local_err = NULL;
1163 visit_type_str(v, &ptr, name, &local_err);
1166 ret = prop->info->parse(dev, prop, ptr);
1168 error_set(errp, QERR_INVALID_PARAMETER_VALUE,
1169 name, prop->info->name);
1173 error_propagate(errp, local_err);
1176 error_set(errp, QERR_PERMISSION_DENIED);
1181 * @qdev_add_legacy_property - adds a legacy property
1183 * Do not use this is new code! Properties added through this interface will
1184 * be given types in the "legacy<>" type namespace.
1186 * Legacy properties are always processed as strings. The format of the string
1187 * depends on the property type.
1189 void qdev_property_add_legacy(DeviceState *dev, Property *prop,
1194 type = g_strdup_printf("legacy<%s>", prop->info->name);
1196 qdev_property_add(dev, prop->name, type,
1197 qdev_get_legacy_property,
1198 qdev_set_legacy_property,
1205 DeviceState *qdev_get_root(void)
1207 static DeviceState *qdev_root;
1210 qdev_root = qdev_create(NULL, "container");
1211 qdev_init_nofail(qdev_root);
1217 static void qdev_get_child_property(DeviceState *dev, Visitor *v, void *opaque,
1218 const char *name, Error **errp)
1220 DeviceState *child = opaque;
1223 path = qdev_get_canonical_path(child);
1224 visit_type_str(v, &path, name, errp);
1228 void qdev_property_add_child(DeviceState *dev, const char *name,
1229 DeviceState *child, Error **errp)
1233 type = g_strdup_printf("child<%s>", child->info->name);
1235 qdev_property_add(dev, name, type, qdev_get_child_property,
1236 NULL, NULL, child, errp);
1239 g_assert(child->parent == NULL);
1240 child->parent = dev;
1245 static void qdev_get_link_property(DeviceState *dev, Visitor *v, void *opaque,
1246 const char *name, Error **errp)
1248 DeviceState **child = opaque;
1252 path = qdev_get_canonical_path(*child);
1253 visit_type_str(v, &path, name, errp);
1257 visit_type_str(v, &path, name, errp);
1261 static void qdev_set_link_property(DeviceState *dev, Visitor *v, void *opaque,
1262 const char *name, Error **errp)
1264 DeviceState **child = opaque;
1265 bool ambiguous = false;
1269 type = qdev_property_get_type(dev, name, NULL);
1271 visit_type_str(v, &path, name, errp);
1277 if (strcmp(path, "") != 0) {
1278 DeviceState *target;
1280 target = qdev_resolve_path(path, &ambiguous);
1284 target_type = g_strdup_printf("link<%s>", target->info->name);
1285 if (strcmp(target_type, type) == 0) {
1289 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
1292 g_free(target_type);
1294 error_set(errp, QERR_DEVICE_NOT_FOUND, path);
1303 void qdev_property_add_link(DeviceState *dev, const char *name,
1304 const char *type, DeviceState **child,
1309 full_type = g_strdup_printf("link<%s>", type);
1311 qdev_property_add(dev, name, full_type,
1312 qdev_get_link_property,
1313 qdev_set_link_property,
1319 gchar *qdev_get_canonical_path(DeviceState *dev)
1321 DeviceState *root = qdev_get_root();
1322 char *newpath = NULL, *path = NULL;
1324 while (dev != root) {
1325 DeviceProperty *prop = NULL;
1327 g_assert(dev->parent != NULL);
1329 QTAILQ_FOREACH(prop, &dev->parent->properties, node) {
1330 if (!strstart(prop->type, "child<", NULL)) {
1334 if (prop->opaque == dev) {
1336 newpath = g_strdup_printf("%s/%s", prop->name, path);
1340 path = g_strdup(prop->name);
1346 g_assert(prop != NULL);
1351 newpath = g_strdup_printf("/%s", path);
1357 static DeviceState *qdev_resolve_abs_path(DeviceState *parent,
1361 DeviceProperty *prop;
1364 if (parts[index] == NULL) {
1368 if (strcmp(parts[index], "") == 0) {
1369 return qdev_resolve_abs_path(parent, parts, index + 1);
1372 prop = qdev_property_find(parent, parts[index]);
1378 if (strstart(prop->type, "link<", NULL)) {
1379 DeviceState **pchild = prop->opaque;
1383 } else if (strstart(prop->type, "child<", NULL)) {
1384 child = prop->opaque;
1391 return qdev_resolve_abs_path(child, parts, index + 1);
1394 static DeviceState *qdev_resolve_partial_path(DeviceState *parent,
1399 DeviceProperty *prop;
1401 dev = qdev_resolve_abs_path(parent, parts, 0);
1403 QTAILQ_FOREACH(prop, &parent->properties, node) {
1406 if (!strstart(prop->type, "child<", NULL)) {
1410 found = qdev_resolve_partial_path(prop->opaque, parts, ambiguous);
1421 if (ambiguous && *ambiguous) {
1429 DeviceState *qdev_resolve_path(const char *path, bool *ambiguous)
1431 bool partial_path = true;
1435 parts = g_strsplit(path, "/", 0);
1436 if (parts == NULL || parts[0] == NULL) {
1438 return qdev_get_root();
1441 if (strcmp(parts[0], "") == 0) {
1442 partial_path = false;
1449 dev = qdev_resolve_partial_path(qdev_get_root(), parts, ambiguous);
1451 dev = qdev_resolve_abs_path(qdev_get_root(), parts, 1);
1459 typedef struct StringProperty
1461 char *(*get)(DeviceState *, Error **);
1462 void (*set)(DeviceState *, const char *, Error **);
1465 static void qdev_property_get_str(DeviceState *dev, Visitor *v, void *opaque,
1466 const char *name, Error **errp)
1468 StringProperty *prop = opaque;
1471 value = prop->get(dev, errp);
1473 visit_type_str(v, &value, name, errp);
1478 static void qdev_property_set_str(DeviceState *dev, Visitor *v, void *opaque,
1479 const char *name, Error **errp)
1481 StringProperty *prop = opaque;
1483 Error *local_err = NULL;
1485 visit_type_str(v, &value, name, &local_err);
1487 error_propagate(errp, local_err);
1491 prop->set(dev, value, errp);
1495 static void qdev_property_release_str(DeviceState *dev, const char *name,
1498 StringProperty *prop = opaque;
1502 void qdev_property_add_str(DeviceState *dev, const char *name,
1503 char *(*get)(DeviceState *, Error **),
1504 void (*set)(DeviceState *, const char *, Error **),
1507 StringProperty *prop = g_malloc0(sizeof(*prop));
1512 qdev_property_add(dev, name, "string",
1513 get ? qdev_property_get_str : NULL,
1514 set ? qdev_property_set_str : NULL,
1515 qdev_property_release_str,