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