Commit 8cdb2833 authored by Gavin Shan's avatar Gavin Shan Committed by Benjamin Herrenschmidt

powerpc/eeh: Trace PCI bus from PE

There're several types of PEs can be supported for now: PHB, Bus
and Device dependent PE. For PCI bus dependent PE, tracing the
corresponding PCI bus from PE (struct eeh_pe) would make the code
more efficient. The patch also enables the retrieval of PCI bus based
on the PCI bus dependent PE.
Signed-off-by: default avatarGavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 01566808
...@@ -59,6 +59,7 @@ struct eeh_pe { ...@@ -59,6 +59,7 @@ struct eeh_pe {
int config_addr; /* Traditional PCI address */ int config_addr; /* Traditional PCI address */
int addr; /* PE configuration address */ int addr; /* PE configuration address */
struct pci_controller *phb; /* Associated PHB */ struct pci_controller *phb; /* Associated PHB */
struct pci_bus *bus; /* Top PCI bus for bus PE */
int check_count; /* Times of ignored error */ int check_count; /* Times of ignored error */
int freeze_count; /* Times of froze up */ int freeze_count; /* Times of froze up */
int false_positives; /* Times of reported #ff's */ int false_positives; /* Times of reported #ff's */
......
...@@ -364,6 +364,17 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) ...@@ -364,6 +364,17 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
pe->addr = edev->pe_config_addr; pe->addr = edev->pe_config_addr;
pe->config_addr = edev->config_addr; pe->config_addr = edev->config_addr;
/*
* While doing PE reset, we probably hot-reset the
* upstream bridge. However, the PCI devices including
* the associated EEH devices might be removed when EEH
* core is doing recovery. So that won't safe to retrieve
* the bridge through downstream EEH device. We have to
* trace the parent PCI bus, then the upstream bridge.
*/
if (eeh_probe_mode_dev())
pe->bus = eeh_dev_to_pci_dev(edev)->bus;
/* /*
* Put the new EEH PE into hierarchy tree. If the parent * Put the new EEH PE into hierarchy tree. If the parent
* can't be found, the newly created PE will be attached * can't be found, the newly created PE will be attached
...@@ -641,12 +652,18 @@ struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe) ...@@ -641,12 +652,18 @@ struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
bus = pe->phb->bus; bus = pe->phb->bus;
} else if (pe->type & EEH_PE_BUS || } else if (pe->type & EEH_PE_BUS ||
pe->type & EEH_PE_DEVICE) { pe->type & EEH_PE_DEVICE) {
if (pe->bus) {
bus = pe->bus;
goto out;
}
edev = list_first_entry(&pe->edevs, struct eeh_dev, list); edev = list_first_entry(&pe->edevs, struct eeh_dev, list);
pdev = eeh_dev_to_pci_dev(edev); pdev = eeh_dev_to_pci_dev(edev);
if (pdev) if (pdev)
bus = pdev->bus; bus = pdev->bus;
} }
out:
eeh_unlock(); eeh_unlock();
return bus; return bus;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment