Commit 4980d5eb authored by Linas Vepstas's avatar Linas Vepstas Committed by Paul Mackerras

[POWERPC] EEH: restructure multi-function support

Rework how multi-function PCI devices are identified and traversed.
This fixes a bug with multi-function recovery on Power4 that was
introduced by a recent Power4 EEH patch.
Signed-off-by: default avatarLinas Vepstas <linas@austin.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent fa1be476
...@@ -282,7 +282,7 @@ void eeh_mark_slot (struct device_node *dn, int mode_flag) ...@@ -282,7 +282,7 @@ void eeh_mark_slot (struct device_node *dn, int mode_flag)
dn = find_device_pe (dn); dn = find_device_pe (dn);
/* Back up one, since config addrs might be shared */ /* Back up one, since config addrs might be shared */
if (PCI_DN(dn) && PCI_DN(dn)->eeh_pe_config_addr) if (!pcibios_find_pci_bus(dn) && PCI_DN(dn->parent))
dn = dn->parent; dn = dn->parent;
PCI_DN(dn)->eeh_mode |= mode_flag; PCI_DN(dn)->eeh_mode |= mode_flag;
...@@ -316,7 +316,7 @@ void eeh_clear_slot (struct device_node *dn, int mode_flag) ...@@ -316,7 +316,7 @@ void eeh_clear_slot (struct device_node *dn, int mode_flag)
dn = find_device_pe (dn); dn = find_device_pe (dn);
/* Back up one, since config addrs might be shared */ /* Back up one, since config addrs might be shared */
if (PCI_DN(dn) && PCI_DN(dn)->eeh_pe_config_addr) if (!pcibios_find_pci_bus(dn) && PCI_DN(dn->parent))
dn = dn->parent; dn = dn->parent;
PCI_DN(dn)->eeh_mode &= ~mode_flag; PCI_DN(dn)->eeh_mode &= ~mode_flag;
......
...@@ -249,6 +249,7 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata) ...@@ -249,6 +249,7 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata)
static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
{ {
struct device_node *dn;
int cnt, rc; int cnt, rc;
/* pcibios will clear the counter; save the value */ /* pcibios will clear the counter; save the value */
...@@ -264,22 +265,19 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) ...@@ -264,22 +265,19 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
if (rc) if (rc)
return rc; return rc;
/* New-style config addrs might be shared across multiple devices, /* Walk over all functions on this device. */
* Walk over all functions on this device */ dn = pe_dn->node;
if (pe_dn->eeh_pe_config_addr) { if (!pcibios_find_pci_bus(dn) && PCI_DN(dn->parent))
struct device_node *pe = pe_dn->node; dn = dn->parent->child;
pe = pe->parent->child;
while (pe) { while (dn) {
struct pci_dn *ppe = PCI_DN(pe); struct pci_dn *ppe = PCI_DN(dn);
/* On Power4, always true because eeh_pe_config_addr=0 */
if (pe_dn->eeh_pe_config_addr == ppe->eeh_pe_config_addr) { if (pe_dn->eeh_pe_config_addr == ppe->eeh_pe_config_addr) {
rtas_configure_bridge(ppe); rtas_configure_bridge(ppe);
eeh_restore_bars(ppe); eeh_restore_bars(ppe);
} }
pe = pe->sibling; dn = dn->sibling;
}
} else {
rtas_configure_bridge(pe_dn);
eeh_restore_bars(pe_dn);
} }
/* Give the system 5 seconds to finish running the user-space /* Give the system 5 seconds to finish running the user-space
......
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