aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2010-08-27 11:13:05 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-08-30 13:57:02 -0400
commit32f9472613b30791d8cb5a953791cf4647166744 (patch)
treebeeddb034f9a859a407ff2b95d906b3f29680e21 /drivers/edac
parent8199d8cc65787bfd83abbfb69d9de1b51e027c41 (diff)
i7300_edac: enrich FBD error info for corrected errors
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/i7300_edac.c63
1 files changed, 51 insertions, 12 deletions
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c
index e33c9900e269..a06db65e1fef 100644
--- a/drivers/edac/i7300_edac.c
+++ b/drivers/edac/i7300_edac.c
@@ -277,6 +277,17 @@ static const char *ferr_global_lo_name[] = {
277 #define NRECMEMB_CAS(v) (((v) >> 16) & 0x1fff) 277 #define NRECMEMB_CAS(v) (((v) >> 16) & 0x1fff)
278 #define NRECMEMB_RAS(v) ((v) & 0xffff) 278 #define NRECMEMB_RAS(v) ((v) & 0xffff)
279 279
280#define REDMEMA 0xdc
281
282#define RECMEMA 0xe0
283 #define RECMEMA_BANK(v) (((v) >> 12) & 7)
284 #define RECMEMA_RANK(v) (((v) >> 8) & 15)
285
286#define RECMEMB 0xe4
287 #define RECMEMB_IS_WR(v) ((v) & (1 << 31))
288 #define RECMEMB_CAS(v) (((v) >> 16) & 0x1fff)
289 #define RECMEMB_RAS(v) ((v) & 0xffff)
290
280 291
281/* Device name and register DID (Device ID) */ 292/* Device name and register DID (Device ID) */
282struct i7300_dev_info { 293struct i7300_dev_info {
@@ -403,10 +414,12 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
403 struct i7300_pvt *pvt; 414 struct i7300_pvt *pvt;
404 u32 errnum, value; 415 u32 errnum, value;
405 u16 val16; 416 u16 val16;
406 int branch, bank, rank, cas, ras; 417 unsigned branch, bank, rank, cas, ras;
418 u32 syndrome;
419
407 unsigned long errors; 420 unsigned long errors;
408 const char *specific; 421 const char *specific;
409 bool is_fatal, is_wr; 422 bool is_wr;
410 423
411 pvt = mci->pvt_info; 424 pvt = mci->pvt_info;
412 425
@@ -418,7 +431,6 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
418 errnum = find_first_bit(&errors, 431 errnum = find_first_bit(&errors,
419 ARRAY_SIZE(ferr_fat_fbd_name)); 432 ARRAY_SIZE(ferr_fat_fbd_name));
420 specific = GET_ERR_FROM_TABLE(ferr_fat_fbd_name, errnum); 433 specific = GET_ERR_FROM_TABLE(ferr_fat_fbd_name, errnum);
421 is_fatal = 1;
422 434
423 branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0; 435 branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0;
424 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, 436 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map,
@@ -436,7 +448,7 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
436 snprintf(pvt->tmp_prt_buffer, PAGE_SIZE, 448 snprintf(pvt->tmp_prt_buffer, PAGE_SIZE,
437 "FATAL (Branch=%d DRAM-Bank=%d %s " 449 "FATAL (Branch=%d DRAM-Bank=%d %s "
438 "RAS=%d CAS=%d Err=0x%lx (%s))", 450 "RAS=%d CAS=%d Err=0x%lx (%s))",
439 branch >> 1, bank, 451 branch, bank,
440 is_wr ? "RDWR" : "RD", 452 is_wr ? "RDWR" : "RD",
441 ras, cas, 453 ras, cas,
442 errors, specific); 454 errors, specific);
@@ -445,7 +457,6 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
445 edac_mc_handle_fbd_ue(mci, rank, branch << 1, 457 edac_mc_handle_fbd_ue(mci, rank, branch << 1,
446 (branch << 1) + 1, 458 (branch << 1) + 1,
447 pvt->tmp_prt_buffer); 459 pvt->tmp_prt_buffer);
448 return;
449 } 460 }
450 461
451 /* read in the 1st NON-FATAL error register */ 462 /* read in the 1st NON-FATAL error register */
@@ -456,20 +467,48 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
456 errnum = find_first_bit(&errors, 467 errnum = find_first_bit(&errors,
457 ARRAY_SIZE(ferr_nf_fbd_name)); 468 ARRAY_SIZE(ferr_nf_fbd_name));
458 specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum); 469 specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum);
459 is_fatal = 0;
460 470
461 /* Clear the error bit */ 471 /* Clear the error bit */
462 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs, 472 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
463 FERR_GLOBAL_LO, value); 473 FERR_GLOBAL_LO, value);
464 474
465 goto error_fbd; 475 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
466 } 476 REDMEMA, &syndrome);
467 return;
468 477
469error_fbd: 478 branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0;
479 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map,
480 RECMEMA, &val16);
481 bank = RECMEMA_BANK(val16);
482 rank = RECMEMA_RANK(val16);
470 483
471 i7300_mc_printk(mci, KERN_EMERG, "%s FBD error on branch %d: %s\n", 484 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
472 is_fatal ? "Fatal" : "NOT fatal", branch, specific); 485 RECMEMB, &value);
486
487 is_wr = RECMEMB_IS_WR(value);
488 cas = RECMEMB_CAS(value);
489 ras = RECMEMB_RAS(value);
490
491 /* Form out message */
492 snprintf(pvt->tmp_prt_buffer, PAGE_SIZE,
493 "Corrected error (Branch=%d (channel %d or %d), "
494 " DRAM-Bank=%d %s "
495 "RAS=%d CAS=%d, CE Err=0x%lx, Syndrome=0x%08x(%s))",
496 branch, branch << 1, (branch << 1) + 1,
497 bank,
498 is_wr ? "RDWR" : "RD",
499 ras, cas,
500 errors, syndrome, specific);
501
502 /*
503 * Call the helper to output message
504 * NOTE: Errors are reported per-branch, and not per-channel
505 * Currently, we don't know how to identify the right
506 * channel.
507 */
508 edac_mc_handle_fbd_ce(mci, rank, branch << 1,
509 pvt->tmp_prt_buffer);
510 }
511 return;
473} 512}
474 513
475/* 514/*