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