From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36709) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uyj1Q-0003rh-Ea for qemu-devel@nongnu.org; Mon, 15 Jul 2013 09:41:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Uyj1I-0006jW-5P for qemu-devel@nongnu.org; Mon, 15 Jul 2013 09:41:00 -0400 Received: from cantor2.suse.de ([195.135.220.15]:42097 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uyj1H-0006j5-Pz for qemu-devel@nongnu.org; Mon, 15 Jul 2013 09:40:52 -0400 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Mon, 15 Jul 2013 15:40:37 +0200 Message-Id: <1373895639-21476-2-git-send-email-afaerber@suse.de> In-Reply-To: <1373895639-21476-1-git-send-email-afaerber@suse.de> References: <1373895639-21476-1-git-send-email-afaerber@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH RFC 1/3] qdev: Add support for recursive realization List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Paolo Bonzini , =?UTF-8?q?Andreas=20F=C3=A4rber?= , Anthony Liguori Add realize_children and unrealize_children QOM methods to DeviceClass. Call them after realized =3D true and before realized =3D false respectiv= ely. The default implementation walks busses and realizes their devices. Signed-off-by: Paolo Bonzini [AF: Transferred from Object to DeviceState] Signed-off-by: Andreas F=C3=A4rber --- hw/core/qdev.c | 58 ++++++++++++++++++++++++++++++++++++++++++++= ++---- include/hw/qdev-core.h | 4 ++++ 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 9190a7e..33e874a 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -183,6 +183,29 @@ static void device_realize(DeviceState *dev, Error *= *err) } } =20 +static int device_realize_one(DeviceState *dev, void *opaque) +{ + Error **errp =3D opaque; + Error *err =3D NULL; + + object_property_set_bool(OBJECT(dev), true, "realized", &err); + if (err !=3D NULL) { + error_propagate(errp, err); + return -1; + } + return 0; +} + +static int bus_realize_children(BusState *bus, void *opaque) +{ + return qbus_walk_children(bus, device_realize_one, NULL, opaque); +} + +static void device_realize_children(DeviceState *dev, Error **errp) +{ + qdev_walk_children(dev, NULL, bus_realize_children, errp); +} + static void device_unrealize(DeviceState *dev, Error **errp) { DeviceClass *dc =3D DEVICE_GET_CLASS(dev); @@ -196,6 +219,29 @@ static void device_unrealize(DeviceState *dev, Error= **errp) } } =20 +static int device_unrealize_one(DeviceState *dev, void *opaque) +{ + Error **errp =3D opaque; + Error *err =3D NULL; + + object_property_set_bool(OBJECT(dev), false, "realized", &err); + if (err !=3D NULL) { + error_propagate(errp, err); + return -1; + } + return 0; +} + +static int bus_unrealize_children(BusState *bus, void *opaque) +{ + return qbus_walk_children(bus, device_unrealize_one, NULL, opaque); +} + +static void device_unrealize_children(DeviceState *dev, Error **errp) +{ + qdev_walk_children(dev, NULL, bus_unrealize_children, errp); +} + void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id, int required_for_version) { @@ -678,7 +724,7 @@ static bool device_get_realized(Object *obj, Error **= err) return dev->realized; } =20 -static void device_set_realized(Object *obj, bool value, Error **err) +static void device_set_realized(Object *obj, bool value, Error **errp) { DeviceState *dev =3D DEVICE(obj); DeviceClass *dc =3D DEVICE_GET_CLASS(dev); @@ -704,24 +750,26 @@ static void device_set_realized(Object *obj, bool v= alue, Error **err) dev->instance_id_alias, dev->alias_required_for_versi= on); } + dev->realized =3D true; + dc->realize_children(dev, errp); if (dev->hotplugged && local_err =3D=3D NULL) { device_reset(dev); } } else if (!value && dev->realized) { + dc->unrealize_children(dev, errp); if (qdev_get_vmsd(dev)) { vmstate_unregister(dev, qdev_get_vmsd(dev), dev); } if (dc->unrealize) { dc->unrealize(dev, &local_err); } + dev->realized =3D false; } =20 if (local_err !=3D NULL) { - error_propagate(err, local_err); + error_propagate(errp, local_err); return; } - - dev->realized =3D value; } =20 static void device_initfn(Object *obj) @@ -825,7 +873,9 @@ static void device_class_init(ObjectClass *class, voi= d *data) =20 class->unparent =3D device_unparent; dc->realize =3D device_realize; + dc->realize_children =3D device_realize_children; dc->unrealize =3D device_unrealize; + dc->unrealize_children =3D device_unrealize_children; } =20 void device_reset(DeviceState *dev) diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 7fbffcb..81dc2f3 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -21,7 +21,9 @@ typedef int (*qdev_initfn)(DeviceState *dev); typedef int (*qdev_event)(DeviceState *dev); typedef void (*qdev_resetfn)(DeviceState *dev); typedef void (*DeviceRealize)(DeviceState *dev, Error **errp); +typedef void (*DeviceRealizeChildren)(DeviceState *dev, Error **errp); typedef void (*DeviceUnrealize)(DeviceState *dev, Error **errp); +typedef void (*DeviceUnrealizeChildren)(DeviceState *dev, Error **errp); =20 struct VMStateDescription; =20 @@ -88,7 +90,9 @@ typedef struct DeviceClass { /* callbacks */ void (*reset)(DeviceState *dev); DeviceRealize realize; + DeviceRealizeChildren realize_children; DeviceUnrealize unrealize; + DeviceUnrealizeChildren unrealize_children; =20 /* device state */ const struct VMStateDescription *vmsd; --=20 1.8.1.4