qdev: introduce reset call back for qbus level
[qemu.git] / hw / qdev.c
blobb76da078088a8b141a031fe8f0aa8a15768f7e03
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 qbus_reset_all(BusState *bus)
327 qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
330 /* can be used as ->unplug() callback for the simple cases */
331 int qdev_simple_unplug_cb(DeviceState *dev)
333 /* just zap it */
334 qdev_free(dev);
335 return 0;
338 /* Like qdev_init(), but terminate program via hw_error() instead of
339 returning an error value. This is okay during machine creation.
340 Don't use for hotplug, because there callers need to recover from
341 failure. Exception: if you know the device's init() callback can't
342 fail, then qdev_init_nofail() can't fail either, and is therefore
343 usable even then. But relying on the device implementation that
344 way is somewhat unclean, and best avoided. */
345 void qdev_init_nofail(DeviceState *dev)
347 DeviceInfo *info = dev->info;
349 if (qdev_init(dev) < 0) {
350 error_report("Initialization of device %s failed\n", info->name);
351 exit(1);
355 /* Unlink device from bus and free the structure. */
356 void qdev_free(DeviceState *dev)
358 BusState *bus;
359 Property *prop;
361 if (dev->state == DEV_STATE_INITIALIZED) {
362 while (dev->num_child_bus) {
363 bus = QLIST_FIRST(&dev->child_bus);
364 qbus_free(bus);
366 if (dev->info->vmsd)
367 vmstate_unregister(dev, dev->info->vmsd, dev);
368 if (dev->info->exit)
369 dev->info->exit(dev);
370 if (dev->opts)
371 qemu_opts_del(dev->opts);
373 QLIST_REMOVE(dev, sibling);
374 for (prop = dev->info->props; prop && prop->name; prop++) {
375 if (prop->info->free) {
376 prop->info->free(dev, prop);
379 qemu_free(dev);
382 void qdev_machine_creation_done(void)
385 * ok, initial machine setup is done, starting from now we can
386 * only create hotpluggable devices
388 qdev_hotplug = 1;
391 /* Get a character (serial) device interface. */
392 CharDriverState *qdev_init_chardev(DeviceState *dev)
394 static int next_serial;
396 /* FIXME: This function needs to go away: use chardev properties! */
397 return serial_hds[next_serial++];
400 BusState *qdev_get_parent_bus(DeviceState *dev)
402 return dev->parent_bus;
405 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
407 assert(dev->num_gpio_in == 0);
408 dev->num_gpio_in = n;
409 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
412 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
414 assert(dev->num_gpio_out == 0);
415 dev->num_gpio_out = n;
416 dev->gpio_out = pins;
419 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
421 assert(n >= 0 && n < dev->num_gpio_in);
422 return dev->gpio_in[n];
425 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
427 assert(n >= 0 && n < dev->num_gpio_out);
428 dev->gpio_out[n] = pin;
431 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
433 qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
434 if (nd->vlan)
435 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
436 if (nd->netdev)
437 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
438 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
439 qdev_prop_exists(dev, "vectors")) {
440 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
444 static int next_block_unit[IF_COUNT];
446 /* Get a block device. This should only be used for single-drive devices
447 (e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
448 appropriate bus. */
449 BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
451 int unit = next_block_unit[type]++;
452 DriveInfo *dinfo;
454 dinfo = drive_get(type, 0, unit);
455 return dinfo ? dinfo->bdrv : NULL;
458 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
460 BusState *bus;
462 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
463 if (strcmp(name, bus->name) == 0) {
464 return bus;
467 return NULL;
470 int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
471 qbus_walkerfn *busfn, void *opaque)
473 DeviceState *dev;
474 int err;
476 if (busfn) {
477 err = busfn(bus, opaque);
478 if (err) {
479 return err;
483 QLIST_FOREACH(dev, &bus->children, sibling) {
484 err = qdev_walk_children(dev, devfn, busfn, opaque);
485 if (err < 0) {
486 return err;
490 return 0;
493 int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
494 qbus_walkerfn *busfn, void *opaque)
496 BusState *bus;
497 int err;
499 if (devfn) {
500 err = devfn(dev, opaque);
501 if (err) {
502 return err;
506 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
507 err = qbus_walk_children(bus, devfn, busfn, opaque);
508 if (err < 0) {
509 return err;
513 return 0;
516 static BusState *qbus_find_recursive(BusState *bus, const char *name,
517 const BusInfo *info)
519 DeviceState *dev;
520 BusState *child, *ret;
521 int match = 1;
523 if (name && (strcmp(bus->name, name) != 0)) {
524 match = 0;
526 if (info && (bus->info != info)) {
527 match = 0;
529 if (match) {
530 return bus;
533 QLIST_FOREACH(dev, &bus->children, sibling) {
534 QLIST_FOREACH(child, &dev->child_bus, sibling) {
535 ret = qbus_find_recursive(child, name, info);
536 if (ret) {
537 return ret;
541 return NULL;
544 static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
546 DeviceState *dev, *ret;
547 BusState *child;
549 QLIST_FOREACH(dev, &bus->children, sibling) {
550 if (dev->id && strcmp(dev->id, id) == 0)
551 return dev;
552 QLIST_FOREACH(child, &dev->child_bus, sibling) {
553 ret = qdev_find_recursive(child, id);
554 if (ret) {
555 return ret;
559 return NULL;
562 static void qbus_list_bus(DeviceState *dev)
564 BusState *child;
565 const char *sep = " ";
567 error_printf("child busses at \"%s\":",
568 dev->id ? dev->id : dev->info->name);
569 QLIST_FOREACH(child, &dev->child_bus, sibling) {
570 error_printf("%s\"%s\"", sep, child->name);
571 sep = ", ";
573 error_printf("\n");
576 static void qbus_list_dev(BusState *bus)
578 DeviceState *dev;
579 const char *sep = " ";
581 error_printf("devices at \"%s\":", bus->name);
582 QLIST_FOREACH(dev, &bus->children, sibling) {
583 error_printf("%s\"%s\"", sep, dev->info->name);
584 if (dev->id)
585 error_printf("/\"%s\"", dev->id);
586 sep = ", ";
588 error_printf("\n");
591 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
593 BusState *child;
595 QLIST_FOREACH(child, &dev->child_bus, sibling) {
596 if (strcmp(child->name, elem) == 0) {
597 return child;
600 return NULL;
603 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
605 DeviceState *dev;
608 * try to match in order:
609 * (1) instance id, if present
610 * (2) driver name
611 * (3) driver alias, if present
613 QLIST_FOREACH(dev, &bus->children, sibling) {
614 if (dev->id && strcmp(dev->id, elem) == 0) {
615 return dev;
618 QLIST_FOREACH(dev, &bus->children, sibling) {
619 if (strcmp(dev->info->name, elem) == 0) {
620 return dev;
623 QLIST_FOREACH(dev, &bus->children, sibling) {
624 if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
625 return dev;
628 return NULL;
631 static BusState *qbus_find(const char *path)
633 DeviceState *dev;
634 BusState *bus;
635 char elem[128];
636 int pos, len;
638 /* find start element */
639 if (path[0] == '/') {
640 bus = main_system_bus;
641 pos = 0;
642 } else {
643 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
644 assert(!path[0]);
645 elem[0] = len = 0;
647 bus = qbus_find_recursive(main_system_bus, elem, NULL);
648 if (!bus) {
649 qerror_report(QERR_BUS_NOT_FOUND, elem);
650 return NULL;
652 pos = len;
655 for (;;) {
656 assert(path[pos] == '/' || !path[pos]);
657 while (path[pos] == '/') {
658 pos++;
660 if (path[pos] == '\0') {
661 return bus;
664 /* find device */
665 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
666 assert(0);
667 elem[0] = len = 0;
669 pos += len;
670 dev = qbus_find_dev(bus, elem);
671 if (!dev) {
672 qerror_report(QERR_DEVICE_NOT_FOUND, elem);
673 if (!monitor_cur_is_qmp()) {
674 qbus_list_dev(bus);
676 return NULL;
679 assert(path[pos] == '/' || !path[pos]);
680 while (path[pos] == '/') {
681 pos++;
683 if (path[pos] == '\0') {
684 /* last specified element is a device. If it has exactly
685 * one child bus accept it nevertheless */
686 switch (dev->num_child_bus) {
687 case 0:
688 qerror_report(QERR_DEVICE_NO_BUS, elem);
689 return NULL;
690 case 1:
691 return QLIST_FIRST(&dev->child_bus);
692 default:
693 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
694 if (!monitor_cur_is_qmp()) {
695 qbus_list_bus(dev);
697 return NULL;
701 /* find bus */
702 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
703 assert(0);
704 elem[0] = len = 0;
706 pos += len;
707 bus = qbus_find_bus(dev, elem);
708 if (!bus) {
709 qerror_report(QERR_BUS_NOT_FOUND, elem);
710 if (!monitor_cur_is_qmp()) {
711 qbus_list_bus(dev);
713 return NULL;
718 void qbus_create_inplace(BusState *bus, BusInfo *info,
719 DeviceState *parent, const char *name)
721 char *buf;
722 int i,len;
724 bus->info = info;
725 bus->parent = parent;
727 if (name) {
728 /* use supplied name */
729 bus->name = qemu_strdup(name);
730 } else if (parent && parent->id) {
731 /* parent device has id -> use it for bus name */
732 len = strlen(parent->id) + 16;
733 buf = qemu_malloc(len);
734 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
735 bus->name = buf;
736 } else {
737 /* no id -> use lowercase bus type for bus name */
738 len = strlen(info->name) + 16;
739 buf = qemu_malloc(len);
740 len = snprintf(buf, len, "%s.%d", info->name,
741 parent ? parent->num_child_bus : 0);
742 for (i = 0; i < len; i++)
743 buf[i] = qemu_tolower(buf[i]);
744 bus->name = buf;
747 QLIST_INIT(&bus->children);
748 if (parent) {
749 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
750 parent->num_child_bus++;
755 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
757 BusState *bus;
759 bus = qemu_mallocz(info->size);
760 bus->qdev_allocated = 1;
761 qbus_create_inplace(bus, info, parent, name);
762 return bus;
765 void qbus_free(BusState *bus)
767 DeviceState *dev;
769 while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
770 qdev_free(dev);
772 if (bus->parent) {
773 QLIST_REMOVE(bus, sibling);
774 bus->parent->num_child_bus--;
776 qemu_free((void*)bus->name);
777 if (bus->qdev_allocated) {
778 qemu_free(bus);
782 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
783 static void qbus_print(Monitor *mon, BusState *bus, int indent);
785 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
786 const char *prefix, int indent)
788 char buf[64];
790 if (!props)
791 return;
792 while (props->name) {
794 * TODO Properties without a print method are just for dirty
795 * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
796 * marked for removal. The test props->info->print should be
797 * removed along with it.
799 if (props->info->print) {
800 props->info->print(dev, props, buf, sizeof(buf));
801 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
803 props++;
807 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
809 BusState *child;
810 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
811 dev->id ? dev->id : "");
812 indent += 2;
813 if (dev->num_gpio_in) {
814 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
816 if (dev->num_gpio_out) {
817 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
819 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
820 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
821 if (dev->parent_bus->info->print_dev)
822 dev->parent_bus->info->print_dev(mon, dev, indent);
823 QLIST_FOREACH(child, &dev->child_bus, sibling) {
824 qbus_print(mon, child, indent);
828 static void qbus_print(Monitor *mon, BusState *bus, int indent)
830 struct DeviceState *dev;
832 qdev_printf("bus: %s\n", bus->name);
833 indent += 2;
834 qdev_printf("type %s\n", bus->info->name);
835 QLIST_FOREACH(dev, &bus->children, sibling) {
836 qdev_print(mon, dev, indent);
839 #undef qdev_printf
841 void do_info_qtree(Monitor *mon)
843 if (main_system_bus)
844 qbus_print(mon, main_system_bus, 0);
847 void do_info_qdm(Monitor *mon)
849 DeviceInfo *info;
851 for (info = device_info_list; info != NULL; info = info->next) {
852 qdev_print_devinfo(info);
856 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
858 QemuOpts *opts;
860 opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
861 if (!opts) {
862 return -1;
864 if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
865 qemu_opts_del(opts);
866 return 0;
868 if (!qdev_device_add(opts)) {
869 qemu_opts_del(opts);
870 return -1;
872 return 0;
875 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
877 const char *id = qdict_get_str(qdict, "id");
878 DeviceState *dev;
880 dev = qdev_find_recursive(main_system_bus, id);
881 if (NULL == dev) {
882 qerror_report(QERR_DEVICE_NOT_FOUND, id);
883 return -1;
885 return qdev_unplug(dev);