Blame view
drivers/edac/e752x_edac.c
39.7 KB
806c35f50 [PATCH] EDAC: dri... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/* * 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. * * See "enum e752x_chips" below for supported chipsets * * Written by Tom Zimmerman * * Contributors: * Thayne Harbaugh at realmsys.com (?) * Wang Zhenyu at intel.com * Dave Jiang at mvista.com * |
da9bb1d27 [PATCH] EDAC: cor... |
16 |
* $Id: edac_e752x.c,v 1.5.2.11 2005/10/05 00:43:44 dsp_llnl Exp $ |
806c35f50 [PATCH] EDAC: dri... |
17 18 |
* */ |
806c35f50 [PATCH] EDAC: dri... |
19 20 |
#include <linux/module.h> #include <linux/init.h> |
806c35f50 [PATCH] EDAC: dri... |
21 22 |
#include <linux/pci.h> #include <linux/pci_ids.h> |
c0d121720 drivers/edac: add... |
23 |
#include <linux/edac.h> |
20bcb7a81 drivers/edac: mod... |
24 |
#include "edac_core.h" |
806c35f50 [PATCH] EDAC: dri... |
25 |
|
152ba3942 edac: Drop __DATE... |
26 |
#define E752X_REVISION " Ver: 2.0.2" |
929a40ec3 [PATCH] EDAC: fix... |
27 |
#define EDAC_MOD_STR "e752x_edac" |
37f04581a [PATCH] EDAC: PCI... |
28 |
|
10d33e9c3 edac: e752x fix t... |
29 |
static int report_non_memory_errors; |
96941026a [PATCH] EDAC Coex... |
30 |
static int force_function_unhide; |
94ee1cf5a edac: add e752x p... |
31 |
static int sysbus_parity = -1; |
96941026a [PATCH] EDAC Coex... |
32 |
|
91b99041c drivers/edac: upd... |
33 |
static struct edac_pci_ctl_info *e752x_pci; |
537fba289 [PATCH] EDAC: pri... |
34 |
#define e752x_printk(level, fmt, arg...) \ |
e7ecd8910 [PATCH] EDAC: for... |
35 |
edac_printk(level, "e752x", fmt, ##arg) |
537fba289 [PATCH] EDAC: pri... |
36 37 |
#define e752x_mc_printk(mci, level, fmt, arg...) \ |
e7ecd8910 [PATCH] EDAC: for... |
38 |
edac_mc_chipset_printk(mci, level, "e752x", fmt, ##arg) |
537fba289 [PATCH] EDAC: pri... |
39 |
|
806c35f50 [PATCH] EDAC: dri... |
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
#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 */ |
5135b797c edac: new support... |
63 64 65 66 67 68 69 |
#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 */ |
806c35f50 [PATCH] EDAC: dri... |
70 |
#define E752X_NR_CSROWS 8 /* number of csrows */ |
806c35f50 [PATCH] EDAC: dri... |
71 |
/* E752X register addresses - device 0 function 0 */ |
8004fd2ad edac: e752x: add ... |
72 73 74 75 76 77 78 79 |
#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 */ |
806c35f50 [PATCH] EDAC: dri... |
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
#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) */ |
10d33e9c3 edac: e752x fix t... |
123 |
#define E752X_BUF_SMICMD 0x7A /* Memory buffer SMI cmd reg (8b) */ |
806c35f50 [PATCH] EDAC: dri... |
124 125 126 127 128 129 130 131 132 |
#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 |
10d33e9c3 edac: e752x fix t... |
133 |
* 30:2 CE address (64 byte block 34:6 |
806c35f50 [PATCH] EDAC: dri... |
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
* 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 */ |
10d33e9c3 edac: e752x fix t... |
153 |
#define E752X_DRAM_SCRB_ADD 0xA8 /* DRAM 1st uncorrectable scrub mem */ |
806c35f50 [PATCH] EDAC: dri... |
154 155 156 |
/* error address register (32b) */ /* * 31 Reserved |
10d33e9c3 edac: e752x fix t... |
157 |
* 30:2 CE address (64 byte block 34:6 |
806c35f50 [PATCH] EDAC: dri... |
158 159 160 161 162 163 164 165 |
* 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) */ |
5135b797c edac: new support... |
166 167 168 169 170 |
/* 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) */ |
806c35f50 [PATCH] EDAC: dri... |
171 172 173 174 175 176 177 178 |
/* 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, |
5135b797c edac: new support... |
179 180 |
E7320 = 2, I3100 = 3 |
806c35f50 [PATCH] EDAC: dri... |
181 |
}; |
806c35f50 [PATCH] EDAC: dri... |
182 183 184 185 186 187 188 189 190 191 192 193 |
struct e752x_pvt { struct pci_dev *bridge_ck; 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; }; |
806c35f50 [PATCH] EDAC: dri... |
194 195 |
struct e752x_dev_info { u16 err_dev; |
3847bccce [PATCH] EDAC: e75... |
196 |
u16 ctl_dev; |
806c35f50 [PATCH] EDAC: dri... |
197 198 199 200 201 202 |
const char *ctl_name; }; struct e752x_error_info { u32 ferr_global; u32 nerr_global; |
5135b797c edac: new support... |
203 204 205 206 |
u32 nsi_ferr; /* 3100 only */ u32 nsi_nerr; /* 3100 only */ u8 hi_ferr; /* all but 3100 */ u8 hi_nerr; /* all but 3100 */ |
806c35f50 [PATCH] EDAC: dri... |
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
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] = { |
052dfb45c drivers/edac: cle... |
224 225 226 |
.err_dev = PCI_DEVICE_ID_INTEL_7520_1_ERR, .ctl_dev = PCI_DEVICE_ID_INTEL_7520_0, .ctl_name = "E7520"}, |
806c35f50 [PATCH] EDAC: dri... |
227 |
[E7525] = { |
052dfb45c drivers/edac: cle... |
228 229 230 |
.err_dev = PCI_DEVICE_ID_INTEL_7525_1_ERR, .ctl_dev = PCI_DEVICE_ID_INTEL_7525_0, .ctl_name = "E7525"}, |
806c35f50 [PATCH] EDAC: dri... |
231 |
[E7320] = { |
052dfb45c drivers/edac: cle... |
232 233 234 |
.err_dev = PCI_DEVICE_ID_INTEL_7320_1_ERR, .ctl_dev = PCI_DEVICE_ID_INTEL_7320_0, .ctl_name = "E7320"}, |
5135b797c edac: new support... |
235 236 237 238 |
[I3100] = { .err_dev = PCI_DEVICE_ID_INTEL_3100_1_ERR, .ctl_dev = PCI_DEVICE_ID_INTEL_3100_0, .ctl_name = "3100"}, |
806c35f50 [PATCH] EDAC: dri... |
239 |
}; |
8004fd2ad edac: e752x: add ... |
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
/* 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 */ }; |
806c35f50 [PATCH] EDAC: dri... |
274 |
static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci, |
052dfb45c drivers/edac: cle... |
275 |
unsigned long page) |
806c35f50 [PATCH] EDAC: dri... |
276 277 |
{ u32 remap; |
203333cbb drivers/edac: Lin... |
278 |
struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info; |
806c35f50 [PATCH] EDAC: dri... |
279 |
|
537fba289 [PATCH] EDAC: pri... |
280 281 |
debugf3("%s() ", __func__); |
806c35f50 [PATCH] EDAC: dri... |
282 283 284 |
if (page < pvt->tolm) return page; |
e7ecd8910 [PATCH] EDAC: for... |
285 |
|
806c35f50 [PATCH] EDAC: dri... |
286 287 |
if ((page >= 0x100000) && (page < pvt->remapbase)) return page; |
e7ecd8910 [PATCH] EDAC: for... |
288 |
|
806c35f50 [PATCH] EDAC: dri... |
289 |
remap = (page - pvt->tolm) + pvt->remapbase; |
e7ecd8910 [PATCH] EDAC: for... |
290 |
|
806c35f50 [PATCH] EDAC: dri... |
291 292 |
if (remap < pvt->remaplimit) return remap; |
e7ecd8910 [PATCH] EDAC: for... |
293 |
|
537fba289 [PATCH] EDAC: pri... |
294 295 |
e752x_printk(KERN_ERR, "Invalid page %lx - out of range ", page); |
806c35f50 [PATCH] EDAC: dri... |
296 297 298 299 |
return pvt->tolm - 1; } static void do_process_ce(struct mem_ctl_info *mci, u16 error_one, |
052dfb45c drivers/edac: cle... |
300 |
u32 sec1_add, u16 sec1_syndrome) |
806c35f50 [PATCH] EDAC: dri... |
301 302 303 304 305 |
{ u32 page; int row; int channel; int i; |
203333cbb drivers/edac: Lin... |
306 |
struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info; |
806c35f50 [PATCH] EDAC: dri... |
307 |
|
537fba289 [PATCH] EDAC: pri... |
308 309 |
debugf3("%s() ", __func__); |
806c35f50 [PATCH] EDAC: dri... |
310 311 312 313 314 315 316 317 |
/* 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); |
537fba289 [PATCH] EDAC: pri... |
318 |
e752x_printk(KERN_WARNING, |
052dfb45c drivers/edac: cle... |
319 320 321 322 323 |
"Test row %d Table %d %d %d %d %d %d %d %d ", 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]); |
806c35f50 [PATCH] EDAC: dri... |
324 325 326 327 328 329 |
/* test for channel remapping */ for (i = 0; i < 8; i++) { if (pvt->map[i] == row) break; } |
e7ecd8910 [PATCH] EDAC: for... |
330 |
|
537fba289 [PATCH] EDAC: pri... |
331 332 |
e752x_printk(KERN_WARNING, "Test computed row %d ", i); |
e7ecd8910 [PATCH] EDAC: for... |
333 |
|
806c35f50 [PATCH] EDAC: dri... |
334 335 336 |
if (i < 8) row = i; else |
537fba289 [PATCH] EDAC: pri... |
337 |
e752x_mc_printk(mci, KERN_WARNING, |
203333cbb drivers/edac: Lin... |
338 339 340 |
"row %d not found in remap table ", row); |
806c35f50 [PATCH] EDAC: dri... |
341 342 |
} else row = edac_mc_find_csrow_by_page(mci, page); |
e7ecd8910 [PATCH] EDAC: for... |
343 |
|
806c35f50 [PATCH] EDAC: dri... |
344 345 |
/* 0 = channel A, 1 = channel B */ channel = !(error_one & 1); |
84db003f2 [PATCH] EDAC: Fix... |
346 347 |
/* e752x mc reads 34:6 of the DRAM linear address */ edac_mc_handle_ce(mci, page, offset_in_page(sec1_add << 4), |
052dfb45c drivers/edac: cle... |
348 |
sec1_syndrome, row, channel, "e752x CE"); |
806c35f50 [PATCH] EDAC: dri... |
349 |
} |
806c35f50 [PATCH] EDAC: dri... |
350 |
static inline void process_ce(struct mem_ctl_info *mci, u16 error_one, |
052dfb45c drivers/edac: cle... |
351 352 |
u32 sec1_add, u16 sec1_syndrome, int *error_found, int handle_error) |
806c35f50 [PATCH] EDAC: dri... |
353 354 355 356 357 358 |
{ *error_found = 1; if (handle_error) do_process_ce(mci, error_one, sec1_add, sec1_syndrome); } |
e7ecd8910 [PATCH] EDAC: for... |
359 |
static void do_process_ue(struct mem_ctl_info *mci, u16 error_one, |
052dfb45c drivers/edac: cle... |
360 |
u32 ded_add, u32 scrb_add) |
806c35f50 [PATCH] EDAC: dri... |
361 362 363 |
{ u32 error_2b, block_page; int row; |
203333cbb drivers/edac: Lin... |
364 |
struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info; |
806c35f50 [PATCH] EDAC: dri... |
365 |
|
537fba289 [PATCH] EDAC: pri... |
366 367 |
debugf3("%s() ", __func__); |
806c35f50 [PATCH] EDAC: dri... |
368 369 370 |
if (error_one & 0x0202) { error_2b = ded_add; |
e7ecd8910 [PATCH] EDAC: for... |
371 |
|
806c35f50 [PATCH] EDAC: dri... |
372 373 |
/* convert to 4k address */ block_page = error_2b >> (PAGE_SHIFT - 4); |
e7ecd8910 [PATCH] EDAC: for... |
374 |
|
806c35f50 [PATCH] EDAC: dri... |
375 |
row = pvt->mc_symmetric ? |
052dfb45c drivers/edac: cle... |
376 377 378 |
/* chip select are bits 14 & 13 */ ((block_page >> 1) & 3) : edac_mc_find_csrow_by_page(mci, block_page); |
e7ecd8910 [PATCH] EDAC: for... |
379 |
|
84db003f2 [PATCH] EDAC: Fix... |
380 381 |
/* e752x mc reads 34:6 of the DRAM linear address */ edac_mc_handle_ue(mci, block_page, |
052dfb45c drivers/edac: cle... |
382 383 |
offset_in_page(error_2b << 4), row, "e752x UE from Read"); |
806c35f50 [PATCH] EDAC: dri... |
384 385 386 |
} if (error_one & 0x0404) { error_2b = scrb_add; |
e7ecd8910 [PATCH] EDAC: for... |
387 |
|
806c35f50 [PATCH] EDAC: dri... |
388 389 |
/* convert to 4k address */ block_page = error_2b >> (PAGE_SHIFT - 4); |
e7ecd8910 [PATCH] EDAC: for... |
390 |
|
806c35f50 [PATCH] EDAC: dri... |
391 |
row = pvt->mc_symmetric ? |
052dfb45c drivers/edac: cle... |
392 393 394 |
/* chip select are bits 14 & 13 */ ((block_page >> 1) & 3) : edac_mc_find_csrow_by_page(mci, block_page); |
e7ecd8910 [PATCH] EDAC: for... |
395 |
|
84db003f2 [PATCH] EDAC: Fix... |
396 397 |
/* e752x mc reads 34:6 of the DRAM linear address */ edac_mc_handle_ue(mci, block_page, |
052dfb45c drivers/edac: cle... |
398 399 |
offset_in_page(error_2b << 4), row, "e752x UE from Scruber"); |
806c35f50 [PATCH] EDAC: dri... |
400 401 402 403 |
} } static inline void process_ue(struct mem_ctl_info *mci, u16 error_one, |
052dfb45c drivers/edac: cle... |
404 405 |
u32 ded_add, u32 scrb_add, int *error_found, int handle_error) |
806c35f50 [PATCH] EDAC: dri... |
406 407 408 409 410 411 412 413 |
{ *error_found = 1; if (handle_error) do_process_ue(mci, error_one, ded_add, scrb_add); } static inline void process_ue_no_info_wr(struct mem_ctl_info *mci, |
203333cbb drivers/edac: Lin... |
414 |
int *error_found, int handle_error) |
806c35f50 [PATCH] EDAC: dri... |
415 416 417 418 419 |
{ *error_found = 1; if (!handle_error) return; |
537fba289 [PATCH] EDAC: pri... |
420 421 |
debugf3("%s() ", __func__); |
806c35f50 [PATCH] EDAC: dri... |
422 423 424 425 |
edac_mc_handle_ue_no_info(mci, "e752x UE log memory write"); } static void do_process_ded_retry(struct mem_ctl_info *mci, u16 error, |
203333cbb drivers/edac: Lin... |
426 |
u32 retry_add) |
806c35f50 [PATCH] EDAC: dri... |
427 428 429 |
{ u32 error_1b, page; int row; |
203333cbb drivers/edac: Lin... |
430 |
struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info; |
806c35f50 [PATCH] EDAC: dri... |
431 432 |
error_1b = retry_add; |
10d33e9c3 edac: e752x fix t... |
433 434 435 436 |
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) : |
052dfb45c drivers/edac: cle... |
437 |
edac_mc_find_csrow_by_page(mci, page); |
10d33e9c3 edac: e752x fix t... |
438 |
|
537fba289 [PATCH] EDAC: pri... |
439 |
e752x_mc_printk(mci, KERN_WARNING, |
203333cbb drivers/edac: Lin... |
440 441 442 |
"CE page 0x%lx, row %d : Memory read retry ", (long unsigned int)page, row); |
806c35f50 [PATCH] EDAC: dri... |
443 444 445 |
} static inline void process_ded_retry(struct mem_ctl_info *mci, u16 error, |
052dfb45c drivers/edac: cle... |
446 447 |
u32 retry_add, int *error_found, int handle_error) |
806c35f50 [PATCH] EDAC: dri... |
448 449 450 451 452 453 454 455 |
{ *error_found = 1; if (handle_error) do_process_ded_retry(mci, error, retry_add); } static inline void process_threshold_ce(struct mem_ctl_info *mci, u16 error, |
203333cbb drivers/edac: Lin... |
456 |
int *error_found, int handle_error) |
806c35f50 [PATCH] EDAC: dri... |
457 458 459 460 |
{ *error_found = 1; if (handle_error) |
537fba289 [PATCH] EDAC: pri... |
461 462 |
e752x_mc_printk(mci, KERN_WARNING, "Memory threshold CE "); |
806c35f50 [PATCH] EDAC: dri... |
463 |
} |
da9bb1d27 [PATCH] EDAC: cor... |
464 |
static char *global_message[11] = { |
10d33e9c3 edac: e752x fix t... |
465 466 467 468 469 470 471 472 473 474 475 |
"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" |
806c35f50 [PATCH] EDAC: dri... |
476 |
}; |
10d33e9c3 edac: e752x fix t... |
477 |
#define DRAM_ENTRY 9 |
da9bb1d27 [PATCH] EDAC: cor... |
478 |
static char *fatal_message[2] = { "Non-Fatal ", "Fatal " }; |
806c35f50 [PATCH] EDAC: dri... |
479 480 481 482 483 484 |
static void do_global_error(int fatal, u32 errors) { int i; for (i = 0; i < 11; i++) { |
10d33e9c3 edac: e752x fix t... |
485 486 487 488 489 490 491 492 493 494 495 |
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 ", fatal_message[fatal], global_message[i]); } |
806c35f50 [PATCH] EDAC: dri... |
496 497 498 499 |
} } static inline void global_error(int fatal, u32 errors, int *error_found, |
203333cbb drivers/edac: Lin... |
500 |
int handle_error) |
806c35f50 [PATCH] EDAC: dri... |
501 502 503 504 505 506 |
{ *error_found = 1; if (handle_error) do_global_error(fatal, errors); } |
da9bb1d27 [PATCH] EDAC: cor... |
507 |
static char *hub_message[7] = { |
806c35f50 [PATCH] EDAC: dri... |
508 509 510 511 512 513 514 515 516 517 518 519 |
"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)) |
537fba289 [PATCH] EDAC: pri... |
520 521 |
e752x_printk(KERN_WARNING, "%sError %s ", |
052dfb45c drivers/edac: cle... |
522 |
fatal_message[fatal], hub_message[i]); |
806c35f50 [PATCH] EDAC: dri... |
523 524 525 526 |
} } static inline void hub_error(int fatal, u8 errors, int *error_found, |
052dfb45c drivers/edac: cle... |
527 |
int handle_error) |
806c35f50 [PATCH] EDAC: dri... |
528 529 530 531 532 533 |
{ *error_found = 1; if (handle_error) do_hub_error(fatal, errors); } |
5135b797c edac: new support... |
534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 |
#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 ", fatal_message[fatal], nsi_message[i]); } } 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); } |
da9bb1d27 [PATCH] EDAC: cor... |
591 |
static char *membuf_message[4] = { |
806c35f50 [PATCH] EDAC: dri... |
592 593 594 595 596 597 598 599 600 601 602 603 |
"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)) |
537fba289 [PATCH] EDAC: pri... |
604 605 |
e752x_printk(KERN_WARNING, "Non-Fatal Error %s ", |
052dfb45c drivers/edac: cle... |
606 |
membuf_message[i]); |
806c35f50 [PATCH] EDAC: dri... |
607 608 609 610 611 612 613 614 615 616 |
} } static inline void membuf_error(u8 errors, int *error_found, int handle_error) { *error_found = 1; if (handle_error) do_membuf_error(errors); } |
e009356f7 [PATCH] EDAC: use... |
617 |
static char *sysbus_message[10] = { |
806c35f50 [PATCH] EDAC: dri... |
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 |
"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)) |
537fba289 [PATCH] EDAC: pri... |
635 636 |
e752x_printk(KERN_WARNING, "%sError System Bus %s ", |
052dfb45c drivers/edac: cle... |
637 |
fatal_message[fatal], sysbus_message[i]); |
806c35f50 [PATCH] EDAC: dri... |
638 639 640 641 |
} } static inline void sysbus_error(int fatal, u32 errors, int *error_found, |
203333cbb drivers/edac: Lin... |
642 |
int handle_error) |
806c35f50 [PATCH] EDAC: dri... |
643 644 645 646 647 648 |
{ *error_found = 1; if (handle_error) do_sysbus_error(fatal, errors); } |
e7ecd8910 [PATCH] EDAC: for... |
649 |
static void e752x_check_hub_interface(struct e752x_error_info *info, |
052dfb45c drivers/edac: cle... |
650 |
int *error_found, int handle_error) |
806c35f50 [PATCH] EDAC: dri... |
651 652 653 654 |
{ u8 stat8; //pci_read_config_byte(dev,E752X_HI_FERR,&stat8); |
e7ecd8910 [PATCH] EDAC: for... |
655 |
|
806c35f50 [PATCH] EDAC: dri... |
656 |
stat8 = info->hi_ferr; |
e7ecd8910 [PATCH] EDAC: for... |
657 |
|
203333cbb drivers/edac: Lin... |
658 |
if (stat8 & 0x7f) { /* Error, so process */ |
806c35f50 [PATCH] EDAC: dri... |
659 |
stat8 &= 0x7f; |
e7ecd8910 [PATCH] EDAC: for... |
660 |
|
203333cbb drivers/edac: Lin... |
661 |
if (stat8 & 0x2b) |
806c35f50 [PATCH] EDAC: dri... |
662 |
hub_error(1, stat8 & 0x2b, error_found, handle_error); |
e7ecd8910 [PATCH] EDAC: for... |
663 |
|
203333cbb drivers/edac: Lin... |
664 |
if (stat8 & 0x54) |
806c35f50 [PATCH] EDAC: dri... |
665 666 667 |
hub_error(0, stat8 & 0x54, error_found, handle_error); } //pci_read_config_byte(dev,E752X_HI_NERR,&stat8); |
e7ecd8910 [PATCH] EDAC: for... |
668 |
|
806c35f50 [PATCH] EDAC: dri... |
669 |
stat8 = info->hi_nerr; |
e7ecd8910 [PATCH] EDAC: for... |
670 |
|
203333cbb drivers/edac: Lin... |
671 |
if (stat8 & 0x7f) { /* Error, so process */ |
806c35f50 [PATCH] EDAC: dri... |
672 |
stat8 &= 0x7f; |
e7ecd8910 [PATCH] EDAC: for... |
673 |
|
806c35f50 [PATCH] EDAC: dri... |
674 675 |
if (stat8 & 0x2b) hub_error(1, stat8 & 0x2b, error_found, handle_error); |
e7ecd8910 [PATCH] EDAC: for... |
676 |
|
203333cbb drivers/edac: Lin... |
677 |
if (stat8 & 0x54) |
806c35f50 [PATCH] EDAC: dri... |
678 679 680 |
hub_error(0, stat8 & 0x54, error_found, handle_error); } } |
5135b797c edac: new support... |
681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 |
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); } } |
e7ecd8910 [PATCH] EDAC: for... |
705 |
static void e752x_check_sysbus(struct e752x_error_info *info, |
052dfb45c drivers/edac: cle... |
706 |
int *error_found, int handle_error) |
806c35f50 [PATCH] EDAC: dri... |
707 708 709 710 711 712 713 |
{ u32 stat32, error32; //pci_read_config_dword(dev,E752X_SYSBUS_FERR,&stat32); stat32 = info->sysbus_ferr + (info->sysbus_nerr << 16); if (stat32 == 0) |
203333cbb drivers/edac: Lin... |
714 |
return; /* no errors */ |
806c35f50 [PATCH] EDAC: dri... |
715 716 717 |
error32 = (stat32 >> 16) & 0x3ff; stat32 = stat32 & 0x3ff; |
e7ecd8910 [PATCH] EDAC: for... |
718 |
|
203333cbb drivers/edac: Lin... |
719 |
if (stat32 & 0x087) |
dfb2a7637 [PATCH] EDAC: e75... |
720 |
sysbus_error(1, stat32 & 0x087, error_found, handle_error); |
e7ecd8910 [PATCH] EDAC: for... |
721 |
|
203333cbb drivers/edac: Lin... |
722 |
if (stat32 & 0x378) |
dfb2a7637 [PATCH] EDAC: e75... |
723 |
sysbus_error(0, stat32 & 0x378, error_found, handle_error); |
e7ecd8910 [PATCH] EDAC: for... |
724 |
|
203333cbb drivers/edac: Lin... |
725 |
if (error32 & 0x087) |
dfb2a7637 [PATCH] EDAC: e75... |
726 |
sysbus_error(1, error32 & 0x087, error_found, handle_error); |
e7ecd8910 [PATCH] EDAC: for... |
727 |
|
203333cbb drivers/edac: Lin... |
728 |
if (error32 & 0x378) |
dfb2a7637 [PATCH] EDAC: e75... |
729 |
sysbus_error(0, error32 & 0x378, error_found, handle_error); |
806c35f50 [PATCH] EDAC: dri... |
730 |
} |
203333cbb drivers/edac: Lin... |
731 |
static void e752x_check_membuf(struct e752x_error_info *info, |
052dfb45c drivers/edac: cle... |
732 |
int *error_found, int handle_error) |
806c35f50 [PATCH] EDAC: dri... |
733 734 735 736 |
{ u8 stat8; stat8 = info->buf_ferr; |
e7ecd8910 [PATCH] EDAC: for... |
737 |
|
203333cbb drivers/edac: Lin... |
738 |
if (stat8 & 0x0f) { /* Error, so process */ |
806c35f50 [PATCH] EDAC: dri... |
739 740 741 |
stat8 &= 0x0f; membuf_error(stat8, error_found, handle_error); } |
e7ecd8910 [PATCH] EDAC: for... |
742 |
|
806c35f50 [PATCH] EDAC: dri... |
743 |
stat8 = info->buf_nerr; |
e7ecd8910 [PATCH] EDAC: for... |
744 |
|
203333cbb drivers/edac: Lin... |
745 |
if (stat8 & 0x0f) { /* Error, so process */ |
806c35f50 [PATCH] EDAC: dri... |
746 747 748 749 |
stat8 &= 0x0f; membuf_error(stat8, error_found, handle_error); } } |
203333cbb drivers/edac: Lin... |
750 |
static void e752x_check_dram(struct mem_ctl_info *mci, |
052dfb45c drivers/edac: cle... |
751 752 |
struct e752x_error_info *info, int *error_found, int handle_error) |
806c35f50 [PATCH] EDAC: dri... |
753 754 755 756 757 758 759 |
{ u16 error_one, error_next; error_one = info->dram_ferr; error_next = info->dram_nerr; /* decode and report errors */ |
203333cbb drivers/edac: Lin... |
760 |
if (error_one & 0x0101) /* check first error correctable */ |
806c35f50 [PATCH] EDAC: dri... |
761 |
process_ce(mci, error_one, info->dram_sec1_add, |
052dfb45c drivers/edac: cle... |
762 |
info->dram_sec1_syndrome, error_found, handle_error); |
806c35f50 [PATCH] EDAC: dri... |
763 |
|
203333cbb drivers/edac: Lin... |
764 |
if (error_next & 0x0101) /* check next error correctable */ |
806c35f50 [PATCH] EDAC: dri... |
765 |
process_ce(mci, error_next, info->dram_sec2_add, |
052dfb45c drivers/edac: cle... |
766 |
info->dram_sec2_syndrome, error_found, handle_error); |
806c35f50 [PATCH] EDAC: dri... |
767 |
|
203333cbb drivers/edac: Lin... |
768 |
if (error_one & 0x4040) |
806c35f50 [PATCH] EDAC: dri... |
769 |
process_ue_no_info_wr(mci, error_found, handle_error); |
203333cbb drivers/edac: Lin... |
770 |
if (error_next & 0x4040) |
806c35f50 [PATCH] EDAC: dri... |
771 |
process_ue_no_info_wr(mci, error_found, handle_error); |
203333cbb drivers/edac: Lin... |
772 |
if (error_one & 0x2020) |
806c35f50 [PATCH] EDAC: dri... |
773 |
process_ded_retry(mci, error_one, info->dram_retr_add, |
052dfb45c drivers/edac: cle... |
774 |
error_found, handle_error); |
806c35f50 [PATCH] EDAC: dri... |
775 |
|
203333cbb drivers/edac: Lin... |
776 |
if (error_next & 0x2020) |
806c35f50 [PATCH] EDAC: dri... |
777 |
process_ded_retry(mci, error_next, info->dram_retr_add, |
052dfb45c drivers/edac: cle... |
778 |
error_found, handle_error); |
806c35f50 [PATCH] EDAC: dri... |
779 |
|
203333cbb drivers/edac: Lin... |
780 781 |
if (error_one & 0x0808) process_threshold_ce(mci, error_one, error_found, handle_error); |
806c35f50 [PATCH] EDAC: dri... |
782 |
|
203333cbb drivers/edac: Lin... |
783 |
if (error_next & 0x0808) |
806c35f50 [PATCH] EDAC: dri... |
784 |
process_threshold_ce(mci, error_next, error_found, |
052dfb45c drivers/edac: cle... |
785 |
handle_error); |
806c35f50 [PATCH] EDAC: dri... |
786 |
|
203333cbb drivers/edac: Lin... |
787 |
if (error_one & 0x0606) |
806c35f50 [PATCH] EDAC: dri... |
788 |
process_ue(mci, error_one, info->dram_ded_add, |
052dfb45c drivers/edac: cle... |
789 |
info->dram_scrb_add, error_found, handle_error); |
806c35f50 [PATCH] EDAC: dri... |
790 |
|
203333cbb drivers/edac: Lin... |
791 |
if (error_next & 0x0606) |
806c35f50 [PATCH] EDAC: dri... |
792 |
process_ue(mci, error_next, info->dram_ded_add, |
052dfb45c drivers/edac: cle... |
793 |
info->dram_scrb_add, error_found, handle_error); |
806c35f50 [PATCH] EDAC: dri... |
794 |
} |
203333cbb drivers/edac: Lin... |
795 796 |
static void e752x_get_error_info(struct mem_ctl_info *mci, struct e752x_error_info *info) |
806c35f50 [PATCH] EDAC: dri... |
797 798 799 800 801 |
{ struct pci_dev *dev; struct e752x_pvt *pvt; memset(info, 0, sizeof(*info)); |
203333cbb drivers/edac: Lin... |
802 |
pvt = (struct e752x_pvt *)mci->pvt_info; |
806c35f50 [PATCH] EDAC: dri... |
803 |
dev = pvt->dev_d0f1; |
806c35f50 [PATCH] EDAC: dri... |
804 805 806 |
pci_read_config_dword(dev, E752X_FERR_GLOBAL, &info->ferr_global); if (info->ferr_global) { |
5135b797c edac: new support... |
807 808 809 810 811 812 813 814 815 |
if (pvt->dev_info->err_dev == PCI_DEVICE_ID_INTEL_3100_1_ERR) { pci_read_config_dword(dev, I3100_NSI_FERR, &info->nsi_ferr); info->hi_ferr = 0; } else { pci_read_config_byte(dev, E752X_HI_FERR, &info->hi_ferr); info->nsi_ferr = 0; } |
806c35f50 [PATCH] EDAC: dri... |
816 |
pci_read_config_word(dev, E752X_SYSBUS_FERR, |
052dfb45c drivers/edac: cle... |
817 |
&info->sysbus_ferr); |
806c35f50 [PATCH] EDAC: dri... |
818 |
pci_read_config_byte(dev, E752X_BUF_FERR, &info->buf_ferr); |
203333cbb drivers/edac: Lin... |
819 |
pci_read_config_word(dev, E752X_DRAM_FERR, &info->dram_ferr); |
806c35f50 [PATCH] EDAC: dri... |
820 |
pci_read_config_dword(dev, E752X_DRAM_SEC1_ADD, |
052dfb45c drivers/edac: cle... |
821 |
&info->dram_sec1_add); |
806c35f50 [PATCH] EDAC: dri... |
822 |
pci_read_config_word(dev, E752X_DRAM_SEC1_SYNDROME, |
052dfb45c drivers/edac: cle... |
823 |
&info->dram_sec1_syndrome); |
806c35f50 [PATCH] EDAC: dri... |
824 |
pci_read_config_dword(dev, E752X_DRAM_DED_ADD, |
052dfb45c drivers/edac: cle... |
825 |
&info->dram_ded_add); |
806c35f50 [PATCH] EDAC: dri... |
826 |
pci_read_config_dword(dev, E752X_DRAM_SCRB_ADD, |
052dfb45c drivers/edac: cle... |
827 |
&info->dram_scrb_add); |
806c35f50 [PATCH] EDAC: dri... |
828 |
pci_read_config_dword(dev, E752X_DRAM_RETR_ADD, |
052dfb45c drivers/edac: cle... |
829 |
&info->dram_retr_add); |
806c35f50 [PATCH] EDAC: dri... |
830 |
|
5135b797c edac: new support... |
831 |
/* ignore the reserved bits just in case */ |
806c35f50 [PATCH] EDAC: dri... |
832 833 |
if (info->hi_ferr & 0x7f) pci_write_config_byte(dev, E752X_HI_FERR, |
052dfb45c drivers/edac: cle... |
834 |
info->hi_ferr); |
806c35f50 [PATCH] EDAC: dri... |
835 |
|
5135b797c edac: new support... |
836 837 838 |
if (info->nsi_ferr & NSI_ERR_MASK) pci_write_config_dword(dev, I3100_NSI_FERR, info->nsi_ferr); |
806c35f50 [PATCH] EDAC: dri... |
839 840 |
if (info->sysbus_ferr) pci_write_config_word(dev, E752X_SYSBUS_FERR, |
052dfb45c drivers/edac: cle... |
841 |
info->sysbus_ferr); |
806c35f50 [PATCH] EDAC: dri... |
842 843 844 |
if (info->buf_ferr & 0x0f) pci_write_config_byte(dev, E752X_BUF_FERR, |
052dfb45c drivers/edac: cle... |
845 |
info->buf_ferr); |
806c35f50 [PATCH] EDAC: dri... |
846 847 848 |
if (info->dram_ferr) pci_write_bits16(pvt->bridge_ck, E752X_DRAM_FERR, |
203333cbb drivers/edac: Lin... |
849 |
info->dram_ferr, info->dram_ferr); |
806c35f50 [PATCH] EDAC: dri... |
850 851 |
pci_write_config_dword(dev, E752X_FERR_GLOBAL, |
052dfb45c drivers/edac: cle... |
852 |
info->ferr_global); |
806c35f50 [PATCH] EDAC: dri... |
853 854 855 856 857 |
} pci_read_config_dword(dev, E752X_NERR_GLOBAL, &info->nerr_global); if (info->nerr_global) { |
5135b797c edac: new support... |
858 859 860 861 862 863 864 865 866 |
if (pvt->dev_info->err_dev == PCI_DEVICE_ID_INTEL_3100_1_ERR) { pci_read_config_dword(dev, I3100_NSI_NERR, &info->nsi_nerr); info->hi_nerr = 0; } else { pci_read_config_byte(dev, E752X_HI_NERR, &info->hi_nerr); info->nsi_nerr = 0; } |
806c35f50 [PATCH] EDAC: dri... |
867 |
pci_read_config_word(dev, E752X_SYSBUS_NERR, |
052dfb45c drivers/edac: cle... |
868 |
&info->sysbus_nerr); |
806c35f50 [PATCH] EDAC: dri... |
869 |
pci_read_config_byte(dev, E752X_BUF_NERR, &info->buf_nerr); |
203333cbb drivers/edac: Lin... |
870 |
pci_read_config_word(dev, E752X_DRAM_NERR, &info->dram_nerr); |
806c35f50 [PATCH] EDAC: dri... |
871 |
pci_read_config_dword(dev, E752X_DRAM_SEC2_ADD, |
052dfb45c drivers/edac: cle... |
872 |
&info->dram_sec2_add); |
806c35f50 [PATCH] EDAC: dri... |
873 |
pci_read_config_word(dev, E752X_DRAM_SEC2_SYNDROME, |
052dfb45c drivers/edac: cle... |
874 |
&info->dram_sec2_syndrome); |
806c35f50 [PATCH] EDAC: dri... |
875 876 877 |
if (info->hi_nerr & 0x7f) pci_write_config_byte(dev, E752X_HI_NERR, |
052dfb45c drivers/edac: cle... |
878 |
info->hi_nerr); |
806c35f50 [PATCH] EDAC: dri... |
879 |
|
5135b797c edac: new support... |
880 881 882 |
if (info->nsi_nerr & NSI_ERR_MASK) pci_write_config_dword(dev, I3100_NSI_NERR, info->nsi_nerr); |
806c35f50 [PATCH] EDAC: dri... |
883 884 |
if (info->sysbus_nerr) pci_write_config_word(dev, E752X_SYSBUS_NERR, |
052dfb45c drivers/edac: cle... |
885 |
info->sysbus_nerr); |
806c35f50 [PATCH] EDAC: dri... |
886 887 888 |
if (info->buf_nerr & 0x0f) pci_write_config_byte(dev, E752X_BUF_NERR, |
052dfb45c drivers/edac: cle... |
889 |
info->buf_nerr); |
806c35f50 [PATCH] EDAC: dri... |
890 891 892 |
if (info->dram_nerr) pci_write_bits16(pvt->bridge_ck, E752X_DRAM_NERR, |
203333cbb drivers/edac: Lin... |
893 |
info->dram_nerr, info->dram_nerr); |
806c35f50 [PATCH] EDAC: dri... |
894 895 |
pci_write_config_dword(dev, E752X_NERR_GLOBAL, |
052dfb45c drivers/edac: cle... |
896 |
info->nerr_global); |
806c35f50 [PATCH] EDAC: dri... |
897 898 |
} } |
203333cbb drivers/edac: Lin... |
899 |
static int e752x_process_error_info(struct mem_ctl_info *mci, |
052dfb45c drivers/edac: cle... |
900 901 |
struct e752x_error_info *info, int handle_errors) |
806c35f50 [PATCH] EDAC: dri... |
902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 |
{ u32 error32, stat32; int error_found; error_found = 0; error32 = (info->ferr_global >> 18) & 0x3ff; stat32 = (info->ferr_global >> 4) & 0x7ff; if (error32) global_error(1, error32, &error_found, handle_errors); if (stat32) global_error(0, stat32, &error_found, handle_errors); error32 = (info->nerr_global >> 18) & 0x3ff; stat32 = (info->nerr_global >> 4) & 0x7ff; if (error32) global_error(1, error32, &error_found, handle_errors); if (stat32) global_error(0, stat32, &error_found, handle_errors); e752x_check_hub_interface(info, &error_found, handle_errors); |
5135b797c edac: new support... |
926 |
e752x_check_ns_interface(info, &error_found, handle_errors); |
806c35f50 [PATCH] EDAC: dri... |
927 928 929 930 931 932 933 934 935 |
e752x_check_sysbus(info, &error_found, handle_errors); e752x_check_membuf(info, &error_found, handle_errors); e752x_check_dram(mci, info, &error_found, handle_errors); return error_found; } static void e752x_check(struct mem_ctl_info *mci) { struct e752x_error_info info; |
e7ecd8910 [PATCH] EDAC: for... |
936 |
|
537fba289 [PATCH] EDAC: pri... |
937 938 |
debugf3("%s() ", __func__); |
806c35f50 [PATCH] EDAC: dri... |
939 940 941 |
e752x_get_error_info(mci, &info); e752x_process_error_info(mci, &info, 1); } |
8004fd2ad edac: e752x: add ... |
942 |
/* Program byte/sec bandwidth scrub rate to hardware */ |
eba042a81 edac, mc: Improve... |
943 |
static int set_sdram_scrub_rate(struct mem_ctl_info *mci, u32 new_bw) |
8004fd2ad edac: e752x: add ... |
944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 |
{ const struct scrubrate *scrubrates; struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info; struct pci_dev *pdev = pvt->dev_d0f0; int i; if (pvt->dev_info->ctl_dev == PCI_DEVICE_ID_INTEL_3100_0) scrubrates = scrubrates_i3100; else scrubrates = scrubrates_e752x; /* Translate the desired scrub rate to a e752x/3100 register value. * Search for the bandwidth that is equal or greater than the * desired rate and program the cooresponding register value. */ for (i = 0; scrubrates[i].bandwidth != SDRATE_EOT; i++) |
eba042a81 edac, mc: Improve... |
960 |
if (scrubrates[i].bandwidth >= new_bw) |
8004fd2ad edac: e752x: add ... |
961 962 963 964 965 966 |
break; if (scrubrates[i].bandwidth == SDRATE_EOT) return -1; pci_write_config_word(pdev, E752X_MCHSCRB, scrubrates[i].scrubval); |
390944439 EDAC: Fixup scrub... |
967 |
return scrubrates[i].bandwidth; |
8004fd2ad edac: e752x: add ... |
968 969 970 |
} /* Convert current scrub rate value into byte/sec bandwidth */ |
390944439 EDAC: Fixup scrub... |
971 |
static int get_sdram_scrub_rate(struct mem_ctl_info *mci) |
8004fd2ad edac: e752x: add ... |
972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 |
{ const struct scrubrate *scrubrates; struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info; struct pci_dev *pdev = pvt->dev_d0f0; u16 scrubval; int i; if (pvt->dev_info->ctl_dev == PCI_DEVICE_ID_INTEL_3100_0) scrubrates = scrubrates_i3100; else scrubrates = scrubrates_e752x; /* Find the bandwidth matching the memory scrubber configuration */ pci_read_config_word(pdev, E752X_MCHSCRB, &scrubval); scrubval = scrubval & 0x0f; for (i = 0; scrubrates[i].bandwidth != SDRATE_EOT; i++) if (scrubrates[i].scrubval == scrubval) break; if (scrubrates[i].bandwidth == SDRATE_EOT) { e752x_printk(KERN_WARNING, "Invalid sdram scrub control value: 0x%x ", scrubval); return -1; } |
390944439 EDAC: Fixup scrub... |
998 |
return scrubrates[i].bandwidth; |
8004fd2ad edac: e752x: add ... |
999 |
|
8004fd2ad edac: e752x: add ... |
1000 |
} |
131895251 [PATCH] EDAC: pro... |
1001 1002 1003 1004 1005 |
/* Return 1 if dual channel mode is active. Else return 0. */ static inline int dual_channel_active(u16 ddrcsr) { return (((ddrcsr >> 12) & 3) == 3); } |
7297c2617 drivers/edac: fix... |
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 |
/* Remap csrow index numbers if map_type is "reverse" */ static inline int remap_csrow_index(struct mem_ctl_info *mci, int index) { struct e752x_pvt *pvt = mci->pvt_info; if (!pvt->map_type) return (7 - index); return (index); } |
131895251 [PATCH] EDAC: pro... |
1017 |
static void e752x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev, |
052dfb45c drivers/edac: cle... |
1018 |
u16 ddrcsr) |
131895251 [PATCH] EDAC: pro... |
1019 1020 1021 1022 |
{ struct csrow_info *csrow; unsigned long last_cumul_size; int index, mem_dev, drc_chan; |
203333cbb drivers/edac: Lin... |
1023 1024 |
int drc_drbg; /* DRB granularity 0=64mb, 1=128mb */ int drc_ddim; /* DRAM Data Integrity Mode 0=none, 2=edac */ |
131895251 [PATCH] EDAC: pro... |
1025 1026 |
u8 value; u32 dra, drc, cumul_size; |
9962fd017 [PATCH] EDAC: e75... |
1027 |
dra = 0; |
203333cbb drivers/edac: Lin... |
1028 |
for (index = 0; index < 4; index++) { |
9962fd017 [PATCH] EDAC: e75... |
1029 |
u8 dra_reg; |
203333cbb drivers/edac: Lin... |
1030 |
pci_read_config_byte(pdev, E752X_DRA + index, &dra_reg); |
9962fd017 [PATCH] EDAC: e75... |
1031 1032 |
dra |= dra_reg << (index * 8); } |
131895251 [PATCH] EDAC: pro... |
1033 1034 |
pci_read_config_dword(pdev, E752X_DRC, &drc); drc_chan = dual_channel_active(ddrcsr); |
203333cbb drivers/edac: Lin... |
1035 |
drc_drbg = drc_chan + 1; /* 128 in dual mode, 64 in single */ |
131895251 [PATCH] EDAC: pro... |
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 |
drc_ddim = (drc >> 20) & 0x3; /* The dram row boundary (DRB) reg values are boundary address for * each DRAM row with a granularity of 64 or 128MB (single/dual * channel operation). DRB regs are cumulative; therefore DRB7 will * contain the total memory contained in all eight rows. */ for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) { /* mem_dev 0=x8, 1=x4 */ mem_dev = (dra >> (index * 4 + 2)) & 0x3; |
7297c2617 drivers/edac: fix... |
1046 |
csrow = &mci->csrows[remap_csrow_index(mci, index)]; |
131895251 [PATCH] EDAC: pro... |
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 |
mem_dev = (mem_dev == 2); pci_read_config_byte(pdev, E752X_DRB + index, &value); /* convert a 128 or 64 MiB DRB to a page size. */ cumul_size = value << (25 + drc_drbg - PAGE_SHIFT); debugf3("%s(): (%d) cumul_size 0x%x ", __func__, index, cumul_size); if (cumul_size == last_cumul_size) continue; /* not populated */ csrow->first_page = last_cumul_size; csrow->last_page = cumul_size - 1; csrow->nr_pages = cumul_size - last_cumul_size; last_cumul_size = cumul_size; csrow->grain = 1 << 12; /* 4KiB - resolution of CELOG */ csrow->mtype = MEM_RDDR; /* only one type supported */ csrow->dtype = mem_dev ? DEV_X4 : DEV_X8; /* * if single channel or x8 devices then SECDED * if dual channel and x4 then S4ECD4ED */ if (drc_ddim) { if (drc_chan && mem_dev) { csrow->edac_mode = EDAC_S4ECD4ED; mci->edac_cap |= EDAC_FLAG_S4ECD4ED; } else { csrow->edac_mode = EDAC_SECDED; mci->edac_cap |= EDAC_FLAG_SECDED; } } else csrow->edac_mode = EDAC_NONE; } } static void e752x_init_mem_map_table(struct pci_dev *pdev, |
052dfb45c drivers/edac: cle... |
1084 |
struct e752x_pvt *pvt) |
806c35f50 [PATCH] EDAC: dri... |
1085 |
{ |
806c35f50 [PATCH] EDAC: dri... |
1086 |
int index; |
7297c2617 drivers/edac: fix... |
1087 |
u8 value, last, row; |
131895251 [PATCH] EDAC: pro... |
1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 |
last = 0; row = 0; for (index = 0; index < 8; index += 2) { pci_read_config_byte(pdev, E752X_DRB + index, &value); /* test if there is a dimm in this slot */ if (value == last) { /* no dimm in the slot, so flag it as empty */ pvt->map[index] = 0xff; pvt->map[index + 1] = 0xff; |
203333cbb drivers/edac: Lin... |
1099 |
} else { /* there is a dimm in the slot */ |
131895251 [PATCH] EDAC: pro... |
1100 1101 1102 1103 1104 1105 1106 |
pvt->map[index] = row; row++; last = value; /* test the next value to see if the dimm is double * sided */ pci_read_config_byte(pdev, E752X_DRB + index + 1, |
052dfb45c drivers/edac: cle... |
1107 1108 1109 1110 1111 |
&value); /* the dimm is single sided, so flag as empty */ /* this is a double sided dimm to save the next row #*/ pvt->map[index + 1] = (value == last) ? 0xff : row; |
131895251 [PATCH] EDAC: pro... |
1112 1113 1114 1115 |
row++; last = value; } } |
131895251 [PATCH] EDAC: pro... |
1116 1117 1118 1119 |
} /* Return 0 on success or 1 on failure. */ static int e752x_get_devs(struct pci_dev *pdev, int dev_idx, |
052dfb45c drivers/edac: cle... |
1120 |
struct e752x_pvt *pvt) |
131895251 [PATCH] EDAC: pro... |
1121 1122 1123 1124 |
{ struct pci_dev *dev; pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL, |
10d33e9c3 edac: e752x fix t... |
1125 |
pvt->dev_info->err_dev, pvt->bridge_ck); |
131895251 [PATCH] EDAC: pro... |
1126 1127 1128 1129 1130 1131 1132 |
if (pvt->bridge_ck == NULL) pvt->bridge_ck = pci_scan_single_device(pdev->bus, PCI_DEVFN(0, 1)); if (pvt->bridge_ck == NULL) { e752x_printk(KERN_ERR, "error reporting device not found:" |
052dfb45c drivers/edac: cle... |
1133 1134 1135 |
"vendor %x device 0x%x (broken BIOS?) ", PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].err_dev); |
131895251 [PATCH] EDAC: pro... |
1136 1137 |
return 1; } |
10d33e9c3 edac: e752x fix t... |
1138 1139 1140 |
dev = pci_get_device(PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].ctl_dev, NULL); |
131895251 [PATCH] EDAC: pro... |
1141 1142 1143 1144 1145 1146 1147 1148 |
if (dev == NULL) goto fail; pvt->dev_d0f0 = dev; pvt->dev_d0f1 = pci_dev_get(pvt->bridge_ck); return 0; |
052dfb45c drivers/edac: cle... |
1149 |
fail: |
131895251 [PATCH] EDAC: pro... |
1150 1151 1152 |
pci_dev_put(pvt->bridge_ck); return 1; } |
94ee1cf5a edac: add e752x p... |
1153 1154 |
/* Setup system bus parity mask register. * Sysbus parity supported on: |
8de5c1a16 edac: e752x fsb ecc |
1155 |
* e7320/e7520/e7525 + Xeon |
94ee1cf5a edac: add e752x p... |
1156 1157 1158 1159 1160 1161 |
*/ static void e752x_init_sysbus_parity_mask(struct e752x_pvt *pvt) { char *cpu_id = cpu_data(0).x86_model_id; struct pci_dev *dev = pvt->dev_d0f1; int enable = 1; |
98a1708de trivial: fix typo... |
1162 |
/* Allow module parameter override, else see if CPU supports parity */ |
94ee1cf5a edac: add e752x p... |
1163 1164 |
if (sysbus_parity != -1) { enable = sysbus_parity; |
8de5c1a16 edac: e752x fsb ecc |
1165 |
} else if (cpu_id[0] && !strstr(cpu_id, "Xeon")) { |
94ee1cf5a edac: add e752x p... |
1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 |
e752x_printk(KERN_INFO, "System Bus Parity not " "supported by CPU, disabling "); enable = 0; } if (enable) pci_write_config_word(dev, E752X_SYSBUS_ERRMASK, 0x0000); else pci_write_config_word(dev, E752X_SYSBUS_ERRMASK, 0x0309); } |
131895251 [PATCH] EDAC: pro... |
1177 1178 1179 1180 1181 1182 |
static void e752x_init_error_reporting_regs(struct e752x_pvt *pvt) { struct pci_dev *dev; dev = pvt->dev_d0f1; /* Turn off error disable & SMI in case the BIOS turned it on */ |
5135b797c edac: new support... |
1183 1184 1185 1186 1187 1188 1189 |
if (pvt->dev_info->err_dev == PCI_DEVICE_ID_INTEL_3100_1_ERR) { pci_write_config_dword(dev, I3100_NSI_EMASK, 0); pci_write_config_dword(dev, I3100_NSI_SMICMD, 0); } else { pci_write_config_byte(dev, E752X_HI_ERRMASK, 0x00); pci_write_config_byte(dev, E752X_HI_SMICMD, 0x00); } |
94ee1cf5a edac: add e752x p... |
1190 1191 |
e752x_init_sysbus_parity_mask(pvt); |
131895251 [PATCH] EDAC: pro... |
1192 1193 1194 1195 1196 1197 1198 1199 1200 |
pci_write_config_word(dev, E752X_SYSBUS_SMICMD, 0x00); pci_write_config_byte(dev, E752X_BUF_ERRMASK, 0x00); pci_write_config_byte(dev, E752X_BUF_SMICMD, 0x00); pci_write_config_byte(dev, E752X_DRAM_ERRMASK, 0x00); pci_write_config_byte(dev, E752X_DRAM_SMICMD, 0x00); } static int e752x_probe1(struct pci_dev *pdev, int dev_idx) { |
3847bccce [PATCH] EDAC: e75... |
1201 |
u16 pci_data; |
806c35f50 [PATCH] EDAC: dri... |
1202 |
u8 stat8; |
131895251 [PATCH] EDAC: pro... |
1203 1204 |
struct mem_ctl_info *mci; struct e752x_pvt *pvt; |
806c35f50 [PATCH] EDAC: dri... |
1205 |
u16 ddrcsr; |
203333cbb drivers/edac: Lin... |
1206 |
int drc_chan; /* Number of channels 0=1chan,1=2chan */ |
749ede574 [PATCH] EDAC: cle... |
1207 |
struct e752x_error_info discard; |
806c35f50 [PATCH] EDAC: dri... |
1208 |
|
537fba289 [PATCH] EDAC: pri... |
1209 1210 |
debugf0("%s(): mci ", __func__); |
806c35f50 [PATCH] EDAC: dri... |
1211 1212 |
debugf0("Starting Probe1 "); |
96941026a [PATCH] EDAC Coex... |
1213 1214 1215 1216 |
/* check to see if device 0 function 1 is enabled; if it isn't, we * assume the BIOS has reserved it for a reason and is expecting * exclusive access, we take care not to violate that assumption and * fail the probe. */ |
806c35f50 [PATCH] EDAC: dri... |
1217 |
pci_read_config_byte(pdev, E752X_DEVPRES1, &stat8); |
96941026a [PATCH] EDAC Coex... |
1218 1219 |
if (!force_function_unhide && !(stat8 & (1 << 5))) { printk(KERN_INFO "Contact your BIOS vendor to see if the " |
052dfb45c drivers/edac: cle... |
1220 1221 |
"E752x error registers can be safely un-hidden "); |
f9b5a5d19 drivers/edac: fix... |
1222 |
return -ENODEV; |
96941026a [PATCH] EDAC Coex... |
1223 |
} |
806c35f50 [PATCH] EDAC: dri... |
1224 1225 |
stat8 |= (1 << 5); pci_write_config_byte(pdev, E752X_DEVPRES1, stat8); |
806c35f50 [PATCH] EDAC: dri... |
1226 1227 1228 |
pci_read_config_word(pdev, E752X_DDRCSR, &ddrcsr); /* FIXME: should check >>12 or 0xf, true for all? */ /* Dual channel = 1, Single channel = 0 */ |
131895251 [PATCH] EDAC: pro... |
1229 |
drc_chan = dual_channel_active(ddrcsr); |
806c35f50 [PATCH] EDAC: dri... |
1230 |
|
b8f6f9755 drivers/edac: fix... |
1231 |
mci = edac_mc_alloc(sizeof(*pvt), E752X_NR_CSROWS, drc_chan + 1, 0); |
806c35f50 [PATCH] EDAC: dri... |
1232 1233 |
if (mci == NULL) { |
131895251 [PATCH] EDAC: pro... |
1234 |
return -ENOMEM; |
806c35f50 [PATCH] EDAC: dri... |
1235 |
} |
537fba289 [PATCH] EDAC: pri... |
1236 1237 |
debugf3("%s(): init mci ", __func__); |
806c35f50 [PATCH] EDAC: dri... |
1238 |
mci->mtype_cap = MEM_FLAG_RDDR; |
5135b797c edac: new support... |
1239 1240 1241 |
/* 3100 IMCH supports SECDEC only */ mci->edac_ctl_cap = (dev_idx == I3100) ? EDAC_FLAG_SECDED : (EDAC_FLAG_NONE | EDAC_FLAG_SECDED | EDAC_FLAG_S4ECD4ED); |
806c35f50 [PATCH] EDAC: dri... |
1242 |
/* FIXME - what if different memory types are in different csrows? */ |
680cbbbb0 [PATCH] EDAC: nam... |
1243 |
mci->mod_name = EDAC_MOD_STR; |
37f04581a [PATCH] EDAC: PCI... |
1244 1245 |
mci->mod_ver = E752X_REVISION; mci->dev = &pdev->dev; |
806c35f50 [PATCH] EDAC: dri... |
1246 |
|
537fba289 [PATCH] EDAC: pri... |
1247 1248 |
debugf3("%s(): init pvt ", __func__); |
203333cbb drivers/edac: Lin... |
1249 |
pvt = (struct e752x_pvt *)mci->pvt_info; |
806c35f50 [PATCH] EDAC: dri... |
1250 |
pvt->dev_info = &e752x_devs[dev_idx]; |
131895251 [PATCH] EDAC: pro... |
1251 |
pvt->mc_symmetric = ((ddrcsr & 0x10) != 0); |
e7ecd8910 [PATCH] EDAC: for... |
1252 |
|
131895251 [PATCH] EDAC: pro... |
1253 1254 1255 |
if (e752x_get_devs(pdev, dev_idx, pvt)) { edac_mc_free(mci); return -ENODEV; |
806c35f50 [PATCH] EDAC: dri... |
1256 |
} |
806c35f50 [PATCH] EDAC: dri... |
1257 |
|
537fba289 [PATCH] EDAC: pri... |
1258 1259 |
debugf3("%s(): more mci init ", __func__); |
806c35f50 [PATCH] EDAC: dri... |
1260 |
mci->ctl_name = pvt->dev_info->ctl_name; |
c4192705f drivers/edac: add... |
1261 |
mci->dev_name = pci_name(pdev); |
806c35f50 [PATCH] EDAC: dri... |
1262 1263 |
mci->edac_check = e752x_check; mci->ctl_page_to_phys = ctl_page_to_phys; |
8004fd2ad edac: e752x: add ... |
1264 1265 |
mci->set_sdram_scrub_rate = set_sdram_scrub_rate; mci->get_sdram_scrub_rate = get_sdram_scrub_rate; |
806c35f50 [PATCH] EDAC: dri... |
1266 |
|
7297c2617 drivers/edac: fix... |
1267 1268 1269 1270 |
/* set the map type. 1 = normal, 0 = reversed * Must be set before e752x_init_csrows in case csrow mapping * is reversed. */ |
37f04581a [PATCH] EDAC: PCI... |
1271 |
pci_read_config_byte(pdev, E752X_DRM, &stat8); |
806c35f50 [PATCH] EDAC: dri... |
1272 |
pvt->map_type = ((stat8 & 0x0f) > ((stat8 >> 4) & 0x0f)); |
7297c2617 drivers/edac: fix... |
1273 1274 |
e752x_init_csrows(mci, pdev, ddrcsr); e752x_init_mem_map_table(pdev, pvt); |
5135b797c edac: new support... |
1275 1276 1277 1278 |
if (dev_idx == I3100) mci->edac_cap = EDAC_FLAG_SECDED; /* the only mode supported */ else mci->edac_cap |= EDAC_FLAG_NONE; |
537fba289 [PATCH] EDAC: pri... |
1279 1280 |
debugf3("%s(): tolm, remapbase, remaplimit ", __func__); |
e7ecd8910 [PATCH] EDAC: for... |
1281 |
|
806c35f50 [PATCH] EDAC: dri... |
1282 |
/* load the top of low memory, remap base, and remap limit vars */ |
37f04581a [PATCH] EDAC: PCI... |
1283 |
pci_read_config_word(pdev, E752X_TOLM, &pci_data); |
806c35f50 [PATCH] EDAC: dri... |
1284 |
pvt->tolm = ((u32) pci_data) << 4; |
37f04581a [PATCH] EDAC: PCI... |
1285 |
pci_read_config_word(pdev, E752X_REMAPBASE, &pci_data); |
806c35f50 [PATCH] EDAC: dri... |
1286 |
pvt->remapbase = ((u32) pci_data) << 14; |
37f04581a [PATCH] EDAC: PCI... |
1287 |
pci_read_config_word(pdev, E752X_REMAPLIMIT, &pci_data); |
806c35f50 [PATCH] EDAC: dri... |
1288 |
pvt->remaplimit = ((u32) pci_data) << 14; |
537fba289 [PATCH] EDAC: pri... |
1289 |
e752x_printk(KERN_INFO, |
052dfb45c drivers/edac: cle... |
1290 1291 1292 |
"tolm = %x, remapbase = %x, remaplimit = %x ", pvt->tolm, pvt->remapbase, pvt->remaplimit); |
806c35f50 [PATCH] EDAC: dri... |
1293 |
|
2d7bbb91c [PATCH] EDAC: mc ... |
1294 1295 1296 |
/* Here we assume that we will never see multiple instances of this * type of memory controller. The ID is therefore hardcoded to 0. */ |
b8f6f9755 drivers/edac: fix... |
1297 |
if (edac_mc_add_mc(mci)) { |
537fba289 [PATCH] EDAC: pri... |
1298 1299 |
debugf3("%s(): failed edac_mc_add_mc() ", __func__); |
806c35f50 [PATCH] EDAC: dri... |
1300 1301 |
goto fail; } |
131895251 [PATCH] EDAC: pro... |
1302 |
e752x_init_error_reporting_regs(pvt); |
203333cbb drivers/edac: Lin... |
1303 |
e752x_get_error_info(mci, &discard); /* clear other MCH errors */ |
806c35f50 [PATCH] EDAC: dri... |
1304 |
|
91b99041c drivers/edac: upd... |
1305 1306 1307 1308 |
/* allocating generic PCI control info */ e752x_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR); if (!e752x_pci) { printk(KERN_WARNING |
052dfb45c drivers/edac: cle... |
1309 1310 |
"%s(): Unable to create PCI control ", __func__); |
91b99041c drivers/edac: upd... |
1311 |
printk(KERN_WARNING |
052dfb45c drivers/edac: cle... |
1312 1313 1314 |
"%s(): PCI error report via EDAC not setup ", __func__); |
91b99041c drivers/edac: upd... |
1315 |
} |
806c35f50 [PATCH] EDAC: dri... |
1316 |
/* get this far and it's successful */ |
537fba289 [PATCH] EDAC: pri... |
1317 1318 |
debugf3("%s(): success ", __func__); |
806c35f50 [PATCH] EDAC: dri... |
1319 |
return 0; |
052dfb45c drivers/edac: cle... |
1320 |
fail: |
131895251 [PATCH] EDAC: pro... |
1321 1322 1323 1324 |
pci_dev_put(pvt->dev_d0f0); pci_dev_put(pvt->dev_d0f1); pci_dev_put(pvt->bridge_ck); edac_mc_free(mci); |
e7ecd8910 [PATCH] EDAC: for... |
1325 |
|
131895251 [PATCH] EDAC: pro... |
1326 |
return -ENODEV; |
806c35f50 [PATCH] EDAC: dri... |
1327 1328 1329 1330 |
} /* returns count (>= 0), or negative on error */ static int __devinit e752x_init_one(struct pci_dev *pdev, |
052dfb45c drivers/edac: cle... |
1331 |
const struct pci_device_id *ent) |
806c35f50 [PATCH] EDAC: dri... |
1332 |
{ |
537fba289 [PATCH] EDAC: pri... |
1333 1334 |
debugf0("%s() ", __func__); |
806c35f50 [PATCH] EDAC: dri... |
1335 1336 |
/* wake up and enable device */ |
203333cbb drivers/edac: Lin... |
1337 |
if (pci_enable_device(pdev) < 0) |
806c35f50 [PATCH] EDAC: dri... |
1338 |
return -EIO; |
e7ecd8910 [PATCH] EDAC: for... |
1339 |
|
806c35f50 [PATCH] EDAC: dri... |
1340 1341 |
return e752x_probe1(pdev, ent->driver_data); } |
806c35f50 [PATCH] EDAC: dri... |
1342 1343 1344 1345 |
static void __devexit e752x_remove_one(struct pci_dev *pdev) { struct mem_ctl_info *mci; struct e752x_pvt *pvt; |
537fba289 [PATCH] EDAC: pri... |
1346 1347 |
debugf0("%s() ", __func__); |
806c35f50 [PATCH] EDAC: dri... |
1348 |
|
91b99041c drivers/edac: upd... |
1349 1350 |
if (e752x_pci) edac_pci_release_generic_ctl(e752x_pci); |
37f04581a [PATCH] EDAC: PCI... |
1351 |
if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL) |
806c35f50 [PATCH] EDAC: dri... |
1352 |
return; |
203333cbb drivers/edac: Lin... |
1353 |
pvt = (struct e752x_pvt *)mci->pvt_info; |
806c35f50 [PATCH] EDAC: dri... |
1354 1355 1356 1357 1358 |
pci_dev_put(pvt->dev_d0f0); pci_dev_put(pvt->dev_d0f1); pci_dev_put(pvt->bridge_ck); edac_mc_free(mci); } |
806c35f50 [PATCH] EDAC: dri... |
1359 |
static const struct pci_device_id e752x_pci_tbl[] __devinitdata = { |
e7ecd8910 [PATCH] EDAC: for... |
1360 |
{ |
203333cbb drivers/edac: Lin... |
1361 1362 |
PCI_VEND_DEV(INTEL, 7520_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, E7520}, |
e7ecd8910 [PATCH] EDAC: for... |
1363 |
{ |
203333cbb drivers/edac: Lin... |
1364 1365 |
PCI_VEND_DEV(INTEL, 7525_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, E7525}, |
e7ecd8910 [PATCH] EDAC: for... |
1366 |
{ |
203333cbb drivers/edac: Lin... |
1367 1368 |
PCI_VEND_DEV(INTEL, 7320_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, E7320}, |
e7ecd8910 [PATCH] EDAC: for... |
1369 |
{ |
5135b797c edac: new support... |
1370 1371 1372 |
PCI_VEND_DEV(INTEL, 3100_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, I3100}, { |
203333cbb drivers/edac: Lin... |
1373 1374 |
0, } /* 0 terminated list. */ |
806c35f50 [PATCH] EDAC: dri... |
1375 1376 1377 |
}; MODULE_DEVICE_TABLE(pci, e752x_pci_tbl); |
806c35f50 [PATCH] EDAC: dri... |
1378 |
static struct pci_driver e752x_driver = { |
680cbbbb0 [PATCH] EDAC: nam... |
1379 |
.name = EDAC_MOD_STR, |
0d38b049f [PATCH] edac: use... |
1380 1381 1382 |
.probe = e752x_init_one, .remove = __devexit_p(e752x_remove_one), .id_table = e752x_pci_tbl, |
806c35f50 [PATCH] EDAC: dri... |
1383 |
}; |
da9bb1d27 [PATCH] EDAC: cor... |
1384 |
static int __init e752x_init(void) |
806c35f50 [PATCH] EDAC: dri... |
1385 1386 |
{ int pci_rc; |
537fba289 [PATCH] EDAC: pri... |
1387 1388 |
debugf3("%s() ", __func__); |
c3c52bce6 edac: fix module ... |
1389 1390 1391 |
/* Ensure that the OPSTATE is set correctly for POLL or NMI */ opstate_init(); |
806c35f50 [PATCH] EDAC: dri... |
1392 1393 1394 |
pci_rc = pci_register_driver(&e752x_driver); return (pci_rc < 0) ? pci_rc : 0; } |
806c35f50 [PATCH] EDAC: dri... |
1395 1396 |
static void __exit e752x_exit(void) { |
537fba289 [PATCH] EDAC: pri... |
1397 1398 |
debugf3("%s() ", __func__); |
806c35f50 [PATCH] EDAC: dri... |
1399 1400 |
pci_unregister_driver(&e752x_driver); } |
806c35f50 [PATCH] EDAC: dri... |
1401 1402 1403 1404 1405 1406 |
module_init(e752x_init); module_exit(e752x_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Linux Networx (http://lnxi.com) Tom Zimmerman "); |
5135b797c edac: new support... |
1407 |
MODULE_DESCRIPTION("MC support for Intel e752x/3100 memory controllers"); |
96941026a [PATCH] EDAC Coex... |
1408 1409 1410 |
module_param(force_function_unhide, int, 0444); MODULE_PARM_DESC(force_function_unhide, "if BIOS sets Dev0:Fun1 up as hidden:" |
10d33e9c3 edac: e752x fix t... |
1411 1412 |
" 1=force unhide and hope BIOS doesn't fight driver for " "Dev0:Fun1 access"); |
c3c52bce6 edac: fix module ... |
1413 |
|
c0d121720 drivers/edac: add... |
1414 1415 |
module_param(edac_op_state, int, 0444); MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI"); |
94ee1cf5a edac: add e752x p... |
1416 1417 1418 1419 |
module_param(sysbus_parity, int, 0444); MODULE_PARM_DESC(sysbus_parity, "0=disable system bus parity checking," " 1=enable system bus parity checking, default=auto-detect"); |
10d33e9c3 edac: e752x fix t... |
1420 1421 1422 |
module_param(report_non_memory_errors, int, 0644); MODULE_PARM_DESC(report_non_memory_errors, "0=disable non-memory error " "reporting, 1=enable non-memory error reporting"); |