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)
dn = find_device_pe (dn);
/* 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;
PCI_DN(dn)->eeh_mode |= mode_flag;
......@@ -316,7 +316,7 @@ void eeh_clear_slot (struct device_node *dn, int mode_flag)
dn = find_device_pe (dn);
/* 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;
PCI_DN(dn)->eeh_mode &= ~mode_flag;
......
......@@ -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)
{
struct device_node *dn;
int cnt, rc;
/* 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)
if (rc)
return rc;
/* New-style config addrs might be shared across multiple devices,
* Walk over all functions on this device */
if (pe_dn->eeh_pe_config_addr) {
struct device_node *pe = pe_dn->node;
pe = pe->parent->child;
while (pe) {
struct pci_dn *ppe = PCI_DN(pe);
/* Walk over all functions on this device. */
dn = pe_dn->node;
if (!pcibios_find_pci_bus(dn) && PCI_DN(dn->parent))
dn = dn->parent->child;
while (dn) {
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) {
rtas_configure_bridge(ppe);
eeh_restore_bars(ppe);
}
pe = pe->sibling;
}
} else {
rtas_configure_bridge(pe_dn);
eeh_restore_bars(pe_dn);
dn = dn->sibling;
}
/* 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