Release 4.11 drivers/edac/e752x_edac.c
/*
* Intel e752x Memory Controller kernel module
* (C) 2004 Linux Networx (http://lnxi.com)
* This file may be distributed under the terms of the
* GNU General Public License.
*
* Implement support for the e7520, E7525, e7320 and i3100 memory controllers.
*
* Datasheets:
* http://www.intel.in/content/www/in/en/chipsets/e7525-memory-controller-hub-datasheet.html
* ftp://download.intel.com/design/intarch/datashts/31345803.pdf
*
* Written by Tom Zimmerman
*
* Contributors:
* Thayne Harbaugh at realmsys.com (?)
* Wang Zhenyu at intel.com
* Dave Jiang at mvista.com
*
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
#include <linux/edac.h>
#include "edac_module.h"
#define E752X_REVISION " Ver: 2.0.2"
#define EDAC_MOD_STR "e752x_edac"
static int report_non_memory_errors;
static int force_function_unhide;
static int sysbus_parity = -1;
static struct edac_pci_ctl_info *e752x_pci;
#define e752x_printk(level, fmt, arg...) \
edac_printk(level, "e752x", fmt, ##arg)
#define e752x_mc_printk(mci, level, fmt, arg...) \
edac_mc_chipset_printk(mci, level, "e752x", fmt, ##arg)
#ifndef PCI_DEVICE_ID_INTEL_7520_0
#define PCI_DEVICE_ID_INTEL_7520_0 0x3590
#endif /* PCI_DEVICE_ID_INTEL_7520_0 */
#ifndef PCI_DEVICE_ID_INTEL_7520_1_ERR
#define PCI_DEVICE_ID_INTEL_7520_1_ERR 0x3591
#endif /* PCI_DEVICE_ID_INTEL_7520_1_ERR */
#ifndef PCI_DEVICE_ID_INTEL_7525_0
#define PCI_DEVICE_ID_INTEL_7525_0 0x359E
#endif /* PCI_DEVICE_ID_INTEL_7525_0 */
#ifndef PCI_DEVICE_ID_INTEL_7525_1_ERR
#define PCI_DEVICE_ID_INTEL_7525_1_ERR 0x3593
#endif /* PCI_DEVICE_ID_INTEL_7525_1_ERR */
#ifndef PCI_DEVICE_ID_INTEL_7320_0
#define PCI_DEVICE_ID_INTEL_7320_0 0x3592
#endif /* PCI_DEVICE_ID_INTEL_7320_0 */
#ifndef PCI_DEVICE_ID_INTEL_7320_1_ERR
#define PCI_DEVICE_ID_INTEL_7320_1_ERR 0x3593
#endif /* PCI_DEVICE_ID_INTEL_7320_1_ERR */
#ifndef PCI_DEVICE_ID_INTEL_3100_0
#define PCI_DEVICE_ID_INTEL_3100_0 0x35B0
#endif /* PCI_DEVICE_ID_INTEL_3100_0 */
#ifndef PCI_DEVICE_ID_INTEL_3100_1_ERR
#define PCI_DEVICE_ID_INTEL_3100_1_ERR 0x35B1
#endif /* PCI_DEVICE_ID_INTEL_3100_1_ERR */
#define E752X_NR_CSROWS 8
/* number of csrows */
/* E752X register addresses - device 0 function 0 */
#define E752X_MCHSCRB 0x52
/* Memory Scrub register (16b) */
/*
* 6:5 Scrub Completion Count
* 3:2 Scrub Rate (i3100 only)
* 01=fast 10=normal
* 1:0 Scrub Mode enable
* 00=off 10=on
*/
#define E752X_DRB 0x60
/* DRAM row boundary register (8b) */
#define E752X_DRA 0x70
/* DRAM row attribute register (8b) */
/*
* 31:30 Device width row 7
* 01=x8 10=x4 11=x8 DDR2
* 27:26 Device width row 6
* 23:22 Device width row 5
* 19:20 Device width row 4
* 15:14 Device width row 3
* 11:10 Device width row 2
* 7:6 Device width row 1
* 3:2 Device width row 0
*/
#define E752X_DRC 0x7C
/* DRAM controller mode reg (32b) */
/* FIXME:IS THIS RIGHT? */
/*
* 22 Number channels 0=1,1=2
* 19:18 DRB Granularity 32/64MB
*/
#define E752X_DRM 0x80
/* Dimm mapping register */
#define E752X_DDRCSR 0x9A
/* DDR control and status reg (16b) */
/*
* 14:12 1 single A, 2 single B, 3 dual
*/
#define E752X_TOLM 0xC4
/* DRAM top of low memory reg (16b) */
#define E752X_REMAPBASE 0xC6
/* DRAM remap base address reg (16b) */
#define E752X_REMAPLIMIT 0xC8
/* DRAM remap limit address reg (16b) */
#define E752X_REMAPOFFSET 0xCA
/* DRAM remap limit offset reg (16b) */
/* E752X register addresses - device 0 function 1 */
#define E752X_FERR_GLOBAL 0x40
/* Global first error register (32b) */
#define E752X_NERR_GLOBAL 0x44
/* Global next error register (32b) */
#define E752X_HI_FERR 0x50
/* Hub interface first error reg (8b) */
#define E752X_HI_NERR 0x52
/* Hub interface next error reg (8b) */
#define E752X_HI_ERRMASK 0x54
/* Hub interface error mask reg (8b) */
#define E752X_HI_SMICMD 0x5A
/* Hub interface SMI command reg (8b) */
#define E752X_SYSBUS_FERR 0x60
/* System buss first error reg (16b) */
#define E752X_SYSBUS_NERR 0x62
/* System buss next error reg (16b) */
#define E752X_SYSBUS_ERRMASK 0x64
/* System buss error mask reg (16b) */
#define E752X_SYSBUS_SMICMD 0x6A
/* System buss SMI command reg (16b) */
#define E752X_BUF_FERR 0x70
/* Memory buffer first error reg (8b) */
#define E752X_BUF_NERR 0x72
/* Memory buffer next error reg (8b) */
#define E752X_BUF_ERRMASK 0x74
/* Memory buffer error mask reg (8b) */
#define E752X_BUF_SMICMD 0x7A
/* Memory buffer SMI cmd reg (8b) */
#define E752X_DRAM_FERR 0x80
/* DRAM first error register (16b) */
#define E752X_DRAM_NERR 0x82
/* DRAM next error register (16b) */
#define E752X_DRAM_ERRMASK 0x84
/* DRAM error mask register (8b) */
#define E752X_DRAM_SMICMD 0x8A
/* DRAM SMI command register (8b) */
#define E752X_DRAM_RETR_ADD 0xAC
/* DRAM Retry address register (32b) */
#define E752X_DRAM_SEC1_ADD 0xA0
/* DRAM first correctable memory */
/* error address register (32b) */
/*
* 31 Reserved
* 30:2 CE address (64 byte block 34:6
* 1 Reserved
* 0 HiLoCS
*/
#define E752X_DRAM_SEC2_ADD 0xC8
/* DRAM first correctable memory */
/* error address register (32b) */
/*
* 31 Reserved
* 30:2 CE address (64 byte block 34:6)
* 1 Reserved
* 0 HiLoCS
*/
#define E752X_DRAM_DED_ADD 0xA4
/* DRAM first uncorrectable memory */
/* error address register (32b) */
/*
* 31 Reserved
* 30:2 CE address (64 byte block 34:6)
* 1 Reserved
* 0 HiLoCS
*/
#define E752X_DRAM_SCRB_ADD 0xA8
/* DRAM 1st uncorrectable scrub mem */
/* error address register (32b) */
/*
* 31 Reserved
* 30:2 CE address (64 byte block 34:6
* 1 Reserved
* 0 HiLoCS
*/
#define E752X_DRAM_SEC1_SYNDROME 0xC4
/* DRAM first correctable memory */
/* error syndrome register (16b) */
#define E752X_DRAM_SEC2_SYNDROME 0xC6
/* DRAM second correctable memory */
/* error syndrome register (16b) */
#define E752X_DEVPRES1 0xF4
/* Device Present 1 register (8b) */
/* 3100 IMCH specific register addresses - device 0 function 1 */
#define I3100_NSI_FERR 0x48
/* NSI first error reg (32b) */
#define I3100_NSI_NERR 0x4C
/* NSI next error reg (32b) */
#define I3100_NSI_SMICMD 0x54
/* NSI SMI command register (32b) */
#define I3100_NSI_EMASK 0x90
/* NSI error mask register (32b) */
/* ICH5R register addresses - device 30 function 0 */
#define ICH5R_PCI_STAT 0x06
/* PCI status register (16b) */
#define ICH5R_PCI_2ND_STAT 0x1E
/* PCI status secondary reg (16b) */
#define ICH5R_PCI_BRIDGE_CTL 0x3E
/* PCI bridge control register (16b) */
enum e752x_chips {
E7520 = 0,
E7525 = 1,
E7320 = 2,
I3100 = 3
};
/*
* Those chips Support single-rank and dual-rank memories only.
*
* On e752x chips, the odd rows are present only on dual-rank memories.
* Dividing the rank by two will provide the dimm#
*
* i3100 MC has a different mapping: it supports only 4 ranks.
*
* The mapping is (from 1 to n):
* slot single-ranked double-ranked
* dimm #1 -> rank #4 NA
* dimm #2 -> rank #3 NA
* dimm #3 -> rank #2 Ranks 2 and 3
* dimm #4 -> rank $1 Ranks 1 and 4
*
* FIXME: The current mapping for i3100 considers that it supports up to 8
* ranks/chanel, but datasheet says that the MC supports only 4 ranks.
*/
struct e752x_pvt {
struct pci_dev *dev_d0f0;
struct pci_dev *dev_d0f1;
u32 tolm;
u32 remapbase;
u32 remaplimit;
int mc_symmetric;
u8 map[8];
int map_type;
const struct e752x_dev_info *dev_info;
};
struct e752x_dev_info {
u16 err_dev;
u16 ctl_dev;
const char *ctl_name;
};
struct e752x_error_info {
u32 ferr_global;
u32 nerr_global;
u32 nsi_ferr; /* 3100 only */
u32 nsi_nerr; /* 3100 only */
u8 hi_ferr; /* all but 3100 */
u8 hi_nerr; /* all but 3100 */
u16 sysbus_ferr;
u16 sysbus_nerr;
u8 buf_ferr;
u8 buf_nerr;
u16 dram_ferr;
u16 dram_nerr;
u32 dram_sec1_add;
u32 dram_sec2_add;
u16 dram_sec1_syndrome;
u16 dram_sec2_syndrome;
u32 dram_ded_add;
u32 dram_scrb_add;
u32 dram_retr_add;
};
static const struct e752x_dev_info e752x_devs[] = {
[E7520] = {
.err_dev = PCI_DEVICE_ID_INTEL_7520_1_ERR,
.ctl_dev = PCI_DEVICE_ID_INTEL_7520_0,
.ctl_name = "E7520"},
[E7525] = {
.err_dev = PCI_DEVICE_ID_INTEL_7525_1_ERR,
.ctl_dev = PCI_DEVICE_ID_INTEL_7525_0,
.ctl_name = "E7525"},
[E7320] = {
.err_dev = PCI_DEVICE_ID_INTEL_7320_1_ERR,
.ctl_dev = PCI_DEVICE_ID_INTEL_7320_0,
.ctl_name = "E7320"},
[I3100] = {
.err_dev = PCI_DEVICE_ID_INTEL_3100_1_ERR,
.ctl_dev = PCI_DEVICE_ID_INTEL_3100_0,
.ctl_name = "3100"},
};
/* Valid scrub rates for the e752x/3100 hardware memory scrubber. We
* map the scrubbing bandwidth to a hardware register value. The 'set'
* operation finds the 'matching or higher value'. Note that scrubbing
* on the e752x can only be enabled/disabled. The 3100 supports
* a normal and fast mode.
*/
#define SDRATE_EOT 0xFFFFFFFF
struct scrubrate {
u32 bandwidth; /* bandwidth consumed by scrubbing in bytes/sec */
u16 scrubval; /* register value for scrub rate */
};
/* Rate below assumes same performance as i3100 using PC3200 DDR2 in
* normal mode. e752x bridges don't support choosing normal or fast mode,
* so the scrubbing bandwidth value isn't all that important - scrubbing is
* either on or off.
*/
static const struct scrubrate scrubrates_e752x[] = {
{0, 0x00}, /* Scrubbing Off */
{500000, 0x02}, /* Scrubbing On */
{SDRATE_EOT, 0x00} /* End of Table */
};
/* Fast mode: 2 GByte PC3200 DDR2 scrubbed in 33s = 63161283 bytes/s
* Normal mode: 125 (32000 / 256) times slower than fast mode.
*/
static const struct scrubrate scrubrates_i3100[] = {
{0, 0x00}, /* Scrubbing Off */
{500000, 0x0a}, /* Normal mode - 32k clocks */
{62500000, 0x06}, /* Fast mode - 256 clocks */
{SDRATE_EOT, 0x00} /* End of Table */
};
static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci,
unsigned long page)
{
u32 remap;
struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info;
edac_dbg(3, "\n");
if (page < pvt->tolm)
return page;
if ((page >= 0x100000) && (page < pvt->remapbase))
return page;
remap = (page - pvt->tolm) + pvt->remapbase;
if (remap < pvt->remaplimit)
return remap;
e752x_printk(KERN_ERR, "Invalid page %lx - out of range\n", page);
return pvt->tolm - 1;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 105 | 94.59% | 1 | 25.00% |
Joe Perches | 3 | 2.70% | 1 | 25.00% |
Dave Peterson | 2 | 1.80% | 1 | 25.00% |
Mauro Carvalho Chehab | 1 | 0.90% | 1 | 25.00% |
Total | 111 | 100.00% | 4 | 100.00% |
static void do_process_ce(struct mem_ctl_info *mci, u16 error_one,
u32 sec1_add, u16 sec1_syndrome)
{
u32 page;
int row;
int channel;
int i;
struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info;
edac_dbg(3, "\n");
/* convert the addr to 4k page */
page = sec1_add >> (PAGE_SHIFT - 4);
/* FIXME - check for -1 */
if (pvt->mc_symmetric) {
/* chip select are bits 14 & 13 */
row = ((page >> 1) & 3);
e752x_printk(KERN_WARNING,
"Test row %d Table %d %d %d %d %d %d %d %d\n", row,
pvt->map[0], pvt->map[1], pvt->map[2], pvt->map[3],
pvt->map[4], pvt->map[5], pvt->map[6],
pvt->map[7]);
/* test for channel remapping */
for (i = 0; i < 8; i++) {
if (pvt->map[i] == row)
break;
}
e752x_printk(KERN_WARNING, "Test computed row %d\n", i);
if (i < 8)
row = i;
else
e752x_mc_printk(mci, KERN_WARNING,
"row %d not found in remap table\n",
row);
} else
row = edac_mc_find_csrow_by_page(mci, page);
/* 0 = channel A, 1 = channel B */
channel = !(error_one & 1);
/* e752x mc reads 34:6 of the DRAM linear address */
edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
page, offset_in_page(sec1_add << 4), sec1_syndrome,
row, channel, -1,
"e752x CE", "");
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 233 | 88.93% | 1 | 14.29% |
Mauro Carvalho Chehab | 11 | 4.20% | 3 | 42.86% |
Dave Peterson | 8 | 3.05% | 1 | 14.29% |
Mike Chan | 7 | 2.67% | 1 | 14.29% |
Joe Perches | 3 | 1.15% | 1 | 14.29% |
Total | 262 | 100.00% | 7 | 100.00% |
static inline void process_ce(struct mem_ctl_info *mci, u16 error_one,
u32 sec1_add, u16 sec1_syndrome, int *error_found,
int handle_error)
{
*error_found = 1;
if (handle_error)
do_process_ce(mci, error_one, sec1_add, sec1_syndrome);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 48 | 100.00% | 1 | 100.00% |
Total | 48 | 100.00% | 1 | 100.00% |
static void do_process_ue(struct mem_ctl_info *mci, u16 error_one,
u32 ded_add, u32 scrb_add)
{
u32 error_2b, block_page;
int row;
struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info;
edac_dbg(3, "\n");
if (error_one & 0x0202) {
error_2b = ded_add;
/* convert to 4k address */
block_page = error_2b >> (PAGE_SHIFT - 4);
row = pvt->mc_symmetric ?
/* chip select are bits 14 & 13 */
((block_page >> 1) & 3) :
edac_mc_find_csrow_by_page(mci, block_page);
/* e752x mc reads 34:6 of the DRAM linear address */
edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
block_page,
offset_in_page(error_2b << 4), 0,
row, -1, -1,
"e752x UE from Read", "");
}
if (error_one & 0x0404) {
error_2b = scrb_add;
/* convert to 4k address */
block_page = error_2b >> (PAGE_SHIFT - 4);
row = pvt->mc_symmetric ?
/* chip select are bits 14 & 13 */
((block_page >> 1) & 3) :
edac_mc_find_csrow_by_page(mci, block_page);
/* e752x mc reads 34:6 of the DRAM linear address */
edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
block_page,
offset_in_page(error_2b << 4), 0,
row, -1, -1,
"e752x UE from Scruber", "");
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 161 | 77.03% | 1 | 16.67% |
Mauro Carvalho Chehab | 31 | 14.83% | 3 | 50.00% |
Mike Chan | 14 | 6.70% | 1 | 16.67% |
Joe Perches | 3 | 1.44% | 1 | 16.67% |
Total | 209 | 100.00% | 6 | 100.00% |
static inline void process_ue(struct mem_ctl_info *mci, u16 error_one,
u32 ded_add, u32 scrb_add, int *error_found,
int handle_error)
{
*error_found = 1;
if (handle_error)
do_process_ue(mci, error_one, ded_add, scrb_add);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 48 | 100.00% | 1 | 100.00% |
Total | 48 | 100.00% | 1 | 100.00% |
static inline void process_ue_no_info_wr(struct mem_ctl_info *mci,
int *error_found, int handle_error)
{
*error_found = 1;
if (!handle_error)
return;
edac_dbg(3, "\n");
edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1, 0, 0, 0,
-1, -1, -1,
"e752x UE log memory write", "");
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 39 | 60.00% | 1 | 20.00% |
Mauro Carvalho Chehab | 23 | 35.38% | 3 | 60.00% |
Joe Perches | 3 | 4.62% | 1 | 20.00% |
Total | 65 | 100.00% | 5 | 100.00% |
static void do_process_ded_retry(struct mem_ctl_info *mci, u16 error,
u32 retry_add)
{
u32 error_1b, page;
int row;
struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info;
error_1b = retry_add;
page = error_1b >> (PAGE_SHIFT - 4); /* convert the addr to 4k page */
/* chip select are bits 14 & 13 */
row = pvt->mc_symmetric ? ((page >> 1) & 3) :
edac_mc_find_csrow_by_page(mci, page);
e752x_mc_printk(mci, KERN_WARNING,
"CE page 0x%lx, row %d : Memory read retry\n",
(long unsigned int)page, row);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 91 | 94.79% | 1 | 33.33% |
Dave Peterson | 4 | 4.17% | 1 | 33.33% |
Doug Thompson | 1 | 1.04% | 1 | 33.33% |
Total | 96 | 100.00% | 3 | 100.00% |
static inline void process_ded_retry(struct mem_ctl_info *mci, u16 error,
u32 retry_add, int *error_found,
int handle_error)
{
*error_found = 1;
if (handle_error)
do_process_ded_retry(mci, error, retry_add);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 43 | 100.00% | 1 | 100.00% |
Total | 43 | 100.00% | 1 | 100.00% |
static inline void process_threshold_ce(struct mem_ctl_info *mci, u16 error,
int *error_found, int handle_error)
{
*error_found = 1;
if (handle_error)
e752x_mc_printk(mci, KERN_WARNING, "Memory threshold CE\n");
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 36 | 90.00% | 1 | 50.00% |
Dave Peterson | 4 | 10.00% | 1 | 50.00% |
Total | 40 | 100.00% | 2 | 100.00% |
static char *global_message[11] = {
"PCI Express C1",
"PCI Express C",
"PCI Express B1",
"PCI Express B",
"PCI Express A1",
"PCI Express A",
"DMA Controller",
"HUB or NS Interface",
"System Bus",
"DRAM Controller", /* 9th entry */
"Internal Buffer"
};
#define DRAM_ENTRY 9
static char *fatal_message[2] = { "Non-Fatal ", "Fatal " };
static void do_global_error(int fatal, u32 errors)
{
int i;
for (i = 0; i < 11; i++) {
if (errors & (1 << i)) {
/* If the error is from DRAM Controller OR
* we are to report ALL errors, then
* report the error
*/
if ((i == DRAM_ENTRY) || report_non_memory_errors)
e752x_printk(KERN_WARNING, "%sError %s\n",
fatal_message[fatal],
global_message[i]);
}
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 55 | 78.57% | 1 | 33.33% |
Doug Thompson | 13 | 18.57% | 1 | 33.33% |
Dave Peterson | 2 | 2.86% | 1 | 33.33% |
Total | 70 | 100.00% | 3 | 100.00% |
static inline void global_error(int fatal, u32 errors, int *error_found,
int handle_error)
{
*error_found = 1;
if (handle_error)
do_global_error(fatal, errors);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 36 | 100.00% | 1 | 100.00% |
Total | 36 | 100.00% | 1 | 100.00% |
static char *hub_message[7] = {
"HI Address or Command Parity", "HI Illegal Access",
"HI Internal Parity", "Out of Range Access",
"HI Data Parity", "Enhanced Config Access",
"Hub Interface Target Abort"
};
static void do_hub_error(int fatal, u8 errors)
{
int i;
for (i = 0; i < 7; i++) {
if (errors & (1 << i))
e752x_printk(KERN_WARNING, "%sError %s\n",
fatal_message[fatal], hub_message[i]);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 55 | 96.49% | 1 | 50.00% |
Dave Peterson | 2 | 3.51% | 1 | 50.00% |
Total | 57 | 100.00% | 2 | 100.00% |
static inline void hub_error(int fatal, u8 errors, int *error_found,
int handle_error)
{
*error_found = 1;
if (handle_error)
do_hub_error(fatal, errors);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 36 | 100.00% | 1 | 100.00% |
Total | 36 | 100.00% | 1 | 100.00% |
#define NSI_FATAL_MASK 0x0c080081
#define NSI_NON_FATAL_MASK 0x23a0ba64
#define NSI_ERR_MASK (NSI_FATAL_MASK | NSI_NON_FATAL_MASK)
static char *nsi_message[30] = {
"NSI Link Down", /* NSI_FERR/NSI_NERR bit 0, fatal error */
"", /* reserved */
"NSI Parity Error", /* bit 2, non-fatal */
"", /* reserved */
"", /* reserved */
"Correctable Error Message", /* bit 5, non-fatal */
"Non-Fatal Error Message", /* bit 6, non-fatal */
"Fatal Error Message", /* bit 7, fatal */
"", /* reserved */
"Receiver Error", /* bit 9, non-fatal */
"", /* reserved */
"Bad TLP", /* bit 11, non-fatal */
"Bad DLLP", /* bit 12, non-fatal */
"REPLAY_NUM Rollover", /* bit 13, non-fatal */
"", /* reserved */
"Replay Timer Timeout", /* bit 15, non-fatal */
"", /* reserved */
"", /* reserved */
"", /* reserved */
"Data Link Protocol Error", /* bit 19, fatal */
"", /* reserved */
"Poisoned TLP", /* bit 21, non-fatal */
"", /* reserved */
"Completion Timeout", /* bit 23, non-fatal */
"Completer Abort", /* bit 24, non-fatal */
"Unexpected Completion", /* bit 25, non-fatal */
"Receiver Overflow", /* bit 26, fatal */
"Malformed TLP", /* bit 27, fatal */
"", /* reserved */
"Unsupported Request" /* bit 29, non-fatal */
};
static void do_nsi_error(int fatal, u32 errors)
{
int i;
for (i = 0; i < 30; i++) {
if (errors & (1 << i))
printk(KERN_WARNING "%sError %s\n",
fatal_message[fatal], nsi_message[i]);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrei Konovalov | 56 | 100.00% | 1 | 100.00% |
Total | 56 | 100.00% | 1 | 100.00% |
static inline void nsi_error(int fatal, u32 errors, int *error_found,
int handle_error)
{
*error_found = 1;
if (handle_error)
do_nsi_error(fatal, errors);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrei Konovalov | 36 | 100.00% | 1 | 100.00% |
Total | 36 | 100.00% | 1 | 100.00% |
static char *membuf_message[4] = {
"Internal PMWB to DRAM parity",
"Internal PMWB to System Bus Parity",
"Internal System Bus or IO to PMWB Parity",
"Internal DRAM to PMWB Parity"
};
static void do_membuf_error(u8 errors)
{
int i;
for (i = 0; i < 4; i++) {
if (errors & (1 << i))
e752x_printk(KERN_WARNING, "Non-Fatal Error %s\n",
membuf_message[i]);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 47 | 95.92% | 1 | 50.00% |
Dave Peterson | 2 | 4.08% | 1 | 50.00% |
Total | 49 | 100.00% | 2 | 100.00% |
static inline void membuf_error(u8 errors, int *error_found, int handle_error)
{
*error_found = 1;
if (handle_error)
do_membuf_error(errors);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 31 | 100.00% | 1 | 100.00% |
Total | 31 | 100.00% | 1 | 100.00% |
static char *sysbus_message[10] = {
"Addr or Request Parity",
"Data Strobe Glitch",
"Addr Strobe Glitch",
"Data Parity",
"Addr Above TOM",
"Non DRAM Lock Error",
"MCERR", "BINIT",
"Memory Parity",
"IO Subsystem Parity"
};
static void do_sysbus_error(int fatal, u32 errors)
{
int i;
for (i = 0; i < 10; i++) {
if (errors & (1 << i))
e752x_printk(KERN_WARNING, "%sError System Bus %s\n",
fatal_message[fatal], sysbus_message[i]);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 54 | 94.74% | 1 | 33.33% |
Dave Peterson | 3 | 5.26% | 2 | 66.67% |
Total | 57 | 100.00% | 3 | 100.00% |
static inline void sysbus_error(int fatal, u32 errors, int *error_found,
int handle_error)
{
*error_found = 1;
if (handle_error)
do_sysbus_error(fatal, errors);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 36 | 100.00% | 1 | 100.00% |
Total | 36 | 100.00% | 1 | 100.00% |
static void e752x_check_hub_interface(struct e752x_error_info *info,
int *error_found, int handle_error)
{
u8 stat8;
//pci_read_config_byte(dev,E752X_HI_FERR,&stat8);
stat8 = info->hi_ferr;
if (stat8 & 0x7f) { /* Error, so process */
stat8 &= 0x7f;
if (stat8 & 0x2b)
hub_error(1, stat8 & 0x2b, error_found, handle_error);
if (stat8 & 0x54)
hub_error(0, stat8 & 0x54, error_found, handle_error);
}
//pci_read_config_byte(dev,E752X_HI_NERR,&stat8);
stat8 = info->hi_nerr;
if (stat8 & 0x7f) { /* Error, so process */
stat8 &= 0x7f;
if (stat8 & 0x2b)
hub_error(1, stat8 & 0x2b, error_found, handle_error);
if (stat8 & 0x54)
hub_error(0, stat8 & 0x54, error_found, handle_error);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 137 | 100.00% | 1 | 100.00% |
Total | 137 | 100.00% | 1 | 100.00% |
static void e752x_check_ns_interface(struct e752x_error_info *info,
int *error_found, int handle_error)
{
u32 stat32;
stat32 = info->nsi_ferr;
if (stat32 & NSI_ERR_MASK) { /* Error, so process */
if (stat32 & NSI_FATAL_MASK) /* check for fatal errors */
nsi_error(1, stat32 & NSI_FATAL_MASK, error_found,
handle_error);
if (stat32 & NSI_NON_FATAL_MASK) /* check for non-fatal ones */
nsi_error(0, stat32 & NSI_NON_FATAL_MASK, error_found,
handle_error);
}
stat32 = info->nsi_nerr;
if (stat32 & NSI_ERR_MASK) {
if (stat32 & NSI_FATAL_MASK)
nsi_error(1, stat32 & NSI_FATAL_MASK, error_found,
handle_error);
if (stat32 & NSI_NON_FATAL_MASK)
nsi_error(0, stat32 & NSI_NON_FATAL_MASK, error_found,
handle_error);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andrei Konovalov | 128 | 100.00% | 1 | 100.00% |
Total | 128 | 100.00% | 1 | 100.00% |
static void e752x_check_sysbus(struct e752x_error_info *info,
int *error_found, int handle_error)
{
u32 stat32, error32;
//pci_read_config_dword(dev,E752X_SYSBUS_FERR,&stat32);
stat32 = info->sysbus_ferr + (info->sysbus_nerr << 16);
if (stat32 == 0)
return; /* no errors */
error32 = (stat32 >> 16) & 0x3ff;
stat32 = stat32 & 0x3ff;
if (stat32 & 0x087)
sysbus_error(1, stat32 & 0x087, error_found, handle_error);
if (stat32 & 0x378)
sysbus_error(0, stat32 & 0x378, error_found, handle_error);
if (error32 & 0x087)
sysbus_error(1, error32 & 0x087, error_found, handle_error);
if (error32 & 0x378)
sysbus_error(0, error32 & 0x378, error_found, handle_error);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 130 | 94.20% | 1 | 50.00% |
Brian Pomerantz | 8 | 5.80% | 1 | 50.00% |
Total | 138 | 100.00% | 2 | 100.00% |
static void e752x_check_membuf(struct e752x_error_info *info,
int *error_found, int handle_error)
{
u8 stat8;
stat8 = info->buf_ferr;
if (stat8 & 0x0f) { /* Error, so process */
stat8 &= 0x0f;
membuf_error(stat8, error_found, handle_error);
}
stat8 = info->buf_nerr;
if (stat8 & 0x0f) { /* Error, so process */
stat8 &= 0x0f;
membuf_error(stat8, error_found, handle_error);
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Alan Cox | 77 | 100.00% | 1 | 100.00% |
Total | 77 | 100.00% | 1 | 100.00% |
static void e752x_check_dram(struct mem_ctl_info *mci,
struct e752x_error_info *info, int *error_found,
int handle_error)
{
u16 error_one, error_next;
error_one = info->dram_ferr;
error_next = info->dram_nerr;