diff options
author | Linas Vepstas <linas@austin.ibm.com> | 2007-03-19 16:01:31 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-03-22 07:52:57 -0400 |
commit | 4980d5eb750288ffc0bb9daff3feb947e1bac61e (patch) | |
tree | b9c8334610e1096b4c3f9a81928dd9d5ee384329 /arch/powerpc/platforms/pseries/eeh_driver.c | |
parent | fa1be476a2baa0961f63161caee6733cdc353adb (diff) |
[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: Linas Vepstas <linas@austin.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/pseries/eeh_driver.c')
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh_driver.c | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c index f5b4f7c20d7a..8cc331eecc9d 100644 --- a/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/arch/powerpc/platforms/pseries/eeh_driver.c | |||
@@ -249,6 +249,7 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata) | |||
249 | 249 | ||
250 | static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) | 250 | static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) |
251 | { | 251 | { |
252 | struct device_node *dn; | ||
252 | int cnt, rc; | 253 | int cnt, rc; |
253 | 254 | ||
254 | /* pcibios will clear the counter; save the value */ | 255 | /* pcibios will clear the counter; save the value */ |
@@ -264,23 +265,20 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) | |||
264 | if (rc) | 265 | if (rc) |
265 | return rc; | 266 | return rc; |
266 | 267 | ||
267 | /* New-style config addrs might be shared across multiple devices, | 268 | /* Walk over all functions on this device. */ |
268 | * Walk over all functions on this device */ | 269 | dn = pe_dn->node; |
269 | if (pe_dn->eeh_pe_config_addr) { | 270 | if (!pcibios_find_pci_bus(dn) && PCI_DN(dn->parent)) |
270 | struct device_node *pe = pe_dn->node; | 271 | dn = dn->parent->child; |
271 | pe = pe->parent->child; | 272 | |
272 | while (pe) { | 273 | while (dn) { |
273 | struct pci_dn *ppe = PCI_DN(pe); | 274 | struct pci_dn *ppe = PCI_DN(dn); |
274 | if (pe_dn->eeh_pe_config_addr == ppe->eeh_pe_config_addr) { | 275 | /* On Power4, always true because eeh_pe_config_addr=0 */ |
275 | rtas_configure_bridge(ppe); | 276 | if (pe_dn->eeh_pe_config_addr == ppe->eeh_pe_config_addr) { |
276 | eeh_restore_bars(ppe); | 277 | rtas_configure_bridge(ppe); |
277 | } | 278 | eeh_restore_bars(ppe); |
278 | pe = pe->sibling; | ||
279 | } | 279 | } |
280 | } else { | 280 | dn = dn->sibling; |
281 | rtas_configure_bridge(pe_dn); | 281 | } |
282 | eeh_restore_bars(pe_dn); | ||
283 | } | ||
284 | 282 | ||
285 | /* Give the system 5 seconds to finish running the user-space | 283 | /* Give the system 5 seconds to finish running the user-space |
286 | * hotplug shutdown scripts, e.g. ifdown for ethernet. Yes, | 284 | * hotplug shutdown scripts, e.g. ifdown for ethernet. Yes, |