aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-26 13:13:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-26 13:13:48 -0400
commitda62aa69c181e3bd465a5c868ece166921a81e14 (patch)
tree5f1a3e234dd791099ba8761f79442b0ac6f664c0 /drivers/edac
parentf1ebdd60cc73ed36fd977f7e719ce70d2f5cd1c0 (diff)
parent76a7bd81130646459dfded1845e0d511488a6afa (diff)
Merge branch 'linux_next' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/i7core
* 'linux_next' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/i7core: (34 commits) i7core_edac: return -ENODEV when devices were already probed i7core_edac: properly terminate pci_dev_table i7core_edac: Avoid PCI refcount to reach zero on successive load/reload i7core_edac: Fix refcount error at PCI devices i7core_edac: it is safe to i7core_unregister_mci() when mci=NULL i7core_edac: Fix an oops at i7core probe i7core_edac: Remove unused member channels in i7core_pvt i7core_edac: Remove unused arg csrow from get_dimm_config i7core_edac: Reduce args of i7core_register_mci i7core_edac: Introduce i7core_unregister_mci i7core_edac: Use saved pointers i7core_edac: Check probe counter in i7core_remove i7core_edac: Call pci_dev_put() when alloc_i7core_dev() failed i7core_edac: Fix error path of i7core_register_mci i7core_edac: Fix order of lines in i7core_register_mci i7core_edac: Always do get/put for all devices i7core_edac: Introduce i7core_pci_ctl_create/release i7core_edac: Introduce free_i7core_dev i7core_edac: Introduce alloc_i7core_dev i7core_edac: Reduce args of i7core_get_onedevice ...
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/edac_core.h11
-rw-r--r--drivers/edac/edac_mc.c12
-rw-r--r--drivers/edac/edac_mc_sysfs.c82
-rw-r--r--drivers/edac/i7core_edac.c432
4 files changed, 313 insertions, 224 deletions
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index ce7146677e9b..d7ca43a828bd 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -42,8 +42,10 @@
42 42
43#if PAGE_SHIFT < 20 43#if PAGE_SHIFT < 20
44#define PAGES_TO_MiB( pages ) ( ( pages ) >> ( 20 - PAGE_SHIFT ) ) 44#define PAGES_TO_MiB( pages ) ( ( pages ) >> ( 20 - PAGE_SHIFT ) )
45#define MiB_TO_PAGES(mb) ((mb) >> (20 - PAGE_SHIFT))
45#else /* PAGE_SHIFT > 20 */ 46#else /* PAGE_SHIFT > 20 */
46#define PAGES_TO_MiB( pages ) ( ( pages ) << ( PAGE_SHIFT - 20 ) ) 47#define PAGES_TO_MiB( pages ) ( ( pages ) << ( PAGE_SHIFT - 20 ) )
48#define MiB_TO_PAGES(mb) ((mb) >> (PAGE_SHIFT - 20))
47#endif 49#endif
48 50
49#define edac_printk(level, prefix, fmt, arg...) \ 51#define edac_printk(level, prefix, fmt, arg...) \
@@ -328,7 +330,7 @@ struct csrow_info {
328 330
329struct mcidev_sysfs_group { 331struct mcidev_sysfs_group {
330 const char *name; /* group name */ 332 const char *name; /* group name */
331 struct mcidev_sysfs_attribute *mcidev_attr; /* group attributes */ 333 const struct mcidev_sysfs_attribute *mcidev_attr; /* group attributes */
332}; 334};
333 335
334struct mcidev_sysfs_group_kobj { 336struct mcidev_sysfs_group_kobj {
@@ -336,7 +338,7 @@ struct mcidev_sysfs_group_kobj {
336 338
337 struct kobject kobj; /* kobj for the group */ 339 struct kobject kobj; /* kobj for the group */
338 340
339 struct mcidev_sysfs_group *grp; /* group description table */ 341 const struct mcidev_sysfs_group *grp; /* group description table */
340 struct mem_ctl_info *mci; /* the parent */ 342 struct mem_ctl_info *mci; /* the parent */
341}; 343};
342 344
@@ -347,7 +349,7 @@ struct mcidev_sysfs_group_kobj {
347struct mcidev_sysfs_attribute { 349struct mcidev_sysfs_attribute {
348 /* It should use either attr or grp */ 350 /* It should use either attr or grp */
349 struct attribute attr; 351 struct attribute attr;
350 struct mcidev_sysfs_group *grp; /* Points to a group of attributes */ 352 const struct mcidev_sysfs_group *grp; /* Points to a group of attributes */
351 353
352 /* Ops for show/store values at the attribute - not used on group */ 354 /* Ops for show/store values at the attribute - not used on group */
353 ssize_t (*show)(struct mem_ctl_info *,char *); 355 ssize_t (*show)(struct mem_ctl_info *,char *);
@@ -440,7 +442,7 @@ struct mem_ctl_info {
440 * If attributes are desired, then set to array of attributes 442 * If attributes are desired, then set to array of attributes
441 * If no attributes are desired, leave NULL 443 * If no attributes are desired, leave NULL
442 */ 444 */
443 struct mcidev_sysfs_attribute *mc_driver_sysfs_attributes; 445 const struct mcidev_sysfs_attribute *mc_driver_sysfs_attributes;
444 446
445 /* work struct for this MC */ 447 /* work struct for this MC */
446 struct delayed_work work; 448 struct delayed_work work;
@@ -810,6 +812,7 @@ extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
810extern int edac_mc_add_mc(struct mem_ctl_info *mci); 812extern int edac_mc_add_mc(struct mem_ctl_info *mci);
811extern void edac_mc_free(struct mem_ctl_info *mci); 813extern void edac_mc_free(struct mem_ctl_info *mci);
812extern struct mem_ctl_info *edac_mc_find(int idx); 814extern struct mem_ctl_info *edac_mc_find(int idx);
815extern struct mem_ctl_info *find_mci_by_dev(struct device *dev);
813extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev); 816extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev);
814extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, 817extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
815 unsigned long page); 818 unsigned long page);
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 6b21e25f7a84..ba6586a69ccc 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -207,6 +207,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
207 } 207 }
208 208
209 mci->op_state = OP_ALLOC; 209 mci->op_state = OP_ALLOC;
210 INIT_LIST_HEAD(&mci->grp_kobj_list);
210 211
211 /* 212 /*
212 * Initialize the 'root' kobj for the edac_mc controller 213 * Initialize the 'root' kobj for the edac_mc controller
@@ -234,18 +235,24 @@ EXPORT_SYMBOL_GPL(edac_mc_alloc);
234 */ 235 */
235void edac_mc_free(struct mem_ctl_info *mci) 236void edac_mc_free(struct mem_ctl_info *mci)
236{ 237{
238 debugf1("%s()\n", __func__);
239
237 edac_mc_unregister_sysfs_main_kobj(mci); 240 edac_mc_unregister_sysfs_main_kobj(mci);
241
242 /* free the mci instance memory here */
243 kfree(mci);
238} 244}
239EXPORT_SYMBOL_GPL(edac_mc_free); 245EXPORT_SYMBOL_GPL(edac_mc_free);
240 246
241 247
242/* 248/**
243 * find_mci_by_dev 249 * find_mci_by_dev
244 * 250 *
245 * scan list of controllers looking for the one that manages 251 * scan list of controllers looking for the one that manages
246 * the 'dev' device 252 * the 'dev' device
253 * @dev: pointer to a struct device related with the MCI
247 */ 254 */
248static struct mem_ctl_info *find_mci_by_dev(struct device *dev) 255struct mem_ctl_info *find_mci_by_dev(struct device *dev)
249{ 256{
250 struct mem_ctl_info *mci; 257 struct mem_ctl_info *mci;
251 struct list_head *item; 258 struct list_head *item;
@@ -261,6 +268,7 @@ static struct mem_ctl_info *find_mci_by_dev(struct device *dev)
261 268
262 return NULL; 269 return NULL;
263} 270}
271EXPORT_SYMBOL_GPL(find_mci_by_dev);
264 272
265/* 273/*
266 * handler for EDAC to check if NMI type handler has asserted interrupt 274 * handler for EDAC to check if NMI type handler has asserted interrupt
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index a4135860149b..dce61f7ba38b 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -631,9 +631,6 @@ static void edac_mci_control_release(struct kobject *kobj)
631 631
632 /* decrement the module ref count */ 632 /* decrement the module ref count */
633 module_put(mci->owner); 633 module_put(mci->owner);
634
635 /* free the mci instance memory here */
636 kfree(mci);
637} 634}
638 635
639static struct kobj_type ktype_mci = { 636static struct kobj_type ktype_mci = {
@@ -713,6 +710,8 @@ fail_out:
713 */ 710 */
714void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci) 711void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci)
715{ 712{
713 debugf1("%s()\n", __func__);
714
716 /* delete the kobj from the mc_kset */ 715 /* delete the kobj from the mc_kset */
717 kobject_put(&mci->edac_mci_kobj); 716 kobject_put(&mci->edac_mci_kobj);
718} 717}
@@ -760,8 +759,6 @@ static void edac_inst_grp_release(struct kobject *kobj)
760 759
761 grp = container_of(kobj, struct mcidev_sysfs_group_kobj, kobj); 760 grp = container_of(kobj, struct mcidev_sysfs_group_kobj, kobj);
762 mci = grp->mci; 761 mci = grp->mci;
763
764 kobject_put(&mci->edac_mci_kobj);
765} 762}
766 763
767/* Intermediate show/store table */ 764/* Intermediate show/store table */
@@ -784,7 +781,7 @@ static struct kobj_type ktype_inst_grp = {
784 * object tree. 781 * object tree.
785 */ 782 */
786static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci, 783static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci,
787 struct mcidev_sysfs_attribute *sysfs_attrib, 784 const struct mcidev_sysfs_attribute *sysfs_attrib,
788 struct kobject *kobj) 785 struct kobject *kobj)
789{ 786{
790 int err; 787 int err;
@@ -792,6 +789,7 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci,
792 debugf1("%s()\n", __func__); 789 debugf1("%s()\n", __func__);
793 790
794 while (sysfs_attrib) { 791 while (sysfs_attrib) {
792 debugf1("%s() sysfs_attrib = %p\n",__func__, sysfs_attrib);
795 if (sysfs_attrib->grp) { 793 if (sysfs_attrib->grp) {
796 struct mcidev_sysfs_group_kobj *grp_kobj; 794 struct mcidev_sysfs_group_kobj *grp_kobj;
797 795
@@ -799,10 +797,9 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci,
799 if (!grp_kobj) 797 if (!grp_kobj)
800 return -ENOMEM; 798 return -ENOMEM;
801 799
802 list_add_tail(&grp_kobj->list, &mci->grp_kobj_list);
803
804 grp_kobj->grp = sysfs_attrib->grp; 800 grp_kobj->grp = sysfs_attrib->grp;
805 grp_kobj->mci = mci; 801 grp_kobj->mci = mci;
802 list_add_tail(&grp_kobj->list, &mci->grp_kobj_list);
806 803
807 debugf0("%s() grp %s, mci %p\n", __func__, 804 debugf0("%s() grp %s, mci %p\n", __func__,
808 sysfs_attrib->grp->name, mci); 805 sysfs_attrib->grp->name, mci);
@@ -811,26 +808,28 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci,
811 &ktype_inst_grp, 808 &ktype_inst_grp,
812 &mci->edac_mci_kobj, 809 &mci->edac_mci_kobj,
813 sysfs_attrib->grp->name); 810 sysfs_attrib->grp->name);
814 if (err) 811 if (err < 0) {
812 printk(KERN_ERR "kobject_init_and_add failed: %d\n", err);
815 return err; 813 return err;
816 814 }
817 err = edac_create_mci_instance_attributes(mci, 815 err = edac_create_mci_instance_attributes(mci,
818 grp_kobj->grp->mcidev_attr, 816 grp_kobj->grp->mcidev_attr,
819 &grp_kobj->kobj); 817 &grp_kobj->kobj);
820 818
821 if (err) 819 if (err < 0)
822 return err; 820 return err;
823 } else if (sysfs_attrib->attr.name) { 821 } else if (sysfs_attrib->attr.name) {
824 debugf0("%s() file %s\n", __func__, 822 debugf0("%s() file %s\n", __func__,
825 sysfs_attrib->attr.name); 823 sysfs_attrib->attr.name);
826 824
827 err = sysfs_create_file(kobj, &sysfs_attrib->attr); 825 err = sysfs_create_file(kobj, &sysfs_attrib->attr);
826 if (err < 0) {
827 printk(KERN_ERR "sysfs_create_file failed: %d\n", err);
828 return err;
829 }
828 } else 830 } else
829 break; 831 break;
830 832
831 if (err) {
832 return err;
833 }
834 sysfs_attrib++; 833 sysfs_attrib++;
835 } 834 }
836 835
@@ -843,7 +842,7 @@ static int edac_create_mci_instance_attributes(struct mem_ctl_info *mci,
843 * directory of this mci instance. 842 * directory of this mci instance.
844 */ 843 */
845static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci, 844static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci,
846 struct mcidev_sysfs_attribute *sysfs_attrib, 845 const struct mcidev_sysfs_attribute *sysfs_attrib,
847 struct kobject *kobj, int count) 846 struct kobject *kobj, int count)
848{ 847{
849 struct mcidev_sysfs_group_kobj *grp_kobj, *tmp; 848 struct mcidev_sysfs_group_kobj *grp_kobj, *tmp;
@@ -855,13 +854,24 @@ static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci,
855 * Remove first all the atributes 854 * Remove first all the atributes
856 */ 855 */
857 while (sysfs_attrib) { 856 while (sysfs_attrib) {
857 debugf1("%s() sysfs_attrib = %p\n",__func__, sysfs_attrib);
858 if (sysfs_attrib->grp) { 858 if (sysfs_attrib->grp) {
859 list_for_each_entry(grp_kobj, &mci->grp_kobj_list, 859 debugf1("%s() seeking for group %s\n",
860 list) 860 __func__, sysfs_attrib->grp->name);
861 if (grp_kobj->grp == sysfs_attrib->grp) 861 list_for_each_entry(grp_kobj,
862 &mci->grp_kobj_list, list) {
863 debugf1("%s() grp_kobj->grp = %p\n",__func__, grp_kobj->grp);
864 if (grp_kobj->grp == sysfs_attrib->grp) {
862 edac_remove_mci_instance_attributes(mci, 865 edac_remove_mci_instance_attributes(mci,
863 grp_kobj->grp->mcidev_attr, 866 grp_kobj->grp->mcidev_attr,
864 &grp_kobj->kobj, count + 1); 867 &grp_kobj->kobj, count + 1);
868 debugf0("%s() group %s\n", __func__,
869 sysfs_attrib->grp->name);
870 kobject_put(&grp_kobj->kobj);
871 }
872 }
873 debugf1("%s() end of seeking for group %s\n",
874 __func__, sysfs_attrib->grp->name);
865 } else if (sysfs_attrib->attr.name) { 875 } else if (sysfs_attrib->attr.name) {
866 debugf0("%s() file %s\n", __func__, 876 debugf0("%s() file %s\n", __func__,
867 sysfs_attrib->attr.name); 877 sysfs_attrib->attr.name);
@@ -871,15 +881,14 @@ static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci,
871 sysfs_attrib++; 881 sysfs_attrib++;
872 } 882 }
873 883
874 /* 884 /* Remove the group objects */
875 * Now that all attributes got removed, it is save to remove all groups 885 if (count)
876 */ 886 return;
877 if (!count) 887 list_for_each_entry_safe(grp_kobj, tmp,
878 list_for_each_entry_safe(grp_kobj, tmp, &mci->grp_kobj_list, 888 &mci->grp_kobj_list, list) {
879 list) { 889 list_del(&grp_kobj->list);
880 debugf0("%s() grp %s\n", __func__, grp_kobj->grp->name); 890 kfree(grp_kobj);
881 kobject_put(&grp_kobj->kobj); 891 }
882 }
883} 892}
884 893
885 894
@@ -971,6 +980,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
971 debugf0("%s()\n", __func__); 980 debugf0("%s()\n", __func__);
972 981
973 /* remove all csrow kobjects */ 982 /* remove all csrow kobjects */
983 debugf0("%s() unregister this mci kobj\n", __func__);
974 for (i = 0; i < mci->nr_csrows; i++) { 984 for (i = 0; i < mci->nr_csrows; i++) {
975 if (mci->csrows[i].nr_pages > 0) { 985 if (mci->csrows[i].nr_pages > 0) {
976 debugf0("%s() unreg csrow-%d\n", __func__, i); 986 debugf0("%s() unreg csrow-%d\n", __func__, i);
@@ -978,20 +988,20 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
978 } 988 }
979 } 989 }
980 990
981 debugf0("%s() remove_link\n", __func__); 991 /* remove this mci instance's attribtes */
992 if (mci->mc_driver_sysfs_attributes) {
993 debugf0("%s() unregister mci private attributes\n", __func__);
994 edac_remove_mci_instance_attributes(mci,
995 mci->mc_driver_sysfs_attributes,
996 &mci->edac_mci_kobj, 0);
997 }
982 998
983 /* remove the symlink */ 999 /* remove the symlink */
1000 debugf0("%s() remove_link\n", __func__);
984 sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK); 1001 sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK);
985 1002
986 debugf0("%s() remove_mci_instance\n", __func__);
987
988 /* remove this mci instance's attribtes */
989 edac_remove_mci_instance_attributes(mci,
990 mci->mc_driver_sysfs_attributes,
991 &mci->edac_mci_kobj, 0);
992 debugf0("%s() unregister this mci kobj\n", __func__);
993
994 /* unregister this instance's kobject */ 1003 /* unregister this instance's kobject */
1004 debugf0("%s() remove_mci_instance\n", __func__);
995 kobject_put(&mci->edac_mci_kobj); 1005 kobject_put(&mci->edac_mci_kobj);
996} 1006}
997 1007
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 0fd5b85a0f75..362861c15779 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -39,6 +39,14 @@
39 39
40#include "edac_core.h" 40#include "edac_core.h"
41 41
42/* Static vars */
43static LIST_HEAD(i7core_edac_list);
44static DEFINE_MUTEX(i7core_edac_lock);
45static int probed;
46
47static int use_pci_fixup;
48module_param(use_pci_fixup, int, 0444);
49MODULE_PARM_DESC(use_pci_fixup, "Enable PCI fixup to seek for hidden devices");
42/* 50/*
43 * This is used for Nehalem-EP and Nehalem-EX devices, where the non-core 51 * This is used for Nehalem-EP and Nehalem-EX devices, where the non-core
44 * registers start at bus 255, and are not reported by BIOS. 52 * registers start at bus 255, and are not reported by BIOS.
@@ -212,8 +220,8 @@ struct pci_id_descr {
212}; 220};
213 221
214struct pci_id_table { 222struct pci_id_table {
215 struct pci_id_descr *descr; 223 const struct pci_id_descr *descr;
216 int n_devs; 224 int n_devs;
217}; 225};
218 226
219struct i7core_dev { 227struct i7core_dev {
@@ -235,8 +243,6 @@ struct i7core_pvt {
235 struct i7core_inject inject; 243 struct i7core_inject inject;
236 struct i7core_channel channel[NUM_CHANS]; 244 struct i7core_channel channel[NUM_CHANS];
237 245
238 int channels; /* Number of active channels */
239
240 int ce_count_available; 246 int ce_count_available;
241 int csrow_map[NUM_CHANS][MAX_DIMMS]; 247 int csrow_map[NUM_CHANS][MAX_DIMMS];
242 248
@@ -261,22 +267,22 @@ struct i7core_pvt {
261 267
262 /* Count indicator to show errors not got */ 268 /* Count indicator to show errors not got */
263 unsigned mce_overrun; 269 unsigned mce_overrun;
264};
265 270
266/* Static vars */ 271 /* Struct to control EDAC polling */
267static LIST_HEAD(i7core_edac_list); 272 struct edac_pci_ctl_info *i7core_pci;
268static DEFINE_MUTEX(i7core_edac_lock); 273};
269 274
270#define PCI_DESCR(device, function, device_id) \ 275#define PCI_DESCR(device, function, device_id) \
271 .dev = (device), \ 276 .dev = (device), \
272 .func = (function), \ 277 .func = (function), \
273 .dev_id = (device_id) 278 .dev_id = (device_id)
274 279
275struct pci_id_descr pci_dev_descr_i7core_nehalem[] = { 280static const struct pci_id_descr pci_dev_descr_i7core_nehalem[] = {
276 /* Memory controller */ 281 /* Memory controller */
277 { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) }, 282 { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR) },
278 { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) }, 283 { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD) },
279 /* Exists only for RDIMM */ 284
285 /* Exists only for RDIMM */
280 { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS), .optional = 1 }, 286 { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS), .optional = 1 },
281 { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) }, 287 { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) },
282 288
@@ -297,19 +303,9 @@ struct pci_id_descr pci_dev_descr_i7core_nehalem[] = {
297 { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR) }, 303 { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR) },
298 { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK) }, 304 { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK) },
299 { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC) }, 305 { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC) },
300
301 /* Generic Non-core registers */
302 /*
303 * This is the PCI device on i7core and on Xeon 35xx (8086:2c41)
304 * On Xeon 55xx, however, it has a different id (8086:2c40). So,
305 * the probing code needs to test for the other address in case of
306 * failure of this one
307 */
308 { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_I7_NONCORE) },
309
310}; 306};
311 307
312struct pci_id_descr pci_dev_descr_lynnfield[] = { 308static const struct pci_id_descr pci_dev_descr_lynnfield[] = {
313 { PCI_DESCR( 3, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR) }, 309 { PCI_DESCR( 3, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR) },
314 { PCI_DESCR( 3, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD) }, 310 { PCI_DESCR( 3, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD) },
315 { PCI_DESCR( 3, 4, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST) }, 311 { PCI_DESCR( 3, 4, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TEST) },
@@ -323,15 +319,9 @@ struct pci_id_descr pci_dev_descr_lynnfield[] = {
323 { PCI_DESCR( 5, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR) }, 319 { PCI_DESCR( 5, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_ADDR) },
324 { PCI_DESCR( 5, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK) }, 320 { PCI_DESCR( 5, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_RANK) },
325 { PCI_DESCR( 5, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC) }, 321 { PCI_DESCR( 5, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH1_TC) },
326
327 /*
328 * This is the PCI device has an alternate address on some
329 * processors like Core i7 860
330 */
331 { PCI_DESCR( 0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE) },
332}; 322};
333 323
334struct pci_id_descr pci_dev_descr_i7core_westmere[] = { 324static const struct pci_id_descr pci_dev_descr_i7core_westmere[] = {
335 /* Memory controller */ 325 /* Memory controller */
336 { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR_REV2) }, 326 { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_MCR_REV2) },
337 { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD_REV2) }, 327 { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_TAD_REV2) },
@@ -356,17 +346,14 @@ struct pci_id_descr pci_dev_descr_i7core_westmere[] = {
356 { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_ADDR_REV2) }, 346 { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_ADDR_REV2) },
357 { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_RANK_REV2) }, 347 { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_RANK_REV2) },
358 { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_TC_REV2) }, 348 { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_LYNNFIELD_MC_CH2_TC_REV2) },
359
360 /* Generic Non-core registers */
361 { PCI_DESCR(0, 0, PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_REV2) },
362
363}; 349};
364 350
365#define PCI_ID_TABLE_ENTRY(A) { A, ARRAY_SIZE(A) } 351#define PCI_ID_TABLE_ENTRY(A) { .descr=A, .n_devs = ARRAY_SIZE(A) }
366struct pci_id_table pci_dev_table[] = { 352static const struct pci_id_table pci_dev_table[] = {
367 PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_nehalem), 353 PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_nehalem),
368 PCI_ID_TABLE_ENTRY(pci_dev_descr_lynnfield), 354 PCI_ID_TABLE_ENTRY(pci_dev_descr_lynnfield),
369 PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_westmere), 355 PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_westmere),
356 {0,} /* 0 terminated list. */
370}; 357};
371 358
372/* 359/*
@@ -378,8 +365,6 @@ static const struct pci_device_id i7core_pci_tbl[] __devinitdata = {
378 {0,} /* 0 terminated list. */ 365 {0,} /* 0 terminated list. */
379}; 366};
380 367
381static struct edac_pci_ctl_info *i7core_pci;
382
383/**************************************************************************** 368/****************************************************************************
384 Anciliary status routines 369 Anciliary status routines
385 ****************************************************************************/ 370 ****************************************************************************/
@@ -442,6 +427,36 @@ static struct i7core_dev *get_i7core_dev(u8 socket)
442 return NULL; 427 return NULL;
443} 428}
444 429
430static struct i7core_dev *alloc_i7core_dev(u8 socket,
431 const struct pci_id_table *table)
432{
433 struct i7core_dev *i7core_dev;
434
435 i7core_dev = kzalloc(sizeof(*i7core_dev), GFP_KERNEL);
436 if (!i7core_dev)
437 return NULL;
438
439 i7core_dev->pdev = kzalloc(sizeof(*i7core_dev->pdev) * table->n_devs,
440 GFP_KERNEL);
441 if (!i7core_dev->pdev) {
442 kfree(i7core_dev);
443 return NULL;
444 }
445
446 i7core_dev->socket = socket;
447 i7core_dev->n_devs = table->n_devs;
448 list_add_tail(&i7core_dev->list, &i7core_edac_list);
449
450 return i7core_dev;
451}
452
453static void free_i7core_dev(struct i7core_dev *i7core_dev)
454{
455 list_del(&i7core_dev->list);
456 kfree(i7core_dev->pdev);
457 kfree(i7core_dev);
458}
459
445/**************************************************************************** 460/****************************************************************************
446 Memory check routines 461 Memory check routines
447 ****************************************************************************/ 462 ****************************************************************************/
@@ -484,7 +499,7 @@ static struct pci_dev *get_pdev_slot_func(u8 socket, unsigned slot,
484 * to add a fake description for csrows. 499 * to add a fake description for csrows.
485 * So, this driver is attributing one DIMM memory for one csrow. 500 * So, this driver is attributing one DIMM memory for one csrow.
486 */ 501 */
487static int i7core_get_active_channels(u8 socket, unsigned *channels, 502static int i7core_get_active_channels(const u8 socket, unsigned *channels,
488 unsigned *csrows) 503 unsigned *csrows)
489{ 504{
490 struct pci_dev *pdev = NULL; 505 struct pci_dev *pdev = NULL;
@@ -545,12 +560,13 @@ static int i7core_get_active_channels(u8 socket, unsigned *channels,
545 return 0; 560 return 0;
546} 561}
547 562
548static int get_dimm_config(struct mem_ctl_info *mci, int *csrow) 563static int get_dimm_config(const struct mem_ctl_info *mci)
549{ 564{
550 struct i7core_pvt *pvt = mci->pvt_info; 565 struct i7core_pvt *pvt = mci->pvt_info;
551 struct csrow_info *csr; 566 struct csrow_info *csr;
552 struct pci_dev *pdev; 567 struct pci_dev *pdev;
553 int i, j; 568 int i, j;
569 int csrow = 0;
554 unsigned long last_page = 0; 570 unsigned long last_page = 0;
555 enum edac_type mode; 571 enum edac_type mode;
556 enum mem_type mtype; 572 enum mem_type mtype;
@@ -664,13 +680,9 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow)
664 RANKOFFSET(dimm_dod[j]), 680 RANKOFFSET(dimm_dod[j]),
665 banks, ranks, rows, cols); 681 banks, ranks, rows, cols);
666 682
667#if PAGE_SHIFT > 20 683 npages = MiB_TO_PAGES(size);
668 npages = size >> (PAGE_SHIFT - 20);
669#else
670 npages = size << (20 - PAGE_SHIFT);
671#endif
672 684
673 csr = &mci->csrows[*csrow]; 685 csr = &mci->csrows[csrow];
674 csr->first_page = last_page + 1; 686 csr->first_page = last_page + 1;
675 last_page += npages; 687 last_page += npages;
676 csr->last_page = last_page; 688 csr->last_page = last_page;
@@ -678,13 +690,13 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow)
678 690
679 csr->page_mask = 0; 691 csr->page_mask = 0;
680 csr->grain = 8; 692 csr->grain = 8;
681 csr->csrow_idx = *csrow; 693 csr->csrow_idx = csrow;
682 csr->nr_channels = 1; 694 csr->nr_channels = 1;
683 695
684 csr->channels[0].chan_idx = i; 696 csr->channels[0].chan_idx = i;
685 csr->channels[0].ce_count = 0; 697 csr->channels[0].ce_count = 0;
686 698
687 pvt->csrow_map[i][j] = *csrow; 699 pvt->csrow_map[i][j] = csrow;
688 700
689 switch (banks) { 701 switch (banks) {
690 case 4: 702 case 4:
@@ -703,7 +715,7 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow)
703 csr->edac_mode = mode; 715 csr->edac_mode = mode;
704 csr->mtype = mtype; 716 csr->mtype = mtype;
705 717
706 (*csrow)++; 718 csrow++;
707 } 719 }
708 720
709 pci_read_config_dword(pdev, MC_SAG_CH_0, &value[0]); 721 pci_read_config_dword(pdev, MC_SAG_CH_0, &value[0]);
@@ -736,7 +748,7 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow)
736 we're disabling error injection on all write calls to the sysfs nodes that 748 we're disabling error injection on all write calls to the sysfs nodes that
737 controls the error code injection. 749 controls the error code injection.
738 */ 750 */
739static int disable_inject(struct mem_ctl_info *mci) 751static int disable_inject(const struct mem_ctl_info *mci)
740{ 752{
741 struct i7core_pvt *pvt = mci->pvt_info; 753 struct i7core_pvt *pvt = mci->pvt_info;
742 754
@@ -921,7 +933,7 @@ DECLARE_ADDR_MATCH(bank, 32);
921DECLARE_ADDR_MATCH(page, 0x10000); 933DECLARE_ADDR_MATCH(page, 0x10000);
922DECLARE_ADDR_MATCH(col, 0x4000); 934DECLARE_ADDR_MATCH(col, 0x4000);
923 935
924static int write_and_test(struct pci_dev *dev, int where, u32 val) 936static int write_and_test(struct pci_dev *dev, const int where, const u32 val)
925{ 937{
926 u32 read; 938 u32 read;
927 int count; 939 int count;
@@ -1120,35 +1132,34 @@ DECLARE_COUNTER(2);
1120 * Sysfs struct 1132 * Sysfs struct
1121 */ 1133 */
1122 1134
1123 1135static const struct mcidev_sysfs_attribute i7core_addrmatch_attrs[] = {
1124static struct mcidev_sysfs_attribute i7core_addrmatch_attrs[] = {
1125 ATTR_ADDR_MATCH(channel), 1136 ATTR_ADDR_MATCH(channel),
1126 ATTR_ADDR_MATCH(dimm), 1137 ATTR_ADDR_MATCH(dimm),
1127 ATTR_ADDR_MATCH(rank), 1138 ATTR_ADDR_MATCH(rank),
1128 ATTR_ADDR_MATCH(bank), 1139 ATTR_ADDR_MATCH(bank),
1129 ATTR_ADDR_MATCH(page), 1140 ATTR_ADDR_MATCH(page),
1130 ATTR_ADDR_MATCH(col), 1141 ATTR_ADDR_MATCH(col),
1131 { .attr = { .name = NULL } } 1142 { } /* End of list */
1132}; 1143};
1133 1144
1134static struct mcidev_sysfs_group i7core_inject_addrmatch = { 1145static const struct mcidev_sysfs_group i7core_inject_addrmatch = {
1135 .name = "inject_addrmatch", 1146 .name = "inject_addrmatch",
1136 .mcidev_attr = i7core_addrmatch_attrs, 1147 .mcidev_attr = i7core_addrmatch_attrs,
1137}; 1148};
1138 1149
1139static struct mcidev_sysfs_attribute i7core_udimm_counters_attrs[] = { 1150static const struct mcidev_sysfs_attribute i7core_udimm_counters_attrs[] = {
1140 ATTR_COUNTER(0), 1151 ATTR_COUNTER(0),
1141 ATTR_COUNTER(1), 1152 ATTR_COUNTER(1),
1142 ATTR_COUNTER(2), 1153 ATTR_COUNTER(2),
1143 { .attr = { .name = NULL } } 1154 { .attr = { .name = NULL } }
1144}; 1155};
1145 1156
1146static struct mcidev_sysfs_group i7core_udimm_counters = { 1157static const struct mcidev_sysfs_group i7core_udimm_counters = {
1147 .name = "all_channel_counts", 1158 .name = "all_channel_counts",
1148 .mcidev_attr = i7core_udimm_counters_attrs, 1159 .mcidev_attr = i7core_udimm_counters_attrs,
1149}; 1160};
1150 1161
1151static struct mcidev_sysfs_attribute i7core_sysfs_attrs[] = { 1162static const struct mcidev_sysfs_attribute i7core_sysfs_rdimm_attrs[] = {
1152 { 1163 {
1153 .attr = { 1164 .attr = {
1154 .name = "inject_section", 1165 .name = "inject_section",
@@ -1180,8 +1191,44 @@ static struct mcidev_sysfs_attribute i7core_sysfs_attrs[] = {
1180 .show = i7core_inject_enable_show, 1191 .show = i7core_inject_enable_show,
1181 .store = i7core_inject_enable_store, 1192 .store = i7core_inject_enable_store,
1182 }, 1193 },
1183 { .attr = { .name = NULL } }, /* Reserved for udimm counters */ 1194 { } /* End of list */
1184 { .attr = { .name = NULL } } 1195};
1196
1197static const struct mcidev_sysfs_attribute i7core_sysfs_udimm_attrs[] = {
1198 {
1199 .attr = {
1200 .name = "inject_section",
1201 .mode = (S_IRUGO | S_IWUSR)
1202 },
1203 .show = i7core_inject_section_show,
1204 .store = i7core_inject_section_store,
1205 }, {
1206 .attr = {
1207 .name = "inject_type",
1208 .mode = (S_IRUGO | S_IWUSR)
1209 },
1210 .show = i7core_inject_type_show,
1211 .store = i7core_inject_type_store,
1212 }, {
1213 .attr = {
1214 .name = "inject_eccmask",
1215 .mode = (S_IRUGO | S_IWUSR)
1216 },
1217 .show = i7core_inject_eccmask_show,
1218 .store = i7core_inject_eccmask_store,
1219 }, {
1220 .grp = &i7core_inject_addrmatch,
1221 }, {
1222 .attr = {
1223 .name = "inject_enable",
1224 .mode = (S_IRUGO | S_IWUSR)
1225 },
1226 .show = i7core_inject_enable_show,
1227 .store = i7core_inject_enable_store,
1228 }, {
1229 .grp = &i7core_udimm_counters,
1230 },
1231 { } /* End of list */
1185}; 1232};
1186 1233
1187/**************************************************************************** 1234/****************************************************************************
@@ -1189,7 +1236,7 @@ static struct mcidev_sysfs_attribute i7core_sysfs_attrs[] = {
1189 ****************************************************************************/ 1236 ****************************************************************************/
1190 1237
1191/* 1238/*
1192 * i7core_put_devices 'put' all the devices that we have 1239 * i7core_put_all_devices 'put' all the devices that we have
1193 * reserved via 'get' 1240 * reserved via 'get'
1194 */ 1241 */
1195static void i7core_put_devices(struct i7core_dev *i7core_dev) 1242static void i7core_put_devices(struct i7core_dev *i7core_dev)
@@ -1206,23 +1253,23 @@ static void i7core_put_devices(struct i7core_dev *i7core_dev)
1206 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); 1253 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
1207 pci_dev_put(pdev); 1254 pci_dev_put(pdev);
1208 } 1255 }
1209 kfree(i7core_dev->pdev);
1210 list_del(&i7core_dev->list);
1211 kfree(i7core_dev);
1212} 1256}
1213 1257
1214static void i7core_put_all_devices(void) 1258static void i7core_put_all_devices(void)
1215{ 1259{
1216 struct i7core_dev *i7core_dev, *tmp; 1260 struct i7core_dev *i7core_dev, *tmp;
1217 1261
1218 list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list) 1262 list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list) {
1219 i7core_put_devices(i7core_dev); 1263 i7core_put_devices(i7core_dev);
1264 free_i7core_dev(i7core_dev);
1265 }
1220} 1266}
1221 1267
1222static void __init i7core_xeon_pci_fixup(struct pci_id_table *table) 1268static void __init i7core_xeon_pci_fixup(const struct pci_id_table *table)
1223{ 1269{
1224 struct pci_dev *pdev = NULL; 1270 struct pci_dev *pdev = NULL;
1225 int i; 1271 int i;
1272
1226 /* 1273 /*
1227 * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core pci buses 1274 * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core pci buses
1228 * aren't announced by acpi. So, we need to use a legacy scan probing 1275 * aren't announced by acpi. So, we need to use a legacy scan probing
@@ -1257,16 +1304,18 @@ static unsigned i7core_pci_lastbus(void)
1257} 1304}
1258 1305
1259/* 1306/*
1260 * i7core_get_devices Find and perform 'get' operation on the MCH's 1307 * i7core_get_all_devices Find and perform 'get' operation on the MCH's
1261 * device/functions we want to reference for this driver 1308 * device/functions we want to reference for this driver
1262 * 1309 *
1263 * Need to 'get' device 16 func 1 and func 2 1310 * Need to 'get' device 16 func 1 and func 2
1264 */ 1311 */
1265int i7core_get_onedevice(struct pci_dev **prev, int devno, 1312static int i7core_get_onedevice(struct pci_dev **prev,
1266 struct pci_id_descr *dev_descr, unsigned n_devs, 1313 const struct pci_id_table *table,
1267 unsigned last_bus) 1314 const unsigned devno,
1315 const unsigned last_bus)
1268{ 1316{
1269 struct i7core_dev *i7core_dev; 1317 struct i7core_dev *i7core_dev;
1318 const struct pci_id_descr *dev_descr = &table->descr[devno];
1270 1319
1271 struct pci_dev *pdev = NULL; 1320 struct pci_dev *pdev = NULL;
1272 u8 bus = 0; 1321 u8 bus = 0;
@@ -1275,20 +1324,6 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno,
1275 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 1324 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1276 dev_descr->dev_id, *prev); 1325 dev_descr->dev_id, *prev);
1277 1326
1278 /*
1279 * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core regs
1280 * is at addr 8086:2c40, instead of 8086:2c41. So, we need
1281 * to probe for the alternate address in case of failure
1282 */
1283 if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev)
1284 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1285 PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev);
1286
1287 if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev)
1288 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1289 PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT,
1290 *prev);
1291
1292 if (!pdev) { 1327 if (!pdev) {
1293 if (*prev) { 1328 if (*prev) {
1294 *prev = pdev; 1329 *prev = pdev;
@@ -1315,18 +1350,11 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno,
1315 1350
1316 i7core_dev = get_i7core_dev(socket); 1351 i7core_dev = get_i7core_dev(socket);
1317 if (!i7core_dev) { 1352 if (!i7core_dev) {
1318 i7core_dev = kzalloc(sizeof(*i7core_dev), GFP_KERNEL); 1353 i7core_dev = alloc_i7core_dev(socket, table);
1319 if (!i7core_dev) 1354 if (!i7core_dev) {
1320 return -ENOMEM; 1355 pci_dev_put(pdev);
1321 i7core_dev->pdev = kzalloc(sizeof(*i7core_dev->pdev) * n_devs,
1322 GFP_KERNEL);
1323 if (!i7core_dev->pdev) {
1324 kfree(i7core_dev);
1325 return -ENOMEM; 1356 return -ENOMEM;
1326 } 1357 }
1327 i7core_dev->socket = socket;
1328 i7core_dev->n_devs = n_devs;
1329 list_add_tail(&i7core_dev->list, &i7core_edac_list);
1330 } 1358 }
1331 1359
1332 if (i7core_dev->pdev[devno]) { 1360 if (i7core_dev->pdev[devno]) {
@@ -1368,27 +1396,31 @@ int i7core_get_onedevice(struct pci_dev **prev, int devno,
1368 dev_descr->func, 1396 dev_descr->func,
1369 PCI_VENDOR_ID_INTEL, dev_descr->dev_id); 1397 PCI_VENDOR_ID_INTEL, dev_descr->dev_id);
1370 1398
1399 /*
1400 * As stated on drivers/pci/search.c, the reference count for
1401 * @from is always decremented if it is not %NULL. So, as we need
1402 * to get all devices up to null, we need to do a get for the device
1403 */
1404 pci_dev_get(pdev);
1405
1371 *prev = pdev; 1406 *prev = pdev;
1372 1407
1373 return 0; 1408 return 0;
1374} 1409}
1375 1410
1376static int i7core_get_devices(struct pci_id_table *table) 1411static int i7core_get_all_devices(void)
1377{ 1412{
1378 int i, rc, last_bus; 1413 int i, rc, last_bus;
1379 struct pci_dev *pdev = NULL; 1414 struct pci_dev *pdev = NULL;
1380 struct pci_id_descr *dev_descr; 1415 const struct pci_id_table *table = pci_dev_table;
1381 1416
1382 last_bus = i7core_pci_lastbus(); 1417 last_bus = i7core_pci_lastbus();
1383 1418
1384 while (table && table->descr) { 1419 while (table && table->descr) {
1385 dev_descr = table->descr;
1386 for (i = 0; i < table->n_devs; i++) { 1420 for (i = 0; i < table->n_devs; i++) {
1387 pdev = NULL; 1421 pdev = NULL;
1388 do { 1422 do {
1389 rc = i7core_get_onedevice(&pdev, i, 1423 rc = i7core_get_onedevice(&pdev, table, i,
1390 &dev_descr[i],
1391 table->n_devs,
1392 last_bus); 1424 last_bus);
1393 if (rc < 0) { 1425 if (rc < 0) {
1394 if (i == 0) { 1426 if (i == 0) {
@@ -1404,7 +1436,6 @@ static int i7core_get_devices(struct pci_id_table *table)
1404 } 1436 }
1405 1437
1406 return 0; 1438 return 0;
1407 return 0;
1408} 1439}
1409 1440
1410static int mci_bind_devs(struct mem_ctl_info *mci, 1441static int mci_bind_devs(struct mem_ctl_info *mci,
@@ -1414,10 +1445,6 @@ static int mci_bind_devs(struct mem_ctl_info *mci,
1414 struct pci_dev *pdev; 1445 struct pci_dev *pdev;
1415 int i, func, slot; 1446 int i, func, slot;
1416 1447
1417 /* Associates i7core_dev and mci for future usage */
1418 pvt->i7core_dev = i7core_dev;
1419 i7core_dev->mci = mci;
1420
1421 pvt->is_registered = 0; 1448 pvt->is_registered = 0;
1422 for (i = 0; i < i7core_dev->n_devs; i++) { 1449 for (i = 0; i < i7core_dev->n_devs; i++) {
1423 pdev = i7core_dev->pdev[i]; 1450 pdev = i7core_dev->pdev[i];
@@ -1448,15 +1475,6 @@ static int mci_bind_devs(struct mem_ctl_info *mci,
1448 pvt->is_registered = 1; 1475 pvt->is_registered = 1;
1449 } 1476 }
1450 1477
1451 /*
1452 * Add extra nodes to count errors on udimm
1453 * For registered memory, this is not needed, since the counters
1454 * are already displayed at the standard locations
1455 */
1456 if (!pvt->is_registered)
1457 i7core_sysfs_attrs[ARRAY_SIZE(i7core_sysfs_attrs)-2].grp =
1458 &i7core_udimm_counters;
1459
1460 return 0; 1478 return 0;
1461 1479
1462error: 1480error:
@@ -1470,7 +1488,9 @@ error:
1470 Error check routines 1488 Error check routines
1471 ****************************************************************************/ 1489 ****************************************************************************/
1472static void i7core_rdimm_update_csrow(struct mem_ctl_info *mci, 1490static void i7core_rdimm_update_csrow(struct mem_ctl_info *mci,
1473 int chan, int dimm, int add) 1491 const int chan,
1492 const int dimm,
1493 const int add)
1474{ 1494{
1475 char *msg; 1495 char *msg;
1476 struct i7core_pvt *pvt = mci->pvt_info; 1496 struct i7core_pvt *pvt = mci->pvt_info;
@@ -1487,7 +1507,10 @@ static void i7core_rdimm_update_csrow(struct mem_ctl_info *mci,
1487} 1507}
1488 1508
1489static void i7core_rdimm_update_ce_count(struct mem_ctl_info *mci, 1509static void i7core_rdimm_update_ce_count(struct mem_ctl_info *mci,
1490 int chan, int new0, int new1, int new2) 1510 const int chan,
1511 const int new0,
1512 const int new1,
1513 const int new2)
1491{ 1514{
1492 struct i7core_pvt *pvt = mci->pvt_info; 1515 struct i7core_pvt *pvt = mci->pvt_info;
1493 int add0 = 0, add1 = 0, add2 = 0; 1516 int add0 = 0, add1 = 0, add2 = 0;
@@ -1641,7 +1664,7 @@ static void i7core_udimm_check_mc_ecc_err(struct mem_ctl_info *mci)
1641 * fields 1664 * fields
1642 */ 1665 */
1643static void i7core_mce_output_error(struct mem_ctl_info *mci, 1666static void i7core_mce_output_error(struct mem_ctl_info *mci,
1644 struct mce *m) 1667 const struct mce *m)
1645{ 1668{
1646 struct i7core_pvt *pvt = mci->pvt_info; 1669 struct i7core_pvt *pvt = mci->pvt_info;
1647 char *type, *optype, *err, *msg; 1670 char *type, *optype, *err, *msg;
@@ -1845,28 +1868,85 @@ static int i7core_mce_check_error(void *priv, struct mce *mce)
1845 return 1; 1868 return 1;
1846} 1869}
1847 1870
1848static int i7core_register_mci(struct i7core_dev *i7core_dev, 1871static void i7core_pci_ctl_create(struct i7core_pvt *pvt)
1849 int num_channels, int num_csrows) 1872{
1873 pvt->i7core_pci = edac_pci_create_generic_ctl(
1874 &pvt->i7core_dev->pdev[0]->dev,
1875 EDAC_MOD_STR);
1876 if (unlikely(!pvt->i7core_pci))
1877 pr_warn("Unable to setup PCI error report via EDAC\n");
1878}
1879
1880static void i7core_pci_ctl_release(struct i7core_pvt *pvt)
1881{
1882 if (likely(pvt->i7core_pci))
1883 edac_pci_release_generic_ctl(pvt->i7core_pci);
1884 else
1885 i7core_printk(KERN_ERR,
1886 "Couldn't find mem_ctl_info for socket %d\n",
1887 pvt->i7core_dev->socket);
1888 pvt->i7core_pci = NULL;
1889}
1890
1891static void i7core_unregister_mci(struct i7core_dev *i7core_dev)
1892{
1893 struct mem_ctl_info *mci = i7core_dev->mci;
1894 struct i7core_pvt *pvt;
1895
1896 if (unlikely(!mci || !mci->pvt_info)) {
1897 debugf0("MC: " __FILE__ ": %s(): dev = %p\n",
1898 __func__, &i7core_dev->pdev[0]->dev);
1899
1900 i7core_printk(KERN_ERR, "Couldn't find mci handler\n");
1901 return;
1902 }
1903
1904 pvt = mci->pvt_info;
1905
1906 debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n",
1907 __func__, mci, &i7core_dev->pdev[0]->dev);
1908
1909 /* Disable MCE NMI handler */
1910 edac_mce_unregister(&pvt->edac_mce);
1911
1912 /* Disable EDAC polling */
1913 i7core_pci_ctl_release(pvt);
1914
1915 /* Remove MC sysfs nodes */
1916 edac_mc_del_mc(mci->dev);
1917
1918 debugf1("%s: free mci struct\n", mci->ctl_name);
1919 kfree(mci->ctl_name);
1920 edac_mc_free(mci);
1921 i7core_dev->mci = NULL;
1922}
1923
1924static int i7core_register_mci(struct i7core_dev *i7core_dev)
1850{ 1925{
1851 struct mem_ctl_info *mci; 1926 struct mem_ctl_info *mci;
1852 struct i7core_pvt *pvt; 1927 struct i7core_pvt *pvt;
1853 int csrow = 0; 1928 int rc, channels, csrows;
1854 int rc; 1929
1930 /* Check the number of active and not disabled channels */
1931 rc = i7core_get_active_channels(i7core_dev->socket, &channels, &csrows);
1932 if (unlikely(rc < 0))
1933 return rc;
1855 1934
1856 /* allocate a new MC control structure */ 1935 /* allocate a new MC control structure */
1857 mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 1936 mci = edac_mc_alloc(sizeof(*pvt), csrows, channels, i7core_dev->socket);
1858 i7core_dev->socket);
1859 if (unlikely(!mci)) 1937 if (unlikely(!mci))
1860 return -ENOMEM; 1938 return -ENOMEM;
1861 1939
1862 debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); 1940 debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n",
1863 1941 __func__, mci, &i7core_dev->pdev[0]->dev);
1864 /* record ptr to the generic device */
1865 mci->dev = &i7core_dev->pdev[0]->dev;
1866 1942
1867 pvt = mci->pvt_info; 1943 pvt = mci->pvt_info;
1868 memset(pvt, 0, sizeof(*pvt)); 1944 memset(pvt, 0, sizeof(*pvt));
1869 1945
1946 /* Associates i7core_dev and mci for future usage */
1947 pvt->i7core_dev = i7core_dev;
1948 i7core_dev->mci = mci;
1949
1870 /* 1950 /*
1871 * FIXME: how to handle RDDR3 at MCI level? It is possible to have 1951 * FIXME: how to handle RDDR3 at MCI level? It is possible to have
1872 * Mixed RDDR3/UDDR3 with Nehalem, provided that they are on different 1952 * Mixed RDDR3/UDDR3 with Nehalem, provided that they are on different
@@ -1881,17 +1961,23 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev,
1881 i7core_dev->socket); 1961 i7core_dev->socket);
1882 mci->dev_name = pci_name(i7core_dev->pdev[0]); 1962 mci->dev_name = pci_name(i7core_dev->pdev[0]);
1883 mci->ctl_page_to_phys = NULL; 1963 mci->ctl_page_to_phys = NULL;
1884 mci->mc_driver_sysfs_attributes = i7core_sysfs_attrs;
1885 /* Set the function pointer to an actual operation function */
1886 mci->edac_check = i7core_check_error;
1887 1964
1888 /* Store pci devices at mci for faster access */ 1965 /* Store pci devices at mci for faster access */
1889 rc = mci_bind_devs(mci, i7core_dev); 1966 rc = mci_bind_devs(mci, i7core_dev);
1890 if (unlikely(rc < 0)) 1967 if (unlikely(rc < 0))
1891 goto fail; 1968 goto fail0;
1969
1970 if (pvt->is_registered)
1971 mci->mc_driver_sysfs_attributes = i7core_sysfs_rdimm_attrs;
1972 else
1973 mci->mc_driver_sysfs_attributes = i7core_sysfs_udimm_attrs;
1892 1974
1893 /* Get dimm basic config */ 1975 /* Get dimm basic config */
1894 get_dimm_config(mci, &csrow); 1976 get_dimm_config(mci);
1977 /* record ptr to the generic device */
1978 mci->dev = &i7core_dev->pdev[0]->dev;
1979 /* Set the function pointer to an actual operation function */
1980 mci->edac_check = i7core_check_error;
1895 1981
1896 /* add this new MC control structure to EDAC's list of MCs */ 1982 /* add this new MC control structure to EDAC's list of MCs */
1897 if (unlikely(edac_mc_add_mc(mci))) { 1983 if (unlikely(edac_mc_add_mc(mci))) {
@@ -1902,19 +1988,7 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev,
1902 */ 1988 */
1903 1989
1904 rc = -EINVAL; 1990 rc = -EINVAL;
1905 goto fail; 1991 goto fail0;
1906 }
1907
1908 /* allocating generic PCI control info */
1909 i7core_pci = edac_pci_create_generic_ctl(&i7core_dev->pdev[0]->dev,
1910 EDAC_MOD_STR);
1911 if (unlikely(!i7core_pci)) {
1912 printk(KERN_WARNING
1913 "%s(): Unable to create PCI control\n",
1914 __func__);
1915 printk(KERN_WARNING
1916 "%s(): PCI error report via EDAC not setup\n",
1917 __func__);
1918 } 1992 }
1919 1993
1920 /* Default error mask is any memory */ 1994 /* Default error mask is any memory */
@@ -1925,19 +1999,28 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev,
1925 pvt->inject.page = -1; 1999 pvt->inject.page = -1;
1926 pvt->inject.col = -1; 2000 pvt->inject.col = -1;
1927 2001
2002 /* allocating generic PCI control info */
2003 i7core_pci_ctl_create(pvt);
2004
1928 /* Registers on edac_mce in order to receive memory errors */ 2005 /* Registers on edac_mce in order to receive memory errors */
1929 pvt->edac_mce.priv = mci; 2006 pvt->edac_mce.priv = mci;
1930 pvt->edac_mce.check_error = i7core_mce_check_error; 2007 pvt->edac_mce.check_error = i7core_mce_check_error;
1931
1932 rc = edac_mce_register(&pvt->edac_mce); 2008 rc = edac_mce_register(&pvt->edac_mce);
1933 if (unlikely(rc < 0)) { 2009 if (unlikely(rc < 0)) {
1934 debugf0("MC: " __FILE__ 2010 debugf0("MC: " __FILE__
1935 ": %s(): failed edac_mce_register()\n", __func__); 2011 ": %s(): failed edac_mce_register()\n", __func__);
2012 goto fail1;
1936 } 2013 }
1937 2014
1938fail: 2015 return 0;
1939 if (rc < 0) 2016
1940 edac_mc_free(mci); 2017fail1:
2018 i7core_pci_ctl_release(pvt);
2019 edac_mc_del_mc(mci->dev);
2020fail0:
2021 kfree(mci->ctl_name);
2022 edac_mc_free(mci);
2023 i7core_dev->mci = NULL;
1941 return rc; 2024 return rc;
1942} 2025}
1943 2026
@@ -1949,8 +2032,6 @@ fail:
1949 * < 0 for error code 2032 * < 0 for error code
1950 */ 2033 */
1951 2034
1952static int probed = 0;
1953
1954static int __devinit i7core_probe(struct pci_dev *pdev, 2035static int __devinit i7core_probe(struct pci_dev *pdev,
1955 const struct pci_device_id *id) 2036 const struct pci_device_id *id)
1956{ 2037{
@@ -1965,25 +2046,16 @@ static int __devinit i7core_probe(struct pci_dev *pdev,
1965 */ 2046 */
1966 if (unlikely(probed >= 1)) { 2047 if (unlikely(probed >= 1)) {
1967 mutex_unlock(&i7core_edac_lock); 2048 mutex_unlock(&i7core_edac_lock);
1968 return -EINVAL; 2049 return -ENODEV;
1969 } 2050 }
1970 probed++; 2051 probed++;
1971 2052
1972 rc = i7core_get_devices(pci_dev_table); 2053 rc = i7core_get_all_devices();
1973 if (unlikely(rc < 0)) 2054 if (unlikely(rc < 0))
1974 goto fail0; 2055 goto fail0;
1975 2056
1976 list_for_each_entry(i7core_dev, &i7core_edac_list, list) { 2057 list_for_each_entry(i7core_dev, &i7core_edac_list, list) {
1977 int channels; 2058 rc = i7core_register_mci(i7core_dev);
1978 int csrows;
1979
1980 /* Check the number of active and not disabled channels */
1981 rc = i7core_get_active_channels(i7core_dev->socket,
1982 &channels, &csrows);
1983 if (unlikely(rc < 0))
1984 goto fail1;
1985
1986 rc = i7core_register_mci(i7core_dev, channels, csrows);
1987 if (unlikely(rc < 0)) 2059 if (unlikely(rc < 0))
1988 goto fail1; 2060 goto fail1;
1989 } 2061 }
@@ -1994,6 +2066,9 @@ static int __devinit i7core_probe(struct pci_dev *pdev,
1994 return 0; 2066 return 0;
1995 2067
1996fail1: 2068fail1:
2069 list_for_each_entry(i7core_dev, &i7core_edac_list, list)
2070 i7core_unregister_mci(i7core_dev);
2071
1997 i7core_put_all_devices(); 2072 i7core_put_all_devices();
1998fail0: 2073fail0:
1999 mutex_unlock(&i7core_edac_lock); 2074 mutex_unlock(&i7core_edac_lock);
@@ -2006,14 +2081,10 @@ fail0:
2006 */ 2081 */
2007static void __devexit i7core_remove(struct pci_dev *pdev) 2082static void __devexit i7core_remove(struct pci_dev *pdev)
2008{ 2083{
2009 struct mem_ctl_info *mci; 2084 struct i7core_dev *i7core_dev;
2010 struct i7core_dev *i7core_dev, *tmp;
2011 2085
2012 debugf0(__FILE__ ": %s()\n", __func__); 2086 debugf0(__FILE__ ": %s()\n", __func__);
2013 2087
2014 if (i7core_pci)
2015 edac_pci_release_generic_ctl(i7core_pci);
2016
2017 /* 2088 /*
2018 * we have a trouble here: pdev value for removal will be wrong, since 2089 * we have a trouble here: pdev value for removal will be wrong, since
2019 * it will point to the X58 register used to detect that the machine 2090 * it will point to the X58 register used to detect that the machine
@@ -2023,22 +2094,18 @@ static void __devexit i7core_remove(struct pci_dev *pdev)
2023 */ 2094 */
2024 2095
2025 mutex_lock(&i7core_edac_lock); 2096 mutex_lock(&i7core_edac_lock);
2026 list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list) { 2097
2027 mci = edac_mc_del_mc(&i7core_dev->pdev[0]->dev); 2098 if (unlikely(!probed)) {
2028 if (mci) { 2099 mutex_unlock(&i7core_edac_lock);
2029 struct i7core_pvt *pvt = mci->pvt_info; 2100 return;
2030
2031 i7core_dev = pvt->i7core_dev;
2032 edac_mce_unregister(&pvt->edac_mce);
2033 kfree(mci->ctl_name);
2034 edac_mc_free(mci);
2035 i7core_put_devices(i7core_dev);
2036 } else {
2037 i7core_printk(KERN_ERR,
2038 "Couldn't find mci for socket %d\n",
2039 i7core_dev->socket);
2040 }
2041 } 2101 }
2102
2103 list_for_each_entry(i7core_dev, &i7core_edac_list, list)
2104 i7core_unregister_mci(i7core_dev);
2105
2106 /* Release PCI resources */
2107 i7core_put_all_devices();
2108
2042 probed--; 2109 probed--;
2043 2110
2044 mutex_unlock(&i7core_edac_lock); 2111 mutex_unlock(&i7core_edac_lock);
@@ -2070,7 +2137,8 @@ static int __init i7core_init(void)
2070 /* Ensure that the OPSTATE is set correctly for POLL or NMI */ 2137 /* Ensure that the OPSTATE is set correctly for POLL or NMI */
2071 opstate_init(); 2138 opstate_init();
2072 2139
2073 i7core_xeon_pci_fixup(pci_dev_table); 2140 if (use_pci_fixup)
2141 i7core_xeon_pci_fixup(pci_dev_table);
2074 2142
2075 pci_rc = pci_register_driver(&i7core_driver); 2143 pci_rc = pci_register_driver(&i7core_driver);
2076 2144