scsi: Remove references to SET_WINDOW
[qemu/ar7.git] / hw / qdev.c
blobb4ea8e13d16f253be9e9b15c054056a7691ec6cb
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;
40 DeviceInfo *device_info_list;
42 static BusState *qbus_find_recursive(BusState *bus, const char *name,
43 const BusInfo *info);
44 static BusState *qbus_find(const char *path);
46 /* Register a new device type. */
47 void qdev_register(DeviceInfo *info)
49 assert(info->size >= sizeof(DeviceState));
50 assert(!info->next);
52 info->next = device_info_list;
53 device_info_list = info;
56 static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
58 DeviceInfo *info;
60 /* first check device names */
61 for (info = device_info_list; info != NULL; info = info->next) {
62 if (bus_info && info->bus_info != bus_info)
63 continue;
64 if (strcmp(info->name, name) != 0)
65 continue;
66 return info;
69 /* failing that check the aliases */
70 for (info = device_info_list; info != NULL; info = info->next) {
71 if (bus_info && info->bus_info != bus_info)
72 continue;
73 if (!info->alias)
74 continue;
75 if (strcmp(info->alias, name) != 0)
76 continue;
77 return info;
79 return NULL;
82 static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
84 DeviceState *dev;
86 assert(bus->info == info->bus_info);
87 dev = qemu_mallocz(info->size);
88 dev->info = info;
89 dev->parent_bus = bus;
90 qdev_prop_set_defaults(dev, dev->info->props);
91 qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
92 qdev_prop_set_globals(dev);
93 QLIST_INSERT_HEAD(&bus->children, dev, sibling);
94 if (qdev_hotplug) {
95 assert(bus->allow_hotplug);
96 dev->hotplugged = 1;
97 qdev_hot_added = true;
99 dev->instance_id_alias = -1;
100 dev->state = DEV_STATE_CREATED;
101 return dev;
104 /* Create a new device. This only initializes the device state structure
105 and allows properties to be set. qdev_init should be called to
106 initialize the actual device emulation. */
107 DeviceState *qdev_create(BusState *bus, const char *name)
109 DeviceState *dev;
111 dev = qdev_try_create(bus, name);
112 if (!dev) {
113 hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
116 return dev;
119 DeviceState *qdev_try_create(BusState *bus, const char *name)
121 DeviceInfo *info;
123 if (!bus) {
124 bus = sysbus_get_default();
127 info = qdev_find_info(bus->info, name);
128 if (!info) {
129 return NULL;
132 return qdev_create_from_info(bus, info);
135 static void qdev_print_devinfo(DeviceInfo *info)
137 error_printf("name \"%s\", bus %s",
138 info->name, info->bus_info->name);
139 if (info->alias) {
140 error_printf(", alias \"%s\"", info->alias);
142 if (info->desc) {
143 error_printf(", desc \"%s\"", info->desc);
145 if (info->no_user) {
146 error_printf(", no-user");
148 error_printf("\n");
151 static int set_property(const char *name, const char *value, void *opaque)
153 DeviceState *dev = opaque;
155 if (strcmp(name, "driver") == 0)
156 return 0;
157 if (strcmp(name, "bus") == 0)
158 return 0;
160 if (qdev_prop_parse(dev, name, value) == -1) {
161 return -1;
163 return 0;
166 int qdev_device_help(QemuOpts *opts)
168 const char *driver;
169 DeviceInfo *info;
170 Property *prop;
172 driver = qemu_opt_get(opts, "driver");
173 if (driver && !strcmp(driver, "?")) {
174 for (info = device_info_list; info != NULL; info = info->next) {
175 if (info->no_user) {
176 continue; /* not available, don't show */
178 qdev_print_devinfo(info);
180 return 1;
183 if (!qemu_opt_get(opts, "?")) {
184 return 0;
187 info = qdev_find_info(NULL, driver);
188 if (!info) {
189 return 0;
192 for (prop = info->props; prop && prop->name; prop++) {
194 * TODO Properties without a parser are just for dirty hacks.
195 * qdev_prop_ptr is the only such PropertyInfo. It's marked
196 * for removal. This conditional should be removed along with
197 * it.
199 if (!prop->info->parse) {
200 continue; /* no way to set it, don't show */
202 error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
204 return 1;
207 DeviceState *qdev_device_add(QemuOpts *opts)
209 const char *driver, *path, *id;
210 DeviceInfo *info;
211 DeviceState *qdev;
212 BusState *bus;
214 driver = qemu_opt_get(opts, "driver");
215 if (!driver) {
216 qerror_report(QERR_MISSING_PARAMETER, "driver");
217 return NULL;
220 /* find driver */
221 info = qdev_find_info(NULL, driver);
222 if (!info || info->no_user) {
223 qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
224 error_printf_unless_qmp("Try with argument '?' for a list.\n");
225 return NULL;
228 /* find bus */
229 path = qemu_opt_get(opts, "bus");
230 if (path != NULL) {
231 bus = qbus_find(path);
232 if (!bus) {
233 return NULL;
235 if (bus->info != info->bus_info) {
236 qerror_report(QERR_BAD_BUS_FOR_DEVICE,
237 driver, bus->info->name);
238 return NULL;
240 } else {
241 bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
242 if (!bus) {
243 qerror_report(QERR_NO_BUS_FOR_DEVICE,
244 info->name, info->bus_info->name);
245 return NULL;
248 if (qdev_hotplug && !bus->allow_hotplug) {
249 qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
250 return NULL;
253 /* create device, set properties */
254 qdev = qdev_create_from_info(bus, info);
255 id = qemu_opts_id(opts);
256 if (id) {
257 qdev->id = id;
259 if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
260 qdev_free(qdev);
261 return NULL;
263 if (qdev_init(qdev) < 0) {
264 qerror_report(QERR_DEVICE_INIT_FAILED, driver);
265 return NULL;
267 qdev->opts = opts;
268 return qdev;
271 /* Initialize a device. Device properties should be set before calling
272 this function. IRQs and MMIO regions should be connected/mapped after
273 calling this function.
274 On failure, destroy the device and return negative value.
275 Return 0 on success. */
276 int qdev_init(DeviceState *dev)
278 int rc;
280 assert(dev->state == DEV_STATE_CREATED);
281 rc = dev->info->init(dev, dev->info);
282 if (rc < 0) {
283 qdev_free(dev);
284 return rc;
286 if (dev->info->vmsd) {
287 vmstate_register_with_alias_id(dev, -1, dev->info->vmsd, dev,
288 dev->instance_id_alias,
289 dev->alias_required_for_version);
291 dev->state = DEV_STATE_INITIALIZED;
292 if (dev->hotplugged && dev->info->reset) {
293 dev->info->reset(dev);
295 return 0;
298 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
299 int required_for_version)
301 assert(dev->state == DEV_STATE_CREATED);
302 dev->instance_id_alias = alias_id;
303 dev->alias_required_for_version = required_for_version;
306 int qdev_unplug(DeviceState *dev)
308 if (!dev->parent_bus->allow_hotplug) {
309 qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
310 return -1;
312 assert(dev->info->unplug != NULL);
314 qdev_hot_removed = true;
316 return dev->info->unplug(dev);
319 static int qdev_reset_one(DeviceState *dev, void *opaque)
321 if (dev->info->reset) {
322 dev->info->reset(dev);
325 return 0;
328 BusState *sysbus_get_default(void)
330 if (!main_system_bus) {
331 main_system_bus = qbus_create(&system_bus_info, NULL,
332 "main-system-bus");
334 return main_system_bus;
337 static int qbus_reset_one(BusState *bus, void *opaque)
339 if (bus->info->reset) {
340 return bus->info->reset(bus);
342 return 0;
345 void qdev_reset_all(DeviceState *dev)
347 qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
350 void qbus_reset_all_fn(void *opaque)
352 BusState *bus = opaque;
353 qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
356 /* can be used as ->unplug() callback for the simple cases */
357 int qdev_simple_unplug_cb(DeviceState *dev)
359 /* just zap it */
360 qdev_free(dev);
361 return 0;
365 /* Like qdev_init(), but terminate program via error_report() instead of
366 returning an error value. This is okay during machine creation.
367 Don't use for hotplug, because there callers need to recover from
368 failure. Exception: if you know the device's init() callback can't
369 fail, then qdev_init_nofail() can't fail either, and is therefore
370 usable even then. But relying on the device implementation that
371 way is somewhat unclean, and best avoided. */
372 void qdev_init_nofail(DeviceState *dev)
374 DeviceInfo *info = dev->info;
376 if (qdev_init(dev) < 0) {
377 error_report("Initialization of device %s failed", info->name);
378 exit(1);
382 /* Unlink device from bus and free the structure. */
383 void qdev_free(DeviceState *dev)
385 BusState *bus;
386 Property *prop;
388 if (dev->state == DEV_STATE_INITIALIZED) {
389 while (dev->num_child_bus) {
390 bus = QLIST_FIRST(&dev->child_bus);
391 qbus_free(bus);
393 if (dev->info->vmsd)
394 vmstate_unregister(dev, dev->info->vmsd, dev);
395 if (dev->info->exit)
396 dev->info->exit(dev);
397 if (dev->opts)
398 qemu_opts_del(dev->opts);
400 QLIST_REMOVE(dev, sibling);
401 for (prop = dev->info->props; prop && prop->name; prop++) {
402 if (prop->info->free) {
403 prop->info->free(dev, prop);
406 qemu_free(dev);
409 void qdev_machine_creation_done(void)
412 * ok, initial machine setup is done, starting from now we can
413 * only create hotpluggable devices
415 qdev_hotplug = 1;
418 bool qdev_machine_modified(void)
420 return qdev_hot_added || qdev_hot_removed;
423 /* Get a character (serial) device interface. */
424 CharDriverState *qdev_init_chardev(DeviceState *dev)
426 static int next_serial;
428 /* FIXME: This function needs to go away: use chardev properties! */
429 return serial_hds[next_serial++];
432 BusState *qdev_get_parent_bus(DeviceState *dev)
434 return dev->parent_bus;
437 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
439 assert(dev->num_gpio_in == 0);
440 dev->num_gpio_in = n;
441 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
444 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
446 assert(dev->num_gpio_out == 0);
447 dev->num_gpio_out = n;
448 dev->gpio_out = pins;
451 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
453 assert(n >= 0 && n < dev->num_gpio_in);
454 return dev->gpio_in[n];
457 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
459 assert(n >= 0 && n < dev->num_gpio_out);
460 dev->gpio_out[n] = pin;
463 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
465 qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
466 if (nd->vlan)
467 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
468 if (nd->netdev)
469 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
470 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
471 qdev_prop_exists(dev, "vectors")) {
472 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
474 nd->instantiated = 1;
477 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
479 BusState *bus;
481 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
482 if (strcmp(name, bus->name) == 0) {
483 return bus;
486 return NULL;
489 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
490 qbus_walkerfn *busfn, void *opaque)
492 DeviceState *dev;
493 int err;
495 if (busfn) {
496 err = busfn(bus, opaque);
497 if (err) {
498 return err;
502 QLIST_FOREACH(dev, &bus->children, sibling) {
503 err = qdev_walk_children(dev, devfn, busfn, opaque);
504 if (err < 0) {
505 return err;
509 return 0;
512 int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
513 qbus_walkerfn *busfn, void *opaque)
515 BusState *bus;
516 int err;
518 if (devfn) {
519 err = devfn(dev, opaque);
520 if (err) {
521 return err;
525 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
526 err = qbus_walk_children(bus, devfn, busfn, opaque);
527 if (err < 0) {
528 return err;
532 return 0;
535 static BusState *qbus_find_recursive(BusState *bus, const char *name,
536 const BusInfo *info)
538 DeviceState *dev;
539 BusState *child, *ret;
540 int match = 1;
542 if (name && (strcmp(bus->name, name) != 0)) {
543 match = 0;
545 if (info && (bus->info != info)) {
546 match = 0;
548 if (match) {
549 return bus;
552 QLIST_FOREACH(dev, &bus->children, sibling) {
553 QLIST_FOREACH(child, &dev->child_bus, sibling) {
554 ret = qbus_find_recursive(child, name, info);
555 if (ret) {
556 return ret;
560 return NULL;
563 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
565 DeviceState *dev, *ret;
566 BusState *child;
568 QLIST_FOREACH(dev, &bus->children, sibling) {
569 if (dev->id && strcmp(dev->id, id) == 0)
570 return dev;
571 QLIST_FOREACH(child, &dev->child_bus, sibling) {
572 ret = qdev_find_recursive(child, id);
573 if (ret) {
574 return ret;
578 return NULL;
581 static void qbus_list_bus(DeviceState *dev)
583 BusState *child;
584 const char *sep = " ";
586 error_printf("child busses at \"%s\":",
587 dev->id ? dev->id : dev->info->name);
588 QLIST_FOREACH(child, &dev->child_bus, sibling) {
589 error_printf("%s\"%s\"", sep, child->name);
590 sep = ", ";
592 error_printf("\n");
595 static void qbus_list_dev(BusState *bus)
597 DeviceState *dev;
598 const char *sep = " ";
600 error_printf("devices at \"%s\":", bus->name);
601 QLIST_FOREACH(dev, &bus->children, sibling) {
602 error_printf("%s\"%s\"", sep, dev->info->name);
603 if (dev->id)
604 error_printf("/\"%s\"", dev->id);
605 sep = ", ";
607 error_printf("\n");
610 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
612 BusState *child;
614 QLIST_FOREACH(child, &dev->child_bus, sibling) {
615 if (strcmp(child->name, elem) == 0) {
616 return child;
619 return NULL;
622 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
624 DeviceState *dev;
627 * try to match in order:
628 * (1) instance id, if present
629 * (2) driver name
630 * (3) driver alias, if present
632 QLIST_FOREACH(dev, &bus->children, sibling) {
633 if (dev->id && strcmp(dev->id, elem) == 0) {
634 return dev;
637 QLIST_FOREACH(dev, &bus->children, sibling) {
638 if (strcmp(dev->info->name, elem) == 0) {
639 return dev;
642 QLIST_FOREACH(dev, &bus->children, sibling) {
643 if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
644 return dev;
647 return NULL;
650 static BusState *qbus_find(const char *path)
652 DeviceState *dev;
653 BusState *bus;
654 char elem[128];
655 int pos, len;
657 /* find start element */
658 if (path[0] == '/') {
659 bus = main_system_bus;
660 pos = 0;
661 } else {
662 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
663 assert(!path[0]);
664 elem[0] = len = 0;
666 bus = qbus_find_recursive(main_system_bus, elem, NULL);
667 if (!bus) {
668 qerror_report(QERR_BUS_NOT_FOUND, elem);
669 return NULL;
671 pos = len;
674 for (;;) {
675 assert(path[pos] == '/' || !path[pos]);
676 while (path[pos] == '/') {
677 pos++;
679 if (path[pos] == '\0') {
680 return bus;
683 /* find device */
684 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
685 assert(0);
686 elem[0] = len = 0;
688 pos += len;
689 dev = qbus_find_dev(bus, elem);
690 if (!dev) {
691 qerror_report(QERR_DEVICE_NOT_FOUND, elem);
692 if (!monitor_cur_is_qmp()) {
693 qbus_list_dev(bus);
695 return NULL;
698 assert(path[pos] == '/' || !path[pos]);
699 while (path[pos] == '/') {
700 pos++;
702 if (path[pos] == '\0') {
703 /* last specified element is a device. If it has exactly
704 * one child bus accept it nevertheless */
705 switch (dev->num_child_bus) {
706 case 0:
707 qerror_report(QERR_DEVICE_NO_BUS, elem);
708 return NULL;
709 case 1:
710 return QLIST_FIRST(&dev->child_bus);
711 default:
712 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
713 if (!monitor_cur_is_qmp()) {
714 qbus_list_bus(dev);
716 return NULL;
720 /* find bus */
721 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
722 assert(0);
723 elem[0] = len = 0;
725 pos += len;
726 bus = qbus_find_bus(dev, elem);
727 if (!bus) {
728 qerror_report(QERR_BUS_NOT_FOUND, elem);
729 if (!monitor_cur_is_qmp()) {
730 qbus_list_bus(dev);
732 return NULL;
737 void qbus_create_inplace(BusState *bus, BusInfo *info,
738 DeviceState *parent, const char *name)
740 char *buf;
741 int i,len;
743 bus->info = info;
744 bus->parent = parent;
746 if (name) {
747 /* use supplied name */
748 bus->name = qemu_strdup(name);
749 } else if (parent && parent->id) {
750 /* parent device has id -> use it for bus name */
751 len = strlen(parent->id) + 16;
752 buf = qemu_malloc(len);
753 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
754 bus->name = buf;
755 } else {
756 /* no id -> use lowercase bus type for bus name */
757 len = strlen(info->name) + 16;
758 buf = qemu_malloc(len);
759 len = snprintf(buf, len, "%s.%d", info->name,
760 parent ? parent->num_child_bus : 0);
761 for (i = 0; i < len; i++)
762 buf[i] = qemu_tolower(buf[i]);
763 bus->name = buf;
766 QLIST_INIT(&bus->children);
767 if (parent) {
768 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
769 parent->num_child_bus++;
770 } else if (bus != main_system_bus) {
771 /* TODO: once all bus devices are qdevified,
772 only reset handler for main_system_bus should be registered here. */
773 qemu_register_reset(qbus_reset_all_fn, bus);
777 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
779 BusState *bus;
781 bus = qemu_mallocz(info->size);
782 bus->qdev_allocated = 1;
783 qbus_create_inplace(bus, info, parent, name);
784 return bus;
787 void qbus_free(BusState *bus)
789 DeviceState *dev;
791 while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
792 qdev_free(dev);
794 if (bus->parent) {
795 QLIST_REMOVE(bus, sibling);
796 bus->parent->num_child_bus--;
797 } else {
798 assert(bus != main_system_bus); /* main_system_bus is never freed */
799 qemu_unregister_reset(qbus_reset_all_fn, bus);
801 qemu_free((void*)bus->name);
802 if (bus->qdev_allocated) {
803 qemu_free(bus);
807 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
808 static void qbus_print(Monitor *mon, BusState *bus, int indent);
810 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
811 const char *prefix, int indent)
813 char buf[64];
815 if (!props)
816 return;
817 while (props->name) {
819 * TODO Properties without a print method are just for dirty
820 * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
821 * marked for removal. The test props->info->print should be
822 * removed along with it.
824 if (props->info->print) {
825 props->info->print(dev, props, buf, sizeof(buf));
826 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
828 props++;
832 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
834 BusState *child;
835 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
836 dev->id ? dev->id : "");
837 indent += 2;
838 if (dev->num_gpio_in) {
839 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
841 if (dev->num_gpio_out) {
842 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
844 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
845 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
846 if (dev->parent_bus->info->print_dev)
847 dev->parent_bus->info->print_dev(mon, dev, indent);
848 QLIST_FOREACH(child, &dev->child_bus, sibling) {
849 qbus_print(mon, child, indent);
853 static void qbus_print(Monitor *mon, BusState *bus, int indent)
855 struct DeviceState *dev;
857 qdev_printf("bus: %s\n", bus->name);
858 indent += 2;
859 qdev_printf("type %s\n", bus->info->name);
860 QLIST_FOREACH(dev, &bus->children, sibling) {
861 qdev_print(mon, dev, indent);
864 #undef qdev_printf
866 void do_info_qtree(Monitor *mon)
868 if (main_system_bus)
869 qbus_print(mon, main_system_bus, 0);
872 void do_info_qdm(Monitor *mon)
874 DeviceInfo *info;
876 for (info = device_info_list; info != NULL; info = info->next) {
877 qdev_print_devinfo(info);
881 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
883 QemuOpts *opts;
885 opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
886 if (!opts) {
887 return -1;
889 if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
890 qemu_opts_del(opts);
891 return 0;
893 if (!qdev_device_add(opts)) {
894 qemu_opts_del(opts);
895 return -1;
897 return 0;
900 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
902 const char *id = qdict_get_str(qdict, "id");
903 DeviceState *dev;
905 dev = qdev_find_recursive(main_system_bus, id);
906 if (NULL == dev) {
907 qerror_report(QERR_DEVICE_NOT_FOUND, id);
908 return -1;
910 return qdev_unplug(dev);
913 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
915 int l = 0;
917 if (dev && dev->parent_bus) {
918 char *d;
919 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
920 if (dev->parent_bus->info->get_fw_dev_path) {
921 d = dev->parent_bus->info->get_fw_dev_path(dev);
922 l += snprintf(p + l, size - l, "%s", d);
923 qemu_free(d);
924 } else {
925 l += snprintf(p + l, size - l, "%s", dev->info->name);
928 l += snprintf(p + l , size - l, "/");
930 return l;
933 char* qdev_get_fw_dev_path(DeviceState *dev)
935 char path[128];
936 int l;
938 l = qdev_get_fw_dev_path_helper(dev, path, 128);
940 path[l-1] = '\0';
942 return strdup(path);