]> Git Repo - qemu.git/blame - hw/qdev.c
error: Drop extra messages after qemu_opts_set() and qemu_opts_parse()
[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) {
cc601cb7 290 qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
3418bd25
GH
291 return -1;
292 }
593831de
AS
293 assert(dev->info->unplug != NULL);
294
3418bd25
GH
295 return dev->info->unplug(dev);
296}
297
298/* can be used as ->unplug() callback for the simple cases */
299int qdev_simple_unplug_cb(DeviceState *dev)
300{
301 /* just zap it */
302 qdev_free(dev);
303 return 0;
304}
305
e23a1b33
MA
306/* Like qdev_init(), but terminate program via hw_error() instead of
307 returning an error value. This is okay during machine creation.
308 Don't use for hotplug, because there callers need to recover from
309 failure. Exception: if you know the device's init() callback can't
310 fail, then qdev_init_nofail() can't fail either, and is therefore
311 usable even then. But relying on the device implementation that
312 way is somewhat unclean, and best avoided. */
313void qdev_init_nofail(DeviceState *dev)
314{
315 DeviceInfo *info = dev->info;
316
317 if (qdev_init(dev) < 0)
318 hw_error("Initialization of device %s failed\n", info->name);
319}
320
02e2da45
PB
321/* Unlink device from bus and free the structure. */
322void qdev_free(DeviceState *dev)
323{
131ec1bd
GH
324 BusState *bus;
325
326 if (dev->state == DEV_STATE_INITIALIZED) {
327 while (dev->num_child_bus) {
328 bus = QLIST_FIRST(&dev->child_bus);
329 qbus_free(bus);
330 }
131ec1bd
GH
331 if (dev->info->vmsd)
332 vmstate_unregister(dev->info->vmsd, dev);
d29275f1
GH
333 if (dev->info->exit)
334 dev->info->exit(dev);
ef80b466
GH
335 if (dev->opts)
336 qemu_opts_del(dev->opts);
131ec1bd 337 }
7f23f812 338 qemu_unregister_reset(qdev_reset, dev);
72cf2d4f 339 QLIST_REMOVE(dev, sibling);
ccb63de3 340 qemu_free(dev);
aae9460e
PB
341}
342
3418bd25
GH
343void qdev_machine_creation_done(void)
344{
345 /*
346 * ok, initial machine setup is done, starting from now we can
347 * only create hotpluggable devices
348 */
349 qdev_hotplug = 1;
350}
351
aae9460e
PB
352/* Get a character (serial) device interface. */
353CharDriverState *qdev_init_chardev(DeviceState *dev)
354{
355 static int next_serial;
98b19252
AS
356
357 /* FIXME: This function needs to go away: use chardev properties! */
358 return serial_hds[next_serial++];
aae9460e
PB
359}
360
02e2da45 361BusState *qdev_get_parent_bus(DeviceState *dev)
aae9460e 362{
02e2da45 363 return dev->parent_bus;
aae9460e
PB
364}
365
aae9460e
PB
366void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
367{
368 assert(dev->num_gpio_in == 0);
369 dev->num_gpio_in = n;
370 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
371}
372
373void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
374{
375 assert(dev->num_gpio_out == 0);
376 dev->num_gpio_out = n;
377 dev->gpio_out = pins;
378}
379
380qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
381{
382 assert(n >= 0 && n < dev->num_gpio_in);
383 return dev->gpio_in[n];
384}
385
386void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
387{
388 assert(n >= 0 && n < dev->num_gpio_out);
389 dev->gpio_out[n] = pin;
390}
391
ed16ab5a
GH
392void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
393{
394 qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
395 if (nd->vlan)
396 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
397 if (nd->netdev)
398 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
75422b0d 399 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
97b15621
GH
400 qdev_prop_exists(dev, "vectors")) {
401 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
402 }
ed16ab5a
GH
403}
404
aae9460e
PB
405static int next_block_unit[IF_COUNT];
406
407/* Get a block device. This should only be used for single-drive devices
408 (e.g. SD/Floppy/MTD). Multi-disk devices (scsi/ide) should use the
409 appropriate bus. */
410BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
411{
412 int unit = next_block_unit[type]++;
751c6a17 413 DriveInfo *dinfo;
aae9460e 414
751c6a17
GH
415 dinfo = drive_get(type, 0, unit);
416 return dinfo ? dinfo->bdrv : NULL;
aae9460e 417}
4d6ae674 418
02e2da45 419BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
4d6ae674 420{
02e2da45 421 BusState *bus;
4d6ae674 422
72cf2d4f 423 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
4d6ae674 424 if (strcmp(name, bus->name) == 0) {
02e2da45 425 return bus;
4d6ae674
PB
426 }
427 }
428 return NULL;
429}
430
8ffb1bcf
GH
431static BusState *qbus_find_recursive(BusState *bus, const char *name,
432 const BusInfo *info)
433{
434 DeviceState *dev;
435 BusState *child, *ret;
436 int match = 1;
437
438 if (name && (strcmp(bus->name, name) != 0)) {
439 match = 0;
440 }
441 if (info && (bus->info != info)) {
442 match = 0;
443 }
444 if (match) {
445 return bus;
446 }
447
72cf2d4f
BS
448 QLIST_FOREACH(dev, &bus->children, sibling) {
449 QLIST_FOREACH(child, &dev->child_bus, sibling) {
8ffb1bcf
GH
450 ret = qbus_find_recursive(child, name, info);
451 if (ret) {
452 return ret;
453 }
454 }
455 }
456 return NULL;
457}
458
3418bd25
GH
459static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
460{
461 DeviceState *dev, *ret;
462 BusState *child;
463
464 QLIST_FOREACH(dev, &bus->children, sibling) {
465 if (dev->id && strcmp(dev->id, id) == 0)
466 return dev;
467 QLIST_FOREACH(child, &dev->child_bus, sibling) {
468 ret = qdev_find_recursive(child, id);
469 if (ret) {
470 return ret;
471 }
472 }
473 }
474 return NULL;
475}
476
53db16b5 477static void qbus_list_bus(DeviceState *dev)
8ffb1bcf
GH
478{
479 BusState *child;
480 const char *sep = " ";
8ffb1bcf 481
53db16b5
MA
482 error_printf("child busses at \"%s\":",
483 dev->id ? dev->id : dev->info->name);
72cf2d4f 484 QLIST_FOREACH(child, &dev->child_bus, sibling) {
53db16b5 485 error_printf("%s\"%s\"", sep, child->name);
8ffb1bcf
GH
486 sep = ", ";
487 }
53db16b5 488 error_printf("\n");
8ffb1bcf
GH
489}
490
53db16b5 491static void qbus_list_dev(BusState *bus)
8ffb1bcf
GH
492{
493 DeviceState *dev;
494 const char *sep = " ";
8ffb1bcf 495
53db16b5 496 error_printf("devices at \"%s\":", bus->name);
72cf2d4f 497 QLIST_FOREACH(dev, &bus->children, sibling) {
53db16b5 498 error_printf("%s\"%s\"", sep, dev->info->name);
8ffb1bcf 499 if (dev->id)
53db16b5 500 error_printf("/\"%s\"", dev->id);
8ffb1bcf
GH
501 sep = ", ";
502 }
53db16b5 503 error_printf("\n");
8ffb1bcf
GH
504}
505
506static BusState *qbus_find_bus(DeviceState *dev, char *elem)
507{
508 BusState *child;
509
72cf2d4f 510 QLIST_FOREACH(child, &dev->child_bus, sibling) {
8ffb1bcf
GH
511 if (strcmp(child->name, elem) == 0) {
512 return child;
513 }
514 }
515 return NULL;
516}
517
518static DeviceState *qbus_find_dev(BusState *bus, char *elem)
519{
520 DeviceState *dev;
521
522 /*
523 * try to match in order:
524 * (1) instance id, if present
525 * (2) driver name
526 * (3) driver alias, if present
527 */
72cf2d4f 528 QLIST_FOREACH(dev, &bus->children, sibling) {
8ffb1bcf
GH
529 if (dev->id && strcmp(dev->id, elem) == 0) {
530 return dev;
531 }
532 }
72cf2d4f 533 QLIST_FOREACH(dev, &bus->children, sibling) {
8ffb1bcf
GH
534 if (strcmp(dev->info->name, elem) == 0) {
535 return dev;
536 }
537 }
72cf2d4f 538 QLIST_FOREACH(dev, &bus->children, sibling) {
8ffb1bcf
GH
539 if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
540 return dev;
541 }
542 }
543 return NULL;
544}
545
546static BusState *qbus_find(const char *path)
547{
548 DeviceState *dev;
549 BusState *bus;
53db16b5 550 char elem[128];
8ffb1bcf
GH
551 int pos, len;
552
553 /* find start element */
554 if (path[0] == '/') {
555 bus = main_system_bus;
556 pos = 0;
557 } else {
558 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
fc98eb43
MA
559 assert(!path[0]);
560 elem[0] = len = 0;
8ffb1bcf
GH
561 }
562 bus = qbus_find_recursive(main_system_bus, elem, NULL);
563 if (!bus) {
ac8dae67 564 qerror_report(QERR_BUS_NOT_FOUND, elem);
8ffb1bcf
GH
565 return NULL;
566 }
567 pos = len;
568 }
569
570 for (;;) {
fc98eb43
MA
571 assert(path[pos] == '/' || !path[pos]);
572 while (path[pos] == '/') {
573 pos++;
574 }
8ffb1bcf 575 if (path[pos] == '\0') {
8ffb1bcf
GH
576 return bus;
577 }
578
579 /* find device */
fc98eb43
MA
580 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
581 assert(0);
582 elem[0] = len = 0;
8ffb1bcf
GH
583 }
584 pos += len;
585 dev = qbus_find_dev(bus, elem);
586 if (!dev) {
ac8dae67 587 qerror_report(QERR_DEVICE_NOT_FOUND, elem);
8bc27249
MA
588 if (!monitor_cur_is_qmp()) {
589 qbus_list_dev(bus);
590 }
8ffb1bcf
GH
591 return NULL;
592 }
fc98eb43
MA
593
594 assert(path[pos] == '/' || !path[pos]);
595 while (path[pos] == '/') {
596 pos++;
597 }
8ffb1bcf
GH
598 if (path[pos] == '\0') {
599 /* last specified element is a device. If it has exactly
600 * one child bus accept it nevertheless */
601 switch (dev->num_child_bus) {
602 case 0:
ac8dae67 603 qerror_report(QERR_DEVICE_NO_BUS, elem);
8ffb1bcf
GH
604 return NULL;
605 case 1:
72cf2d4f 606 return QLIST_FIRST(&dev->child_bus);
8ffb1bcf 607 default:
ac8dae67 608 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
8bc27249
MA
609 if (!monitor_cur_is_qmp()) {
610 qbus_list_bus(dev);
611 }
8ffb1bcf
GH
612 return NULL;
613 }
614 }
615
616 /* find bus */
fc98eb43
MA
617 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
618 assert(0);
619 elem[0] = len = 0;
8ffb1bcf
GH
620 }
621 pos += len;
622 bus = qbus_find_bus(dev, elem);
623 if (!bus) {
ac8dae67 624 qerror_report(QERR_BUS_NOT_FOUND, elem);
8bc27249
MA
625 if (!monitor_cur_is_qmp()) {
626 qbus_list_bus(dev);
627 }
8ffb1bcf
GH
628 return NULL;
629 }
630 }
631}
632
cd739fb6
GH
633void qbus_create_inplace(BusState *bus, BusInfo *info,
634 DeviceState *parent, const char *name)
02e2da45 635{
d271de9f
GH
636 char *buf;
637 int i,len;
02e2da45 638
10c4c98a 639 bus->info = info;
02e2da45 640 bus->parent = parent;
d271de9f
GH
641
642 if (name) {
643 /* use supplied name */
644 bus->name = qemu_strdup(name);
645 } else if (parent && parent->id) {
646 /* parent device has id -> use it for bus name */
647 len = strlen(parent->id) + 16;
648 buf = qemu_malloc(len);
649 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
650 bus->name = buf;
651 } else {
652 /* no id -> use lowercase bus type for bus name */
653 len = strlen(info->name) + 16;
654 buf = qemu_malloc(len);
655 len = snprintf(buf, len, "%s.%d", info->name,
656 parent ? parent->num_child_bus : 0);
657 for (i = 0; i < len; i++)
bb87ece5 658 buf[i] = qemu_tolower(buf[i]);
d271de9f
GH
659 bus->name = buf;
660 }
661
72cf2d4f 662 QLIST_INIT(&bus->children);
02e2da45 663 if (parent) {
72cf2d4f 664 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
d271de9f 665 parent->num_child_bus++;
02e2da45 666 }
cd739fb6
GH
667
668}
669
670BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
671{
672 BusState *bus;
673
674 bus = qemu_mallocz(info->size);
675 bus->qdev_allocated = 1;
676 qbus_create_inplace(bus, info, parent, name);
02e2da45
PB
677 return bus;
678}
cae4956e 679
131ec1bd
GH
680void qbus_free(BusState *bus)
681{
682 DeviceState *dev;
683
684 while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
685 qdev_free(dev);
686 }
687 if (bus->parent) {
688 QLIST_REMOVE(bus, sibling);
689 bus->parent->num_child_bus--;
690 }
691 if (bus->qdev_allocated) {
692 qemu_free(bus);
693 }
694}
695
cae4956e
GH
696#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
697static void qbus_print(Monitor *mon, BusState *bus, int indent);
698
ee6847d1
GH
699static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
700 const char *prefix, int indent)
701{
702 char buf[64];
703
704 if (!props)
705 return;
706 while (props->name) {
036f7166
MA
707 /*
708 * TODO Properties without a print method are just for dirty
709 * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
710 * marked for removal. The test props->info->print should be
711 * removed along with it.
712 */
ee6847d1
GH
713 if (props->info->print) {
714 props->info->print(dev, props, buf, sizeof(buf));
715 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
716 }
717 props++;
718 }
719}
720
cae4956e
GH
721static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
722{
cae4956e 723 BusState *child;
ccb63de3
GH
724 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
725 dev->id ? dev->id : "");
cae4956e
GH
726 indent += 2;
727 if (dev->num_gpio_in) {
728 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
729 }
730 if (dev->num_gpio_out) {
731 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
732 }
ee6847d1
GH
733 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
734 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
10c4c98a
GH
735 if (dev->parent_bus->info->print_dev)
736 dev->parent_bus->info->print_dev(mon, dev, indent);
72cf2d4f 737 QLIST_FOREACH(child, &dev->child_bus, sibling) {
cae4956e
GH
738 qbus_print(mon, child, indent);
739 }
740}
741
742static void qbus_print(Monitor *mon, BusState *bus, int indent)
743{
744 struct DeviceState *dev;
745
746 qdev_printf("bus: %s\n", bus->name);
747 indent += 2;
10c4c98a 748 qdev_printf("type %s\n", bus->info->name);
72cf2d4f 749 QLIST_FOREACH(dev, &bus->children, sibling) {
cae4956e
GH
750 qdev_print(mon, dev, indent);
751 }
752}
753#undef qdev_printf
754
755void do_info_qtree(Monitor *mon)
756{
757 if (main_system_bus)
758 qbus_print(mon, main_system_bus, 0);
759}
9316d30f 760
f6c64e0e 761void do_info_qdm(Monitor *mon)
9316d30f
GH
762{
763 DeviceInfo *info;
9316d30f
GH
764
765 for (info = device_info_list; info != NULL; info = info->next) {
8a9662ca 766 qdev_print_devinfo(info);
9316d30f
GH
767 }
768}
3418bd25 769
8bc27249
MA
770/**
771 * do_device_add(): Add a device
772 *
773 * Argument qdict contains
774 * - "driver": the name of the new device's driver
775 * - "bus": the device's parent bus (device tree path)
776 * - "id": the device's ID (must be unique)
777 * - device properties
778 *
779 * Example:
780 *
781 * { "driver": "usb-net", "id": "eth1", "netdev": "netdev1" }
782 */
783int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
3418bd25
GH
784{
785 QemuOpts *opts;
786
c7e4e8ce 787 opts = qemu_opts_from_qdict(&qemu_device_opts, qdict);
8bc27249
MA
788 if (!opts) {
789 return -1;
790 }
791 if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
792 qemu_opts_del(opts);
793 return 0;
0f853a38 794 }
8bc27249
MA
795 if (!qdev_device_add(opts)) {
796 qemu_opts_del(opts);
797 return -1;
798 }
799 return 0;
3418bd25
GH
800}
801
17a38eaa 802int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
3418bd25
GH
803{
804 const char *id = qdict_get_str(qdict, "id");
805 DeviceState *dev;
806
807 dev = qdev_find_recursive(main_system_bus, id);
808 if (NULL == dev) {
17a38eaa
MA
809 qerror_report(QERR_DEVICE_NOT_FOUND, id);
810 return -1;
3418bd25 811 }
17a38eaa 812 return qdev_unplug(dev);
3418bd25 813}
This page took 0.365123 seconds and 4 git commands to generate.