]> git.proxmox.com Git - mirror_qemu.git/blame - hw/qdev.c
qdev: register all types natively through QEMU Object Model
[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
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. */
30fbb9fc
AL
46static void qdev_subclass_init(ObjectClass *klass, void *data)
47{
48 DeviceClass *dc = DEVICE_CLASS(klass);
6e008585 49 DeviceInfo *info = data;
94afdadc 50
d253e096
AL
51 if (info->fw_name) {
52 dc->fw_name = info->fw_name;
53 }
54 if (info->alias) {
55 dc->alias = info->alias;
56 }
57 if (info->desc) {
58 dc->desc = info->desc;
59 }
60 if (info->props) {
61 dc->props = info->props;
62 }
63 if (info->no_user) {
64 dc->no_user = info->no_user;
65 }
66 if (info->reset) {
67 dc->reset = info->reset;
68 }
69 if (info->vmsd) {
70 dc->vmsd = info->vmsd;
71 }
72 if (info->init) {
73 dc->init = info->init;
74 }
75 if (info->unplug) {
76 dc->unplug = info->unplug;
77 }
78 if (info->exit) {
79 dc->exit = info->exit;
80 }
81 if (info->bus_info) {
82 dc->bus_info = info->bus_info;
83 }
6e008585
AL
84 if (info->class_init) {
85 info->class_init(klass, data);
86 }
30fbb9fc
AL
87}
88
4be9f0d1
AL
89const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
90{
6e008585
AL
91 DeviceClass *dc = DEVICE_GET_CLASS(dev);
92 return dc->vmsd;
4be9f0d1
AL
93}
94
95BusInfo *qdev_get_bus_info(DeviceState *dev)
96{
6e008585
AL
97 DeviceClass *dc = DEVICE_GET_CLASS(dev);
98 return dc->bus_info;
4be9f0d1
AL
99}
100
101Property *qdev_get_props(DeviceState *dev)
102{
6e008585
AL
103 DeviceClass *dc = DEVICE_GET_CLASS(dev);
104 return dc->props;
4be9f0d1
AL
105}
106
107const char *qdev_fw_name(DeviceState *dev)
108{
6e008585 109 DeviceClass *dc = DEVICE_GET_CLASS(dev);
4be9f0d1 110
6e008585
AL
111 if (dc->fw_name) {
112 return dc->fw_name;
113 } else if (dc->alias) {
114 return dc->alias;
4be9f0d1
AL
115 }
116
117 return object_get_typename(OBJECT(dev));
118}
119
18b6dade
AL
120static void qdev_do_register_subclass(DeviceInfo *info, const char *parent,
121 const char *name)
aae9460e 122{
32fea402
AL
123 TypeInfo type_info = {};
124
074f2fff 125 assert(info->size >= sizeof(DeviceState));
aae9460e 126
18b6dade 127 type_info.name = name;
3cc90eb2 128 type_info.parent = parent;
32fea402 129 type_info.instance_size = info->size;
30fbb9fc
AL
130 type_info.class_init = qdev_subclass_init;
131 type_info.class_data = info;
32fea402
AL
132
133 type_register_static(&type_info);
18b6dade 134}
32fea402 135
18b6dade
AL
136void qdev_register_subclass(DeviceInfo *info, const char *parent)
137{
138 qdev_do_register_subclass(info, parent, info->name);
139 if (info->alias) {
140 qdev_do_register_subclass(info, parent, info->alias);
141 }
81ebb98b
GH
142}
143
a369da5f
BS
144bool qdev_exists(const char *name)
145{
212ad111 146 return !!object_class_by_name(name);
a369da5f 147}
40021f08 148
ca2cc788
PB
149static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
150 Error **errp);
151
18b6dade 152static DeviceState *qdev_create_from_info(BusState *bus, const char *typename)
0c17542d
MA
153{
154 DeviceState *dev;
a5296ca9 155 Property *prop;
0c17542d 156
18b6dade 157 dev = DEVICE(object_new(typename));
0c17542d 158 dev->parent_bus = bus;
6e008585 159 qdev_prop_set_defaults(dev, qdev_get_props(dev));
0c17542d
MA
160 qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
161 qdev_prop_set_globals(dev);
d8bb00d6 162 QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
0c17542d
MA
163 if (qdev_hotplug) {
164 assert(bus->allow_hotplug);
165 dev->hotplugged = 1;
0ac8ef71 166 qdev_hot_added = true;
0c17542d 167 }
4d2ffa08 168 dev->instance_id_alias = -1;
44677ded 169 QTAILQ_INIT(&dev->properties);
0c17542d 170 dev->state = DEV_STATE_CREATED;
a5296ca9 171
6e008585 172 for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
a5296ca9 173 qdev_property_add_legacy(dev, prop, NULL);
ca2cc788 174 qdev_property_add_static(dev, prop, NULL);
a5296ca9
AL
175 }
176
6e008585 177 for (prop = qdev_get_bus_info(dev)->props; prop && prop->name; prop++) {
a5296ca9 178 qdev_property_add_legacy(dev, prop, NULL);
ca2cc788 179 qdev_property_add_static(dev, prop, NULL);
a5296ca9
AL
180 }
181
cd34d667
AL
182 qdev_property_add_str(dev, "type", qdev_get_type, NULL, NULL);
183
0c17542d
MA
184 return dev;
185}
186
aae9460e
PB
187/* Create a new device. This only initializes the device state structure
188 and allows properties to be set. qdev_init should be called to
189 initialize the actual device emulation. */
02e2da45 190DeviceState *qdev_create(BusState *bus, const char *name)
0bcdeda7
BS
191{
192 DeviceState *dev;
193
194 dev = qdev_try_create(bus, name);
195 if (!dev) {
e92714c7
PM
196 if (bus) {
197 hw_error("Unknown device '%s' for bus '%s'\n", name,
198 bus->info->name);
199 } else {
200 hw_error("Unknown device '%s' for default sysbus\n", name);
201 }
0bcdeda7
BS
202 }
203
204 return dev;
205}
206
207DeviceState *qdev_try_create(BusState *bus, const char *name)
aae9460e 208{
10c4c98a 209 if (!bus) {
68694897 210 bus = sysbus_get_default();
10c4c98a
GH
211 }
212
18b6dade 213 return qdev_create_from_info(bus, name);
aae9460e
PB
214}
215
212ad111 216static void qdev_print_devinfo(ObjectClass *klass, void *opaque)
1b524b04 217{
212ad111
AL
218 DeviceClass *dc;
219 bool *show_no_user = opaque;
220
221 dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);
222
223 if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {
224 return;
22f2e344 225 }
212ad111
AL
226
227 error_printf("name \"%s\"", object_class_get_name(klass));
228 if (dc->bus_info) {
229 error_printf(", bus %s", dc->bus_info->name);
22f2e344 230 }
212ad111
AL
231 if (dc->alias) {
232 error_printf(", alias \"%s\"", dc->alias);
233 }
234 if (dc->desc) {
235 error_printf(", desc \"%s\"", dc->desc);
236 }
237 if (dc->no_user) {
8a9662ca 238 error_printf(", no-user");
22f2e344 239 }
8a9662ca 240 error_printf("\n");
1b524b04
GH
241}
242
f31d07d1 243static int set_property(const char *name, const char *value, void *opaque)
8ffb1bcf 244{
f31d07d1
GH
245 DeviceState *dev = opaque;
246
247 if (strcmp(name, "driver") == 0)
248 return 0;
249 if (strcmp(name, "bus") == 0)
250 return 0;
251
3df04ac3 252 if (qdev_prop_parse(dev, name, value) == -1) {
f31d07d1
GH
253 return -1;
254 }
255 return 0;
256}
257
ff952ba2
MA
258int qdev_device_help(QemuOpts *opts)
259{
260 const char *driver;
08350cf0 261 Property *prop;
212ad111
AL
262 ObjectClass *klass;
263 DeviceClass *info;
ff952ba2
MA
264
265 driver = qemu_opt_get(opts, "driver");
266 if (driver && !strcmp(driver, "?")) {
212ad111
AL
267 bool show_no_user = false;
268 object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, &show_no_user);
ff952ba2
MA
269 return 1;
270 }
271
542379f4 272 if (!driver || !qemu_opt_get(opts, "?")) {
08350cf0
MA
273 return 0;
274 }
275
212ad111
AL
276 klass = object_class_by_name(driver);
277 if (!klass) {
08350cf0
MA
278 return 0;
279 }
212ad111 280 info = DEVICE_CLASS(klass);
08350cf0
MA
281
282 for (prop = info->props; prop && prop->name; prop++) {
036f7166
MA
283 /*
284 * TODO Properties without a parser are just for dirty hacks.
285 * qdev_prop_ptr is the only such PropertyInfo. It's marked
286 * for removal. This conditional should be removed along with
287 * it.
288 */
289 if (!prop->info->parse) {
290 continue; /* no way to set it, don't show */
291 }
212ad111 292 error_printf("%s.%s=%s\n", driver, prop->name,
cafe5bdb 293 prop->info->legacy_name ?: prop->info->name);
a8467c7a
GH
294 }
295 for (prop = info->bus_info->props; prop && prop->name; prop++) {
296 if (!prop->info->parse) {
297 continue; /* no way to set it, don't show */
298 }
212ad111 299 error_printf("%s.%s=%s\n", driver, prop->name,
cafe5bdb 300 prop->info->legacy_name ?: prop->info->name);
08350cf0
MA
301 }
302 return 1;
ff952ba2
MA
303}
304
1bdaacb1
AL
305static DeviceState *qdev_get_peripheral(void)
306{
307 static DeviceState *dev;
308
309 if (dev == NULL) {
310 dev = qdev_create(NULL, "container");
311 qdev_property_add_child(qdev_get_root(), "peripheral", dev, NULL);
312 qdev_init_nofail(dev);
313 }
314
315 return dev;
316}
317
8eb02831
AL
318static DeviceState *qdev_get_peripheral_anon(void)
319{
320 static DeviceState *dev;
321
322 if (dev == NULL) {
323 dev = qdev_create(NULL, "container");
324 qdev_property_add_child(qdev_get_root(), "peripheral-anon", dev, NULL);
325 qdev_init_nofail(dev);
326 }
327
328 return dev;
329}
330
f31d07d1
GH
331DeviceState *qdev_device_add(QemuOpts *opts)
332{
18b6dade 333 DeviceClass *k;
f31d07d1 334 const char *driver, *path, *id;
8ffb1bcf
GH
335 DeviceState *qdev;
336 BusState *bus;
8ffb1bcf 337
f31d07d1
GH
338 driver = qemu_opt_get(opts, "driver");
339 if (!driver) {
0204276b 340 qerror_report(QERR_MISSING_PARAMETER, "driver");
8ffb1bcf
GH
341 return NULL;
342 }
f31d07d1
GH
343
344 /* find driver */
18b6dade 345 k = DEVICE_CLASS(object_class_by_name(driver));
8ffb1bcf 346
f31d07d1
GH
347 /* find bus */
348 path = qemu_opt_get(opts, "bus");
349 if (path != NULL) {
8ffb1bcf 350 bus = qbus_find(path);
ac8dae67
MA
351 if (!bus) {
352 return NULL;
353 }
18b6dade 354 if (bus->info != k->bus_info) {
0204276b
MA
355 qerror_report(QERR_BAD_BUS_FOR_DEVICE,
356 driver, bus->info->name);
327867b6
MA
357 return NULL;
358 }
8ffb1bcf 359 } else {
18b6dade 360 bus = qbus_find_recursive(main_system_bus, NULL, k->bus_info);
ac8dae67 361 if (!bus) {
0204276b 362 qerror_report(QERR_NO_BUS_FOR_DEVICE,
18b6dade 363 driver, k->bus_info->name);
ac8dae67
MA
364 return NULL;
365 }
75570088 366 }
3418bd25 367 if (qdev_hotplug && !bus->allow_hotplug) {
0204276b 368 qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
3418bd25
GH
369 return NULL;
370 }
8ffb1bcf 371
f31d07d1 372 /* create device, set properties */
18b6dade 373 qdev = qdev_create_from_info(bus, driver);
f31d07d1
GH
374 id = qemu_opts_id(opts);
375 if (id) {
376 qdev->id = id;
1bdaacb1 377 qdev_property_add_child(qdev_get_peripheral(), qdev->id, qdev, NULL);
8eb02831
AL
378 } else {
379 static int anon_count;
380 gchar *name = g_strdup_printf("device[%d]", anon_count++);
381 qdev_property_add_child(qdev_get_peripheral_anon(), name,
382 qdev, NULL);
383 g_free(name);
384 }
f31d07d1
GH
385 if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
386 qdev_free(qdev);
387 return NULL;
8ffb1bcf 388 }
5c17ca25 389 if (qdev_init(qdev) < 0) {
0204276b 390 qerror_report(QERR_DEVICE_INIT_FAILED, driver);
81a322d4
GH
391 return NULL;
392 }
ef80b466 393 qdev->opts = opts;
8ffb1bcf
GH
394 return qdev;
395}
396
aae9460e
PB
397/* Initialize a device. Device properties should be set before calling
398 this function. IRQs and MMIO regions should be connected/mapped after
18cfeb52
MA
399 calling this function.
400 On failure, destroy the device and return negative value.
401 Return 0 on success. */
81a322d4 402int qdev_init(DeviceState *dev)
aae9460e 403{
6e008585 404 DeviceClass *dc = DEVICE_GET_CLASS(dev);
959f733a
GH
405 int rc;
406
131ec1bd 407 assert(dev->state == DEV_STATE_CREATED);
6e008585
AL
408
409 /* FIXME hopefully this doesn't break anything */
410 rc = dc->init(dev, NULL);
18cfeb52
MA
411 if (rc < 0) {
412 qdev_free(dev);
959f733a 413 return rc;
18cfeb52 414 }
6e008585
AL
415 if (qdev_get_vmsd(dev)) {
416 vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
4d2ffa08
JK
417 dev->instance_id_alias,
418 dev->alias_required_for_version);
419 }
131ec1bd 420 dev->state = DEV_STATE_INITIALIZED;
94afdadc
AL
421 if (dev->hotplugged) {
422 device_reset(dev);
5ab28c83 423 }
959f733a 424 return 0;
02e2da45
PB
425}
426
4d2ffa08
JK
427void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
428 int required_for_version)
429{
430 assert(dev->state == DEV_STATE_CREATED);
431 dev->instance_id_alias = alias_id;
432 dev->alias_required_for_version = required_for_version;
433}
434
3418bd25
GH
435int qdev_unplug(DeviceState *dev)
436{
6e008585
AL
437 DeviceClass *dc = DEVICE_GET_CLASS(dev);
438
3418bd25 439 if (!dev->parent_bus->allow_hotplug) {
cc601cb7 440 qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
3418bd25
GH
441 return -1;
442 }
6e008585 443 assert(dc->unplug != NULL);
593831de 444
0ac8ef71
AW
445 qdev_hot_removed = true;
446
6e008585 447 return dc->unplug(dev);
3418bd25
GH
448}
449
ec990eb6
AL
450static int qdev_reset_one(DeviceState *dev, void *opaque)
451{
94afdadc 452 device_reset(dev);
ec990eb6
AL
453
454 return 0;
455}
456
457BusState *sysbus_get_default(void)
458{
68694897 459 if (!main_system_bus) {
2da8bb92 460 main_system_bus_create();
68694897 461 }
ec990eb6
AL
462 return main_system_bus;
463}
464
b4694b7c
IY
465static int qbus_reset_one(BusState *bus, void *opaque)
466{
467 if (bus->info->reset) {
468 return bus->info->reset(bus);
469 }
470 return 0;
471}
472
5af0a04b
IY
473void qdev_reset_all(DeviceState *dev)
474{
475 qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
476}
477
80376c3f
IY
478void qbus_reset_all_fn(void *opaque)
479{
480 BusState *bus = opaque;
f530cce3 481 qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
80376c3f
IY
482}
483
3418bd25
GH
484/* can be used as ->unplug() callback for the simple cases */
485int qdev_simple_unplug_cb(DeviceState *dev)
486{
487 /* just zap it */
488 qdev_free(dev);
489 return 0;
490}
491
3b29a101
MT
492
493/* Like qdev_init(), but terminate program via error_report() instead of
e23a1b33
MA
494 returning an error value. This is okay during machine creation.
495 Don't use for hotplug, because there callers need to recover from
496 failure. Exception: if you know the device's init() callback can't
497 fail, then qdev_init_nofail() can't fail either, and is therefore
498 usable even then. But relying on the device implementation that
499 way is somewhat unclean, and best avoided. */
500void qdev_init_nofail(DeviceState *dev)
501{
bd6c9a61 502 if (qdev_init(dev) < 0) {
6e008585
AL
503 error_report("Initialization of device %s failed",
504 object_get_typename(OBJECT(dev)));
bd6c9a61
MA
505 exit(1);
506 }
e23a1b33
MA
507}
508
44677ded
AL
509static void qdev_property_del_all(DeviceState *dev)
510{
511 while (!QTAILQ_EMPTY(&dev->properties)) {
512 DeviceProperty *prop = QTAILQ_FIRST(&dev->properties);
513
514 QTAILQ_REMOVE(&dev->properties, prop, node);
515
516 if (prop->release) {
517 prop->release(dev, prop->name, prop->opaque);
518 }
519
520 g_free(prop->name);
521 g_free(prop->type);
522 g_free(prop);
523 }
524}
525
024a6fbd
AL
526static void qdev_property_del_child(DeviceState *dev, DeviceState *child, Error **errp)
527{
528 DeviceProperty *prop;
529
530 QTAILQ_FOREACH(prop, &dev->properties, node) {
531 if (strstart(prop->type, "child<", NULL) && prop->opaque == child) {
532 break;
533 }
534 }
535
536 g_assert(prop != NULL);
537
538 QTAILQ_REMOVE(&dev->properties, prop, node);
539
540 if (prop->release) {
541 prop->release(dev, prop->name, prop->opaque);
542 }
543
544 g_free(prop->name);
545 g_free(prop->type);
546 g_free(prop);
547}
548
02e2da45
PB
549/* Unlink device from bus and free the structure. */
550void qdev_free(DeviceState *dev)
551{
131ec1bd 552 BusState *bus;
d21357df 553 Property *prop;
6e008585 554 DeviceClass *dc = DEVICE_GET_CLASS(dev);
131ec1bd 555
44677ded
AL
556 qdev_property_del_all(dev);
557
131ec1bd
GH
558 if (dev->state == DEV_STATE_INITIALIZED) {
559 while (dev->num_child_bus) {
560 bus = QLIST_FIRST(&dev->child_bus);
561 qbus_free(bus);
562 }
6e008585
AL
563 if (qdev_get_vmsd(dev)) {
564 vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
565 }
566 if (dc->exit) {
567 dc->exit(dev);
568 }
569 if (dev->opts) {
ef80b466 570 qemu_opts_del(dev->opts);
6e008585 571 }
131ec1bd 572 }
d8bb00d6 573 QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
6e008585 574 for (prop = qdev_get_props(dev); prop && prop->name; prop++) {
d21357df
MA
575 if (prop->info->free) {
576 prop->info->free(dev, prop);
577 }
578 }
024a6fbd
AL
579 if (dev->parent) {
580 qdev_property_del_child(dev->parent, dev, NULL);
581 }
582 if (dev->ref != 0) {
583 qerror_report(QERR_DEVICE_IN_USE, dev->id?:"");
584 }
32fea402 585 object_delete(OBJECT(dev));
aae9460e
PB
586}
587
3418bd25
GH
588void qdev_machine_creation_done(void)
589{
590 /*
591 * ok, initial machine setup is done, starting from now we can
592 * only create hotpluggable devices
593 */
594 qdev_hotplug = 1;
595}
596
0ac8ef71
AW
597bool qdev_machine_modified(void)
598{
599 return qdev_hot_added || qdev_hot_removed;
600}
601
aae9460e
PB
602/* Get a character (serial) device interface. */
603CharDriverState *qdev_init_chardev(DeviceState *dev)
604{
605 static int next_serial;
98b19252
AS
606
607 /* FIXME: This function needs to go away: use chardev properties! */
608 return serial_hds[next_serial++];
aae9460e
PB
609}
610
02e2da45 611BusState *qdev_get_parent_bus(DeviceState *dev)
aae9460e 612{
02e2da45 613 return dev->parent_bus;
aae9460e
PB
614}
615
aae9460e
PB
616void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
617{
618 assert(dev->num_gpio_in == 0);
619 dev->num_gpio_in = n;
620 dev->gpio_in = qemu_allocate_irqs(handler, dev, n);
621}
622
623void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
624{
625 assert(dev->num_gpio_out == 0);
626 dev->num_gpio_out = n;
627 dev->gpio_out = pins;
628}
629
630qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
631{
632 assert(n >= 0 && n < dev->num_gpio_in);
633 return dev->gpio_in[n];
634}
635
636void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
637{
638 assert(n >= 0 && n < dev->num_gpio_out);
639 dev->gpio_out[n] = pin;
640}
641
ed16ab5a
GH
642void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
643{
6eed1856 644 qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
ed16ab5a
GH
645 if (nd->vlan)
646 qdev_prop_set_vlan(dev, "vlan", nd->vlan);
647 if (nd->netdev)
648 qdev_prop_set_netdev(dev, "netdev", nd->netdev);
75422b0d 649 if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
97b15621
GH
650 qdev_prop_exists(dev, "vectors")) {
651 qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
652 }
48e2faf2 653 nd->instantiated = 1;
ed16ab5a
GH
654}
655
02e2da45 656BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
4d6ae674 657{
02e2da45 658 BusState *bus;
4d6ae674 659
72cf2d4f 660 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
4d6ae674 661 if (strcmp(name, bus->name) == 0) {
02e2da45 662 return bus;
4d6ae674
PB
663 }
664 }
665 return NULL;
666}
667
81699d8a
AL
668int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
669 qbus_walkerfn *busfn, void *opaque)
670{
671 DeviceState *dev;
672 int err;
673
674 if (busfn) {
675 err = busfn(bus, opaque);
676 if (err) {
677 return err;
678 }
679 }
680
d8bb00d6 681 QTAILQ_FOREACH(dev, &bus->children, sibling) {
81699d8a
AL
682 err = qdev_walk_children(dev, devfn, busfn, opaque);
683 if (err < 0) {
684 return err;
685 }
686 }
687
688 return 0;
689}
690
691int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
692 qbus_walkerfn *busfn, void *opaque)
693{
694 BusState *bus;
695 int err;
696
697 if (devfn) {
698 err = devfn(dev, opaque);
699 if (err) {
700 return err;
701 }
702 }
703
704 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
705 err = qbus_walk_children(bus, devfn, busfn, opaque);
706 if (err < 0) {
707 return err;
708 }
709 }
710
711 return 0;
712}
713
8ffb1bcf
GH
714static BusState *qbus_find_recursive(BusState *bus, const char *name,
715 const BusInfo *info)
716{
717 DeviceState *dev;
718 BusState *child, *ret;
719 int match = 1;
720
721 if (name && (strcmp(bus->name, name) != 0)) {
722 match = 0;
723 }
724 if (info && (bus->info != info)) {
725 match = 0;
726 }
727 if (match) {
728 return bus;
729 }
730
d8bb00d6 731 QTAILQ_FOREACH(dev, &bus->children, sibling) {
72cf2d4f 732 QLIST_FOREACH(child, &dev->child_bus, sibling) {
8ffb1bcf
GH
733 ret = qbus_find_recursive(child, name, info);
734 if (ret) {
735 return ret;
736 }
737 }
738 }
739 return NULL;
740}
741
a2ee6b4f 742DeviceState *qdev_find_recursive(BusState *bus, const char *id)
3418bd25
GH
743{
744 DeviceState *dev, *ret;
745 BusState *child;
746
d8bb00d6 747 QTAILQ_FOREACH(dev, &bus->children, sibling) {
3418bd25
GH
748 if (dev->id && strcmp(dev->id, id) == 0)
749 return dev;
750 QLIST_FOREACH(child, &dev->child_bus, sibling) {
751 ret = qdev_find_recursive(child, id);
752 if (ret) {
753 return ret;
754 }
755 }
756 }
757 return NULL;
758}
759
53db16b5 760static void qbus_list_bus(DeviceState *dev)
8ffb1bcf
GH
761{
762 BusState *child;
763 const char *sep = " ";
8ffb1bcf 764
53db16b5 765 error_printf("child busses at \"%s\":",
f79f2bfc 766 dev->id ? dev->id : object_get_typename(OBJECT(dev)));
72cf2d4f 767 QLIST_FOREACH(child, &dev->child_bus, sibling) {
53db16b5 768 error_printf("%s\"%s\"", sep, child->name);
8ffb1bcf
GH
769 sep = ", ";
770 }
53db16b5 771 error_printf("\n");
8ffb1bcf
GH
772}
773
53db16b5 774static void qbus_list_dev(BusState *bus)
8ffb1bcf
GH
775{
776 DeviceState *dev;
777 const char *sep = " ";
8ffb1bcf 778
53db16b5 779 error_printf("devices at \"%s\":", bus->name);
d8bb00d6 780 QTAILQ_FOREACH(dev, &bus->children, sibling) {
f79f2bfc 781 error_printf("%s\"%s\"", sep, object_get_typename(OBJECT(dev)));
8ffb1bcf 782 if (dev->id)
53db16b5 783 error_printf("/\"%s\"", dev->id);
8ffb1bcf
GH
784 sep = ", ";
785 }
53db16b5 786 error_printf("\n");
8ffb1bcf
GH
787}
788
789static BusState *qbus_find_bus(DeviceState *dev, char *elem)
790{
791 BusState *child;
792
72cf2d4f 793 QLIST_FOREACH(child, &dev->child_bus, sibling) {
8ffb1bcf
GH
794 if (strcmp(child->name, elem) == 0) {
795 return child;
796 }
797 }
798 return NULL;
799}
800
801static DeviceState *qbus_find_dev(BusState *bus, char *elem)
802{
803 DeviceState *dev;
804
805 /*
806 * try to match in order:
807 * (1) instance id, if present
808 * (2) driver name
809 * (3) driver alias, if present
810 */
d8bb00d6 811 QTAILQ_FOREACH(dev, &bus->children, sibling) {
8ffb1bcf
GH
812 if (dev->id && strcmp(dev->id, elem) == 0) {
813 return dev;
814 }
815 }
d8bb00d6 816 QTAILQ_FOREACH(dev, &bus->children, sibling) {
f79f2bfc 817 if (strcmp(object_get_typename(OBJECT(dev)), elem) == 0) {
8ffb1bcf
GH
818 return dev;
819 }
820 }
d8bb00d6 821 QTAILQ_FOREACH(dev, &bus->children, sibling) {
6e008585
AL
822 DeviceClass *dc = DEVICE_GET_CLASS(dev);
823
824 if (dc->alias && strcmp(dc->alias, elem) == 0) {
8ffb1bcf
GH
825 return dev;
826 }
827 }
828 return NULL;
829}
830
831static BusState *qbus_find(const char *path)
832{
833 DeviceState *dev;
834 BusState *bus;
53db16b5 835 char elem[128];
8ffb1bcf
GH
836 int pos, len;
837
838 /* find start element */
839 if (path[0] == '/') {
840 bus = main_system_bus;
841 pos = 0;
842 } else {
843 if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
fc98eb43
MA
844 assert(!path[0]);
845 elem[0] = len = 0;
8ffb1bcf
GH
846 }
847 bus = qbus_find_recursive(main_system_bus, elem, NULL);
848 if (!bus) {
ac8dae67 849 qerror_report(QERR_BUS_NOT_FOUND, elem);
8ffb1bcf
GH
850 return NULL;
851 }
852 pos = len;
853 }
854
855 for (;;) {
fc98eb43
MA
856 assert(path[pos] == '/' || !path[pos]);
857 while (path[pos] == '/') {
858 pos++;
859 }
8ffb1bcf 860 if (path[pos] == '\0') {
8ffb1bcf
GH
861 return bus;
862 }
863
864 /* find device */
fc98eb43
MA
865 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
866 assert(0);
867 elem[0] = len = 0;
8ffb1bcf
GH
868 }
869 pos += len;
870 dev = qbus_find_dev(bus, elem);
871 if (!dev) {
ac8dae67 872 qerror_report(QERR_DEVICE_NOT_FOUND, elem);
8bc27249
MA
873 if (!monitor_cur_is_qmp()) {
874 qbus_list_dev(bus);
875 }
8ffb1bcf
GH
876 return NULL;
877 }
fc98eb43
MA
878
879 assert(path[pos] == '/' || !path[pos]);
880 while (path[pos] == '/') {
881 pos++;
882 }
8ffb1bcf
GH
883 if (path[pos] == '\0') {
884 /* last specified element is a device. If it has exactly
885 * one child bus accept it nevertheless */
886 switch (dev->num_child_bus) {
887 case 0:
ac8dae67 888 qerror_report(QERR_DEVICE_NO_BUS, elem);
8ffb1bcf
GH
889 return NULL;
890 case 1:
72cf2d4f 891 return QLIST_FIRST(&dev->child_bus);
8ffb1bcf 892 default:
ac8dae67 893 qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
8bc27249
MA
894 if (!monitor_cur_is_qmp()) {
895 qbus_list_bus(dev);
896 }
8ffb1bcf
GH
897 return NULL;
898 }
899 }
900
901 /* find bus */
fc98eb43
MA
902 if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
903 assert(0);
904 elem[0] = len = 0;
8ffb1bcf
GH
905 }
906 pos += len;
907 bus = qbus_find_bus(dev, elem);
908 if (!bus) {
ac8dae67 909 qerror_report(QERR_BUS_NOT_FOUND, elem);
8bc27249
MA
910 if (!monitor_cur_is_qmp()) {
911 qbus_list_bus(dev);
912 }
8ffb1bcf
GH
913 return NULL;
914 }
915 }
916}
917
cd739fb6
GH
918void qbus_create_inplace(BusState *bus, BusInfo *info,
919 DeviceState *parent, const char *name)
02e2da45 920{
d271de9f
GH
921 char *buf;
922 int i,len;
02e2da45 923
10c4c98a 924 bus->info = info;
02e2da45 925 bus->parent = parent;
d271de9f
GH
926
927 if (name) {
928 /* use supplied name */
7267c094 929 bus->name = g_strdup(name);
d271de9f
GH
930 } else if (parent && parent->id) {
931 /* parent device has id -> use it for bus name */
932 len = strlen(parent->id) + 16;
7267c094 933 buf = g_malloc(len);
d271de9f
GH
934 snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
935 bus->name = buf;
936 } else {
937 /* no id -> use lowercase bus type for bus name */
938 len = strlen(info->name) + 16;
7267c094 939 buf = g_malloc(len);
d271de9f
GH
940 len = snprintf(buf, len, "%s.%d", info->name,
941 parent ? parent->num_child_bus : 0);
942 for (i = 0; i < len; i++)
bb87ece5 943 buf[i] = qemu_tolower(buf[i]);
d271de9f
GH
944 bus->name = buf;
945 }
946
d8bb00d6 947 QTAILQ_INIT(&bus->children);
02e2da45 948 if (parent) {
72cf2d4f 949 QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
d271de9f 950 parent->num_child_bus++;
80376c3f
IY
951 } else if (bus != main_system_bus) {
952 /* TODO: once all bus devices are qdevified,
953 only reset handler for main_system_bus should be registered here. */
954 qemu_register_reset(qbus_reset_all_fn, bus);
02e2da45 955 }
cd739fb6
GH
956}
957
958BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
959{
960 BusState *bus;
961
7267c094 962 bus = g_malloc0(info->size);
cd739fb6
GH
963 bus->qdev_allocated = 1;
964 qbus_create_inplace(bus, info, parent, name);
02e2da45
PB
965 return bus;
966}
cae4956e 967
2da8bb92
IY
968static void main_system_bus_create(void)
969{
970 /* assign main_system_bus before qbus_create_inplace()
971 * in order to make "if (bus != main_system_bus)" work */
7267c094 972 main_system_bus = g_malloc0(system_bus_info.size);
2da8bb92
IY
973 main_system_bus->qdev_allocated = 1;
974 qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
975 "main-system-bus");
976}
977
131ec1bd
GH
978void qbus_free(BusState *bus)
979{
980 DeviceState *dev;
981
d8bb00d6 982 while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
131ec1bd
GH
983 qdev_free(dev);
984 }
985 if (bus->parent) {
986 QLIST_REMOVE(bus, sibling);
987 bus->parent->num_child_bus--;
80376c3f
IY
988 } else {
989 assert(bus != main_system_bus); /* main_system_bus is never freed */
990 qemu_unregister_reset(qbus_reset_all_fn, bus);
131ec1bd 991 }
7267c094 992 g_free((void*)bus->name);
131ec1bd 993 if (bus->qdev_allocated) {
7267c094 994 g_free(bus);
131ec1bd
GH
995 }
996}
997
cae4956e
GH
998#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
999static void qbus_print(Monitor *mon, BusState *bus, int indent);
1000
ee6847d1
GH
1001static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
1002 const char *prefix, int indent)
1003{
1004 char buf[64];
1005
1006 if (!props)
1007 return;
1008 while (props->name) {
036f7166
MA
1009 /*
1010 * TODO Properties without a print method are just for dirty
1011 * hacks. qdev_prop_ptr is the only such PropertyInfo. It's
1012 * marked for removal. The test props->info->print should be
1013 * removed along with it.
1014 */
ee6847d1
GH
1015 if (props->info->print) {
1016 props->info->print(dev, props, buf, sizeof(buf));
1017 qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
1018 }
1019 props++;
1020 }
1021}
1022
cae4956e
GH
1023static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
1024{
cae4956e 1025 BusState *child;
f79f2bfc 1026 qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)),
ccb63de3 1027 dev->id ? dev->id : "");
cae4956e
GH
1028 indent += 2;
1029 if (dev->num_gpio_in) {
1030 qdev_printf("gpio-in %d\n", dev->num_gpio_in);
1031 }
1032 if (dev->num_gpio_out) {
1033 qdev_printf("gpio-out %d\n", dev->num_gpio_out);
1034 }
6e008585 1035 qdev_print_props(mon, dev, qdev_get_props(dev), "dev", indent);
ee6847d1 1036 qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
10c4c98a
GH
1037 if (dev->parent_bus->info->print_dev)
1038 dev->parent_bus->info->print_dev(mon, dev, indent);
72cf2d4f 1039 QLIST_FOREACH(child, &dev->child_bus, sibling) {
cae4956e
GH
1040 qbus_print(mon, child, indent);
1041 }
1042}
1043
1044static void qbus_print(Monitor *mon, BusState *bus, int indent)
1045{
1046 struct DeviceState *dev;
1047
1048 qdev_printf("bus: %s\n", bus->name);
1049 indent += 2;
10c4c98a 1050 qdev_printf("type %s\n", bus->info->name);
d8bb00d6 1051 QTAILQ_FOREACH(dev, &bus->children, sibling) {
cae4956e
GH
1052 qdev_print(mon, dev, indent);
1053 }
1054}
1055#undef qdev_printf
1056
1057void do_info_qtree(Monitor *mon)
1058{
1059 if (main_system_bus)
1060 qbus_print(mon, main_system_bus, 0);
1061}
9316d30f 1062
f6c64e0e 1063void do_info_qdm(Monitor *mon)
9316d30f 1064{
212ad111 1065 object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, NULL);
9316d30f 1066}
3418bd25 1067
8bc27249 1068int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
3418bd25
GH
1069{
1070 QemuOpts *opts;
1071
3329f07b 1072 opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict);
8bc27249
MA
1073 if (!opts) {
1074 return -1;
1075 }
1076 if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
1077 qemu_opts_del(opts);
1078 return 0;
0f853a38 1079 }
8bc27249
MA
1080 if (!qdev_device_add(opts)) {
1081 qemu_opts_del(opts);
1082 return -1;
1083 }
1084 return 0;
3418bd25
GH
1085}
1086
17a38eaa 1087int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
3418bd25
GH
1088{
1089 const char *id = qdict_get_str(qdict, "id");
1090 DeviceState *dev;
1091
1092 dev = qdev_find_recursive(main_system_bus, id);
1093 if (NULL == dev) {
17a38eaa
MA
1094 qerror_report(QERR_DEVICE_NOT_FOUND, id);
1095 return -1;
3418bd25 1096 }
17a38eaa 1097 return qdev_unplug(dev);
3418bd25 1098}
1ca4d09a
GN
1099
1100static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
1101{
1102 int l = 0;
1103
1104 if (dev && dev->parent_bus) {
1105 char *d;
1106 l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size);
1107 if (dev->parent_bus->info->get_fw_dev_path) {
1108 d = dev->parent_bus->info->get_fw_dev_path(dev);
1109 l += snprintf(p + l, size - l, "%s", d);
7267c094 1110 g_free(d);
1ca4d09a 1111 } else {
f79f2bfc 1112 l += snprintf(p + l, size - l, "%s", object_get_typename(OBJECT(dev)));
1ca4d09a
GN
1113 }
1114 }
1115 l += snprintf(p + l , size - l, "/");
1116
1117 return l;
1118}
1119
1120char* qdev_get_fw_dev_path(DeviceState *dev)
1121{
1122 char path[128];
1123 int l;
1124
1125 l = qdev_get_fw_dev_path_helper(dev, path, 128);
1126
1127 path[l-1] = '\0';
1128
1129 return strdup(path);
1130}
85ed303b 1131
cd34d667
AL
1132char *qdev_get_type(DeviceState *dev, Error **errp)
1133{
f79f2bfc 1134 return g_strdup(object_get_typename(OBJECT(dev)));
cd34d667
AL
1135}
1136
85ed303b
AL
1137void qdev_ref(DeviceState *dev)
1138{
1139 dev->ref++;
1140}
1141
1142void qdev_unref(DeviceState *dev)
1143{
1144 g_assert(dev->ref > 0);
1145 dev->ref--;
1146}
44677ded
AL
1147
1148void qdev_property_add(DeviceState *dev, const char *name, const char *type,
1149 DevicePropertyAccessor *get, DevicePropertyAccessor *set,
1150 DevicePropertyRelease *release,
1151 void *opaque, Error **errp)
1152{
1153 DeviceProperty *prop = g_malloc0(sizeof(*prop));
1154
1155 prop->name = g_strdup(name);
1156 prop->type = g_strdup(type);
1157
1158 prop->get = get;
1159 prop->set = set;
1160 prop->release = release;
1161 prop->opaque = opaque;
1162
1163 QTAILQ_INSERT_TAIL(&dev->properties, prop, node);
1164}
1165
1166static DeviceProperty *qdev_property_find(DeviceState *dev, const char *name)
1167{
1168 DeviceProperty *prop;
1169
1170 QTAILQ_FOREACH(prop, &dev->properties, node) {
1171 if (strcmp(prop->name, name) == 0) {
1172 return prop;
1173 }
1174 }
1175
1176 return NULL;
1177}
1178
1179void qdev_property_get(DeviceState *dev, Visitor *v, const char *name,
1180 Error **errp)
1181{
1182 DeviceProperty *prop = qdev_property_find(dev, name);
1183
1184 if (prop == NULL) {
1185 error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1186 return;
1187 }
1188
1189 if (!prop->get) {
1190 error_set(errp, QERR_PERMISSION_DENIED);
1191 } else {
1192 prop->get(dev, v, prop->opaque, name, errp);
1193 }
1194}
1195
1196void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
1197 Error **errp)
1198{
1199 DeviceProperty *prop = qdev_property_find(dev, name);
1200
1201 if (prop == NULL) {
1202 error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1203 return;
1204 }
1205
1206 if (!prop->set) {
1207 error_set(errp, QERR_PERMISSION_DENIED);
1208 } else {
0d41d9aa 1209 prop->set(dev, v, prop->opaque, name, errp);
44677ded
AL
1210 }
1211}
1212
1213const char *qdev_property_get_type(DeviceState *dev, const char *name, Error **errp)
1214{
1215 DeviceProperty *prop = qdev_property_find(dev, name);
1216
1217 if (prop == NULL) {
1218 error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
1219 return NULL;
1220 }
1221
1222 return prop->type;
1223}
a5296ca9
AL
1224
1225/**
1226 * Legacy property handling
1227 */
1228
1229static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1230 const char *name, Error **errp)
1231{
1232 Property *prop = opaque;
1233
e3cb6ba6
PB
1234 char buffer[1024];
1235 char *ptr = buffer;
a5296ca9 1236
e3cb6ba6
PB
1237 prop->info->print(dev, prop, buffer, sizeof(buffer));
1238 visit_type_str(v, &ptr, name, errp);
a5296ca9
AL
1239}
1240
1241static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
1242 const char *name, Error **errp)
1243{
1244 Property *prop = opaque;
e3cb6ba6
PB
1245 Error *local_err = NULL;
1246 char *ptr = NULL;
1247 int ret;
a5296ca9
AL
1248
1249 if (dev->state != DEV_STATE_CREATED) {
1250 error_set(errp, QERR_PERMISSION_DENIED);
1251 return;
1252 }
1253
e3cb6ba6
PB
1254 visit_type_str(v, &ptr, name, &local_err);
1255 if (local_err) {
1256 error_propagate(errp, local_err);
1257 return;
1258 }
a5296ca9 1259
e3cb6ba6 1260 ret = prop->info->parse(dev, prop, ptr);
7db4c4e8 1261 error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
e3cb6ba6 1262 g_free(ptr);
a5296ca9
AL
1263}
1264
1265/**
1266 * @qdev_add_legacy_property - adds a legacy property
1267 *
1268 * Do not use this is new code! Properties added through this interface will
ca2cc788 1269 * be given names and types in the "legacy" namespace.
a5296ca9
AL
1270 *
1271 * Legacy properties are always processed as strings. The format of the string
1272 * depends on the property type.
1273 */
1274void qdev_property_add_legacy(DeviceState *dev, Property *prop,
1275 Error **errp)
1276{
ca2cc788 1277 gchar *name, *type;
a5296ca9 1278
ca2cc788 1279 name = g_strdup_printf("legacy-%s", prop->name);
cafe5bdb
PB
1280 type = g_strdup_printf("legacy<%s>",
1281 prop->info->legacy_name ?: prop->info->name);
a5296ca9 1282
ca2cc788 1283 qdev_property_add(dev, name, type,
e3cb6ba6
PB
1284 prop->info->print ? qdev_get_legacy_property : NULL,
1285 prop->info->parse ? qdev_set_legacy_property : NULL,
a5296ca9
AL
1286 NULL,
1287 prop, errp);
1288
1289 g_free(type);
ca2cc788
PB
1290 g_free(name);
1291}
1292
1293/**
1294 * @qdev_property_add_static - add a @Property to a device.
1295 *
1296 * Static properties access data in a struct. The actual type of the
1297 * property and the field depends on the property type.
1298 */
1299void qdev_property_add_static(DeviceState *dev, Property *prop,
1300 Error **errp)
1301{
1302 qdev_property_add(dev, prop->name, prop->info->name,
1303 prop->info->get, prop->info->set,
1304 NULL,
1305 prop, errp);
a5296ca9 1306}
a10f07a7
AL
1307
1308DeviceState *qdev_get_root(void)
1309{
1310 static DeviceState *qdev_root;
1311
1312 if (!qdev_root) {
1313 qdev_root = qdev_create(NULL, "container");
1314 qdev_init_nofail(qdev_root);
1315 }
1316
1317 return qdev_root;
1318}
f9fbd2fd 1319
3de1c3e8
AL
1320static void qdev_get_child_property(DeviceState *dev, Visitor *v, void *opaque,
1321 const char *name, Error **errp)
1322{
1323 DeviceState *child = opaque;
1324 gchar *path;
1325
1326 path = qdev_get_canonical_path(child);
1327 visit_type_str(v, &path, name, errp);
1328 g_free(path);
1329}
1330
024a6fbd
AL
1331static void qdev_release_child_property(DeviceState *dev, const char *name,
1332 void *opaque)
1333{
1334 DeviceState *child = opaque;
1335
1336 qdev_unref(child);
1337}
1338
3de1c3e8
AL
1339void qdev_property_add_child(DeviceState *dev, const char *name,
1340 DeviceState *child, Error **errp)
1341{
1342 gchar *type;
1343
f79f2bfc 1344 type = g_strdup_printf("child<%s>", object_get_typename(OBJECT(child)));
3de1c3e8
AL
1345
1346 qdev_property_add(dev, name, type, qdev_get_child_property,
024a6fbd
AL
1347 NULL, qdev_release_child_property,
1348 child, errp);
3de1c3e8
AL
1349
1350 qdev_ref(child);
b2b6c39a
AL
1351 g_assert(child->parent == NULL);
1352 child->parent = dev;
3de1c3e8
AL
1353
1354 g_free(type);
1355}
1356
83e94fb8
AL
1357static void qdev_get_link_property(DeviceState *dev, Visitor *v, void *opaque,
1358 const char *name, Error **errp)
1359{
1360 DeviceState **child = opaque;
1361 gchar *path;
1362
1363 if (*child) {
1364 path = qdev_get_canonical_path(*child);
1365 visit_type_str(v, &path, name, errp);
1366 g_free(path);
1367 } else {
1368 path = (gchar *)"";
1369 visit_type_str(v, &path, name, errp);
1370 }
1371}
1372
1373static void qdev_set_link_property(DeviceState *dev, Visitor *v, void *opaque,
1374 const char *name, Error **errp)
1375{
1376 DeviceState **child = opaque;
1377 bool ambiguous = false;
1378 const char *type;
1379 char *path;
1380
1381 type = qdev_property_get_type(dev, name, NULL);
1382
1383 visit_type_str(v, &path, name, errp);
1384
1385 if (*child) {
1386 qdev_unref(*child);
1387 }
1388
1389 if (strcmp(path, "") != 0) {
1390 DeviceState *target;
1391
1392 target = qdev_resolve_path(path, &ambiguous);
1393 if (target) {
1394 gchar *target_type;
1395
f79f2bfc 1396 target_type = g_strdup_printf("link<%s>", object_get_typename(OBJECT(target)));
83e94fb8
AL
1397 if (strcmp(target_type, type) == 0) {
1398 *child = target;
1399 qdev_ref(target);
1400 } else {
1401 error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
1402 }
1403
1404 g_free(target_type);
1405 } else {
1406 error_set(errp, QERR_DEVICE_NOT_FOUND, path);
1407 }
1408 } else {
1409 *child = NULL;
1410 }
1411
1412 g_free(path);
1413}
1414
1415void qdev_property_add_link(DeviceState *dev, const char *name,
1416 const char *type, DeviceState **child,
1417 Error **errp)
1418{
1419 gchar *full_type;
1420
1421 full_type = g_strdup_printf("link<%s>", type);
1422
1423 qdev_property_add(dev, name, full_type,
1424 qdev_get_link_property,
1425 qdev_set_link_property,
1426 NULL, child, errp);
1427
1428 g_free(full_type);
1429}
1430
b2b6c39a 1431gchar *qdev_get_canonical_path(DeviceState *dev)
f9fbd2fd 1432{
b2b6c39a
AL
1433 DeviceState *root = qdev_get_root();
1434 char *newpath = NULL, *path = NULL;
f9fbd2fd 1435
b2b6c39a
AL
1436 while (dev != root) {
1437 DeviceProperty *prop = NULL;
f9fbd2fd 1438
b2b6c39a 1439 g_assert(dev->parent != NULL);
f9fbd2fd 1440
b2b6c39a
AL
1441 QTAILQ_FOREACH(prop, &dev->parent->properties, node) {
1442 if (!strstart(prop->type, "child<", NULL)) {
1443 continue;
1444 }
f9fbd2fd 1445
b2b6c39a
AL
1446 if (prop->opaque == dev) {
1447 if (path) {
1448 newpath = g_strdup_printf("%s/%s", prop->name, path);
1449 g_free(path);
1450 path = newpath;
1451 } else {
1452 path = g_strdup(prop->name);
1453 }
1454 break;
1455 }
f9fbd2fd
AL
1456 }
1457
b2b6c39a 1458 g_assert(prop != NULL);
f9fbd2fd 1459
b2b6c39a 1460 dev = dev->parent;
f9fbd2fd
AL
1461 }
1462
f9fbd2fd
AL
1463 newpath = g_strdup_printf("/%s", path);
1464 g_free(path);
1465
1466 return newpath;
1467}
dc45c21f
AL
1468
1469static DeviceState *qdev_resolve_abs_path(DeviceState *parent,
1470 gchar **parts,
1471 int index)
1472{
1473 DeviceProperty *prop;
1474 DeviceState *child;
1475
1476 if (parts[index] == NULL) {
1477 return parent;
1478 }
1479
1480 if (strcmp(parts[index], "") == 0) {
1481 return qdev_resolve_abs_path(parent, parts, index + 1);
1482 }
1483
1484 prop = qdev_property_find(parent, parts[index]);
1485 if (prop == NULL) {
1486 return NULL;
1487 }
1488
1489 child = NULL;
1490 if (strstart(prop->type, "link<", NULL)) {
1491 DeviceState **pchild = prop->opaque;
1492 if (*pchild) {
1493 child = *pchild;
1494 }
1495 } else if (strstart(prop->type, "child<", NULL)) {
1496 child = prop->opaque;
1497 }
1498
1499 if (!child) {
1500 return NULL;
1501 }
1502
1503 return qdev_resolve_abs_path(child, parts, index + 1);
1504}
1505
1506static DeviceState *qdev_resolve_partial_path(DeviceState *parent,
1507 gchar **parts,
1508 bool *ambiguous)
1509{
1510 DeviceState *dev;
1511 DeviceProperty *prop;
1512
1513 dev = qdev_resolve_abs_path(parent, parts, 0);
1514
1515 QTAILQ_FOREACH(prop, &parent->properties, node) {
1516 DeviceState *found;
1517
1518 if (!strstart(prop->type, "child<", NULL)) {
1519 continue;
1520 }
1521
1522 found = qdev_resolve_partial_path(prop->opaque, parts, ambiguous);
1523 if (found) {
1524 if (dev) {
1525 if (ambiguous) {
1526 *ambiguous = true;
1527 }
1528 return NULL;
1529 }
1530 dev = found;
1531 }
1532
1533 if (ambiguous && *ambiguous) {
1534 return NULL;
1535 }
1536 }
1537
1538 return dev;
1539}
1540
1541DeviceState *qdev_resolve_path(const char *path, bool *ambiguous)
1542{
1543 bool partial_path = true;
1544 DeviceState *dev;
1545 gchar **parts;
1546
1547 parts = g_strsplit(path, "/", 0);
1548 if (parts == NULL || parts[0] == NULL) {
1549 g_strfreev(parts);
1550 return qdev_get_root();
1551 }
1552
1553 if (strcmp(parts[0], "") == 0) {
1554 partial_path = false;
1555 }
1556
1557 if (partial_path) {
1558 if (ambiguous) {
1559 *ambiguous = false;
1560 }
1561 dev = qdev_resolve_partial_path(qdev_get_root(), parts, ambiguous);
1562 } else {
1563 dev = qdev_resolve_abs_path(qdev_get_root(), parts, 1);
1564 }
1565
1566 g_strfreev(parts);
1567
1568 return dev;
1569}
1570
6a146eba
AL
1571typedef struct StringProperty
1572{
1573 char *(*get)(DeviceState *, Error **);
1574 void (*set)(DeviceState *, const char *, Error **);
1575} StringProperty;
1576
1577static void qdev_property_get_str(DeviceState *dev, Visitor *v, void *opaque,
1578 const char *name, Error **errp)
1579{
1580 StringProperty *prop = opaque;
1581 char *value;
1582
1583 value = prop->get(dev, errp);
1584 if (value) {
1585 visit_type_str(v, &value, name, errp);
1586 g_free(value);
1587 }
1588}
1589
1590static void qdev_property_set_str(DeviceState *dev, Visitor *v, void *opaque,
1591 const char *name, Error **errp)
1592{
1593 StringProperty *prop = opaque;
1594 char *value;
1595 Error *local_err = NULL;
1596
1597 visit_type_str(v, &value, name, &local_err);
1598 if (local_err) {
1599 error_propagate(errp, local_err);
1600 return;
1601 }
1602
1603 prop->set(dev, value, errp);
1604 g_free(value);
1605}
1606
1607static void qdev_property_release_str(DeviceState *dev, const char *name,
1608 void *opaque)
1609{
1610 StringProperty *prop = opaque;
1611 g_free(prop);
1612}
1613
1614void qdev_property_add_str(DeviceState *dev, const char *name,
1615 char *(*get)(DeviceState *, Error **),
1616 void (*set)(DeviceState *, const char *, Error **),
1617 Error **errp)
1618{
1619 StringProperty *prop = g_malloc0(sizeof(*prop));
1620
1621 prop->get = get;
1622 prop->set = set;
1623
1624 qdev_property_add(dev, name, "string",
1625 get ? qdev_property_get_str : NULL,
1626 set ? qdev_property_set_str : NULL,
1627 qdev_property_release_str,
1628 prop, errp);
1629}
1de81d28
AL
1630
1631void qdev_machine_init(void)
1632{
1633 qdev_get_peripheral_anon();
1634 qdev_get_peripheral();
1635}
32fea402 1636
94afdadc
AL
1637void device_reset(DeviceState *dev)
1638{
1639 DeviceClass *klass = DEVICE_GET_CLASS(dev);
1640
1641 if (klass->reset) {
1642 klass->reset(dev);
1643 }
1644}
1645
32fea402
AL
1646static TypeInfo device_type_info = {
1647 .name = TYPE_DEVICE,
1648 .parent = TYPE_OBJECT,
1649 .instance_size = sizeof(DeviceState),
1650 .abstract = true,
1651 .class_size = sizeof(DeviceClass),
1652};
1653
1654static void init_qdev(void)
1655{
1656 type_register_static(&device_type_info);
1657}
1658
1659device_init(init_qdev);