diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c index 7a5af873d8bce41030da847c887f6176aeda10dc..46a5b84f88427099c41e1e1b0845640a9b4ac886 100644 --- a/drivers/pci/pcie/err.c +++ b/drivers/pci/pcie/err.c @@ -151,24 +151,27 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev, pci_ers_result_t (*reset_subordinates)(struct pci_dev *pdev)) { int type = pci_pcie_type(dev); - pci_ers_result_t status = PCI_ERS_RESULT_CAN_RECOVER; + struct pci_dev *bridge; struct pci_bus *bus; + pci_ers_result_t status = PCI_ERS_RESULT_CAN_RECOVER; /* - * Error recovery runs on all subordinates of the first downstream port. - * If the downstream port detected the error, it is cleared at the end. + * Error recovery runs on all subordinates of the bridge. If the + * bridge detected the error, it is cleared at the end. */ if (!(type == PCI_EXP_TYPE_ROOT_PORT || type == PCI_EXP_TYPE_DOWNSTREAM)) - dev = pci_upstream_bridge(dev); - bus = dev->subordinate; + bridge = pci_upstream_bridge(dev); + else + bridge = dev; - pci_dbg(dev, "broadcast error_detected message\n"); + bus = bridge->subordinate; + pci_dbg(bridge, "broadcast error_detected message\n"); if (state == pci_channel_io_frozen) { pci_walk_bus(bus, report_frozen_detected, &status); - status = reset_subordinates(dev); + status = reset_subordinates(bridge); if (status != PCI_ERS_RESULT_RECOVERED) { - pci_warn(dev, "subordinate device reset failed\n"); + pci_warn(bridge, "subordinate device reset failed\n"); goto failed; } } else { @@ -177,7 +180,7 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev, if (status == PCI_ERS_RESULT_CAN_RECOVER) { status = PCI_ERS_RESULT_RECOVERED; - pci_dbg(dev, "broadcast mmio_enabled message\n"); + pci_dbg(bridge, "broadcast mmio_enabled message\n"); pci_walk_bus(bus, report_mmio_enabled, &status); } @@ -188,27 +191,27 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev, * drivers' slot_reset callbacks? */ status = PCI_ERS_RESULT_RECOVERED; - pci_dbg(dev, "broadcast slot_reset message\n"); + pci_dbg(bridge, "broadcast slot_reset message\n"); pci_walk_bus(bus, report_slot_reset, &status); } if (status != PCI_ERS_RESULT_RECOVERED) goto failed; - pci_dbg(dev, "broadcast resume message\n"); + pci_dbg(bridge, "broadcast resume message\n"); pci_walk_bus(bus, report_resume, &status); - if (pcie_aer_is_native(dev)) - pcie_clear_device_status(dev); - pci_aer_clear_nonfatal_status(dev); - pci_info(dev, "device recovery successful\n"); + if (pcie_aer_is_native(bridge)) + pcie_clear_device_status(bridge); + pci_aer_clear_nonfatal_status(bridge); + pci_info(bridge, "device recovery successful\n"); return status; failed: - pci_uevent_ers(dev, PCI_ERS_RESULT_DISCONNECT); + pci_uevent_ers(bridge, PCI_ERS_RESULT_DISCONNECT); /* TODO: Should kernel panic here? */ - pci_info(dev, "device recovery failed\n"); + pci_info(bridge, "device recovery failed\n"); return status; }