aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorLinas Vepstas <linas@austin.ibm.com>2007-01-26 15:55:03 -0500
committerPaul Mackerras <paulus@samba.org>2007-02-06 22:03:17 -0500
commit25c4a46f0ed8ece9ac6699e200fcc83a4642dce7 (patch)
treec58b4f08996ea35663370713961c9e941a8caab2 /arch/powerpc/platforms
parent2dc08572cc11a1ab2e67b214a4f3d7d0997473f8 (diff)
[POWERPC] pSeries: EEH improperly enabled for some Power4 systems
It appears that EEH is improperly enabled for some Power4 systems. On these systems, the ibm,set-eeh-option returns a value of success even when EEH is not supported on the given node. Thus, an explicit check for support is required. During boot, on power4, without this patch, one sees messages similar to: EEH: event on unsupported device, rc=0 dn=/pci@400000000110/IBM,sp@1 EEH: event on unsupported device, rc=0 dn=/pci@400000000110/pci@2 EEH: event on unsupported device, rc=0 dn=/pci@400000000110/pci@2,2 etc. The patch makes these go away. Without this patch, EEH recovery does seem to work correctly for at least some devices (I tested ethernet e1000), but fails to recover others (the Emulex LightPulse LPFC, most notably). Off the top of my head, I don't remember why some devices are affected, but not others. The PAPR indicates that the correct way to test for EEH is as done in this patch; its not clear to me if this was in the PAPR all along, or recently added; if it was there all along, its not clear to me why this hadn't been fixed long ago. I suspect only certain firmware levels are affected. Signed-off-by: Linas Vepstas <linas@austin.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index da6e5362e7cd..9437f48cc9e7 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -747,6 +747,7 @@ struct eeh_early_enable_info {
747/* Enable eeh for the given device node. */ 747/* Enable eeh for the given device node. */
748static void *early_enable_eeh(struct device_node *dn, void *data) 748static void *early_enable_eeh(struct device_node *dn, void *data)
749{ 749{
750 unsigned int rets[3];
750 struct eeh_early_enable_info *info = data; 751 struct eeh_early_enable_info *info = data;
751 int ret; 752 int ret;
752 const char *status = get_property(dn, "status", NULL); 753 const char *status = get_property(dn, "status", NULL);
@@ -803,16 +804,14 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
803 regs[0], info->buid_hi, info->buid_lo, 804 regs[0], info->buid_hi, info->buid_lo,
804 EEH_ENABLE); 805 EEH_ENABLE);
805 806
807 enable = 0;
806 if (ret == 0) { 808 if (ret == 0) {
807 eeh_subsystem_enabled = 1;
808 pdn->eeh_mode |= EEH_MODE_SUPPORTED;
809 pdn->eeh_config_addr = regs[0]; 809 pdn->eeh_config_addr = regs[0];
810 810
811 /* If the newer, better, ibm,get-config-addr-info is supported, 811 /* If the newer, better, ibm,get-config-addr-info is supported,
812 * then use that instead. */ 812 * then use that instead. */
813 pdn->eeh_pe_config_addr = 0; 813 pdn->eeh_pe_config_addr = 0;
814 if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) { 814 if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) {
815 unsigned int rets[2];
816 ret = rtas_call (ibm_get_config_addr_info, 4, 2, rets, 815 ret = rtas_call (ibm_get_config_addr_info, 4, 2, rets,
817 pdn->eeh_config_addr, 816 pdn->eeh_config_addr,
818 info->buid_hi, info->buid_lo, 817 info->buid_hi, info->buid_lo,
@@ -820,6 +819,20 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
820 if (ret == 0) 819 if (ret == 0)
821 pdn->eeh_pe_config_addr = rets[0]; 820 pdn->eeh_pe_config_addr = rets[0];
822 } 821 }
822
823 /* Some older systems (Power4) allow the
824 * ibm,set-eeh-option call to succeed even on nodes
825 * where EEH is not supported. Verify support
826 * explicitly. */
827 ret = read_slot_reset_state(pdn, rets);
828 if ((ret == 0) && (rets[1] == 1))
829 enable = 1;
830 }
831
832 if (enable) {
833 eeh_subsystem_enabled = 1;
834 pdn->eeh_mode |= EEH_MODE_SUPPORTED;
835
823#ifdef DEBUG 836#ifdef DEBUG
824 printk(KERN_DEBUG "EEH: %s: eeh enabled, config=%x pe_config=%x\n", 837 printk(KERN_DEBUG "EEH: %s: eeh enabled, config=%x pe_config=%x\n",
825 dn->full_name, pdn->eeh_config_addr, pdn->eeh_pe_config_addr); 838 dn->full_name, pdn->eeh_config_addr, pdn->eeh_pe_config_addr);