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