virtio: fix up VQ checks
[qemu.git] / hw / qdev.c
blobb65b63e10ee26c1c5086e18f46020015bd0e53e9
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;
36 /* This is a nasty hack to allow passing a NULL bus to qdev_create. */
37 static BusState *main_system_bus;
39 DeviceInfo *device_info_list;
41 static BusState *qbus_find_recursive(BusState *bus, const char *name,
42 const BusInfo *info);
43 static BusState *qbus_find(const char *path);
45 /* Register a new device type. */
46 void qdev_register(DeviceInfo *info)
48 assert(info->size >= sizeof(DeviceState));
49 assert(!info->next);
51 info->next = device_info_list;
52 device_info_list = info;
55 static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
57 DeviceInfo *info;
59 /* first check device names */
60 for (info = device_info_list; info != NULL; info = info->next) {
61 if (bus_info && info->bus_info != bus_info)
62 continue;
63 if (strcmp(info->name, name) != 0)
64 continue;
65 return info;
68 /* failing that check the aliases */
69 for (info = device_info_list; info != NULL; info = info->next) {
70 if (bus_info && info->bus_info != bus_info)
71 continue;
72 if (!info->alias)
73 continue;
74 if (strcmp(info->alias, name) != 0)
75 continue;
76 return info;
78 return NULL;
81 static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
83 DeviceState *dev;
85 assert(bus->info == info->bus_info);
86 dev = qemu_mallocz(info->size);
87 dev->info = info;
88 dev->parent_bus = bus;
89 qdev_prop_set_defaults(dev, dev->info->props);
90 qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
91 qdev_prop_set_globals(dev);
92 QLIST_INSERT_HEAD(&bus->children, dev, sibling);
93 if (qdev_hotplug) {
94 assert(bus->allow_hotplug);
95 dev->hotplugged = 1;
97 dev->instance_id_alias = -1;
98 dev->state = DEV_STATE_CREATED;
99 return dev;
102 /* Create a new device. This only initializes the device state structure
103 and allows properties to be set. qdev_init should be called to
104 initialize the actual device emulation. */
105 DeviceState *qdev_create(BusState *bus, const char *name)
107 DeviceInfo *info;
109 if (!bus) {
110 if (!main_system_bus) {
111 main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
113 bus = main_system_bus;
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 return dev->info->unplug(dev);
303 static int qdev_reset_one(DeviceState *dev, void *opaque)
305 if (dev->info->reset) {
306 dev->info->reset(dev);
309 return 0;
312 BusState *sysbus_get_default(void)
314 return main_system_bus;
317 static int qbus_reset_one(BusState *bus, void *opaque)
319 if (bus->info->reset) {
320 return bus->info->reset(bus);
322 return 0;
325 void qdev_reset_all(DeviceState *dev)
327 qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
330 void qbus_reset_all(BusState *bus)
332 qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
335 /* can be used as ->unplug() callback for the simple cases */
336 int qdev_simple_unplug_cb(DeviceState *dev)
338 /* just zap it */
339 qdev_free(dev);
340 return 0;
343 /* Like qdev_init(), but terminate program via hw_error() instead of
344 returning an error value. This is okay during machine creation.
345 Don't use for hotplug, because there callers need to recover from
346 failure. Exception: if you know the device's init() callback can't
347 fail, then qdev_init_nofail() can't fail either, and is therefore
348 usable even then. But relying on the device implementation that
349 way is somewhat unclean, and best avoided. */
350 void qdev_init_nofail(DeviceState *dev)
352 DeviceInfo *info = dev->info;
354 if (qdev_init(dev) < 0) {
355 error_report("Initialization of device %s failed\n", info->name);
356 exit(1);
360 /* Unlink device from bus and free the structure. */
361 void qdev_free(DeviceState *dev)
363 BusState *bus;
364 Property *prop;
366 if (dev->state == DEV_STATE_INITIALIZED) {
367 while (dev->num_child_bus) {
368 bus = QLIST_FIRST(&dev->child_bus);
369 qbus_free(bus);
371 if (dev->info->vmsd)
372 vmstate_unregister(dev, dev->info->vmsd, dev);
373 if (dev->info->exit)
374 dev->info->exit(dev);
375 if (dev->opts)
376 qemu_opts_del(dev->opts);
378 QLIST_REMOVE(dev, sibling);
379 for (prop = dev->info->props; prop && prop->name; prop++) {
380 if (prop->info->free) {
381 prop->info->free(dev, prop);
384 qemu_free(dev);
387 void qdev_machine_creation_done(void)
390 * ok, initial machine setup is done, starting from now we can
391 * only create hotpluggable devices
393 qdev_hotplug = 1;
396 /* Get a character (serial) device interface. */
397 CharDriverState *qdev_init_chardev(DeviceState *dev)
399 static int next_serial;
401 /* FIXME: This function needs to go away: use chardev properties! */
402 return serial_hds[next_serial++];
405 BusState *qdev_get_parent_bus(DeviceState *dev)
407 return dev->parent_bus;
410 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
412 assert(dev->num_gpio_in == 0);
413 dev->num_gpio_in = n;
414 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
417 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
419 assert(dev->num_gpio_out == 0);
420 dev->num_gpio_out = n;
421 dev->gpio_out = pins;
424 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
426 assert(n >= 0 && n < dev->num_gpio_in);
427 return dev->gpio_in[n];
430 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
432 assert(n >= 0 && n < dev->num_gpio_out);
433 dev->gpio_out[n] = pin;
436 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
438 qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
439 if (nd->vlan)
440 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
441 if (nd->netdev)
442 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
443 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
444 qdev_prop_exists(dev, "vectors")) {
445 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
449 static int next_block_unit[IF_COUNT];
451 /* Get a block device. This should only be used for single-drive devices
452 (e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
453 appropriate bus. */
454 BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
456 int unit = next_block_unit[type]++;
457 DriveInfo *dinfo;
459 dinfo = drive_get(type, 0, unit);
460 return dinfo ? dinfo->bdrv : NULL;
463 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
465 BusState *bus;
467 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
468 if (strcmp(name, bus->name) == 0) {
469 return bus;
472 return NULL;
475 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
476 qbus_walkerfn *busfn, void *opaque)
478 DeviceState *dev;
479 int err;
481 if (busfn) {
482 err = busfn(bus, opaque);
483 if (err) {
484 return err;
488 QLIST_FOREACH(dev, &bus->children, sibling) {
489 err = qdev_walk_children(dev, devfn, busfn, opaque);
490 if (err < 0) {
491 return err;
495 return 0;
498 int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
499 qbus_walkerfn *busfn, void *opaque)
501 BusState *bus;
502 int err;
504 if (devfn) {
505 err = devfn(dev, opaque);
506 if (err) {
507 return err;
511 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
512 err = qbus_walk_children(bus, devfn, busfn, opaque);
513 if (err < 0) {
514 return err;
518 return 0;
521 static BusState *qbus_find_recursive(BusState *bus, const char *name,
522 const BusInfo *info)
524 DeviceState *dev;
525 BusState *child, *ret;
526 int match = 1;
528 if (name && (strcmp(bus->name, name) != 0)) {
529 match = 0;
531 if (info && (bus->info != info)) {
532 match = 0;
534 if (match) {
535 return bus;
538 QLIST_FOREACH(dev, &bus->children, sibling) {
539 QLIST_FOREACH(child, &dev->child_bus, sibling) {
540 ret = qbus_find_recursive(child, name, info);
541 if (ret) {
542 return ret;
546 return NULL;
549 static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
551 DeviceState *dev, *ret;
552 BusState *child;
554 QLIST_FOREACH(dev, &bus->children, sibling) {
555 if (dev->id && strcmp(dev->id, id) == 0)
556 return dev;
557 QLIST_FOREACH(child, &dev->child_bus, sibling) {
558 ret = qdev_find_recursive(child, id);
559 if (ret) {
560 return ret;
564 return NULL;
567 static void qbus_list_bus(DeviceState *dev)
569 BusState *child;
570 const char *sep = " ";
572 error_printf("child busses at \"%s\":",
573 dev->id ? dev->id : dev->info->name);
574 QLIST_FOREACH(child, &dev->child_bus, sibling) {
575 error_printf("%s\"%s\"", sep, child->name);
576 sep = ", ";
578 error_printf("\n");
581 static void qbus_list_dev(BusState *bus)
583 DeviceState *dev;
584 const char *sep = " ";
586 error_printf("devices at \"%s\":", bus->name);
587 QLIST_FOREACH(dev, &bus->children, sibling) {
588 error_printf("%s\"%s\"", sep, dev->info->name);
589 if (dev->id)
590 error_printf("/\"%s\"", dev->id);
591 sep = ", ";
593 error_printf("\n");
596 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
598 BusState *child;
600 QLIST_FOREACH(child, &dev->child_bus, sibling) {
601 if (strcmp(child->name, elem) == 0) {
602 return child;
605 return NULL;
608 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
610 DeviceState *dev;
613 * try to match in order:
614 * (1) instance id, if present
615 * (2) driver name
616 * (3) driver alias, if present
618 QLIST_FOREACH(dev, &bus->children, sibling) {
619 if (dev->id && strcmp(dev->id, elem) == 0) {
620 return dev;
623 QLIST_FOREACH(dev, &bus->children, sibling) {
624 if (strcmp(dev->info->name, elem) == 0) {
625 return dev;
628 QLIST_FOREACH(dev, &bus->children, sibling) {
629 if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
630 return dev;
633 return NULL;
636 static BusState *qbus_find(const char *path)
638 DeviceState *dev;
639 BusState *bus;
640 char elem[128];
641 int pos, len;
643 /* find start element */
644 if (path[0] == '/') {
645 bus = main_system_bus;
646 pos = 0;
647 } else {
648 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
649 assert(!path[0]);
650 elem[0] = len = 0;
652 bus = qbus_find_recursive(main_system_bus, elem, NULL);
653 if (!bus) {
654 qerror_report(QERR_BUS_NOT_FOUND, elem);
655 return NULL;
657 pos = len;
660 for (;;) {
661 assert(path[pos] == '/' || !path[pos]);
662 while (path[pos] == '/') {
663 pos++;
665 if (path[pos] == '\0') {
666 return bus;
669 /* find device */
670 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
671 assert(0);
672 elem[0] = len = 0;
674 pos += len;
675 dev = qbus_find_dev(bus, elem);
676 if (!dev) {
677 qerror_report(QERR_DEVICE_NOT_FOUND, elem);
678 if (!monitor_cur_is_qmp()) {
679 qbus_list_dev(bus);
681 return NULL;
684 assert(path[pos] == '/' || !path[pos]);
685 while (path[pos] == '/') {
686 pos++;
688 if (path[pos] == '\0') {
689 /* last specified element is a device. If it has exactly
690 * one child bus accept it nevertheless */
691 switch (dev->num_child_bus) {
692 case 0:
693 qerror_report(QERR_DEVICE_NO_BUS, elem);
694 return NULL;
695 case 1:
696 return QLIST_FIRST(&dev->child_bus);
697 default:
698 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
699 if (!monitor_cur_is_qmp()) {
700 qbus_list_bus(dev);
702 return NULL;
706 /* find bus */
707 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
708 assert(0);
709 elem[0] = len = 0;
711 pos += len;
712 bus = qbus_find_bus(dev, elem);
713 if (!bus) {
714 qerror_report(QERR_BUS_NOT_FOUND, elem);
715 if (!monitor_cur_is_qmp()) {
716 qbus_list_bus(dev);
718 return NULL;
723 void qbus_create_inplace(BusState *bus, BusInfo *info,
724 DeviceState *parent, const char *name)
726 char *buf;
727 int i,len;
729 bus->info = info;
730 bus->parent = parent;
732 if (name) {
733 /* use supplied name */
734 bus->name = qemu_strdup(name);
735 } else if (parent && parent->id) {
736 /* parent device has id -> use it for bus name */
737 len = strlen(parent->id) + 16;
738 buf = qemu_malloc(len);
739 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
740 bus->name = buf;
741 } else {
742 /* no id -> use lowercase bus type for bus name */
743 len = strlen(info->name) + 16;
744 buf = qemu_malloc(len);
745 len = snprintf(buf, len, "%s.%d", info->name,
746 parent ? parent->num_child_bus : 0);
747 for (i = 0; i < len; i++)
748 buf[i] = qemu_tolower(buf[i]);
749 bus->name = buf;
752 QLIST_INIT(&bus->children);
753 if (parent) {
754 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
755 parent->num_child_bus++;
760 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
762 BusState *bus;
764 bus = qemu_mallocz(info->size);
765 bus->qdev_allocated = 1;
766 qbus_create_inplace(bus, info, parent, name);
767 return bus;
770 void qbus_free(BusState *bus)
772 DeviceState *dev;
774 while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
775 qdev_free(dev);
777 if (bus->parent) {
778 QLIST_REMOVE(bus, sibling);
779 bus->parent->num_child_bus--;
781 qemu_free((void*)bus->name);
782 if (bus->qdev_allocated) {
783 qemu_free(bus);
787 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
788 static void qbus_print(Monitor *mon, BusState *bus, int indent);
790 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
791 const char *prefix, int indent)
793 char buf[64];
795 if (!props)
796 return;
797 while (props->name) {
799 * TODO Properties without a print method are just for dirty
800 * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
801 * marked for removal. The test props->info->print should be
802 * removed along with it.
804 if (props->info->print) {
805 props->info->print(dev, props, buf, sizeof(buf));
806 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
808 props++;
812 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
814 BusState *child;
815 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
816 dev->id ? dev->id : "");
817 indent += 2;
818 if (dev->num_gpio_in) {
819 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
821 if (dev->num_gpio_out) {
822 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
824 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
825 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
826 if (dev->parent_bus->info->print_dev)
827 dev->parent_bus->info->print_dev(mon, dev, indent);
828 QLIST_FOREACH(child, &dev->child_bus, sibling) {
829 qbus_print(mon, child, indent);
833 static void qbus_print(Monitor *mon, BusState *bus, int indent)
835 struct DeviceState *dev;
837 qdev_printf("bus: %s\n", bus->name);
838 indent += 2;
839 qdev_printf("type %s\n", bus->info->name);
840 QLIST_FOREACH(dev, &bus->children, sibling) {
841 qdev_print(mon, dev, indent);
844 #undef qdev_printf
846 void do_info_qtree(Monitor *mon)
848 if (main_system_bus)
849 qbus_print(mon, main_system_bus, 0);
852 void do_info_qdm(Monitor *mon)
854 DeviceInfo *info;
856 for (info = device_info_list; info != NULL; info = info->next) {
857 qdev_print_devinfo(info);
861 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
863 QemuOpts *opts;
865 opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
866 if (!opts) {
867 return -1;
869 if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
870 qemu_opts_del(opts);
871 return 0;
873 if (!qdev_device_add(opts)) {
874 qemu_opts_del(opts);
875 return -1;
877 return 0;
880 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
882 const char *id = qdict_get_str(qdict, "id");
883 DeviceState *dev;
885 dev = qdev_find_recursive(main_system_bus, id);
886 if (NULL == dev) {
887 qerror_report(QERR_DEVICE_NOT_FOUND, id);
888 return -1;
890 return qdev_unplug(dev);