i7300_edac.c (8199d8cc65787bfd83abbfb69d9de1b51e027c41) | i7300_edac.c (32f9472613b30791d8cb5a953791cf4647166744) |
---|---|
1/* 2 * Intel 7300 class Memory Controllers kernel module (Clarksboro) 3 * 4 * This file may be distributed under the terms of the 5 * GNU General Public License version 2 only. 6 * 7 * Copyright (c) 2010 by: 8 * Mauro Carvalho Chehab <mchehab@redhat.com> --- 263 unchanged lines hidden (view full) --- 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 | 1/* 2 * Intel 7300 class Memory Controllers kernel module (Clarksboro) 3 * 4 * This file may be distributed under the terms of the 5 * GNU General Public License version 2 only. 6 * 7 * Copyright (c) 2010 by: 8 * Mauro Carvalho Chehab <mchehab@redhat.com> --- 263 unchanged lines hidden (view full) --- 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#define REDMEMA 0xdc |
|
280 | 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 291 |
|
281/* Device name and register DID (Device ID) */ 282struct i7300_dev_info { 283 const char *ctl_name; /* name for this device */ 284 u16 fsb_mapping_errors; /* DID for the branchmap,control */ 285}; 286 287/* Table of devices attributes supported by this driver */ 288static const struct i7300_dev_info i7300_devs[] = { --- 109 unchanged lines hidden (view full) --- 398 * the hardware and cache it in the 'info' 399 * structure 400 */ 401static void i7300_process_fbd_error(struct mem_ctl_info *mci) 402{ 403 struct i7300_pvt *pvt; 404 u32 errnum, value; 405 u16 val16; | 292/* Device name and register DID (Device ID) */ 293struct i7300_dev_info { 294 const char *ctl_name; /* name for this device */ 295 u16 fsb_mapping_errors; /* DID for the branchmap,control */ 296}; 297 298/* Table of devices attributes supported by this driver */ 299static const struct i7300_dev_info i7300_devs[] = { --- 109 unchanged lines hidden (view full) --- 409 * the hardware and cache it in the 'info' 410 * structure 411 */ 412static void i7300_process_fbd_error(struct mem_ctl_info *mci) 413{ 414 struct i7300_pvt *pvt; 415 u32 errnum, value; 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; 408 const char *specific; | 420 unsigned long errors; 421 const char *specific; |
409 bool is_fatal, is_wr; | 422 bool is_wr; |
410 411 pvt = mci->pvt_info; 412 413 /* read in the 1st FATAL error register */ 414 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, 415 FERR_FAT_FBD, &value); 416 if (unlikely(value & FERR_FAT_FBD_ERR_MASK)) { 417 errors = value & FERR_FAT_FBD_ERR_MASK ; 418 errnum = find_first_bit(&errors, 419 ARRAY_SIZE(ferr_fat_fbd_name)); 420 specific = GET_ERR_FROM_TABLE(ferr_fat_fbd_name, errnum); | 423 424 pvt = mci->pvt_info; 425 426 /* read in the 1st FATAL error register */ 427 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, 428 FERR_FAT_FBD, &value); 429 if (unlikely(value & FERR_FAT_FBD_ERR_MASK)) { 430 errors = value & FERR_FAT_FBD_ERR_MASK ; 431 errnum = find_first_bit(&errors, 432 ARRAY_SIZE(ferr_fat_fbd_name)); 433 specific = GET_ERR_FROM_TABLE(ferr_fat_fbd_name, errnum); |
421 is_fatal = 1; | |
422 423 branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0; 424 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, 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))", | 434 435 branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0; 436 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, 437 NRECMEMA, &val16); 438 bank = NRECMEMA_BANK(val16); 439 rank = NRECMEMA_RANK(val16); 440 441 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, 442 NRECMEMB, &value); 443 444 is_wr = NRECMEMB_IS_WR(value); 445 cas = NRECMEMB_CAS(value); 446 ras = NRECMEMB_RAS(value); 447 448 snprintf(pvt->tmp_prt_buffer, PAGE_SIZE, 449 "FATAL (Branch=%d DRAM-Bank=%d %s " 450 "RAS=%d CAS=%d Err=0x%lx (%s))", |
439 branch >> 1, bank, | 451 branch, 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); | 452 is_wr ? "RDWR" : "RD", 453 ras, cas, 454 errors, specific); 455 456 /* Call the helper to output message */ 457 edac_mc_handle_fbd_ue(mci, rank, branch << 1, 458 (branch << 1) + 1, 459 pvt->tmp_prt_buffer); |
448 return; | |
449 } 450 451 /* read in the 1st NON-FATAL error register */ 452 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, 453 FERR_NF_FBD, &value); 454 if (unlikely(value & FERR_NF_FBD_ERR_MASK)) { 455 errors = value & FERR_NF_FBD_ERR_MASK; 456 errnum = find_first_bit(&errors, 457 ARRAY_SIZE(ferr_nf_fbd_name)); 458 specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum); | 460 } 461 462 /* read in the 1st NON-FATAL error register */ 463 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, 464 FERR_NF_FBD, &value); 465 if (unlikely(value & FERR_NF_FBD_ERR_MASK)) { 466 errors = value & FERR_NF_FBD_ERR_MASK; 467 errnum = find_first_bit(&errors, 468 ARRAY_SIZE(ferr_nf_fbd_name)); 469 specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum); |
459 is_fatal = 0; | |
460 461 /* Clear the error bit */ 462 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs, 463 FERR_GLOBAL_LO, value); 464 | 470 471 /* Clear the error bit */ 472 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs, 473 FERR_GLOBAL_LO, value); 474 |
465 goto error_fbd; 466 } 467 return; | 475 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, 476 REDMEMA, &syndrome); |
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", 472 is_fatal ? "Fatal" : "NOT fatal", branch, specific); | 484 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, 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} 474 475/* 476 * i7300_check_error Retrieve the hardware error information from 477 * the hardware and cache it in the 'info' 478 * structure 479 */ 480static void i7300_check_error(struct mem_ctl_info *mci) --- 714 unchanged lines hidden --- | 512} 513 514/* 515 * i7300_check_error Retrieve the hardware error information from 516 * the hardware and cache it in the 'info' 517 * structure 518 */ 519static void i7300_check_error(struct mem_ctl_info *mci) --- 714 unchanged lines hidden --- |