]> git.ipfire.org Git - thirdparty/qemu.git/blame - hw/core/qdev.c
qdev: set properties with device_class_set_props()
[thirdparty/qemu.git] / hw / core / 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
18c86e2b 28#include "qemu/osdep.h"
e688df6b 29#include "qapi/error.h"
c577ff62 30#include "qapi/qapi-events-qdev.h"
b4a42f81 31#include "qapi/qmp/qerror.h"
7b1b5d19 32#include "qapi/visitor.h"
d49b6836 33#include "qemu/error-report.h"
922a01a0 34#include "qemu/option.h"
0ee4de6c 35#include "hw/hotplug.h"
64552b6b 36#include "hw/irq.h"
a27bd6c7 37#include "hw/qdev-properties.h"
b7454548 38#include "hw/boards.h"
7474f1be 39#include "hw/sysbus.h"
d6454270 40#include "migration/vmstate.h"
aae9460e 41
9bed84c1 42bool qdev_hotplug = false;
0ac8ef71 43static bool qdev_hot_added = false;
21def24a 44bool qdev_hot_removed = false;
3418bd25 45
4be9f0d1
AL
46const VMStateDescription *qdev_get_vmsd(DeviceState *dev)
47{
6e008585
AL
48 DeviceClass *dc = DEVICE_GET_CLASS(dev);
49 return dc->vmsd;
4be9f0d1
AL
50}
51
0866aca1 52static void bus_remove_child(BusState *bus, DeviceState *child)
0c17542d 53{
0866aca1
AL
54 BusChild *kid;
55
56 QTAILQ_FOREACH(kid, &bus->children, sibling) {
57 if (kid->child == child) {
58 char name[32];
59
60 snprintf(name, sizeof(name), "child[%d]", kid->index);
61 QTAILQ_REMOVE(&bus->children, kid, sibling);
9d127820 62
12b2e9f3
TK
63 bus->num_children--;
64
9d127820 65 /* This gives back ownership of kid->child back to us. */
0866aca1 66 object_property_del(OBJECT(bus), name, NULL);
9d127820 67 object_unref(OBJECT(kid->child));
0866aca1
AL
68 g_free(kid);
69 return;
70 }
71 }
72}
73
74static void bus_add_child(BusState *bus, DeviceState *child)
75{
76 char name[32];
77 BusChild *kid = g_malloc0(sizeof(*kid));
0c17542d 78
12b2e9f3 79 bus->num_children++;
0866aca1
AL
80 kid->index = bus->max_index++;
81 kid->child = child;
9d127820 82 object_ref(OBJECT(kid->child));
a5296ca9 83
0866aca1
AL
84 QTAILQ_INSERT_HEAD(&bus->children, kid, sibling);
85
9d127820 86 /* This transfers ownership of kid->child to the property. */
0866aca1
AL
87 snprintf(name, sizeof(name), "child[%d]", kid->index);
88 object_property_add_link(OBJECT(bus), name,
89 object_get_typename(OBJECT(child)),
39f72ef9
SH
90 (Object **)&kid->child,
91 NULL, /* read-only property */
92 0, /* return ownership on prop deletion */
93 NULL);
0866aca1
AL
94}
95
96void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
97{
91c968ac
PM
98 bool replugging = dev->parent_bus != NULL;
99
100 if (replugging) {
101 /* Keep a reference to the device while it's not plugged into
102 * any bus, to avoid it potentially evaporating when it is
103 * dereffed in bus_remove_child().
104 */
105 object_ref(OBJECT(dev));
106 bus_remove_child(dev->parent_bus, dev);
107 object_unref(OBJECT(dev->parent_bus));
108 }
9fbe6127 109 dev->parent_bus = bus;
62d7ba66 110 object_ref(OBJECT(bus));
0866aca1 111 bus_add_child(bus, dev);
91c968ac
PM
112 if (replugging) {
113 object_unref(OBJECT(dev));
114 }
0c17542d
MA
115}
116
0210afe6
MA
117/* Create a new device. This only initializes the device state
118 structure and allows properties to be set. The device still needs
119 to be realized. See qdev-core.h. */
02e2da45 120DeviceState *qdev_create(BusState *bus, const char *name)
0bcdeda7
BS
121{
122 DeviceState *dev;
123
124 dev = qdev_try_create(bus, name);
125 if (!dev) {
e92714c7 126 if (bus) {
312fd5f2 127 error_report("Unknown device '%s' for bus '%s'", name,
23e3fbec 128 object_get_typename(OBJECT(bus)));
e92714c7 129 } else {
312fd5f2 130 error_report("Unknown device '%s' for default sysbus", name);
e92714c7 131 }
01ed1d52 132 abort();
0bcdeda7
BS
133 }
134
135 return dev;
136}
137
da57febf 138DeviceState *qdev_try_create(BusState *bus, const char *type)
aae9460e 139{
9fbe6127
AL
140 DeviceState *dev;
141
da57febf 142 if (object_class_by_name(type) == NULL) {
4ed658ca
AF
143 return NULL;
144 }
da57febf 145 dev = DEVICE(object_new(type));
9fbe6127
AL
146 if (!dev) {
147 return NULL;
148 }
149
10c4c98a 150 if (!bus) {
7474f1be
PM
151 /* Assert that the device really is a SysBusDevice before
152 * we put it onto the sysbus. Non-sysbus devices which aren't
153 * being put onto a bus should be created with object_new(TYPE_FOO),
154 * not qdev_create(NULL, TYPE_FOO).
155 */
156 g_assert(object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE));
68694897 157 bus = sysbus_get_default();
10c4c98a
GH
158 }
159
9fbe6127 160 qdev_set_parent_bus(dev, bus);
b09995ae 161 object_unref(OBJECT(dev));
9fbe6127 162 return dev;
aae9460e
PB
163}
164
eae3eb3e 165static QTAILQ_HEAD(, DeviceListener) device_listeners
707ff800
PD
166 = QTAILQ_HEAD_INITIALIZER(device_listeners);
167
168enum ListenerDirection { Forward, Reverse };
169
170#define DEVICE_LISTENER_CALL(_callback, _direction, _args...) \
171 do { \
172 DeviceListener *_listener; \
173 \
174 switch (_direction) { \
175 case Forward: \
176 QTAILQ_FOREACH(_listener, &device_listeners, link) { \
177 if (_listener->_callback) { \
178 _listener->_callback(_listener, ##_args); \
179 } \
180 } \
181 break; \
182 case Reverse: \
183 QTAILQ_FOREACH_REVERSE(_listener, &device_listeners, \
eae3eb3e 184 link) { \
707ff800
PD
185 if (_listener->_callback) { \
186 _listener->_callback(_listener, ##_args); \
187 } \
188 } \
189 break; \
190 default: \
191 abort(); \
192 } \
193 } while (0)
194
195static int device_listener_add(DeviceState *dev, void *opaque)
196{
197 DEVICE_LISTENER_CALL(realize, Forward, dev);
198
199 return 0;
200}
201
202void device_listener_register(DeviceListener *listener)
203{
204 QTAILQ_INSERT_TAIL(&device_listeners, listener, link);
205
206 qbus_walk_children(sysbus_get_default(), NULL, NULL, device_listener_add,
207 NULL, NULL);
208}
209
210void device_listener_unregister(DeviceListener *listener)
211{
212 QTAILQ_REMOVE(&device_listeners, listener, link);
213}
214
f3a85056
JF
215bool qdev_should_hide_device(QemuOpts *opts)
216{
217 int rc = -1;
218 DeviceListener *listener;
219
220 QTAILQ_FOREACH(listener, &device_listeners, link) {
221 if (listener->should_be_hidden) {
222 /*
223 * should_be_hidden_will return
224 * 1 if device matches opts and it should be hidden
225 * 0 if device matches opts and should not be hidden
226 * -1 if device doesn't match ops
227 */
228 rc = listener->should_be_hidden(listener, opts);
229 }
230
231 if (rc > 0) {
232 break;
233 }
234 }
235
236 return rc > 0;
237}
238
4d2ffa08
JK
239void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
240 int required_for_version)
241{
7983c8a3 242 assert(!dev->realized);
4d2ffa08
JK
243 dev->instance_id_alias = alias_id;
244 dev->alias_required_for_version = required_for_version;
245}
246
03fcbd9d
TH
247HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
248{
249 MachineState *machine;
250 MachineClass *mc;
251 Object *m_obj = qdev_get_machine();
252
253 if (object_dynamic_cast(m_obj, TYPE_MACHINE)) {
254 machine = MACHINE(m_obj);
255 mc = MACHINE_GET_CLASS(machine);
256 if (mc->get_hotplug_handler) {
257 return mc->get_hotplug_handler(machine, dev);
258 }
259 }
260
261 return NULL;
262}
263
d2321d31
PX
264bool qdev_hotplug_allowed(DeviceState *dev, Error **errp)
265{
266 MachineState *machine;
267 MachineClass *mc;
268 Object *m_obj = qdev_get_machine();
269
270 if (object_dynamic_cast(m_obj, TYPE_MACHINE)) {
271 machine = MACHINE(m_obj);
272 mc = MACHINE_GET_CLASS(machine);
273 if (mc->hotplug_allowed) {
274 return mc->hotplug_allowed(machine, dev, errp);
275 }
276 }
277
278 return true;
279}
280
14405c27
DH
281HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev)
282{
283 if (dev->parent_bus) {
284 return dev->parent_bus->hotplug_handler;
285 }
286 return NULL;
287}
288
c06b2ffb 289HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
7716b8ca 290{
17cc0128 291 HotplugHandler *hotplug_ctrl = qdev_get_machine_hotplug_handler(dev);
7716b8ca 292
17cc0128 293 if (hotplug_ctrl == NULL && dev->parent_bus) {
14405c27 294 hotplug_ctrl = qdev_get_bus_hotplug_handler(dev);
7716b8ca
IM
295 }
296 return hotplug_ctrl;
297}
298
ec990eb6
AL
299static int qdev_reset_one(DeviceState *dev, void *opaque)
300{
94afdadc 301 device_reset(dev);
ec990eb6
AL
302
303 return 0;
304}
305
b4694b7c
IY
306static int qbus_reset_one(BusState *bus, void *opaque)
307{
0d936928
AL
308 BusClass *bc = BUS_GET_CLASS(bus);
309 if (bc->reset) {
dcc20931 310 bc->reset(bus);
b4694b7c
IY
311 }
312 return 0;
313}
314
5af0a04b
IY
315void qdev_reset_all(DeviceState *dev)
316{
dcc20931 317 qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
5af0a04b
IY
318}
319
ff8de075
DH
320void qdev_reset_all_fn(void *opaque)
321{
322 qdev_reset_all(DEVICE(opaque));
323}
324
d0508c36
PB
325void qbus_reset_all(BusState *bus)
326{
dcc20931 327 qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
d0508c36
PB
328}
329
80376c3f
IY
330void qbus_reset_all_fn(void *opaque)
331{
332 BusState *bus = opaque;
d0508c36 333 qbus_reset_all(bus);
80376c3f
IY
334}
335
3418bd25 336/* can be used as ->unplug() callback for the simple cases */
014176f9
IM
337void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
338 DeviceState *dev, Error **errp)
339{
07578b0a 340 object_property_set_bool(OBJECT(dev), false, "realized", NULL);
014176f9 341}
3b29a101 342
0210afe6
MA
343/*
344 * Realize @dev.
345 * Device properties should be set before calling this function. IRQs
346 * and MMIO regions should be connected/mapped after calling this
347 * function.
348 * On failure, report an error with error_report() and terminate the
349 * program. This is okay during machine creation. Don't use for
350 * hotplug, because there callers need to recover from failure.
351 * Exception: if you know the device's init() callback can't fail,
352 * then qdev_init_nofail() can't fail either, and is therefore usable
353 * even then. But relying on the device implementation that way is
354 * somewhat unclean, and best avoided.
355 */
e23a1b33
MA
356void qdev_init_nofail(DeviceState *dev)
357{
c4bacafb 358 Error *err = NULL;
7de3abe5 359
c4bacafb
MA
360 assert(!dev->realized);
361
0d4104e5 362 object_ref(OBJECT(dev));
c4bacafb
MA
363 object_property_set_bool(OBJECT(dev), true, "realized", &err);
364 if (err) {
c29b77f9
MA
365 error_reportf_err(err, "Initialization of device %s failed: ",
366 object_get_typename(OBJECT(dev)));
bd6c9a61
MA
367 exit(1);
368 }
0d4104e5 369 object_unref(OBJECT(dev));
e23a1b33
MA
370}
371
3418bd25
GH
372void qdev_machine_creation_done(void)
373{
374 /*
375 * ok, initial machine setup is done, starting from now we can
376 * only create hotpluggable devices
377 */
9bed84c1 378 qdev_hotplug = true;
3418bd25
GH
379}
380
0ac8ef71
AW
381bool qdev_machine_modified(void)
382{
383 return qdev_hot_added || qdev_hot_removed;
384}
385
02e2da45 386BusState *qdev_get_parent_bus(DeviceState *dev)
aae9460e 387{
02e2da45 388 return dev->parent_bus;
aae9460e
PB
389}
390
a5f54290
PC
391static NamedGPIOList *qdev_get_named_gpio_list(DeviceState *dev,
392 const char *name)
393{
394 NamedGPIOList *ngl;
395
396 QLIST_FOREACH(ngl, &dev->gpios, node) {
3a87dde8
MAL
397 /* NULL is a valid and matchable name. */
398 if (g_strcmp0(name, ngl->name) == 0) {
a5f54290
PC
399 return ngl;
400 }
401 }
402
403 ngl = g_malloc0(sizeof(*ngl));
404 ngl->name = g_strdup(name);
405 QLIST_INSERT_HEAD(&dev->gpios, ngl, node);
406 return ngl;
407}
408
4a151677
PM
409void qdev_init_gpio_in_named_with_opaque(DeviceState *dev,
410 qemu_irq_handler handler,
411 void *opaque,
412 const char *name, int n)
a5f54290 413{
a69bef1c 414 int i;
a5f54290
PC
415 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
416
b235a71f 417 assert(gpio_list->num_out == 0 || !name);
a5f54290 418 gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler,
4a151677 419 opaque, n);
a69bef1c 420
6c76b377
PF
421 if (!name) {
422 name = "unnamed-gpio-in";
423 }
a69bef1c 424 for (i = gpio_list->num_in; i < gpio_list->num_in + n; i++) {
6c76b377
PF
425 gchar *propname = g_strdup_printf("%s[%u]", name, i);
426
a69bef1c
PC
427 object_property_add_child(OBJECT(dev), propname,
428 OBJECT(gpio_list->in[i]), &error_abort);
6c76b377 429 g_free(propname);
a69bef1c 430 }
a69bef1c 431
a5f54290
PC
432 gpio_list->num_in += n;
433}
434
aae9460e
PB
435void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
436{
a5f54290
PC
437 qdev_init_gpio_in_named(dev, handler, NULL, n);
438}
439
440void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins,
441 const char *name, int n)
442{
688b057a 443 int i;
a5f54290
PC
444 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
445
b235a71f 446 assert(gpio_list->num_in == 0 || !name);
688b057a 447
6c76b377
PF
448 if (!name) {
449 name = "unnamed-gpio-out";
450 }
451 memset(pins, 0, sizeof(*pins) * n);
688b057a 452 for (i = 0; i < n; ++i) {
6c76b377
PF
453 gchar *propname = g_strdup_printf("%s[%u]", name,
454 gpio_list->num_out + i);
455
688b057a
PC
456 object_property_add_link(OBJECT(dev), propname, TYPE_IRQ,
457 (Object **)&pins[i],
458 object_property_allow_set_link,
265b578c 459 OBJ_PROP_LINK_STRONG,
688b057a 460 &error_abort);
6c76b377 461 g_free(propname);
688b057a 462 }
6c76b377 463 gpio_list->num_out += n;
aae9460e
PB
464}
465
466void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
467{
a5f54290
PC
468 qdev_init_gpio_out_named(dev, pins, NULL, n);
469}
470
471qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n)
472{
473 NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
474
475 assert(n >= 0 && n < gpio_list->num_in);
476 return gpio_list->in[n];
aae9460e
PB
477}
478
479qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)
480{
a5f54290
PC
481 return qdev_get_gpio_in_named(dev, NULL, n);
482}
483
484void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n,
485 qemu_irq pin)
486{
02757df2
PC
487 char *propname = g_strdup_printf("%s[%d]",
488 name ? name : "unnamed-gpio-out", n);
489 if (pin) {
490 /* We need a name for object_property_set_link to work. If the
491 * object has a parent, object_property_add_child will come back
492 * with an error without doing anything. If it has none, it will
493 * never fail. So we can just call it with a NULL Error pointer.
494 */
88950eef
AF
495 object_property_add_child(container_get(qdev_get_machine(),
496 "/unattached"),
497 "non-qdev-gpio[*]", OBJECT(pin), NULL);
02757df2
PC
498 }
499 object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort);
500 g_free(propname);
aae9460e
PB
501}
502
b7973186
AG
503qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n)
504{
505 char *propname = g_strdup_printf("%s[%d]",
506 name ? name : "unnamed-gpio-out", n);
507
508 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
509 NULL);
510
511 return ret;
512}
513
67cc32eb 514/* disconnect a GPIO output, returning the disconnected input (if any) */
0c24db2b
PC
515
516static qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev,
517 const char *name, int n)
518{
519 char *propname = g_strdup_printf("%s[%d]",
520 name ? name : "unnamed-gpio-out", n);
521
522 qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
523 NULL);
524 if (ret) {
525 object_property_set_link(OBJECT(dev), NULL, propname, NULL);
526 }
527 g_free(propname);
528 return ret;
529}
a5f54290 530
0c24db2b
PC
531qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt,
532 const char *name, int n)
533{
534 qemu_irq disconnected = qdev_disconnect_gpio_out_named(dev, name, n);
535 qdev_connect_gpio_out_named(dev, name, n, icpt);
536 return disconnected;
aae9460e
PB
537}
538
539void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
540{
a5f54290 541 qdev_connect_gpio_out_named(dev, NULL, n, pin);
aae9460e
PB
542}
543
17a96a14
PC
544void qdev_pass_gpios(DeviceState *dev, DeviceState *container,
545 const char *name)
546{
547 int i;
548 NamedGPIOList *ngl = qdev_get_named_gpio_list(dev, name);
549
550 for (i = 0; i < ngl->num_in; i++) {
551 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-in";
552 char *propname = g_strdup_printf("%s[%d]", nm, i);
553
554 object_property_add_alias(OBJECT(container), propname,
555 OBJECT(dev), propname,
556 &error_abort);
6bc5cf92 557 g_free(propname);
17a96a14
PC
558 }
559 for (i = 0; i < ngl->num_out; i++) {
560 const char *nm = ngl->name ? ngl->name : "unnamed-gpio-out";
561 char *propname = g_strdup_printf("%s[%d]", nm, i);
562
563 object_property_add_alias(OBJECT(container), propname,
564 OBJECT(dev), propname,
565 &error_abort);
6bc5cf92 566 g_free(propname);
17a96a14
PC
567 }
568 QLIST_REMOVE(ngl, node);
569 QLIST_INSERT_HEAD(&container->gpios, ngl, node);
570}
571
02e2da45 572BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
4d6ae674 573{
02e2da45 574 BusState *bus;
f698c8ba
PC
575 Object *child = object_resolve_path_component(OBJECT(dev), name);
576
577 bus = (BusState *)object_dynamic_cast(child, TYPE_BUS);
578 if (bus) {
579 return bus;
580 }
4d6ae674 581
72cf2d4f 582 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
4d6ae674 583 if (strcmp(name, bus->name) == 0) {
02e2da45 584 return bus;
4d6ae674
PB
585 }
586 }
587 return NULL;
588}
589
0293214b
PB
590int qdev_walk_children(DeviceState *dev,
591 qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
592 qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
593 void *opaque)
81699d8a
AL
594{
595 BusState *bus;
596 int err;
597
0293214b
PB
598 if (pre_devfn) {
599 err = pre_devfn(dev, opaque);
81699d8a
AL
600 if (err) {
601 return err;
602 }
603 }
604
605 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
0293214b
PB
606 err = qbus_walk_children(bus, pre_devfn, pre_busfn,
607 post_devfn, post_busfn, opaque);
81699d8a
AL
608 if (err < 0) {
609 return err;
610 }
611 }
612
0293214b
PB
613 if (post_devfn) {
614 err = post_devfn(dev, opaque);
615 if (err) {
616 return err;
617 }
618 }
619
81699d8a
AL
620 return 0;
621}
622
a2ee6b4f 623DeviceState *qdev_find_recursive(BusState *bus, const char *id)
3418bd25 624{
0866aca1
AL
625 BusChild *kid;
626 DeviceState *ret;
3418bd25
GH
627 BusState *child;
628
0866aca1
AL
629 QTAILQ_FOREACH(kid, &bus->children, sibling) {
630 DeviceState *dev = kid->child;
631
632 if (dev->id && strcmp(dev->id, id) == 0) {
3418bd25 633 return dev;
0866aca1
AL
634 }
635
3418bd25
GH
636 QLIST_FOREACH(child, &dev->child_bus, sibling) {
637 ret = qdev_find_recursive(child, id);
638 if (ret) {
639 return ret;
640 }
641 }
642 }
643 return NULL;
644}
645
09e5ab63 646char *qdev_get_dev_path(DeviceState *dev)
85ed303b 647{
0d936928 648 BusClass *bc;
09e5ab63
AL
649
650 if (!dev || !dev->parent_bus) {
651 return NULL;
652 }
653
0d936928
AL
654 bc = BUS_GET_CLASS(dev->parent_bus);
655 if (bc->get_dev_path) {
656 return bc->get_dev_path(dev);
09e5ab63
AL
657 }
658
659 return NULL;
44677ded 660}
a5296ca9
AL
661
662/**
663 * Legacy property handling
664 */
665
d7bce999
EB
666static void qdev_get_legacy_property(Object *obj, Visitor *v,
667 const char *name, void *opaque,
668 Error **errp)
a5296ca9 669{
57c9fafe 670 DeviceState *dev = DEVICE(obj);
a5296ca9
AL
671 Property *prop = opaque;
672
e3cb6ba6
PB
673 char buffer[1024];
674 char *ptr = buffer;
a5296ca9 675
e3cb6ba6 676 prop->info->print(dev, prop, buffer, sizeof(buffer));
51e72bc1 677 visit_type_str(v, name, &ptr, errp);
a5296ca9
AL
678}
679
a5296ca9 680/**
d9d8d452
C
681 * qdev_property_add_legacy:
682 * @dev: Device to add the property to.
683 * @prop: The qdev property definition.
684 * @errp: location to store error information.
685 *
686 * Add a legacy QOM property to @dev for qdev property @prop.
687 * On error, store error in @errp.
a5296ca9 688 *
d9d8d452
C
689 * Legacy properties are string versions of QOM properties. The format of
690 * the string depends on the property type. Legacy properties are only
691 * needed for "info qtree".
a5296ca9 692 *
6871a0d0 693 * Do not use this in new code! QOM Properties added through this interface
d9d8d452 694 * will be given names in the "legacy" namespace.
a5296ca9 695 */
f5a014d2
SW
696static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
697 Error **errp)
a5296ca9 698{
7ce7ffe0 699 gchar *name;
a5296ca9 700
f3be016d 701 /* Register pointer properties as legacy properties */
03ff7770 702 if (!prop->info->print && prop->info->get) {
68ee3569
PB
703 return;
704 }
f3be016d 705
faabdbb7
FZ
706 if (prop->info->create) {
707 return;
708 }
709
ca2cc788 710 name = g_strdup_printf("legacy-%s", prop->name);
7ce7ffe0 711 object_property_add(OBJECT(dev), name, "str",
68ee3569 712 prop->info->print ? qdev_get_legacy_property : prop->info->get,
03ff7770 713 NULL,
57c9fafe
AL
714 NULL,
715 prop, errp);
a5296ca9 716
ca2cc788
PB
717 g_free(name);
718}
719
94d912d1 720void qdev_property_add_static(DeviceState *dev, Property *prop)
ca2cc788 721{
fdae245f
PB
722 Object *obj = OBJECT(dev);
723
faabdbb7 724 if (prop->info->create) {
94d912d1 725 prop->info->create(obj, prop, &error_abort);
faabdbb7 726 } else {
faabdbb7
FZ
727 object_property_add(obj, prop->name, prop->info->name,
728 prop->info->get, prop->info->set,
729 prop->info->release,
94d912d1 730 prop, &error_abort);
fdae245f 731 }
b8c9cd5c
GA
732
733 object_property_set_description(obj, prop->name,
734 prop->info->description,
735 &error_abort);
736
5cc56cc6 737 if (prop->set_default) {
a2740ad5 738 prop->info->set_default_value(obj, prop);
fdae245f 739 }
6a146eba 740}
1de81d28 741
67cc7e0a
SH
742/* @qdev_alias_all_properties - Add alias properties to the source object for
743 * all qdev properties on the target DeviceState.
744 */
745void qdev_alias_all_properties(DeviceState *target, Object *source)
746{
747 ObjectClass *class;
748 Property *prop;
749
750 class = object_get_class(OBJECT(target));
751 do {
752 DeviceClass *dc = DEVICE_CLASS(class);
753
754 for (prop = dc->props; prop && prop->name; prop++) {
755 object_property_add_alias(source, prop->name,
756 OBJECT(target), prop->name,
757 &error_abort);
758 }
759 class = object_class_get_parent(class);
760 } while (class != object_class_by_name(TYPE_DEVICE));
761}
762
a7737e44 763static bool device_get_realized(Object *obj, Error **errp)
249d4172
AF
764{
765 DeviceState *dev = DEVICE(obj);
766 return dev->realized;
767}
768
40f03bd5 769static bool check_only_migratable(Object *obj, Error **errp)
1bfe5f05
JQ
770{
771 DeviceClass *dc = DEVICE_GET_CLASS(obj);
772
773 if (!vmstate_check_only_migratable(dc->vmsd)) {
40f03bd5 774 error_setg(errp, "Device %s is not migratable, but "
1bfe5f05
JQ
775 "--only-migratable was specified",
776 object_get_typename(obj));
777 return false;
778 }
779
780 return true;
781}
782
a7737e44 783static void device_set_realized(Object *obj, bool value, Error **errp)
249d4172
AF
784{
785 DeviceState *dev = DEVICE(obj);
786 DeviceClass *dc = DEVICE_GET_CLASS(dev);
7716b8ca 787 HotplugHandler *hotplug_ctrl;
5c21ce77 788 BusState *bus;
249d4172 789 Error *local_err = NULL;
69382d8b
IM
790 bool unattached_parent = false;
791 static int unattached_count;
249d4172 792
1a37eca1 793 if (dev->hotplugged && !dc->hotpluggable) {
c6bd8c70 794 error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
1a37eca1
IM
795 return;
796 }
797
249d4172 798 if (value && !dev->realized) {
1bfe5f05 799 if (!check_only_migratable(obj, &local_err)) {
7562f907
AA
800 goto fail;
801 }
802
d578029e 803 if (!obj->parent) {
249d4172
AF
804 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
805
806 object_property_add_child(container_get(qdev_get_machine(),
807 "/unattached"),
d578029e 808 name, obj, &error_abort);
69382d8b 809 unattached_parent = true;
249d4172
AF
810 g_free(name);
811 }
812
41346263
IM
813 hotplug_ctrl = qdev_get_hotplug_handler(dev);
814 if (hotplug_ctrl) {
815 hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err);
816 if (local_err != NULL) {
817 goto fail;
818 }
819 }
820
a7ddba52
IM
821 if (dc->realize) {
822 dc->realize(dev, &local_err);
40f03bd5
VSO
823 if (local_err != NULL) {
824 goto fail;
825 }
1d45a705
GA
826 }
827
707ff800
PD
828 DEVICE_LISTENER_CALL(realize, Forward, dev);
829
04162f8f
MR
830 /*
831 * always free/re-initialize here since the value cannot be cleaned up
832 * in device_unrealize due to its usage later on in the unplug path
833 */
834 g_free(dev->canonical_path);
835 dev->canonical_path = object_get_canonical_path(OBJECT(dev));
836
1d45a705 837 if (qdev_get_vmsd(dev)) {
3cad405b 838 if (vmstate_register_with_alias_id(VMSTATE_IF(dev),
1df2c9a2
PX
839 VMSTATE_INSTANCE_ID_ANY,
840 qdev_get_vmsd(dev), dev,
67980031
DDAG
841 dev->instance_id_alias,
842 dev->alias_required_for_version,
843 &local_err) < 0) {
844 goto post_realize_fail;
845 }
249d4172 846 }
1d45a705
GA
847
848 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
849 object_property_set_bool(OBJECT(bus), true, "realized",
5c21ce77 850 &local_err);
1d45a705
GA
851 if (local_err != NULL) {
852 goto child_realize_fail;
5c21ce77
BD
853 }
854 }
1d45a705 855 if (dev->hotplugged) {
249d4172
AF
856 device_reset(dev);
857 }
352e8da7 858 dev->pending_deleted_event = false;
25e89788
SH
859
860 if (hotplug_ctrl) {
8b5e6caf
IM
861 hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
862 if (local_err != NULL) {
863 goto child_realize_fail;
864 }
865 }
866
249d4172 867 } else if (!value && dev->realized) {
40f03bd5 868 /* We want local_err to track only the first error */
5c21ce77
BD
869 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
870 object_property_set_bool(OBJECT(bus), false, "realized",
40f03bd5 871 local_err ? NULL : &local_err);
5c21ce77 872 }
cd4520ad 873 if (qdev_get_vmsd(dev)) {
3cad405b 874 vmstate_unregister(VMSTATE_IF(dev), qdev_get_vmsd(dev), dev);
fe6c2117 875 }
cd4520ad 876 if (dc->unrealize) {
40f03bd5 877 dc->unrealize(dev, local_err ? NULL : &local_err);
249d4172 878 }
352e8da7 879 dev->pending_deleted_event = true;
707ff800 880 DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
249d4172 881
40f03bd5
VSO
882 if (local_err != NULL) {
883 goto fail;
884 }
249d4172
AF
885 }
886
40f03bd5 887 assert(local_err == NULL);
c7f8d0f3 888 dev->realized = value;
1d45a705
GA
889 return;
890
891child_realize_fail:
892 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
893 object_property_set_bool(OBJECT(bus), false, "realized",
894 NULL);
895 }
896
897 if (qdev_get_vmsd(dev)) {
3cad405b 898 vmstate_unregister(VMSTATE_IF(dev), qdev_get_vmsd(dev), dev);
1d45a705
GA
899 }
900
901post_realize_fail:
04162f8f
MR
902 g_free(dev->canonical_path);
903 dev->canonical_path = NULL;
1d45a705
GA
904 if (dc->unrealize) {
905 dc->unrealize(dev, NULL);
906 }
907
908fail:
909 error_propagate(errp, local_err);
69382d8b
IM
910 if (unattached_parent) {
911 object_unparent(OBJECT(dev));
912 unattached_count--;
913 }
249d4172
AF
914}
915
a7737e44 916static bool device_get_hotpluggable(Object *obj, Error **errp)
1a37eca1
IM
917{
918 DeviceClass *dc = DEVICE_GET_CLASS(obj);
919 DeviceState *dev = DEVICE(obj);
920
2b81b35f 921 return dc->hotpluggable && (dev->parent_bus == NULL ||
39b888bd 922 qbus_is_hotpluggable(dev->parent_bus));
1a37eca1
IM
923}
924
40f03bd5 925static bool device_get_hotplugged(Object *obj, Error **errp)
d012ffc1
IM
926{
927 DeviceState *dev = DEVICE(obj);
928
929 return dev->hotplugged;
930}
931
9674bfe4
AL
932static void device_initfn(Object *obj)
933{
934 DeviceState *dev = DEVICE(obj);
bce54474 935 ObjectClass *class;
9674bfe4
AL
936 Property *prop;
937
938 if (qdev_hotplug) {
939 dev->hotplugged = 1;
940 qdev_hot_added = true;
941 }
942
943 dev->instance_id_alias = -1;
7983c8a3 944 dev->realized = false;
a1190ab6 945 dev->allow_unplug_during_migration = false;
9674bfe4 946
249d4172
AF
947 object_property_add_bool(obj, "realized",
948 device_get_realized, device_set_realized, NULL);
1a37eca1
IM
949 object_property_add_bool(obj, "hotpluggable",
950 device_get_hotpluggable, NULL, NULL);
d012ffc1 951 object_property_add_bool(obj, "hotplugged",
36cccb8c 952 device_get_hotplugged, NULL,
d012ffc1 953 &error_abort);
249d4172 954
bce54474
PB
955 class = object_get_class(OBJECT(dev));
956 do {
957 for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
5433a0a8 958 qdev_property_add_legacy(dev, prop, &error_abort);
94d912d1 959 qdev_property_add_static(dev, prop);
bce54474 960 }
bce54474
PB
961 class = object_class_get_parent(class);
962 } while (class != object_class_by_name(TYPE_DEVICE));
9674bfe4 963
f968fc68 964 object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
39f72ef9 965 (Object **)&dev->parent_bus, NULL, 0,
9561fda8 966 &error_abort);
a5f54290 967 QLIST_INIT(&dev->gpios);
9674bfe4
AL
968}
969
1c3994f6
MAL
970static void device_post_init(Object *obj)
971{
1a3ec8c1
MA
972 /*
973 * Note: ordered so that the user's global properties take
974 * precedence.
975 */
1c3994f6 976 object_apply_compat_props(obj);
25f8dd96 977 qdev_prop_set_globals(DEVICE(obj));
99a0b036
EH
978}
979
60adba37
AL
980/* Unlink device from bus and free the structure. */
981static void device_finalize(Object *obj)
982{
a5f54290
PC
983 NamedGPIOList *ngl, *next;
984
60adba37 985 DeviceState *dev = DEVICE(obj);
a5f54290
PC
986
987 QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
988 QLIST_REMOVE(ngl, node);
f173d57a 989 qemu_free_irqs(ngl->in, ngl->num_in);
a5f54290
PC
990 g_free(ngl->name);
991 g_free(ngl);
992 /* ngl->out irqs are owned by the other end and should not be freed
993 * here
994 */
995 }
f7b879e0
MR
996
997 /* Only send event if the device had been completely realized */
998 if (dev->pending_deleted_event) {
999 g_assert(dev->canonical_path);
1000
3ab72385 1001 qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path);
f7b879e0
MR
1002 g_free(dev->canonical_path);
1003 dev->canonical_path = NULL;
1004 }
1005
1006 qemu_opts_del(dev->opts);
60adba37
AL
1007}
1008
bce54474
PB
1009static void device_class_base_init(ObjectClass *class, void *data)
1010{
1011 DeviceClass *klass = DEVICE_CLASS(class);
1012
1013 /* We explicitly look up properties in the superclasses,
1014 * so do not propagate them to the subclasses.
1015 */
1016 klass->props = NULL;
60adba37
AL
1017}
1018
5d5b24d0 1019static void device_unparent(Object *obj)
667d22d1
PB
1020{
1021 DeviceState *dev = DEVICE(obj);
06f7f2bb 1022 BusState *bus;
667d22d1 1023
5c21ce77
BD
1024 if (dev->realized) {
1025 object_property_set_bool(obj, false, "realized", NULL);
1026 }
06f7f2bb
PB
1027 while (dev->num_child_bus) {
1028 bus = QLIST_FIRST(&dev->child_bus);
6780a22c 1029 object_unparent(OBJECT(bus));
06f7f2bb 1030 }
06f7f2bb 1031 if (dev->parent_bus) {
5d5b24d0 1032 bus_remove_child(dev->parent_bus, dev);
62d7ba66
PB
1033 object_unref(OBJECT(dev->parent_bus));
1034 dev->parent_bus = NULL;
5d5b24d0 1035 }
667d22d1
PB
1036}
1037
107b5969
MAL
1038static char *
1039device_vmstate_if_get_id(VMStateIf *obj)
1040{
1041 DeviceState *dev = DEVICE(obj);
1042
1043 return qdev_get_dev_path(dev);
1044}
1045
667d22d1
PB
1046static void device_class_init(ObjectClass *class, void *data)
1047{
249d4172 1048 DeviceClass *dc = DEVICE_CLASS(class);
107b5969 1049 VMStateIfClass *vc = VMSTATE_IF_CLASS(class);
249d4172 1050
5d5b24d0 1051 class->unparent = device_unparent;
267a3264
IM
1052
1053 /* by default all devices were considered as hotpluggable,
1054 * so with intent to check it in generic qdev_unplug() /
1055 * device_set_realized() functions make every device
1056 * hotpluggable. Devices that shouldn't be hotpluggable,
1057 * should override it in their class_init()
1058 */
1059 dc->hotpluggable = true;
e90f2a8c 1060 dc->user_creatable = true;
107b5969 1061 vc->get_id = device_vmstate_if_get_id;
667d22d1
PB
1062}
1063
4f67d30b
MAL
1064void device_class_set_props(DeviceClass *dc, Property *props)
1065{
1066 dc->props = props;
1067}
1068
46795cf2
PMD
1069void device_class_set_parent_reset(DeviceClass *dc,
1070 DeviceReset dev_reset,
1071 DeviceReset *parent_reset)
1072{
1073 *parent_reset = dc->reset;
1074 dc->reset = dev_reset;
1075}
1076
1077void device_class_set_parent_realize(DeviceClass *dc,
1078 DeviceRealize dev_realize,
1079 DeviceRealize *parent_realize)
1080{
1081 *parent_realize = dc->realize;
1082 dc->realize = dev_realize;
1083}
1084
1085void device_class_set_parent_unrealize(DeviceClass *dc,
1086 DeviceUnrealize dev_unrealize,
1087 DeviceUnrealize *parent_unrealize)
1088{
1089 *parent_unrealize = dc->unrealize;
1090 dc->unrealize = dev_unrealize;
1091}
1092
94afdadc
AL
1093void device_reset(DeviceState *dev)
1094{
1095 DeviceClass *klass = DEVICE_GET_CLASS(dev);
1096
1097 if (klass->reset) {
1098 klass->reset(dev);
1099 }
1100}
1101
f05f6b4a
PB
1102Object *qdev_get_machine(void)
1103{
1104 static Object *dev;
1105
1106 if (dev == NULL) {
dfe47e70 1107 dev = container_get(object_get_root(), "/machine");
f05f6b4a
PB
1108 }
1109
1110 return dev;
1111}
1112
8c43a6f0 1113static const TypeInfo device_type_info = {
32fea402
AL
1114 .name = TYPE_DEVICE,
1115 .parent = TYPE_OBJECT,
1116 .instance_size = sizeof(DeviceState),
9674bfe4 1117 .instance_init = device_initfn,
99a0b036 1118 .instance_post_init = device_post_init,
60adba37 1119 .instance_finalize = device_finalize,
bce54474 1120 .class_base_init = device_class_base_init,
667d22d1 1121 .class_init = device_class_init,
32fea402
AL
1122 .abstract = true,
1123 .class_size = sizeof(DeviceClass),
107b5969
MAL
1124 .interfaces = (InterfaceInfo[]) {
1125 { TYPE_VMSTATE_IF },
1126 { }
1127 }
32fea402
AL
1128};
1129
83f7d43a 1130static void qdev_register_types(void)
32fea402
AL
1131{
1132 type_register_static(&device_type_info);
1133}
1134
83f7d43a 1135type_init(qdev_register_types)