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