diff options
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/amd76x_edac.c | 23 | ||||
-rw-r--r-- | drivers/edac/e752x_edac.c | 23 | ||||
-rw-r--r-- | drivers/edac/e7xxx_edac.c | 16 | ||||
-rw-r--r-- | drivers/edac/edac_mc.c | 538 | ||||
-rw-r--r-- | drivers/edac/edac_mc.h | 16 | ||||
-rw-r--r-- | drivers/edac/i82860_edac.c | 30 | ||||
-rw-r--r-- | drivers/edac/i82875p_edac.c | 30 | ||||
-rw-r--r-- | drivers/edac/r82600_edac.c | 21 |
8 files changed, 374 insertions, 323 deletions
diff --git a/drivers/edac/amd76x_edac.c b/drivers/edac/amd76x_edac.c index 53423ad6d4a3..7fd6283fe008 100644 --- a/drivers/edac/amd76x_edac.c +++ b/drivers/edac/amd76x_edac.c | |||
@@ -20,6 +20,9 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include "edac_mc.h" | 21 | #include "edac_mc.h" |
22 | 22 | ||
23 | #define AMD76X_REVISION " Ver: 2.0.0 " __DATE__ | ||
24 | |||
25 | |||
23 | #define amd76x_printk(level, fmt, arg...) \ | 26 | #define amd76x_printk(level, fmt, arg...) \ |
24 | edac_printk(level, "amd76x", fmt, ##arg) | 27 | edac_printk(level, "amd76x", fmt, ##arg) |
25 | 28 | ||
@@ -102,15 +105,18 @@ static const struct amd76x_dev_info amd76x_devs[] = { | |||
102 | static void amd76x_get_error_info(struct mem_ctl_info *mci, | 105 | static void amd76x_get_error_info(struct mem_ctl_info *mci, |
103 | struct amd76x_error_info *info) | 106 | struct amd76x_error_info *info) |
104 | { | 107 | { |
105 | pci_read_config_dword(mci->pdev, AMD76X_ECC_MODE_STATUS, | 108 | struct pci_dev *pdev; |
109 | |||
110 | pdev = to_pci_dev(mci->dev); | ||
111 | pci_read_config_dword(pdev, AMD76X_ECC_MODE_STATUS, | ||
106 | &info->ecc_mode_status); | 112 | &info->ecc_mode_status); |
107 | 113 | ||
108 | if (info->ecc_mode_status & BIT(8)) | 114 | if (info->ecc_mode_status & BIT(8)) |
109 | pci_write_bits32(mci->pdev, AMD76X_ECC_MODE_STATUS, | 115 | pci_write_bits32(pdev, AMD76X_ECC_MODE_STATUS, |
110 | (u32) BIT(8), (u32) BIT(8)); | 116 | (u32) BIT(8), (u32) BIT(8)); |
111 | 117 | ||
112 | if (info->ecc_mode_status & BIT(9)) | 118 | if (info->ecc_mode_status & BIT(9)) |
113 | pci_write_bits32(mci->pdev, AMD76X_ECC_MODE_STATUS, | 119 | pci_write_bits32(pdev, AMD76X_ECC_MODE_STATUS, |
114 | (u32) BIT(9), (u32) BIT(9)); | 120 | (u32) BIT(9), (u32) BIT(9)); |
115 | } | 121 | } |
116 | 122 | ||
@@ -211,13 +217,13 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) | |||
211 | } | 217 | } |
212 | 218 | ||
213 | debugf0("%s(): mci = %p\n", __func__, mci); | 219 | debugf0("%s(): mci = %p\n", __func__, mci); |
214 | mci->pdev = pdev; | 220 | mci->dev = &pdev->dev; |
215 | mci->mtype_cap = MEM_FLAG_RDDR; | 221 | mci->mtype_cap = MEM_FLAG_RDDR; |
216 | mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; | 222 | mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; |
217 | mci->edac_cap = ems_mode ? | 223 | mci->edac_cap = ems_mode ? |
218 | (EDAC_FLAG_EC | EDAC_FLAG_SECDED) : EDAC_FLAG_NONE; | 224 | (EDAC_FLAG_EC | EDAC_FLAG_SECDED) : EDAC_FLAG_NONE; |
219 | mci->mod_name = EDAC_MOD_STR; | 225 | mci->mod_name = EDAC_MOD_STR; |
220 | mci->mod_ver = "$Revision: 1.4.2.5 $"; | 226 | mci->mod_ver = AMD76X_REVISION; |
221 | mci->ctl_name = amd76x_devs[dev_idx].ctl_name; | 227 | mci->ctl_name = amd76x_devs[dev_idx].ctl_name; |
222 | mci->edac_check = amd76x_check; | 228 | mci->edac_check = amd76x_check; |
223 | mci->ctl_page_to_phys = NULL; | 229 | mci->ctl_page_to_phys = NULL; |
@@ -230,7 +236,7 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) | |||
230 | u32 dms; | 236 | u32 dms; |
231 | 237 | ||
232 | /* find the DRAM Chip Select Base address and mask */ | 238 | /* find the DRAM Chip Select Base address and mask */ |
233 | pci_read_config_dword(mci->pdev, | 239 | pci_read_config_dword(pdev, |
234 | AMD76X_MEM_BASE_ADDR + (index * 4), &mba); | 240 | AMD76X_MEM_BASE_ADDR + (index * 4), &mba); |
235 | 241 | ||
236 | if (!(mba & BIT(0))) | 242 | if (!(mba & BIT(0))) |
@@ -238,8 +244,7 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) | |||
238 | 244 | ||
239 | mba_base = mba & 0xff800000UL; | 245 | mba_base = mba & 0xff800000UL; |
240 | mba_mask = ((mba & 0xff80) << 16) | 0x7fffffUL; | 246 | mba_mask = ((mba & 0xff80) << 16) | 0x7fffffUL; |
241 | pci_read_config_dword(mci->pdev, AMD76X_DRAM_MODE_STATUS, | 247 | pci_read_config_dword(pdev, AMD76X_DRAM_MODE_STATUS, &dms); |
242 | &dms); | ||
243 | csrow->first_page = mba_base >> PAGE_SHIFT; | 248 | csrow->first_page = mba_base >> PAGE_SHIFT; |
244 | csrow->nr_pages = (mba_mask + 1) >> PAGE_SHIFT; | 249 | csrow->nr_pages = (mba_mask + 1) >> PAGE_SHIFT; |
245 | csrow->last_page = csrow->first_page + csrow->nr_pages - 1; | 250 | csrow->last_page = csrow->first_page + csrow->nr_pages - 1; |
@@ -291,7 +296,7 @@ static void __devexit amd76x_remove_one(struct pci_dev *pdev) | |||
291 | 296 | ||
292 | debugf0("%s()\n", __func__); | 297 | debugf0("%s()\n", __func__); |
293 | 298 | ||
294 | if ((mci = edac_mc_del_mc(pdev)) == NULL) | 299 | if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL) |
295 | return; | 300 | return; |
296 | 301 | ||
297 | edac_mc_free(mci); | 302 | edac_mc_free(mci); |
diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c index fce31936e6d7..de9f332eabf0 100644 --- a/drivers/edac/e752x_edac.c +++ b/drivers/edac/e752x_edac.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include "edac_mc.h" | 26 | #include "edac_mc.h" |
27 | 27 | ||
28 | #define E752X_REVISION " Ver: 2.0.0 " __DATE__ | ||
29 | |||
28 | static int force_function_unhide; | 30 | static int force_function_unhide; |
29 | 31 | ||
30 | #define e752x_printk(level, fmt, arg...) \ | 32 | #define e752x_printk(level, fmt, arg...) \ |
@@ -819,8 +821,8 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) | |||
819 | EDAC_FLAG_S4ECD4ED; | 821 | EDAC_FLAG_S4ECD4ED; |
820 | /* FIXME - what if different memory types are in different csrows? */ | 822 | /* FIXME - what if different memory types are in different csrows? */ |
821 | mci->mod_name = EDAC_MOD_STR; | 823 | mci->mod_name = EDAC_MOD_STR; |
822 | mci->mod_ver = "$Revision: 1.5.2.11 $"; | 824 | mci->mod_ver = E752X_REVISION; |
823 | mci->pdev = pdev; | 825 | mci->dev = &pdev->dev; |
824 | 826 | ||
825 | debugf3("%s(): init pvt\n", __func__); | 827 | debugf3("%s(): init pvt\n", __func__); |
826 | pvt = (struct e752x_pvt *) mci->pvt_info; | 828 | pvt = (struct e752x_pvt *) mci->pvt_info; |
@@ -864,7 +866,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) | |||
864 | struct csrow_info *csrow = &mci->csrows[index]; | 866 | struct csrow_info *csrow = &mci->csrows[index]; |
865 | 867 | ||
866 | mem_dev = (mem_dev == 2); | 868 | mem_dev = (mem_dev == 2); |
867 | pci_read_config_byte(mci->pdev, E752X_DRB + index, &value); | 869 | pci_read_config_byte(pdev, E752X_DRB + index, &value); |
868 | /* convert a 128 or 64 MiB DRB to a page size. */ | 870 | /* convert a 128 or 64 MiB DRB to a page size. */ |
869 | cumul_size = value << (25 + drc_drbg - PAGE_SHIFT); | 871 | cumul_size = value << (25 + drc_drbg - PAGE_SHIFT); |
870 | debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, | 872 | debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, |
@@ -904,8 +906,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) | |||
904 | u8 row = 0; | 906 | u8 row = 0; |
905 | 907 | ||
906 | for (index = 0; index < 8; index += 2) { | 908 | for (index = 0; index < 8; index += 2) { |
907 | pci_read_config_byte(mci->pdev, E752X_DRB + index, | 909 | pci_read_config_byte(pdev, E752X_DRB + index, &value); |
908 | &value); | ||
909 | 910 | ||
910 | /* test if there is a dimm in this slot */ | 911 | /* test if there is a dimm in this slot */ |
911 | if (value == last) { | 912 | if (value == last) { |
@@ -918,7 +919,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) | |||
918 | last = value; | 919 | last = value; |
919 | /* test the next value to see if the dimm is | 920 | /* test the next value to see if the dimm is |
920 | double sided */ | 921 | double sided */ |
921 | pci_read_config_byte(mci->pdev, | 922 | pci_read_config_byte(pdev, |
922 | E752X_DRB + index + 1, | 923 | E752X_DRB + index + 1, |
923 | &value); | 924 | &value); |
924 | pvt->map[index + 1] = (value == last) ? | 925 | pvt->map[index + 1] = (value == last) ? |
@@ -935,18 +936,18 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) | |||
935 | } | 936 | } |
936 | 937 | ||
937 | /* set the map type. 1 = normal, 0 = reversed */ | 938 | /* set the map type. 1 = normal, 0 = reversed */ |
938 | pci_read_config_byte(mci->pdev, E752X_DRM, &stat8); | 939 | pci_read_config_byte(pdev, E752X_DRM, &stat8); |
939 | pvt->map_type = ((stat8 & 0x0f) > ((stat8 >> 4) & 0x0f)); | 940 | pvt->map_type = ((stat8 & 0x0f) > ((stat8 >> 4) & 0x0f)); |
940 | 941 | ||
941 | mci->edac_cap |= EDAC_FLAG_NONE; | 942 | mci->edac_cap |= EDAC_FLAG_NONE; |
942 | debugf3("%s(): tolm, remapbase, remaplimit\n", __func__); | 943 | debugf3("%s(): tolm, remapbase, remaplimit\n", __func__); |
943 | 944 | ||
944 | /* load the top of low memory, remap base, and remap limit vars */ | 945 | /* load the top of low memory, remap base, and remap limit vars */ |
945 | pci_read_config_word(mci->pdev, E752X_TOLM, &pci_data); | 946 | pci_read_config_word(pdev, E752X_TOLM, &pci_data); |
946 | pvt->tolm = ((u32) pci_data) << 4; | 947 | pvt->tolm = ((u32) pci_data) << 4; |
947 | pci_read_config_word(mci->pdev, E752X_REMAPBASE, &pci_data); | 948 | pci_read_config_word(pdev, E752X_REMAPBASE, &pci_data); |
948 | pvt->remapbase = ((u32) pci_data) << 14; | 949 | pvt->remapbase = ((u32) pci_data) << 14; |
949 | pci_read_config_word(mci->pdev, E752X_REMAPLIMIT, &pci_data); | 950 | pci_read_config_word(pdev, E752X_REMAPLIMIT, &pci_data); |
950 | pvt->remaplimit = ((u32) pci_data) << 14; | 951 | pvt->remaplimit = ((u32) pci_data) << 14; |
951 | e752x_printk(KERN_INFO, | 952 | e752x_printk(KERN_INFO, |
952 | "tolm = %x, remapbase = %x, remaplimit = %x\n", pvt->tolm, | 953 | "tolm = %x, remapbase = %x, remaplimit = %x\n", pvt->tolm, |
@@ -1015,7 +1016,7 @@ static void __devexit e752x_remove_one(struct pci_dev *pdev) | |||
1015 | 1016 | ||
1016 | debugf0("%s()\n", __func__); | 1017 | debugf0("%s()\n", __func__); |
1017 | 1018 | ||
1018 | if ((mci = edac_mc_del_mc(pdev)) == NULL) | 1019 | if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL) |
1019 | return; | 1020 | return; |
1020 | 1021 | ||
1021 | pvt = (struct e752x_pvt *) mci->pvt_info; | 1022 | pvt = (struct e752x_pvt *) mci->pvt_info; |
diff --git a/drivers/edac/e7xxx_edac.c b/drivers/edac/e7xxx_edac.c index a9518d3e4be4..d601d53b9920 100644 --- a/drivers/edac/e7xxx_edac.c +++ b/drivers/edac/e7xxx_edac.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include "edac_mc.h" | 31 | #include "edac_mc.h" |
32 | 32 | ||
33 | #define E7XXX_REVISION " Ver: 2.0.0 " __DATE__ | ||
34 | |||
33 | #define e7xxx_printk(level, fmt, arg...) \ | 35 | #define e7xxx_printk(level, fmt, arg...) \ |
34 | edac_printk(level, "e7xxx", fmt, ##arg) | 36 | edac_printk(level, "e7xxx", fmt, ##arg) |
35 | 37 | ||
@@ -373,8 +375,8 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) | |||
373 | EDAC_FLAG_S4ECD4ED; | 375 | EDAC_FLAG_S4ECD4ED; |
374 | /* FIXME - what if different memory types are in different csrows? */ | 376 | /* FIXME - what if different memory types are in different csrows? */ |
375 | mci->mod_name = EDAC_MOD_STR; | 377 | mci->mod_name = EDAC_MOD_STR; |
376 | mci->mod_ver = "$Revision: 1.5.2.9 $"; | 378 | mci->mod_ver = E7XXX_REVISION; |
377 | mci->pdev = pdev; | 379 | mci->dev = &pdev->dev; |
378 | 380 | ||
379 | debugf3("%s(): init pvt\n", __func__); | 381 | debugf3("%s(): init pvt\n", __func__); |
380 | pvt = (struct e7xxx_pvt *) mci->pvt_info; | 382 | pvt = (struct e7xxx_pvt *) mci->pvt_info; |
@@ -411,7 +413,7 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) | |||
411 | int mem_dev = (dra >> (index * 4 + 3)) & 0x1; | 413 | int mem_dev = (dra >> (index * 4 + 3)) & 0x1; |
412 | struct csrow_info *csrow = &mci->csrows[index]; | 414 | struct csrow_info *csrow = &mci->csrows[index]; |
413 | 415 | ||
414 | pci_read_config_byte(mci->pdev, E7XXX_DRB + index, &value); | 416 | pci_read_config_byte(pdev, E7XXX_DRB + index, &value); |
415 | /* convert a 64 or 32 MiB DRB to a page size. */ | 417 | /* convert a 64 or 32 MiB DRB to a page size. */ |
416 | cumul_size = value << (25 + drc_drbg - PAGE_SHIFT); | 418 | cumul_size = value << (25 + drc_drbg - PAGE_SHIFT); |
417 | debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, | 419 | debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, |
@@ -448,11 +450,11 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) | |||
448 | 450 | ||
449 | debugf3("%s(): tolm, remapbase, remaplimit\n", __func__); | 451 | debugf3("%s(): tolm, remapbase, remaplimit\n", __func__); |
450 | /* load the top of low memory, remap base, and remap limit vars */ | 452 | /* load the top of low memory, remap base, and remap limit vars */ |
451 | pci_read_config_word(mci->pdev, E7XXX_TOLM, &pci_data); | 453 | pci_read_config_word(pdev, E7XXX_TOLM, &pci_data); |
452 | pvt->tolm = ((u32) pci_data) << 4; | 454 | pvt->tolm = ((u32) pci_data) << 4; |
453 | pci_read_config_word(mci->pdev, E7XXX_REMAPBASE, &pci_data); | 455 | pci_read_config_word(pdev, E7XXX_REMAPBASE, &pci_data); |
454 | pvt->remapbase = ((u32) pci_data) << 14; | 456 | pvt->remapbase = ((u32) pci_data) << 14; |
455 | pci_read_config_word(mci->pdev, E7XXX_REMAPLIMIT, &pci_data); | 457 | pci_read_config_word(pdev, E7XXX_REMAPLIMIT, &pci_data); |
456 | pvt->remaplimit = ((u32) pci_data) << 14; | 458 | pvt->remaplimit = ((u32) pci_data) << 14; |
457 | e7xxx_printk(KERN_INFO, | 459 | e7xxx_printk(KERN_INFO, |
458 | "tolm = %x, remapbase = %x, remaplimit = %x\n", pvt->tolm, | 460 | "tolm = %x, remapbase = %x, remaplimit = %x\n", pvt->tolm, |
@@ -498,7 +500,7 @@ static void __devexit e7xxx_remove_one(struct pci_dev *pdev) | |||
498 | 500 | ||
499 | debugf0("%s()\n", __func__); | 501 | debugf0("%s()\n", __func__); |
500 | 502 | ||
501 | if ((mci = edac_mc_del_mc(pdev)) == NULL) | 503 | if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL) |
502 | return; | 504 | return; |
503 | 505 | ||
504 | pvt = (struct e7xxx_pvt *) mci->pvt_info; | 506 | pvt = (struct e7xxx_pvt *) mci->pvt_info; |
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index ea06e3a4dc35..603de8b49f27 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -54,16 +54,17 @@ static int log_ce = 1; | |||
54 | static int panic_on_ue; | 54 | static int panic_on_ue; |
55 | static int poll_msec = 1000; | 55 | static int poll_msec = 1000; |
56 | 56 | ||
57 | static int check_pci_parity = 0; /* default YES check PCI parity */ | ||
58 | static int panic_on_pci_parity; /* default no panic on PCI Parity */ | ||
59 | static atomic_t pci_parity_count = ATOMIC_INIT(0); | ||
60 | |||
61 | /* lock to memory controller's control array */ | 57 | /* lock to memory controller's control array */ |
62 | static DECLARE_MUTEX(mem_ctls_mutex); | 58 | static DECLARE_MUTEX(mem_ctls_mutex); |
63 | static struct list_head mc_devices = LIST_HEAD_INIT(mc_devices); | 59 | static struct list_head mc_devices = LIST_HEAD_INIT(mc_devices); |
64 | 60 | ||
65 | static struct task_struct *edac_thread; | 61 | static struct task_struct *edac_thread; |
66 | 62 | ||
63 | #ifdef CONFIG_PCI | ||
64 | static int check_pci_parity = 0; /* default YES check PCI parity */ | ||
65 | static int panic_on_pci_parity; /* default no panic on PCI Parity */ | ||
66 | static atomic_t pci_parity_count = ATOMIC_INIT(0); | ||
67 | |||
67 | /* Structure of the whitelist and blacklist arrays */ | 68 | /* Structure of the whitelist and blacklist arrays */ |
68 | struct edac_pci_device_list { | 69 | struct edac_pci_device_list { |
69 | unsigned int vendor; /* Vendor ID */ | 70 | unsigned int vendor; /* Vendor ID */ |
@@ -80,6 +81,12 @@ static int pci_blacklist_count; | |||
80 | static struct edac_pci_device_list pci_whitelist[MAX_LISTED_PCI_DEVICES]; | 81 | static struct edac_pci_device_list pci_whitelist[MAX_LISTED_PCI_DEVICES]; |
81 | static int pci_whitelist_count ; | 82 | static int pci_whitelist_count ; |
82 | 83 | ||
84 | #ifndef DISABLE_EDAC_SYSFS | ||
85 | static struct kobject edac_pci_kobj; /* /sys/devices/system/edac/pci */ | ||
86 | static struct completion edac_pci_kobj_complete; | ||
87 | #endif /* DISABLE_EDAC_SYSFS */ | ||
88 | #endif /* CONFIG_PCI */ | ||
89 | |||
83 | /* START sysfs data and methods */ | 90 | /* START sysfs data and methods */ |
84 | 91 | ||
85 | #ifndef DISABLE_EDAC_SYSFS | 92 | #ifndef DISABLE_EDAC_SYSFS |
@@ -127,18 +134,15 @@ static struct sysdev_class edac_class = { | |||
127 | set_kset_name("edac"), | 134 | set_kset_name("edac"), |
128 | }; | 135 | }; |
129 | 136 | ||
130 | /* sysfs objects: | 137 | /* sysfs object: |
131 | * /sys/devices/system/edac/mc | 138 | * /sys/devices/system/edac/mc |
132 | * /sys/devices/system/edac/pci | ||
133 | */ | 139 | */ |
134 | static struct kobject edac_memctrl_kobj; | 140 | static struct kobject edac_memctrl_kobj; |
135 | static struct kobject edac_pci_kobj; | ||
136 | 141 | ||
137 | /* We use these to wait for the reference counts on edac_memctrl_kobj and | 142 | /* We use these to wait for the reference counts on edac_memctrl_kobj and |
138 | * edac_pci_kobj to reach 0. | 143 | * edac_pci_kobj to reach 0. |
139 | */ | 144 | */ |
140 | static struct completion edac_memctrl_kobj_complete; | 145 | static struct completion edac_memctrl_kobj_complete; |
141 | static struct completion edac_pci_kobj_complete; | ||
142 | 146 | ||
143 | /* | 147 | /* |
144 | * /sys/devices/system/edac/mc; | 148 | * /sys/devices/system/edac/mc; |
@@ -324,6 +328,8 @@ static void edac_sysfs_memctrl_teardown(void) | |||
324 | #endif /* DISABLE_EDAC_SYSFS */ | 328 | #endif /* DISABLE_EDAC_SYSFS */ |
325 | } | 329 | } |
326 | 330 | ||
331 | #ifdef CONFIG_PCI | ||
332 | |||
327 | #ifndef DISABLE_EDAC_SYSFS | 333 | #ifndef DISABLE_EDAC_SYSFS |
328 | 334 | ||
329 | /* | 335 | /* |
@@ -624,6 +630,252 @@ static void edac_sysfs_pci_teardown(void) | |||
624 | #endif | 630 | #endif |
625 | } | 631 | } |
626 | 632 | ||
633 | |||
634 | static u16 get_pci_parity_status(struct pci_dev *dev, int secondary) | ||
635 | { | ||
636 | int where; | ||
637 | u16 status; | ||
638 | |||
639 | where = secondary ? PCI_SEC_STATUS : PCI_STATUS; | ||
640 | pci_read_config_word(dev, where, &status); | ||
641 | |||
642 | /* If we get back 0xFFFF then we must suspect that the card has been | ||
643 | * pulled but the Linux PCI layer has not yet finished cleaning up. | ||
644 | * We don't want to report on such devices | ||
645 | */ | ||
646 | |||
647 | if (status == 0xFFFF) { | ||
648 | u32 sanity; | ||
649 | |||
650 | pci_read_config_dword(dev, 0, &sanity); | ||
651 | |||
652 | if (sanity == 0xFFFFFFFF) | ||
653 | return 0; | ||
654 | } | ||
655 | |||
656 | status &= PCI_STATUS_DETECTED_PARITY | PCI_STATUS_SIG_SYSTEM_ERROR | | ||
657 | PCI_STATUS_PARITY; | ||
658 | |||
659 | if (status) | ||
660 | /* reset only the bits we are interested in */ | ||
661 | pci_write_config_word(dev, where, status); | ||
662 | |||
663 | return status; | ||
664 | } | ||
665 | |||
666 | typedef void (*pci_parity_check_fn_t) (struct pci_dev *dev); | ||
667 | |||
668 | /* Clear any PCI parity errors logged by this device. */ | ||
669 | static void edac_pci_dev_parity_clear(struct pci_dev *dev) | ||
670 | { | ||
671 | u8 header_type; | ||
672 | |||
673 | get_pci_parity_status(dev, 0); | ||
674 | |||
675 | /* read the device TYPE, looking for bridges */ | ||
676 | pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type); | ||
677 | |||
678 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) | ||
679 | get_pci_parity_status(dev, 1); | ||
680 | } | ||
681 | |||
682 | /* | ||
683 | * PCI Parity polling | ||
684 | * | ||
685 | */ | ||
686 | static void edac_pci_dev_parity_test(struct pci_dev *dev) | ||
687 | { | ||
688 | u16 status; | ||
689 | u8 header_type; | ||
690 | |||
691 | /* read the STATUS register on this device | ||
692 | */ | ||
693 | status = get_pci_parity_status(dev, 0); | ||
694 | |||
695 | debugf2("PCI STATUS= 0x%04x %s\n", status, dev->dev.bus_id ); | ||
696 | |||
697 | /* check the status reg for errors */ | ||
698 | if (status) { | ||
699 | if (status & (PCI_STATUS_SIG_SYSTEM_ERROR)) | ||
700 | edac_printk(KERN_CRIT, EDAC_PCI, | ||
701 | "Signaled System Error on %s\n", | ||
702 | pci_name(dev)); | ||
703 | |||
704 | if (status & (PCI_STATUS_PARITY)) { | ||
705 | edac_printk(KERN_CRIT, EDAC_PCI, | ||
706 | "Master Data Parity Error on %s\n", | ||
707 | pci_name(dev)); | ||
708 | |||
709 | atomic_inc(&pci_parity_count); | ||
710 | } | ||
711 | |||
712 | if (status & (PCI_STATUS_DETECTED_PARITY)) { | ||
713 | edac_printk(KERN_CRIT, EDAC_PCI, | ||
714 | "Detected Parity Error on %s\n", | ||
715 | pci_name(dev)); | ||
716 | |||
717 | atomic_inc(&pci_parity_count); | ||
718 | } | ||
719 | } | ||
720 | |||
721 | /* read the device TYPE, looking for bridges */ | ||
722 | pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type); | ||
723 | |||
724 | debugf2("PCI HEADER TYPE= 0x%02x %s\n", header_type, dev->dev.bus_id ); | ||
725 | |||
726 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { | ||
727 | /* On bridges, need to examine secondary status register */ | ||
728 | status = get_pci_parity_status(dev, 1); | ||
729 | |||
730 | debugf2("PCI SEC_STATUS= 0x%04x %s\n", | ||
731 | status, dev->dev.bus_id ); | ||
732 | |||
733 | /* check the secondary status reg for errors */ | ||
734 | if (status) { | ||
735 | if (status & (PCI_STATUS_SIG_SYSTEM_ERROR)) | ||
736 | edac_printk(KERN_CRIT, EDAC_PCI, "Bridge " | ||
737 | "Signaled System Error on %s\n", | ||
738 | pci_name(dev)); | ||
739 | |||
740 | if (status & (PCI_STATUS_PARITY)) { | ||
741 | edac_printk(KERN_CRIT, EDAC_PCI, "Bridge " | ||
742 | "Master Data Parity Error on " | ||
743 | "%s\n", pci_name(dev)); | ||
744 | |||
745 | atomic_inc(&pci_parity_count); | ||
746 | } | ||
747 | |||
748 | if (status & (PCI_STATUS_DETECTED_PARITY)) { | ||
749 | edac_printk(KERN_CRIT, EDAC_PCI, "Bridge " | ||
750 | "Detected Parity Error on %s\n", | ||
751 | pci_name(dev)); | ||
752 | |||
753 | atomic_inc(&pci_parity_count); | ||
754 | } | ||
755 | } | ||
756 | } | ||
757 | } | ||
758 | |||
759 | /* | ||
760 | * check_dev_on_list: Scan for a PCI device on a white/black list | ||
761 | * @list: an EDAC &edac_pci_device_list white/black list pointer | ||
762 | * @free_index: index of next free entry on the list | ||
763 | * @pci_dev: PCI Device pointer | ||
764 | * | ||
765 | * see if list contains the device. | ||
766 | * | ||
767 | * Returns: 0 not found | ||
768 | * 1 found on list | ||
769 | */ | ||
770 | static int check_dev_on_list(struct edac_pci_device_list *list, | ||
771 | int free_index, struct pci_dev *dev) | ||
772 | { | ||
773 | int i; | ||
774 | int rc = 0; /* Assume not found */ | ||
775 | unsigned short vendor=dev->vendor; | ||
776 | unsigned short device=dev->device; | ||
777 | |||
778 | /* Scan the list, looking for a vendor/device match */ | ||
779 | for (i = 0; i < free_index; i++, list++ ) { | ||
780 | if ((list->vendor == vendor ) && (list->device == device )) { | ||
781 | rc = 1; | ||
782 | break; | ||
783 | } | ||
784 | } | ||
785 | |||
786 | return rc; | ||
787 | } | ||
788 | |||
789 | /* | ||
790 | * pci_dev parity list iterator | ||
791 | * Scan the PCI device list for one iteration, looking for SERRORs | ||
792 | * Master Parity ERRORS or Parity ERRORs on primary or secondary devices | ||
793 | */ | ||
794 | static inline void edac_pci_dev_parity_iterator(pci_parity_check_fn_t fn) | ||
795 | { | ||
796 | struct pci_dev *dev = NULL; | ||
797 | |||
798 | /* request for kernel access to the next PCI device, if any, | ||
799 | * and while we are looking at it have its reference count | ||
800 | * bumped until we are done with it | ||
801 | */ | ||
802 | while((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | ||
803 | /* if whitelist exists then it has priority, so only scan | ||
804 | * those devices on the whitelist | ||
805 | */ | ||
806 | if (pci_whitelist_count > 0 ) { | ||
807 | if (check_dev_on_list(pci_whitelist, | ||
808 | pci_whitelist_count, dev)) | ||
809 | fn(dev); | ||
810 | } else { | ||
811 | /* | ||
812 | * if no whitelist, then check if this devices is | ||
813 | * blacklisted | ||
814 | */ | ||
815 | if (!check_dev_on_list(pci_blacklist, | ||
816 | pci_blacklist_count, dev)) | ||
817 | fn(dev); | ||
818 | } | ||
819 | } | ||
820 | } | ||
821 | |||
822 | static void do_pci_parity_check(void) | ||
823 | { | ||
824 | unsigned long flags; | ||
825 | int before_count; | ||
826 | |||
827 | debugf3("%s()\n", __func__); | ||
828 | |||
829 | if (!check_pci_parity) | ||
830 | return; | ||
831 | |||
832 | before_count = atomic_read(&pci_parity_count); | ||
833 | |||
834 | /* scan all PCI devices looking for a Parity Error on devices and | ||
835 | * bridges | ||
836 | */ | ||
837 | local_irq_save(flags); | ||
838 | edac_pci_dev_parity_iterator(edac_pci_dev_parity_test); | ||
839 | local_irq_restore(flags); | ||
840 | |||
841 | /* Only if operator has selected panic on PCI Error */ | ||
842 | if (panic_on_pci_parity) { | ||
843 | /* If the count is different 'after' from 'before' */ | ||
844 | if (before_count != atomic_read(&pci_parity_count)) | ||
845 | panic("EDAC: PCI Parity Error"); | ||
846 | } | ||
847 | } | ||
848 | |||
849 | static inline void clear_pci_parity_errors(void) | ||
850 | { | ||
851 | /* Clear any PCI bus parity errors that devices initially have logged | ||
852 | * in their registers. | ||
853 | */ | ||
854 | edac_pci_dev_parity_iterator(edac_pci_dev_parity_clear); | ||
855 | } | ||
856 | |||
857 | #else /* CONFIG_PCI */ | ||
858 | |||
859 | static inline void do_pci_parity_check(void) | ||
860 | { | ||
861 | /* no-op */ | ||
862 | } | ||
863 | |||
864 | static inline void clear_pci_parity_errors(void) | ||
865 | { | ||
866 | /* no-op */ | ||
867 | } | ||
868 | |||
869 | static void edac_sysfs_pci_teardown(void) | ||
870 | { | ||
871 | } | ||
872 | |||
873 | static int edac_sysfs_pci_setup(void) | ||
874 | { | ||
875 | return 0; | ||
876 | } | ||
877 | #endif /* CONFIG_PCI */ | ||
878 | |||
627 | #ifndef DISABLE_EDAC_SYSFS | 879 | #ifndef DISABLE_EDAC_SYSFS |
628 | 880 | ||
629 | /* EDAC sysfs CSROW data structures and methods */ | 881 | /* EDAC sysfs CSROW data structures and methods */ |
@@ -1132,7 +1384,7 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) | |||
1132 | return err; | 1384 | return err; |
1133 | 1385 | ||
1134 | /* create a symlink for the device */ | 1386 | /* create a symlink for the device */ |
1135 | err = sysfs_create_link(edac_mci_kobj, &mci->pdev->dev.kobj, | 1387 | err = sysfs_create_link(edac_mci_kobj, &mci->dev->kobj, |
1136 | EDAC_DEVICE_SYMLINK); | 1388 | EDAC_DEVICE_SYMLINK); |
1137 | 1389 | ||
1138 | if (err) | 1390 | if (err) |
@@ -1238,7 +1490,7 @@ void edac_mc_dump_mci(struct mem_ctl_info *mci) | |||
1238 | debugf4("\tmci->edac_check = %p\n", mci->edac_check); | 1490 | debugf4("\tmci->edac_check = %p\n", mci->edac_check); |
1239 | debugf3("\tmci->nr_csrows = %d, csrows = %p\n", | 1491 | debugf3("\tmci->nr_csrows = %d, csrows = %p\n", |
1240 | mci->nr_csrows, mci->csrows); | 1492 | mci->nr_csrows, mci->csrows); |
1241 | debugf3("\tpdev = %p\n", mci->pdev); | 1493 | debugf3("\tdev = %p\n", mci->dev); |
1242 | debugf3("\tmod_name:ctl_name = %s:%s\n", | 1494 | debugf3("\tmod_name:ctl_name = %s:%s\n", |
1243 | mci->mod_name, mci->ctl_name); | 1495 | mci->mod_name, mci->ctl_name); |
1244 | debugf3("\tpvt_info = %p\n\n", mci->pvt_info); | 1496 | debugf3("\tpvt_info = %p\n\n", mci->pvt_info); |
@@ -1363,7 +1615,7 @@ void edac_mc_free(struct mem_ctl_info *mci) | |||
1363 | } | 1615 | } |
1364 | EXPORT_SYMBOL_GPL(edac_mc_free); | 1616 | EXPORT_SYMBOL_GPL(edac_mc_free); |
1365 | 1617 | ||
1366 | static struct mem_ctl_info *find_mci_by_pdev(struct pci_dev *pdev) | 1618 | static struct mem_ctl_info *find_mci_by_dev(struct device *dev) |
1367 | { | 1619 | { |
1368 | struct mem_ctl_info *mci; | 1620 | struct mem_ctl_info *mci; |
1369 | struct list_head *item; | 1621 | struct list_head *item; |
@@ -1373,7 +1625,7 @@ static struct mem_ctl_info *find_mci_by_pdev(struct pci_dev *pdev) | |||
1373 | list_for_each(item, &mc_devices) { | 1625 | list_for_each(item, &mc_devices) { |
1374 | mci = list_entry(item, struct mem_ctl_info, link); | 1626 | mci = list_entry(item, struct mem_ctl_info, link); |
1375 | 1627 | ||
1376 | if (mci->pdev == pdev) | 1628 | if (mci->dev == dev) |
1377 | return mci; | 1629 | return mci; |
1378 | } | 1630 | } |
1379 | 1631 | ||
@@ -1390,12 +1642,12 @@ static int add_mc_to_global_list(struct mem_ctl_info *mci) | |||
1390 | mci->mc_idx = 0; | 1642 | mci->mc_idx = 0; |
1391 | insert_before = &mc_devices; | 1643 | insert_before = &mc_devices; |
1392 | } else { | 1644 | } else { |
1393 | if (find_mci_by_pdev(mci->pdev)) { | 1645 | if (find_mci_by_dev(mci->dev)) { |
1394 | edac_printk(KERN_WARNING, EDAC_MC, | 1646 | edac_printk(KERN_WARNING, EDAC_MC, |
1395 | "%s (%s) %s %s already assigned %d\n", | 1647 | "%s (%s) %s %s already assigned %d\n", |
1396 | mci->pdev->dev.bus_id, | 1648 | mci->dev->bus_id, dev_name(mci->dev), |
1397 | pci_name(mci->pdev), mci->mod_name, | 1649 | mci->mod_name, mci->ctl_name, |
1398 | mci->ctl_name, mci->mc_idx); | 1650 | mci->mc_idx); |
1399 | return 1; | 1651 | return 1; |
1400 | } | 1652 | } |
1401 | 1653 | ||
@@ -1486,8 +1738,8 @@ int edac_mc_add_mc(struct mem_ctl_info *mci) | |||
1486 | } | 1738 | } |
1487 | 1739 | ||
1488 | /* Report action taken */ | 1740 | /* Report action taken */ |
1489 | edac_mc_printk(mci, KERN_INFO, "Giving out device to %s %s: PCI %s\n", | 1741 | edac_mc_printk(mci, KERN_INFO, "Giving out device to %s %s: DEV %s\n", |
1490 | mci->mod_name, mci->ctl_name, pci_name(mci->pdev)); | 1742 | mci->mod_name, mci->ctl_name, dev_name(mci->dev)); |
1491 | 1743 | ||
1492 | up(&mem_ctls_mutex); | 1744 | up(&mem_ctls_mutex); |
1493 | return 0; | 1745 | return 0; |
@@ -1504,18 +1756,18 @@ EXPORT_SYMBOL_GPL(edac_mc_add_mc); | |||
1504 | /** | 1756 | /** |
1505 | * edac_mc_del_mc: Remove sysfs entries for specified mci structure and | 1757 | * edac_mc_del_mc: Remove sysfs entries for specified mci structure and |
1506 | * remove mci structure from global list | 1758 | * remove mci structure from global list |
1507 | * @pdev: Pointer to 'struct pci_dev' representing mci structure to remove. | 1759 | * @pdev: Pointer to 'struct device' representing mci structure to remove. |
1508 | * | 1760 | * |
1509 | * Return pointer to removed mci structure, or NULL if device not found. | 1761 | * Return pointer to removed mci structure, or NULL if device not found. |
1510 | */ | 1762 | */ |
1511 | struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev) | 1763 | struct mem_ctl_info * edac_mc_del_mc(struct device *dev) |
1512 | { | 1764 | { |
1513 | struct mem_ctl_info *mci; | 1765 | struct mem_ctl_info *mci; |
1514 | 1766 | ||
1515 | debugf0("MC: %s()\n", __func__); | 1767 | debugf0("MC: %s()\n", __func__); |
1516 | down(&mem_ctls_mutex); | 1768 | down(&mem_ctls_mutex); |
1517 | 1769 | ||
1518 | if ((mci = find_mci_by_pdev(pdev)) == NULL) { | 1770 | if ((mci = find_mci_by_dev(dev)) == NULL) { |
1519 | up(&mem_ctls_mutex); | 1771 | up(&mem_ctls_mutex); |
1520 | return NULL; | 1772 | return NULL; |
1521 | } | 1773 | } |
@@ -1524,8 +1776,8 @@ struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev) | |||
1524 | del_mc_from_global_list(mci); | 1776 | del_mc_from_global_list(mci); |
1525 | up(&mem_ctls_mutex); | 1777 | up(&mem_ctls_mutex); |
1526 | edac_printk(KERN_INFO, EDAC_MC, | 1778 | edac_printk(KERN_INFO, EDAC_MC, |
1527 | "Removed device %d for %s %s: PCI %s\n", mci->mc_idx, | 1779 | "Removed device %d for %s %s: DEV %s\n", mci->mc_idx, |
1528 | mci->mod_name, mci->ctl_name, pci_name(mci->pdev)); | 1780 | mci->mod_name, mci->ctl_name, dev_name(mci->dev)); |
1529 | return mci; | 1781 | return mci; |
1530 | } | 1782 | } |
1531 | EXPORT_SYMBOL_GPL(edac_mc_del_mc); | 1783 | EXPORT_SYMBOL_GPL(edac_mc_del_mc); |
@@ -1739,244 +1991,6 @@ void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, const char *msg) | |||
1739 | } | 1991 | } |
1740 | EXPORT_SYMBOL_GPL(edac_mc_handle_ue_no_info); | 1992 | EXPORT_SYMBOL_GPL(edac_mc_handle_ue_no_info); |
1741 | 1993 | ||
1742 | #ifdef CONFIG_PCI | ||
1743 | |||
1744 | static u16 get_pci_parity_status(struct pci_dev *dev, int secondary) | ||
1745 | { | ||
1746 | int where; | ||
1747 | u16 status; | ||
1748 | |||
1749 | where = secondary ? PCI_SEC_STATUS : PCI_STATUS; | ||
1750 | pci_read_config_word(dev, where, &status); | ||
1751 | |||
1752 | /* If we get back 0xFFFF then we must suspect that the card has been | ||
1753 | * pulled but the Linux PCI layer has not yet finished cleaning up. | ||
1754 | * We don't want to report on such devices | ||
1755 | */ | ||
1756 | |||
1757 | if (status == 0xFFFF) { | ||
1758 | u32 sanity; | ||
1759 | |||
1760 | pci_read_config_dword(dev, 0, &sanity); | ||
1761 | |||
1762 | if (sanity == 0xFFFFFFFF) | ||
1763 | return 0; | ||
1764 | } | ||
1765 | |||
1766 | status &= PCI_STATUS_DETECTED_PARITY | PCI_STATUS_SIG_SYSTEM_ERROR | | ||
1767 | PCI_STATUS_PARITY; | ||
1768 | |||
1769 | if (status) | ||
1770 | /* reset only the bits we are interested in */ | ||
1771 | pci_write_config_word(dev, where, status); | ||
1772 | |||
1773 | return status; | ||
1774 | } | ||
1775 | |||
1776 | typedef void (*pci_parity_check_fn_t) (struct pci_dev *dev); | ||
1777 | |||
1778 | /* Clear any PCI parity errors logged by this device. */ | ||
1779 | static void edac_pci_dev_parity_clear(struct pci_dev *dev) | ||
1780 | { | ||
1781 | u8 header_type; | ||
1782 | |||
1783 | get_pci_parity_status(dev, 0); | ||
1784 | |||
1785 | /* read the device TYPE, looking for bridges */ | ||
1786 | pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type); | ||
1787 | |||
1788 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) | ||
1789 | get_pci_parity_status(dev, 1); | ||
1790 | } | ||
1791 | |||
1792 | /* | ||
1793 | * PCI Parity polling | ||
1794 | * | ||
1795 | */ | ||
1796 | static void edac_pci_dev_parity_test(struct pci_dev *dev) | ||
1797 | { | ||
1798 | u16 status; | ||
1799 | u8 header_type; | ||
1800 | |||
1801 | /* read the STATUS register on this device | ||
1802 | */ | ||
1803 | status = get_pci_parity_status(dev, 0); | ||
1804 | |||
1805 | debugf2("PCI STATUS= 0x%04x %s\n", status, dev->dev.bus_id ); | ||
1806 | |||
1807 | /* check the status reg for errors */ | ||
1808 | if (status) { | ||
1809 | if (status & (PCI_STATUS_SIG_SYSTEM_ERROR)) | ||
1810 | edac_printk(KERN_CRIT, EDAC_PCI, | ||
1811 | "Signaled System Error on %s\n", | ||
1812 | pci_name(dev)); | ||
1813 | |||
1814 | if (status & (PCI_STATUS_PARITY)) { | ||
1815 | edac_printk(KERN_CRIT, EDAC_PCI, | ||
1816 | "Master Data Parity Error on %s\n", | ||
1817 | pci_name(dev)); | ||
1818 | |||
1819 | atomic_inc(&pci_parity_count); | ||
1820 | } | ||
1821 | |||
1822 | if (status & (PCI_STATUS_DETECTED_PARITY)) { | ||
1823 | edac_printk(KERN_CRIT, EDAC_PCI, | ||
1824 | "Detected Parity Error on %s\n", | ||
1825 | pci_name(dev)); | ||
1826 | |||
1827 | atomic_inc(&pci_parity_count); | ||
1828 | } | ||
1829 | } | ||
1830 | |||
1831 | /* read the device TYPE, looking for bridges */ | ||
1832 | pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type); | ||
1833 | |||
1834 | debugf2("PCI HEADER TYPE= 0x%02x %s\n", header_type, dev->dev.bus_id ); | ||
1835 | |||
1836 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { | ||
1837 | /* On bridges, need to examine secondary status register */ | ||
1838 | status = get_pci_parity_status(dev, 1); | ||
1839 | |||
1840 | debugf2("PCI SEC_STATUS= 0x%04x %s\n", | ||
1841 | status, dev->dev.bus_id ); | ||
1842 | |||
1843 | /* check the secondary status reg for errors */ | ||
1844 | if (status) { | ||
1845 | if (status & (PCI_STATUS_SIG_SYSTEM_ERROR)) | ||
1846 | edac_printk(KERN_CRIT, EDAC_PCI, "Bridge " | ||
1847 | "Signaled System Error on %s\n", | ||
1848 | pci_name(dev)); | ||
1849 | |||
1850 | if (status & (PCI_STATUS_PARITY)) { | ||
1851 | edac_printk(KERN_CRIT, EDAC_PCI, "Bridge " | ||
1852 | "Master Data Parity Error on " | ||
1853 | "%s\n", pci_name(dev)); | ||
1854 | |||
1855 | atomic_inc(&pci_parity_count); | ||
1856 | } | ||
1857 | |||
1858 | if (status & (PCI_STATUS_DETECTED_PARITY)) { | ||
1859 | edac_printk(KERN_CRIT, EDAC_PCI, "Bridge " | ||
1860 | "Detected Parity Error on %s\n", | ||
1861 | pci_name(dev)); | ||
1862 | |||
1863 | atomic_inc(&pci_parity_count); | ||
1864 | } | ||
1865 | } | ||
1866 | } | ||
1867 | } | ||
1868 | |||
1869 | /* | ||
1870 | * check_dev_on_list: Scan for a PCI device on a white/black list | ||
1871 | * @list: an EDAC &edac_pci_device_list white/black list pointer | ||
1872 | * @free_index: index of next free entry on the list | ||
1873 | * @pci_dev: PCI Device pointer | ||
1874 | * | ||
1875 | * see if list contains the device. | ||
1876 | * | ||
1877 | * Returns: 0 not found | ||
1878 | * 1 found on list | ||
1879 | */ | ||
1880 | static int check_dev_on_list(struct edac_pci_device_list *list, | ||
1881 | int free_index, struct pci_dev *dev) | ||
1882 | { | ||
1883 | int i; | ||
1884 | int rc = 0; /* Assume not found */ | ||
1885 | unsigned short vendor=dev->vendor; | ||
1886 | unsigned short device=dev->device; | ||
1887 | |||
1888 | /* Scan the list, looking for a vendor/device match */ | ||
1889 | for (i = 0; i < free_index; i++, list++ ) { | ||
1890 | if ((list->vendor == vendor ) && (list->device == device )) { | ||
1891 | rc = 1; | ||
1892 | break; | ||
1893 | } | ||
1894 | } | ||
1895 | |||
1896 | return rc; | ||
1897 | } | ||
1898 | |||
1899 | /* | ||
1900 | * pci_dev parity list iterator | ||
1901 | * Scan the PCI device list for one iteration, looking for SERRORs | ||
1902 | * Master Parity ERRORS or Parity ERRORs on primary or secondary devices | ||
1903 | */ | ||
1904 | static inline void edac_pci_dev_parity_iterator(pci_parity_check_fn_t fn) | ||
1905 | { | ||
1906 | struct pci_dev *dev = NULL; | ||
1907 | |||
1908 | /* request for kernel access to the next PCI device, if any, | ||
1909 | * and while we are looking at it have its reference count | ||
1910 | * bumped until we are done with it | ||
1911 | */ | ||
1912 | while((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | ||
1913 | /* if whitelist exists then it has priority, so only scan | ||
1914 | * those devices on the whitelist | ||
1915 | */ | ||
1916 | if (pci_whitelist_count > 0 ) { | ||
1917 | if (check_dev_on_list(pci_whitelist, | ||
1918 | pci_whitelist_count, dev)) | ||
1919 | fn(dev); | ||
1920 | } else { | ||
1921 | /* | ||
1922 | * if no whitelist, then check if this devices is | ||
1923 | * blacklisted | ||
1924 | */ | ||
1925 | if (!check_dev_on_list(pci_blacklist, | ||
1926 | pci_blacklist_count, dev)) | ||
1927 | fn(dev); | ||
1928 | } | ||
1929 | } | ||
1930 | } | ||
1931 | |||
1932 | static void do_pci_parity_check(void) | ||
1933 | { | ||
1934 | unsigned long flags; | ||
1935 | int before_count; | ||
1936 | |||
1937 | debugf3("%s()\n", __func__); | ||
1938 | |||
1939 | if (!check_pci_parity) | ||
1940 | return; | ||
1941 | |||
1942 | before_count = atomic_read(&pci_parity_count); | ||
1943 | |||
1944 | /* scan all PCI devices looking for a Parity Error on devices and | ||
1945 | * bridges | ||
1946 | */ | ||
1947 | local_irq_save(flags); | ||
1948 | edac_pci_dev_parity_iterator(edac_pci_dev_parity_test); | ||
1949 | local_irq_restore(flags); | ||
1950 | |||
1951 | /* Only if operator has selected panic on PCI Error */ | ||
1952 | if (panic_on_pci_parity) { | ||
1953 | /* If the count is different 'after' from 'before' */ | ||
1954 | if (before_count != atomic_read(&pci_parity_count)) | ||
1955 | panic("EDAC: PCI Parity Error"); | ||
1956 | } | ||
1957 | } | ||
1958 | |||
1959 | static inline void clear_pci_parity_errors(void) | ||
1960 | { | ||
1961 | /* Clear any PCI bus parity errors that devices initially have logged | ||
1962 | * in their registers. | ||
1963 | */ | ||
1964 | edac_pci_dev_parity_iterator(edac_pci_dev_parity_clear); | ||
1965 | } | ||
1966 | |||
1967 | #else /* CONFIG_PCI */ | ||
1968 | |||
1969 | static inline void do_pci_parity_check(void) | ||
1970 | { | ||
1971 | /* no-op */ | ||
1972 | } | ||
1973 | |||
1974 | static inline void clear_pci_parity_errors(void) | ||
1975 | { | ||
1976 | /* no-op */ | ||
1977 | } | ||
1978 | |||
1979 | #endif /* CONFIG_PCI */ | ||
1980 | 1994 | ||
1981 | /* | 1995 | /* |
1982 | * Iterate over all MC instances and check for ECC, et al, errors | 1996 | * Iterate over all MC instances and check for ECC, et al, errors |
@@ -2096,10 +2110,12 @@ MODULE_DESCRIPTION("Core library routines for MC reporting"); | |||
2096 | 2110 | ||
2097 | module_param(panic_on_ue, int, 0644); | 2111 | module_param(panic_on_ue, int, 0644); |
2098 | MODULE_PARM_DESC(panic_on_ue, "Panic on uncorrected error: 0=off 1=on"); | 2112 | MODULE_PARM_DESC(panic_on_ue, "Panic on uncorrected error: 0=off 1=on"); |
2113 | #ifdef CONFIG_PCI | ||
2099 | module_param(check_pci_parity, int, 0644); | 2114 | module_param(check_pci_parity, int, 0644); |
2100 | MODULE_PARM_DESC(check_pci_parity, "Check for PCI bus parity errors: 0=off 1=on"); | 2115 | MODULE_PARM_DESC(check_pci_parity, "Check for PCI bus parity errors: 0=off 1=on"); |
2101 | module_param(panic_on_pci_parity, int, 0644); | 2116 | module_param(panic_on_pci_parity, int, 0644); |
2102 | MODULE_PARM_DESC(panic_on_pci_parity, "Panic on PCI Bus Parity error: 0=off 1=on"); | 2117 | MODULE_PARM_DESC(panic_on_pci_parity, "Panic on PCI Bus Parity error: 0=off 1=on"); |
2118 | #endif | ||
2103 | module_param(log_ue, int, 0644); | 2119 | module_param(log_ue, int, 0644); |
2104 | MODULE_PARM_DESC(log_ue, "Log uncorrectable error to console: 0=off 1=on"); | 2120 | MODULE_PARM_DESC(log_ue, "Log uncorrectable error to console: 0=off 1=on"); |
2105 | module_param(log_ce, int, 0644); | 2121 | module_param(log_ce, int, 0644); |
diff --git a/drivers/edac/edac_mc.h b/drivers/edac/edac_mc.h index 8d9e83909b9c..a2c3a4607a89 100644 --- a/drivers/edac/edac_mc.h +++ b/drivers/edac/edac_mc.h | |||
@@ -88,6 +88,12 @@ extern int edac_debug_level; | |||
88 | #define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \ | 88 | #define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \ |
89 | PCI_DEVICE_ID_ ## vend ## _ ## dev | 89 | PCI_DEVICE_ID_ ## vend ## _ ## dev |
90 | 90 | ||
91 | #if defined(CONFIG_X86) && defined(CONFIG_PCI) | ||
92 | #define dev_name(dev) pci_name(to_pci_dev(dev)) | ||
93 | #else | ||
94 | #define dev_name(dev) to_platform_device(dev)->name | ||
95 | #endif | ||
96 | |||
91 | /* memory devices */ | 97 | /* memory devices */ |
92 | enum dev_type { | 98 | enum dev_type { |
93 | DEV_UNKNOWN = 0, | 99 | DEV_UNKNOWN = 0, |
@@ -327,10 +333,10 @@ struct mem_ctl_info { | |||
327 | struct csrow_info *csrows; | 333 | struct csrow_info *csrows; |
328 | /* | 334 | /* |
329 | * FIXME - what about controllers on other busses? - IDs must be | 335 | * FIXME - what about controllers on other busses? - IDs must be |
330 | * unique. pdev pointer should be sufficiently unique, but | 336 | * unique. dev pointer should be sufficiently unique, but |
331 | * BUS:SLOT.FUNC numbers may not be unique. | 337 | * BUS:SLOT.FUNC numbers may not be unique. |
332 | */ | 338 | */ |
333 | struct pci_dev *pdev; | 339 | struct device *dev; |
334 | const char *mod_name; | 340 | const char *mod_name; |
335 | const char *mod_ver; | 341 | const char *mod_ver; |
336 | const char *ctl_name; | 342 | const char *ctl_name; |
@@ -353,6 +359,8 @@ struct mem_ctl_info { | |||
353 | struct completion kobj_complete; | 359 | struct completion kobj_complete; |
354 | }; | 360 | }; |
355 | 361 | ||
362 | #ifdef CONFIG_PCI | ||
363 | |||
356 | /* write all or some bits in a byte-register*/ | 364 | /* write all or some bits in a byte-register*/ |
357 | static inline void pci_write_bits8(struct pci_dev *pdev, int offset, u8 value, | 365 | static inline void pci_write_bits8(struct pci_dev *pdev, int offset, u8 value, |
358 | u8 mask) | 366 | u8 mask) |
@@ -401,6 +409,8 @@ static inline void pci_write_bits32(struct pci_dev *pdev, int offset, | |||
401 | pci_write_config_dword(pdev, offset, value); | 409 | pci_write_config_dword(pdev, offset, value); |
402 | } | 410 | } |
403 | 411 | ||
412 | #endif /* CONFIG_PCI */ | ||
413 | |||
404 | #ifdef CONFIG_EDAC_DEBUG | 414 | #ifdef CONFIG_EDAC_DEBUG |
405 | void edac_mc_dump_channel(struct channel_info *chan); | 415 | void edac_mc_dump_channel(struct channel_info *chan); |
406 | void edac_mc_dump_mci(struct mem_ctl_info *mci); | 416 | void edac_mc_dump_mci(struct mem_ctl_info *mci); |
@@ -408,7 +418,7 @@ void edac_mc_dump_csrow(struct csrow_info *csrow); | |||
408 | #endif /* CONFIG_EDAC_DEBUG */ | 418 | #endif /* CONFIG_EDAC_DEBUG */ |
409 | 419 | ||
410 | extern int edac_mc_add_mc(struct mem_ctl_info *mci); | 420 | extern int edac_mc_add_mc(struct mem_ctl_info *mci); |
411 | extern struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev); | 421 | extern struct mem_ctl_info * edac_mc_del_mc(struct device *dev); |
412 | extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, | 422 | extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, |
413 | unsigned long page); | 423 | unsigned long page); |
414 | extern void edac_mc_scrub_block(unsigned long page, unsigned long offset, | 424 | extern void edac_mc_scrub_block(unsigned long page, unsigned long offset, |
diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c index fd342163cf97..baa021b96d18 100644 --- a/drivers/edac/i82860_edac.c +++ b/drivers/edac/i82860_edac.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include "edac_mc.h" | 18 | #include "edac_mc.h" |
19 | 19 | ||
20 | #define I82860_REVISION " Ver: 2.0.0 " __DATE__ | ||
21 | |||
20 | #define i82860_printk(level, fmt, arg...) \ | 22 | #define i82860_printk(level, fmt, arg...) \ |
21 | edac_printk(level, "i82860", fmt, ##arg) | 23 | edac_printk(level, "i82860", fmt, ##arg) |
22 | 24 | ||
@@ -63,17 +65,21 @@ static struct pci_dev *mci_pdev = NULL; /* init dev: in case that AGP code | |||
63 | static void i82860_get_error_info(struct mem_ctl_info *mci, | 65 | static void i82860_get_error_info(struct mem_ctl_info *mci, |
64 | struct i82860_error_info *info) | 66 | struct i82860_error_info *info) |
65 | { | 67 | { |
68 | struct pci_dev *pdev; | ||
69 | |||
70 | pdev = to_pci_dev(mci->dev); | ||
71 | |||
66 | /* | 72 | /* |
67 | * This is a mess because there is no atomic way to read all the | 73 | * This is a mess because there is no atomic way to read all the |
68 | * registers at once and the registers can transition from CE being | 74 | * registers at once and the registers can transition from CE being |
69 | * overwritten by UE. | 75 | * overwritten by UE. |
70 | */ | 76 | */ |
71 | pci_read_config_word(mci->pdev, I82860_ERRSTS, &info->errsts); | 77 | pci_read_config_word(pdev, I82860_ERRSTS, &info->errsts); |
72 | pci_read_config_dword(mci->pdev, I82860_EAP, &info->eap); | 78 | pci_read_config_dword(pdev, I82860_EAP, &info->eap); |
73 | pci_read_config_word(mci->pdev, I82860_DERRCTL_STS, &info->derrsyn); | 79 | pci_read_config_word(pdev, I82860_DERRCTL_STS, &info->derrsyn); |
74 | pci_read_config_word(mci->pdev, I82860_ERRSTS, &info->errsts2); | 80 | pci_read_config_word(pdev, I82860_ERRSTS, &info->errsts2); |
75 | 81 | ||
76 | pci_write_bits16(mci->pdev, I82860_ERRSTS, 0x0003, 0x0003); | 82 | pci_write_bits16(pdev, I82860_ERRSTS, 0x0003, 0x0003); |
77 | 83 | ||
78 | /* | 84 | /* |
79 | * If the error is the same for both reads then the first set of reads | 85 | * If the error is the same for both reads then the first set of reads |
@@ -84,8 +90,8 @@ static void i82860_get_error_info(struct mem_ctl_info *mci, | |||
84 | return; | 90 | return; |
85 | 91 | ||
86 | if ((info->errsts ^ info->errsts2) & 0x0003) { | 92 | if ((info->errsts ^ info->errsts2) & 0x0003) { |
87 | pci_read_config_dword(mci->pdev, I82860_EAP, &info->eap); | 93 | pci_read_config_dword(pdev, I82860_EAP, &info->eap); |
88 | pci_read_config_word(mci->pdev, I82860_DERRCTL_STS, | 94 | pci_read_config_word(pdev, I82860_DERRCTL_STS, |
89 | &info->derrsyn); | 95 | &info->derrsyn); |
90 | } | 96 | } |
91 | } | 97 | } |
@@ -151,7 +157,7 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) | |||
151 | return -ENOMEM; | 157 | return -ENOMEM; |
152 | 158 | ||
153 | debugf3("%s(): init mci\n", __func__); | 159 | debugf3("%s(): init mci\n", __func__); |
154 | mci->pdev = pdev; | 160 | mci->dev = &pdev->dev; |
155 | mci->mtype_cap = MEM_FLAG_DDR; | 161 | mci->mtype_cap = MEM_FLAG_DDR; |
156 | 162 | ||
157 | mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; | 163 | mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; |
@@ -160,12 +166,12 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) | |||
160 | /* adjust FLAGS */ | 166 | /* adjust FLAGS */ |
161 | 167 | ||
162 | mci->mod_name = EDAC_MOD_STR; | 168 | mci->mod_name = EDAC_MOD_STR; |
163 | mci->mod_ver = "$Revision: 1.1.2.6 $"; | 169 | mci->mod_ver = I82860_REVISION; |
164 | mci->ctl_name = i82860_devs[dev_idx].ctl_name; | 170 | mci->ctl_name = i82860_devs[dev_idx].ctl_name; |
165 | mci->edac_check = i82860_check; | 171 | mci->edac_check = i82860_check; |
166 | mci->ctl_page_to_phys = NULL; | 172 | mci->ctl_page_to_phys = NULL; |
167 | 173 | ||
168 | pci_read_config_word(mci->pdev, I82860_MCHCFG, &mchcfg_ddim); | 174 | pci_read_config_word(pdev, I82860_MCHCFG, &mchcfg_ddim); |
169 | mchcfg_ddim = mchcfg_ddim & 0x180; | 175 | mchcfg_ddim = mchcfg_ddim & 0x180; |
170 | 176 | ||
171 | /* | 177 | /* |
@@ -179,7 +185,7 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) | |||
179 | u32 cumul_size; | 185 | u32 cumul_size; |
180 | struct csrow_info *csrow = &mci->csrows[index]; | 186 | struct csrow_info *csrow = &mci->csrows[index]; |
181 | 187 | ||
182 | pci_read_config_word(mci->pdev, I82860_GBA + index * 2, | 188 | pci_read_config_word(pdev, I82860_GBA + index * 2, |
183 | &value); | 189 | &value); |
184 | 190 | ||
185 | cumul_size = (value & I82860_GBA_MASK) << | 191 | cumul_size = (value & I82860_GBA_MASK) << |
@@ -240,7 +246,7 @@ static void __devexit i82860_remove_one(struct pci_dev *pdev) | |||
240 | 246 | ||
241 | debugf0("%s()\n", __func__); | 247 | debugf0("%s()\n", __func__); |
242 | 248 | ||
243 | if ((mci = edac_mc_del_mc(pdev)) == NULL) | 249 | if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL) |
244 | return; | 250 | return; |
245 | 251 | ||
246 | edac_mc_free(mci); | 252 | edac_mc_free(mci); |
diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c index 0aec92698f17..3f509a7ea02a 100644 --- a/drivers/edac/i82875p_edac.c +++ b/drivers/edac/i82875p_edac.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include "edac_mc.h" | 22 | #include "edac_mc.h" |
23 | 23 | ||
24 | #define I82875P_REVISION " Ver: 2.0.0 " __DATE__ | ||
25 | |||
24 | #define i82875p_printk(level, fmt, arg...) \ | 26 | #define i82875p_printk(level, fmt, arg...) \ |
25 | edac_printk(level, "i82875p", fmt, ##arg) | 27 | edac_printk(level, "i82875p", fmt, ##arg) |
26 | 28 | ||
@@ -185,18 +187,22 @@ static int i82875p_registered = 1; | |||
185 | static void i82875p_get_error_info(struct mem_ctl_info *mci, | 187 | static void i82875p_get_error_info(struct mem_ctl_info *mci, |
186 | struct i82875p_error_info *info) | 188 | struct i82875p_error_info *info) |
187 | { | 189 | { |
190 | struct pci_dev *pdev; | ||
191 | |||
192 | pdev = to_pci_dev(mci->dev); | ||
193 | |||
188 | /* | 194 | /* |
189 | * This is a mess because there is no atomic way to read all the | 195 | * This is a mess because there is no atomic way to read all the |
190 | * registers at once and the registers can transition from CE being | 196 | * registers at once and the registers can transition from CE being |
191 | * overwritten by UE. | 197 | * overwritten by UE. |
192 | */ | 198 | */ |
193 | pci_read_config_word(mci->pdev, I82875P_ERRSTS, &info->errsts); | 199 | pci_read_config_word(pdev, I82875P_ERRSTS, &info->errsts); |
194 | pci_read_config_dword(mci->pdev, I82875P_EAP, &info->eap); | 200 | pci_read_config_dword(pdev, I82875P_EAP, &info->eap); |
195 | pci_read_config_byte(mci->pdev, I82875P_DES, &info->des); | 201 | pci_read_config_byte(pdev, I82875P_DES, &info->des); |
196 | pci_read_config_byte(mci->pdev, I82875P_DERRSYN, &info->derrsyn); | 202 | pci_read_config_byte(pdev, I82875P_DERRSYN, &info->derrsyn); |
197 | pci_read_config_word(mci->pdev, I82875P_ERRSTS, &info->errsts2); | 203 | pci_read_config_word(pdev, I82875P_ERRSTS, &info->errsts2); |
198 | 204 | ||
199 | pci_write_bits16(mci->pdev, I82875P_ERRSTS, 0x0081, 0x0081); | 205 | pci_write_bits16(pdev, I82875P_ERRSTS, 0x0081, 0x0081); |
200 | 206 | ||
201 | /* | 207 | /* |
202 | * If the error is the same then we can for both reads then | 208 | * If the error is the same then we can for both reads then |
@@ -208,9 +214,9 @@ static void i82875p_get_error_info(struct mem_ctl_info *mci, | |||
208 | return; | 214 | return; |
209 | 215 | ||
210 | if ((info->errsts ^ info->errsts2) & 0x0081) { | 216 | if ((info->errsts ^ info->errsts2) & 0x0081) { |
211 | pci_read_config_dword(mci->pdev, I82875P_EAP, &info->eap); | 217 | pci_read_config_dword(pdev, I82875P_EAP, &info->eap); |
212 | pci_read_config_byte(mci->pdev, I82875P_DES, &info->des); | 218 | pci_read_config_byte(pdev, I82875P_DES, &info->des); |
213 | pci_read_config_byte(mci->pdev, I82875P_DERRSYN, | 219 | pci_read_config_byte(pdev, I82875P_DERRSYN, |
214 | &info->derrsyn); | 220 | &info->derrsyn); |
215 | } | 221 | } |
216 | } | 222 | } |
@@ -337,14 +343,14 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) | |||
337 | } | 343 | } |
338 | 344 | ||
339 | debugf3("%s(): init mci\n", __func__); | 345 | debugf3("%s(): init mci\n", __func__); |
340 | mci->pdev = pdev; | 346 | mci->dev = &pdev->dev; |
341 | mci->mtype_cap = MEM_FLAG_DDR; | 347 | mci->mtype_cap = MEM_FLAG_DDR; |
342 | mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; | 348 | mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; |
343 | mci->edac_cap = EDAC_FLAG_UNKNOWN; | 349 | mci->edac_cap = EDAC_FLAG_UNKNOWN; |
344 | /* adjust FLAGS */ | 350 | /* adjust FLAGS */ |
345 | 351 | ||
346 | mci->mod_name = EDAC_MOD_STR; | 352 | mci->mod_name = EDAC_MOD_STR; |
347 | mci->mod_ver = "$Revision: 1.5.2.11 $"; | 353 | mci->mod_ver = I82875P_REVISION; |
348 | mci->ctl_name = i82875p_devs[dev_idx].ctl_name; | 354 | mci->ctl_name = i82875p_devs[dev_idx].ctl_name; |
349 | mci->edac_check = i82875p_check; | 355 | mci->edac_check = i82875p_check; |
350 | mci->ctl_page_to_phys = NULL; | 356 | mci->ctl_page_to_phys = NULL; |
@@ -437,7 +443,7 @@ static void __devexit i82875p_remove_one(struct pci_dev *pdev) | |||
437 | 443 | ||
438 | debugf0("%s()\n", __func__); | 444 | debugf0("%s()\n", __func__); |
439 | 445 | ||
440 | if ((mci = edac_mc_del_mc(pdev)) == NULL) | 446 | if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL) |
441 | return; | 447 | return; |
442 | 448 | ||
443 | pvt = (struct i82875p_pvt *) mci->pvt_info; | 449 | pvt = (struct i82875p_pvt *) mci->pvt_info; |
diff --git a/drivers/edac/r82600_edac.c b/drivers/edac/r82600_edac.c index 2c29fafe67c7..d04769aade5d 100644 --- a/drivers/edac/r82600_edac.c +++ b/drivers/edac/r82600_edac.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include "edac_mc.h" | 24 | #include "edac_mc.h" |
25 | 25 | ||
26 | #define R82600_REVISION " Ver: 2.0.0 " __DATE__ | ||
27 | |||
26 | #define r82600_printk(level, fmt, arg...) \ | 28 | #define r82600_printk(level, fmt, arg...) \ |
27 | edac_printk(level, "r82600", fmt, ##arg) | 29 | edac_printk(level, "r82600", fmt, ##arg) |
28 | 30 | ||
@@ -134,17 +136,20 @@ static unsigned int disable_hardware_scrub = 0; | |||
134 | static void r82600_get_error_info (struct mem_ctl_info *mci, | 136 | static void r82600_get_error_info (struct mem_ctl_info *mci, |
135 | struct r82600_error_info *info) | 137 | struct r82600_error_info *info) |
136 | { | 138 | { |
137 | pci_read_config_dword(mci->pdev, R82600_EAP, &info->eapr); | 139 | struct pci_dev *pdev; |
140 | |||
141 | pdev = to_pci_dev(mci->dev); | ||
142 | pci_read_config_dword(pdev, R82600_EAP, &info->eapr); | ||
138 | 143 | ||
139 | if (info->eapr & BIT(0)) | 144 | if (info->eapr & BIT(0)) |
140 | /* Clear error to allow next error to be reported [p.62] */ | 145 | /* Clear error to allow next error to be reported [p.62] */ |
141 | pci_write_bits32(mci->pdev, R82600_EAP, | 146 | pci_write_bits32(pdev, R82600_EAP, |
142 | ((u32) BIT(0) & (u32) BIT(1)), | 147 | ((u32) BIT(0) & (u32) BIT(1)), |
143 | ((u32) BIT(0) & (u32) BIT(1))); | 148 | ((u32) BIT(0) & (u32) BIT(1))); |
144 | 149 | ||
145 | if (info->eapr & BIT(1)) | 150 | if (info->eapr & BIT(1)) |
146 | /* Clear error to allow next error to be reported [p.62] */ | 151 | /* Clear error to allow next error to be reported [p.62] */ |
147 | pci_write_bits32(mci->pdev, R82600_EAP, | 152 | pci_write_bits32(pdev, R82600_EAP, |
148 | ((u32) BIT(0) & (u32) BIT(1)), | 153 | ((u32) BIT(0) & (u32) BIT(1)), |
149 | ((u32) BIT(0) & (u32) BIT(1))); | 154 | ((u32) BIT(0) & (u32) BIT(1))); |
150 | } | 155 | } |
@@ -232,7 +237,7 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) | |||
232 | } | 237 | } |
233 | 238 | ||
234 | debugf0("%s(): mci = %p\n", __func__, mci); | 239 | debugf0("%s(): mci = %p\n", __func__, mci); |
235 | mci->pdev = pdev; | 240 | mci->dev = &pdev->dev; |
236 | mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR; | 241 | mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR; |
237 | mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; | 242 | mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; |
238 | /* FIXME try to work out if the chip leads have been used for COM2 | 243 | /* FIXME try to work out if the chip leads have been used for COM2 |
@@ -253,7 +258,7 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) | |||
253 | mci->edac_cap = EDAC_FLAG_NONE; | 258 | mci->edac_cap = EDAC_FLAG_NONE; |
254 | 259 | ||
255 | mci->mod_name = EDAC_MOD_STR; | 260 | mci->mod_name = EDAC_MOD_STR; |
256 | mci->mod_ver = "$Revision: 1.1.2.6 $"; | 261 | mci->mod_ver = R82600_REVISION; |
257 | mci->ctl_name = "R82600"; | 262 | mci->ctl_name = "R82600"; |
258 | mci->edac_check = r82600_check; | 263 | mci->edac_check = r82600_check; |
259 | mci->ctl_page_to_phys = NULL; | 264 | mci->ctl_page_to_phys = NULL; |
@@ -265,7 +270,7 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) | |||
265 | u32 row_base; | 270 | u32 row_base; |
266 | 271 | ||
267 | /* find the DRAM Chip Select Base address and mask */ | 272 | /* find the DRAM Chip Select Base address and mask */ |
268 | pci_read_config_byte(mci->pdev, R82600_DRBA + index, &drbar); | 273 | pci_read_config_byte(pdev, R82600_DRBA + index, &drbar); |
269 | 274 | ||
270 | debugf1("MC%d: %s() Row=%d DRBA = %#0x\n", mci->mc_idx, | 275 | debugf1("MC%d: %s() Row=%d DRBA = %#0x\n", mci->mc_idx, |
271 | __func__, index, drbar); | 276 | __func__, index, drbar); |
@@ -309,7 +314,7 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) | |||
309 | if (disable_hardware_scrub) { | 314 | if (disable_hardware_scrub) { |
310 | debugf3("%s(): Disabling Hardware Scrub (scrub on error)\n", | 315 | debugf3("%s(): Disabling Hardware Scrub (scrub on error)\n", |
311 | __func__); | 316 | __func__); |
312 | pci_write_bits32(mci->pdev, R82600_EAP, BIT(31), BIT(31)); | 317 | pci_write_bits32(pdev, R82600_EAP, BIT(31), BIT(31)); |
313 | } | 318 | } |
314 | 319 | ||
315 | debugf3("%s(): success\n", __func__); | 320 | debugf3("%s(): success\n", __func__); |
@@ -338,7 +343,7 @@ static void __devexit r82600_remove_one(struct pci_dev *pdev) | |||
338 | 343 | ||
339 | debugf0("%s()\n", __func__); | 344 | debugf0("%s()\n", __func__); |
340 | 345 | ||
341 | if ((mci = edac_mc_del_mc(pdev)) == NULL) | 346 | if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL) |
342 | return; | 347 | return; |
343 | 348 | ||
344 | edac_mc_free(mci); | 349 | edac_mc_free(mci); |