aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/eeh.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries/eeh.c')
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c96
1 files changed, 73 insertions, 23 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 32eaddfa5470..84bc8f7e17ef 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -449,7 +449,11 @@ EXPORT_SYMBOL(eeh_check_failure);
449/* ------------------------------------------------------------- */ 449/* ------------------------------------------------------------- */
450/* The code below deals with error recovery */ 450/* The code below deals with error recovery */
451 451
452/** Return negative value if a permanent error, else return 452/**
453 * eeh_slot_availability - returns error status of slot
454 * @pdn pci device node
455 *
456 * Return negative value if a permanent error, else return
453 * a number of milliseconds to wait until the PCI slot is 457 * a number of milliseconds to wait until the PCI slot is
454 * ready to be used. 458 * ready to be used.
455 */ 459 */
@@ -474,11 +478,42 @@ eeh_slot_availability(struct pci_dn *pdn)
474 478
475 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",
476 rc, rets[0], rets[1], rets[2]); 480 rc, rets[0], rets[1], rets[2]);
477 return -1; 481 return -2;
482}
483
484/**
485 * rtas_pci_enable - enable MMIO or DMA transfers for this slot
486 * @pdn pci device node
487 */
488
489int
490rtas_pci_enable(struct pci_dn *pdn, int function)
491{
492 int config_addr;
493 int rc;
494
495 /* Use PE configuration address, if present */
496 config_addr = pdn->eeh_config_addr;
497 if (pdn->eeh_pe_config_addr)
498 config_addr = pdn->eeh_pe_config_addr;
499
500 rc = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
501 config_addr,
502 BUID_HI(pdn->phb->buid),
503 BUID_LO(pdn->phb->buid),
504 function);
505
506 if (rc)
507 printk(KERN_WARNING "EEH: Cannot enable function %d, err=%d dn=%s\n",
508 function, rc, pdn->node->full_name);
509
510 return rc;
478} 511}
479 512
480/** rtas_pci_slot_reset raises/lowers the pci #RST line 513/**
481 * state: 1/0 to raise/lower the #RST 514 * rtas_pci_slot_reset - raises/lowers the pci #RST line
515 * @pdn pci device node
516 * @state: 1/0 to raise/lower the #RST
482 * 517 *
483 * Clear the EEH-frozen condition on a slot. This routine 518 * Clear the EEH-frozen condition on a slot. This routine
484 * asserts the PCI #RST line if the 'state' argument is '1', 519 * asserts the PCI #RST line if the 'state' argument is '1',
@@ -511,24 +546,21 @@ rtas_pci_slot_reset(struct pci_dn *pdn, int state)
511 BUID_HI(pdn->phb->buid), 546 BUID_HI(pdn->phb->buid),
512 BUID_LO(pdn->phb->buid), 547 BUID_LO(pdn->phb->buid),
513 state); 548 state);
514 if (rc) { 549 if (rc)
515 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",
516 rc, state, pdn->node->full_name); 552 rc, state, pdn->node->full_name);
517 return;
518 }
519} 553}
520 554
521/** rtas_set_slot_reset -- assert the pci #RST line for 1/4 second 555/**
522 * dn -- device node to be reset. 556 * rtas_set_slot_reset -- assert the pci #RST line for 1/4 second
557 * @pdn: pci device node to be reset.
523 * 558 *
524 * Return 0 if success, else a non-zero value. 559 * Return 0 if success, else a non-zero value.
525 */ 560 */
526 561
527int 562static void __rtas_set_slot_reset(struct pci_dn *pdn)
528rtas_set_slot_reset(struct pci_dn *pdn)
529{ 563{
530 int i, rc;
531
532 rtas_pci_slot_reset (pdn, 1); 564 rtas_pci_slot_reset (pdn, 1);
533 565
534 /* 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
@@ -549,17 +581,33 @@ rtas_set_slot_reset(struct pci_dn *pdn)
549 * up traffic. */ 581 * up traffic. */
550#define PCI_BUS_SETTLE_TIME_MSEC 1800 582#define PCI_BUS_SETTLE_TIME_MSEC 1800
551 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);
552 591
553 /* 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
554 * ready to be used; if not, wait for recovery. */ 593 * ready to be used; if not, wait for recovery. */
555 for (i=0; i<10; i++) { 594 for (i=0; i<10; i++) {
556 rc = eeh_slot_availability (pdn); 595 rc = eeh_slot_availability (pdn);
557 if (rc < 0)
558 printk (KERN_ERR "EEH: failed (%d) to reset slot %s\n", rc, pdn->node->full_name);
559 if (rc == 0) 596 if (rc == 0)
560 return 0; 597 return 0;
561 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);
562 return -1; 609 return -1;
610 }
563 611
564 msleep (rc+100); 612 msleep (rc+100);
565 } 613 }
@@ -582,6 +630,8 @@ rtas_set_slot_reset(struct pci_dn *pdn)
582 630
583/** 631/**
584 * __restore_bars - Restore the Base Address Registers 632 * __restore_bars - Restore the Base Address Registers
633 * @pdn: pci device node
634 *
585 * Loads the PCI configuration space base address registers, 635 * Loads the PCI configuration space base address registers,
586 * the expansion ROM base address, the latency timer, and etc. 636 * the expansion ROM base address, the latency timer, and etc.
587 * from the saved values in the device node. 637 * from the saved values in the device node.
@@ -691,11 +741,11 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
691{ 741{
692 struct eeh_early_enable_info *info = data; 742 struct eeh_early_enable_info *info = data;
693 int ret; 743 int ret;
694 char *status = get_property(dn, "status", NULL); 744 const char *status = get_property(dn, "status", NULL);
695 u32 *class_code = (u32 *)get_property(dn, "class-code", NULL); 745 const u32 *class_code = get_property(dn, "class-code", NULL);
696 u32 *vendor_id = (u32 *)get_property(dn, "vendor-id", NULL); 746 const u32 *vendor_id = get_property(dn, "vendor-id", NULL);
697 u32 *device_id = (u32 *)get_property(dn, "device-id", NULL); 747 const u32 *device_id = get_property(dn, "device-id", NULL);
698 u32 *regs; 748 const u32 *regs;
699 int enable; 749 int enable;
700 struct pci_dn *pdn = PCI_DN(dn); 750 struct pci_dn *pdn = PCI_DN(dn);
701 751
@@ -737,7 +787,7 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
737 787
738 /* Ok... see if this device supports EEH. Some do, some don't, 788 /* Ok... see if this device supports EEH. Some do, some don't,
739 * and the only way to find out is to check each and every one. */ 789 * and the only way to find out is to check each and every one. */
740 regs = (u32 *)get_property(dn, "reg", NULL); 790 regs = get_property(dn, "reg", NULL);
741 if (regs) { 791 if (regs) {
742 /* First register entry is addr (00BBSS00) */ 792 /* First register entry is addr (00BBSS00) */
743 /* Try to enable eeh */ 793 /* Try to enable eeh */