diff options
-rw-r--r-- | drivers/edac/i7core_edac.c | 59 |
1 files changed, 32 insertions, 27 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index e0a3b217c52b..914914759690 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
@@ -113,7 +113,7 @@ | |||
113 | #define MC_DOD_NUMBANK(x) (((x) & MC_DOD_NUMBANK_MASK) >> 7) | 113 | #define MC_DOD_NUMBANK(x) (((x) & MC_DOD_NUMBANK_MASK) >> 7) |
114 | #define MC_DOD_NUMRANK_MASK ((1 << 6) | (1 << 5)) | 114 | #define MC_DOD_NUMRANK_MASK ((1 << 6) | (1 << 5)) |
115 | #define MC_DOD_NUMRANK(x) (((x) & MC_DOD_NUMRANK_MASK) >> 5) | 115 | #define MC_DOD_NUMRANK(x) (((x) & MC_DOD_NUMRANK_MASK) >> 5) |
116 | #define MC_DOD_NUMROW_MASK ((1 << 4) | (1 << 3)| (1 << 2)) | 116 | #define MC_DOD_NUMROW_MASK ((1 << 4) | (1 << 3) | (1 << 2)) |
117 | #define MC_DOD_NUMROW(x) (((x) & MC_DOD_NUMROW_MASK) >> 2) | 117 | #define MC_DOD_NUMROW(x) (((x) & MC_DOD_NUMROW_MASK) >> 2) |
118 | #define MC_DOD_NUMCOL_MASK 3 | 118 | #define MC_DOD_NUMCOL_MASK 3 |
119 | #define MC_DOD_NUMCOL(x) ((x) & MC_DOD_NUMCOL_MASK) | 119 | #define MC_DOD_NUMCOL(x) ((x) & MC_DOD_NUMCOL_MASK) |
@@ -352,9 +352,8 @@ static int i7core_get_active_channels(int *channels, int *csrows) | |||
352 | continue; | 352 | continue; |
353 | 353 | ||
354 | /* Check if the channel is disabled */ | 354 | /* Check if the channel is disabled */ |
355 | if (status & (1 << i)) { | 355 | if (status & (1 << i)) |
356 | continue; | 356 | continue; |
357 | } | ||
358 | 357 | ||
359 | pdev = get_pdev_slot_func(i + 4, 1); | 358 | pdev = get_pdev_slot_func(i + 4, 1); |
360 | if (!pdev) { | 359 | if (!pdev) { |
@@ -410,7 +409,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) | |||
410 | pvt->info.max_dod, pvt->info.ch_map); | 409 | pvt->info.max_dod, pvt->info.ch_map); |
411 | 410 | ||
412 | if (ECC_ENABLED(pvt)) { | 411 | if (ECC_ENABLED(pvt)) { |
413 | debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt) ?8:4); | 412 | debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt) ? 8 : 4); |
414 | if (ECCx8(pvt)) | 413 | if (ECCx8(pvt)) |
415 | mode = EDAC_S8ECD8ED; | 414 | mode = EDAC_S8ECD8ED; |
416 | else | 415 | else |
@@ -447,7 +446,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) | |||
447 | pci_read_config_dword(pvt->pci_ch[i][0], | 446 | pci_read_config_dword(pvt->pci_ch[i][0], |
448 | MC_CHANNEL_DIMM_INIT_PARAMS, &data); | 447 | MC_CHANNEL_DIMM_INIT_PARAMS, &data); |
449 | 448 | ||
450 | pvt->channel[i].ranks = (data & QUAD_RANK_PRESENT)? 4 : 2; | 449 | pvt->channel[i].ranks = (data & QUAD_RANK_PRESENT) ? 4 : 2; |
451 | 450 | ||
452 | if (data & REGISTERED_DIMM) | 451 | if (data & REGISTERED_DIMM) |
453 | mtype = MEM_RDDR3; | 452 | mtype = MEM_RDDR3; |
@@ -476,7 +475,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) | |||
476 | RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i), | 475 | RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i), |
477 | data, | 476 | data, |
478 | pvt->channel[i].ranks, | 477 | pvt->channel[i].ranks, |
479 | (data & REGISTERED_DIMM)? 'R' : 'U'); | 478 | (data & REGISTERED_DIMM) ? 'R' : 'U'); |
480 | 479 | ||
481 | for (j = 0; j < 3; j++) { | 480 | for (j = 0; j < 3; j++) { |
482 | u32 banks, ranks, rows, cols; | 481 | u32 banks, ranks, rows, cols; |
@@ -550,9 +549,9 @@ static int get_dimm_config(struct mem_ctl_info *mci) | |||
550 | pci_read_config_dword(pdev, MC_SAG_CH_5, &value[5]); | 549 | pci_read_config_dword(pdev, MC_SAG_CH_5, &value[5]); |
551 | pci_read_config_dword(pdev, MC_SAG_CH_6, &value[6]); | 550 | pci_read_config_dword(pdev, MC_SAG_CH_6, &value[6]); |
552 | pci_read_config_dword(pdev, MC_SAG_CH_7, &value[7]); | 551 | pci_read_config_dword(pdev, MC_SAG_CH_7, &value[7]); |
553 | printk("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i); | 552 | debugf0("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i); |
554 | for (j = 0; j < 8; j++) | 553 | for (j = 0; j < 8; j++) |
555 | printk("\t\t%#x\t%#x\t%#x\n", | 554 | debugf0("\t\t%#x\t%#x\t%#x\n", |
556 | (value[j] >> 27) & 0x1, | 555 | (value[j] >> 27) & 0x1, |
557 | (value[j] >> 24) & 0x7, | 556 | (value[j] >> 24) & 0x7, |
558 | (value[j] && ((1 << 24) - 1))); | 557 | (value[j] && ((1 << 24) - 1))); |
@@ -602,7 +601,7 @@ static ssize_t i7core_inject_section_store(struct mem_ctl_info *mci, | |||
602 | int rc; | 601 | int rc; |
603 | 602 | ||
604 | if (pvt->inject.enable) | 603 | if (pvt->inject.enable) |
605 | disable_inject(mci); | 604 | disable_inject(mci); |
606 | 605 | ||
607 | rc = strict_strtoul(data, 10, &value); | 606 | rc = strict_strtoul(data, 10, &value); |
608 | if ((rc < 0) || (value > 3)) | 607 | if ((rc < 0) || (value > 3)) |
@@ -635,7 +634,7 @@ static ssize_t i7core_inject_type_store(struct mem_ctl_info *mci, | |||
635 | int rc; | 634 | int rc; |
636 | 635 | ||
637 | if (pvt->inject.enable) | 636 | if (pvt->inject.enable) |
638 | disable_inject(mci); | 637 | disable_inject(mci); |
639 | 638 | ||
640 | rc = strict_strtoul(data, 10, &value); | 639 | rc = strict_strtoul(data, 10, &value); |
641 | if ((rc < 0) || (value > 7)) | 640 | if ((rc < 0) || (value > 7)) |
@@ -670,7 +669,7 @@ static ssize_t i7core_inject_eccmask_store(struct mem_ctl_info *mci, | |||
670 | int rc; | 669 | int rc; |
671 | 670 | ||
672 | if (pvt->inject.enable) | 671 | if (pvt->inject.enable) |
673 | disable_inject(mci); | 672 | disable_inject(mci); |
674 | 673 | ||
675 | rc = strict_strtoul(data, 10, &value); | 674 | rc = strict_strtoul(data, 10, &value); |
676 | if (rc < 0) | 675 | if (rc < 0) |
@@ -706,7 +705,7 @@ static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci, | |||
706 | int rc; | 705 | int rc; |
707 | 706 | ||
708 | if (pvt->inject.enable) | 707 | if (pvt->inject.enable) |
709 | disable_inject(mci); | 708 | disable_inject(mci); |
710 | 709 | ||
711 | do { | 710 | do { |
712 | cmd = strsep((char **) &data, ":"); | 711 | cmd = strsep((char **) &data, ":"); |
@@ -716,7 +715,7 @@ static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci, | |||
716 | if (!val) | 715 | if (!val) |
717 | return cmd - data; | 716 | return cmd - data; |
718 | 717 | ||
719 | if (!strcasecmp(val,"any")) | 718 | if (!strcasecmp(val, "any")) |
720 | value = -1; | 719 | value = -1; |
721 | else { | 720 | else { |
722 | rc = strict_strtol(val, 10, &value); | 721 | rc = strict_strtol(val, 10, &value); |
@@ -724,33 +723,33 @@ static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci, | |||
724 | return cmd - data; | 723 | return cmd - data; |
725 | } | 724 | } |
726 | 725 | ||
727 | if (!strcasecmp(cmd,"channel")) { | 726 | if (!strcasecmp(cmd, "channel")) { |
728 | if (value < 3) | 727 | if (value < 3) |
729 | pvt->inject.channel = value; | 728 | pvt->inject.channel = value; |
730 | else | 729 | else |
731 | return cmd - data; | 730 | return cmd - data; |
732 | } else if (!strcasecmp(cmd,"dimm")) { | 731 | } else if (!strcasecmp(cmd, "dimm")) { |
733 | if (value < 4) | 732 | if (value < 4) |
734 | pvt->inject.dimm = value; | 733 | pvt->inject.dimm = value; |
735 | else | 734 | else |
736 | return cmd - data; | 735 | return cmd - data; |
737 | } else if (!strcasecmp(cmd,"rank")) { | 736 | } else if (!strcasecmp(cmd, "rank")) { |
738 | if (value < 4) | 737 | if (value < 4) |
739 | pvt->inject.rank = value; | 738 | pvt->inject.rank = value; |
740 | else | 739 | else |
741 | return cmd - data; | 740 | return cmd - data; |
742 | } else if (!strcasecmp(cmd,"bank")) { | 741 | } else if (!strcasecmp(cmd, "bank")) { |
743 | if (value < 4) | 742 | if (value < 4) |
744 | pvt->inject.bank = value; | 743 | pvt->inject.bank = value; |
745 | else | 744 | else |
746 | return cmd - data; | 745 | return cmd - data; |
747 | } else if (!strcasecmp(cmd,"page")) { | 746 | } else if (!strcasecmp(cmd, "page")) { |
748 | if (value <= 0xffff) | 747 | if (value <= 0xffff) |
749 | pvt->inject.page = value; | 748 | pvt->inject.page = value; |
750 | else | 749 | else |
751 | return cmd - data; | 750 | return cmd - data; |
752 | } else if (!strcasecmp(cmd,"col") || | 751 | } else if (!strcasecmp(cmd, "col") || |
753 | !strcasecmp(cmd,"column")) { | 752 | !strcasecmp(cmd, "column")) { |
754 | if (value <= 0x3fff) | 753 | if (value <= 0x3fff) |
755 | pvt->inject.col = value; | 754 | pvt->inject.col = value; |
756 | else | 755 | else |
@@ -923,7 +922,8 @@ static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci, | |||
923 | pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], | 922 | pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0], |
924 | MC_CHANNEL_ERROR_MASK, injectmask); | 923 | MC_CHANNEL_ERROR_MASK, injectmask); |
925 | 924 | ||
926 | debugf0("Error inject addr match 0x%016llx, ecc 0x%08x, inject 0x%08x\n", | 925 | debugf0("Error inject addr match 0x%016llx, ecc 0x%08x," |
926 | " inject 0x%08x\n", | ||
927 | mask, pvt->inject.eccmask, injectmask); | 927 | mask, pvt->inject.eccmask, injectmask); |
928 | 928 | ||
929 | 929 | ||
@@ -1048,7 +1048,7 @@ static int i7core_get_devices(void) | |||
1048 | "Device not found: PCI ID %04x:%04x " | 1048 | "Device not found: PCI ID %04x:%04x " |
1049 | "(dev %d, func %d)\n", | 1049 | "(dev %d, func %d)\n", |
1050 | PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, | 1050 | PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id, |
1051 | pci_devs[i].dev,pci_devs[i].func); | 1051 | pci_devs[i].dev, pci_devs[i].func); |
1052 | 1052 | ||
1053 | /* Dev 3 function 2 only exists on chips with RDIMMs */ | 1053 | /* Dev 3 function 2 only exists on chips with RDIMMs */ |
1054 | if ((pci_devs[i].dev == 3) && (pci_devs[i].func == 2)) | 1054 | if ((pci_devs[i].dev == 3) && (pci_devs[i].func == 2)) |
@@ -1231,12 +1231,12 @@ static int __devinit i7core_probe(struct pci_dev *pdev, | |||
1231 | 1231 | ||
1232 | /* Check the number of active and not disabled channels */ | 1232 | /* Check the number of active and not disabled channels */ |
1233 | rc = i7core_get_active_channels(&num_channels, &num_csrows); | 1233 | rc = i7core_get_active_channels(&num_channels, &num_csrows); |
1234 | if (unlikely (rc < 0)) | 1234 | if (unlikely(rc < 0)) |
1235 | goto fail0; | 1235 | goto fail0; |
1236 | 1236 | ||
1237 | /* allocate a new MC control structure */ | 1237 | /* allocate a new MC control structure */ |
1238 | mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); | 1238 | mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); |
1239 | if (unlikely (!mci)) { | 1239 | if (unlikely(!mci)) { |
1240 | rc = -ENOMEM; | 1240 | rc = -ENOMEM; |
1241 | goto fail0; | 1241 | goto fail0; |
1242 | } | 1242 | } |
@@ -1249,7 +1249,12 @@ static int __devinit i7core_probe(struct pci_dev *pdev, | |||
1249 | memset(pvt, 0, sizeof(*pvt)); | 1249 | memset(pvt, 0, sizeof(*pvt)); |
1250 | 1250 | ||
1251 | mci->mc_idx = 0; | 1251 | mci->mc_idx = 0; |
1252 | mci->mtype_cap = MEM_FLAG_DDR3; /* FIXME: how to handle RDDR3? */ | 1252 | /* |
1253 | * FIXME: how to handle RDDR3 at MCI level? It is possible to have | ||
1254 | * Mixed RDDR3/UDDR3 with Nehalem, provided that they are on different | ||
1255 | * memory channels | ||
1256 | */ | ||
1257 | mci->mtype_cap = MEM_FLAG_DDR3; | ||
1253 | mci->edac_ctl_cap = EDAC_FLAG_NONE; | 1258 | mci->edac_ctl_cap = EDAC_FLAG_NONE; |
1254 | mci->edac_cap = EDAC_FLAG_NONE; | 1259 | mci->edac_cap = EDAC_FLAG_NONE; |
1255 | mci->mod_name = "i7core_edac.c"; | 1260 | mci->mod_name = "i7core_edac.c"; |
@@ -1263,7 +1268,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, | |||
1263 | 1268 | ||
1264 | /* Store pci devices at mci for faster access */ | 1269 | /* Store pci devices at mci for faster access */ |
1265 | rc = mci_bind_devs(mci); | 1270 | rc = mci_bind_devs(mci); |
1266 | if (unlikely (rc < 0)) | 1271 | if (unlikely(rc < 0)) |
1267 | goto fail1; | 1272 | goto fail1; |
1268 | 1273 | ||
1269 | /* Get dimm basic config */ | 1274 | /* Get dimm basic config */ |
@@ -1283,7 +1288,7 @@ static int __devinit i7core_probe(struct pci_dev *pdev, | |||
1283 | 1288 | ||
1284 | /* allocating generic PCI control info */ | 1289 | /* allocating generic PCI control info */ |
1285 | i7core_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR); | 1290 | i7core_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR); |
1286 | if (unlikely (!i7core_pci)) { | 1291 | if (unlikely(!i7core_pci)) { |
1287 | printk(KERN_WARNING | 1292 | printk(KERN_WARNING |
1288 | "%s(): Unable to create PCI control\n", | 1293 | "%s(): Unable to create PCI control\n", |
1289 | __func__); | 1294 | __func__); |