aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/edac_mc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac/edac_mc.c')
-rw-r--r--drivers/edac/edac_mc.c325
1 files changed, 149 insertions, 176 deletions
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index f67a4d6f8974..bb3460457fa3 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -12,7 +12,6 @@
12 * 12 *
13 */ 13 */
14 14
15
16#include <linux/config.h> 15#include <linux/config.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/proc_fs.h> 17#include <linux/proc_fs.h>
@@ -30,14 +29,12 @@
30#include <linux/sysdev.h> 29#include <linux/sysdev.h>
31#include <linux/ctype.h> 30#include <linux/ctype.h>
32#include <linux/kthread.h> 31#include <linux/kthread.h>
33
34#include <asm/uaccess.h> 32#include <asm/uaccess.h>
35#include <asm/page.h> 33#include <asm/page.h>
36#include <asm/edac.h> 34#include <asm/edac.h>
37
38#include "edac_mc.h" 35#include "edac_mc.h"
39 36
40#define EDAC_MC_VERSION "Ver: 2.0.0 " __DATE__ 37#define EDAC_MC_VERSION "Ver: 2.0.0 " __DATE__
41 38
42/* For now, disable the EDAC sysfs code. The sysfs interface that EDAC 39/* For now, disable the EDAC sysfs code. The sysfs interface that EDAC
43 * presents to user space needs more thought, and is likely to change 40 * presents to user space needs more thought, and is likely to change
@@ -73,7 +70,6 @@ struct edac_pci_device_list {
73 unsigned int device; /* Deviice ID */ 70 unsigned int device; /* Deviice ID */
74}; 71};
75 72
76
77#define MAX_LISTED_PCI_DEVICES 32 73#define MAX_LISTED_PCI_DEVICES 32
78 74
79/* List of PCI devices (vendor-id:device-id) that should be skipped */ 75/* List of PCI devices (vendor-id:device-id) that should be skipped */
@@ -126,7 +122,6 @@ static const char *edac_caps[] = {
126 [EDAC_S16ECD16ED] = "S16ECD16ED" 122 [EDAC_S16ECD16ED] = "S16ECD16ED"
127}; 123};
128 124
129
130/* sysfs object: /sys/devices/system/edac */ 125/* sysfs object: /sys/devices/system/edac */
131static struct sysdev_class edac_class = { 126static struct sysdev_class edac_class = {
132 set_kset_name("edac"), 127 set_kset_name("edac"),
@@ -147,7 +142,7 @@ static struct completion edac_pci_kobj_complete;
147 142
148/* 143/*
149 * /sys/devices/system/edac/mc; 144 * /sys/devices/system/edac/mc;
150 * data structures and methods 145 * data structures and methods
151 */ 146 */
152#if 0 147#if 0
153static ssize_t memctrl_string_show(void *ptr, char *buffer) 148static ssize_t memctrl_string_show(void *ptr, char *buffer)
@@ -174,33 +169,34 @@ static ssize_t memctrl_int_store(void *ptr, const char *buffer, size_t count)
174} 169}
175 170
176struct memctrl_dev_attribute { 171struct memctrl_dev_attribute {
177 struct attribute attr; 172 struct attribute attr;
178 void *value; 173 void *value;
179 ssize_t (*show)(void *,char *); 174 ssize_t (*show)(void *,char *);
180 ssize_t (*store)(void *, const char *, size_t); 175 ssize_t (*store)(void *, const char *, size_t);
181}; 176};
182 177
183/* Set of show/store abstract level functions for memory control object */ 178/* Set of show/store abstract level functions for memory control object */
184static ssize_t 179static ssize_t memctrl_dev_show(struct kobject *kobj,
185memctrl_dev_show(struct kobject *kobj, struct attribute *attr, char *buffer) 180 struct attribute *attr, char *buffer)
186{ 181{
187 struct memctrl_dev_attribute *memctrl_dev; 182 struct memctrl_dev_attribute *memctrl_dev;
188 memctrl_dev = (struct memctrl_dev_attribute*)attr; 183 memctrl_dev = (struct memctrl_dev_attribute*)attr;
189 184
190 if (memctrl_dev->show) 185 if (memctrl_dev->show)
191 return memctrl_dev->show(memctrl_dev->value, buffer); 186 return memctrl_dev->show(memctrl_dev->value, buffer);
187
192 return -EIO; 188 return -EIO;
193} 189}
194 190
195static ssize_t 191static ssize_t memctrl_dev_store(struct kobject *kobj, struct attribute *attr,
196memctrl_dev_store(struct kobject *kobj, struct attribute *attr, 192 const char *buffer, size_t count)
197 const char *buffer, size_t count)
198{ 193{
199 struct memctrl_dev_attribute *memctrl_dev; 194 struct memctrl_dev_attribute *memctrl_dev;
200 memctrl_dev = (struct memctrl_dev_attribute*)attr; 195 memctrl_dev = (struct memctrl_dev_attribute*)attr;
201 196
202 if (memctrl_dev->store) 197 if (memctrl_dev->store)
203 return memctrl_dev->store(memctrl_dev->value, buffer, count); 198 return memctrl_dev->store(memctrl_dev->value, buffer, count);
199
204 return -EIO; 200 return -EIO;
205} 201}
206 202
@@ -236,7 +232,6 @@ MEMCTRL_ATTR(log_ue,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
236MEMCTRL_ATTR(log_ce,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store); 232MEMCTRL_ATTR(log_ce,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
237MEMCTRL_ATTR(poll_msec,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store); 233MEMCTRL_ATTR(poll_msec,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
238 234
239
240/* Base Attributes of the memory ECC object */ 235/* Base Attributes of the memory ECC object */
241static struct memctrl_dev_attribute *memctrl_attr[] = { 236static struct memctrl_dev_attribute *memctrl_attr[] = {
242 &attr_panic_on_ue, 237 &attr_panic_on_ue,
@@ -254,9 +249,9 @@ static void edac_memctrl_master_release(struct kobject *kobj)
254} 249}
255 250
256static struct kobj_type ktype_memctrl = { 251static struct kobj_type ktype_memctrl = {
257 .release = edac_memctrl_master_release, 252 .release = edac_memctrl_master_release,
258 .sysfs_ops = &memctrlfs_ops, 253 .sysfs_ops = &memctrlfs_ops,
259 .default_attrs = (struct attribute **) memctrl_attr, 254 .default_attrs = (struct attribute **) memctrl_attr,
260}; 255};
261 256
262#endif /* DISABLE_EDAC_SYSFS */ 257#endif /* DISABLE_EDAC_SYSFS */
@@ -282,6 +277,7 @@ static int edac_sysfs_memctrl_setup(void)
282 277
283 /* create the /sys/devices/system/edac directory */ 278 /* create the /sys/devices/system/edac directory */
284 err = sysdev_class_register(&edac_class); 279 err = sysdev_class_register(&edac_class);
280
285 if (!err) { 281 if (!err) {
286 /* Init the MC's kobject */ 282 /* Init the MC's kobject */
287 memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj)); 283 memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj));
@@ -290,18 +286,18 @@ static int edac_sysfs_memctrl_setup(void)
290 286
291 /* generate sysfs "..../edac/mc" */ 287 /* generate sysfs "..../edac/mc" */
292 err = kobject_set_name(&edac_memctrl_kobj,"mc"); 288 err = kobject_set_name(&edac_memctrl_kobj,"mc");
289
293 if (!err) { 290 if (!err) {
294 /* FIXME: maybe new sysdev_create_subdir() */ 291 /* FIXME: maybe new sysdev_create_subdir() */
295 err = kobject_register(&edac_memctrl_kobj); 292 err = kobject_register(&edac_memctrl_kobj);
296 if (err) { 293
294 if (err)
297 debugf1("Failed to register '.../edac/mc'\n"); 295 debugf1("Failed to register '.../edac/mc'\n");
298 } else { 296 else
299 debugf1("Registered '.../edac/mc' kobject\n"); 297 debugf1("Registered '.../edac/mc' kobject\n");
300 }
301 } 298 }
302 } else { 299 } else
303 debugf1("%s() error=%d\n", __func__, err); 300 debugf1("%s() error=%d\n", __func__, err);
304 }
305 301
306 return err; 302 return err;
307} 303}
@@ -340,7 +336,6 @@ struct list_control {
340 int *count; 336 int *count;
341}; 337};
342 338
343
344#if 0 339#if 0
345/* Output the list as: vendor_id:device:id<,vendor_id:device_id> */ 340/* Output the list as: vendor_id:device:id<,vendor_id:device_id> */
346static ssize_t edac_pci_list_string_show(void *ptr, char *buffer) 341static ssize_t edac_pci_list_string_show(void *ptr, char *buffer)
@@ -365,7 +360,6 @@ static ssize_t edac_pci_list_string_show(void *ptr, char *buffer)
365 } 360 }
366 361
367 len += snprintf(p + len,(PAGE_SIZE-len), "\n"); 362 len += snprintf(p + len,(PAGE_SIZE-len), "\n");
368
369 return (ssize_t) len; 363 return (ssize_t) len;
370} 364}
371 365
@@ -387,7 +381,7 @@ static int parse_one_device(const char **s,const char **e,
387 381
388 /* if null byte, we are done */ 382 /* if null byte, we are done */
389 if (!**s) { 383 if (!**s) {
390 (*s)++; /* keep *s moving */ 384 (*s)++; /* keep *s moving */
391 return 0; 385 return 0;
392 } 386 }
393 387
@@ -404,6 +398,7 @@ static int parse_one_device(const char **s,const char **e,
404 398
405 /* parse vendor_id */ 399 /* parse vendor_id */
406 runner = *s; 400 runner = *s;
401
407 while (runner < *e) { 402 while (runner < *e) {
408 /* scan for vendor:device delimiter */ 403 /* scan for vendor:device delimiter */
409 if (*runner == ':') { 404 if (*runner == ':') {
@@ -411,6 +406,7 @@ static int parse_one_device(const char **s,const char **e,
411 runner = p + 1; 406 runner = p + 1;
412 break; 407 break;
413 } 408 }
409
414 runner++; 410 runner++;
415 } 411 }
416 412
@@ -426,12 +422,11 @@ static int parse_one_device(const char **s,const char **e,
426 } 422 }
427 423
428 *s = runner; 424 *s = runner;
429
430 return 1; 425 return 1;
431} 426}
432 427
433static ssize_t edac_pci_list_string_store(void *ptr, const char *buffer, 428static ssize_t edac_pci_list_string_store(void *ptr, const char *buffer,
434 size_t count) 429 size_t count)
435{ 430{
436 struct list_control *listctl; 431 struct list_control *listctl;
437 struct edac_pci_device_list *list; 432 struct edac_pci_device_list *list;
@@ -441,14 +436,12 @@ static ssize_t edac_pci_list_string_store(void *ptr, const char *buffer,
441 436
442 s = (char*)buffer; 437 s = (char*)buffer;
443 e = s + count; 438 e = s + count;
444
445 listctl = ptr; 439 listctl = ptr;
446 list = listctl->list; 440 list = listctl->list;
447 index = listctl->count; 441 index = listctl->count;
448
449 *index = 0; 442 *index = 0;
450 while (*index < MAX_LISTED_PCI_DEVICES) {
451 443
444 while (*index < MAX_LISTED_PCI_DEVICES) {
452 if (parse_one_device(&s,&e,&vendor_id,&device_id)) { 445 if (parse_one_device(&s,&e,&vendor_id,&device_id)) {
453 list[ *index ].vendor = vendor_id; 446 list[ *index ].vendor = vendor_id;
454 list[ *index ].device = device_id; 447 list[ *index ].device = device_id;
@@ -481,15 +474,15 @@ static ssize_t edac_pci_int_store(void *ptr, const char *buffer, size_t count)
481} 474}
482 475
483struct edac_pci_dev_attribute { 476struct edac_pci_dev_attribute {
484 struct attribute attr; 477 struct attribute attr;
485 void *value; 478 void *value;
486 ssize_t (*show)(void *,char *); 479 ssize_t (*show)(void *,char *);
487 ssize_t (*store)(void *, const char *,size_t); 480 ssize_t (*store)(void *, const char *,size_t);
488}; 481};
489 482
490/* Set of show/store abstract level functions for PCI Parity object */ 483/* Set of show/store abstract level functions for PCI Parity object */
491static ssize_t edac_pci_dev_show(struct kobject *kobj, struct attribute *attr, 484static ssize_t edac_pci_dev_show(struct kobject *kobj, struct attribute *attr,
492 char *buffer) 485 char *buffer)
493{ 486{
494 struct edac_pci_dev_attribute *edac_pci_dev; 487 struct edac_pci_dev_attribute *edac_pci_dev;
495 edac_pci_dev= (struct edac_pci_dev_attribute*)attr; 488 edac_pci_dev= (struct edac_pci_dev_attribute*)attr;
@@ -499,8 +492,8 @@ static ssize_t edac_pci_dev_show(struct kobject *kobj, struct attribute *attr,
499 return -EIO; 492 return -EIO;
500} 493}
501 494
502static ssize_t edac_pci_dev_store(struct kobject *kobj, struct attribute *attr, 495static ssize_t edac_pci_dev_store(struct kobject *kobj,
503 const char *buffer, size_t count) 496 struct attribute *attr, const char *buffer, size_t count)
504{ 497{
505 struct edac_pci_dev_attribute *edac_pci_dev; 498 struct edac_pci_dev_attribute *edac_pci_dev;
506 edac_pci_dev= (struct edac_pci_dev_attribute*)attr; 499 edac_pci_dev= (struct edac_pci_dev_attribute*)attr;
@@ -515,7 +508,6 @@ static struct sysfs_ops edac_pci_sysfs_ops = {
515 .store = edac_pci_dev_store 508 .store = edac_pci_dev_store
516}; 509};
517 510
518
519#define EDAC_PCI_ATTR(_name,_mode,_show,_store) \ 511#define EDAC_PCI_ATTR(_name,_mode,_show,_store) \
520struct edac_pci_dev_attribute edac_pci_attr_##_name = { \ 512struct edac_pci_dev_attribute edac_pci_attr_##_name = { \
521 .attr = {.name = __stringify(_name), .mode = _mode }, \ 513 .attr = {.name = __stringify(_name), .mode = _mode }, \
@@ -558,9 +550,11 @@ EDAC_PCI_STRING_ATTR(pci_parity_blacklist,
558#endif 550#endif
559 551
560/* PCI Parity control files */ 552/* PCI Parity control files */
561EDAC_PCI_ATTR(check_pci_parity,S_IRUGO|S_IWUSR,edac_pci_int_show,edac_pci_int_store); 553EDAC_PCI_ATTR(check_pci_parity, S_IRUGO|S_IWUSR, edac_pci_int_show,
562EDAC_PCI_ATTR(panic_on_pci_parity,S_IRUGO|S_IWUSR,edac_pci_int_show,edac_pci_int_store); 554 edac_pci_int_store);
563EDAC_PCI_ATTR(pci_parity_count,S_IRUGO,edac_pci_int_show,NULL); 555EDAC_PCI_ATTR(panic_on_pci_parity, S_IRUGO|S_IWUSR, edac_pci_int_show,
556 edac_pci_int_store);
557EDAC_PCI_ATTR(pci_parity_count, S_IRUGO, edac_pci_int_show, NULL);
564 558
565/* Base Attributes of the memory ECC object */ 559/* Base Attributes of the memory ECC object */
566static struct edac_pci_dev_attribute *edac_pci_attr[] = { 560static struct edac_pci_dev_attribute *edac_pci_attr[] = {
@@ -578,9 +572,9 @@ static void edac_pci_release(struct kobject *kobj)
578} 572}
579 573
580static struct kobj_type ktype_edac_pci = { 574static struct kobj_type ktype_edac_pci = {
581 .release = edac_pci_release, 575 .release = edac_pci_release,
582 .sysfs_ops = &edac_pci_sysfs_ops, 576 .sysfs_ops = &edac_pci_sysfs_ops,
583 .default_attrs = (struct attribute **) edac_pci_attr, 577 .default_attrs = (struct attribute **) edac_pci_attr,
584}; 578};
585 579
586#endif /* DISABLE_EDAC_SYSFS */ 580#endif /* DISABLE_EDAC_SYSFS */
@@ -603,17 +597,19 @@ static int edac_sysfs_pci_setup(void)
603 memset(&edac_pci_kobj, 0, sizeof(edac_pci_kobj)); 597 memset(&edac_pci_kobj, 0, sizeof(edac_pci_kobj));
604 edac_pci_kobj.parent = &edac_class.kset.kobj; 598 edac_pci_kobj.parent = &edac_class.kset.kobj;
605 edac_pci_kobj.ktype = &ktype_edac_pci; 599 edac_pci_kobj.ktype = &ktype_edac_pci;
606
607 err = kobject_set_name(&edac_pci_kobj, "pci"); 600 err = kobject_set_name(&edac_pci_kobj, "pci");
601
608 if (!err) { 602 if (!err) {
609 /* Instanstiate the csrow object */ 603 /* Instanstiate the csrow object */
610 /* FIXME: maybe new sysdev_create_subdir() */ 604 /* FIXME: maybe new sysdev_create_subdir() */
611 err = kobject_register(&edac_pci_kobj); 605 err = kobject_register(&edac_pci_kobj);
606
612 if (err) 607 if (err)
613 debugf1("Failed to register '.../edac/pci'\n"); 608 debugf1("Failed to register '.../edac/pci'\n");
614 else 609 else
615 debugf1("Registered '.../edac/pci' kobject\n"); 610 debugf1("Registered '.../edac/pci' kobject\n");
616 } 611 }
612
617 return err; 613 return err;
618} 614}
619#endif /* DISABLE_EDAC_SYSFS */ 615#endif /* DISABLE_EDAC_SYSFS */
@@ -641,6 +637,7 @@ static ssize_t csrow_ch0_dimm_label_show(struct csrow_info *csrow, char *data)
641 size = snprintf(data, EDAC_MC_LABEL_LEN,"%s\n", 637 size = snprintf(data, EDAC_MC_LABEL_LEN,"%s\n",
642 csrow->channels[0].label); 638 csrow->channels[0].label);
643 } 639 }
640
644 return size; 641 return size;
645} 642}
646 643
@@ -652,11 +649,12 @@ static ssize_t csrow_ch1_dimm_label_show(struct csrow_info *csrow, char *data)
652 size = snprintf(data, EDAC_MC_LABEL_LEN, "%s\n", 649 size = snprintf(data, EDAC_MC_LABEL_LEN, "%s\n",
653 csrow->channels[1].label); 650 csrow->channels[1].label);
654 } 651 }
652
655 return size; 653 return size;
656} 654}
657 655
658static ssize_t csrow_ch0_dimm_label_store(struct csrow_info *csrow, 656static ssize_t csrow_ch0_dimm_label_store(struct csrow_info *csrow,
659 const char *data, size_t size) 657 const char *data, size_t size)
660{ 658{
661 ssize_t max_size = 0; 659 ssize_t max_size = 0;
662 660
@@ -665,11 +663,12 @@ static ssize_t csrow_ch0_dimm_label_store(struct csrow_info *csrow,
665 strncpy(csrow->channels[0].label, data, max_size); 663 strncpy(csrow->channels[0].label, data, max_size);
666 csrow->channels[0].label[max_size] = '\0'; 664 csrow->channels[0].label[max_size] = '\0';
667 } 665 }
666
668 return size; 667 return size;
669} 668}
670 669
671static ssize_t csrow_ch1_dimm_label_store(struct csrow_info *csrow, 670static ssize_t csrow_ch1_dimm_label_store(struct csrow_info *csrow,
672 const char *data, size_t size) 671 const char *data, size_t size)
673{ 672{
674 ssize_t max_size = 0; 673 ssize_t max_size = 0;
675 674
@@ -678,6 +677,7 @@ static ssize_t csrow_ch1_dimm_label_store(struct csrow_info *csrow,
678 strncpy(csrow->channels[1].label, data, max_size); 677 strncpy(csrow->channels[1].label, data, max_size);
679 csrow->channels[1].label[max_size] = '\0'; 678 csrow->channels[1].label[max_size] = '\0';
680 } 679 }
680
681 return max_size; 681 return max_size;
682} 682}
683 683
@@ -698,6 +698,7 @@ static ssize_t csrow_ch0_ce_count_show(struct csrow_info *csrow, char *data)
698 if (csrow->nr_channels > 0) { 698 if (csrow->nr_channels > 0) {
699 size = sprintf(data,"%u\n", csrow->channels[0].ce_count); 699 size = sprintf(data,"%u\n", csrow->channels[0].ce_count);
700 } 700 }
701
701 return size; 702 return size;
702} 703}
703 704
@@ -708,6 +709,7 @@ static ssize_t csrow_ch1_ce_count_show(struct csrow_info *csrow, char *data)
708 if (csrow->nr_channels > 1) { 709 if (csrow->nr_channels > 1) {
709 size = sprintf(data,"%u\n", csrow->channels[1].ce_count); 710 size = sprintf(data,"%u\n", csrow->channels[1].ce_count);
710 } 711 }
712
711 return size; 713 return size;
712} 714}
713 715
@@ -732,7 +734,7 @@ static ssize_t csrow_edac_mode_show(struct csrow_info *csrow, char *data)
732} 734}
733 735
734struct csrowdev_attribute { 736struct csrowdev_attribute {
735 struct attribute attr; 737 struct attribute attr;
736 ssize_t (*show)(struct csrow_info *,char *); 738 ssize_t (*show)(struct csrow_info *,char *);
737 ssize_t (*store)(struct csrow_info *, const char *,size_t); 739 ssize_t (*store)(struct csrow_info *, const char *,size_t);
738}; 740};
@@ -742,24 +744,26 @@ struct csrowdev_attribute {
742 744
743/* Set of show/store higher level functions for csrow objects */ 745/* Set of show/store higher level functions for csrow objects */
744static ssize_t csrowdev_show(struct kobject *kobj, struct attribute *attr, 746static ssize_t csrowdev_show(struct kobject *kobj, struct attribute *attr,
745 char *buffer) 747 char *buffer)
746{ 748{
747 struct csrow_info *csrow = to_csrow(kobj); 749 struct csrow_info *csrow = to_csrow(kobj);
748 struct csrowdev_attribute *csrowdev_attr = to_csrowdev_attr(attr); 750 struct csrowdev_attribute *csrowdev_attr = to_csrowdev_attr(attr);
749 751
750 if (csrowdev_attr->show) 752 if (csrowdev_attr->show)
751 return csrowdev_attr->show(csrow, buffer); 753 return csrowdev_attr->show(csrow, buffer);
754
752 return -EIO; 755 return -EIO;
753} 756}
754 757
755static ssize_t csrowdev_store(struct kobject *kobj, struct attribute *attr, 758static ssize_t csrowdev_store(struct kobject *kobj, struct attribute *attr,
756 const char *buffer, size_t count) 759 const char *buffer, size_t count)
757{ 760{
758 struct csrow_info *csrow = to_csrow(kobj); 761 struct csrow_info *csrow = to_csrow(kobj);
759 struct csrowdev_attribute * csrowdev_attr = to_csrowdev_attr(attr); 762 struct csrowdev_attribute * csrowdev_attr = to_csrowdev_attr(attr);
760 763
761 if (csrowdev_attr->store) 764 if (csrowdev_attr->store)
762 return csrowdev_attr->store(csrow, buffer, count); 765 return csrowdev_attr->store(csrow, buffer, count);
766
763 return -EIO; 767 return -EIO;
764} 768}
765 769
@@ -793,7 +797,6 @@ CSROWDEV_ATTR(ch1_dimm_label,S_IRUGO|S_IWUSR,
793 csrow_ch1_dimm_label_show, 797 csrow_ch1_dimm_label_show,
794 csrow_ch1_dimm_label_store); 798 csrow_ch1_dimm_label_store);
795 799
796
797/* Attributes of the CSROW<id> object */ 800/* Attributes of the CSROW<id> object */
798static struct csrowdev_attribute *csrow_attr[] = { 801static struct csrowdev_attribute *csrow_attr[] = {
799 &attr_dev_type, 802 &attr_dev_type,
@@ -809,7 +812,6 @@ static struct csrowdev_attribute *csrow_attr[] = {
809 NULL, 812 NULL,
810}; 813};
811 814
812
813/* No memory to release */ 815/* No memory to release */
814static void edac_csrow_instance_release(struct kobject *kobj) 816static void edac_csrow_instance_release(struct kobject *kobj)
815{ 817{
@@ -821,19 +823,18 @@ static void edac_csrow_instance_release(struct kobject *kobj)
821} 823}
822 824
823static struct kobj_type ktype_csrow = { 825static struct kobj_type ktype_csrow = {
824 .release = edac_csrow_instance_release, 826 .release = edac_csrow_instance_release,
825 .sysfs_ops = &csrowfs_ops, 827 .sysfs_ops = &csrowfs_ops,
826 .default_attrs = (struct attribute **) csrow_attr, 828 .default_attrs = (struct attribute **) csrow_attr,
827}; 829};
828 830
829/* Create a CSROW object under specifed edac_mc_device */ 831/* Create a CSROW object under specifed edac_mc_device */
830static int edac_create_csrow_object(struct kobject *edac_mci_kobj, 832static int edac_create_csrow_object(struct kobject *edac_mci_kobj,
831 struct csrow_info *csrow, int index ) 833 struct csrow_info *csrow, int index)
832{ 834{
833 int err = 0; 835 int err = 0;
834 836
835 debugf0("%s()\n", __func__); 837 debugf0("%s()\n", __func__);
836
837 memset(&csrow->kobj, 0, sizeof(csrow->kobj)); 838 memset(&csrow->kobj, 0, sizeof(csrow->kobj));
838 839
839 /* generate ..../edac/mc/mc<id>/csrow<index> */ 840 /* generate ..../edac/mc/mc<id>/csrow<index> */
@@ -843,9 +844,11 @@ static int edac_create_csrow_object(struct kobject *edac_mci_kobj,
843 844
844 /* name this instance of csrow<id> */ 845 /* name this instance of csrow<id> */
845 err = kobject_set_name(&csrow->kobj,"csrow%d",index); 846 err = kobject_set_name(&csrow->kobj,"csrow%d",index);
847
846 if (!err) { 848 if (!err) {
847 /* Instanstiate the csrow object */ 849 /* Instanstiate the csrow object */
848 err = kobject_register(&csrow->kobj); 850 err = kobject_register(&csrow->kobj);
851
849 if (err) 852 if (err)
850 debugf0("Failed to register CSROW%d\n",index); 853 debugf0("Failed to register CSROW%d\n",index);
851 else 854 else
@@ -857,8 +860,8 @@ static int edac_create_csrow_object(struct kobject *edac_mci_kobj,
857 860
858/* sysfs data structures and methods for the MCI kobjects */ 861/* sysfs data structures and methods for the MCI kobjects */
859 862
860static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci, 863static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci,
861 const char *data, size_t count ) 864 const char *data, size_t count)
862{ 865{
863 int row, chan; 866 int row, chan;
864 867
@@ -866,16 +869,18 @@ static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci,
866 mci->ce_noinfo_count = 0; 869 mci->ce_noinfo_count = 0;
867 mci->ue_count = 0; 870 mci->ue_count = 0;
868 mci->ce_count = 0; 871 mci->ce_count = 0;
872
869 for (row = 0; row < mci->nr_csrows; row++) { 873 for (row = 0; row < mci->nr_csrows; row++) {
870 struct csrow_info *ri = &mci->csrows[row]; 874 struct csrow_info *ri = &mci->csrows[row];
871 875
872 ri->ue_count = 0; 876 ri->ue_count = 0;
873 ri->ce_count = 0; 877 ri->ce_count = 0;
878
874 for (chan = 0; chan < ri->nr_channels; chan++) 879 for (chan = 0; chan < ri->nr_channels; chan++)
875 ri->channels[chan].ce_count = 0; 880 ri->channels[chan].ce_count = 0;
876 } 881 }
877 mci->start_time = jiffies;
878 882
883 mci->start_time = jiffies;
879 return count; 884 return count;
880} 885}
881 886
@@ -933,18 +938,16 @@ static ssize_t mci_edac_capability_show(struct mem_ctl_info *mci, char *data)
933 938
934 p += mci_output_edac_cap(p,mci->edac_ctl_cap); 939 p += mci_output_edac_cap(p,mci->edac_ctl_cap);
935 p += sprintf(p, "\n"); 940 p += sprintf(p, "\n");
936
937 return p - data; 941 return p - data;
938} 942}
939 943
940static ssize_t mci_edac_current_capability_show(struct mem_ctl_info *mci, 944static ssize_t mci_edac_current_capability_show(struct mem_ctl_info *mci,
941 char *data) 945 char *data)
942{ 946{
943 char *p = data; 947 char *p = data;
944 948
945 p += mci_output_edac_cap(p,mci->edac_cap); 949 p += mci_output_edac_cap(p,mci->edac_cap);
946 p += sprintf(p, "\n"); 950 p += sprintf(p, "\n");
947
948 return p - data; 951 return p - data;
949} 952}
950 953
@@ -961,13 +964,13 @@ static int mci_output_mtype_cap(char *buf, unsigned long mtype_cap)
961 return p - buf; 964 return p - buf;
962} 965}
963 966
964static ssize_t mci_supported_mem_type_show(struct mem_ctl_info *mci, char *data) 967static ssize_t mci_supported_mem_type_show(struct mem_ctl_info *mci,
968 char *data)
965{ 969{
966 char *p = data; 970 char *p = data;
967 971
968 p += mci_output_mtype_cap(p,mci->mtype_cap); 972 p += mci_output_mtype_cap(p,mci->mtype_cap);
969 p += sprintf(p, "\n"); 973 p += sprintf(p, "\n");
970
971 return p - data; 974 return p - data;
972} 975}
973 976
@@ -981,6 +984,7 @@ static ssize_t mci_size_mb_show(struct mem_ctl_info *mci, char *data)
981 984
982 if (!csrow->nr_pages) 985 if (!csrow->nr_pages)
983 continue; 986 continue;
987
984 total_pages += csrow->nr_pages; 988 total_pages += csrow->nr_pages;
985 } 989 }
986 990
@@ -988,7 +992,7 @@ static ssize_t mci_size_mb_show(struct mem_ctl_info *mci, char *data)
988} 992}
989 993
990struct mcidev_attribute { 994struct mcidev_attribute {
991 struct attribute attr; 995 struct attribute attr;
992 ssize_t (*show)(struct mem_ctl_info *,char *); 996 ssize_t (*show)(struct mem_ctl_info *,char *);
993 ssize_t (*store)(struct mem_ctl_info *, const char *,size_t); 997 ssize_t (*store)(struct mem_ctl_info *, const char *,size_t);
994}; 998};
@@ -997,30 +1001,32 @@ struct mcidev_attribute {
997#define to_mcidev_attr(a) container_of(a, struct mcidev_attribute, attr) 1001#define to_mcidev_attr(a) container_of(a, struct mcidev_attribute, attr)
998 1002
999static ssize_t mcidev_show(struct kobject *kobj, struct attribute *attr, 1003static ssize_t mcidev_show(struct kobject *kobj, struct attribute *attr,
1000 char *buffer) 1004 char *buffer)
1001{ 1005{
1002 struct mem_ctl_info *mem_ctl_info = to_mci(kobj); 1006 struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
1003 struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr); 1007 struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr);
1004 1008
1005 if (mcidev_attr->show) 1009 if (mcidev_attr->show)
1006 return mcidev_attr->show(mem_ctl_info, buffer); 1010 return mcidev_attr->show(mem_ctl_info, buffer);
1011
1007 return -EIO; 1012 return -EIO;
1008} 1013}
1009 1014
1010static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr, 1015static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr,
1011 const char *buffer, size_t count) 1016 const char *buffer, size_t count)
1012{ 1017{
1013 struct mem_ctl_info *mem_ctl_info = to_mci(kobj); 1018 struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
1014 struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr); 1019 struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr);
1015 1020
1016 if (mcidev_attr->store) 1021 if (mcidev_attr->store)
1017 return mcidev_attr->store(mem_ctl_info, buffer, count); 1022 return mcidev_attr->store(mem_ctl_info, buffer, count);
1023
1018 return -EIO; 1024 return -EIO;
1019} 1025}
1020 1026
1021static struct sysfs_ops mci_ops = { 1027static struct sysfs_ops mci_ops = {
1022 .show = mcidev_show, 1028 .show = mcidev_show,
1023 .store = mcidev_store 1029 .store = mcidev_store
1024}; 1030};
1025 1031
1026#define MCIDEV_ATTR(_name,_mode,_show,_store) \ 1032#define MCIDEV_ATTR(_name,_mode,_show,_store) \
@@ -1048,7 +1054,6 @@ MCIDEV_ATTR(edac_current_capability,S_IRUGO,
1048MCIDEV_ATTR(supported_mem_type,S_IRUGO, 1054MCIDEV_ATTR(supported_mem_type,S_IRUGO,
1049 mci_supported_mem_type_show,NULL); 1055 mci_supported_mem_type_show,NULL);
1050 1056
1051
1052static struct mcidev_attribute *mci_attr[] = { 1057static struct mcidev_attribute *mci_attr[] = {
1053 &mci_attr_reset_counters, 1058 &mci_attr_reset_counters,
1054 &mci_attr_module_name, 1059 &mci_attr_module_name,
@@ -1065,7 +1070,6 @@ static struct mcidev_attribute *mci_attr[] = {
1065 NULL 1070 NULL
1066}; 1071};
1067 1072
1068
1069/* 1073/*
1070 * Release of a MC controlling instance 1074 * Release of a MC controlling instance
1071 */ 1075 */
@@ -1079,9 +1083,9 @@ static void edac_mci_instance_release(struct kobject *kobj)
1079} 1083}
1080 1084
1081static struct kobj_type ktype_mci = { 1085static struct kobj_type ktype_mci = {
1082 .release = edac_mci_instance_release, 1086 .release = edac_mci_instance_release,
1083 .sysfs_ops = &mci_ops, 1087 .sysfs_ops = &mci_ops,
1084 .default_attrs = (struct attribute **) mci_attr, 1088 .default_attrs = (struct attribute **) mci_attr,
1085}; 1089};
1086 1090
1087#endif /* DISABLE_EDAC_SYSFS */ 1091#endif /* DISABLE_EDAC_SYSFS */
@@ -1109,11 +1113,11 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
1109 struct kobject *edac_mci_kobj=&mci->edac_mci_kobj; 1113 struct kobject *edac_mci_kobj=&mci->edac_mci_kobj;
1110 1114
1111 debugf0("%s() idx=%d\n", __func__, mci->mc_idx); 1115 debugf0("%s() idx=%d\n", __func__, mci->mc_idx);
1112
1113 memset(edac_mci_kobj, 0, sizeof(*edac_mci_kobj)); 1116 memset(edac_mci_kobj, 0, sizeof(*edac_mci_kobj));
1114 1117
1115 /* set the name of the mc<id> object */ 1118 /* set the name of the mc<id> object */
1116 err = kobject_set_name(edac_mci_kobj,"mc%d",mci->mc_idx); 1119 err = kobject_set_name(edac_mci_kobj,"mc%d",mci->mc_idx);
1120
1117 if (err) 1121 if (err)
1118 return err; 1122 return err;
1119 1123
@@ -1123,12 +1127,14 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
1123 1127
1124 /* register the mc<id> kobject */ 1128 /* register the mc<id> kobject */
1125 err = kobject_register(edac_mci_kobj); 1129 err = kobject_register(edac_mci_kobj);
1130
1126 if (err) 1131 if (err)
1127 return err; 1132 return err;
1128 1133
1129 /* create a symlink for the device */ 1134 /* create a symlink for the device */
1130 err = sysfs_create_link(edac_mci_kobj, &mci->pdev->dev.kobj, 1135 err = sysfs_create_link(edac_mci_kobj, &mci->pdev->dev.kobj,
1131 EDAC_DEVICE_SYMLINK); 1136 EDAC_DEVICE_SYMLINK);
1137
1132 if (err) 1138 if (err)
1133 goto fail0; 1139 goto fail0;
1134 1140
@@ -1136,12 +1142,12 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
1136 * under the mc<id> kobject 1142 * under the mc<id> kobject
1137 */ 1143 */
1138 for (i = 0; i < mci->nr_csrows; i++) { 1144 for (i = 0; i < mci->nr_csrows; i++) {
1139
1140 csrow = &mci->csrows[i]; 1145 csrow = &mci->csrows[i];
1141 1146
1142 /* Only expose populated CSROWs */ 1147 /* Only expose populated CSROWs */
1143 if (csrow->nr_pages > 0) { 1148 if (csrow->nr_pages > 0) {
1144 err = edac_create_csrow_object(edac_mci_kobj,csrow,i); 1149 err = edac_create_csrow_object(edac_mci_kobj,csrow,i);
1150
1145 if (err) 1151 if (err)
1146 goto fail1; 1152 goto fail1;
1147 } 1153 }
@@ -1149,7 +1155,6 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
1149 1155
1150 return 0; 1156 return 0;
1151 1157
1152
1153 /* CSROW error: backout what has already been registered, */ 1158 /* CSROW error: backout what has already been registered, */
1154fail1: 1159fail1:
1155 for ( i--; i >= 0; i--) { 1160 for ( i--; i >= 0; i--) {
@@ -1164,7 +1169,6 @@ fail0:
1164 init_completion(&mci->kobj_complete); 1169 init_completion(&mci->kobj_complete);
1165 kobject_unregister(edac_mci_kobj); 1170 kobject_unregister(edac_mci_kobj);
1166 wait_for_completion(&mci->kobj_complete); 1171 wait_for_completion(&mci->kobj_complete);
1167
1168 return err; 1172 return err;
1169} 1173}
1170#endif /* DISABLE_EDAC_SYSFS */ 1174#endif /* DISABLE_EDAC_SYSFS */
@@ -1199,7 +1203,6 @@ static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
1199 1203
1200#ifdef CONFIG_EDAC_DEBUG 1204#ifdef CONFIG_EDAC_DEBUG
1201 1205
1202
1203void edac_mc_dump_channel(struct channel_info *chan) 1206void edac_mc_dump_channel(struct channel_info *chan)
1204{ 1207{
1205 debugf4("\tchannel = %p\n", chan); 1208 debugf4("\tchannel = %p\n", chan);
@@ -1210,7 +1213,6 @@ void edac_mc_dump_channel(struct channel_info *chan)
1210} 1213}
1211EXPORT_SYMBOL(edac_mc_dump_channel); 1214EXPORT_SYMBOL(edac_mc_dump_channel);
1212 1215
1213
1214void edac_mc_dump_csrow(struct csrow_info *csrow) 1216void edac_mc_dump_csrow(struct csrow_info *csrow)
1215{ 1217{
1216 debugf4("\tcsrow = %p\n", csrow); 1218 debugf4("\tcsrow = %p\n", csrow);
@@ -1227,7 +1229,6 @@ void edac_mc_dump_csrow(struct csrow_info *csrow)
1227} 1229}
1228EXPORT_SYMBOL(edac_mc_dump_csrow); 1230EXPORT_SYMBOL(edac_mc_dump_csrow);
1229 1231
1230
1231void edac_mc_dump_mci(struct mem_ctl_info *mci) 1232void edac_mc_dump_mci(struct mem_ctl_info *mci)
1232{ 1233{
1233 debugf3("\tmci = %p\n", mci); 1234 debugf3("\tmci = %p\n", mci);
@@ -1244,8 +1245,7 @@ void edac_mc_dump_mci(struct mem_ctl_info *mci)
1244} 1245}
1245EXPORT_SYMBOL(edac_mc_dump_mci); 1246EXPORT_SYMBOL(edac_mc_dump_mci);
1246 1247
1247 1248#endif /* CONFIG_EDAC_DEBUG */
1248#endif /* CONFIG_EDAC_DEBUG */
1249 1249
1250/* 'ptr' points to a possibly unaligned item X such that sizeof(X) is 'size'. 1250/* 'ptr' points to a possibly unaligned item X such that sizeof(X) is 'size'.
1251 * Adjust 'ptr' so that its alignment is at least as stringent as what the 1251 * Adjust 'ptr' so that its alignment is at least as stringent as what the
@@ -1254,7 +1254,7 @@ EXPORT_SYMBOL(edac_mc_dump_mci);
1254 * If 'size' is a constant, the compiler will optimize this whole function 1254 * If 'size' is a constant, the compiler will optimize this whole function
1255 * down to either a no-op or the addition of a constant to the value of 'ptr'. 1255 * down to either a no-op or the addition of a constant to the value of 'ptr'.
1256 */ 1256 */
1257static inline char * align_ptr (void *ptr, unsigned size) 1257static inline char * align_ptr(void *ptr, unsigned size)
1258{ 1258{
1259 unsigned align, r; 1259 unsigned align, r;
1260 1260
@@ -1281,7 +1281,6 @@ static inline char * align_ptr (void *ptr, unsigned size)
1281 return (char *) (((unsigned long) ptr) + align - r); 1281 return (char *) (((unsigned long) ptr) + align - r);
1282} 1282}
1283 1283
1284
1285/** 1284/**
1286 * edac_mc_alloc: Allocate a struct mem_ctl_info structure 1285 * edac_mc_alloc: Allocate a struct mem_ctl_info structure
1287 * @size_pvt: size of private storage needed 1286 * @size_pvt: size of private storage needed
@@ -1299,7 +1298,7 @@ static inline char * align_ptr (void *ptr, unsigned size)
1299 * struct mem_ctl_info pointer 1298 * struct mem_ctl_info pointer
1300 */ 1299 */
1301struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, 1300struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
1302 unsigned nr_chans) 1301 unsigned nr_chans)
1303{ 1302{
1304 struct mem_ctl_info *mci; 1303 struct mem_ctl_info *mci;
1305 struct csrow_info *csi, *csrow; 1304 struct csrow_info *csi, *csrow;
@@ -1330,8 +1329,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
1330 chi = (struct channel_info *) (((char *) mci) + ((unsigned long) chi)); 1329 chi = (struct channel_info *) (((char *) mci) + ((unsigned long) chi));
1331 pvt = sz_pvt ? (((char *) mci) + ((unsigned long) pvt)) : NULL; 1330 pvt = sz_pvt ? (((char *) mci) + ((unsigned long) pvt)) : NULL;
1332 1331
1333 memset(mci, 0, size); /* clear all fields */ 1332 memset(mci, 0, size); /* clear all fields */
1334
1335 mci->csrows = csi; 1333 mci->csrows = csi;
1336 mci->pvt_info = pvt; 1334 mci->pvt_info = pvt;
1337 mci->nr_csrows = nr_csrows; 1335 mci->nr_csrows = nr_csrows;
@@ -1355,7 +1353,6 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
1355} 1353}
1356EXPORT_SYMBOL(edac_mc_alloc); 1354EXPORT_SYMBOL(edac_mc_alloc);
1357 1355
1358
1359/** 1356/**
1360 * edac_mc_free: Free a previously allocated 'mci' structure 1357 * edac_mc_free: Free a previously allocated 'mci' structure
1361 * @mci: pointer to a struct mem_ctl_info structure 1358 * @mci: pointer to a struct mem_ctl_info structure
@@ -1383,7 +1380,7 @@ static struct mem_ctl_info *find_mci_by_pdev(struct pci_dev *pdev)
1383 return NULL; 1380 return NULL;
1384} 1381}
1385 1382
1386static int add_mc_to_global_list (struct mem_ctl_info *mci) 1383static int add_mc_to_global_list(struct mem_ctl_info *mci)
1387{ 1384{
1388 struct list_head *item, *insert_before; 1385 struct list_head *item, *insert_before;
1389 struct mem_ctl_info *p; 1386 struct mem_ctl_info *p;
@@ -1426,8 +1423,7 @@ static int add_mc_to_global_list (struct mem_ctl_info *mci)
1426 return 0; 1423 return 0;
1427} 1424}
1428 1425
1429 1426static void complete_mc_list_del(struct rcu_head *head)
1430static void complete_mc_list_del (struct rcu_head *head)
1431{ 1427{
1432 struct mem_ctl_info *mci; 1428 struct mem_ctl_info *mci;
1433 1429
@@ -1436,8 +1432,7 @@ static void complete_mc_list_del (struct rcu_head *head)
1436 complete(&mci->complete); 1432 complete(&mci->complete);
1437} 1433}
1438 1434
1439 1435static void del_mc_from_global_list(struct mem_ctl_info *mci)
1440static void del_mc_from_global_list (struct mem_ctl_info *mci)
1441{ 1436{
1442 list_del_rcu(&mci->link); 1437 list_del_rcu(&mci->link);
1443 init_completion(&mci->complete); 1438 init_completion(&mci->complete);
@@ -1445,7 +1440,6 @@ static void del_mc_from_global_list (struct mem_ctl_info *mci)
1445 wait_for_completion(&mci->complete); 1440 wait_for_completion(&mci->complete);
1446} 1441}
1447 1442
1448
1449/** 1443/**
1450 * edac_mc_add_mc: Insert the 'mci' structure into the mci global list and 1444 * edac_mc_add_mc: Insert the 'mci' structure into the mci global list and
1451 * create sysfs entries associated with mci structure 1445 * create sysfs entries associated with mci structure
@@ -1463,15 +1457,17 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
1463#ifdef CONFIG_EDAC_DEBUG 1457#ifdef CONFIG_EDAC_DEBUG
1464 if (edac_debug_level >= 3) 1458 if (edac_debug_level >= 3)
1465 edac_mc_dump_mci(mci); 1459 edac_mc_dump_mci(mci);
1460
1466 if (edac_debug_level >= 4) { 1461 if (edac_debug_level >= 4) {
1467 int i; 1462 int i;
1468 1463
1469 for (i = 0; i < mci->nr_csrows; i++) { 1464 for (i = 0; i < mci->nr_csrows; i++) {
1470 int j; 1465 int j;
1466
1471 edac_mc_dump_csrow(&mci->csrows[i]); 1467 edac_mc_dump_csrow(&mci->csrows[i]);
1472 for (j = 0; j < mci->csrows[i].nr_channels; j++) 1468 for (j = 0; j < mci->csrows[i].nr_channels; j++)
1473 edac_mc_dump_channel(&mci->csrows[i]. 1469 edac_mc_dump_channel(
1474 channels[j]); 1470 &mci->csrows[i].channels[j]);
1475 } 1471 }
1476 } 1472 }
1477#endif 1473#endif
@@ -1505,7 +1501,6 @@ fail0:
1505} 1501}
1506EXPORT_SYMBOL(edac_mc_add_mc); 1502EXPORT_SYMBOL(edac_mc_add_mc);
1507 1503
1508
1509/** 1504/**
1510 * edac_mc_del_mc: Remove sysfs entries for specified mci structure and 1505 * edac_mc_del_mc: Remove sysfs entries for specified mci structure and
1511 * remove mci structure from global list 1506 * remove mci structure from global list
@@ -1535,9 +1530,7 @@ struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev)
1535} 1530}
1536EXPORT_SYMBOL(edac_mc_del_mc); 1531EXPORT_SYMBOL(edac_mc_del_mc);
1537 1532
1538 1533void edac_mc_scrub_block(unsigned long page, unsigned long offset, u32 size)
1539void edac_mc_scrub_block(unsigned long page, unsigned long offset,
1540 u32 size)
1541{ 1534{
1542 struct page *pg; 1535 struct page *pg;
1543 void *virt_addr; 1536 void *virt_addr;
@@ -1568,10 +1561,8 @@ void edac_mc_scrub_block(unsigned long page, unsigned long offset,
1568} 1561}
1569EXPORT_SYMBOL(edac_mc_scrub_block); 1562EXPORT_SYMBOL(edac_mc_scrub_block);
1570 1563
1571
1572/* FIXME - should return -1 */ 1564/* FIXME - should return -1 */
1573int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, 1565int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page)
1574 unsigned long page)
1575{ 1566{
1576 struct csrow_info *csrows = mci->csrows; 1567 struct csrow_info *csrows = mci->csrows;
1577 int row, i; 1568 int row, i;
@@ -1608,14 +1599,11 @@ int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
1608} 1599}
1609EXPORT_SYMBOL(edac_mc_find_csrow_by_page); 1600EXPORT_SYMBOL(edac_mc_find_csrow_by_page);
1610 1601
1611
1612/* FIXME - setable log (warning/emerg) levels */ 1602/* FIXME - setable log (warning/emerg) levels */
1613/* FIXME - integrate with evlog: http://evlog.sourceforge.net/ */ 1603/* FIXME - integrate with evlog: http://evlog.sourceforge.net/ */
1614void edac_mc_handle_ce(struct mem_ctl_info *mci, 1604void edac_mc_handle_ce(struct mem_ctl_info *mci,
1615 unsigned long page_frame_number, 1605 unsigned long page_frame_number, unsigned long offset_in_page,
1616 unsigned long offset_in_page, 1606 unsigned long syndrome, int row, int channel, const char *msg)
1617 unsigned long syndrome, int row, int channel,
1618 const char *msg)
1619{ 1607{
1620 unsigned long remapped_page; 1608 unsigned long remapped_page;
1621 1609
@@ -1630,6 +1618,7 @@ void edac_mc_handle_ce(struct mem_ctl_info *mci,
1630 edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR"); 1618 edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR");
1631 return; 1619 return;
1632 } 1620 }
1621
1633 if (channel >= mci->csrows[row].nr_channels || channel < 0) { 1622 if (channel >= mci->csrows[row].nr_channels || channel < 0) {
1634 /* something is wrong */ 1623 /* something is wrong */
1635 edac_mc_printk(mci, KERN_ERR, 1624 edac_mc_printk(mci, KERN_ERR,
@@ -1668,28 +1657,25 @@ void edac_mc_handle_ce(struct mem_ctl_info *mci,
1668 page_frame_number; 1657 page_frame_number;
1669 1658
1670 edac_mc_scrub_block(remapped_page, offset_in_page, 1659 edac_mc_scrub_block(remapped_page, offset_in_page,
1671 mci->csrows[row].grain); 1660 mci->csrows[row].grain);
1672 } 1661 }
1673} 1662}
1674EXPORT_SYMBOL(edac_mc_handle_ce); 1663EXPORT_SYMBOL(edac_mc_handle_ce);
1675 1664
1676 1665void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, const char *msg)
1677void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci,
1678 const char *msg)
1679{ 1666{
1680 if (log_ce) 1667 if (log_ce)
1681 edac_mc_printk(mci, KERN_WARNING, 1668 edac_mc_printk(mci, KERN_WARNING,
1682 "CE - no information available: %s\n", msg); 1669 "CE - no information available: %s\n", msg);
1670
1683 mci->ce_noinfo_count++; 1671 mci->ce_noinfo_count++;
1684 mci->ce_count++; 1672 mci->ce_count++;
1685} 1673}
1686EXPORT_SYMBOL(edac_mc_handle_ce_no_info); 1674EXPORT_SYMBOL(edac_mc_handle_ce_no_info);
1687 1675
1688
1689void edac_mc_handle_ue(struct mem_ctl_info *mci, 1676void edac_mc_handle_ue(struct mem_ctl_info *mci,
1690 unsigned long page_frame_number, 1677 unsigned long page_frame_number, unsigned long offset_in_page,
1691 unsigned long offset_in_page, int row, 1678 int row, const char *msg)
1692 const char *msg)
1693{ 1679{
1694 int len = EDAC_MC_LABEL_LEN * 4; 1680 int len = EDAC_MC_LABEL_LEN * 4;
1695 char labels[len + 1]; 1681 char labels[len + 1];
@@ -1710,13 +1696,14 @@ void edac_mc_handle_ue(struct mem_ctl_info *mci,
1710 } 1696 }
1711 1697
1712 chars = snprintf(pos, len + 1, "%s", 1698 chars = snprintf(pos, len + 1, "%s",
1713 mci->csrows[row].channels[0].label); 1699 mci->csrows[row].channels[0].label);
1714 len -= chars; 1700 len -= chars;
1715 pos += chars; 1701 pos += chars;
1702
1716 for (chan = 1; (chan < mci->csrows[row].nr_channels) && (len > 0); 1703 for (chan = 1; (chan < mci->csrows[row].nr_channels) && (len > 0);
1717 chan++) { 1704 chan++) {
1718 chars = snprintf(pos, len + 1, ":%s", 1705 chars = snprintf(pos, len + 1, ":%s",
1719 mci->csrows[row].channels[chan].label); 1706 mci->csrows[row].channels[chan].label);
1720 len -= chars; 1707 len -= chars;
1721 pos += chars; 1708 pos += chars;
1722 } 1709 }
@@ -1729,20 +1716,17 @@ void edac_mc_handle_ue(struct mem_ctl_info *mci,
1729 msg); 1716 msg);
1730 1717
1731 if (panic_on_ue) 1718 if (panic_on_ue)
1732 panic 1719 panic("EDAC MC%d: UE page 0x%lx, offset 0x%lx, grain %d, "
1733 ("EDAC MC%d: UE page 0x%lx, offset 0x%lx, grain %d, row %d," 1720 "row %d, labels \"%s\": %s\n", mci->mc_idx,
1734 " labels \"%s\": %s\n", mci->mc_idx, 1721 page_frame_number, offset_in_page,
1735 page_frame_number, offset_in_page, 1722 mci->csrows[row].grain, row, labels, msg);
1736 mci->csrows[row].grain, row, labels, msg);
1737 1723
1738 mci->ue_count++; 1724 mci->ue_count++;
1739 mci->csrows[row].ue_count++; 1725 mci->csrows[row].ue_count++;
1740} 1726}
1741EXPORT_SYMBOL(edac_mc_handle_ue); 1727EXPORT_SYMBOL(edac_mc_handle_ue);
1742 1728
1743 1729void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, const char *msg)
1744void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci,
1745 const char *msg)
1746{ 1730{
1747 if (panic_on_ue) 1731 if (panic_on_ue)
1748 panic("EDAC MC%d: Uncorrected Error", mci->mc_idx); 1732 panic("EDAC MC%d: Uncorrected Error", mci->mc_idx);
@@ -1755,7 +1739,6 @@ void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci,
1755} 1739}
1756EXPORT_SYMBOL(edac_mc_handle_ue_no_info); 1740EXPORT_SYMBOL(edac_mc_handle_ue_no_info);
1757 1741
1758
1759#ifdef CONFIG_PCI 1742#ifdef CONFIG_PCI
1760 1743
1761static u16 get_pci_parity_status(struct pci_dev *dev, int secondary) 1744static u16 get_pci_parity_status(struct pci_dev *dev, int secondary)
@@ -1766,18 +1749,22 @@ static u16 get_pci_parity_status(struct pci_dev *dev, int secondary)
1766 where = secondary ? PCI_SEC_STATUS : PCI_STATUS; 1749 where = secondary ? PCI_SEC_STATUS : PCI_STATUS;
1767 pci_read_config_word(dev, where, &status); 1750 pci_read_config_word(dev, where, &status);
1768 1751
1769 /* If we get back 0xFFFF then we must suspect that the card has been pulled but 1752 /* If we get back 0xFFFF then we must suspect that the card has been
1770 the Linux PCI layer has not yet finished cleaning up. We don't want to report 1753 * pulled but the Linux PCI layer has not yet finished cleaning up.
1771 on such devices */ 1754 * We don't want to report on such devices
1755 */
1772 1756
1773 if (status == 0xFFFF) { 1757 if (status == 0xFFFF) {
1774 u32 sanity; 1758 u32 sanity;
1759
1775 pci_read_config_dword(dev, 0, &sanity); 1760 pci_read_config_dword(dev, 0, &sanity);
1761
1776 if (sanity == 0xFFFFFFFF) 1762 if (sanity == 0xFFFFFFFF)
1777 return 0; 1763 return 0;
1778 } 1764 }
1765
1779 status &= PCI_STATUS_DETECTED_PARITY | PCI_STATUS_SIG_SYSTEM_ERROR | 1766 status &= PCI_STATUS_DETECTED_PARITY | PCI_STATUS_SIG_SYSTEM_ERROR |
1780 PCI_STATUS_PARITY; 1767 PCI_STATUS_PARITY;
1781 1768
1782 if (status) 1769 if (status)
1783 /* reset only the bits we are interested in */ 1770 /* reset only the bits we are interested in */
@@ -1789,7 +1776,7 @@ static u16 get_pci_parity_status(struct pci_dev *dev, int secondary)
1789typedef void (*pci_parity_check_fn_t) (struct pci_dev *dev); 1776typedef void (*pci_parity_check_fn_t) (struct pci_dev *dev);
1790 1777
1791/* Clear any PCI parity errors logged by this device. */ 1778/* Clear any PCI parity errors logged by this device. */
1792static void edac_pci_dev_parity_clear( struct pci_dev *dev ) 1779static void edac_pci_dev_parity_clear(struct pci_dev *dev)
1793{ 1780{
1794 u8 header_type; 1781 u8 header_type;
1795 1782
@@ -1890,58 +1877,55 @@ static void edac_pci_dev_parity_test(struct pci_dev *dev)
1890 * Returns: 0 not found 1877 * Returns: 0 not found
1891 * 1 found on list 1878 * 1 found on list
1892 */ 1879 */
1893static int check_dev_on_list(struct edac_pci_device_list *list, int free_index, 1880static int check_dev_on_list(struct edac_pci_device_list *list,
1894 struct pci_dev *dev) 1881 int free_index, struct pci_dev *dev)
1895{ 1882{
1896 int i; 1883 int i;
1897 int rc = 0; /* Assume not found */ 1884 int rc = 0; /* Assume not found */
1898 unsigned short vendor=dev->vendor; 1885 unsigned short vendor=dev->vendor;
1899 unsigned short device=dev->device; 1886 unsigned short device=dev->device;
1900 1887
1901 /* Scan the list, looking for a vendor/device match 1888 /* Scan the list, looking for a vendor/device match */
1902 */ 1889 for (i = 0; i < free_index; i++, list++ ) {
1903 for (i = 0; i < free_index; i++, list++ ) { 1890 if ((list->vendor == vendor ) && (list->device == device )) {
1904 if ( (list->vendor == vendor ) && 1891 rc = 1;
1905 (list->device == device )) { 1892 break;
1906 rc = 1; 1893 }
1907 break; 1894 }
1908 }
1909 }
1910 1895
1911 return rc; 1896 return rc;
1912} 1897}
1913 1898
1914/* 1899/*
1915 * pci_dev parity list iterator 1900 * pci_dev parity list iterator
1916 * Scan the PCI device list for one iteration, looking for SERRORs 1901 * Scan the PCI device list for one iteration, looking for SERRORs
1917 * Master Parity ERRORS or Parity ERRORs on primary or secondary devices 1902 * Master Parity ERRORS or Parity ERRORs on primary or secondary devices
1918 */ 1903 */
1919static inline void edac_pci_dev_parity_iterator(pci_parity_check_fn_t fn) 1904static inline void edac_pci_dev_parity_iterator(pci_parity_check_fn_t fn)
1920{ 1905{
1921 struct pci_dev *dev=NULL; 1906 struct pci_dev *dev = NULL;
1922 1907
1923 /* request for kernel access to the next PCI device, if any, 1908 /* request for kernel access to the next PCI device, if any,
1924 * and while we are looking at it have its reference count 1909 * and while we are looking at it have its reference count
1925 * bumped until we are done with it 1910 * bumped until we are done with it
1926 */ 1911 */
1927 while((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { 1912 while((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
1928 1913 /* if whitelist exists then it has priority, so only scan
1929 /* if whitelist exists then it has priority, so only scan those 1914 * those devices on the whitelist
1930 * devices on the whitelist 1915 */
1931 */ 1916 if (pci_whitelist_count > 0 ) {
1932 if (pci_whitelist_count > 0 ) { 1917 if (check_dev_on_list(pci_whitelist,
1933 if (check_dev_on_list(pci_whitelist,
1934 pci_whitelist_count, dev)) 1918 pci_whitelist_count, dev))
1935 fn(dev); 1919 fn(dev);
1936 } else { 1920 } else {
1937 /* 1921 /*
1938 * if no whitelist, then check if this devices is 1922 * if no whitelist, then check if this devices is
1939 * blacklisted 1923 * blacklisted
1940 */ 1924 */
1941 if (!check_dev_on_list(pci_blacklist, 1925 if (!check_dev_on_list(pci_blacklist,
1942 pci_blacklist_count, dev)) 1926 pci_blacklist_count, dev))
1943 fn(dev); 1927 fn(dev);
1944 } 1928 }
1945 } 1929 }
1946} 1930}
1947 1931
@@ -1972,7 +1956,6 @@ static void do_pci_parity_check(void)
1972 } 1956 }
1973} 1957}
1974 1958
1975
1976static inline void clear_pci_parity_errors(void) 1959static inline void clear_pci_parity_errors(void)
1977{ 1960{
1978 /* Clear any PCI bus parity errors that devices initially have logged 1961 /* Clear any PCI bus parity errors that devices initially have logged
@@ -1981,34 +1964,29 @@ static inline void clear_pci_parity_errors(void)
1981 edac_pci_dev_parity_iterator(edac_pci_dev_parity_clear); 1964 edac_pci_dev_parity_iterator(edac_pci_dev_parity_clear);
1982} 1965}
1983 1966
1984
1985#else /* CONFIG_PCI */ 1967#else /* CONFIG_PCI */
1986 1968
1987
1988static inline void do_pci_parity_check(void) 1969static inline void do_pci_parity_check(void)
1989{ 1970{
1990 /* no-op */ 1971 /* no-op */
1991} 1972}
1992 1973
1993
1994static inline void clear_pci_parity_errors(void) 1974static inline void clear_pci_parity_errors(void)
1995{ 1975{
1996 /* no-op */ 1976 /* no-op */
1997} 1977}
1998 1978
1999
2000#endif /* CONFIG_PCI */ 1979#endif /* CONFIG_PCI */
2001 1980
2002/* 1981/*
2003 * Iterate over all MC instances and check for ECC, et al, errors 1982 * Iterate over all MC instances and check for ECC, et al, errors
2004 */ 1983 */
2005static inline void check_mc_devices (void) 1984static inline void check_mc_devices(void)
2006{ 1985{
2007 struct list_head *item; 1986 struct list_head *item;
2008 struct mem_ctl_info *mci; 1987 struct mem_ctl_info *mci;
2009 1988
2010 debugf3("%s()\n", __func__); 1989 debugf3("%s()\n", __func__);
2011
2012 down(&mem_ctls_mutex); 1990 down(&mem_ctls_mutex);
2013 1991
2014 list_for_each(item, &mc_devices) { 1992 list_for_each(item, &mc_devices) {
@@ -2021,7 +1999,6 @@ static inline void check_mc_devices (void)
2021 up(&mem_ctls_mutex); 1999 up(&mem_ctls_mutex);
2022} 2000}
2023 2001
2024
2025/* 2002/*
2026 * Check MC status every poll_msec. 2003 * Check MC status every poll_msec.
2027 * Check PCI status every poll_msec as well. 2004 * Check PCI status every poll_msec as well.
@@ -2084,6 +2061,7 @@ static int __init edac_mc_init(void)
2084 2061
2085 /* create our kernel thread */ 2062 /* create our kernel thread */
2086 edac_thread = kthread_run(edac_kernel_thread, NULL, "kedac"); 2063 edac_thread = kthread_run(edac_kernel_thread, NULL, "kedac");
2064
2087 if (IS_ERR(edac_thread)) { 2065 if (IS_ERR(edac_thread)) {
2088 /* remove the sysfs entries */ 2066 /* remove the sysfs entries */
2089 edac_sysfs_memctrl_teardown(); 2067 edac_sysfs_memctrl_teardown();
@@ -2094,7 +2072,6 @@ static int __init edac_mc_init(void)
2094 return 0; 2072 return 0;
2095} 2073}
2096 2074
2097
2098/* 2075/*
2099 * edac_mc_exit() 2076 * edac_mc_exit()
2100 * module exit/termination functioni 2077 * module exit/termination functioni
@@ -2102,7 +2079,6 @@ static int __init edac_mc_init(void)
2102static void __exit edac_mc_exit(void) 2079static void __exit edac_mc_exit(void)
2103{ 2080{
2104 debugf0("%s()\n", __func__); 2081 debugf0("%s()\n", __func__);
2105
2106 kthread_stop(edac_thread); 2082 kthread_stop(edac_thread);
2107 2083
2108 /* tear down the sysfs device */ 2084 /* tear down the sysfs device */
@@ -2110,15 +2086,12 @@ static void __exit edac_mc_exit(void)
2110 edac_sysfs_pci_teardown(); 2086 edac_sysfs_pci_teardown();
2111} 2087}
2112 2088
2113
2114
2115
2116module_init(edac_mc_init); 2089module_init(edac_mc_init);
2117module_exit(edac_mc_exit); 2090module_exit(edac_mc_exit);
2118 2091
2119MODULE_LICENSE("GPL"); 2092MODULE_LICENSE("GPL");
2120MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh et al\n" 2093MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh et al\n"
2121 "Based on.work by Dan Hollis et al"); 2094 "Based on work by Dan Hollis et al");
2122MODULE_DESCRIPTION("Core library routines for MC reporting"); 2095MODULE_DESCRIPTION("Core library routines for MC reporting");
2123 2096
2124module_param(panic_on_ue, int, 0644); 2097module_param(panic_on_ue, int, 0644);