2 * Dynamic device configuration and creation.
4 * Copyright (c) 2009 CodeSourcery
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.
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.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
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
29 #include "hw/fw-path-provider.h"
30 #include "sysemu/sysemu.h"
31 #include "qapi/error.h"
32 #include "qapi/qmp/qerror.h"
33 #include "qapi/visitor.h"
34 #include "qapi/qmp/qjson.h"
35 #include "hw/hotplug.h"
36 #include "hw/boards.h"
37 #include "qapi-event.h"
40 static bool qdev_hot_added
= false;
41 static bool qdev_hot_removed
= false;
43 const VMStateDescription
*qdev_get_vmsd(DeviceState
*dev
)
45 DeviceClass
*dc
= DEVICE_GET_CLASS(dev
);
49 const char *qdev_fw_name(DeviceState
*dev
)
51 DeviceClass
*dc
= DEVICE_GET_CLASS(dev
);
57 return object_get_typename(OBJECT(dev
));
60 static void qdev_property_add_legacy(DeviceState
*dev
, Property
*prop
,
63 static void bus_remove_child(BusState
*bus
, DeviceState
*child
)
67 QTAILQ_FOREACH(kid
, &bus
->children
, sibling
) {
68 if (kid
->child
== child
) {
71 snprintf(name
, sizeof(name
), "child[%d]", kid
->index
);
72 QTAILQ_REMOVE(&bus
->children
, kid
, sibling
);
74 /* This gives back ownership of kid->child back to us. */
75 object_property_del(OBJECT(bus
), name
, NULL
);
76 object_unref(OBJECT(kid
->child
));
83 static void bus_add_child(BusState
*bus
, DeviceState
*child
)
86 BusChild
*kid
= g_malloc0(sizeof(*kid
));
88 kid
->index
= bus
->max_index
++;
90 object_ref(OBJECT(kid
->child
));
92 QTAILQ_INSERT_HEAD(&bus
->children
, kid
, sibling
);
94 /* This transfers ownership of kid->child to the property. */
95 snprintf(name
, sizeof(name
), "child[%d]", kid
->index
);
96 object_property_add_link(OBJECT(bus
), name
,
97 object_get_typename(OBJECT(child
)),
98 (Object
**)&kid
->child
,
99 NULL
, /* read-only property */
100 0, /* return ownership on prop deletion */
104 void qdev_set_parent_bus(DeviceState
*dev
, BusState
*bus
)
106 dev
->parent_bus
= bus
;
107 object_ref(OBJECT(bus
));
108 bus_add_child(bus
, dev
);
111 static void qbus_set_hotplug_handler_internal(BusState
*bus
, Object
*handler
,
115 object_property_set_link(OBJECT(bus
), OBJECT(handler
),
116 QDEV_HOTPLUG_HANDLER_PROPERTY
, errp
);
119 void qbus_set_hotplug_handler(BusState
*bus
, DeviceState
*handler
, Error
**errp
)
121 qbus_set_hotplug_handler_internal(bus
, OBJECT(handler
), errp
);
124 void qbus_set_bus_hotplug_handler(BusState
*bus
, Error
**errp
)
126 qbus_set_hotplug_handler_internal(bus
, OBJECT(bus
), errp
);
129 /* Create a new device. This only initializes the device state structure
130 and allows properties to be set. qdev_init should be called to
131 initialize the actual device emulation. */
132 DeviceState
*qdev_create(BusState
*bus
, const char *name
)
136 dev
= qdev_try_create(bus
, name
);
139 error_report("Unknown device '%s' for bus '%s'", name
,
140 object_get_typename(OBJECT(bus
)));
142 error_report("Unknown device '%s' for default sysbus", name
);
150 DeviceState
*qdev_try_create(BusState
*bus
, const char *type
)
154 if (object_class_by_name(type
) == NULL
) {
157 dev
= DEVICE(object_new(type
));
163 bus
= sysbus_get_default();
166 qdev_set_parent_bus(dev
, bus
);
167 object_unref(OBJECT(dev
));
171 /* Initialize a device. Device properties should be set before calling
172 this function. IRQs and MMIO regions should be connected/mapped after
173 calling this function.
174 On failure, destroy the device and return negative value.
175 Return 0 on success. */
176 int qdev_init(DeviceState
*dev
)
178 Error
*local_err
= NULL
;
180 assert(!dev
->realized
);
182 object_property_set_bool(OBJECT(dev
), true, "realized", &local_err
);
183 if (local_err
!= NULL
) {
184 qerror_report_err(local_err
);
185 error_free(local_err
);
186 object_unparent(OBJECT(dev
));
192 static QTAILQ_HEAD(device_listeners
, DeviceListener
) device_listeners
193 = QTAILQ_HEAD_INITIALIZER(device_listeners
);
195 enum ListenerDirection
{ Forward
, Reverse
};
197 #define DEVICE_LISTENER_CALL(_callback, _direction, _args...) \
199 DeviceListener *_listener; \
201 switch (_direction) { \
203 QTAILQ_FOREACH(_listener, &device_listeners, link) { \
204 if (_listener->_callback) { \
205 _listener->_callback(_listener, ##_args); \
210 QTAILQ_FOREACH_REVERSE(_listener, &device_listeners, \
211 device_listeners, link) { \
212 if (_listener->_callback) { \
213 _listener->_callback(_listener, ##_args); \
222 static int device_listener_add(DeviceState
*dev
, void *opaque
)
224 DEVICE_LISTENER_CALL(realize
, Forward
, dev
);
229 void device_listener_register(DeviceListener
*listener
)
231 QTAILQ_INSERT_TAIL(&device_listeners
, listener
, link
);
233 qbus_walk_children(sysbus_get_default(), NULL
, NULL
, device_listener_add
,
237 void device_listener_unregister(DeviceListener
*listener
)
239 QTAILQ_REMOVE(&device_listeners
, listener
, link
);
242 static void device_realize(DeviceState
*dev
, Error
**errp
)
244 DeviceClass
*dc
= DEVICE_GET_CLASS(dev
);
247 int rc
= dc
->init(dev
);
249 error_setg(errp
, "Device initialization failed.");
255 static void device_unrealize(DeviceState
*dev
, Error
**errp
)
257 DeviceClass
*dc
= DEVICE_GET_CLASS(dev
);
260 int rc
= dc
->exit(dev
);
262 error_setg(errp
, "Device exit failed.");
268 void qdev_set_legacy_instance_id(DeviceState
*dev
, int alias_id
,
269 int required_for_version
)
271 assert(!dev
->realized
);
272 dev
->instance_id_alias
= alias_id
;
273 dev
->alias_required_for_version
= required_for_version
;
276 static HotplugHandler
*qdev_get_hotplug_handler(DeviceState
*dev
)
278 HotplugHandler
*hotplug_ctrl
= NULL
;
280 if (dev
->parent_bus
&& dev
->parent_bus
->hotplug_handler
) {
281 hotplug_ctrl
= dev
->parent_bus
->hotplug_handler
;
282 } else if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE
)) {
283 MachineState
*machine
= MACHINE(qdev_get_machine());
284 MachineClass
*mc
= MACHINE_GET_CLASS(machine
);
286 if (mc
->get_hotplug_handler
) {
287 hotplug_ctrl
= mc
->get_hotplug_handler(machine
, dev
);
293 void qdev_unplug(DeviceState
*dev
, Error
**errp
)
295 DeviceClass
*dc
= DEVICE_GET_CLASS(dev
);
296 HotplugHandler
*hotplug_ctrl
;
297 HotplugHandlerClass
*hdc
;
299 if (dev
->parent_bus
&& !qbus_is_hotpluggable(dev
->parent_bus
)) {
300 error_set(errp
, QERR_BUS_NO_HOTPLUG
, dev
->parent_bus
->name
);
304 if (!dc
->hotpluggable
) {
305 error_set(errp
, QERR_DEVICE_NO_HOTPLUG
,
306 object_get_typename(OBJECT(dev
)));
310 qdev_hot_removed
= true;
312 hotplug_ctrl
= qdev_get_hotplug_handler(dev
);
313 /* hotpluggable device MUST have HotplugHandler, if it doesn't
314 * then something is very wrong with it */
315 g_assert(hotplug_ctrl
);
317 /* If device supports async unplug just request it to be done,
318 * otherwise just remove it synchronously */
319 hdc
= HOTPLUG_HANDLER_GET_CLASS(hotplug_ctrl
);
320 if (hdc
->unplug_request
) {
321 hotplug_handler_unplug_request(hotplug_ctrl
, dev
, errp
);
323 hotplug_handler_unplug(hotplug_ctrl
, dev
, errp
);
327 static int qdev_reset_one(DeviceState
*dev
, void *opaque
)
334 static int qbus_reset_one(BusState
*bus
, void *opaque
)
336 BusClass
*bc
= BUS_GET_CLASS(bus
);
343 void qdev_reset_all(DeviceState
*dev
)
345 qdev_walk_children(dev
, NULL
, NULL
, qdev_reset_one
, qbus_reset_one
, NULL
);
348 void qbus_reset_all(BusState
*bus
)
350 qbus_walk_children(bus
, NULL
, NULL
, qdev_reset_one
, qbus_reset_one
, NULL
);
353 void qbus_reset_all_fn(void *opaque
)
355 BusState
*bus
= opaque
;
359 /* can be used as ->unplug() callback for the simple cases */
360 void qdev_simple_device_unplug_cb(HotplugHandler
*hotplug_dev
,
361 DeviceState
*dev
, Error
**errp
)
364 object_unparent(OBJECT(dev
));
367 /* Like qdev_init(), but terminate program via error_report() instead of
368 returning an error value. This is okay during machine creation.
369 Don't use for hotplug, because there callers need to recover from
370 failure. Exception: if you know the device's init() callback can't
371 fail, then qdev_init_nofail() can't fail either, and is therefore
372 usable even then. But relying on the device implementation that
373 way is somewhat unclean, and best avoided. */
374 void qdev_init_nofail(DeviceState
*dev
)
376 const char *typename
= object_get_typename(OBJECT(dev
));
378 if (qdev_init(dev
) < 0) {
379 error_report("Initialization of device %s failed", typename
);
384 void qdev_machine_creation_done(void)
387 * ok, initial machine setup is done, starting from now we can
388 * only create hotpluggable devices
393 bool qdev_machine_modified(void)
395 return qdev_hot_added
|| qdev_hot_removed
;
398 BusState
*qdev_get_parent_bus(DeviceState
*dev
)
400 return dev
->parent_bus
;
403 static NamedGPIOList
*qdev_get_named_gpio_list(DeviceState
*dev
,
408 QLIST_FOREACH(ngl
, &dev
->gpios
, node
) {
409 /* NULL is a valid and matchable name, otherwise do a normal
412 if ((!ngl
->name
&& !name
) ||
413 (name
&& ngl
->name
&& strcmp(name
, ngl
->name
) == 0)) {
418 ngl
= g_malloc0(sizeof(*ngl
));
419 ngl
->name
= g_strdup(name
);
420 QLIST_INSERT_HEAD(&dev
->gpios
, ngl
, node
);
424 void qdev_init_gpio_in_named(DeviceState
*dev
, qemu_irq_handler handler
,
425 const char *name
, int n
)
428 NamedGPIOList
*gpio_list
= qdev_get_named_gpio_list(dev
, name
);
429 char *propname
= g_strdup_printf("%s[*]", name
? name
: "unnamed-gpio-in");
431 assert(gpio_list
->num_out
== 0 || !name
);
432 gpio_list
->in
= qemu_extend_irqs(gpio_list
->in
, gpio_list
->num_in
, handler
,
435 for (i
= gpio_list
->num_in
; i
< gpio_list
->num_in
+ n
; i
++) {
436 object_property_add_child(OBJECT(dev
), propname
,
437 OBJECT(gpio_list
->in
[i
]), &error_abort
);
441 gpio_list
->num_in
+= n
;
444 void qdev_init_gpio_in(DeviceState
*dev
, qemu_irq_handler handler
, int n
)
446 qdev_init_gpio_in_named(dev
, handler
, NULL
, n
);
449 void qdev_init_gpio_out_named(DeviceState
*dev
, qemu_irq
*pins
,
450 const char *name
, int n
)
453 NamedGPIOList
*gpio_list
= qdev_get_named_gpio_list(dev
, name
);
454 char *propname
= g_strdup_printf("%s[*]", name
? name
: "unnamed-gpio-out");
456 assert(gpio_list
->num_in
== 0 || !name
);
457 gpio_list
->num_out
+= n
;
459 for (i
= 0; i
< n
; ++i
) {
460 memset(&pins
[i
], 0, sizeof(*pins
));
461 object_property_add_link(OBJECT(dev
), propname
, TYPE_IRQ
,
463 object_property_allow_set_link
,
464 OBJ_PROP_LINK_UNREF_ON_RELEASE
,
470 void qdev_init_gpio_out(DeviceState
*dev
, qemu_irq
*pins
, int n
)
472 qdev_init_gpio_out_named(dev
, pins
, NULL
, n
);
475 qemu_irq
qdev_get_gpio_in_named(DeviceState
*dev
, const char *name
, int n
)
477 NamedGPIOList
*gpio_list
= qdev_get_named_gpio_list(dev
, name
);
479 assert(n
>= 0 && n
< gpio_list
->num_in
);
480 return gpio_list
->in
[n
];
483 qemu_irq
qdev_get_gpio_in(DeviceState
*dev
, int n
)
485 return qdev_get_gpio_in_named(dev
, NULL
, n
);
488 void qdev_connect_gpio_out_named(DeviceState
*dev
, const char *name
, int n
,
491 char *propname
= g_strdup_printf("%s[%d]",
492 name
? name
: "unnamed-gpio-out", n
);
494 /* We need a name for object_property_set_link to work. If the
495 * object has a parent, object_property_add_child will come back
496 * with an error without doing anything. If it has none, it will
497 * never fail. So we can just call it with a NULL Error pointer.
499 object_property_add_child(qdev_get_machine(), "non-qdev-gpio[*]",
502 object_property_set_link(OBJECT(dev
), OBJECT(pin
), propname
, &error_abort
);
506 qemu_irq
qdev_get_gpio_out_connector(DeviceState
*dev
, const char *name
, int n
)
508 char *propname
= g_strdup_printf("%s[%d]",
509 name
? name
: "unnamed-gpio-out", n
);
511 qemu_irq ret
= (qemu_irq
)object_property_get_link(OBJECT(dev
), propname
,
517 /* disconnect a GPIO ouput, returning the disconnected input (if any) */
519 static qemu_irq
qdev_disconnect_gpio_out_named(DeviceState
*dev
,
520 const char *name
, int n
)
522 char *propname
= g_strdup_printf("%s[%d]",
523 name
? name
: "unnamed-gpio-out", n
);
525 qemu_irq ret
= (qemu_irq
)object_property_get_link(OBJECT(dev
), propname
,
528 object_property_set_link(OBJECT(dev
), NULL
, propname
, NULL
);
534 qemu_irq
qdev_intercept_gpio_out(DeviceState
*dev
, qemu_irq icpt
,
535 const char *name
, int n
)
537 qemu_irq disconnected
= qdev_disconnect_gpio_out_named(dev
, name
, n
);
538 qdev_connect_gpio_out_named(dev
, name
, n
, icpt
);
542 void qdev_connect_gpio_out(DeviceState
* dev
, int n
, qemu_irq pin
)
544 qdev_connect_gpio_out_named(dev
, NULL
, n
, pin
);
547 void qdev_pass_gpios(DeviceState
*dev
, DeviceState
*container
,
551 NamedGPIOList
*ngl
= qdev_get_named_gpio_list(dev
, name
);
553 for (i
= 0; i
< ngl
->num_in
; i
++) {
554 const char *nm
= ngl
->name
? ngl
->name
: "unnamed-gpio-in";
555 char *propname
= g_strdup_printf("%s[%d]", nm
, i
);
557 object_property_add_alias(OBJECT(container
), propname
,
558 OBJECT(dev
), propname
,
561 for (i
= 0; i
< ngl
->num_out
; i
++) {
562 const char *nm
= ngl
->name
? ngl
->name
: "unnamed-gpio-out";
563 char *propname
= g_strdup_printf("%s[%d]", nm
, i
);
565 object_property_add_alias(OBJECT(container
), propname
,
566 OBJECT(dev
), propname
,
569 QLIST_REMOVE(ngl
, node
);
570 QLIST_INSERT_HEAD(&container
->gpios
, ngl
, node
);
573 BusState
*qdev_get_child_bus(DeviceState
*dev
, const char *name
)
577 QLIST_FOREACH(bus
, &dev
->child_bus
, sibling
) {
578 if (strcmp(name
, bus
->name
) == 0) {
585 int qbus_walk_children(BusState
*bus
,
586 qdev_walkerfn
*pre_devfn
, qbus_walkerfn
*pre_busfn
,
587 qdev_walkerfn
*post_devfn
, qbus_walkerfn
*post_busfn
,
594 err
= pre_busfn(bus
, opaque
);
600 QTAILQ_FOREACH(kid
, &bus
->children
, sibling
) {
601 err
= qdev_walk_children(kid
->child
,
602 pre_devfn
, pre_busfn
,
603 post_devfn
, post_busfn
, opaque
);
610 err
= post_busfn(bus
, opaque
);
619 int qdev_walk_children(DeviceState
*dev
,
620 qdev_walkerfn
*pre_devfn
, qbus_walkerfn
*pre_busfn
,
621 qdev_walkerfn
*post_devfn
, qbus_walkerfn
*post_busfn
,
628 err
= pre_devfn(dev
, opaque
);
634 QLIST_FOREACH(bus
, &dev
->child_bus
, sibling
) {
635 err
= qbus_walk_children(bus
, pre_devfn
, pre_busfn
,
636 post_devfn
, post_busfn
, opaque
);
643 err
= post_devfn(dev
, opaque
);
652 DeviceState
*qdev_find_recursive(BusState
*bus
, const char *id
)
658 QTAILQ_FOREACH(kid
, &bus
->children
, sibling
) {
659 DeviceState
*dev
= kid
->child
;
661 if (dev
->id
&& strcmp(dev
->id
, id
) == 0) {
665 QLIST_FOREACH(child
, &dev
->child_bus
, sibling
) {
666 ret
= qdev_find_recursive(child
, id
);
675 static void qbus_realize(BusState
*bus
, DeviceState
*parent
, const char *name
)
677 const char *typename
= object_get_typename(OBJECT(bus
));
682 bus
->parent
= parent
;
685 bus
->name
= g_strdup(name
);
686 } else if (bus
->parent
&& bus
->parent
->id
) {
687 /* parent device has id -> use it plus parent-bus-id for bus name */
688 bus_id
= bus
->parent
->num_child_bus
;
690 len
= strlen(bus
->parent
->id
) + 16;
692 snprintf(buf
, len
, "%s.%d", bus
->parent
->id
, bus_id
);
695 /* no id -> use lowercase bus type plus global bus-id for bus name */
696 bc
= BUS_GET_CLASS(bus
);
697 bus_id
= bc
->automatic_ids
++;
699 len
= strlen(typename
) + 16;
701 len
= snprintf(buf
, len
, "%s.%d", typename
, bus_id
);
702 for (i
= 0; i
< len
; i
++) {
703 buf
[i
] = qemu_tolower(buf
[i
]);
709 QLIST_INSERT_HEAD(&bus
->parent
->child_bus
, bus
, sibling
);
710 bus
->parent
->num_child_bus
++;
711 object_property_add_child(OBJECT(bus
->parent
), bus
->name
, OBJECT(bus
), NULL
);
712 object_unref(OBJECT(bus
));
713 } else if (bus
!= sysbus_get_default()) {
714 /* TODO: once all bus devices are qdevified,
715 only reset handler for main_system_bus should be registered here. */
716 qemu_register_reset(qbus_reset_all_fn
, bus
);
720 static void bus_unparent(Object
*obj
)
722 BusState
*bus
= BUS(obj
);
725 while ((kid
= QTAILQ_FIRST(&bus
->children
)) != NULL
) {
726 DeviceState
*dev
= kid
->child
;
727 object_unparent(OBJECT(dev
));
730 QLIST_REMOVE(bus
, sibling
);
731 bus
->parent
->num_child_bus
--;
734 assert(bus
!= sysbus_get_default()); /* main_system_bus is never freed */
735 qemu_unregister_reset(qbus_reset_all_fn
, bus
);
739 static bool bus_get_realized(Object
*obj
, Error
**errp
)
741 BusState
*bus
= BUS(obj
);
743 return bus
->realized
;
746 static void bus_set_realized(Object
*obj
, bool value
, Error
**errp
)
748 BusState
*bus
= BUS(obj
);
749 BusClass
*bc
= BUS_GET_CLASS(bus
);
751 Error
*local_err
= NULL
;
753 if (value
&& !bus
->realized
) {
755 bc
->realize(bus
, &local_err
);
758 /* TODO: recursive realization */
759 } else if (!value
&& bus
->realized
) {
760 QTAILQ_FOREACH(kid
, &bus
->children
, sibling
) {
761 DeviceState
*dev
= kid
->child
;
762 object_property_set_bool(OBJECT(dev
), false, "realized",
764 if (local_err
!= NULL
) {
768 if (bc
->unrealize
&& local_err
== NULL
) {
769 bc
->unrealize(bus
, &local_err
);
773 if (local_err
!= NULL
) {
774 error_propagate(errp
, local_err
);
778 bus
->realized
= value
;
781 void qbus_create_inplace(void *bus
, size_t size
, const char *typename
,
782 DeviceState
*parent
, const char *name
)
784 object_initialize(bus
, size
, typename
);
785 qbus_realize(bus
, parent
, name
);
788 BusState
*qbus_create(const char *typename
, DeviceState
*parent
, const char *name
)
792 bus
= BUS(object_new(typename
));
793 qbus_realize(bus
, parent
, name
);
798 static char *bus_get_fw_dev_path(BusState
*bus
, DeviceState
*dev
)
800 BusClass
*bc
= BUS_GET_CLASS(bus
);
802 if (bc
->get_fw_dev_path
) {
803 return bc
->get_fw_dev_path(dev
);
809 static char *qdev_get_fw_dev_path_from_handler(BusState
*bus
, DeviceState
*dev
)
811 Object
*obj
= OBJECT(dev
);
814 while (!d
&& obj
->parent
) {
816 d
= fw_path_provider_try_get_dev_path(obj
, bus
, dev
);
821 char *qdev_get_own_fw_dev_path_from_handler(BusState
*bus
, DeviceState
*dev
)
823 Object
*obj
= OBJECT(dev
);
825 return fw_path_provider_try_get_dev_path(obj
, bus
, dev
);
828 static int qdev_get_fw_dev_path_helper(DeviceState
*dev
, char *p
, int size
)
832 if (dev
&& dev
->parent_bus
) {
834 l
= qdev_get_fw_dev_path_helper(dev
->parent_bus
->parent
, p
, size
);
835 d
= qdev_get_fw_dev_path_from_handler(dev
->parent_bus
, dev
);
837 d
= bus_get_fw_dev_path(dev
->parent_bus
, dev
);
840 l
+= snprintf(p
+ l
, size
- l
, "%s", d
);
846 l
+= snprintf(p
+ l
, size
- l
, "/");
851 char* qdev_get_fw_dev_path(DeviceState
*dev
)
856 l
= qdev_get_fw_dev_path_helper(dev
, path
, 128);
860 return g_strdup(path
);
863 char *qdev_get_dev_path(DeviceState
*dev
)
867 if (!dev
|| !dev
->parent_bus
) {
871 bc
= BUS_GET_CLASS(dev
->parent_bus
);
872 if (bc
->get_dev_path
) {
873 return bc
->get_dev_path(dev
);
880 * Legacy property handling
883 static void qdev_get_legacy_property(Object
*obj
, Visitor
*v
, void *opaque
,
884 const char *name
, Error
**errp
)
886 DeviceState
*dev
= DEVICE(obj
);
887 Property
*prop
= opaque
;
892 prop
->info
->print(dev
, prop
, buffer
, sizeof(buffer
));
893 visit_type_str(v
, &ptr
, name
, errp
);
897 * @qdev_add_legacy_property - adds a legacy property
899 * Do not use this is new code! Properties added through this interface will
900 * be given names and types in the "legacy" namespace.
902 * Legacy properties are string versions of other OOM properties. The format
903 * of the string depends on the property type.
905 static void qdev_property_add_legacy(DeviceState
*dev
, Property
*prop
,
910 /* Register pointer properties as legacy properties */
911 if (!prop
->info
->print
&& prop
->info
->get
) {
915 name
= g_strdup_printf("legacy-%s", prop
->name
);
916 object_property_add(OBJECT(dev
), name
, "str",
917 prop
->info
->print
? qdev_get_legacy_property
: prop
->info
->get
,
926 * @qdev_property_add_static - add a @Property to a device.
928 * Static properties access data in a struct. The actual type of the
929 * property and the field depends on the property type.
931 void qdev_property_add_static(DeviceState
*dev
, Property
*prop
,
934 Error
*local_err
= NULL
;
935 Object
*obj
= OBJECT(dev
);
938 * TODO qdev_prop_ptr does not have getters or setters. It must
939 * go now that it can be replaced with links. The test should be
940 * removed along with it: all static properties are read/write.
942 if (!prop
->info
->get
&& !prop
->info
->set
) {
946 object_property_add(obj
, prop
->name
, prop
->info
->name
,
947 prop
->info
->get
, prop
->info
->set
,
952 error_propagate(errp
, local_err
);
956 object_property_set_description(obj
, prop
->name
,
957 prop
->info
->description
,
960 if (prop
->qtype
== QTYPE_NONE
) {
964 if (prop
->qtype
== QTYPE_QBOOL
) {
965 object_property_set_bool(obj
, prop
->defval
, prop
->name
, &error_abort
);
966 } else if (prop
->info
->enum_table
) {
967 object_property_set_str(obj
, prop
->info
->enum_table
[prop
->defval
],
968 prop
->name
, &error_abort
);
969 } else if (prop
->qtype
== QTYPE_QINT
) {
970 object_property_set_int(obj
, prop
->defval
, prop
->name
, &error_abort
);
974 /* @qdev_alias_all_properties - Add alias properties to the source object for
975 * all qdev properties on the target DeviceState.
977 void qdev_alias_all_properties(DeviceState
*target
, Object
*source
)
982 class = object_get_class(OBJECT(target
));
984 DeviceClass
*dc
= DEVICE_CLASS(class);
986 for (prop
= dc
->props
; prop
&& prop
->name
; prop
++) {
987 object_property_add_alias(source
, prop
->name
,
988 OBJECT(target
), prop
->name
,
991 class = object_class_get_parent(class);
992 } while (class != object_class_by_name(TYPE_DEVICE
));
995 static int qdev_add_hotpluggable_device(Object
*obj
, void *opaque
)
997 GSList
**list
= opaque
;
998 DeviceState
*dev
= DEVICE(obj
);
1000 if (dev
->realized
&& object_property_get_bool(obj
, "hotpluggable", NULL
)) {
1001 *list
= g_slist_append(*list
, dev
);
1007 GSList
*qdev_build_hotpluggable_device_list(Object
*peripheral
)
1009 GSList
*list
= NULL
;
1011 object_child_foreach(peripheral
, qdev_add_hotpluggable_device
, &list
);
1016 static bool device_get_realized(Object
*obj
, Error
**errp
)
1018 DeviceState
*dev
= DEVICE(obj
);
1019 return dev
->realized
;
1022 static void device_set_realized(Object
*obj
, bool value
, Error
**errp
)
1024 DeviceState
*dev
= DEVICE(obj
);
1025 DeviceClass
*dc
= DEVICE_GET_CLASS(dev
);
1026 HotplugHandler
*hotplug_ctrl
;
1028 Error
*local_err
= NULL
;
1030 if (dev
->hotplugged
&& !dc
->hotpluggable
) {
1031 error_set(errp
, QERR_DEVICE_NO_HOTPLUG
, object_get_typename(obj
));
1035 if (value
&& !dev
->realized
) {
1037 static int unattached_count
;
1038 gchar
*name
= g_strdup_printf("device[%d]", unattached_count
++);
1040 object_property_add_child(container_get(qdev_get_machine(),
1042 name
, obj
, &error_abort
);
1047 dc
->realize(dev
, &local_err
);
1050 if (local_err
!= NULL
) {
1054 DEVICE_LISTENER_CALL(realize
, Forward
, dev
);
1056 hotplug_ctrl
= qdev_get_hotplug_handler(dev
);
1058 hotplug_handler_plug(hotplug_ctrl
, dev
, &local_err
);
1061 if (local_err
!= NULL
) {
1062 goto post_realize_fail
;
1065 if (qdev_get_vmsd(dev
)) {
1066 vmstate_register_with_alias_id(dev
, -1, qdev_get_vmsd(dev
), dev
,
1067 dev
->instance_id_alias
,
1068 dev
->alias_required_for_version
);
1071 QLIST_FOREACH(bus
, &dev
->child_bus
, sibling
) {
1072 object_property_set_bool(OBJECT(bus
), true, "realized",
1074 if (local_err
!= NULL
) {
1075 goto child_realize_fail
;
1078 if (dev
->hotplugged
) {
1081 dev
->pending_deleted_event
= false;
1082 } else if (!value
&& dev
->realized
) {
1083 Error
**local_errp
= NULL
;
1084 QLIST_FOREACH(bus
, &dev
->child_bus
, sibling
) {
1085 local_errp
= local_err
? NULL
: &local_err
;
1086 object_property_set_bool(OBJECT(bus
), false, "realized",
1089 if (qdev_get_vmsd(dev
)) {
1090 vmstate_unregister(dev
, qdev_get_vmsd(dev
), dev
);
1092 if (dc
->unrealize
) {
1093 local_errp
= local_err
? NULL
: &local_err
;
1094 dc
->unrealize(dev
, local_errp
);
1096 dev
->pending_deleted_event
= true;
1097 DEVICE_LISTENER_CALL(unrealize
, Reverse
, dev
);
1100 if (local_err
!= NULL
) {
1104 dev
->realized
= value
;
1108 QLIST_FOREACH(bus
, &dev
->child_bus
, sibling
) {
1109 object_property_set_bool(OBJECT(bus
), false, "realized",
1113 if (qdev_get_vmsd(dev
)) {
1114 vmstate_unregister(dev
, qdev_get_vmsd(dev
), dev
);
1118 if (dc
->unrealize
) {
1119 dc
->unrealize(dev
, NULL
);
1123 error_propagate(errp
, local_err
);
1127 static bool device_get_hotpluggable(Object
*obj
, Error
**errp
)
1129 DeviceClass
*dc
= DEVICE_GET_CLASS(obj
);
1130 DeviceState
*dev
= DEVICE(obj
);
1132 return dc
->hotpluggable
&& (dev
->parent_bus
== NULL
||
1133 qbus_is_hotpluggable(dev
->parent_bus
));
1136 static bool device_get_hotplugged(Object
*obj
, Error
**err
)
1138 DeviceState
*dev
= DEVICE(obj
);
1140 return dev
->hotplugged
;
1143 static void device_set_hotplugged(Object
*obj
, bool value
, Error
**err
)
1145 DeviceState
*dev
= DEVICE(obj
);
1147 dev
->hotplugged
= value
;
1150 static void device_initfn(Object
*obj
)
1152 DeviceState
*dev
= DEVICE(obj
);
1157 dev
->hotplugged
= 1;
1158 qdev_hot_added
= true;
1161 dev
->instance_id_alias
= -1;
1162 dev
->realized
= false;
1164 object_property_add_bool(obj
, "realized",
1165 device_get_realized
, device_set_realized
, NULL
);
1166 object_property_add_bool(obj
, "hotpluggable",
1167 device_get_hotpluggable
, NULL
, NULL
);
1168 object_property_add_bool(obj
, "hotplugged",
1169 device_get_hotplugged
, device_set_hotplugged
,
1172 class = object_get_class(OBJECT(dev
));
1174 for (prop
= DEVICE_CLASS(class)->props
; prop
&& prop
->name
; prop
++) {
1175 qdev_property_add_legacy(dev
, prop
, &error_abort
);
1176 qdev_property_add_static(dev
, prop
, &error_abort
);
1178 class = object_class_get_parent(class);
1179 } while (class != object_class_by_name(TYPE_DEVICE
));
1181 object_property_add_link(OBJECT(dev
), "parent_bus", TYPE_BUS
,
1182 (Object
**)&dev
->parent_bus
, NULL
, 0,
1184 QLIST_INIT(&dev
->gpios
);
1187 static void device_post_init(Object
*obj
)
1190 qdev_prop_set_globals(DEVICE(obj
), &err
);
1192 qerror_report_err(err
);
1198 /* Unlink device from bus and free the structure. */
1199 static void device_finalize(Object
*obj
)
1201 NamedGPIOList
*ngl
, *next
;
1203 DeviceState
*dev
= DEVICE(obj
);
1204 qemu_opts_del(dev
->opts
);
1206 QLIST_FOREACH_SAFE(ngl
, &dev
->gpios
, node
, next
) {
1207 QLIST_REMOVE(ngl
, node
);
1208 qemu_free_irqs(ngl
->in
, ngl
->num_in
);
1211 /* ngl->out irqs are owned by the other end and should not be freed
1217 static void device_class_base_init(ObjectClass
*class, void *data
)
1219 DeviceClass
*klass
= DEVICE_CLASS(class);
1221 /* We explicitly look up properties in the superclasses,
1222 * so do not propagate them to the subclasses.
1224 klass
->props
= NULL
;
1227 static void device_unparent(Object
*obj
)
1229 DeviceState
*dev
= DEVICE(obj
);
1232 if (dev
->realized
) {
1233 object_property_set_bool(obj
, false, "realized", NULL
);
1235 while (dev
->num_child_bus
) {
1236 bus
= QLIST_FIRST(&dev
->child_bus
);
1237 object_unparent(OBJECT(bus
));
1239 if (dev
->parent_bus
) {
1240 bus_remove_child(dev
->parent_bus
, dev
);
1241 object_unref(OBJECT(dev
->parent_bus
));
1242 dev
->parent_bus
= NULL
;
1245 /* Only send event if the device had been completely realized */
1246 if (dev
->pending_deleted_event
) {
1247 gchar
*path
= object_get_canonical_path(OBJECT(dev
));
1249 qapi_event_send_device_deleted(!!dev
->id
, dev
->id
, path
, &error_abort
);
1254 static void device_class_init(ObjectClass
*class, void *data
)
1256 DeviceClass
*dc
= DEVICE_CLASS(class);
1258 class->unparent
= device_unparent
;
1259 dc
->realize
= device_realize
;
1260 dc
->unrealize
= device_unrealize
;
1262 /* by default all devices were considered as hotpluggable,
1263 * so with intent to check it in generic qdev_unplug() /
1264 * device_set_realized() functions make every device
1265 * hotpluggable. Devices that shouldn't be hotpluggable,
1266 * should override it in their class_init()
1268 dc
->hotpluggable
= true;
1271 void device_reset(DeviceState
*dev
)
1273 DeviceClass
*klass
= DEVICE_GET_CLASS(dev
);
1280 Object
*qdev_get_machine(void)
1285 dev
= container_get(object_get_root(), "/machine");
1291 static const TypeInfo device_type_info
= {
1292 .name
= TYPE_DEVICE
,
1293 .parent
= TYPE_OBJECT
,
1294 .instance_size
= sizeof(DeviceState
),
1295 .instance_init
= device_initfn
,
1296 .instance_post_init
= device_post_init
,
1297 .instance_finalize
= device_finalize
,
1298 .class_base_init
= device_class_base_init
,
1299 .class_init
= device_class_init
,
1301 .class_size
= sizeof(DeviceClass
),
1304 static void qbus_initfn(Object
*obj
)
1306 BusState
*bus
= BUS(obj
);
1308 QTAILQ_INIT(&bus
->children
);
1309 object_property_add_link(obj
, QDEV_HOTPLUG_HANDLER_PROPERTY
,
1310 TYPE_HOTPLUG_HANDLER
,
1311 (Object
**)&bus
->hotplug_handler
,
1312 object_property_allow_set_link
,
1313 OBJ_PROP_LINK_UNREF_ON_RELEASE
,
1315 object_property_add_bool(obj
, "realized",
1316 bus_get_realized
, bus_set_realized
, NULL
);
1319 static char *default_bus_get_fw_dev_path(DeviceState
*dev
)
1321 return g_strdup(object_get_typename(OBJECT(dev
)));
1324 static void bus_class_init(ObjectClass
*class, void *data
)
1326 BusClass
*bc
= BUS_CLASS(class);
1328 class->unparent
= bus_unparent
;
1329 bc
->get_fw_dev_path
= default_bus_get_fw_dev_path
;
1332 static void qbus_finalize(Object
*obj
)
1334 BusState
*bus
= BUS(obj
);
1336 g_free((char *)bus
->name
);
1339 static const TypeInfo bus_info
= {
1341 .parent
= TYPE_OBJECT
,
1342 .instance_size
= sizeof(BusState
),
1344 .class_size
= sizeof(BusClass
),
1345 .instance_init
= qbus_initfn
,
1346 .instance_finalize
= qbus_finalize
,
1347 .class_init
= bus_class_init
,
1350 static void qdev_register_types(void)
1352 type_register_static(&bus_info
);
1353 type_register_static(&device_type_info
);
1356 type_init(qdev_register_types
)