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