summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinas Vepstas <linas@austin.ibm.com>2007-01-26 21:55:03 +0100
committerPaul Mackerras <paulus@samba.org>2007-02-07 04:03:17 +0100
commit25c4a46f0ed8ece9ac6699e200fcc83a4642dce7 (patch)
treec58b4f08996ea35663370713961c9e941a8caab2
parent[POWERPC] Fix apparent typo "CONFIG_SERIAL_CPM_SMC". (diff)
downloadlinux-25c4a46f0ed8ece9ac6699e200fcc83a4642dce7.tar.xz
linux-25c4a46f0ed8ece9ac6699e200fcc83a4642dce7.zip
[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>
-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 {
/* Enable eeh for the given device node. */
static void *early_enable_eeh(struct device_node *dn, void *data)
{
+ unsigned int rets[3];
struct eeh_early_enable_info *info = data;
int ret;
const char *status = get_property(dn, "status", NULL);
@@ -803,16 +804,14 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
regs[0], info->buid_hi, info->buid_lo,
EEH_ENABLE);
+ enable = 0;
if (ret == 0) {
- eeh_subsystem_enabled = 1;
- pdn->eeh_mode |= EEH_MODE_SUPPORTED;
pdn->eeh_config_addr = regs[0];
/* If the newer, better, ibm,get-config-addr-info is supported,
* then use that instead. */
pdn->eeh_pe_config_addr = 0;
if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) {
- unsigned int rets[2];
ret = rtas_call (ibm_get_config_addr_info, 4, 2, rets,
pdn->eeh_config_addr,
info->buid_hi, info->buid_lo,
@@ -820,6 +819,20 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
if (ret == 0)
pdn->eeh_pe_config_addr = rets[0];
}
+
+ /* Some older systems (Power4) allow the
+ * ibm,set-eeh-option call to succeed even on nodes
+ * where EEH is not supported. Verify support
+ * explicitly. */
+ ret = read_slot_reset_state(pdn, rets);
+ if ((ret == 0) && (rets[1] == 1))
+ enable = 1;
+ }
+
+ if (enable) {
+ eeh_subsystem_enabled = 1;
+ pdn->eeh_mode |= EEH_MODE_SUPPORTED;
+
#ifdef DEBUG
printk(KERN_DEBUG "EEH: %s: eeh enabled, config=%x pe_config=%x\n",
dn->full_name, pdn->eeh_config_addr, pdn->eeh_pe_config_addr);