qdev: Realize buses on device realization
authorBandan Das <bsd@redhat.com>
Wed, 12 Mar 2014 20:02:12 +0000 (21:02 +0100)
committerAndreas Färber <afaerber@suse.de>
Thu, 13 Mar 2014 00:21:57 +0000 (01:21 +0100)
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>
hw/core/qdev.c

index 7e58259911f63422636bb2e35dc82da179480668..9f0a522ee8749e3495064ca83e052e04b4b791b6 100644 (file)
@@ -716,6 +716,7 @@ static void device_set_realized(Object *obj, bool value, Error **err)
 {
     DeviceState *dev = DEVICE(obj);
     DeviceClass *dc = DEVICE_GET_CLASS(dev);
+    BusState *bus;
     Error *local_err = NULL;
 
     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->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) {
             device_reset(dev);
         }
     } 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);
         }
-        if (dc->unrealize) {
+        if (dc->unrealize && local_err == NULL) {
             dc->unrealize(dev, &local_err);
         }
     }
@@ -841,13 +858,13 @@ static void device_unparent(Object *obj)
     QObject *event_data;
     bool have_realized = dev->realized;
 
+    if (dev->realized) {
+        object_property_set_bool(obj, false, "realized", NULL);
+    }
     while (dev->num_child_bus) {
         bus = QLIST_FIRST(&dev->child_bus);
         object_unparent(OBJECT(bus));
     }
-    if (dev->realized) {
-        object_property_set_bool(obj, false, "realized", NULL);
-    }
     if (dev->parent_bus) {
         bus_remove_child(dev->parent_bus, dev);
         object_unref(OBJECT(dev->parent_bus));