aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c36
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
563int 562static void __rtas_set_slot_reset(struct pci_dn *pdn)
564rtas_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
586int 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 }