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