diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-08-27 11:13:05 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-08-30 13:57:02 -0400 |
commit | 32f9472613b30791d8cb5a953791cf4647166744 (patch) | |
tree | beeddb034f9a859a407ff2b95d906b3f29680e21 /drivers/edac | |
parent | 8199d8cc65787bfd83abbfb69d9de1b51e027c41 (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.c | 63 |
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) */ |
282 | struct i7300_dev_info { | 293 | struct 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 | ||
469 | error_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 | /* |