diff options
Diffstat (limited to 'drivers/edac/i7300_edac.c')
| -rw-r--r-- | drivers/edac/i7300_edac.c | 80 |
1 files changed, 46 insertions, 34 deletions
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c index a09d0667f72..dcac982fdc7 100644 --- a/drivers/edac/i7300_edac.c +++ b/drivers/edac/i7300_edac.c @@ -5,7 +5,7 @@ * GNU General Public License version 2 only. * * Copyright (c) 2010 by: - * Mauro Carvalho Chehab <mchehab@redhat.com> + * Mauro Carvalho Chehab * * Red Hat Inc. http://www.redhat.com * @@ -197,8 +197,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[] = { @@ -225,7 +225,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) |\ @@ -464,7 +464,7 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci) errnum = find_first_bit(&errors, ARRAY_SIZE(ferr_nf_fbd_name)); specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum); - branch = (GET_FBD_FAT_IDX(error_reg) == 2) ? 1 : 0; + branch = (GET_FBD_NF_IDX(error_reg) == 2) ? 1 : 0; pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, REDMEMA, &syndrome); @@ -750,15 +750,23 @@ static int i7300_init_csrows(struct mem_ctl_info *mci) struct i7300_dimm_info *dinfo; int rc = -ENODEV; int mtr; - int ch, branch, slot, channel; + int ch, branch, slot, channel, max_channel, max_branch; struct dimm_info *dimm; pvt = mci->pvt_info; edac_dbg(2, "Memory Technology Registers:\n"); + if (IS_SINGLE_MODE(pvt->mc_settings_a)) { + max_branch = 1; + max_channel = 1; + } else { + max_branch = MAX_BRANCHES; + max_channel = MAX_CH_PER_BRANCH; + } + /* Get the AMB present registers for the four channels */ - for (branch = 0; branch < MAX_BRANCHES; branch++) { + for (branch = 0; branch < max_branch; branch++) { /* Read and dump branch 0's MTRs */ channel = to_channel(0, branch); pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], @@ -767,6 +775,9 @@ static int i7300_init_csrows(struct mem_ctl_info *mci) edac_dbg(2, "\t\tAMB-present CH%d = 0x%x:\n", channel, pvt->ambpresent[channel]); + if (max_channel == 1) + continue; + channel = to_channel(1, branch); pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], AMBPRESENT_1, @@ -778,11 +789,11 @@ static int i7300_init_csrows(struct mem_ctl_info *mci) /* Get the set of MTR[0-7] regs by each branch */ for (slot = 0; slot < MAX_SLOTS; slot++) { int where = mtr_regs[slot]; - for (branch = 0; branch < MAX_BRANCHES; branch++) { + for (branch = 0; branch < max_branch; branch++) { pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], where, &pvt->mtr[slot][branch]); - for (ch = 0; ch < MAX_CH_PER_BRANCH; ch++) { + for (ch = 0; ch < max_channel; ch++) { int channel = to_channel(ch, branch); dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, @@ -923,7 +934,7 @@ static void i7300_put_devices(struct mem_ctl_info *mci) * Device 21 function 0: PCI_DEVICE_ID_INTEL_I7300_MCH_FB0 * Device 22 function 0: PCI_DEVICE_ID_INTEL_I7300_MCH_FB1 */ -static int __devinit i7300_get_devices(struct mem_ctl_info *mci) +static int i7300_get_devices(struct mem_ctl_info *mci) { struct i7300_pvt *pvt; struct pci_dev *pdev; @@ -932,33 +943,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; + } + edac_dbg(1, "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, @@ -1008,8 +1021,7 @@ error: * @pdev: struct pci_dev pointer * @id: struct pci_device_id pointer - currently unused */ -static int __devinit i7300_init_one(struct pci_dev *pdev, - const struct pci_device_id *id) +static int i7300_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { struct mem_ctl_info *mci; struct edac_mc_layer layers[3]; @@ -1122,7 +1134,7 @@ fail0: * i7300_remove_one() - Remove the driver * @pdev: struct pci_dev pointer */ -static void __devexit i7300_remove_one(struct pci_dev *pdev) +static void i7300_remove_one(struct pci_dev *pdev) { struct mem_ctl_info *mci; char *tmp; @@ -1150,7 +1162,7 @@ static void __devexit i7300_remove_one(struct pci_dev *pdev) * * Has only 8086:360c PCI ID */ -static DEFINE_PCI_DEVICE_TABLE(i7300_pci_tbl) = { +static const struct pci_device_id i7300_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7300_MCH_ERR)}, {0,} /* 0 terminated list. */ }; @@ -1163,7 +1175,7 @@ MODULE_DEVICE_TABLE(pci, i7300_pci_tbl); static struct pci_driver i7300_driver = { .name = "i7300_edac", .probe = i7300_init_one, - .remove = __devexit_p(i7300_remove_one), + .remove = i7300_remove_one, .id_table = i7300_pci_tbl, }; @@ -1197,7 +1209,7 @@ module_init(i7300_init); module_exit(i7300_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); +MODULE_AUTHOR("Mauro Carvalho Chehab"); MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); MODULE_DESCRIPTION("MC Driver for Intel I7300 memory controllers - " I7300_REVISION); |
