summaryrefslogtreecommitdiff
path: root/drivers/pci/pcie/err.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pcie/err.c')
-rw-r--r--drivers/pci/pcie/err.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index 8b53aecdb43d..d89d7ed70768 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -148,13 +148,16 @@ out:
/**
* pci_walk_bridge - walk bridges potentially AER affected
- * @bridge: bridge which may be a Port
+ * @bridge: bridge which may be a Port or an RCEC
* @cb: callback to be called for each device found
* @userdata: arbitrary pointer to be passed to callback
*
* If the device provided is a bridge, walk the subordinate bus, including
* any bridged devices on buses under this bus. Call the provided callback
* on each device found.
+ *
+ * If the device provided has no subordinate bus, e.g., an RCEC, call the
+ * callback on the device itself.
*/
static void pci_walk_bridge(struct pci_dev *bridge,
int (*cb)(struct pci_dev *, void *),
@@ -162,6 +165,8 @@ static void pci_walk_bridge(struct pci_dev *bridge,
{
if (bridge->subordinate)
pci_walk_bus(bridge->subordinate, cb, userdata);
+ else
+ cb(bridge, userdata);
}
pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
@@ -173,11 +178,17 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
pci_ers_result_t status = PCI_ERS_RESULT_CAN_RECOVER;
/*
- * Error recovery runs on all subordinates of the bridge. If the
- * bridge detected the error, it is cleared at the end.
+ * If the error was detected by a Root Port, Downstream Port, or
+ * RCEC, recovery runs on the device itself. For Ports, that also
+ * includes any subordinate devices.
+ *
+ * If it was detected by another device (Endpoint, etc), recovery
+ * runs on the device and anything else under the same Port, i.e.,
+ * everything under "bridge".
*/
if (type == PCI_EXP_TYPE_ROOT_PORT ||
- type == PCI_EXP_TYPE_DOWNSTREAM)
+ type == PCI_EXP_TYPE_DOWNSTREAM ||
+ type == PCI_EXP_TYPE_RC_EC)
bridge = dev;
else
bridge = pci_upstream_bridge(dev);