qdev: add explicitly named devices to the root complex
[qemu/kevin.git] / hw / qdev.c
blobcb3fc6e56dd1a7dc1cf8c25c3f8987023747d80c
1 /*
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
26 this API directly. */
28 #include "net.h"
29 #include "qdev.h"
30 #include "sysemu.h"
31 #include "monitor.h"
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,
44 const BusInfo *info);
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));
51 assert(!info->next);
53 info->next = device_info_list;
54 device_info_list = info;
57 static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
59 DeviceInfo *info;
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)
64 continue;
65 if (strcmp(info->name, name) != 0)
66 continue;
67 return info;
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)
73 continue;
74 if (!info->alias)
75 continue;
76 if (strcmp(info->alias, name) != 0)
77 continue;
78 return info;
80 return NULL;
83 static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
85 DeviceState *dev;
86 Property *prop;
88 assert(bus->info == info->bus_info);
89 dev = g_malloc0(info->size);
90 dev->info = info;
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);
96 if (qdev_hotplug) {
97 assert(bus->allow_hotplug);
98 dev->hotplugged = 1;
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 return dev;
116 /* Create a new device. This only initializes the device state structure
117 and allows properties to be set. qdev_init should be called to
118 initialize the actual device emulation. */
119 DeviceState *qdev_create(BusState *bus, const char *name)
121 DeviceState *dev;
123 dev = qdev_try_create(bus, name);
124 if (!dev) {
125 if (bus) {
126 hw_error("Unknown device '%s' for bus '%s'\n", name,
127 bus->info->name);
128 } else {
129 hw_error("Unknown device '%s' for default sysbus\n", name);
133 return dev;
136 DeviceState *qdev_try_create(BusState *bus, const char *name)
138 DeviceInfo *info;
140 if (!bus) {
141 bus = sysbus_get_default();
144 info = qdev_find_info(bus->info, name);
145 if (!info) {
146 return NULL;
149 return qdev_create_from_info(bus, info);
152 static void qdev_print_devinfo(DeviceInfo *info)
154 error_printf("name \"%s\", bus %s",
155 info->name, info->bus_info->name);
156 if (info->alias) {
157 error_printf(", alias \"%s\"", info->alias);
159 if (info->desc) {
160 error_printf(", desc \"%s\"", info->desc);
162 if (info->no_user) {
163 error_printf(", no-user");
165 error_printf("\n");
168 static int set_property(const char *name, const char *value, void *opaque)
170 DeviceState *dev = opaque;
172 if (strcmp(name, "driver") == 0)
173 return 0;
174 if (strcmp(name, "bus") == 0)
175 return 0;
177 if (qdev_prop_parse(dev, name, value) == -1) {
178 return -1;
180 return 0;
183 int qdev_device_help(QemuOpts *opts)
185 const char *driver;
186 DeviceInfo *info;
187 Property *prop;
189 driver = qemu_opt_get(opts, "driver");
190 if (driver && !strcmp(driver, "?")) {
191 for (info = device_info_list; info != NULL; info = info->next) {
192 if (info->no_user) {
193 continue; /* not available, don't show */
195 qdev_print_devinfo(info);
197 return 1;
200 if (!driver || !qemu_opt_get(opts, "?")) {
201 return 0;
204 info = qdev_find_info(NULL, driver);
205 if (!info) {
206 return 0;
209 for (prop = info->props; prop && prop->name; prop++) {
211 * TODO Properties without a parser are just for dirty hacks.
212 * qdev_prop_ptr is the only such PropertyInfo. It's marked
213 * for removal. This conditional should be removed along with
214 * it.
216 if (!prop->info->parse) {
217 continue; /* no way to set it, don't show */
219 error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
221 for (prop = info->bus_info->props; prop && prop->name; prop++) {
222 if (!prop->info->parse) {
223 continue; /* no way to set it, don't show */
225 error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
227 return 1;
230 static DeviceState *qdev_get_peripheral(void)
232 static DeviceState *dev;
234 if (dev == NULL) {
235 dev = qdev_create(NULL, "container");
236 qdev_property_add_child(qdev_get_root(), "peripheral", dev, NULL);
237 qdev_init_nofail(dev);
240 return dev;
243 DeviceState *qdev_device_add(QemuOpts *opts)
245 const char *driver, *path, *id;
246 DeviceInfo *info;
247 DeviceState *qdev;
248 BusState *bus;
250 driver = qemu_opt_get(opts, "driver");
251 if (!driver) {
252 qerror_report(QERR_MISSING_PARAMETER, "driver");
253 return NULL;
256 /* find driver */
257 info = qdev_find_info(NULL, driver);
258 if (!info || info->no_user) {
259 qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
260 error_printf_unless_qmp("Try with argument '?' for a list.\n");
261 return NULL;
264 /* find bus */
265 path = qemu_opt_get(opts, "bus");
266 if (path != NULL) {
267 bus = qbus_find(path);
268 if (!bus) {
269 return NULL;
271 if (bus->info != info->bus_info) {
272 qerror_report(QERR_BAD_BUS_FOR_DEVICE,
273 driver, bus->info->name);
274 return NULL;
276 } else {
277 bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
278 if (!bus) {
279 qerror_report(QERR_NO_BUS_FOR_DEVICE,
280 info->name, info->bus_info->name);
281 return NULL;
284 if (qdev_hotplug && !bus->allow_hotplug) {
285 qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
286 return NULL;
289 /* create device, set properties */
290 qdev = qdev_create_from_info(bus, info);
291 id = qemu_opts_id(opts);
292 if (id) {
293 qdev->id = id;
294 qdev_property_add_child(qdev_get_peripheral(), qdev->id, qdev, NULL);
296 if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
297 qdev_free(qdev);
298 return NULL;
300 if (qdev_init(qdev) < 0) {
301 qerror_report(QERR_DEVICE_INIT_FAILED, driver);
302 return NULL;
304 qdev->opts = opts;
305 return qdev;
308 /* Initialize a device. Device properties should be set before calling
309 this function. IRQs and MMIO regions should be connected/mapped after
310 calling this function.
311 On failure, destroy the device and return negative value.
312 Return 0 on success. */
313 int qdev_init(DeviceState *dev)
315 int rc;
317 assert(dev->state == DEV_STATE_CREATED);
318 rc = dev->info->init(dev, dev->info);
319 if (rc < 0) {
320 qdev_free(dev);
321 return rc;
323 if (dev->info->vmsd) {
324 vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,
325 dev->instance_id_alias,
326 dev->alias_required_for_version);
328 dev->state = DEV_STATE_INITIALIZED;
329 if (dev->hotplugged && dev->info->reset) {
330 dev->info->reset(dev);
332 return 0;
335 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
336 int required_for_version)
338 assert(dev->state == DEV_STATE_CREATED);
339 dev->instance_id_alias = alias_id;
340 dev->alias_required_for_version = required_for_version;
343 int qdev_unplug(DeviceState *dev)
345 if (!dev->parent_bus->allow_hotplug) {
346 qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
347 return -1;
349 assert(dev->info->unplug != NULL);
351 if (dev->ref != 0) {
352 qerror_report(QERR_DEVICE_IN_USE, dev->id?:"");
353 return -1;
356 qdev_hot_removed = true;
358 return dev->info->unplug(dev);
361 static int qdev_reset_one(DeviceState *dev, void *opaque)
363 if (dev->info->reset) {
364 dev->info->reset(dev);
367 return 0;
370 BusState *sysbus_get_default(void)
372 if (!main_system_bus) {
373 main_system_bus_create();
375 return main_system_bus;
378 static int qbus_reset_one(BusState *bus, void *opaque)
380 if (bus->info->reset) {
381 return bus->info->reset(bus);
383 return 0;
386 void qdev_reset_all(DeviceState *dev)
388 qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
391 void qbus_reset_all_fn(void *opaque)
393 BusState *bus = opaque;
394 qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
397 /* can be used as ->unplug() callback for the simple cases */
398 int qdev_simple_unplug_cb(DeviceState *dev)
400 /* just zap it */
401 qdev_free(dev);
402 return 0;
406 /* Like qdev_init(), but terminate program via error_report() instead of
407 returning an error value. This is okay during machine creation.
408 Don't use for hotplug, because there callers need to recover from
409 failure. Exception: if you know the device's init() callback can't
410 fail, then qdev_init_nofail() can't fail either, and is therefore
411 usable even then. But relying on the device implementation that
412 way is somewhat unclean, and best avoided. */
413 void qdev_init_nofail(DeviceState *dev)
415 DeviceInfo *info = dev->info;
417 if (qdev_init(dev) < 0) {
418 error_report("Initialization of device %s failed", info->name);
419 exit(1);
423 static void qdev_property_del_all(DeviceState *dev)
425 while (!QTAILQ_EMPTY(&dev->properties)) {
426 DeviceProperty *prop = QTAILQ_FIRST(&dev->properties);
428 QTAILQ_REMOVE(&dev->properties, prop, node);
430 if (prop->release) {
431 prop->release(dev, prop->name, prop->opaque);
434 g_free(prop->name);
435 g_free(prop->type);
436 g_free(prop);
440 /* Unlink device from bus and free the structure. */
441 void qdev_free(DeviceState *dev)
443 BusState *bus;
444 Property *prop;
446 qdev_property_del_all(dev);
448 if (dev->state == DEV_STATE_INITIALIZED) {
449 while (dev->num_child_bus) {
450 bus = QLIST_FIRST(&dev->child_bus);
451 qbus_free(bus);
453 if (dev->info->vmsd)
454 vmstate_unregister(dev, dev->info->vmsd, dev);
455 if (dev->info->exit)
456 dev->info->exit(dev);
457 if (dev->opts)
458 qemu_opts_del(dev->opts);
460 QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
461 for (prop = dev->info->props; prop && prop->name; prop++) {
462 if (prop->info->free) {
463 prop->info->free(dev, prop);
466 g_free(dev);
469 void qdev_machine_creation_done(void)
472 * ok, initial machine setup is done, starting from now we can
473 * only create hotpluggable devices
475 qdev_hotplug = 1;
478 bool qdev_machine_modified(void)
480 return qdev_hot_added || qdev_hot_removed;
483 /* Get a character (serial) device interface. */
484 CharDriverState *qdev_init_chardev(DeviceState *dev)
486 static int next_serial;
488 /* FIXME: This function needs to go away: use chardev properties! */
489 return serial_hds[next_serial++];
492 BusState *qdev_get_parent_bus(DeviceState *dev)
494 return dev->parent_bus;
497 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
499 assert(dev->num_gpio_in == 0);
500 dev->num_gpio_in = n;
501 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
504 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
506 assert(dev->num_gpio_out == 0);
507 dev->num_gpio_out = n;
508 dev->gpio_out = pins;
511 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
513 assert(n >= 0 && n < dev->num_gpio_in);
514 return dev->gpio_in[n];
517 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
519 assert(n >= 0 && n < dev->num_gpio_out);
520 dev->gpio_out[n] = pin;
523 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
525 qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
526 if (nd->vlan)
527 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
528 if (nd->netdev)
529 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
530 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
531 qdev_prop_exists(dev, "vectors")) {
532 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
534 nd->instantiated = 1;
537 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
539 BusState *bus;
541 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
542 if (strcmp(name, bus->name) == 0) {
543 return bus;
546 return NULL;
549 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
550 qbus_walkerfn *busfn, void *opaque)
552 DeviceState *dev;
553 int err;
555 if (busfn) {
556 err = busfn(bus, opaque);
557 if (err) {
558 return err;
562 QTAILQ_FOREACH(dev, &bus->children, sibling) {
563 err = qdev_walk_children(dev, devfn, busfn, opaque);
564 if (err < 0) {
565 return err;
569 return 0;
572 int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
573 qbus_walkerfn *busfn, void *opaque)
575 BusState *bus;
576 int err;
578 if (devfn) {
579 err = devfn(dev, opaque);
580 if (err) {
581 return err;
585 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
586 err = qbus_walk_children(bus, devfn, busfn, opaque);
587 if (err < 0) {
588 return err;
592 return 0;
595 static BusState *qbus_find_recursive(BusState *bus, const char *name,
596 const BusInfo *info)
598 DeviceState *dev;
599 BusState *child, *ret;
600 int match = 1;
602 if (name && (strcmp(bus->name, name) != 0)) {
603 match = 0;
605 if (info && (bus->info != info)) {
606 match = 0;
608 if (match) {
609 return bus;
612 QTAILQ_FOREACH(dev, &bus->children, sibling) {
613 QLIST_FOREACH(child, &dev->child_bus, sibling) {
614 ret = qbus_find_recursive(child, name, info);
615 if (ret) {
616 return ret;
620 return NULL;
623 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
625 DeviceState *dev, *ret;
626 BusState *child;
628 QTAILQ_FOREACH(dev, &bus->children, sibling) {
629 if (dev->id && strcmp(dev->id, id) == 0)
630 return dev;
631 QLIST_FOREACH(child, &dev->child_bus, sibling) {
632 ret = qdev_find_recursive(child, id);
633 if (ret) {
634 return ret;
638 return NULL;
641 static void qbus_list_bus(DeviceState *dev)
643 BusState *child;
644 const char *sep = " ";
646 error_printf("child busses at \"%s\":",
647 dev->id ? dev->id : dev->info->name);
648 QLIST_FOREACH(child, &dev->child_bus, sibling) {
649 error_printf("%s\"%s\"", sep, child->name);
650 sep = ", ";
652 error_printf("\n");
655 static void qbus_list_dev(BusState *bus)
657 DeviceState *dev;
658 const char *sep = " ";
660 error_printf("devices at \"%s\":", bus->name);
661 QTAILQ_FOREACH(dev, &bus->children, sibling) {
662 error_printf("%s\"%s\"", sep, dev->info->name);
663 if (dev->id)
664 error_printf("/\"%s\"", dev->id);
665 sep = ", ";
667 error_printf("\n");
670 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
672 BusState *child;
674 QLIST_FOREACH(child, &dev->child_bus, sibling) {
675 if (strcmp(child->name, elem) == 0) {
676 return child;
679 return NULL;
682 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
684 DeviceState *dev;
687 * try to match in order:
688 * (1) instance id, if present
689 * (2) driver name
690 * (3) driver alias, if present
692 QTAILQ_FOREACH(dev, &bus->children, sibling) {
693 if (dev->id && strcmp(dev->id, elem) == 0) {
694 return dev;
697 QTAILQ_FOREACH(dev, &bus->children, sibling) {
698 if (strcmp(dev->info->name, elem) == 0) {
699 return dev;
702 QTAILQ_FOREACH(dev, &bus->children, sibling) {
703 if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
704 return dev;
707 return NULL;
710 static BusState *qbus_find(const char *path)
712 DeviceState *dev;
713 BusState *bus;
714 char elem[128];
715 int pos, len;
717 /* find start element */
718 if (path[0] == '/') {
719 bus = main_system_bus;
720 pos = 0;
721 } else {
722 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
723 assert(!path[0]);
724 elem[0] = len = 0;
726 bus = qbus_find_recursive(main_system_bus, elem, NULL);
727 if (!bus) {
728 qerror_report(QERR_BUS_NOT_FOUND, elem);
729 return NULL;
731 pos = len;
734 for (;;) {
735 assert(path[pos] == '/' || !path[pos]);
736 while (path[pos] == '/') {
737 pos++;
739 if (path[pos] == '\0') {
740 return bus;
743 /* find device */
744 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
745 assert(0);
746 elem[0] = len = 0;
748 pos += len;
749 dev = qbus_find_dev(bus, elem);
750 if (!dev) {
751 qerror_report(QERR_DEVICE_NOT_FOUND, elem);
752 if (!monitor_cur_is_qmp()) {
753 qbus_list_dev(bus);
755 return NULL;
758 assert(path[pos] == '/' || !path[pos]);
759 while (path[pos] == '/') {
760 pos++;
762 if (path[pos] == '\0') {
763 /* last specified element is a device. If it has exactly
764 * one child bus accept it nevertheless */
765 switch (dev->num_child_bus) {
766 case 0:
767 qerror_report(QERR_DEVICE_NO_BUS, elem);
768 return NULL;
769 case 1:
770 return QLIST_FIRST(&dev->child_bus);
771 default:
772 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
773 if (!monitor_cur_is_qmp()) {
774 qbus_list_bus(dev);
776 return NULL;
780 /* find bus */
781 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
782 assert(0);
783 elem[0] = len = 0;
785 pos += len;
786 bus = qbus_find_bus(dev, elem);
787 if (!bus) {
788 qerror_report(QERR_BUS_NOT_FOUND, elem);
789 if (!monitor_cur_is_qmp()) {
790 qbus_list_bus(dev);
792 return NULL;
797 void qbus_create_inplace(BusState *bus, BusInfo *info,
798 DeviceState *parent, const char *name)
800 char *buf;
801 int i,len;
803 bus->info = info;
804 bus->parent = parent;
806 if (name) {
807 /* use supplied name */
808 bus->name = g_strdup(name);
809 } else if (parent && parent->id) {
810 /* parent device has id -> use it for bus name */
811 len = strlen(parent->id) + 16;
812 buf = g_malloc(len);
813 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
814 bus->name = buf;
815 } else {
816 /* no id -> use lowercase bus type for bus name */
817 len = strlen(info->name) + 16;
818 buf = g_malloc(len);
819 len = snprintf(buf, len, "%s.%d", info->name,
820 parent ? parent->num_child_bus : 0);
821 for (i = 0; i < len; i++)
822 buf[i] = qemu_tolower(buf[i]);
823 bus->name = buf;
826 QTAILQ_INIT(&bus->children);
827 if (parent) {
828 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
829 parent->num_child_bus++;
830 } else if (bus != main_system_bus) {
831 /* TODO: once all bus devices are qdevified,
832 only reset handler for main_system_bus should be registered here. */
833 qemu_register_reset(qbus_reset_all_fn, bus);
837 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
839 BusState *bus;
841 bus = g_malloc0(info->size);
842 bus->qdev_allocated = 1;
843 qbus_create_inplace(bus, info, parent, name);
844 return bus;
847 static void main_system_bus_create(void)
849 /* assign main_system_bus before qbus_create_inplace()
850 * in order to make "if (bus != main_system_bus)" work */
851 main_system_bus = g_malloc0(system_bus_info.size);
852 main_system_bus->qdev_allocated = 1;
853 qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
854 "main-system-bus");
857 void qbus_free(BusState *bus)
859 DeviceState *dev;
861 while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
862 qdev_free(dev);
864 if (bus->parent) {
865 QLIST_REMOVE(bus, sibling);
866 bus->parent->num_child_bus--;
867 } else {
868 assert(bus != main_system_bus); /* main_system_bus is never freed */
869 qemu_unregister_reset(qbus_reset_all_fn, bus);
871 g_free((void*)bus->name);
872 if (bus->qdev_allocated) {
873 g_free(bus);
877 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
878 static void qbus_print(Monitor *mon, BusState *bus, int indent);
880 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
881 const char *prefix, int indent)
883 char buf[64];
885 if (!props)
886 return;
887 while (props->name) {
889 * TODO Properties without a print method are just for dirty
890 * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
891 * marked for removal. The test props->info->print should be
892 * removed along with it.
894 if (props->info->print) {
895 props->info->print(dev, props, buf, sizeof(buf));
896 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
898 props++;
902 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
904 BusState *child;
905 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
906 dev->id ? dev->id : "");
907 indent += 2;
908 if (dev->num_gpio_in) {
909 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
911 if (dev->num_gpio_out) {
912 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
914 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
915 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
916 if (dev->parent_bus->info->print_dev)
917 dev->parent_bus->info->print_dev(mon, dev, indent);
918 QLIST_FOREACH(child, &dev->child_bus, sibling) {
919 qbus_print(mon, child, indent);
923 static void qbus_print(Monitor *mon, BusState *bus, int indent)
925 struct DeviceState *dev;
927 qdev_printf("bus: %s\n", bus->name);
928 indent += 2;
929 qdev_printf("type %s\n", bus->info->name);
930 QTAILQ_FOREACH(dev, &bus->children, sibling) {
931 qdev_print(mon, dev, indent);
934 #undef qdev_printf
936 void do_info_qtree(Monitor *mon)
938 if (main_system_bus)
939 qbus_print(mon, main_system_bus, 0);
942 void do_info_qdm(Monitor *mon)
944 DeviceInfo *info;
946 for (info = device_info_list; info != NULL; info = info->next) {
947 qdev_print_devinfo(info);
951 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
953 QemuOpts *opts;
955 opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
956 if (!opts) {
957 return -1;
959 if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
960 qemu_opts_del(opts);
961 return 0;
963 if (!qdev_device_add(opts)) {
964 qemu_opts_del(opts);
965 return -1;
967 return 0;
970 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
972 const char *id = qdict_get_str(qdict, "id");
973 DeviceState *dev;
975 dev = qdev_find_recursive(main_system_bus, id);
976 if (NULL == dev) {
977 qerror_report(QERR_DEVICE_NOT_FOUND, id);
978 return -1;
980 return qdev_unplug(dev);
983 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
985 int l = 0;
987 if (dev && dev->parent_bus) {
988 char *d;
989 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
990 if (dev->parent_bus->info->get_fw_dev_path) {
991 d = dev->parent_bus->info->get_fw_dev_path(dev);
992 l += snprintf(p + l, size - l, "%s", d);
993 g_free(d);
994 } else {
995 l += snprintf(p + l, size - l, "%s", dev->info->name);
998 l += snprintf(p + l , size - l, "/");
1000 return l;
1003 char* qdev_get_fw_dev_path(DeviceState *dev)
1005 char path[128];
1006 int l;
1008 l = qdev_get_fw_dev_path_helper(dev, path, 128);
1010 path[l-1] = '\0';
1012 return strdup(path);
1015 void qdev_ref(DeviceState *dev)
1017 dev->ref++;
1020 void qdev_unref(DeviceState *dev)
1022 g_assert(dev->ref > 0);
1023 dev->ref--;
1026 void qdev_property_add(DeviceState *dev, const char *name, const char *type,
1027 DevicePropertyAccessor *get, DevicePropertyAccessor *set,
1028 DevicePropertyRelease *release,
1029 void *opaque, Error **errp)
1031 DeviceProperty *prop = g_malloc0(sizeof(*prop));
1033 prop->name = g_strdup(name);
1034 prop->type = g_strdup(type);
1036 prop->get = get;
1037 prop->set = set;
1038 prop->release = release;
1039 prop->opaque = opaque;
1041 QTAILQ_INSERT_TAIL(&dev->properties, prop, node);
1044 static DeviceProperty *qdev_property_find(DeviceState *dev, const char *name)
1046 DeviceProperty *prop;
1048 QTAILQ_FOREACH(prop, &dev->properties, node) {
1049 if (strcmp(prop->name, name) == 0) {
1050 return prop;
1054 return NULL;
1057 void qdev_property_get(DeviceState *dev, Visitor *v, const char *name,
1058 Error **errp)
1060 DeviceProperty *prop = qdev_property_find(dev, name);
1062 if (prop == NULL) {
1063 error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1064 return;
1067 if (!prop->get) {
1068 error_set(errp, QERR_PERMISSION_DENIED);
1069 } else {
1070 prop->get(dev, v, prop->opaque, name, errp);
1074 void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
1075 Error **errp)
1077 DeviceProperty *prop = qdev_property_find(dev, name);
1079 if (prop == NULL) {
1080 error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1081 return;
1084 if (!prop->set) {
1085 error_set(errp, QERR_PERMISSION_DENIED);
1086 } else {
1087 prop->set(dev, prop->opaque, v, name, errp);
1091 const char *qdev_property_get_type(DeviceState *dev, const char *name, Error **errp)
1093 DeviceProperty *prop = qdev_property_find(dev, name);
1095 if (prop == NULL) {
1096 error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1097 return NULL;
1100 return prop->type;
1104 * Legacy property handling
1107 static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1108 const char *name, Error **errp)
1110 Property *prop = opaque;
1112 if (prop->info->print) {
1113 char buffer[1024];
1114 char *ptr = buffer;
1116 prop->info->print(dev, prop, buffer, sizeof(buffer));
1117 visit_type_str(v, &ptr, name, errp);
1118 } else {
1119 error_set(errp, QERR_PERMISSION_DENIED);
1123 static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1124 const char *name, Error **errp)
1126 Property *prop = opaque;
1128 if (dev->state != DEV_STATE_CREATED) {
1129 error_set(errp, QERR_PERMISSION_DENIED);
1130 return;
1133 if (prop->info->parse) {
1134 Error *local_err = NULL;
1135 char *ptr = NULL;
1137 visit_type_str(v, &ptr, name, &local_err);
1138 if (!local_err) {
1139 int ret;
1140 ret = prop->info->parse(dev, prop, ptr);
1141 if (ret != 0) {
1142 error_set(errp, QERR_INVALID_PARAMETER_VALUE,
1143 name, prop->info->name);
1145 g_free(ptr);
1146 } else {
1147 error_propagate(errp, local_err);
1149 } else {
1150 error_set(errp, QERR_PERMISSION_DENIED);
1155 * @qdev_add_legacy_property - adds a legacy property
1157 * Do not use this is new code! Properties added through this interface will
1158 * be given types in the "legacy<>" type namespace.
1160 * Legacy properties are always processed as strings. The format of the string
1161 * depends on the property type.
1163 void qdev_property_add_legacy(DeviceState *dev, Property *prop,
1164 Error **errp)
1166 gchar *type;
1168 type = g_strdup_printf("legacy<%s>", prop->info->name);
1170 qdev_property_add(dev, prop->name, type,
1171 qdev_get_legacy_property,
1172 qdev_set_legacy_property,
1173 NULL,
1174 prop, errp);
1176 g_free(type);
1179 DeviceState *qdev_get_root(void)
1181 static DeviceState *qdev_root;
1183 if (!qdev_root) {
1184 qdev_root = qdev_create(NULL, "container");
1185 qdev_init_nofail(qdev_root);
1188 return qdev_root;
1191 static void qdev_get_child_property(DeviceState *dev, Visitor *v, void *opaque,
1192 const char *name, Error **errp)
1194 DeviceState *child = opaque;
1195 gchar *path;
1197 path = qdev_get_canonical_path(child);
1198 visit_type_str(v, &path, name, errp);
1199 g_free(path);
1202 void qdev_property_add_child(DeviceState *dev, const char *name,
1203 DeviceState *child, Error **errp)
1205 gchar *type;
1207 type = g_strdup_printf("child<%s>", child->info->name);
1209 qdev_property_add(dev, name, type, qdev_get_child_property,
1210 NULL, NULL, child, errp);
1212 qdev_ref(child);
1214 g_free(type);
1217 static void qdev_get_link_property(DeviceState *dev, Visitor *v, void *opaque,
1218 const char *name, Error **errp)
1220 DeviceState **child = opaque;
1221 gchar *path;
1223 if (*child) {
1224 path = qdev_get_canonical_path(*child);
1225 visit_type_str(v, &path, name, errp);
1226 g_free(path);
1227 } else {
1228 path = (gchar *)"";
1229 visit_type_str(v, &path, name, errp);
1233 static void qdev_set_link_property(DeviceState *dev, Visitor *v, void *opaque,
1234 const char *name, Error **errp)
1236 DeviceState **child = opaque;
1237 bool ambiguous = false;
1238 const char *type;
1239 char *path;
1241 type = qdev_property_get_type(dev, name, NULL);
1243 visit_type_str(v, &path, name, errp);
1245 if (*child) {
1246 qdev_unref(*child);
1249 if (strcmp(path, "") != 0) {
1250 DeviceState *target;
1252 target = qdev_resolve_path(path, &ambiguous);
1253 if (target) {
1254 gchar *target_type;
1256 target_type = g_strdup_printf("link<%s>", target->info->name);
1257 if (strcmp(target_type, type) == 0) {
1258 *child = target;
1259 qdev_ref(target);
1260 } else {
1261 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
1264 g_free(target_type);
1265 } else {
1266 error_set(errp, QERR_DEVICE_NOT_FOUND, path);
1268 } else {
1269 *child = NULL;
1272 g_free(path);
1275 void qdev_property_add_link(DeviceState *dev, const char *name,
1276 const char *type, DeviceState **child,
1277 Error **errp)
1279 gchar *full_type;
1281 full_type = g_strdup_printf("link<%s>", type);
1283 qdev_property_add(dev, name, full_type,
1284 qdev_get_link_property,
1285 qdev_set_link_property,
1286 NULL, child, errp);
1288 g_free(full_type);
1291 static gchar *qdev_get_path_in(DeviceState *parent, DeviceState *dev)
1293 DeviceProperty *prop;
1295 if (parent == dev) {
1296 return g_strdup("");
1299 QTAILQ_FOREACH(prop, &parent->properties, node) {
1300 gchar *subpath;
1302 if (!strstart(prop->type, "child<", NULL)) {
1303 continue;
1306 /* Check to see if the device is one of parent's children */
1307 if (prop->opaque == dev) {
1308 return g_strdup(prop->name);
1311 /* Check to see if the device is a child of our child */
1312 subpath = qdev_get_path_in(prop->opaque, dev);
1313 if (subpath) {
1314 gchar *path;
1316 path = g_strdup_printf("%s/%s", prop->name, subpath);
1317 g_free(subpath);
1319 return path;
1323 return NULL;
1326 gchar *qdev_get_canonical_path(DeviceState *dev)
1328 gchar *path, *newpath;
1330 path = qdev_get_path_in(qdev_get_root(), dev);
1331 g_assert(path != NULL);
1333 newpath = g_strdup_printf("/%s", path);
1334 g_free(path);
1336 return newpath;
1339 static DeviceState *qdev_resolve_abs_path(DeviceState *parent,
1340 gchar **parts,
1341 int index)
1343 DeviceProperty *prop;
1344 DeviceState *child;
1346 if (parts[index] == NULL) {
1347 return parent;
1350 if (strcmp(parts[index], "") == 0) {
1351 return qdev_resolve_abs_path(parent, parts, index + 1);
1354 prop = qdev_property_find(parent, parts[index]);
1355 if (prop == NULL) {
1356 return NULL;
1359 child = NULL;
1360 if (strstart(prop->type, "link<", NULL)) {
1361 DeviceState **pchild = prop->opaque;
1362 if (*pchild) {
1363 child = *pchild;
1365 } else if (strstart(prop->type, "child<", NULL)) {
1366 child = prop->opaque;
1369 if (!child) {
1370 return NULL;
1373 return qdev_resolve_abs_path(child, parts, index + 1);
1376 static DeviceState *qdev_resolve_partial_path(DeviceState *parent,
1377 gchar **parts,
1378 bool *ambiguous)
1380 DeviceState *dev;
1381 DeviceProperty *prop;
1383 dev = qdev_resolve_abs_path(parent, parts, 0);
1385 QTAILQ_FOREACH(prop, &parent->properties, node) {
1386 DeviceState *found;
1388 if (!strstart(prop->type, "child<", NULL)) {
1389 continue;
1392 found = qdev_resolve_partial_path(prop->opaque, parts, ambiguous);
1393 if (found) {
1394 if (dev) {
1395 if (ambiguous) {
1396 *ambiguous = true;
1398 return NULL;
1400 dev = found;
1403 if (ambiguous && *ambiguous) {
1404 return NULL;
1408 return dev;
1411 DeviceState *qdev_resolve_path(const char *path, bool *ambiguous)
1413 bool partial_path = true;
1414 DeviceState *dev;
1415 gchar **parts;
1417 parts = g_strsplit(path, "/", 0);
1418 if (parts == NULL || parts[0] == NULL) {
1419 g_strfreev(parts);
1420 return qdev_get_root();
1423 if (strcmp(parts[0], "") == 0) {
1424 partial_path = false;
1427 if (partial_path) {
1428 if (ambiguous) {
1429 *ambiguous = false;
1431 dev = qdev_resolve_partial_path(qdev_get_root(), parts, ambiguous);
1432 } else {
1433 dev = qdev_resolve_abs_path(qdev_get_root(), parts, 1);
1436 g_strfreev(parts);
1438 return dev;