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