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