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