diff options
author | Linas Vepstas <linas@linas.org> | 2005-11-03 19:54:54 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-09 23:30:14 -0500 |
commit | b6495c0c8f100b882d85774f44529519befefba9 (patch) | |
tree | ec38027b7e7e50ffbe843a5333fbf95456bc1cf5 /arch/powerpc/platforms/pseries/eeh.c | |
parent | 21e464dd7c943c984dcccd9aff8c9f6a5ea920d7 (diff) |
[PATCH] powerpc: Don't continue with PCI Error recovery if slot reset failed.
238-eeh-stop-if-reset_failed.patch
If the firmware is unable to reset the PCI slot for some reason, then
don't attempt any further recovery steps after that point. Instead,
mark the device as permanently failed.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
(cherry picked from e06b942521eb2cdaf232726f45a820d5837acb12 commit)
Diffstat (limited to 'arch/powerpc/platforms/pseries/eeh.c')
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index d8d24502970f..b0fa76d0c78a 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -450,11 +450,16 @@ eeh_slot_availability(struct pci_dn *pdn) | |||
450 | if (rc) return rc; | 450 | if (rc) return rc; |
451 | 451 | ||
452 | if (rets[1] == 0) return -1; /* EEH is not supported */ | 452 | if (rets[1] == 0) return -1; /* EEH is not supported */ |
453 | if (rets[0] == 0) return 0; /* Oll Korrect */ | 453 | if (rets[0] == 0) return 0; /* Oll Korrect */ |
454 | if (rets[0] == 5) { | 454 | if (rets[0] == 5) { |
455 | if (rets[2] == 0) return -1; /* permanently unavailable */ | 455 | if (rets[2] == 0) return -1; /* permanently unavailable */ |
456 | return rets[2]; /* number of millisecs to wait */ | 456 | return rets[2]; /* number of millisecs to wait */ |
457 | } | 457 | } |
458 | if (rets[0] == 1) | ||
459 | return 250; | ||
460 | |||
461 | printk (KERN_ERR "EEH: Slot unavailable: rc=%d, rets=%d %d %d\n", | ||
462 | rc, rets[0], rets[1], rets[2]); | ||
458 | return -1; | 463 | return -1; |
459 | } | 464 | } |
460 | 465 | ||
@@ -501,9 +506,11 @@ rtas_pci_slot_reset(struct pci_dn *pdn, int state) | |||
501 | 506 | ||
502 | /** rtas_set_slot_reset -- assert the pci #RST line for 1/4 second | 507 | /** rtas_set_slot_reset -- assert the pci #RST line for 1/4 second |
503 | * dn -- device node to be reset. | 508 | * dn -- device node to be reset. |
509 | * | ||
510 | * Return 0 if success, else a non-zero value. | ||
504 | */ | 511 | */ |
505 | 512 | ||
506 | void | 513 | int |
507 | rtas_set_slot_reset(struct pci_dn *pdn) | 514 | rtas_set_slot_reset(struct pci_dn *pdn) |
508 | { | 515 | { |
509 | int i, rc; | 516 | int i, rc; |
@@ -533,10 +540,21 @@ rtas_set_slot_reset(struct pci_dn *pdn) | |||
533 | * ready to be used; if not, wait for recovery. */ | 540 | * ready to be used; if not, wait for recovery. */ |
534 | for (i=0; i<10; i++) { | 541 | for (i=0; i<10; i++) { |
535 | rc = eeh_slot_availability (pdn); | 542 | rc = eeh_slot_availability (pdn); |
536 | if (rc <= 0) break; | 543 | if (rc < 0) |
544 | printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n", rc, pdn->node->full_name); | ||
545 | if (rc == 0) | ||
546 | return 0; | ||
547 | if (rc < 0) | ||
548 | return -1; | ||
537 | 549 | ||
538 | msleep (rc+100); | 550 | msleep (rc+100); |
539 | } | 551 | } |
552 | |||
553 | rc = eeh_slot_availability (pdn); | ||
554 | if (rc) | ||
555 | printk (KERN_ERR "EEH: timeout resetting slot %s\n", pdn->node->full_name); | ||
556 | |||
557 | return rc; | ||
540 | } | 558 | } |
541 | 559 | ||
542 | /* ------------------------------------------------------- */ | 560 | /* ------------------------------------------------------- */ |