]> git.proxmox.com Git - qemu.git/blob - hw/qdev.c
qdev: Don't leak string property value on hot unplug
[qemu.git] / hw / qdev.c
1 /*
2 * Dynamic device configuration and creation.
3 *
4 * Copyright (c) 2009 CodeSourcery
5 *
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.
10 *
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.
15 *
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/>.
18 */
19
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. */
27
28 #include "net.h"
29 #include "qdev.h"
30 #include "sysemu.h"
31 #include "monitor.h"
32
33 static int qdev_hotplug = 0;
34
35 /* This is a nasty hack to allow passing a NULL bus to qdev_create. */
36 static BusState *main_system_bus;
37
38 DeviceInfo *device_info_list;
39
40 static BusState *qbus_find_recursive(BusState *bus, const char *name,
41 const BusInfo *info);
42 static BusState *qbus_find(const char *path);
43
44 /* Register a new device type. */
45 void qdev_register(DeviceInfo *info)
46 {
47 assert(info->size >= sizeof(DeviceState));
48 assert(!info->next);
49
50 info->next = device_info_list;
51 device_info_list = info;
52 }
53
54 static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
55 {
56 DeviceInfo *info;
57
58 /* first check device names */
59 for (info = device_info_list; info != NULL; info = info->next) {
60 if (bus_info && info->bus_info != bus_info)
61 continue;
62 if (strcmp(info->name, name) != 0)
63 continue;
64 return info;
65 }
66
67 /* failing that check the aliases */
68 for (info = device_info_list; info != NULL; info = info->next) {
69 if (bus_info && info->bus_info != bus_info)
70 continue;
71 if (!info->alias)
72 continue;
73 if (strcmp(info->alias, name) != 0)
74 continue;
75 return info;
76 }
77 return NULL;
78 }
79
80 static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
81 {
82 DeviceState *dev;
83
84 assert(bus->info == info->bus_info);
85 dev = qemu_mallocz(info->size);
86 dev->info = info;
87 dev->parent_bus = bus;
88 qdev_prop_set_defaults(dev, dev->info->props);
89 qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
90 qdev_prop_set_globals(dev);
91 QLIST_INSERT_HEAD(&bus->children, dev, sibling);
92 if (qdev_hotplug) {
93 assert(bus->allow_hotplug);
94 dev->hotplugged = 1;
95 }
96 dev->instance_id_alias = -1;
97 dev->state = DEV_STATE_CREATED;
98 return dev;
99 }
100
101 /* Create a new device. This only initializes the device state structure
102 and allows properties to be set. qdev_init should be called to
103 initialize the actual device emulation. */
104 DeviceState *qdev_create(BusState *bus, const char *name)
105 {
106 DeviceInfo *info;
107
108 if (!bus) {
109 if (!main_system_bus) {
110 main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
111 }
112 bus = main_system_bus;
113 }
114
115 info = qdev_find_info(bus->info, name);
116 if (!info) {
117 hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
118 }
119
120 return qdev_create_from_info(bus, info);
121 }
122
123 static void qdev_print_devinfo(DeviceInfo *info)
124 {
125 error_printf("name \"%s\", bus %s",
126 info->name, info->bus_info->name);
127 if (info->alias) {
128 error_printf(", alias \"%s\"", info->alias);
129 }
130 if (info->desc) {
131 error_printf(", desc \"%s\"", info->desc);
132 }
133 if (info->no_user) {
134 error_printf(", no-user");
135 }
136 error_printf("\n");
137 }
138
139 static int set_property(const char *name, const char *value, void *opaque)
140 {
141 DeviceState *dev = opaque;
142
143 if (strcmp(name, "driver") == 0)
144 return 0;
145 if (strcmp(name, "bus") == 0)
146 return 0;
147
148 if (qdev_prop_parse(dev, name, value) == -1) {
149 return -1;
150 }
151 return 0;
152 }
153
154 int qdev_device_help(QemuOpts *opts)
155 {
156 const char *driver;
157 DeviceInfo *info;
158 Property *prop;
159
160 driver = qemu_opt_get(opts, "driver");
161 if (driver && !strcmp(driver, "?")) {
162 for (info = device_info_list; info != NULL; info = info->next) {
163 if (info->no_user) {
164 continue; /* not available, don't show */
165 }
166 qdev_print_devinfo(info);
167 }
168 return 1;
169 }
170
171 if (!qemu_opt_get(opts, "?")) {
172 return 0;
173 }
174
175 info = qdev_find_info(NULL, driver);
176 if (!info) {
177 return 0;
178 }
179
180 for (prop = info->props; prop && prop->name; prop++) {
181 /*
182 * TODO Properties without a parser are just for dirty hacks.
183 * qdev_prop_ptr is the only such PropertyInfo. It's marked
184 * for removal. This conditional should be removed along with
185 * it.
186 */
187 if (!prop->info->parse) {
188 continue; /* no way to set it, don't show */
189 }
190 error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
191 }
192 return 1;
193 }
194
195 DeviceState *qdev_device_add(QemuOpts *opts)
196 {
197 const char *driver, *path, *id;
198 DeviceInfo *info;
199 DeviceState *qdev;
200 BusState *bus;
201
202 driver = qemu_opt_get(opts, "driver");
203 if (!driver) {
204 qerror_report(QERR_MISSING_PARAMETER, "driver");
205 return NULL;
206 }
207
208 /* find driver */
209 info = qdev_find_info(NULL, driver);
210 if (!info || info->no_user) {
211 qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "a driver name");
212 error_printf_unless_qmp("Try with argument '?' for a list.\n");
213 return NULL;
214 }
215
216 /* find bus */
217 path = qemu_opt_get(opts, "bus");
218 if (path != NULL) {
219 bus = qbus_find(path);
220 if (!bus) {
221 return NULL;
222 }
223 if (bus->info != info->bus_info) {
224 qerror_report(QERR_BAD_BUS_FOR_DEVICE,
225 driver, bus->info->name);
226 return NULL;
227 }
228 } else {
229 bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
230 if (!bus) {
231 qerror_report(QERR_NO_BUS_FOR_DEVICE,
232 info->name, info->bus_info->name);
233 return NULL;
234 }
235 }
236 if (qdev_hotplug && !bus->allow_hotplug) {
237 qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
238 return NULL;
239 }
240
241 /* create device, set properties */
242 qdev = qdev_create_from_info(bus, info);
243 id = qemu_opts_id(opts);
244 if (id) {
245 qdev->id = id;
246 }
247 if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
248 qdev_free(qdev);
249 return NULL;
250 }
251 if (qdev_init(qdev) < 0) {
252 qerror_report(QERR_DEVICE_INIT_FAILED, driver);
253 return NULL;
254 }
255 qdev->opts = opts;
256 return qdev;
257 }
258
259 static void qdev_reset(void *opaque)
260 {
261 DeviceState *dev = opaque;
262 if (dev->info->reset)
263 dev->info->reset(dev);
264 }
265
266 /* Initialize a device. Device properties should be set before calling
267 this function. IRQs and MMIO regions should be connected/mapped after
268 calling this function.
269 On failure, destroy the device and return negative value.
270 Return 0 on success. */
271 int qdev_init(DeviceState *dev)
272 {
273 int rc;
274
275 assert(dev->state == DEV_STATE_CREATED);
276 rc = dev->info->init(dev, dev->info);
277 if (rc < 0) {
278 qdev_free(dev);
279 return rc;
280 }
281 qemu_register_reset(qdev_reset, dev);
282 if (dev->info->vmsd) {
283 vmstate_register_with_alias_id(-1, dev->info->vmsd, dev,
284 dev->instance_id_alias,
285 dev->alias_required_for_version);
286 }
287 dev->state = DEV_STATE_INITIALIZED;
288 return 0;
289 }
290
291 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
292 int required_for_version)
293 {
294 assert(dev->state == DEV_STATE_CREATED);
295 dev->instance_id_alias = alias_id;
296 dev->alias_required_for_version = required_for_version;
297 }
298
299 int qdev_unplug(DeviceState *dev)
300 {
301 if (!dev->parent_bus->allow_hotplug) {
302 qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
303 return -1;
304 }
305 assert(dev->info->unplug != NULL);
306
307 return dev->info->unplug(dev);
308 }
309
310 /* can be used as ->unplug() callback for the simple cases */
311 int qdev_simple_unplug_cb(DeviceState *dev)
312 {
313 /* just zap it */
314 qdev_free(dev);
315 return 0;
316 }
317
318 /* Like qdev_init(), but terminate program via hw_error() instead of
319 returning an error value. This is okay during machine creation.
320 Don't use for hotplug, because there callers need to recover from
321 failure. Exception: if you know the device's init() callback can't
322 fail, then qdev_init_nofail() can't fail either, and is therefore
323 usable even then. But relying on the device implementation that
324 way is somewhat unclean, and best avoided. */
325 void qdev_init_nofail(DeviceState *dev)
326 {
327 DeviceInfo *info = dev->info;
328
329 if (qdev_init(dev) < 0)
330 hw_error("Initialization of device %s failed\n", info->name);
331 }
332
333 /* Unlink device from bus and free the structure. */
334 void qdev_free(DeviceState *dev)
335 {
336 BusState *bus;
337 Property *prop;
338
339 if (dev->state == DEV_STATE_INITIALIZED) {
340 while (dev->num_child_bus) {
341 bus = QLIST_FIRST(&dev->child_bus);
342 qbus_free(bus);
343 }
344 if (dev->info->vmsd)
345 vmstate_unregister(dev->info->vmsd, dev);
346 if (dev->info->exit)
347 dev->info->exit(dev);
348 if (dev->opts)
349 qemu_opts_del(dev->opts);
350 }
351 qemu_unregister_reset(qdev_reset, dev);
352 QLIST_REMOVE(dev, sibling);
353 for (prop = dev->info->props; prop && prop->name; prop++) {
354 if (prop->info->free) {
355 prop->info->free(dev, prop);
356 }
357 }
358 qemu_free(dev);
359 }
360
361 void qdev_machine_creation_done(void)
362 {
363 /*
364 * ok, initial machine setup is done, starting from now we can
365 * only create hotpluggable devices
366 */
367 qdev_hotplug = 1;
368 }
369
370 /* Get a character (serial) device interface. */
371 CharDriverState *qdev_init_chardev(DeviceState *dev)
372 {
373 static int next_serial;
374
375 /* FIXME: This function needs to go away: use chardev properties! */
376 return serial_hds[next_serial++];
377 }
378
379 BusState *qdev_get_parent_bus(DeviceState *dev)
380 {
381 return dev->parent_bus;
382 }
383
384 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
385 {
386 assert(dev->num_gpio_in == 0);
387 dev->num_gpio_in = n;
388 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
389 }
390
391 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
392 {
393 assert(dev->num_gpio_out == 0);
394 dev->num_gpio_out = n;
395 dev->gpio_out = pins;
396 }
397
398 qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
399 {
400 assert(n >= 0 && n < dev->num_gpio_in);
401 return dev->gpio_in[n];
402 }
403
404 void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
405 {
406 assert(n >= 0 && n < dev->num_gpio_out);
407 dev->gpio_out[n] = pin;
408 }
409
410 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
411 {
412 qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
413 if (nd->vlan)
414 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
415 if (nd->netdev)
416 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
417 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
418 qdev_prop_exists(dev, "vectors")) {
419 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
420 }
421 }
422
423 static int next_block_unit[IF_COUNT];
424
425 /* Get a block device. This should only be used for single-drive devices
426 (e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
427 appropriate bus. */
428 BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
429 {
430 int unit = next_block_unit[type]++;
431 DriveInfo *dinfo;
432
433 dinfo = drive_get(type, 0, unit);
434 return dinfo ? dinfo->bdrv : NULL;
435 }
436
437 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
438 {
439 BusState *bus;
440
441 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
442 if (strcmp(name, bus->name) == 0) {
443 return bus;
444 }
445 }
446 return NULL;
447 }
448
449 static BusState *qbus_find_recursive(BusState *bus, const char *name,
450 const BusInfo *info)
451 {
452 DeviceState *dev;
453 BusState *child, *ret;
454 int match = 1;
455
456 if (name && (strcmp(bus->name, name) != 0)) {
457 match = 0;
458 }
459 if (info && (bus->info != info)) {
460 match = 0;
461 }
462 if (match) {
463 return bus;
464 }
465
466 QLIST_FOREACH(dev, &bus->children, sibling) {
467 QLIST_FOREACH(child, &dev->child_bus, sibling) {
468 ret = qbus_find_recursive(child, name, info);
469 if (ret) {
470 return ret;
471 }
472 }
473 }
474 return NULL;
475 }
476
477 static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
478 {
479 DeviceState *dev, *ret;
480 BusState *child;
481
482 QLIST_FOREACH(dev, &bus->children, sibling) {
483 if (dev->id && strcmp(dev->id, id) == 0)
484 return dev;
485 QLIST_FOREACH(child, &dev->child_bus, sibling) {
486 ret = qdev_find_recursive(child, id);
487 if (ret) {
488 return ret;
489 }
490 }
491 }
492 return NULL;
493 }
494
495 static void qbus_list_bus(DeviceState *dev)
496 {
497 BusState *child;
498 const char *sep = " ";
499
500 error_printf("child busses at \"%s\":",
501 dev->id ? dev->id : dev->info->name);
502 QLIST_FOREACH(child, &dev->child_bus, sibling) {
503 error_printf("%s\"%s\"", sep, child->name);
504 sep = ", ";
505 }
506 error_printf("\n");
507 }
508
509 static void qbus_list_dev(BusState *bus)
510 {
511 DeviceState *dev;
512 const char *sep = " ";
513
514 error_printf("devices at \"%s\":", bus->name);
515 QLIST_FOREACH(dev, &bus->children, sibling) {
516 error_printf("%s\"%s\"", sep, dev->info->name);
517 if (dev->id)
518 error_printf("/\"%s\"", dev->id);
519 sep = ", ";
520 }
521 error_printf("\n");
522 }
523
524 static BusState *qbus_find_bus(DeviceState *dev, char *elem)
525 {
526 BusState *child;
527
528 QLIST_FOREACH(child, &dev->child_bus, sibling) {
529 if (strcmp(child->name, elem) == 0) {
530 return child;
531 }
532 }
533 return NULL;
534 }
535
536 static DeviceState *qbus_find_dev(BusState *bus, char *elem)
537 {
538 DeviceState *dev;
539
540 /*
541 * try to match in order:
542 * (1) instance id, if present
543 * (2) driver name
544 * (3) driver alias, if present
545 */
546 QLIST_FOREACH(dev, &bus->children, sibling) {
547 if (dev->id && strcmp(dev->id, elem) == 0) {
548 return dev;
549 }
550 }
551 QLIST_FOREACH(dev, &bus->children, sibling) {
552 if (strcmp(dev->info->name, elem) == 0) {
553 return dev;
554 }
555 }
556 QLIST_FOREACH(dev, &bus->children, sibling) {
557 if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
558 return dev;
559 }
560 }
561 return NULL;
562 }
563
564 static BusState *qbus_find(const char *path)
565 {
566 DeviceState *dev;
567 BusState *bus;
568 char elem[128];
569 int pos, len;
570
571 /* find start element */
572 if (path[0] == '/') {
573 bus = main_system_bus;
574 pos = 0;
575 } else {
576 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
577 assert(!path[0]);
578 elem[0] = len = 0;
579 }
580 bus = qbus_find_recursive(main_system_bus, elem, NULL);
581 if (!bus) {
582 qerror_report(QERR_BUS_NOT_FOUND, elem);
583 return NULL;
584 }
585 pos = len;
586 }
587
588 for (;;) {
589 assert(path[pos] == '/' || !path[pos]);
590 while (path[pos] == '/') {
591 pos++;
592 }
593 if (path[pos] == '\0') {
594 return bus;
595 }
596
597 /* find device */
598 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
599 assert(0);
600 elem[0] = len = 0;
601 }
602 pos += len;
603 dev = qbus_find_dev(bus, elem);
604 if (!dev) {
605 qerror_report(QERR_DEVICE_NOT_FOUND, elem);
606 if (!monitor_cur_is_qmp()) {
607 qbus_list_dev(bus);
608 }
609 return NULL;
610 }
611
612 assert(path[pos] == '/' || !path[pos]);
613 while (path[pos] == '/') {
614 pos++;
615 }
616 if (path[pos] == '\0') {
617 /* last specified element is a device. If it has exactly
618 * one child bus accept it nevertheless */
619 switch (dev->num_child_bus) {
620 case 0:
621 qerror_report(QERR_DEVICE_NO_BUS, elem);
622 return NULL;
623 case 1:
624 return QLIST_FIRST(&dev->child_bus);
625 default:
626 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
627 if (!monitor_cur_is_qmp()) {
628 qbus_list_bus(dev);
629 }
630 return NULL;
631 }
632 }
633
634 /* find bus */
635 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
636 assert(0);
637 elem[0] = len = 0;
638 }
639 pos += len;
640 bus = qbus_find_bus(dev, elem);
641 if (!bus) {
642 qerror_report(QERR_BUS_NOT_FOUND, elem);
643 if (!monitor_cur_is_qmp()) {
644 qbus_list_bus(dev);
645 }
646 return NULL;
647 }
648 }
649 }
650
651 void qbus_create_inplace(BusState *bus, BusInfo *info,
652 DeviceState *parent, const char *name)
653 {
654 char *buf;
655 int i,len;
656
657 bus->info = info;
658 bus->parent = parent;
659
660 if (name) {
661 /* use supplied name */
662 bus->name = qemu_strdup(name);
663 } else if (parent && parent->id) {
664 /* parent device has id -> use it for bus name */
665 len = strlen(parent->id) + 16;
666 buf = qemu_malloc(len);
667 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
668 bus->name = buf;
669 } else {
670 /* no id -> use lowercase bus type for bus name */
671 len = strlen(info->name) + 16;
672 buf = qemu_malloc(len);
673 len = snprintf(buf, len, "%s.%d", info->name,
674 parent ? parent->num_child_bus : 0);
675 for (i = 0; i < len; i++)
676 buf[i] = qemu_tolower(buf[i]);
677 bus->name = buf;
678 }
679
680 QLIST_INIT(&bus->children);
681 if (parent) {
682 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
683 parent->num_child_bus++;
684 }
685
686 }
687
688 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
689 {
690 BusState *bus;
691
692 bus = qemu_mallocz(info->size);
693 bus->qdev_allocated = 1;
694 qbus_create_inplace(bus, info, parent, name);
695 return bus;
696 }
697
698 void qbus_free(BusState *bus)
699 {
700 DeviceState *dev;
701
702 while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
703 qdev_free(dev);
704 }
705 if (bus->parent) {
706 QLIST_REMOVE(bus, sibling);
707 bus->parent->num_child_bus--;
708 }
709 if (bus->qdev_allocated) {
710 qemu_free(bus);
711 }
712 }
713
714 #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
715 static void qbus_print(Monitor *mon, BusState *bus, int indent);
716
717 static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
718 const char *prefix, int indent)
719 {
720 char buf[64];
721
722 if (!props)
723 return;
724 while (props->name) {
725 /*
726 * TODO Properties without a print method are just for dirty
727 * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
728 * marked for removal. The test props->info->print should be
729 * removed along with it.
730 */
731 if (props->info->print) {
732 props->info->print(dev, props, buf, sizeof(buf));
733 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
734 }
735 props++;
736 }
737 }
738
739 static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
740 {
741 BusState *child;
742 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
743 dev->id ? dev->id : "");
744 indent += 2;
745 if (dev->num_gpio_in) {
746 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
747 }
748 if (dev->num_gpio_out) {
749 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
750 }
751 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
752 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
753 if (dev->parent_bus->info->print_dev)
754 dev->parent_bus->info->print_dev(mon, dev, indent);
755 QLIST_FOREACH(child, &dev->child_bus, sibling) {
756 qbus_print(mon, child, indent);
757 }
758 }
759
760 static void qbus_print(Monitor *mon, BusState *bus, int indent)
761 {
762 struct DeviceState *dev;
763
764 qdev_printf("bus: %s\n", bus->name);
765 indent += 2;
766 qdev_printf("type %s\n", bus->info->name);
767 QLIST_FOREACH(dev, &bus->children, sibling) {
768 qdev_print(mon, dev, indent);
769 }
770 }
771 #undef qdev_printf
772
773 void do_info_qtree(Monitor *mon)
774 {
775 if (main_system_bus)
776 qbus_print(mon, main_system_bus, 0);
777 }
778
779 void do_info_qdm(Monitor *mon)
780 {
781 DeviceInfo *info;
782
783 for (info = device_info_list; info != NULL; info = info->next) {
784 qdev_print_devinfo(info);
785 }
786 }
787
788 int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
789 {
790 QemuOpts *opts;
791
792 opts = qemu_opts_from_qdict(&qemu_device_opts, qdict);
793 if (!opts) {
794 return -1;
795 }
796 if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
797 qemu_opts_del(opts);
798 return 0;
799 }
800 if (!qdev_device_add(opts)) {
801 qemu_opts_del(opts);
802 return -1;
803 }
804 return 0;
805 }
806
807 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
808 {
809 const char *id = qdict_get_str(qdict, "id");
810 DeviceState *dev;
811
812 dev = qdev_find_recursive(main_system_bus, id);
813 if (NULL == dev) {
814 qerror_report(QERR_DEVICE_NOT_FOUND, id);
815 return -1;
816 }
817 return qdev_unplug(dev);
818 }