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