diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 4534886e3b4e..84bc8f7e17ef 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -478,7 +478,7 @@ eeh_slot_availability(struct pci_dn *pdn) | |||
478 | 478 | ||
479 | printk (KERN_ERR "EEH: Slot unavailable: rc=%d, rets=%d %d %d\n", | 479 | printk (KERN_ERR "EEH: Slot unavailable: rc=%d, rets=%d %d %d\n", |
480 | rc, rets[0], rets[1], rets[2]); | 480 | rc, rets[0], rets[1], rets[2]); |
481 | return -1; | 481 | return -2; |
482 | } | 482 | } |
483 | 483 | ||
484 | /** | 484 | /** |
@@ -546,11 +546,10 @@ rtas_pci_slot_reset(struct pci_dn *pdn, int state) | |||
546 | BUID_HI(pdn->phb->buid), | 546 | BUID_HI(pdn->phb->buid), |
547 | BUID_LO(pdn->phb->buid), | 547 | BUID_LO(pdn->phb->buid), |
548 | state); | 548 | state); |
549 | if (rc) { | 549 | if (rc) |
550 | printk (KERN_WARNING "EEH: Unable to reset the failed slot, (%d) #RST=%d dn=%s\n", | 550 | printk (KERN_WARNING "EEH: Unable to reset the failed slot," |
551 | " (%d) #RST=%d dn=%s\n", | ||
551 | rc, state, pdn->node->full_name); | 552 | rc, state, pdn->node->full_name); |
552 | return; | ||
553 | } | ||
554 | } | 553 | } |
555 | 554 | ||
556 | /** | 555 | /** |
@@ -560,11 +559,8 @@ rtas_pci_slot_reset(struct pci_dn *pdn, int state) | |||
560 | * Return 0 if success, else a non-zero value. | 559 | * Return 0 if success, else a non-zero value. |
561 | */ | 560 | */ |
562 | 561 | ||
563 | int | 562 | static void __rtas_set_slot_reset(struct pci_dn *pdn) |
564 | rtas_set_slot_reset(struct pci_dn *pdn) | ||
565 | { | 563 | { |
566 | int i, rc; | ||
567 | |||
568 | rtas_pci_slot_reset (pdn, 1); | 564 | rtas_pci_slot_reset (pdn, 1); |
569 | 565 | ||
570 | /* The PCI bus requires that the reset be held high for at least | 566 | /* The PCI bus requires that the reset be held high for at least |
@@ -585,17 +581,33 @@ rtas_set_slot_reset(struct pci_dn *pdn) | |||
585 | * up traffic. */ | 581 | * up traffic. */ |
586 | #define PCI_BUS_SETTLE_TIME_MSEC 1800 | 582 | #define PCI_BUS_SETTLE_TIME_MSEC 1800 |
587 | msleep (PCI_BUS_SETTLE_TIME_MSEC); | 583 | msleep (PCI_BUS_SETTLE_TIME_MSEC); |
584 | } | ||
585 | |||
586 | int rtas_set_slot_reset(struct pci_dn *pdn) | ||
587 | { | ||
588 | int i, rc; | ||
589 | |||
590 | __rtas_set_slot_reset(pdn); | ||
588 | 591 | ||
589 | /* Now double check with the firmware to make sure the device is | 592 | /* Now double check with the firmware to make sure the device is |
590 | * ready to be used; if not, wait for recovery. */ | 593 | * ready to be used; if not, wait for recovery. */ |
591 | for (i=0; i<10; i++) { | 594 | for (i=0; i<10; i++) { |
592 | rc = eeh_slot_availability (pdn); | 595 | rc = eeh_slot_availability (pdn); |
593 | if (rc < 0) | ||
594 | printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n", rc, pdn->node->full_name); | ||
595 | if (rc == 0) | 596 | if (rc == 0) |
596 | return 0; | 597 | return 0; |
597 | if (rc < 0) | 598 | |
599 | if (rc == -2) { | ||
600 | printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n", | ||
601 | i, pdn->node->full_name); | ||
602 | __rtas_set_slot_reset(pdn); | ||
603 | continue; | ||
604 | } | ||
605 | |||
606 | if (rc < 0) { | ||
607 | printk (KERN_ERR "EEH: unrecoverable slot failure %s\n", | ||
608 | pdn->node->full_name); | ||
598 | return -1; | 609 | return -1; |
610 | } | ||
599 | 611 | ||
600 | msleep (rc+100); | 612 | msleep (rc+100); |
601 | } | 613 | } |