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