diff options
Diffstat (limited to 'drivers/edac/i7300_edac.c')
| -rw-r--r-- | drivers/edac/i7300_edac.c | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c index 4c239ce6986b..e33c9900e269 100644 --- a/drivers/edac/i7300_edac.c +++ b/drivers/edac/i7300_edac.c | |||
| @@ -268,6 +268,16 @@ static const char *ferr_global_lo_name[] = { | |||
| 268 | }; | 268 | }; |
| 269 | #define ferr_global_lo_is_fatal(errno) ((errno < 16) ? 0 : 1) | 269 | #define ferr_global_lo_is_fatal(errno) ((errno < 16) ? 0 : 1) |
| 270 | 270 | ||
| 271 | #define NRECMEMA 0xbe | ||
| 272 | #define NRECMEMA_BANK(v) (((v) >> 12) & 7) | ||
| 273 | #define NRECMEMA_RANK(v) (((v) >> 8) & 15) | ||
| 274 | |||
| 275 | #define NRECMEMB 0xc0 | ||
| 276 | #define NRECMEMB_IS_WR(v) ((v) & (1 << 31)) | ||
| 277 | #define NRECMEMB_CAS(v) (((v) >> 16) & 0x1fff) | ||
| 278 | #define NRECMEMB_RAS(v) ((v) & 0xffff) | ||
| 279 | |||
| 280 | |||
| 271 | /* Device name and register DID (Device ID) */ | 281 | /* Device name and register DID (Device ID) */ |
| 272 | struct i7300_dev_info { | 282 | struct i7300_dev_info { |
| 273 | const char *ctl_name; /* name for this device */ | 283 | const char *ctl_name; /* name for this device */ |
| @@ -392,10 +402,11 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci) | |||
| 392 | { | 402 | { |
| 393 | struct i7300_pvt *pvt; | 403 | struct i7300_pvt *pvt; |
| 394 | u32 errnum, value; | 404 | u32 errnum, value; |
| 395 | int branch; | 405 | u16 val16; |
| 406 | int branch, bank, rank, cas, ras; | ||
| 396 | unsigned long errors; | 407 | unsigned long errors; |
| 397 | const char *specific; | 408 | const char *specific; |
| 398 | bool is_fatal; | 409 | bool is_fatal, is_wr; |
| 399 | 410 | ||
| 400 | pvt = mci->pvt_info; | 411 | pvt = mci->pvt_info; |
| 401 | 412 | ||
| @@ -410,8 +421,31 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci) | |||
| 410 | is_fatal = 1; | 421 | is_fatal = 1; |
| 411 | 422 | ||
| 412 | branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0; | 423 | branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0; |
| 413 | 424 | pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, | |
| 414 | goto error_fbd; | 425 | NRECMEMA, &val16); |
| 426 | bank = NRECMEMA_BANK(val16); | ||
| 427 | rank = NRECMEMA_RANK(val16); | ||
| 428 | |||
| 429 | pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, | ||
| 430 | NRECMEMB, &value); | ||
| 431 | |||
| 432 | is_wr = NRECMEMB_IS_WR(value); | ||
| 433 | cas = NRECMEMB_CAS(value); | ||
| 434 | ras = NRECMEMB_RAS(value); | ||
| 435 | |||
| 436 | snprintf(pvt->tmp_prt_buffer, PAGE_SIZE, | ||
| 437 | "FATAL (Branch=%d DRAM-Bank=%d %s " | ||
| 438 | "RAS=%d CAS=%d Err=0x%lx (%s))", | ||
| 439 | branch >> 1, bank, | ||
| 440 | is_wr ? "RDWR" : "RD", | ||
| 441 | ras, cas, | ||
| 442 | errors, specific); | ||
| 443 | |||
| 444 | /* Call the helper to output message */ | ||
| 445 | edac_mc_handle_fbd_ue(mci, rank, branch << 1, | ||
| 446 | (branch << 1) + 1, | ||
| 447 | pvt->tmp_prt_buffer); | ||
| 448 | return; | ||
| 415 | } | 449 | } |
| 416 | 450 | ||
| 417 | /* read in the 1st NON-FATAL error register */ | 451 | /* read in the 1st NON-FATAL error register */ |
| @@ -433,6 +467,7 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci) | |||
| 433 | return; | 467 | return; |
| 434 | 468 | ||
| 435 | error_fbd: | 469 | error_fbd: |
| 470 | |||
| 436 | i7300_mc_printk(mci, KERN_EMERG, "%s FBD error on branch %d: %s\n", | 471 | i7300_mc_printk(mci, KERN_EMERG, "%s FBD error on branch %d: %s\n", |
| 437 | is_fatal ? "Fatal" : "NOT fatal", branch, specific); | 472 | is_fatal ? "Fatal" : "NOT fatal", branch, specific); |
| 438 | } | 473 | } |
