diff options
Diffstat (limited to 'drivers/edac/i7300_edac.c')
-rw-r--r-- | drivers/edac/i7300_edac.c | 95 |
1 files changed, 49 insertions, 46 deletions
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c index a76fe83..1e08426 100644 --- a/drivers/edac/i7300_edac.c +++ b/drivers/edac/i7300_edac.c @@ -215,8 +215,8 @@ static const char *ferr_fat_fbd_name[] = { [0] = "Memory Write error on non-redundant retry or " "FBD configuration Write error on retry", }; -#define GET_FBD_FAT_IDX(fbderr) (fbderr & (3 << 28)) -#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)) +#define GET_FBD_FAT_IDX(fbderr) (((fbderr) >> 28) & 3) +#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 22)) #define FERR_NF_FBD 0xa0 static const char *ferr_nf_fbd_name[] = { @@ -243,7 +243,7 @@ static const char *ferr_nf_fbd_name[] = { [1] = "Aliased Uncorrectable Non-Mirrored Demand Data ECC", [0] = "Uncorrectable Data ECC on Replay", }; -#define GET_FBD_NF_IDX(fbderr) (fbderr & (3 << 28)) +#define GET_FBD_NF_IDX(fbderr) (((fbderr) >> 28) & 3) #define FERR_NF_FBD_ERR_MASK ((1 << 24) | (1 << 23) | (1 << 22) | (1 << 21) |\ (1 << 18) | (1 << 17) | (1 << 16) | (1 << 15) |\ (1 << 14) | (1 << 13) | (1 << 11) | (1 << 10) |\ @@ -372,7 +372,7 @@ static const char *get_err_from_table(const char *table[], int size, int pos) static void i7300_process_error_global(struct mem_ctl_info *mci) { struct i7300_pvt *pvt; - u32 errnum, value; + u32 errnum, error_reg; unsigned long errors; const char *specific; bool is_fatal; @@ -381,9 +381,9 @@ static void i7300_process_error_global(struct mem_ctl_info *mci) /* read in the 1st FATAL error register */ pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs, - FERR_GLOBAL_HI, &value); - if (unlikely(value)) { - errors = value; + FERR_GLOBAL_HI, &error_reg); + if (unlikely(error_reg)) { + errors = error_reg; errnum = find_first_bit(&errors, ARRAY_SIZE(ferr_global_hi_name)); specific = GET_ERR_FROM_TABLE(ferr_global_hi_name, errnum); @@ -391,15 +391,15 @@ static void i7300_process_error_global(struct mem_ctl_info *mci) /* Clear the error bit */ pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs, - FERR_GLOBAL_HI, value); + FERR_GLOBAL_HI, error_reg); goto error_global; } pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs, - FERR_GLOBAL_LO, &value); - if (unlikely(value)) { - errors = value; + FERR_GLOBAL_LO, &error_reg); + if (unlikely(error_reg)) { + errors = error_reg; errnum = find_first_bit(&errors, ARRAY_SIZE(ferr_global_lo_name)); specific = GET_ERR_FROM_TABLE(ferr_global_lo_name, errnum); @@ -407,7 +407,7 @@ static void i7300_process_error_global(struct mem_ctl_info *mci) /* Clear the error bit */ pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs, - FERR_GLOBAL_LO, value); + FERR_GLOBAL_LO, error_reg); goto error_global; } @@ -427,7 +427,7 @@ error_global: static void i7300_process_fbd_error(struct mem_ctl_info *mci) { struct i7300_pvt *pvt; - u32 errnum, value; + u32 errnum, value, error_reg; u16 val16; unsigned branch, channel, bank, rank, cas, ras; u32 syndrome; @@ -440,14 +440,14 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci) /* read in the 1st FATAL error register */ pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, - FERR_FAT_FBD, &value); - if (unlikely(value & FERR_FAT_FBD_ERR_MASK)) { - errors = value & FERR_FAT_FBD_ERR_MASK ; + FERR_FAT_FBD, &error_reg); + if (unlikely(error_reg & FERR_FAT_FBD_ERR_MASK)) { + errors = error_reg & FERR_FAT_FBD_ERR_MASK ; errnum = find_first_bit(&errors, ARRAY_SIZE(ferr_fat_fbd_name)); specific = GET_ERR_FROM_TABLE(ferr_fat_fbd_name, errnum); + branch = (GET_FBD_FAT_IDX(error_reg) == 2) ? 1 : 0; - branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0; pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, NRECMEMA, &val16); bank = NRECMEMA_BANK(val16); @@ -455,11 +455,14 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci) pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, NRECMEMB, &value); - is_wr = NRECMEMB_IS_WR(value); cas = NRECMEMB_CAS(value); ras = NRECMEMB_RAS(value); + /* Clean the error register */ + pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map, + FERR_FAT_FBD, error_reg); + snprintf(pvt->tmp_prt_buffer, PAGE_SIZE, "FATAL (Branch=%d DRAM-Bank=%d %s " "RAS=%d CAS=%d Err=0x%lx (%s))", @@ -476,21 +479,17 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci) /* read in the 1st NON-FATAL error register */ pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, - FERR_NF_FBD, &value); - if (unlikely(value & FERR_NF_FBD_ERR_MASK)) { - errors = value & FERR_NF_FBD_ERR_MASK; + FERR_NF_FBD, &error_reg); + if (unlikely(error_reg & FERR_NF_FBD_ERR_MASK)) { + errors = error_reg & FERR_NF_FBD_ERR_MASK; errnum = find_first_bit(&errors, ARRAY_SIZE(ferr_nf_fbd_name)); specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum); - - /* Clear the error bit */ - pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs, - FERR_GLOBAL_LO, value); + branch = (GET_FBD_NF_IDX(error_reg) == 2) ? 1 : 0; pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, REDMEMA, &syndrome); - branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0; pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, RECMEMA, &val16); bank = RECMEMA_BANK(val16); @@ -498,18 +497,20 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci) pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, RECMEMB, &value); - is_wr = RECMEMB_IS_WR(value); cas = RECMEMB_CAS(value); ras = RECMEMB_RAS(value); pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, REDMEMB, &value); - channel = (branch << 1); if (IS_SECOND_CH(value)) channel++; + /* Clear the error bit */ + pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map, + FERR_NF_FBD, error_reg); + /* Form out message */ snprintf(pvt->tmp_prt_buffer, PAGE_SIZE, "Corrected error (Branch=%d, Channel %d), " @@ -961,33 +962,35 @@ static int __devinit i7300_get_devices(struct mem_ctl_info *mci) /* Attempt to 'get' the MCH register we want */ pdev = NULL; - while (!pvt->pci_dev_16_1_fsb_addr_map || - !pvt->pci_dev_16_2_fsb_err_regs) { - pdev = pci_get_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_I7300_MCH_ERR, pdev); - if (!pdev) { - /* End of list, leave */ - i7300_printk(KERN_ERR, - "'system address,Process Bus' " - "device not found:" - "vendor 0x%x device 0x%x ERR funcs " - "(broken BIOS?)\n", - PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_I7300_MCH_ERR); - goto error; - } - + while ((pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_I7300_MCH_ERR, + pdev))) { /* Store device 16 funcs 1 and 2 */ switch (PCI_FUNC(pdev->devfn)) { case 1: - pvt->pci_dev_16_1_fsb_addr_map = pdev; + if (!pvt->pci_dev_16_1_fsb_addr_map) + pvt->pci_dev_16_1_fsb_addr_map = + pci_dev_get(pdev); break; case 2: - pvt->pci_dev_16_2_fsb_err_regs = pdev; + if (!pvt->pci_dev_16_2_fsb_err_regs) + pvt->pci_dev_16_2_fsb_err_regs = + pci_dev_get(pdev); break; } } + if (!pvt->pci_dev_16_1_fsb_addr_map || + !pvt->pci_dev_16_2_fsb_err_regs) { + /* At least one device was not found */ + i7300_printk(KERN_ERR, + "'system address,Process Bus' device not found:" + "vendor 0x%x device 0x%x ERR funcs (broken BIOS?)\n", + PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_I7300_MCH_ERR); + goto error; + } + debugf1("System Address, processor bus- PCI Bus ID: %s %x:%x\n", pci_name(pvt->pci_dev_16_0_fsb_ctlr), pvt->pci_dev_16_0_fsb_ctlr->vendor, |