aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/eeh_driver.c
diff options
context:
space:
mode:
authorLinas Vepstas <linas@austin.ibm.com>2007-03-19 16:01:31 -0400
committerPaul Mackerras <paulus@samba.org>2007-03-22 07:52:57 -0400
commit4980d5eb750288ffc0bb9daff3feb947e1bac61e (patch)
treeb9c8334610e1096b4c3f9a81928dd9d5ee384329 /arch/powerpc/platforms/pseries/eeh_driver.c
parentfa1be476a2baa0961f63161caee6733cdc353adb (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.c30
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
250static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) 250static 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,