Blame 0006-qdev-switch-reset-to-post-order.patch

9e0a86
From 59164410b2f021d53be2ce45630647e952ccf9c2 Mon Sep 17 00:00:00 2001
9e0a86
From: Paolo Bonzini <pbonzini@redhat.com>
9e0a86
Date: Thu, 2 May 2013 11:38:39 +0200
9e0a86
Subject: [PATCH] qdev: switch reset to post-order
9e0a86
9e0a86
Post-order is the only sensible direction for the reset signals.
9e0a86
For example, suppose pre-order is used and the parent has some data
9e0a86
structures that cache children state (for example a list of active
9e0a86
requests).  When the reset method is invoked on the parent, these caches
9e0a86
could be in any state.
9e0a86
9e0a86
If post-order is used, on the other hand, these will be in a known state
9e0a86
when the reset method is invoked on the parent.
9e0a86
9e0a86
This change means that it is no longer possible to block the visit of
9e0a86
the devices, so the callback is changed to return void.  This is not
9e0a86
a problem, because PCI was returning 1 exactly in order to achieve the
9e0a86
same ordering that this patch implements.
9e0a86
9e0a86
PCI can then rely on the qdev core having sent a "reset signal"
9e0a86
(whatever that means) to the device, and only do the PCI-specific
9e0a86
initialization with the new function pci_do_device_reset, extracted
9e0a86
from pci_device_reset.  There is no change in the operation of FLR,
9e0a86
which used and still uses pci_device_reset.
9e0a86
9e0a86
Tested-by: Claudio Bley <cbley@av-test.de>
9e0a86
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
9e0a86
---
9e0a86
 hw/core/qdev.c         |  6 +++---
9e0a86
 hw/pci/pci.c           | 31 ++++++++++++++++---------------
9e0a86
 include/hw/qdev-core.h |  2 +-
9e0a86
 3 files changed, 20 insertions(+), 19 deletions(-)
9e0a86
9e0a86
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
9e0a86
index 842804f..87d7e1e 100644
9e0a86
--- a/hw/core/qdev.c
9e0a86
+++ b/hw/core/qdev.c
9e0a86
@@ -233,19 +233,19 @@ static int qbus_reset_one(BusState *bus, void *opaque)
9e0a86
 {
9e0a86
     BusClass *bc = BUS_GET_CLASS(bus);
9e0a86
     if (bc->reset) {
9e0a86
-        return bc->reset(bus);
9e0a86
+        bc->reset(bus);
9e0a86
     }
9e0a86
     return 0;
9e0a86
 }
9e0a86
 
9e0a86
 void qdev_reset_all(DeviceState *dev)
9e0a86
 {
9e0a86
-    qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL);
9e0a86
+    qdev_walk_children(dev, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
9e0a86
 }
9e0a86
 
9e0a86
 void qbus_reset_all(BusState *bus)
9e0a86
 {
9e0a86
-    qbus_walk_children(bus, qdev_reset_one, qbus_reset_one, NULL, NULL, NULL);
9e0a86
+    qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL);
9e0a86
 }
9e0a86
 
9e0a86
 void qbus_reset_all_fn(void *opaque)
9e0a86
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
9e0a86
index 0389375..bbca696 100644
9e0a86
--- a/hw/pci/pci.c
9e0a86
+++ b/hw/pci/pci.c
9e0a86
@@ -46,7 +46,7 @@
9e0a86
 static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
9e0a86
 static char *pcibus_get_dev_path(DeviceState *dev);
9e0a86
 static char *pcibus_get_fw_dev_path(DeviceState *dev);
9e0a86
-static int pcibus_reset(BusState *qbus);
9e0a86
+static void pcibus_reset(BusState *qbus);
9e0a86
 
9e0a86
 static Property pci_props[] = {
9e0a86
     DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
9e0a86
@@ -165,16 +165,10 @@ void pci_device_deassert_intx(PCIDevice *dev)
9e0a86
     }
9e0a86
 }
9e0a86
 
9e0a86
-/*
9e0a86
- * This function is called on #RST and FLR.
9e0a86
- * FLR if PCI_EXP_DEVCTL_BCR_FLR is set
9e0a86
- */
9e0a86
-void pci_device_reset(PCIDevice *dev)
9e0a86
+static void pci_do_device_reset(PCIDevice *dev)
9e0a86
 {
9e0a86
     int r;
9e0a86
 
9e0a86
-    qdev_reset_all(&dev->qdev);
9e0a86
-
9e0a86
     dev->irq_state = 0;
9e0a86
     pci_update_irq_status(dev);
9e0a86
     pci_device_deassert_intx(dev);
9e0a86
@@ -207,10 +201,21 @@ void pci_device_reset(PCIDevice *dev)
9e0a86
 }
9e0a86
 
9e0a86
 /*
9e0a86
+ * This function is called on #RST and FLR.
9e0a86
+ * FLR if PCI_EXP_DEVCTL_BCR_FLR is set
9e0a86
+ */
9e0a86
+void pci_device_reset(PCIDevice *dev)
9e0a86
+{
9e0a86
+    qdev_reset_all(&dev->qdev);
9e0a86
+    pci_do_device_reset(dev);
9e0a86
+}
9e0a86
+
9e0a86
+/*
9e0a86
  * Trigger pci bus reset under a given bus.
9e0a86
- * To be called on RST# assert.
9e0a86
+ * Called via qbus_reset_all on RST# assert, after the devices
9e0a86
+ * have been reset qdev_reset_all-ed already.
9e0a86
  */
9e0a86
-static int pcibus_reset(BusState *qbus)
9e0a86
+static void pcibus_reset(BusState *qbus)
9e0a86
 {
9e0a86
     PCIBus *bus = DO_UPCAST(PCIBus, qbus, qbus);
9e0a86
     int i;
9e0a86
@@ -220,13 +225,9 @@ static int pcibus_reset(BusState *qbus)
9e0a86
     }
9e0a86
     for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
9e0a86
         if (bus->devices[i]) {
9e0a86
-            pci_device_reset(bus->devices[i]);
9e0a86
+            pci_do_device_reset(bus->devices[i]);
9e0a86
         }
9e0a86
     }
9e0a86
-
9e0a86
-    /* topology traverse is done by pci_bus_reset().
9e0a86
-       Tell qbus/qdev walker not to traverse the tree */
9e0a86
-    return 1;
9e0a86
 }
9e0a86
 
9e0a86
 static void pci_host_bus_register(PCIBus *bus, DeviceState *parent)
9e0a86
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
9e0a86
index c6c9b14..89dcbad 100644
9e0a86
--- a/include/hw/qdev-core.h
9e0a86
+++ b/include/hw/qdev-core.h
9e0a86
@@ -174,7 +174,7 @@ struct BusClass {
9e0a86
      * bindings can be found at http://playground.sun.com/1275/bindings/.
9e0a86
      */
9e0a86
     char *(*get_fw_dev_path)(DeviceState *dev);
9e0a86
-    int (*reset)(BusState *bus);
9e0a86
+    void (*reset)(BusState *bus);
9e0a86
     /* maximum devices allowed on the bus, 0: no limit. */
9e0a86
     int max_dev;
9e0a86
 };