mirror of https://gitee.com/openkylin/qemu.git
qdev: Realize buses on device realization
Integrate (un)realization of child buses with realization/unrealization of the device hosting them. Code in device_unparent() is reordered for unrealization of buses to work as part of device unrealization. That way no changes need to be made to bus instantiation. Signed-off-by: Bandan Das <bsd@redhat.com> Signed-off-by: Andreas Färber <afaerber@suse.de>
This commit is contained in:
parent
02e7f85dac
commit
5c21ce77d7
|
@ -716,6 +716,7 @@ static void device_set_realized(Object *obj, bool value, Error **err)
|
||||||
{
|
{
|
||||||
DeviceState *dev = DEVICE(obj);
|
DeviceState *dev = DEVICE(obj);
|
||||||
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
||||||
|
BusState *bus;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
if (dev->hotplugged && !dc->hotpluggable) {
|
if (dev->hotplugged && !dc->hotpluggable) {
|
||||||
|
@ -749,14 +750,30 @@ static void device_set_realized(Object *obj, bool value, Error **err)
|
||||||
dev->instance_id_alias,
|
dev->instance_id_alias,
|
||||||
dev->alias_required_for_version);
|
dev->alias_required_for_version);
|
||||||
}
|
}
|
||||||
|
if (local_err == NULL) {
|
||||||
|
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
|
||||||
|
object_property_set_bool(OBJECT(bus), true, "realized",
|
||||||
|
&local_err);
|
||||||
|
if (local_err != NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (dev->hotplugged && local_err == NULL) {
|
if (dev->hotplugged && local_err == NULL) {
|
||||||
device_reset(dev);
|
device_reset(dev);
|
||||||
}
|
}
|
||||||
} else if (!value && dev->realized) {
|
} else if (!value && dev->realized) {
|
||||||
if (qdev_get_vmsd(dev)) {
|
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
|
||||||
|
object_property_set_bool(OBJECT(bus), false, "realized",
|
||||||
|
&local_err);
|
||||||
|
if (local_err != NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (qdev_get_vmsd(dev) && local_err == NULL) {
|
||||||
vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
|
vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
|
||||||
}
|
}
|
||||||
if (dc->unrealize) {
|
if (dc->unrealize && local_err == NULL) {
|
||||||
dc->unrealize(dev, &local_err);
|
dc->unrealize(dev, &local_err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -841,13 +858,13 @@ static void device_unparent(Object *obj)
|
||||||
QObject *event_data;
|
QObject *event_data;
|
||||||
bool have_realized = dev->realized;
|
bool have_realized = dev->realized;
|
||||||
|
|
||||||
|
if (dev->realized) {
|
||||||
|
object_property_set_bool(obj, false, "realized", NULL);
|
||||||
|
}
|
||||||
while (dev->num_child_bus) {
|
while (dev->num_child_bus) {
|
||||||
bus = QLIST_FIRST(&dev->child_bus);
|
bus = QLIST_FIRST(&dev->child_bus);
|
||||||
object_unparent(OBJECT(bus));
|
object_unparent(OBJECT(bus));
|
||||||
}
|
}
|
||||||
if (dev->realized) {
|
|
||||||
object_property_set_bool(obj, false, "realized", NULL);
|
|
||||||
}
|
|
||||||
if (dev->parent_bus) {
|
if (dev->parent_bus) {
|
||||||
bus_remove_child(dev->parent_bus, dev);
|
bus_remove_child(dev->parent_bus, dev);
|
||||||
object_unref(OBJECT(dev->parent_bus));
|
object_unref(OBJECT(dev->parent_bus));
|
||||||
|
|
Loading…
Reference in New Issue