Delete unused tb_invalidate_page_range
[qemu/mdroth.git] / hw / qdev.c
blob9519f5dd57a53184175804edfaf30fa53758f9bc
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 return 0;
295 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
296 int required_for_version)
298 assert(dev->state == DEV_STATE_CREATED);
299 dev->instance_id_alias = alias_id;
300 dev->alias_required_for_version = required_for_version;
303 int qdev_unplug(DeviceState *dev)
305 if (!dev->parent_bus->allow_hotplug) {
306 qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
307 return -1;
309 assert(dev->info->unplug != NULL);
311 qdev_hot_removed = true;
313 return dev->info->unplug(dev);
316 static int qdev_reset_one(DeviceState *dev, void *opaque)
318 if (dev->info->reset) {
319 dev->info->reset(dev);
322 return 0;
325 BusState *sysbus_get_default(void)
327 if (!main_system_bus) {
328 main_system_bus = qbus_create(&system_bus_info, NULL,
329 "main-system-bus");
331 return main_system_bus;
334 static int qbus_reset_one(BusState *bus, void *opaque)
336 if (bus->info->reset) {
337 return bus->info->reset(bus);
339 return 0;
342 void qdev_reset_all(DeviceState *dev)
344 qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
347 void qbus_reset_all_fn(void *opaque)
349 BusState *bus = opaque;
350 qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
353 /* can be used as ->unplug() callback for the simple cases */
354 int qdev_simple_unplug_cb(DeviceState *dev)
356 /* just zap it */
357 qdev_free(dev);
358 return 0;
362 /* Like qdev_init(), but terminate program via error_report() instead of
363 returning an error value. This is okay during machine creation.
364 Don't use for hotplug, because there callers need to recover from
365 failure. Exception: if you know the device's init() callback can't
366 fail, then qdev_init_nofail() can't fail either, and is therefore
367 usable even then. But relying on the device implementation that
368 way is somewhat unclean, and best avoided. */
369 void qdev_init_nofail(DeviceState *dev)
371 DeviceInfo *info = dev->info;
373 if (qdev_init(dev) < 0) {
374 error_report("Initialization of device %s failed\n", info->name);
375 exit(1);
379 /* Unlink device from bus and free the structure. */
380 void qdev_free(DeviceState *dev)
382 BusState *bus;
383 Property *prop;
385 if (dev->state == DEV_STATE_INITIALIZED) {
386 while (dev->num_child_bus) {
387 bus = QLIST_FIRST(&dev->child_bus);
388 qbus_free(bus);
390 if (dev->info->vmsd)
391 vmstate_unregister(dev, dev->info->vmsd, dev);
392 if (dev->info->exit)
393 dev->info->exit(dev);
394 if (dev->opts)
395 qemu_opts_del(dev->opts);
397 QLIST_REMOVE(dev, sibling);
398 for (prop = dev->info->props; prop && prop->name; prop++) {
399 if (prop->info->free) {
400 prop->info->free(dev, prop);
403 qemu_free(dev);
406 void qdev_machine_creation_done(void)
409 * ok, initial machine setup is done, starting from now we can
410 * only create hotpluggable devices
412 qdev_hotplug = 1;
415 bool qdev_machine_modified(void)
417 return qdev_hot_added || qdev_hot_removed;
420 /* Get a character (serial) device interface. */
421 CharDriverState *qdev_init_chardev(DeviceState *dev)
423 static int next_serial;
425 /* FIXME: This function needs to go away: use chardev properties! */
426 return serial_hds[next_serial++];
429 BusState *qdev_get_parent_bus(DeviceState *dev)
431 return dev->parent_bus;
434 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
436 assert(dev->num_gpio_in == 0);
437 dev->num_gpio_in = n;
438 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
441 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
443 assert(dev->num_gpio_out == 0);
444 dev->num_gpio_out = n;
445 dev->gpio_out = pins;
448 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
450 assert(n >= 0 && n < dev->num_gpio_in);
451 return dev->gpio_in[n];
454 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
456 assert(n >= 0 && n < dev->num_gpio_out);
457 dev->gpio_out[n] = pin;
460 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
462 qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
463 if (nd->vlan)
464 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
465 if (nd->netdev)
466 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
467 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
468 qdev_prop_exists(dev, "vectors")) {
469 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
473 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
475 BusState *bus;
477 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
478 if (strcmp(name, bus->name) == 0) {
479 return bus;
482 return NULL;
485 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
486 qbus_walkerfn *busfn, void *opaque)
488 DeviceState *dev;
489 int err;
491 if (busfn) {
492 err = busfn(bus, opaque);
493 if (err) {
494 return err;
498 QLIST_FOREACH(dev, &bus->children, sibling) {
499 err = qdev_walk_children(dev, devfn, busfn, opaque);
500 if (err < 0) {
501 return err;
505 return 0;
508 int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
509 qbus_walkerfn *busfn, void *opaque)
511 BusState *bus;
512 int err;
514 if (devfn) {
515 err = devfn(dev, opaque);
516 if (err) {
517 return err;
521 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
522 err = qbus_walk_children(bus, devfn, busfn, opaque);
523 if (err < 0) {
524 return err;
528 return 0;
531 static BusState *qbus_find_recursive(BusState *bus, const char *name,
532 const BusInfo *info)
534 DeviceState *dev;
535 BusState *child, *ret;
536 int match = 1;
538 if (name && (strcmp(bus->name, name) != 0)) {
539 match = 0;
541 if (info && (bus->info != info)) {
542 match = 0;
544 if (match) {
545 return bus;
548 QLIST_FOREACH(dev, &bus->children, sibling) {
549 QLIST_FOREACH(child, &dev->child_bus, sibling) {
550 ret = qbus_find_recursive(child, name, info);
551 if (ret) {
552 return ret;
556 return NULL;
559 DeviceState *qdev_find_recursive(BusState *bus, const char *id)
561 DeviceState *dev, *ret;
562 BusState *child;
564 QLIST_FOREACH(dev, &bus->children, sibling) {
565 if (dev->id && strcmp(dev->id, id) == 0)
566 return dev;
567 QLIST_FOREACH(child, &dev->child_bus, sibling) {
568 ret = qdev_find_recursive(child, id);
569 if (ret) {
570 return ret;
574 return NULL;
577 static void qbus_list_bus(DeviceState *dev)
579 BusState *child;
580 const char *sep = " ";
582 error_printf("child busses at \"%s\":",
583 dev->id ? dev->id : dev->info->name);
584 QLIST_FOREACH(child, &dev->child_bus, sibling) {
585 error_printf("%s\"%s\"", sep, child->name);
586 sep = ", ";
588 error_printf("\n");
591 static void qbus_list_dev(BusState *bus)
593 DeviceState *dev;
594 const char *sep = " ";
596 error_printf("devices at \"%s\":", bus->name);
597 QLIST_FOREACH(dev, &bus->children, sibling) {
598 error_printf("%s\"%s\"", sep, dev->info->name);
599 if (dev->id)
600 error_printf("/\"%s\"", dev->id);
601 sep = ", ";
603 error_printf("\n");
606 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
608 BusState *child;
610 QLIST_FOREACH(child, &dev->child_bus, sibling) {
611 if (strcmp(child->name, elem) == 0) {
612 return child;
615 return NULL;
618 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
620 DeviceState *dev;
623 * try to match in order:
624 * (1) instance id, if present
625 * (2) driver name
626 * (3) driver alias, if present
628 QLIST_FOREACH(dev, &bus->children, sibling) {
629 if (dev->id && strcmp(dev->id, elem) == 0) {
630 return dev;
633 QLIST_FOREACH(dev, &bus->children, sibling) {
634 if (strcmp(dev->info->name, elem) == 0) {
635 return dev;
638 QLIST_FOREACH(dev, &bus->children, sibling) {
639 if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
640 return dev;
643 return NULL;
646 static BusState *qbus_find(const char *path)
648 DeviceState *dev;
649 BusState *bus;
650 char elem[128];
651 int pos, len;
653 /* find start element */
654 if (path[0] == '/') {
655 bus = main_system_bus;
656 pos = 0;
657 } else {
658 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
659 assert(!path[0]);
660 elem[0] = len = 0;
662 bus = qbus_find_recursive(main_system_bus, elem, NULL);
663 if (!bus) {
664 qerror_report(QERR_BUS_NOT_FOUND, elem);
665 return NULL;
667 pos = len;
670 for (;;) {
671 assert(path[pos] == '/' || !path[pos]);
672 while (path[pos] == '/') {
673 pos++;
675 if (path[pos] == '\0') {
676 return bus;
679 /* find device */
680 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
681 assert(0);
682 elem[0] = len = 0;
684 pos += len;
685 dev = qbus_find_dev(bus, elem);
686 if (!dev) {
687 qerror_report(QERR_DEVICE_NOT_FOUND, elem);
688 if (!monitor_cur_is_qmp()) {
689 qbus_list_dev(bus);
691 return NULL;
694 assert(path[pos] == '/' || !path[pos]);
695 while (path[pos] == '/') {
696 pos++;
698 if (path[pos] == '\0') {
699 /* last specified element is a device. If it has exactly
700 * one child bus accept it nevertheless */
701 switch (dev->num_child_bus) {
702 case 0:
703 qerror_report(QERR_DEVICE_NO_BUS, elem);
704 return NULL;
705 case 1:
706 return QLIST_FIRST(&dev->child_bus);
707 default:
708 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
709 if (!monitor_cur_is_qmp()) {
710 qbus_list_bus(dev);
712 return NULL;
716 /* find bus */
717 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
718 assert(0);
719 elem[0] = len = 0;
721 pos += len;
722 bus = qbus_find_bus(dev, elem);
723 if (!bus) {
724 qerror_report(QERR_BUS_NOT_FOUND, elem);
725 if (!monitor_cur_is_qmp()) {
726 qbus_list_bus(dev);
728 return NULL;
733 void qbus_create_inplace(BusState *bus, BusInfo *info,
734 DeviceState *parent, const char *name)
736 char *buf;
737 int i,len;
739 bus->info = info;
740 bus->parent = parent;
742 if (name) {
743 /* use supplied name */
744 bus->name = qemu_strdup(name);
745 } else if (parent && parent->id) {
746 /* parent device has id -> use it for bus name */
747 len = strlen(parent->id) + 16;
748 buf = qemu_malloc(len);
749 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
750 bus->name = buf;
751 } else {
752 /* no id -> use lowercase bus type for bus name */
753 len = strlen(info->name) + 16;
754 buf = qemu_malloc(len);
755 len = snprintf(buf, len, "%s.%d", info->name,
756 parent ? parent->num_child_bus : 0);
757 for (i = 0; i < len; i++)
758 buf[i] = qemu_tolower(buf[i]);
759 bus->name = buf;
762 QLIST_INIT(&bus->children);
763 if (parent) {
764 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
765 parent->num_child_bus++;
766 } else if (bus != main_system_bus) {
767 /* TODO: once all bus devices are qdevified,
768 only reset handler for main_system_bus should be registered here. */
769 qemu_register_reset(qbus_reset_all_fn, bus);
773 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
775 BusState *bus;
777 bus = qemu_mallocz(info->size);
778 bus->qdev_allocated = 1;
779 qbus_create_inplace(bus, info, parent, name);
780 return bus;
783 void qbus_free(BusState *bus)
785 DeviceState *dev;
787 while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
788 qdev_free(dev);
790 if (bus->parent) {
791 QLIST_REMOVE(bus, sibling);
792 bus->parent->num_child_bus--;
793 } else {
794 assert(bus != main_system_bus); /* main_system_bus is never freed */
795 qemu_unregister_reset(qbus_reset_all_fn, bus);
797 qemu_free((void*)bus->name);
798 if (bus->qdev_allocated) {
799 qemu_free(bus);
803 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
804 static void qbus_print(Monitor *mon, BusState *bus, int indent);
806 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
807 const char *prefix, int indent)
809 char buf[64];
811 if (!props)
812 return;
813 while (props->name) {
815 * TODO Properties without a print method are just for dirty
816 * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
817 * marked for removal. The test props->info->print should be
818 * removed along with it.
820 if (props->info->print) {
821 props->info->print(dev, props, buf, sizeof(buf));
822 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
824 props++;
828 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
830 BusState *child;
831 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
832 dev->id ? dev->id : "");
833 indent += 2;
834 if (dev->num_gpio_in) {
835 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
837 if (dev->num_gpio_out) {
838 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
840 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
841 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
842 if (dev->parent_bus->info->print_dev)
843 dev->parent_bus->info->print_dev(mon, dev, indent);
844 QLIST_FOREACH(child, &dev->child_bus, sibling) {
845 qbus_print(mon, child, indent);
849 static void qbus_print(Monitor *mon, BusState *bus, int indent)
851 struct DeviceState *dev;
853 qdev_printf("bus: %s\n", bus->name);
854 indent += 2;
855 qdev_printf("type %s\n", bus->info->name);
856 QLIST_FOREACH(dev, &bus->children, sibling) {
857 qdev_print(mon, dev, indent);
860 #undef qdev_printf
862 void do_info_qtree(Monitor *mon)
864 if (main_system_bus)
865 qbus_print(mon, main_system_bus, 0);
868 void do_info_qdm(Monitor *mon)
870 DeviceInfo *info;
872 for (info = device_info_list; info != NULL; info = info->next) {
873 qdev_print_devinfo(info);
877 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
879 QemuOpts *opts;
881 opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
882 if (!opts) {
883 return -1;
885 if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
886 qemu_opts_del(opts);
887 return 0;
889 if (!qdev_device_add(opts)) {
890 qemu_opts_del(opts);
891 return -1;
893 return 0;
896 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
898 const char *id = qdict_get_str(qdict, "id");
899 DeviceState *dev;
901 dev = qdev_find_recursive(main_system_bus, id);
902 if (NULL == dev) {
903 qerror_report(QERR_DEVICE_NOT_FOUND, id);
904 return -1;
906 return qdev_unplug(dev);
909 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
911 int l = 0;
913 if (dev && dev->parent_bus) {
914 char *d;
915 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
916 if (dev->parent_bus->info->get_fw_dev_path) {
917 d = dev->parent_bus->info->get_fw_dev_path(dev);
918 l += snprintf(p + l, size - l, "%s", d);
919 qemu_free(d);
920 } else {
921 l += snprintf(p + l, size - l, "%s", dev->info->name);
924 l += snprintf(p + l , size - l, "/");
926 return l;
929 char* qdev_get_fw_dev_path(DeviceState *dev)
931 char path[128];
932 int l;
934 l = qdev_get_fw_dev_path_helper(dev, path, 128);
936 path[l-1] = '\0';
938 return strdup(path);