Commit da9bb1d2 authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] EDAC: core EDAC support code

This is a subset of the bluesmoke project core code, stripped of the NMI work
which isn't ready to merge and some of the "interesting" proc functionality
that needs reworking or just has no place in kernel.  It requires no core
kernel changes except the added scrub functions already posted.

The goal is to merge further functionality only after the core code is
accepted and proven in the base kernel, and only at the point the upstream
extras are really ready to merge.

From: doug thompson <norsk5@xmission.com>

  This converts EDAC to sysfs and is the final chunk neccessary before EDAC
  has a stable user space API and can be considered for submission into the
  base kernel.
Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarAdrian Bunk <bunk@stusta.de>
Signed-off-by: default avatarJesper Juhl <jesper.juhl@gmail.com>
Signed-off-by: default avatardoug thompson <norsk5@xmission.com>
Signed-off-by: default avatarPavel Machek <pavel@suse.cz>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 2f768af7
This diff is collapsed.
...@@ -867,6 +867,15 @@ L: ebtables-devel@lists.sourceforge.net ...@@ -867,6 +867,15 @@ L: ebtables-devel@lists.sourceforge.net
W: http://ebtables.sourceforge.net/ W: http://ebtables.sourceforge.net/
S: Maintained S: Maintained
EDAC-CORE
P: Doug Thompson
M: norsk5@xmission.com, dthompson@linuxnetworx.com
P: Dave Peterson
M: dsp@llnl.gov, dave_peterson@pobox.com
L: bluesmoke-devel@lists.sourceforge.net
W: bluesmoke.sourceforge.net
S: Maintained
EEPRO100 NETWORK DRIVER EEPRO100 NETWORK DRIVER
P: Andrey V. Savochkin P: Andrey V. Savochkin
M: saw@saw.sw.com.sg M: saw@saw.sw.com.sg
......
...@@ -25,8 +25,7 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) ...@@ -25,8 +25,7 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
/* enable access to config space*/ /* enable access to config space*/
pci_read_config_byte(dev, 0xf4, &config); pci_read_config_byte(dev, 0xf4, &config);
config |= 0x2; pci_write_config_byte(dev, 0xf4, config|0x2);
pci_write_config_byte(dev, 0xf4, config);
/* read xTPR register */ /* read xTPR register */
raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word);
...@@ -42,9 +41,9 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) ...@@ -42,9 +41,9 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
#endif #endif
} }
config &= ~0x2; /* put back the original value for config space*/
/* disable access to config space*/ if (!(config & 0x2))
pci_write_config_byte(dev, 0xf4, config); pci_write_config_byte(dev, 0xf4, config);
} }
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance);
......
...@@ -68,4 +68,6 @@ source "drivers/infiniband/Kconfig" ...@@ -68,4 +68,6 @@ source "drivers/infiniband/Kconfig"
source "drivers/sn/Kconfig" source "drivers/sn/Kconfig"
source "drivers/edac/Kconfig"
endmenu endmenu
...@@ -63,6 +63,7 @@ obj-$(CONFIG_PHONE) += telephony/ ...@@ -63,6 +63,7 @@ obj-$(CONFIG_PHONE) += telephony/
obj-$(CONFIG_MD) += md/ obj-$(CONFIG_MD) += md/
obj-$(CONFIG_BT) += bluetooth/ obj-$(CONFIG_BT) += bluetooth/
obj-$(CONFIG_ISDN) += isdn/ obj-$(CONFIG_ISDN) += isdn/
obj-$(CONFIG_EDAC) += edac/
obj-$(CONFIG_MCA) += mca/ obj-$(CONFIG_MCA) += mca/
obj-$(CONFIG_EISA) += eisa/ obj-$(CONFIG_EISA) += eisa/
obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_CPU_FREQ) += cpufreq/
......
#
# EDAC Kconfig
# Copyright (c) 2003 Linux Networx
# Licensed and distributed under the GPL
#
# $Id: Kconfig,v 1.4.2.7 2005/07/08 22:05:38 dsp_llnl Exp $
#
menu 'EDAC - error detection and reporting (RAS)'
config EDAC
tristate "EDAC core system error reporting"
depends on X86
default y
help
EDAC is designed to report errors in the core system.
These are low-level errors that are reported in the CPU or
supporting chipset: memory errors, cache errors, PCI errors,
thermal throttling, etc.. If unsure, select 'Y'.
comment "Reporting subsystems"
depends on EDAC
config EDAC_DEBUG
bool "Debugging"
depends on EDAC
help
This turns on debugging information for the entire EDAC
sub-system. You can insert module with "debug_level=x", current
there're four debug levels (x=0,1,2,3 from low to high).
Usually you should select 'N'.
config EDAC_MM_EDAC
tristate "Main Memory EDAC (Error Detection And Correction) reporting"
depends on EDAC
default y
help
Some systems are able to detect and correct errors in main
memory. EDAC can report statistics on memory error
detection and correction (EDAC - or commonly referred to ECC
errors). EDAC will also try to decode where these errors
occurred so that a particular failing memory module can be
replaced. If unsure, select 'Y'.
config EDAC_AMD76X
tristate "AMD 76x (760, 762, 768)"
depends on EDAC_MM_EDAC && PCI
help
Support for error detection and correction on the AMD 76x
series of chipsets used with the Athlon processor.
config EDAC_E7XXX
tristate "Intel e7xxx (e7205, e7500, e7501, e7505)"
depends on EDAC_MM_EDAC && PCI
help
Support for error detection and correction on the Intel
E7205, E7500, E7501 and E7505 server chipsets.
config EDAC_E752X
tristate "Intel e752x (e7520, e7525, e7320)"
depends on EDAC_MM_EDAC && PCI
help
Support for error detection and correction on the Intel
E7520, E7525, E7320 server chipsets.
config EDAC_I82875P
tristate "Intel 82875p (D82875P, E7210)"
depends on EDAC_MM_EDAC && PCI
help
Support for error detection and correction on the Intel
DP82785P and E7210 server chipsets.
config EDAC_I82860
tristate "Intel 82860"
depends on EDAC_MM_EDAC && PCI
help
Support for error detection and correction on the Intel
82860 chipset.
config EDAC_R82600
tristate "Radisys 82600 embedded chipset"
depends on EDAC_MM_EDAC
help
Support for error detection and correction on the Radisys
82600 embedded chipset.
choice
prompt "Error detecting method"
depends on EDAC
default EDAC_POLL
config EDAC_POLL
bool "Poll for errors"
depends on EDAC
help
Poll the chipset periodically to detect errors.
endchoice
endmenu
#
# Makefile for the Linux kernel EDAC drivers.
#
# Copyright 02 Jul 2003, Linux Networx (http://lnxi.com)
# This file may be distributed under the terms of the
# GNU General Public License.
#
# $Id: Makefile,v 1.4.2.3 2005/07/08 22:05:38 dsp_llnl Exp $
obj-$(CONFIG_EDAC_MM_EDAC) += edac_mc.o
obj-$(CONFIG_EDAC_AMD76X) += amd76x_edac.o
obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o
obj-$(CONFIG_EDAC_E752X) += e752x_edac.o
obj-$(CONFIG_EDAC_I82875P) += i82875p_edac.o
obj-$(CONFIG_EDAC_I82860) += i82860_edac.o
obj-$(CONFIG_EDAC_R82600) += r82600_edac.o
...@@ -338,7 +338,7 @@ static struct pci_driver amd76x_driver = { ...@@ -338,7 +338,7 @@ static struct pci_driver amd76x_driver = {
.id_table = amd76x_pci_tbl, .id_table = amd76x_pci_tbl,
}; };
int __init amd76x_init(void) static int __init amd76x_init(void)
{ {
return pci_register_driver(&amd76x_driver); return pci_register_driver(&amd76x_driver);
} }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* Wang Zhenyu at intel.com * Wang Zhenyu at intel.com
* Dave Jiang at mvista.com * Dave Jiang at mvista.com
* *
* $Id: bluesmoke_e752x.c,v 1.5.2.11 2005/10/05 00:43:44 dsp_llnl Exp $ * $Id: edac_e752x.c,v 1.5.2.11 2005/10/05 00:43:44 dsp_llnl Exp $
* *
*/ */
...@@ -376,14 +376,14 @@ static inline void process_threshold_ce(struct mem_ctl_info *mci, u16 error, ...@@ -376,14 +376,14 @@ static inline void process_threshold_ce(struct mem_ctl_info *mci, u16 error,
mci->mc_idx); mci->mc_idx);
} }
char *global_message[11] = { static char *global_message[11] = {
"PCI Express C1", "PCI Express C", "PCI Express B1", "PCI Express C1", "PCI Express C", "PCI Express B1",
"PCI Express B", "PCI Express A1", "PCI Express A", "PCI Express B", "PCI Express A1", "PCI Express A",
"DMA Controler", "HUB Interface", "System Bus", "DMA Controler", "HUB Interface", "System Bus",
"DRAM Controler", "Internal Buffer" "DRAM Controler", "Internal Buffer"
}; };
char *fatal_message[2] = { "Non-Fatal ", "Fatal " }; static char *fatal_message[2] = { "Non-Fatal ", "Fatal " };
static void do_global_error(int fatal, u32 errors) static void do_global_error(int fatal, u32 errors)
{ {
...@@ -405,7 +405,7 @@ static inline void global_error(int fatal, u32 errors, int *error_found, ...@@ -405,7 +405,7 @@ static inline void global_error(int fatal, u32 errors, int *error_found,
do_global_error(fatal, errors); do_global_error(fatal, errors);
} }
char *hub_message[7] = { static char *hub_message[7] = {
"HI Address or Command Parity", "HI Illegal Access", "HI Address or Command Parity", "HI Illegal Access",
"HI Internal Parity", "Out of Range Access", "HI Internal Parity", "Out of Range Access",
"HI Data Parity", "Enhanced Config Access", "HI Data Parity", "Enhanced Config Access",
...@@ -432,7 +432,7 @@ static inline void hub_error(int fatal, u8 errors, int *error_found, ...@@ -432,7 +432,7 @@ static inline void hub_error(int fatal, u8 errors, int *error_found,
do_hub_error(fatal, errors); do_hub_error(fatal, errors);
} }
char *membuf_message[4] = { static char *membuf_message[4] = {
"Internal PMWB to DRAM parity", "Internal PMWB to DRAM parity",
"Internal PMWB to System Bus Parity", "Internal PMWB to System Bus Parity",
"Internal System Bus or IO to PMWB Parity", "Internal System Bus or IO to PMWB Parity",
...@@ -458,6 +458,7 @@ static inline void membuf_error(u8 errors, int *error_found, int handle_error) ...@@ -458,6 +458,7 @@ static inline void membuf_error(u8 errors, int *error_found, int handle_error)
do_membuf_error(errors); do_membuf_error(errors);
} }
#if 0
char *sysbus_message[10] = { char *sysbus_message[10] = {
"Addr or Request Parity", "Addr or Request Parity",
"Data Strobe Glitch", "Data Strobe Glitch",
...@@ -469,6 +470,7 @@ char *sysbus_message[10] = { ...@@ -469,6 +470,7 @@ char *sysbus_message[10] = {
"Memory Parity", "Memory Parity",
"IO Subsystem Parity" "IO Subsystem Parity"
}; };
#endif /* 0 */
static void do_sysbus_error(int fatal, u32 errors) static void do_sysbus_error(int fatal, u32 errors)
{ {
...@@ -1044,7 +1046,7 @@ static struct pci_driver e752x_driver = { ...@@ -1044,7 +1046,7 @@ static struct pci_driver e752x_driver = {
}; };
int __init e752x_init(void) static int __init e752x_init(void)
{ {
int pci_rc; int pci_rc;
......
...@@ -537,7 +537,7 @@ static struct pci_driver e7xxx_driver = { ...@@ -537,7 +537,7 @@ static struct pci_driver e7xxx_driver = {
}; };
int __init e7xxx_init(void) static int __init e7xxx_init(void)
{ {
return pci_register_driver(&e7xxx_driver); return pci_register_driver(&e7xxx_driver);
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -253,7 +253,7 @@ static struct pci_driver i82860_driver = { ...@@ -253,7 +253,7 @@ static struct pci_driver i82860_driver = {
.id_table = i82860_pci_tbl, .id_table = i82860_pci_tbl,
}; };
int __init i82860_init(void) static int __init i82860_init(void)
{ {
int pci_rc; int pci_rc;
......
...@@ -483,7 +483,7 @@ static struct pci_driver i82875p_driver = { ...@@ -483,7 +483,7 @@ static struct pci_driver i82875p_driver = {
}; };
int __init i82875p_init(void) static int __init i82875p_init(void)
{ {
int pci_rc; int pci_rc;
......
...@@ -381,7 +381,7 @@ static struct pci_driver r82600_driver = { ...@@ -381,7 +381,7 @@ static struct pci_driver r82600_driver = {
}; };
int __init r82600_init(void) static int __init r82600_init(void)
{ {
return pci_register_driver(&r82600_driver); return pci_register_driver(&r82600_driver);
} }
......
...@@ -255,17 +255,5 @@ __asm__ __volatile__(LOCK "orl %0,%1" \ ...@@ -255,17 +255,5 @@ __asm__ __volatile__(LOCK "orl %0,%1" \
#define smp_mb__before_atomic_inc() barrier() #define smp_mb__before_atomic_inc() barrier()
#define smp_mb__after_atomic_inc() barrier() #define smp_mb__after_atomic_inc() barrier()
/* ECC atomic, DMA, SMP and interrupt safe scrub function */
static __inline__ void atomic_scrub(unsigned long *virt_addr, u32 size)
{
u32 i;
for (i = 0; i < size / 4; i++, virt_addr++)
/* Very carefully read and write to memory atomically
* so we are interrupt, DMA and SMP safe.
*/
__asm__ __volatile__("lock; addl $0, %0"::"m"(*virt_addr));
}
#include <asm-generic/atomic.h> #include <asm-generic/atomic.h>
#endif #endif
#ifndef ASM_EDAC_H
#define ASM_EDAC_H
/* ECC atomic, DMA, SMP and interrupt safe scrub function */
static __inline__ void atomic_scrub(void *va, u32 size)
{
unsigned long *virt_addr = va;
u32 i;
for (i = 0; i < size / 4; i++, virt_addr++)
/* Very carefully read and write to memory atomically
* so we are interrupt, DMA and SMP safe.
*/
__asm__ __volatile__("lock; addl $0, %0"::"m"(*virt_addr));
}
#endif
...@@ -426,17 +426,5 @@ __asm__ __volatile__(LOCK "orl %0,%1" \ ...@@ -426,17 +426,5 @@ __asm__ __volatile__(LOCK "orl %0,%1" \
#define smp_mb__before_atomic_inc() barrier() #define smp_mb__before_atomic_inc() barrier()
#define smp_mb__after_atomic_inc() barrier() #define smp_mb__after_atomic_inc() barrier()
/* ECC atomic, DMA, SMP and interrupt safe scrub function */
static __inline__ void atomic_scrub(u32 *virt_addr, u32 size)
{
u32 i;
for (i = 0; i < size / 4; i++, virt_addr++)
/* Very carefully read and write to memory atomically
* so we are interrupt, DMA and SMP safe.
*/
__asm__ __volatile__("lock; addl $0, %0"::"m"(*virt_addr));
}
#include <asm-generic/atomic.h> #include <asm-generic/atomic.h>
#endif #endif
#ifndef ASM_EDAC_H
#define ASM_EDAC_H
/* ECC atomic, DMA, SMP and interrupt safe scrub function */
static __inline__ void atomic_scrub(void *va, u32 size)
{
unsigned int *virt_addr = va;
u32 i;
for (i = 0; i < size / 4; i++, virt_addr++)
/* Very carefully read and write to memory atomically
* so we are interrupt, DMA and SMP safe.
*/
__asm__ __volatile__("lock; addl $0, %0"::"m"(*virt_addr));
}
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment