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