]> Git Repo - qemu.git/blame - hw/core/qdev.c
Merge remote-tracking branch 'remotes/elmarco/tags/prop-ptr-pull-request' into staging
[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
720/**
d9d8d452
C
721 * qdev_property_add_static:
722 * @dev: Device to add the property to.
723 * @prop: The qdev property definition.
724 * @errp: location to store error information.
ca2cc788 725 *
d9d8d452
C
726 * Add a static QOM property to @dev for qdev property @prop.
727 * On error, store error in @errp. Static properties access data in a struct.
728 * The type of the QOM property is derived from prop->info.
ca2cc788
PB
729 */
730void qdev_property_add_static(DeviceState *dev, Property *prop,
731 Error **errp)
732{
fdae245f
PB
733 Error *local_err = NULL;
734 Object *obj = OBJECT(dev);
735
faabdbb7
FZ
736 if (prop->info->create) {
737 prop->info->create(obj, prop, &local_err);
738 } else {
faabdbb7
FZ
739 object_property_add(obj, prop->name, prop->info->name,
740 prop->info->get, prop->info->set,
741 prop->info->release,
742 prop, &local_err);
d822979b
PB
743 }
744
fdae245f
PB
745 if (local_err) {
746 error_propagate(errp, local_err);
747 return;
748 }
b8c9cd5c
GA
749
750 object_property_set_description(obj, prop->name,
751 prop->info->description,
752 &error_abort);
753
5cc56cc6 754 if (prop->set_default) {
a2740ad5 755 prop->info->set_default_value(obj, prop);
fdae245f 756 }
6a146eba 757}
1de81d28 758
67cc7e0a
SH
759/* @qdev_alias_all_properties - Add alias properties to the source object for
760 * all qdev properties on the target DeviceState.
761 */
762void qdev_alias_all_properties(DeviceState *target, Object *source)
763{
764 ObjectClass *class;
765 Property *prop;
766
767 class = object_get_class(OBJECT(target));
768 do {
769 DeviceClass *dc = DEVICE_CLASS(class);
770
771 for (prop = dc->props; prop && prop->name; prop++) {
772 object_property_add_alias(source, prop->name,
773 OBJECT(target), prop->name,
774 &error_abort);
775 }
776 class = object_class_get_parent(class);
777 } while (class != object_class_by_name(TYPE_DEVICE));
778}
779
4cae4d5a 780static int qdev_add_hotpluggable_device(Object *obj, void *opaque)
66e56b13
ZG
781{
782 GSList **list = opaque;
09d56017
JL
783 DeviceState *dev = (DeviceState *)object_dynamic_cast(OBJECT(obj),
784 TYPE_DEVICE);
785
786 if (dev == NULL) {
787 return 0;
788 }
66e56b13
ZG
789
790 if (dev->realized && object_property_get_bool(obj, "hotpluggable", NULL)) {
791 *list = g_slist_append(*list, dev);
792 }
793
66e56b13
ZG
794 return 0;
795}
796
4cae4d5a
MA
797GSList *qdev_build_hotpluggable_device_list(Object *peripheral)
798{
799 GSList *list = NULL;
800
801 object_child_foreach(peripheral, qdev_add_hotpluggable_device, &list);
802
803 return list;
804}
805
a7737e44 806static bool device_get_realized(Object *obj, Error **errp)
249d4172
AF
807{
808 DeviceState *dev = DEVICE(obj);
809 return dev->realized;
810}
811
40f03bd5 812static bool check_only_migratable(Object *obj, Error **errp)
1bfe5f05
JQ
813{
814 DeviceClass *dc = DEVICE_GET_CLASS(obj);
815
816 if (!vmstate_check_only_migratable(dc->vmsd)) {
40f03bd5 817 error_setg(errp, "Device %s is not migratable, but "
1bfe5f05
JQ
818 "--only-migratable was specified",
819 object_get_typename(obj));
820 return false;
821 }
822
823 return true;
824}
825
a7737e44 826static void device_set_realized(Object *obj, bool value, Error **errp)
249d4172
AF
827{
828 DeviceState *dev = DEVICE(obj);
829 DeviceClass *dc = DEVICE_GET_CLASS(dev);
7716b8ca 830 HotplugHandler *hotplug_ctrl;
5c21ce77 831 BusState *bus;
249d4172 832 Error *local_err = NULL;
69382d8b
IM
833 bool unattached_parent = false;
834 static int unattached_count;
249d4172 835
1a37eca1 836 if (dev->hotplugged && !dc->hotpluggable) {
c6bd8c70 837 error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
1a37eca1
IM
838 return;
839 }
840
249d4172 841 if (value && !dev->realized) {
1bfe5f05 842 if (!check_only_migratable(obj, &local_err)) {
7562f907
AA
843 goto fail;
844 }
845
d578029e 846 if (!obj->parent) {
249d4172
AF
847 gchar *name = g_strdup_printf("device[%d]", unattached_count++);
848
849 object_property_add_child(container_get(qdev_get_machine(),
850 "/unattached"),
d578029e 851 name, obj, &error_abort);
69382d8b 852 unattached_parent = true;
249d4172
AF
853 g_free(name);
854 }
855
41346263
IM
856 hotplug_ctrl = qdev_get_hotplug_handler(dev);
857 if (hotplug_ctrl) {
858 hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err);
859 if (local_err != NULL) {
860 goto fail;
861 }
862 }
863
a7ddba52
IM
864 if (dc->realize) {
865 dc->realize(dev, &local_err);
40f03bd5
VSO
866 if (local_err != NULL) {
867 goto fail;
868 }
1d45a705
GA
869 }
870
707ff800
PD
871 DEVICE_LISTENER_CALL(realize, Forward, dev);
872
04162f8f
MR
873 /*
874 * always free/re-initialize here since the value cannot be cleaned up
875 * in device_unrealize due to its usage later on in the unplug path
876 */
877 g_free(dev->canonical_path);
878 dev->canonical_path = object_get_canonical_path(OBJECT(dev));
879
1d45a705 880 if (qdev_get_vmsd(dev)) {
3cad405b
MAL
881 if (vmstate_register_with_alias_id(VMSTATE_IF(dev),
882 -1, qdev_get_vmsd(dev), dev,
67980031
DDAG
883 dev->instance_id_alias,
884 dev->alias_required_for_version,
885 &local_err) < 0) {
886 goto post_realize_fail;
887 }
249d4172 888 }
1d45a705
GA
889
890 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
891 object_property_set_bool(OBJECT(bus), true, "realized",
5c21ce77 892 &local_err);
1d45a705
GA
893 if (local_err != NULL) {
894 goto child_realize_fail;
5c21ce77
BD
895 }
896 }
1d45a705 897 if (dev->hotplugged) {
249d4172
AF
898 device_reset(dev);
899 }
352e8da7 900 dev->pending_deleted_event = false;
25e89788
SH
901
902 if (hotplug_ctrl) {
8b5e6caf
IM
903 hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
904 if (local_err != NULL) {
905 goto child_realize_fail;
906 }
907 }
908
249d4172 909 } else if (!value && dev->realized) {
40f03bd5 910 /* We want local_err to track only the first error */
5c21ce77
BD
911 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
912 object_property_set_bool(OBJECT(bus), false, "realized",
40f03bd5 913 local_err ? NULL : &local_err);
5c21ce77 914 }
cd4520ad 915 if (qdev_get_vmsd(dev)) {
3cad405b 916 vmstate_unregister(VMSTATE_IF(dev), qdev_get_vmsd(dev), dev);
fe6c2117 917 }
cd4520ad 918 if (dc->unrealize) {
40f03bd5 919 dc->unrealize(dev, local_err ? NULL : &local_err);
249d4172 920 }
352e8da7 921 dev->pending_deleted_event = true;
707ff800 922 DEVICE_LISTENER_CALL(unrealize, Reverse, dev);
249d4172 923
40f03bd5
VSO
924 if (local_err != NULL) {
925 goto fail;
926 }
249d4172
AF
927 }
928
40f03bd5 929 assert(local_err == NULL);
c7f8d0f3 930 dev->realized = value;
1d45a705
GA
931 return;
932
933child_realize_fail:
934 QLIST_FOREACH(bus, &dev->child_bus, sibling) {
935 object_property_set_bool(OBJECT(bus), false, "realized",
936 NULL);
937 }
938
939 if (qdev_get_vmsd(dev)) {
3cad405b 940 vmstate_unregister(VMSTATE_IF(dev), qdev_get_vmsd(dev), dev);
1d45a705
GA
941 }
942
943post_realize_fail:
04162f8f
MR
944 g_free(dev->canonical_path);
945 dev->canonical_path = NULL;
1d45a705
GA
946 if (dc->unrealize) {
947 dc->unrealize(dev, NULL);
948 }
949
950fail:
951 error_propagate(errp, local_err);
69382d8b
IM
952 if (unattached_parent) {
953 object_unparent(OBJECT(dev));
954 unattached_count--;
955 }
249d4172
AF
956}
957
a7737e44 958static bool device_get_hotpluggable(Object *obj, Error **errp)
1a37eca1
IM
959{
960 DeviceClass *dc = DEVICE_GET_CLASS(obj);
961 DeviceState *dev = DEVICE(obj);
962
2b81b35f 963 return dc->hotpluggable && (dev->parent_bus == NULL ||
39b888bd 964 qbus_is_hotpluggable(dev->parent_bus));
1a37eca1
IM
965}
966
40f03bd5 967static bool device_get_hotplugged(Object *obj, Error **errp)
d012ffc1
IM
968{
969 DeviceState *dev = DEVICE(obj);
970
971 return dev->hotplugged;
972}
973
9674bfe4
AL
974static void device_initfn(Object *obj)
975{
976 DeviceState *dev = DEVICE(obj);
bce54474 977 ObjectClass *class;
9674bfe4
AL
978 Property *prop;
979
980 if (qdev_hotplug) {
981 dev->hotplugged = 1;
982 qdev_hot_added = true;
983 }
984
985 dev->instance_id_alias = -1;
7983c8a3 986 dev->realized = false;
a1190ab6 987 dev->allow_unplug_during_migration = false;
9674bfe4 988
249d4172
AF
989 object_property_add_bool(obj, "realized",
990 device_get_realized, device_set_realized, NULL);
1a37eca1
IM
991 object_property_add_bool(obj, "hotpluggable",
992 device_get_hotpluggable, NULL, NULL);
d012ffc1 993 object_property_add_bool(obj, "hotplugged",
36cccb8c 994 device_get_hotplugged, NULL,
d012ffc1 995 &error_abort);
249d4172 996
bce54474
PB
997 class = object_get_class(OBJECT(dev));
998 do {
999 for (prop = DEVICE_CLASS(class)->props; prop && prop->name; prop++) {
5433a0a8
PC
1000 qdev_property_add_legacy(dev, prop, &error_abort);
1001 qdev_property_add_static(dev, prop, &error_abort);
bce54474 1002 }
bce54474
PB
1003 class = object_class_get_parent(class);
1004 } while (class != object_class_by_name(TYPE_DEVICE));
9674bfe4 1005
f968fc68 1006 object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
39f72ef9 1007 (Object **)&dev->parent_bus, NULL, 0,
9561fda8 1008 &error_abort);
a5f54290 1009 QLIST_INIT(&dev->gpios);
9674bfe4
AL
1010}
1011
1c3994f6
MAL
1012static void device_post_init(Object *obj)
1013{
1a3ec8c1
MA
1014 /*
1015 * Note: ordered so that the user's global properties take
1016 * precedence.
1017 */
1c3994f6 1018 object_apply_compat_props(obj);
25f8dd96 1019 qdev_prop_set_globals(DEVICE(obj));
99a0b036
EH
1020}
1021
60adba37
AL
1022/* Unlink device from bus and free the structure. */
1023static void device_finalize(Object *obj)
1024{
a5f54290
PC
1025 NamedGPIOList *ngl, *next;
1026
60adba37 1027 DeviceState *dev = DEVICE(obj);
a5f54290
PC
1028
1029 QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) {
1030 QLIST_REMOVE(ngl, node);
f173d57a 1031 qemu_free_irqs(ngl->in, ngl->num_in);
a5f54290
PC
1032 g_free(ngl->name);
1033 g_free(ngl);
1034 /* ngl->out irqs are owned by the other end and should not be freed
1035 * here
1036 */
1037 }
f7b879e0
MR
1038
1039 /* Only send event if the device had been completely realized */
1040 if (dev->pending_deleted_event) {
1041 g_assert(dev->canonical_path);
1042
3ab72385 1043 qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path);
f7b879e0
MR
1044 g_free(dev->canonical_path);
1045 dev->canonical_path = NULL;
1046 }
1047
1048 qemu_opts_del(dev->opts);
60adba37
AL
1049}
1050
bce54474
PB
1051static void device_class_base_init(ObjectClass *class, void *data)
1052{
1053 DeviceClass *klass = DEVICE_CLASS(class);
1054
1055 /* We explicitly look up properties in the superclasses,
1056 * so do not propagate them to the subclasses.
1057 */
1058 klass->props = NULL;
60adba37
AL
1059}
1060
5d5b24d0 1061static void device_unparent(Object *obj)
667d22d1
PB
1062{
1063 DeviceState *dev = DEVICE(obj);
06f7f2bb 1064 BusState *bus;
667d22d1 1065
5c21ce77
BD
1066 if (dev->realized) {
1067 object_property_set_bool(obj, false, "realized", NULL);
1068 }
06f7f2bb
PB
1069 while (dev->num_child_bus) {
1070 bus = QLIST_FIRST(&dev->child_bus);
6780a22c 1071 object_unparent(OBJECT(bus));
06f7f2bb 1072 }
06f7f2bb 1073 if (dev->parent_bus) {
5d5b24d0 1074 bus_remove_child(dev->parent_bus, dev);
62d7ba66
PB
1075 object_unref(OBJECT(dev->parent_bus));
1076 dev->parent_bus = NULL;
5d5b24d0 1077 }
667d22d1
PB
1078}
1079
107b5969
MAL
1080static char *
1081device_vmstate_if_get_id(VMStateIf *obj)
1082{
1083 DeviceState *dev = DEVICE(obj);
1084
1085 return qdev_get_dev_path(dev);
1086}
1087
667d22d1
PB
1088static void device_class_init(ObjectClass *class, void *data)
1089{
249d4172 1090 DeviceClass *dc = DEVICE_CLASS(class);
107b5969 1091 VMStateIfClass *vc = VMSTATE_IF_CLASS(class);
249d4172 1092
5d5b24d0 1093 class->unparent = device_unparent;
267a3264
IM
1094
1095 /* by default all devices were considered as hotpluggable,
1096 * so with intent to check it in generic qdev_unplug() /
1097 * device_set_realized() functions make every device
1098 * hotpluggable. Devices that shouldn't be hotpluggable,
1099 * should override it in their class_init()
1100 */
1101 dc->hotpluggable = true;
e90f2a8c 1102 dc->user_creatable = true;
107b5969 1103 vc->get_id = device_vmstate_if_get_id;
667d22d1
PB
1104}
1105
46795cf2
PMD
1106void device_class_set_parent_reset(DeviceClass *dc,
1107 DeviceReset dev_reset,
1108 DeviceReset *parent_reset)
1109{
1110 *parent_reset = dc->reset;
1111 dc->reset = dev_reset;
1112}
1113
1114void device_class_set_parent_realize(DeviceClass *dc,
1115 DeviceRealize dev_realize,
1116 DeviceRealize *parent_realize)
1117{
1118 *parent_realize = dc->realize;
1119 dc->realize = dev_realize;
1120}
1121
1122void device_class_set_parent_unrealize(DeviceClass *dc,
1123 DeviceUnrealize dev_unrealize,
1124 DeviceUnrealize *parent_unrealize)
1125{
1126 *parent_unrealize = dc->unrealize;
1127 dc->unrealize = dev_unrealize;
1128}
1129
94afdadc
AL
1130void device_reset(DeviceState *dev)
1131{
1132 DeviceClass *klass = DEVICE_GET_CLASS(dev);
1133
1134 if (klass->reset) {
1135 klass->reset(dev);
1136 }
1137}
1138
f05f6b4a
PB
1139Object *qdev_get_machine(void)
1140{
1141 static Object *dev;
1142
1143 if (dev == NULL) {
dfe47e70 1144 dev = container_get(object_get_root(), "/machine");
f05f6b4a
PB
1145 }
1146
1147 return dev;
1148}
1149
8c43a6f0 1150static const TypeInfo device_type_info = {
32fea402
AL
1151 .name = TYPE_DEVICE,
1152 .parent = TYPE_OBJECT,
1153 .instance_size = sizeof(DeviceState),
9674bfe4 1154 .instance_init = device_initfn,
99a0b036 1155 .instance_post_init = device_post_init,
60adba37 1156 .instance_finalize = device_finalize,
bce54474 1157 .class_base_init = device_class_base_init,
667d22d1 1158 .class_init = device_class_init,
32fea402
AL
1159 .abstract = true,
1160 .class_size = sizeof(DeviceClass),
107b5969
MAL
1161 .interfaces = (InterfaceInfo[]) {
1162 { TYPE_VMSTATE_IF },
1163 { }
1164 }
32fea402
AL
1165};
1166
83f7d43a 1167static void qdev_register_types(void)
32fea402
AL
1168{
1169 type_register_static(&device_type_info);
1170}
1171
83f7d43a 1172type_init(qdev_register_types)
This page took 1.082098 seconds and 4 git commands to generate.