aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/i7300_edac.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2010-08-27 09:22:36 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-08-30 13:56:54 -0400
commit57021918aa9c310524d7e9754506e4e8272b4c0e (patch)
treeafa0b4aac5a27ea1c7f9f5b26050ed34d18df487 /drivers/edac/i7300_edac.c
parent15154c57c62494292f43df9133a7b370cbbf1ecb (diff)
i7300_edac: Add support for reporting FBD errors
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac/i7300_edac.c')
-rw-r--r--drivers/edac/i7300_edac.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c
index b5152256967..728f9b0ab62 100644
--- a/drivers/edac/i7300_edac.c
+++ b/drivers/edac/i7300_edac.c
@@ -161,6 +161,63 @@ static const char *numcol_toString[] = {
161/************************************************ 161/************************************************
162 * i7300 Register definitions for error detection 162 * i7300 Register definitions for error detection
163 ************************************************/ 163 ************************************************/
164
165/*
166 * Device 16.1: FBD Error Registers
167 */
168#define FERR_FAT_FBD 0x98
169static const char *ferr_fat_fbd_name[] = {
170 [22] = "Non-Redundant Fast Reset Timeout",
171 [2] = ">Tmid Thermal event with intelligent throttling disabled",
172 [1] = "Memory or FBD configuration CRC read error",
173 [0] = "Memory Write error on non-redundant retry or "
174 "FBD configuration Write error on retry",
175};
176#define GET_FBD_FAT_IDX(fbderr) (fbderr & (3 << 28))
177#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3))
178
179#define FERR_NF_FBD 0xa0
180static const char *ferr_nf_fbd_name[] = {
181 [24] = "DIMM-Spare Copy Completed",
182 [23] = "DIMM-Spare Copy Initiated",
183 [22] = "Redundant Fast Reset Timeout",
184 [21] = "Memory Write error on redundant retry",
185 [18] = "SPD protocol Error",
186 [17] = "FBD Northbound parity error on FBD Sync Status",
187 [16] = "Correctable Patrol Data ECC",
188 [15] = "Correctable Resilver- or Spare-Copy Data ECC",
189 [14] = "Correctable Mirrored Demand Data ECC",
190 [13] = "Correctable Non-Mirrored Demand Data ECC",
191 [11] = "Memory or FBD configuration CRC read error",
192 [10] = "FBD Configuration Write error on first attempt",
193 [9] = "Memory Write error on first attempt",
194 [8] = "Non-Aliased Uncorrectable Patrol Data ECC",
195 [7] = "Non-Aliased Uncorrectable Resilver- or Spare-Copy Data ECC",
196 [6] = "Non-Aliased Uncorrectable Mirrored Demand Data ECC",
197 [5] = "Non-Aliased Uncorrectable Non-Mirrored Demand Data ECC",
198 [4] = "Aliased Uncorrectable Patrol Data ECC",
199 [3] = "Aliased Uncorrectable Resilver- or Spare-Copy Data ECC",
200 [2] = "Aliased Uncorrectable Mirrored Demand Data ECC",
201 [1] = "Aliased Uncorrectable Non-Mirrored Demand Data ECC",
202 [0] = "Uncorrectable Data ECC on Replay",
203};
204#define GET_FBD_NF_IDX(fbderr) (fbderr & (3 << 28))
205#define FERR_NF_FBD_ERR_MASK ((1 << 24) | (1 << 23) | (1 << 22) | (1 << 21) |\
206 (1 << 18) | (1 << 17) | (1 << 16) | (1 << 15) |\
207 (1 << 14) | (1 << 13) | (1 << 11) | (1 << 10) |\
208 (1 << 9) | (1 << 8) | (1 << 7) | (1 << 6) |\
209 (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) |\
210 (1 << 1) | (1 << 0))
211
212#define EMASK_FBD 0xa8
213#define EMASK_FBD_ERR_MASK ((1 << 27) | (1 << 26) | (1 << 25) | (1 << 24) |\
214 (1 << 22) | (1 << 21) | (1 << 20) | (1 << 19) |\
215 (1 << 18) | (1 << 17) | (1 << 16) | (1 << 14) |\
216 (1 << 13) | (1 << 12) | (1 << 11) | (1 << 10) |\
217 (1 << 9) | (1 << 8) | (1 << 7) | (1 << 6) |\
218 (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) |\
219 (1 << 1) | (1 << 0))
220
164/* 221/*
165 * Device 16.2: Global Error Registers 222 * Device 16.2: Global Error Registers
166 */ 223 */
@@ -339,6 +396,61 @@ error_global:
339} 396}
340 397
341/* 398/*
399 * i7300_process_fbd_error Retrieve the hardware error information from
400 * the hardware and cache it in the 'info'
401 * structure
402 */
403static void i7300_process_fbd_error(struct mem_ctl_info *mci,
404 struct i7300_error_info *info)
405{
406 struct i7300_pvt *pvt;
407 u32 errnum, value;
408 int branch;
409 unsigned long errors;
410 const char *specific;
411 bool is_fatal;
412
413 pvt = mci->pvt_info;
414
415 /* read in the 1st FATAL error register */
416 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
417 FERR_FAT_FBD, &value);
418 if (unlikely(value & FERR_FAT_FBD_ERR_MASK)) {
419 errors = value & FERR_FAT_FBD_ERR_MASK ;
420 errnum = find_first_bit(&errors,
421 ARRAY_SIZE(ferr_fat_fbd_name));
422 specific = GET_ERR_FROM_TABLE(ferr_fat_fbd_name, errnum);
423 is_fatal = 1;
424
425 branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0;
426
427 goto error_fbd;
428 }
429
430 /* read in the 1st NON-FATAL error register */
431 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
432 FERR_NF_FBD, &value);
433 if (unlikely(value & FERR_NF_FBD_ERR_MASK)) {
434 errors = value & FERR_NF_FBD_ERR_MASK;
435 errnum = find_first_bit(&errors,
436 ARRAY_SIZE(ferr_nf_fbd_name));
437 specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum);
438 is_fatal = 0;
439
440 /* Clear the error bit */
441 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
442 FERR_GLOBAL_LO, value);
443
444 goto error_fbd;
445 }
446 return;
447
448error_fbd:
449 i7300_mc_printk(mci, KERN_EMERG, "%s FBD error on branch %d: %s\n",
450 is_fatal ? "Fatal" : "NOT fatal", branch, specific);
451}
452
453/*
342 * i7300_process_error_info Retrieve the hardware error information from 454 * i7300_process_error_info Retrieve the hardware error information from
343 * the hardware and cache it in the 'info' 455 * the hardware and cache it in the 'info'
344 * structure 456 * structure
@@ -347,6 +459,7 @@ static void i7300_process_error_info(struct mem_ctl_info *mci,
347 struct i7300_error_info *info) 459 struct i7300_error_info *info)
348{ 460{
349 i7300_process_error_global(mci, info); 461 i7300_process_error_global(mci, info);
462 i7300_process_fbd_error(mci, info);
350}; 463};
351 464
352/* 465/*
@@ -381,6 +494,18 @@ static void i7300_check_error(struct mem_ctl_info *mci)
381 */ 494 */
382static void i7300_enable_error_reporting(struct mem_ctl_info *mci) 495static void i7300_enable_error_reporting(struct mem_ctl_info *mci)
383{ 496{
497 struct i7300_pvt *pvt = mci->pvt_info;
498 u32 fbd_error_mask;
499
500 /* Read the FBD Error Mask Register */
501 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
502 EMASK_FBD, &fbd_error_mask);
503
504 /* Enable with a '0' */
505 fbd_error_mask &= ~(EMASK_FBD_ERR_MASK);
506
507 pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
508 EMASK_FBD, fbd_error_mask);
384} 509}
385 510
386/************************************************ 511/************************************************