]> git.proxmox.com Git - qemu.git/blame - hw/qdev.c
qom: add a reference count to qdev objects
[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);
d8bb00d6 94 QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
0c17542d
MA
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
542379f4 189 if (!driver || !qemu_opt_get(opts, "?")) {
08350cf0
MA
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
85ed303b
AL
326 if (dev->ref != 0) {
327 qerror_report(QERR_DEVICE_IN_USE, dev->id?:"");
328 return -1;
329 }
330
0ac8ef71
AW
331 qdev_hot_removed = true;
332
3418bd25
GH
333 return dev->info->unplug(dev);
334}
335
ec990eb6
AL
336static int qdev_reset_one(DeviceState *dev, void *opaque)
337{
338 if (dev->info->reset) {
339 dev->info->reset(dev);
340 }
341
342 return 0;
343}
344
345BusState *sysbus_get_default(void)
346{
68694897 347 if (!main_system_bus) {
2da8bb92 348 main_system_bus_create();
68694897 349 }
ec990eb6
AL
350 return main_system_bus;
351}
352
b4694b7c
IY
353static int qbus_reset_one(BusState *bus, void *opaque)
354{
355 if (bus->info->reset) {
356 return bus->info->reset(bus);
357 }
358 return 0;
359}
360
5af0a04b
IY
361void qdev_reset_all(DeviceState *dev)
362{
363 qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
364}
365
80376c3f
IY
366void qbus_reset_all_fn(void *opaque)
367{
368 BusState *bus = opaque;
f530cce3 369 qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
80376c3f
IY
370}
371
3418bd25
GH
372/* can be used as ->unplug() callback for the simple cases */
373int qdev_simple_unplug_cb(DeviceState *dev)
374{
375 /* just zap it */
376 qdev_free(dev);
377 return 0;
378}
379
3b29a101
MT
380
381/* Like qdev_init(), but terminate program via error_report() instead of
e23a1b33
MA
382 returning an error value. This is okay during machine creation.
383 Don't use for hotplug, because there callers need to recover from
384 failure. Exception: if you know the device's init() callback can't
385 fail, then qdev_init_nofail() can't fail either, and is therefore
386 usable even then. But relying on the device implementation that
387 way is somewhat unclean, and best avoided. */
388void qdev_init_nofail(DeviceState *dev)
389{
390 DeviceInfo *info = dev->info;
391
bd6c9a61 392 if (qdev_init(dev) < 0) {
6daf194d 393 error_report("Initialization of device %s failed", info->name);
bd6c9a61
MA
394 exit(1);
395 }
e23a1b33
MA
396}
397
02e2da45
PB
398/* Unlink device from bus and free the structure. */
399void qdev_free(DeviceState *dev)
400{
131ec1bd 401 BusState *bus;
d21357df 402 Property *prop;
131ec1bd
GH
403
404 if (dev->state == DEV_STATE_INITIALIZED) {
405 while (dev->num_child_bus) {
406 bus = QLIST_FIRST(&dev->child_bus);
407 qbus_free(bus);
408 }
131ec1bd 409 if (dev->info->vmsd)
0be71e32 410 vmstate_unregister(dev, dev->info->vmsd, dev);
d29275f1
GH
411 if (dev->info->exit)
412 dev->info->exit(dev);
ef80b466
GH
413 if (dev->opts)
414 qemu_opts_del(dev->opts);
131ec1bd 415 }
d8bb00d6 416 QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
d21357df
MA
417 for (prop = dev->info->props; prop && prop->name; prop++) {
418 if (prop->info->free) {
419 prop->info->free(dev, prop);
420 }
421 }
7267c094 422 g_free(dev);
aae9460e
PB
423}
424
3418bd25
GH
425void qdev_machine_creation_done(void)
426{
427 /*
428 * ok, initial machine setup is done, starting from now we can
429 * only create hotpluggable devices
430 */
431 qdev_hotplug = 1;
432}
433
0ac8ef71
AW
434bool qdev_machine_modified(void)
435{
436 return qdev_hot_added || qdev_hot_removed;
437}
438
aae9460e
PB
439/* Get a character (serial) device interface. */
440CharDriverState *qdev_init_chardev(DeviceState *dev)
441{
442 static int next_serial;
98b19252
AS
443
444 /* FIXME: This function needs to go away: use chardev properties! */
445 return serial_hds[next_serial++];
aae9460e
PB
446}
447
02e2da45 448BusState *qdev_get_parent_bus(DeviceState *dev)
aae9460e 449{
02e2da45 450 return dev->parent_bus;
aae9460e
PB
451}
452
aae9460e
PB
453void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
454{
455 assert(dev->num_gpio_in == 0);
456 dev->num_gpio_in = n;
457 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
458}
459
460void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
461{
462 assert(dev->num_gpio_out == 0);
463 dev->num_gpio_out = n;
464 dev->gpio_out = pins;
465}
466
467qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
468{
469 assert(n >= 0 && n < dev->num_gpio_in);
470 return dev->gpio_in[n];
471}
472
473void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
474{
475 assert(n >= 0 && n < dev->num_gpio_out);
476 dev->gpio_out[n] = pin;
477}
478
ed16ab5a
GH
479void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
480{
6eed1856 481 qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
ed16ab5a
GH
482 if (nd->vlan)
483 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
484 if (nd->netdev)
485 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
75422b0d 486 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
97b15621
GH
487 qdev_prop_exists(dev, "vectors")) {
488 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
489 }
48e2faf2 490 nd->instantiated = 1;
ed16ab5a
GH
491}
492
02e2da45 493BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
4d6ae674 494{
02e2da45 495 BusState *bus;
4d6ae674 496
72cf2d4f 497 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
4d6ae674 498 if (strcmp(name, bus->name) == 0) {
02e2da45 499 return bus;
4d6ae674
PB
500 }
501 }
502 return NULL;
503}
504
81699d8a
AL
505int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
506 qbus_walkerfn *busfn, void *opaque)
507{
508 DeviceState *dev;
509 int err;
510
511 if (busfn) {
512 err = busfn(bus, opaque);
513 if (err) {
514 return err;
515 }
516 }
517
d8bb00d6 518 QTAILQ_FOREACH(dev, &bus->children, sibling) {
81699d8a
AL
519 err = qdev_walk_children(dev, devfn, busfn, opaque);
520 if (err < 0) {
521 return err;
522 }
523 }
524
525 return 0;
526}
527
528int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
529 qbus_walkerfn *busfn, void *opaque)
530{
531 BusState *bus;
532 int err;
533
534 if (devfn) {
535 err = devfn(dev, opaque);
536 if (err) {
537 return err;
538 }
539 }
540
541 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
542 err = qbus_walk_children(bus, devfn, busfn, opaque);
543 if (err < 0) {
544 return err;
545 }
546 }
547
548 return 0;
549}
550
8ffb1bcf
GH
551static BusState *qbus_find_recursive(BusState *bus, const char *name,
552 const BusInfo *info)
553{
554 DeviceState *dev;
555 BusState *child, *ret;
556 int match = 1;
557
558 if (name && (strcmp(bus->name, name) != 0)) {
559 match = 0;
560 }
561 if (info && (bus->info != info)) {
562 match = 0;
563 }
564 if (match) {
565 return bus;
566 }
567
d8bb00d6 568 QTAILQ_FOREACH(dev, &bus->children, sibling) {
72cf2d4f 569 QLIST_FOREACH(child, &dev->child_bus, sibling) {
8ffb1bcf
GH
570 ret = qbus_find_recursive(child, name, info);
571 if (ret) {
572 return ret;
573 }
574 }
575 }
576 return NULL;
577}
578
a2ee6b4f 579DeviceState *qdev_find_recursive(BusState *bus, const char *id)
3418bd25
GH
580{
581 DeviceState *dev, *ret;
582 BusState *child;
583
d8bb00d6 584 QTAILQ_FOREACH(dev, &bus->children, sibling) {
3418bd25
GH
585 if (dev->id && strcmp(dev->id, id) == 0)
586 return dev;
587 QLIST_FOREACH(child, &dev->child_bus, sibling) {
588 ret = qdev_find_recursive(child, id);
589 if (ret) {
590 return ret;
591 }
592 }
593 }
594 return NULL;
595}
596
53db16b5 597static void qbus_list_bus(DeviceState *dev)
8ffb1bcf
GH
598{
599 BusState *child;
600 const char *sep = " ";
8ffb1bcf 601
53db16b5
MA
602 error_printf("child busses at \"%s\":",
603 dev->id ? dev->id : dev->info->name);
72cf2d4f 604 QLIST_FOREACH(child, &dev->child_bus, sibling) {
53db16b5 605 error_printf("%s\"%s\"", sep, child->name);
8ffb1bcf
GH
606 sep = ", ";
607 }
53db16b5 608 error_printf("\n");
8ffb1bcf
GH
609}
610
53db16b5 611static void qbus_list_dev(BusState *bus)
8ffb1bcf
GH
612{
613 DeviceState *dev;
614 const char *sep = " ";
8ffb1bcf 615
53db16b5 616 error_printf("devices at \"%s\":", bus->name);
d8bb00d6 617 QTAILQ_FOREACH(dev, &bus->children, sibling) {
53db16b5 618 error_printf("%s\"%s\"", sep, dev->info->name);
8ffb1bcf 619 if (dev->id)
53db16b5 620 error_printf("/\"%s\"", dev->id);
8ffb1bcf
GH
621 sep = ", ";
622 }
53db16b5 623 error_printf("\n");
8ffb1bcf
GH
624}
625
626static BusState *qbus_find_bus(DeviceState *dev, char *elem)
627{
628 BusState *child;
629
72cf2d4f 630 QLIST_FOREACH(child, &dev->child_bus, sibling) {
8ffb1bcf
GH
631 if (strcmp(child->name, elem) == 0) {
632 return child;
633 }
634 }
635 return NULL;
636}
637
638static DeviceState *qbus_find_dev(BusState *bus, char *elem)
639{
640 DeviceState *dev;
641
642 /*
643 * try to match in order:
644 * (1) instance id, if present
645 * (2) driver name
646 * (3) driver alias, if present
647 */
d8bb00d6 648 QTAILQ_FOREACH(dev, &bus->children, sibling) {
8ffb1bcf
GH
649 if (dev->id && strcmp(dev->id, elem) == 0) {
650 return dev;
651 }
652 }
d8bb00d6 653 QTAILQ_FOREACH(dev, &bus->children, sibling) {
8ffb1bcf
GH
654 if (strcmp(dev->info->name, elem) == 0) {
655 return dev;
656 }
657 }
d8bb00d6 658 QTAILQ_FOREACH(dev, &bus->children, sibling) {
8ffb1bcf
GH
659 if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
660 return dev;
661 }
662 }
663 return NULL;
664}
665
666static BusState *qbus_find(const char *path)
667{
668 DeviceState *dev;
669 BusState *bus;
53db16b5 670 char elem[128];
8ffb1bcf
GH
671 int pos, len;
672
673 /* find start element */
674 if (path[0] == '/') {
675 bus = main_system_bus;
676 pos = 0;
677 } else {
678 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
fc98eb43
MA
679 assert(!path[0]);
680 elem[0] = len = 0;
8ffb1bcf
GH
681 }
682 bus = qbus_find_recursive(main_system_bus, elem, NULL);
683 if (!bus) {
ac8dae67 684 qerror_report(QERR_BUS_NOT_FOUND, elem);
8ffb1bcf
GH
685 return NULL;
686 }
687 pos = len;
688 }
689
690 for (;;) {
fc98eb43
MA
691 assert(path[pos] == '/' || !path[pos]);
692 while (path[pos] == '/') {
693 pos++;
694 }
8ffb1bcf 695 if (path[pos] == '\0') {
8ffb1bcf
GH
696 return bus;
697 }
698
699 /* find device */
fc98eb43
MA
700 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
701 assert(0);
702 elem[0] = len = 0;
8ffb1bcf
GH
703 }
704 pos += len;
705 dev = qbus_find_dev(bus, elem);
706 if (!dev) {
ac8dae67 707 qerror_report(QERR_DEVICE_NOT_FOUND, elem);
8bc27249
MA
708 if (!monitor_cur_is_qmp()) {
709 qbus_list_dev(bus);
710 }
8ffb1bcf
GH
711 return NULL;
712 }
fc98eb43
MA
713
714 assert(path[pos] == '/' || !path[pos]);
715 while (path[pos] == '/') {
716 pos++;
717 }
8ffb1bcf
GH
718 if (path[pos] == '\0') {
719 /* last specified element is a device. If it has exactly
720 * one child bus accept it nevertheless */
721 switch (dev->num_child_bus) {
722 case 0:
ac8dae67 723 qerror_report(QERR_DEVICE_NO_BUS, elem);
8ffb1bcf
GH
724 return NULL;
725 case 1:
72cf2d4f 726 return QLIST_FIRST(&dev->child_bus);
8ffb1bcf 727 default:
ac8dae67 728 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
8bc27249
MA
729 if (!monitor_cur_is_qmp()) {
730 qbus_list_bus(dev);
731 }
8ffb1bcf
GH
732 return NULL;
733 }
734 }
735
736 /* find bus */
fc98eb43
MA
737 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
738 assert(0);
739 elem[0] = len = 0;
8ffb1bcf
GH
740 }
741 pos += len;
742 bus = qbus_find_bus(dev, elem);
743 if (!bus) {
ac8dae67 744 qerror_report(QERR_BUS_NOT_FOUND, elem);
8bc27249
MA
745 if (!monitor_cur_is_qmp()) {
746 qbus_list_bus(dev);
747 }
8ffb1bcf
GH
748 return NULL;
749 }
750 }
751}
752
cd739fb6
GH
753void qbus_create_inplace(BusState *bus, BusInfo *info,
754 DeviceState *parent, const char *name)
02e2da45 755{
d271de9f
GH
756 char *buf;
757 int i,len;
02e2da45 758
10c4c98a 759 bus->info = info;
02e2da45 760 bus->parent = parent;
d271de9f
GH
761
762 if (name) {
763 /* use supplied name */
7267c094 764 bus->name = g_strdup(name);
d271de9f
GH
765 } else if (parent && parent->id) {
766 /* parent device has id -> use it for bus name */
767 len = strlen(parent->id) + 16;
7267c094 768 buf = g_malloc(len);
d271de9f
GH
769 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
770 bus->name = buf;
771 } else {
772 /* no id -> use lowercase bus type for bus name */
773 len = strlen(info->name) + 16;
7267c094 774 buf = g_malloc(len);
d271de9f
GH
775 len = snprintf(buf, len, "%s.%d", info->name,
776 parent ? parent->num_child_bus : 0);
777 for (i = 0; i < len; i++)
bb87ece5 778 buf[i] = qemu_tolower(buf[i]);
d271de9f
GH
779 bus->name = buf;
780 }
781
d8bb00d6 782 QTAILQ_INIT(&bus->children);
02e2da45 783 if (parent) {
72cf2d4f 784 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
d271de9f 785 parent->num_child_bus++;
80376c3f
IY
786 } else if (bus != main_system_bus) {
787 /* TODO: once all bus devices are qdevified,
788 only reset handler for main_system_bus should be registered here. */
789 qemu_register_reset(qbus_reset_all_fn, bus);
02e2da45 790 }
cd739fb6
GH
791}
792
793BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
794{
795 BusState *bus;
796
7267c094 797 bus = g_malloc0(info->size);
cd739fb6
GH
798 bus->qdev_allocated = 1;
799 qbus_create_inplace(bus, info, parent, name);
02e2da45
PB
800 return bus;
801}
cae4956e 802
2da8bb92
IY
803static void main_system_bus_create(void)
804{
805 /* assign main_system_bus before qbus_create_inplace()
806 * in order to make "if (bus != main_system_bus)" work */
7267c094 807 main_system_bus = g_malloc0(system_bus_info.size);
2da8bb92
IY
808 main_system_bus->qdev_allocated = 1;
809 qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
810 "main-system-bus");
811}
812
131ec1bd
GH
813void qbus_free(BusState *bus)
814{
815 DeviceState *dev;
816
d8bb00d6 817 while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
131ec1bd
GH
818 qdev_free(dev);
819 }
820 if (bus->parent) {
821 QLIST_REMOVE(bus, sibling);
822 bus->parent->num_child_bus--;
80376c3f
IY
823 } else {
824 assert(bus != main_system_bus); /* main_system_bus is never freed */
825 qemu_unregister_reset(qbus_reset_all_fn, bus);
131ec1bd 826 }
7267c094 827 g_free((void*)bus->name);
131ec1bd 828 if (bus->qdev_allocated) {
7267c094 829 g_free(bus);
131ec1bd
GH
830 }
831}
832
cae4956e
GH
833#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
834static void qbus_print(Monitor *mon, BusState *bus, int indent);
835
ee6847d1
GH
836static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
837 const char *prefix, int indent)
838{
839 char buf[64];
840
841 if (!props)
842 return;
843 while (props->name) {
036f7166
MA
844 /*
845 * TODO Properties without a print method are just for dirty
846 * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
847 * marked for removal. The test props->info->print should be
848 * removed along with it.
849 */
ee6847d1
GH
850 if (props->info->print) {
851 props->info->print(dev, props, buf, sizeof(buf));
852 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
853 }
854 props++;
855 }
856}
857
cae4956e
GH
858static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
859{
cae4956e 860 BusState *child;
ccb63de3
GH
861 qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
862 dev->id ? dev->id : "");
cae4956e
GH
863 indent += 2;
864 if (dev->num_gpio_in) {
865 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
866 }
867 if (dev->num_gpio_out) {
868 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
869 }
ee6847d1
GH
870 qdev_print_props(mon, dev, dev->info->props, "dev", indent);
871 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
10c4c98a
GH
872 if (dev->parent_bus->info->print_dev)
873 dev->parent_bus->info->print_dev(mon, dev, indent);
72cf2d4f 874 QLIST_FOREACH(child, &dev->child_bus, sibling) {
cae4956e
GH
875 qbus_print(mon, child, indent);
876 }
877}
878
879static void qbus_print(Monitor *mon, BusState *bus, int indent)
880{
881 struct DeviceState *dev;
882
883 qdev_printf("bus: %s\n", bus->name);
884 indent += 2;
10c4c98a 885 qdev_printf("type %s\n", bus->info->name);
d8bb00d6 886 QTAILQ_FOREACH(dev, &bus->children, sibling) {
cae4956e
GH
887 qdev_print(mon, dev, indent);
888 }
889}
890#undef qdev_printf
891
892void do_info_qtree(Monitor *mon)
893{
894 if (main_system_bus)
895 qbus_print(mon, main_system_bus, 0);
896}
9316d30f 897
f6c64e0e 898void do_info_qdm(Monitor *mon)
9316d30f
GH
899{
900 DeviceInfo *info;
9316d30f
GH
901
902 for (info = device_info_list; info != NULL; info = info->next) {
8a9662ca 903 qdev_print_devinfo(info);
9316d30f
GH
904 }
905}
3418bd25 906
8bc27249 907int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
3418bd25
GH
908{
909 QemuOpts *opts;
910
3329f07b 911 opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
8bc27249
MA
912 if (!opts) {
913 return -1;
914 }
915 if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
916 qemu_opts_del(opts);
917 return 0;
0f853a38 918 }
8bc27249
MA
919 if (!qdev_device_add(opts)) {
920 qemu_opts_del(opts);
921 return -1;
922 }
923 return 0;
3418bd25
GH
924}
925
17a38eaa 926int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
3418bd25
GH
927{
928 const char *id = qdict_get_str(qdict, "id");
929 DeviceState *dev;
930
931 dev = qdev_find_recursive(main_system_bus, id);
932 if (NULL == dev) {
17a38eaa
MA
933 qerror_report(QERR_DEVICE_NOT_FOUND, id);
934 return -1;
3418bd25 935 }
17a38eaa 936 return qdev_unplug(dev);
3418bd25 937}
1ca4d09a
GN
938
939static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
940{
941 int l = 0;
942
943 if (dev && dev->parent_bus) {
944 char *d;
945 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
946 if (dev->parent_bus->info->get_fw_dev_path) {
947 d = dev->parent_bus->info->get_fw_dev_path(dev);
948 l += snprintf(p + l, size - l, "%s", d);
7267c094 949 g_free(d);
1ca4d09a
GN
950 } else {
951 l += snprintf(p + l, size - l, "%s", dev->info->name);
952 }
953 }
954 l += snprintf(p + l , size - l, "/");
955
956 return l;
957}
958
959char* qdev_get_fw_dev_path(DeviceState *dev)
960{
961 char path[128];
962 int l;
963
964 l = qdev_get_fw_dev_path_helper(dev, path, 128);
965
966 path[l-1] = '\0';
967
968 return strdup(path);
969}
85ed303b
AL
970
971void qdev_ref(DeviceState *dev)
972{
973 dev->ref++;
974}
975
976void qdev_unref(DeviceState *dev)
977{
978 g_assert(dev->ref > 0);
979 dev->ref--;
980}