qemu/0002-qdev-allow-both-pre-and-post-order-vists-in-qdev-wal.patch
Cole Robinson bacd9b0468 Fix qemu-img create with NBD backing file (bz #1034433)
Rebase to qemu-1.7 GA
New monitor command blockdev-add for full featured block device hotplug.
Performance and functionality improvements for USB 3.0.
Many VFIO improvements
ACPI tables can be generated by QEMU and can be used by firmware directly.
Support creating and writing .vhdx images.
qemu-img map: dump detailed image file metadata
2013-12-03 06:36:52 -05:00

142 lines
4.6 KiB
Diff

From 60ab1ca9f2a40610902b610fa0a06fccea7f0f57 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Thu, 2 May 2013 11:38:38 +0200
Subject: [PATCH] qdev: allow both pre- and post-order vists in qdev walking
functions
Resetting should be done in post-order, not pre-order. However,
qdev_walk_children and qbus_walk_children do not allow this. Fix
it by adding two extra arguments to the functions.
Tested-by: Claudio Bley <cbley@av-test.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/core/qdev.c | 45 +++++++++++++++++++++++++++++++++------------
include/hw/qdev-core.h | 13 +++++++++----
2 files changed, 42 insertions(+), 16 deletions(-)
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index e374a93..5ddf1aa 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -240,12 +240,12 @@ static int qbus_reset_one(BusState *bus, void *opaque)
void qdev_reset_all(DeviceState *dev)
{
- qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
+ qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL);
}
void qbus_reset_all(BusState *bus)
{
- qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL);
+ qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL);
}
void qbus_reset_all_fn(void *opaque)
@@ -337,49 +337,70 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
return NULL;
}
-int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
- qbus_walkerfn *busfn, void *opaque)
+int qbus_walk_children(BusState *bus,
+ qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
+ qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
+ void *opaque)
{
BusChild *kid;
int err;
- if (busfn) {
- err = busfn(bus, opaque);
+ if (pre_busfn) {
+ err = pre_busfn(bus, opaque);
if (err) {
return err;
}
}
QTAILQ_FOREACH(kid, &bus->children, sibling) {
- err = qdev_walk_children(kid->child, devfn, busfn, opaque);
+ err = qdev_walk_children(kid->child,
+ pre_devfn, pre_busfn,
+ post_devfn, post_busfn, opaque);
if (err < 0) {
return err;
}
}
+ if (post_busfn) {
+ err = post_busfn(bus, opaque);
+ if (err) {
+ return err;
+ }
+ }
+
return 0;
}
-int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
- qbus_walkerfn *busfn, void *opaque)
+int qdev_walk_children(DeviceState *dev,
+ qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
+ qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
+ void *opaque)
{
BusState *bus;
int err;
- if (devfn) {
- err = devfn(dev, opaque);
+ if (pre_devfn) {
+ err = pre_devfn(dev, opaque);
if (err) {
return err;
}
}
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
- err = qbus_walk_children(bus, devfn, busfn, opaque);
+ err = qbus_walk_children(bus, pre_devfn, pre_busfn,
+ post_devfn, post_busfn, opaque);
if (err < 0) {
return err;
}
}
+ if (post_devfn) {
+ err = post_devfn(dev, opaque);
+ if (err) {
+ return err;
+ }
+ }
+
return 0;
}
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index f2043a6..ecf5cb3 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -253,10 +253,15 @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam
/* Returns > 0 if either devfn or busfn skip walk somewhere in cursion,
* < 0 if either devfn or busfn terminate walk somewhere in cursion,
* 0 otherwise. */
-int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
- qbus_walkerfn *busfn, void *opaque);
-int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
- qbus_walkerfn *busfn, void *opaque);
+int qbus_walk_children(BusState *bus,
+ qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
+ qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
+ void *opaque);
+int qdev_walk_children(DeviceState *dev,
+ qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn,
+ qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn,
+ void *opaque);
+
void qdev_reset_all(DeviceState *dev);
/**