sparc: fix NaN handling
[qemu.git] / hw / qdev.c
blob5b8d3742ec71bf757d6099aae3012988857c32de
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"
32 #include "blockdev.h"
34 static int qdev_hotplug = 0;
35 static bool qdev_hot_added = false;
36 static bool qdev_hot_removed = false;
38 /* This is a nasty hack to allow passing a NULL bus to qdev_create. */
39 static BusState *main_system_bus;
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;
87 assert(bus->info == info->bus_info);
88 dev = qemu_mallocz(info->size);
89 dev->info = info;
90 dev->parent_bus = bus;
91 qdev_prop_set_defaults(dev, dev->info->props);
92 qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
93 qdev_prop_set_globals(dev);
94 QLIST_INSERT_HEAD(&bus->children, dev, sibling);
95 if (qdev_hotplug) {
96 assert(bus->allow_hotplug);
97 dev->hotplugged = 1;
98 qdev_hot_added = true;
100 dev->instance_id_alias = -1;
101 dev->state = DEV_STATE_CREATED;
102 return dev;
105 /* Create a new device. This only initializes the device state structure
106 and allows properties to be set. qdev_init should be called to
107 initialize the actual device emulation. */
108 DeviceState *qdev_create(BusState *bus, const char *name)
110 DeviceInfo *info;
112 if (!bus) {
113 bus = sysbus_get_default();
116 info = qdev_find_info(bus->info, name);
117 if (!info) {
118 hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
121 return qdev_create_from_info(bus, info);
124 static void qdev_print_devinfo(DeviceInfo *info)
126 error_printf("name \"%s\", bus %s",
127 info->name, info->bus_info->name);
128 if (info->alias) {
129 error_printf(", alias \"%s\"", info->alias);
131 if (info->desc) {
132 error_printf(", desc \"%s\"", info->desc);
134 if (info->no_user) {
135 error_printf(", no-user");
137 error_printf("\n");
140 static int set_property(const char *name, const char *value, void *opaque)
142 DeviceState *dev = opaque;
144 if (strcmp(name, "driver") == 0)
145 return 0;
146 if (strcmp(name, "bus") == 0)
147 return 0;
149 if (qdev_prop_parse(dev, name, value) == -1) {
150 return -1;
152 return 0;
155 int qdev_device_help(QemuOpts *opts)
157 const char *driver;
158 DeviceInfo *info;
159 Property *prop;
161 driver = qemu_opt_get(opts, "driver");
162 if (driver && !strcmp(driver, "?")) {
163 for (info = device_info_list; info != NULL; info = info->next) {
164 if (info->no_user) {
165 continue; /* not available, don't show */
167 qdev_print_devinfo(info);
169 return 1;
172 if (!qemu_opt_get(opts, "?")) {
173 return 0;
176 info = qdev_find_info(NULL, driver);
177 if (!info) {
178 return 0;
181 for (prop = info->props; prop && prop->name; prop++) {
183 * TODO Properties without a parser are just for dirty hacks.
184 * qdev_prop_ptr is the only such PropertyInfo. It's marked
185 * for removal. This conditional should be removed along with
186 * it.
188 if (!prop->info->parse) {
189 continue; /* no way to set it, don't show */
191 error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
193 return 1;
196 DeviceState *qdev_device_add(QemuOpts *opts)
198 const char *driver, *path, *id;
199 DeviceInfo *info;
200 DeviceState *qdev;
201 BusState *bus;
203 driver = qemu_opt_get(opts, "driver");
204 if (!driver) {
205 qerror_report(QERR_MISSING_PARAMETER, "driver");
206 return NULL;
209 /* find driver */
210 info = qdev_find_info(NULL, driver);
211 if (!info || info->no_user) {
212 qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
213 error_printf_unless_qmp("Try with argument '?' for a list.\n");
214 return NULL;
217 /* find bus */
218 path = qemu_opt_get(opts, "bus");
219 if (path != NULL) {
220 bus = qbus_find(path);
221 if (!bus) {
222 return NULL;
224 if (bus->info != info->bus_info) {
225 qerror_report(QERR_BAD_BUS_FOR_DEVICE,
226 driver, bus->info->name);
227 return NULL;
229 } else {
230 bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
231 if (!bus) {
232 qerror_report(QERR_NO_BUS_FOR_DEVICE,
233 info->name, info->bus_info->name);
234 return NULL;
237 if (qdev_hotplug && !bus->allow_hotplug) {
238 qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
239 return NULL;
242 /* create device, set properties */
243 qdev = qdev_create_from_info(bus, info);
244 id = qemu_opts_id(opts);
245 if (id) {
246 qdev->id = id;
248 if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
249 qdev_free(qdev);
250 return NULL;
252 if (qdev_init(qdev) < 0) {
253 qerror_report(QERR_DEVICE_INIT_FAILED, driver);
254 return NULL;
256 qdev->opts = opts;
257 return qdev;
260 /* Initialize a device. Device properties should be set before calling
261 this function. IRQs and MMIO regions should be connected/mapped after
262 calling this function.
263 On failure, destroy the device and return negative value.
264 Return 0 on success. */
265 int qdev_init(DeviceState *dev)
267 int rc;
269 assert(dev->state == DEV_STATE_CREATED);
270 rc = dev->info->init(dev, dev->info);
271 if (rc < 0) {
272 qdev_free(dev);
273 return rc;
275 if (dev->info->vmsd) {
276 vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,
277 dev->instance_id_alias,
278 dev->alias_required_for_version);
280 dev->state = DEV_STATE_INITIALIZED;
281 return 0;
284 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
285 int required_for_version)
287 assert(dev->state == DEV_STATE_CREATED);
288 dev->instance_id_alias = alias_id;
289 dev->alias_required_for_version = required_for_version;
292 int qdev_unplug(DeviceState *dev)
294 if (!dev->parent_bus->allow_hotplug) {
295 qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
296 return -1;
298 assert(dev->info->unplug != NULL);
300 qdev_hot_removed = true;
302 return dev->info->unplug(dev);
305 static int qdev_reset_one(DeviceState *dev, void *opaque)
307 if (dev->info->reset) {
308 dev->info->reset(dev);
311 return 0;
314 BusState *sysbus_get_default(void)
316 if (!main_system_bus) {
317 main_system_bus = qbus_create(&system_bus_info, NULL,
318 "main-system-bus");
320 return main_system_bus;
323 static int qbus_reset_one(BusState *bus, void *opaque)
325 if (bus->info->reset) {
326 return bus->info->reset(bus);
328 return 0;
331 void qdev_reset_all(DeviceState *dev)
333 qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
336 void qbus_reset_all_fn(void *opaque)
338 BusState *bus = opaque;
339 qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
342 /* can be used as ->unplug() callback for the simple cases */
343 int qdev_simple_unplug_cb(DeviceState *dev)
345 /* just zap it */
346 qdev_free(dev);
347 return 0;
350 /* Like qdev_init(), but terminate program via hw_error() instead of
351 returning an error value. This is okay during machine creation.
352 Don't use for hotplug, because there callers need to recover from
353 failure. Exception: if you know the device's init() callback can't
354 fail, then qdev_init_nofail() can't fail either, and is therefore
355 usable even then. But relying on the device implementation that
356 way is somewhat unclean, and best avoided. */
357 void qdev_init_nofail(DeviceState *dev)
359 DeviceInfo *info = dev->info;
361 if (qdev_init(dev) < 0) {
362 error_report("Initialization of device %s failed\n", info->name);
363 exit(1);
367 /* Unlink device from bus and free the structure. */
368 void qdev_free(DeviceState *dev)
370 BusState *bus;
371 Property *prop;
373 if (dev->state == DEV_STATE_INITIALIZED) {
374 while (dev->num_child_bus) {
375 bus = QLIST_FIRST(&dev->child_bus);
376 qbus_free(bus);
378 if (dev->info->vmsd)
379 vmstate_unregister(dev, dev->info->vmsd, dev);
380 if (dev->info->exit)
381 dev->info->exit(dev);
382 if (dev->opts)
383 qemu_opts_del(dev->opts);
385 QLIST_REMOVE(dev, sibling);
386 for (prop = dev->info->props; prop && prop->name; prop++) {
387 if (prop->info->free) {
388 prop->info->free(dev, prop);
391 qemu_free(dev);
394 void qdev_machine_creation_done(void)
397 * ok, initial machine setup is done, starting from now we can
398 * only create hotpluggable devices
400 qdev_hotplug = 1;
403 bool qdev_machine_modified(void)
405 return qdev_hot_added || qdev_hot_removed;
408 /* Get a character (serial) device interface. */
409 CharDriverState *qdev_init_chardev(DeviceState *dev)
411 static int next_serial;
413 /* FIXME: This function needs to go away: use chardev properties! */
414 return serial_hds[next_serial++];
417 BusState *qdev_get_parent_bus(DeviceState *dev)
419 return dev->parent_bus;
422 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
424 assert(dev->num_gpio_in == 0);
425 dev->num_gpio_in = n;
426 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
429 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
431 assert(dev->num_gpio_out == 0);
432 dev->num_gpio_out = n;
433 dev->gpio_out = pins;
436 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
438 assert(n >= 0 && n < dev->num_gpio_in);
439 return dev->gpio_in[n];
442 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
444 assert(n >= 0 && n < dev->num_gpio_out);
445 dev->gpio_out[n] = pin;
448 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
450 qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
451 if (nd->vlan)
452 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
453 if (nd->netdev)
454 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
455 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
456 qdev_prop_exists(dev, "vectors")) {
457 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
461 static int next_block_unit[IF_COUNT];
463 /* Get a block device. This should only be used for single-drive devices
464 (e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
465 appropriate bus. */
466 BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
468 int unit = next_block_unit[type]++;
469 DriveInfo *dinfo;
471 dinfo = drive_get(type, 0, unit);
472 return dinfo ? dinfo->bdrv : NULL;
475 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
477 BusState *bus;
479 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
480 if (strcmp(name, bus->name) == 0) {
481 return bus;
484 return NULL;
487 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
488 qbus_walkerfn *busfn, void *opaque)
490 DeviceState *dev;
491 int err;
493 if (busfn) {
494 err = busfn(bus, opaque);
495 if (err) {
496 return err;
500 QLIST_FOREACH(dev, &bus->children, sibling) {
501 err = qdev_walk_children(dev, devfn, busfn, opaque);
502 if (err < 0) {
503 return err;
507 return 0;
510 int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
511 qbus_walkerfn *busfn, void *opaque)
513 BusState *bus;
514 int err;
516 if (devfn) {
517 err = devfn(dev, opaque);
518 if (err) {
519 return err;
523 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
524 err = qbus_walk_children(bus, devfn, busfn, opaque);
525 if (err < 0) {
526 return err;
530 return 0;
533 static BusState *qbus_find_recursive(BusState *bus, const char *name,
534 const BusInfo *info)
536 DeviceState *dev;
537 BusState *child, *ret;
538 int match = 1;
540 if (name && (strcmp(bus->name, name) != 0)) {
541 match = 0;
543 if (info && (bus->info != info)) {
544 match = 0;
546 if (match) {
547 return bus;
550 QLIST_FOREACH(dev, &bus->children, sibling) {
551 QLIST_FOREACH(child, &dev->child_bus, sibling) {
552 ret = qbus_find_recursive(child, name, info);
553 if (ret) {
554 return ret;
558 return NULL;
561 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
563 DeviceState *dev, *ret;
564 BusState *child;
566 QLIST_FOREACH(dev, &bus->children, sibling) {
567 if (dev->id && strcmp(dev->id, id) == 0)
568 return dev;
569 QLIST_FOREACH(child, &dev->child_bus, sibling) {
570 ret = qdev_find_recursive(child, id);
571 if (ret) {
572 return ret;
576 return NULL;
579 static void qbus_list_bus(DeviceState *dev)
581 BusState *child;
582 const char *sep = " ";
584 error_printf("child busses at \"%s\":",
585 dev->id ? dev->id : dev->info->name);
586 QLIST_FOREACH(child, &dev->child_bus, sibling) {
587 error_printf("%s\"%s\"", sep, child->name);
588 sep = ", ";
590 error_printf("\n");
593 static void qbus_list_dev(BusState *bus)
595 DeviceState *dev;
596 const char *sep = " ";
598 error_printf("devices at \"%s\":", bus->name);
599 QLIST_FOREACH(dev, &bus->children, sibling) {
600 error_printf("%s\"%s\"", sep, dev->info->name);
601 if (dev->id)
602 error_printf("/\"%s\"", dev->id);
603 sep = ", ";
605 error_printf("\n");
608 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
610 BusState *child;
612 QLIST_FOREACH(child, &dev->child_bus, sibling) {
613 if (strcmp(child->name, elem) == 0) {
614 return child;
617 return NULL;
620 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
622 DeviceState *dev;
625 * try to match in order:
626 * (1) instance id, if present
627 * (2) driver name
628 * (3) driver alias, if present
630 QLIST_FOREACH(dev, &bus->children, sibling) {
631 if (dev->id && strcmp(dev->id, elem) == 0) {
632 return dev;
635 QLIST_FOREACH(dev, &bus->children, sibling) {
636 if (strcmp(dev->info->name, elem) == 0) {
637 return dev;
640 QLIST_FOREACH(dev, &bus->children, sibling) {
641 if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
642 return dev;
645 return NULL;
648 static BusState *qbus_find(const char *path)
650 DeviceState *dev;
651 BusState *bus;
652 char elem[128];
653 int pos, len;
655 /* find start element */
656 if (path[0] == '/') {
657 bus = main_system_bus;
658 pos = 0;
659 } else {
660 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
661 assert(!path[0]);
662 elem[0] = len = 0;
664 bus = qbus_find_recursive(main_system_bus, elem, NULL);
665 if (!bus) {
666 qerror_report(QERR_BUS_NOT_FOUND, elem);
667 return NULL;
669 pos = len;
672 for (;;) {
673 assert(path[pos] == '/' || !path[pos]);
674 while (path[pos] == '/') {
675 pos++;
677 if (path[pos] == '\0') {
678 return bus;
681 /* find device */
682 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
683 assert(0);
684 elem[0] = len = 0;
686 pos += len;
687 dev = qbus_find_dev(bus, elem);
688 if (!dev) {
689 qerror_report(QERR_DEVICE_NOT_FOUND, elem);
690 if (!monitor_cur_is_qmp()) {
691 qbus_list_dev(bus);
693 return NULL;
696 assert(path[pos] == '/' || !path[pos]);
697 while (path[pos] == '/') {
698 pos++;
700 if (path[pos] == '\0') {
701 /* last specified element is a device. If it has exactly
702 * one child bus accept it nevertheless */
703 switch (dev->num_child_bus) {
704 case 0:
705 qerror_report(QERR_DEVICE_NO_BUS, elem);
706 return NULL;
707 case 1:
708 return QLIST_FIRST(&dev->child_bus);
709 default:
710 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
711 if (!monitor_cur_is_qmp()) {
712 qbus_list_bus(dev);
714 return NULL;
718 /* find bus */
719 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
720 assert(0);
721 elem[0] = len = 0;
723 pos += len;
724 bus = qbus_find_bus(dev, elem);
725 if (!bus) {
726 qerror_report(QERR_BUS_NOT_FOUND, elem);
727 if (!monitor_cur_is_qmp()) {
728 qbus_list_bus(dev);
730 return NULL;
735 void qbus_create_inplace(BusState *bus, BusInfo *info,
736 DeviceState *parent, const char *name)
738 char *buf;
739 int i,len;
741 bus->info = info;
742 bus->parent = parent;
744 if (name) {
745 /* use supplied name */
746 bus->name = qemu_strdup(name);
747 } else if (parent && parent->id) {
748 /* parent device has id -> use it for bus name */
749 len = strlen(parent->id) + 16;
750 buf = qemu_malloc(len);
751 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
752 bus->name = buf;
753 } else {
754 /* no id -> use lowercase bus type for bus name */
755 len = strlen(info->name) + 16;
756 buf = qemu_malloc(len);
757 len = snprintf(buf, len, "%s.%d", info->name,
758 parent ? parent->num_child_bus : 0);
759 for (i = 0; i < len; i++)
760 buf[i] = qemu_tolower(buf[i]);
761 bus->name = buf;
764 QLIST_INIT(&bus->children);
765 if (parent) {
766 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
767 parent->num_child_bus++;
768 } else if (bus != main_system_bus) {
769 /* TODO: once all bus devices are qdevified,
770 only reset handler for main_system_bus should be registered here. */
771 qemu_register_reset(qbus_reset_all_fn, bus);
775 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
777 BusState *bus;
779 bus = qemu_mallocz(info->size);
780 bus->qdev_allocated = 1;
781 qbus_create_inplace(bus, info, parent, name);
782 return bus;
785 void qbus_free(BusState *bus)
787 DeviceState *dev;
789 while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
790 qdev_free(dev);
792 if (bus->parent) {
793 QLIST_REMOVE(bus, sibling);
794 bus->parent->num_child_bus--;
795 } else {
796 assert(bus != main_system_bus); /* main_system_bus is never freed */
797 qemu_unregister_reset(qbus_reset_all_fn, bus);
799 qemu_free((void*)bus->name);
800 if (bus->qdev_allocated) {
801 qemu_free(bus);
805 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
806 static void qbus_print(Monitor *mon, BusState *bus, int indent);
808 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
809 const char *prefix, int indent)
811 char buf[64];
813 if (!props)
814 return;
815 while (props->name) {
817 * TODO Properties without a print method are just for dirty
818 * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
819 * marked for removal. The test props->info->print should be
820 * removed along with it.
822 if (props->info->print) {
823 props->info->print(dev, props, buf, sizeof(buf));
824 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
826 props++;
830 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
832 BusState *child;
833 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
834 dev->id ? dev->id : "");
835 indent += 2;
836 if (dev->num_gpio_in) {
837 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
839 if (dev->num_gpio_out) {
840 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
842 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
843 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
844 if (dev->parent_bus->info->print_dev)
845 dev->parent_bus->info->print_dev(mon, dev, indent);
846 QLIST_FOREACH(child, &dev->child_bus, sibling) {
847 qbus_print(mon, child, indent);
851 static void qbus_print(Monitor *mon, BusState *bus, int indent)
853 struct DeviceState *dev;
855 qdev_printf("bus: %s\n", bus->name);
856 indent += 2;
857 qdev_printf("type %s\n", bus->info->name);
858 QLIST_FOREACH(dev, &bus->children, sibling) {
859 qdev_print(mon, dev, indent);
862 #undef qdev_printf
864 void do_info_qtree(Monitor *mon)
866 if (main_system_bus)
867 qbus_print(mon, main_system_bus, 0);
870 void do_info_qdm(Monitor *mon)
872 DeviceInfo *info;
874 for (info = device_info_list; info != NULL; info = info->next) {
875 qdev_print_devinfo(info);
879 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
881 QemuOpts *opts;
883 opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
884 if (!opts) {
885 return -1;
887 if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
888 qemu_opts_del(opts);
889 return 0;
891 if (!qdev_device_add(opts)) {
892 qemu_opts_del(opts);
893 return -1;
895 return 0;
898 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
900 const char *id = qdict_get_str(qdict, "id");
901 DeviceState *dev;
903 dev = qdev_find_recursive(main_system_bus, id);
904 if (NULL == dev) {
905 qerror_report(QERR_DEVICE_NOT_FOUND, id);
906 return -1;
908 return qdev_unplug(dev);
911 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
913 int l = 0;
915 if (dev && dev->parent_bus) {
916 char *d;
917 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
918 if (dev->parent_bus->info->get_fw_dev_path) {
919 d = dev->parent_bus->info->get_fw_dev_path(dev);
920 l += snprintf(p + l, size - l, "%s", d);
921 qemu_free(d);
922 } else {
923 l += snprintf(p + l, size - l, "%s", dev->info->name);
926 l += snprintf(p + l , size - l, "/");
928 return l;
931 char* qdev_get_fw_dev_path(DeviceState *dev)
933 char path[128];
934 int l;
936 l = qdev_get_fw_dev_path_helper(dev, path, 128);
938 path[l-1] = '\0';
940 return strdup(path);