patch-2.4.22 linux-2.4.22/arch/ppc64/kernel/eeh.c
Next file: linux-2.4.22/arch/ppc64/kernel/entry.S
Previous file: linux-2.4.22/arch/ppc64/kernel/cputable.c
Back to the patch index
Back to the overall index
- Lines: 93
- Date:
2003-08-25 04:44:40.000000000 -0700
- Orig file:
linux-2.4.21/arch/ppc64/kernel/eeh.c
- Orig date:
2003-06-13 07:51:31.000000000 -0700
diff -urN linux-2.4.21/arch/ppc64/kernel/eeh.c linux-2.4.22/arch/ppc64/kernel/eeh.c
@@ -129,17 +129,16 @@
int adapters_enabled;
};
-/* Enable eeh for the given device node. */
-static void *early_enable_eeh(struct device_node *dn, void *data)
+
+/* Enable/disable eeh for the given device node. */
+static void *early_set_eeh(struct device_node *dn, struct eeh_early_enable_info *info, int enable)
{
- struct eeh_early_enable_info *info = data;
long ret;
char *status = get_property(dn, "status", 0);
u32 *class_code = (u32 *)get_property(dn, "class-code", 0);
u32 *vendor_id =(u32 *) get_property(dn, "vendor-id", 0);
u32 *device_id = (u32 *)get_property(dn, "device-id", 0);
u32 *regs;
- int enable;
if (status && strcmp(status, "ok") != 0)
return NULL; /* ignore devices with bad status */
@@ -161,15 +160,19 @@
* hang waiting on status bits that won't change, etc.
* But there are a few cases like display devices that make sense.
*/
- enable = 1; /* i.e. we will do checking */
- if ((*class_code >> 16) == PCI_BASE_CLASS_DISPLAY)
- enable = 0;
if (!eeh_check_opts_config(dn, *class_code, *vendor_id, *device_id, enable)) {
if (enable) {
printk(KERN_INFO "EEH: %s user requested to run without EEH.\n", dn->full_name);
enable = 0;
}
+#if 0
+ /* Turn off EEH automatically for graphics ...
+ * but we don't want to do this, not really. .... */
+ } else if ((*class_code >> 16) == PCI_BASE_CLASS_DISPLAY) {
+ printk(KERN_INFO "EEH: %s DISPLAY automatically set to run without EEH.\n", dn->full_name);
+ enable = 0;
+#endif
}
if (!enable)
@@ -179,6 +182,16 @@
if (dn->parent && (dn->parent->eeh_mode & EEH_MODE_SUPPORTED)) {
/* Parent supports EEH. */
dn->eeh_mode |= EEH_MODE_SUPPORTED;
+
+ /* Recurse to parent to set EEH, since we are probably
+ * a non-eeh supporting pci bridge chip on some card.
+ * But recurse only if our eeh setting is to be different.
+ */
+ if ((enable && (EEH_MODE_NOCHECK == dn->eeh_mode)) ||
+ (!enable && (EEH_MODE_NOCHECK != dn->eeh_mode)))
+ {
+ early_set_eeh (dn->parent, info, enable);
+ }
dn->eeh_config_addr = dn->parent->eeh_config_addr;
return NULL;
}
@@ -187,19 +200,29 @@
regs = (u32 *)get_property(dn, "reg", 0);
if (regs) {
/* First register entry is addr (00BBSS00) */
- /* Try to enable eeh */
+ /* Try to enable/disable eeh */
ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL,
regs[0], info->buid_hi, info->buid_lo,
- EEH_ENABLE);
+ enable ? EEH_ENABLE : EEH_DISABLE);
if (ret == 0) {
info->adapters_enabled++;
dn->eeh_mode |= EEH_MODE_SUPPORTED;
dn->eeh_config_addr = regs[0];
+ } else {
+ printk(KERN_INFO "EEH: %s failed to %s ret=%ld\n", dn->full_name, enable ? "enable" : "disable", ret);
}
}
return NULL;
}
+/* Enable eeh for the given device node. */
+static void *early_enable_eeh(struct device_node *dn, void *data)
+{
+ struct eeh_early_enable_info *info = data;
+ /* Set enable to 1, i.e. we will do checking */
+ return early_set_eeh (dn, info, 1);
+}
+
/*
* Initialize eeh by trying to enable it for all of the adapters in the system.
* As a side effect we can determine here if eeh is supported at all.
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)