blob: 7ee9419234aa29ff32d7930b11b572f85d202abc [file] [log] [blame]
Alan Coxda9bb1d2006-01-18 17:44:13 -08001/*
2 * edac_mc kernel module
3 * (C) 2005 Linux Networx (http://lnxi.com)
4 * This file may be distributed under the terms of the
5 * GNU General Public License.
6 *
7 * Written by Thayne Harbaugh
8 * Based on work by Dan Hollis <goemon at anime dot net> and others.
9 * http://www.anime.net/~goemon/linux-ecc/
10 *
11 * Modified by Dave Peterson and Doug Thompson
12 *
13 */
14
15
16#include <linux/config.h>
Alan Coxda9bb1d2006-01-18 17:44:13 -080017#include <linux/module.h>
18#include <linux/proc_fs.h>
19#include <linux/kernel.h>
20#include <linux/types.h>
21#include <linux/smp.h>
22#include <linux/init.h>
23#include <linux/sysctl.h>
24#include <linux/highmem.h>
25#include <linux/timer.h>
26#include <linux/slab.h>
27#include <linux/jiffies.h>
28#include <linux/spinlock.h>
29#include <linux/list.h>
30#include <linux/sysdev.h>
31#include <linux/ctype.h>
Dave Petersonf2fe42a2006-03-26 01:38:38 -080032#include <linux/kthread.h>
Alan Coxda9bb1d2006-01-18 17:44:13 -080033
34#include <asm/uaccess.h>
35#include <asm/page.h>
36#include <asm/edac.h>
37
38#include "edac_mc.h"
39
Dave Peterson537fba22006-03-26 01:38:40 -080040#define EDAC_MC_VERSION "Ver: 2.0.0 " __DATE__
Alan Coxda9bb1d2006-01-18 17:44:13 -080041
Dave Petersonceb2ca92006-03-13 21:20:50 -080042/* 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
44 * substantially.
45 */
46#define DISABLE_EDAC_SYSFS
47
Alan Coxda9bb1d2006-01-18 17:44:13 -080048#ifdef CONFIG_EDAC_DEBUG
49/* Values of 0 to 4 will generate output */
50int edac_debug_level = 1;
51EXPORT_SYMBOL(edac_debug_level);
52#endif
53
54/* EDAC Controls, setable by module parameter, and sysfs */
55static int log_ue = 1;
56static int log_ce = 1;
Dave Petersonceb2ca92006-03-13 21:20:50 -080057static int panic_on_ue;
Alan Coxda9bb1d2006-01-18 17:44:13 -080058static int poll_msec = 1000;
59
60static int check_pci_parity = 0; /* default YES check PCI parity */
61static int panic_on_pci_parity; /* default no panic on PCI Parity */
62static atomic_t pci_parity_count = ATOMIC_INIT(0);
63
64/* lock to memory controller's control array */
65static DECLARE_MUTEX(mem_ctls_mutex);
66static struct list_head mc_devices = LIST_HEAD_INIT(mc_devices);
67
Dave Petersonf2fe42a2006-03-26 01:38:38 -080068static struct task_struct *edac_thread;
69
Alan Coxda9bb1d2006-01-18 17:44:13 -080070/* Structure of the whitelist and blacklist arrays */
71struct edac_pci_device_list {
72 unsigned int vendor; /* Vendor ID */
73 unsigned int device; /* Deviice ID */
74};
75
76
77#define MAX_LISTED_PCI_DEVICES 32
78
79/* List of PCI devices (vendor-id:device-id) that should be skipped */
80static struct edac_pci_device_list pci_blacklist[MAX_LISTED_PCI_DEVICES];
81static int pci_blacklist_count;
82
83/* List of PCI devices (vendor-id:device-id) that should be scanned */
84static struct edac_pci_device_list pci_whitelist[MAX_LISTED_PCI_DEVICES];
85static int pci_whitelist_count ;
86
87/* START sysfs data and methods */
88
Dave Petersonceb2ca92006-03-13 21:20:50 -080089#ifndef DISABLE_EDAC_SYSFS
90
Alan Coxda9bb1d2006-01-18 17:44:13 -080091static const char *mem_types[] = {
92 [MEM_EMPTY] = "Empty",
93 [MEM_RESERVED] = "Reserved",
94 [MEM_UNKNOWN] = "Unknown",
95 [MEM_FPM] = "FPM",
96 [MEM_EDO] = "EDO",
97 [MEM_BEDO] = "BEDO",
98 [MEM_SDR] = "Unbuffered-SDR",
99 [MEM_RDR] = "Registered-SDR",
100 [MEM_DDR] = "Unbuffered-DDR",
101 [MEM_RDDR] = "Registered-DDR",
102 [MEM_RMBS] = "RMBS"
103};
104
105static const char *dev_types[] = {
106 [DEV_UNKNOWN] = "Unknown",
107 [DEV_X1] = "x1",
108 [DEV_X2] = "x2",
109 [DEV_X4] = "x4",
110 [DEV_X8] = "x8",
111 [DEV_X16] = "x16",
112 [DEV_X32] = "x32",
113 [DEV_X64] = "x64"
114};
115
116static const char *edac_caps[] = {
117 [EDAC_UNKNOWN] = "Unknown",
118 [EDAC_NONE] = "None",
119 [EDAC_RESERVED] = "Reserved",
120 [EDAC_PARITY] = "PARITY",
121 [EDAC_EC] = "EC",
122 [EDAC_SECDED] = "SECDED",
123 [EDAC_S2ECD2ED] = "S2ECD2ED",
124 [EDAC_S4ECD4ED] = "S4ECD4ED",
125 [EDAC_S8ECD8ED] = "S8ECD8ED",
126 [EDAC_S16ECD16ED] = "S16ECD16ED"
127};
128
129
130/* sysfs object: /sys/devices/system/edac */
131static struct sysdev_class edac_class = {
132 set_kset_name("edac"),
133};
134
135/* sysfs objects:
136 * /sys/devices/system/edac/mc
137 * /sys/devices/system/edac/pci
138 */
139static struct kobject edac_memctrl_kobj;
140static struct kobject edac_pci_kobj;
141
Dave Peterson472678e2006-03-26 01:38:49 -0800142/* We use these to wait for the reference counts on edac_memctrl_kobj and
143 * edac_pci_kobj to reach 0.
144 */
145static struct completion edac_memctrl_kobj_complete;
146static struct completion edac_pci_kobj_complete;
147
Alan Coxda9bb1d2006-01-18 17:44:13 -0800148/*
149 * /sys/devices/system/edac/mc;
150 * data structures and methods
151 */
Arjan van de Ven4136cab2006-03-11 03:27:15 -0800152#if 0
Alan Coxda9bb1d2006-01-18 17:44:13 -0800153static ssize_t memctrl_string_show(void *ptr, char *buffer)
154{
155 char *value = (char*) ptr;
156 return sprintf(buffer, "%s\n", value);
157}
Arjan van de Ven4136cab2006-03-11 03:27:15 -0800158#endif
Alan Coxda9bb1d2006-01-18 17:44:13 -0800159
160static ssize_t memctrl_int_show(void *ptr, char *buffer)
161{
162 int *value = (int*) ptr;
163 return sprintf(buffer, "%d\n", *value);
164}
165
166static ssize_t memctrl_int_store(void *ptr, const char *buffer, size_t count)
167{
168 int *value = (int*) ptr;
169
170 if (isdigit(*buffer))
171 *value = simple_strtoul(buffer, NULL, 0);
172
173 return count;
174}
175
176struct memctrl_dev_attribute {
177 struct attribute attr;
178 void *value;
179 ssize_t (*show)(void *,char *);
180 ssize_t (*store)(void *, const char *, size_t);
181};
182
183/* Set of show/store abstract level functions for memory control object */
184static ssize_t
185memctrl_dev_show(struct kobject *kobj, struct attribute *attr, char *buffer)
186{
187 struct memctrl_dev_attribute *memctrl_dev;
188 memctrl_dev = (struct memctrl_dev_attribute*)attr;
189
190 if (memctrl_dev->show)
191 return memctrl_dev->show(memctrl_dev->value, buffer);
192 return -EIO;
193}
194
195static ssize_t
196memctrl_dev_store(struct kobject *kobj, struct attribute *attr,
197 const char *buffer, size_t count)
198{
199 struct memctrl_dev_attribute *memctrl_dev;
200 memctrl_dev = (struct memctrl_dev_attribute*)attr;
201
202 if (memctrl_dev->store)
203 return memctrl_dev->store(memctrl_dev->value, buffer, count);
204 return -EIO;
205}
206
207static struct sysfs_ops memctrlfs_ops = {
208 .show = memctrl_dev_show,
209 .store = memctrl_dev_store
210};
211
212#define MEMCTRL_ATTR(_name,_mode,_show,_store) \
213struct memctrl_dev_attribute attr_##_name = { \
214 .attr = {.name = __stringify(_name), .mode = _mode }, \
215 .value = &_name, \
216 .show = _show, \
217 .store = _store, \
218};
219
220#define MEMCTRL_STRING_ATTR(_name,_data,_mode,_show,_store) \
221struct memctrl_dev_attribute attr_##_name = { \
222 .attr = {.name = __stringify(_name), .mode = _mode }, \
223 .value = _data, \
224 .show = _show, \
225 .store = _store, \
226};
227
228/* cwrow<id> attribute f*/
Arjan van de Ven4136cab2006-03-11 03:27:15 -0800229#if 0
Alan Coxda9bb1d2006-01-18 17:44:13 -0800230MEMCTRL_STRING_ATTR(mc_version,EDAC_MC_VERSION,S_IRUGO,memctrl_string_show,NULL);
Arjan van de Ven4136cab2006-03-11 03:27:15 -0800231#endif
Alan Coxda9bb1d2006-01-18 17:44:13 -0800232
233/* csrow<id> control files */
234MEMCTRL_ATTR(panic_on_ue,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
235MEMCTRL_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);
237MEMCTRL_ATTR(poll_msec,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
238
239
240/* Base Attributes of the memory ECC object */
241static struct memctrl_dev_attribute *memctrl_attr[] = {
242 &attr_panic_on_ue,
243 &attr_log_ue,
244 &attr_log_ce,
245 &attr_poll_msec,
Alan Coxda9bb1d2006-01-18 17:44:13 -0800246 NULL,
247};
248
249/* Main MC kobject release() function */
250static void edac_memctrl_master_release(struct kobject *kobj)
251{
Dave Peterson537fba22006-03-26 01:38:40 -0800252 debugf1("%s()\n", __func__);
Dave Peterson472678e2006-03-26 01:38:49 -0800253 complete(&edac_memctrl_kobj_complete);
Alan Coxda9bb1d2006-01-18 17:44:13 -0800254}
255
256static struct kobj_type ktype_memctrl = {
257 .release = edac_memctrl_master_release,
258 .sysfs_ops = &memctrlfs_ops,
259 .default_attrs = (struct attribute **) memctrl_attr,
260};
261
Dave Petersonceb2ca92006-03-13 21:20:50 -0800262#endif /* DISABLE_EDAC_SYSFS */
Alan Coxda9bb1d2006-01-18 17:44:13 -0800263
264/* Initialize the main sysfs entries for edac:
265 * /sys/devices/system/edac
266 *
267 * and children
268 *
269 * Return: 0 SUCCESS
270 * !0 FAILURE
271 */
272static int edac_sysfs_memctrl_setup(void)
Dave Petersonceb2ca92006-03-13 21:20:50 -0800273#ifdef DISABLE_EDAC_SYSFS
274{
275 return 0;
276}
277#else
Alan Coxda9bb1d2006-01-18 17:44:13 -0800278{
279 int err=0;
280
Dave Peterson537fba22006-03-26 01:38:40 -0800281 debugf1("%s()\n", __func__);
Alan Coxda9bb1d2006-01-18 17:44:13 -0800282
283 /* create the /sys/devices/system/edac directory */
284 err = sysdev_class_register(&edac_class);
285 if (!err) {
286 /* Init the MC's kobject */
287 memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj));
Alan Coxda9bb1d2006-01-18 17:44:13 -0800288 edac_memctrl_kobj.parent = &edac_class.kset.kobj;
289 edac_memctrl_kobj.ktype = &ktype_memctrl;
290
291 /* generate sysfs "..../edac/mc" */
292 err = kobject_set_name(&edac_memctrl_kobj,"mc");
293 if (!err) {
294 /* FIXME: maybe new sysdev_create_subdir() */
295 err = kobject_register(&edac_memctrl_kobj);
296 if (err) {
297 debugf1("Failed to register '.../edac/mc'\n");
298 } else {
299 debugf1("Registered '.../edac/mc' kobject\n");
300 }
301 }
302 } else {
Dave Peterson537fba22006-03-26 01:38:40 -0800303 debugf1("%s() error=%d\n", __func__, err);
Alan Coxda9bb1d2006-01-18 17:44:13 -0800304 }
305
306 return err;
307}
Dave Petersonceb2ca92006-03-13 21:20:50 -0800308#endif /* DISABLE_EDAC_SYSFS */
Alan Coxda9bb1d2006-01-18 17:44:13 -0800309
310/*
311 * MC teardown:
312 * the '..../edac/mc' kobject followed by '..../edac' itself
313 */
314static void edac_sysfs_memctrl_teardown(void)
315{
Dave Petersonceb2ca92006-03-13 21:20:50 -0800316#ifndef DISABLE_EDAC_SYSFS
Alan Coxda9bb1d2006-01-18 17:44:13 -0800317 debugf0("MC: " __FILE__ ": %s()\n", __func__);
318
Dave Peterson472678e2006-03-26 01:38:49 -0800319 /* Unregister the MC's kobject and wait for reference count to reach
320 * 0.
321 */
322 init_completion(&edac_memctrl_kobj_complete);
Alan Coxda9bb1d2006-01-18 17:44:13 -0800323 kobject_unregister(&edac_memctrl_kobj);
Dave Peterson472678e2006-03-26 01:38:49 -0800324 wait_for_completion(&edac_memctrl_kobj_complete);
Alan Coxda9bb1d2006-01-18 17:44:13 -0800325
Alan Coxda9bb1d2006-01-18 17:44:13 -0800326 /* Unregister the 'edac' object */
327 sysdev_class_unregister(&edac_class);
Dave Petersonceb2ca92006-03-13 21:20:50 -0800328#endif /* DISABLE_EDAC_SYSFS */
Alan Coxda9bb1d2006-01-18 17:44:13 -0800329}
330
Dave Petersonceb2ca92006-03-13 21:20:50 -0800331#ifndef DISABLE_EDAC_SYSFS
332
Alan Coxda9bb1d2006-01-18 17:44:13 -0800333/*
334 * /sys/devices/system/edac/pci;
335 * data structures and methods
336 */
337
338struct list_control {
339 struct edac_pci_device_list *list;
340 int *count;
341};
342
Arjan van de Ven4136cab2006-03-11 03:27:15 -0800343
344#if 0
Alan Coxda9bb1d2006-01-18 17:44:13 -0800345/* Output the list as: vendor_id:device:id<,vendor_id:device_id> */
346static ssize_t edac_pci_list_string_show(void *ptr, char *buffer)
347{
348 struct list_control *listctl;
349 struct edac_pci_device_list *list;
350 char *p = buffer;
351 int len=0;
352 int i;
353
354 listctl = ptr;
355 list = listctl->list;
356
357 for (i = 0; i < *(listctl->count); i++, list++ ) {
358 if (len > 0)
359 len += snprintf(p + len, (PAGE_SIZE-len), ",");
360
361 len += snprintf(p + len,
362 (PAGE_SIZE-len),
363 "%x:%x",
364 list->vendor,list->device);
365 }
366
367 len += snprintf(p + len,(PAGE_SIZE-len), "\n");
368
369 return (ssize_t) len;
370}
371
372/**
373 *
374 * Scan string from **s to **e looking for one 'vendor:device' tuple
375 * where each field is a hex value
376 *
377 * return 0 if an entry is NOT found
378 * return 1 if an entry is found
379 * fill in *vendor_id and *device_id with values found
380 *
381 * In both cases, make sure *s has been moved forward toward *e
382 */
383static int parse_one_device(const char **s,const char **e,
384 unsigned int *vendor_id, unsigned int *device_id)
385{
386 const char *runner, *p;
387
388 /* if null byte, we are done */
389 if (!**s) {
390 (*s)++; /* keep *s moving */
391 return 0;
392 }
393
394 /* skip over newlines & whitespace */
395 if ((**s == '\n') || isspace(**s)) {
396 (*s)++;
397 return 0;
398 }
399
400 if (!isxdigit(**s)) {
401 (*s)++;
402 return 0;
403 }
404
405 /* parse vendor_id */
406 runner = *s;
407 while (runner < *e) {
408 /* scan for vendor:device delimiter */
409 if (*runner == ':') {
410 *vendor_id = simple_strtol((char*) *s, (char**) &p, 16);
411 runner = p + 1;
412 break;
413 }
414 runner++;
415 }
416
417 if (!isxdigit(*runner)) {
418 *s = ++runner;
419 return 0;
420 }
421
422 /* parse device_id */
423 if (runner < *e) {
424 *device_id = simple_strtol((char*)runner, (char**)&p, 16);
425 runner = p;
426 }
427
428 *s = runner;
429
430 return 1;
431}
432
433static ssize_t edac_pci_list_string_store(void *ptr, const char *buffer,
434 size_t count)
435{
436 struct list_control *listctl;
437 struct edac_pci_device_list *list;
438 unsigned int vendor_id, device_id;
439 const char *s, *e;
440 int *index;
441
442 s = (char*)buffer;
443 e = s + count;
444
445 listctl = ptr;
446 list = listctl->list;
447 index = listctl->count;
448
449 *index = 0;
450 while (*index < MAX_LISTED_PCI_DEVICES) {
451
452 if (parse_one_device(&s,&e,&vendor_id,&device_id)) {
453 list[ *index ].vendor = vendor_id;
454 list[ *index ].device = device_id;
455 (*index)++;
456 }
457
458 /* check for all data consume */
459 if (s >= e)
460 break;
461 }
462
463 return count;
464}
465
Arjan van de Ven4136cab2006-03-11 03:27:15 -0800466#endif
Alan Coxda9bb1d2006-01-18 17:44:13 -0800467static ssize_t edac_pci_int_show(void *ptr, char *buffer)
468{
469 int *value = ptr;
470 return sprintf(buffer,"%d\n",*value);
471}
472
473static ssize_t edac_pci_int_store(void *ptr, const char *buffer, size_t count)
474{
475 int *value = ptr;
476
477 if (isdigit(*buffer))
478 *value = simple_strtoul(buffer,NULL,0);
479
480 return count;
481}
482
483struct edac_pci_dev_attribute {
484 struct attribute attr;
485 void *value;
486 ssize_t (*show)(void *,char *);
487 ssize_t (*store)(void *, const char *,size_t);
488};
489
490/* Set of show/store abstract level functions for PCI Parity object */
491static ssize_t edac_pci_dev_show(struct kobject *kobj, struct attribute *attr,
492 char *buffer)
493{
494 struct edac_pci_dev_attribute *edac_pci_dev;
495 edac_pci_dev= (struct edac_pci_dev_attribute*)attr;
496
497 if (edac_pci_dev->show)
498 return edac_pci_dev->show(edac_pci_dev->value, buffer);
499 return -EIO;
500}
501
502static ssize_t edac_pci_dev_store(struct kobject *kobj, struct attribute *attr,
503 const char *buffer, size_t count)
504{
505 struct edac_pci_dev_attribute *edac_pci_dev;
506 edac_pci_dev= (struct edac_pci_dev_attribute*)attr;
507
508 if (edac_pci_dev->show)
509 return edac_pci_dev->store(edac_pci_dev->value, buffer, count);
510 return -EIO;
511}
512
513static struct sysfs_ops edac_pci_sysfs_ops = {
514 .show = edac_pci_dev_show,
515 .store = edac_pci_dev_store
516};
517
518
519#define EDAC_PCI_ATTR(_name,_mode,_show,_store) \
520struct edac_pci_dev_attribute edac_pci_attr_##_name = { \
521 .attr = {.name = __stringify(_name), .mode = _mode }, \
522 .value = &_name, \
523 .show = _show, \
524 .store = _store, \
525};
526
527#define EDAC_PCI_STRING_ATTR(_name,_data,_mode,_show,_store) \
528struct edac_pci_dev_attribute edac_pci_attr_##_name = { \
529 .attr = {.name = __stringify(_name), .mode = _mode }, \
530 .value = _data, \
531 .show = _show, \
532 .store = _store, \
533};
534
Arjan van de Ven4136cab2006-03-11 03:27:15 -0800535#if 0
Alan Coxda9bb1d2006-01-18 17:44:13 -0800536static struct list_control pci_whitelist_control = {
537 .list = pci_whitelist,
538 .count = &pci_whitelist_count
539};
540
541static struct list_control pci_blacklist_control = {
542 .list = pci_blacklist,
543 .count = &pci_blacklist_count
544};
545
546/* whitelist attribute */
547EDAC_PCI_STRING_ATTR(pci_parity_whitelist,
548 &pci_whitelist_control,
549 S_IRUGO|S_IWUSR,
550 edac_pci_list_string_show,
551 edac_pci_list_string_store);
552
553EDAC_PCI_STRING_ATTR(pci_parity_blacklist,
554 &pci_blacklist_control,
555 S_IRUGO|S_IWUSR,
556 edac_pci_list_string_show,
557 edac_pci_list_string_store);
Arjan van de Ven4136cab2006-03-11 03:27:15 -0800558#endif
Alan Coxda9bb1d2006-01-18 17:44:13 -0800559
560/* PCI Parity control files */
561EDAC_PCI_ATTR(check_pci_parity,S_IRUGO|S_IWUSR,edac_pci_int_show,edac_pci_int_store);
562EDAC_PCI_ATTR(panic_on_pci_parity,S_IRUGO|S_IWUSR,edac_pci_int_show,edac_pci_int_store);
563EDAC_PCI_ATTR(pci_parity_count,S_IRUGO,edac_pci_int_show,NULL);
564
565/* Base Attributes of the memory ECC object */
566static struct edac_pci_dev_attribute *edac_pci_attr[] = {
567 &edac_pci_attr_check_pci_parity,
568 &edac_pci_attr_panic_on_pci_parity,
569 &edac_pci_attr_pci_parity_count,
Alan Coxda9bb1d2006-01-18 17:44:13 -0800570 NULL,
571};
572
573/* No memory to release */
574static void edac_pci_release(struct kobject *kobj)
575{
Dave Peterson537fba22006-03-26 01:38:40 -0800576 debugf1("%s()\n", __func__);
Dave Peterson472678e2006-03-26 01:38:49 -0800577 complete(&edac_pci_kobj_complete);
Alan Coxda9bb1d2006-01-18 17:44:13 -0800578}
579
580static struct kobj_type ktype_edac_pci = {
581 .release = edac_pci_release,
582 .sysfs_ops = &edac_pci_sysfs_ops,
583 .default_attrs = (struct attribute **) edac_pci_attr,
584};
585
Dave Petersonceb2ca92006-03-13 21:20:50 -0800586#endif /* DISABLE_EDAC_SYSFS */
587
Alan Coxda9bb1d2006-01-18 17:44:13 -0800588/**
589 * edac_sysfs_pci_setup()
590 *
591 */
592static int edac_sysfs_pci_setup(void)
Dave Petersonceb2ca92006-03-13 21:20:50 -0800593#ifdef DISABLE_EDAC_SYSFS
594{
595 return 0;
596}
597#else
Alan Coxda9bb1d2006-01-18 17:44:13 -0800598{
599 int err;
600
Dave Peterson537fba22006-03-26 01:38:40 -0800601 debugf1("%s()\n", __func__);
Alan Coxda9bb1d2006-01-18 17:44:13 -0800602
603 memset(&edac_pci_kobj, 0, sizeof(edac_pci_kobj));
Alan Coxda9bb1d2006-01-18 17:44:13 -0800604 edac_pci_kobj.parent = &edac_class.kset.kobj;
605 edac_pci_kobj.ktype = &ktype_edac_pci;
606
607 err = kobject_set_name(&edac_pci_kobj, "pci");
608 if (!err) {
609 /* Instanstiate the csrow object */
610 /* FIXME: maybe new sysdev_create_subdir() */
611 err = kobject_register(&edac_pci_kobj);
612 if (err)
613 debugf1("Failed to register '.../edac/pci'\n");
614 else
615 debugf1("Registered '.../edac/pci' kobject\n");
616 }
617 return err;
618}
Dave Petersonceb2ca92006-03-13 21:20:50 -0800619#endif /* DISABLE_EDAC_SYSFS */
Alan Coxda9bb1d2006-01-18 17:44:13 -0800620
621static void edac_sysfs_pci_teardown(void)
622{
Dave Petersonceb2ca92006-03-13 21:20:50 -0800623#ifndef DISABLE_EDAC_SYSFS
Dave Peterson537fba22006-03-26 01:38:40 -0800624 debugf0("%s()\n", __func__);
Dave Peterson472678e2006-03-26 01:38:49 -0800625 init_completion(&edac_pci_kobj_complete);
Alan Coxda9bb1d2006-01-18 17:44:13 -0800626 kobject_unregister(&edac_pci_kobj);
Dave Peterson472678e2006-03-26 01:38:49 -0800627 wait_for_completion(&edac_pci_kobj_complete);
Dave Petersonceb2ca92006-03-13 21:20:50 -0800628#endif
Alan Coxda9bb1d2006-01-18 17:44:13 -0800629}
630
Dave Petersonceb2ca92006-03-13 21:20:50 -0800631#ifndef DISABLE_EDAC_SYSFS
632
Alan Coxda9bb1d2006-01-18 17:44:13 -0800633/* EDAC sysfs CSROW data structures and methods */
634
635/* Set of more detailed csrow<id> attribute show/store functions */
636static ssize_t csrow_ch0_dimm_label_show(struct csrow_info *csrow, char *data)
637{
638 ssize_t size = 0;
639
640 if (csrow->nr_channels > 0) {
641 size = snprintf(data, EDAC_MC_LABEL_LEN,"%s\n",
642 csrow->channels[0].label);
643 }
644 return size;
645}
646
647static ssize_t csrow_ch1_dimm_label_show(struct csrow_info *csrow, char *data)
648{
649 ssize_t size = 0;
650
651 if (csrow->nr_channels > 0) {
652 size = snprintf(data, EDAC_MC_LABEL_LEN, "%s\n",
653 csrow->channels[1].label);
654 }
655 return size;
656}
657
658static ssize_t csrow_ch0_dimm_label_store(struct csrow_info *csrow,
659 const char *data, size_t size)
660{
661 ssize_t max_size = 0;
662
663 if (csrow->nr_channels > 0) {
664 max_size = min((ssize_t)size,(ssize_t)EDAC_MC_LABEL_LEN-1);
665 strncpy(csrow->channels[0].label, data, max_size);
666 csrow->channels[0].label[max_size] = '\0';
667 }
668 return size;
669}
670
671static ssize_t csrow_ch1_dimm_label_store(struct csrow_info *csrow,
672 const char *data, size_t size)
673{
674 ssize_t max_size = 0;
675
676 if (csrow->nr_channels > 1) {
677 max_size = min((ssize_t)size,(ssize_t)EDAC_MC_LABEL_LEN-1);
678 strncpy(csrow->channels[1].label, data, max_size);
679 csrow->channels[1].label[max_size] = '\0';
680 }
681 return max_size;
682}
683
684static ssize_t csrow_ue_count_show(struct csrow_info *csrow, char *data)
685{
686 return sprintf(data,"%u\n", csrow->ue_count);
687}
688
689static ssize_t csrow_ce_count_show(struct csrow_info *csrow, char *data)
690{
691 return sprintf(data,"%u\n", csrow->ce_count);
692}
693
694static ssize_t csrow_ch0_ce_count_show(struct csrow_info *csrow, char *data)
695{
696 ssize_t size = 0;
697
698 if (csrow->nr_channels > 0) {
699 size = sprintf(data,"%u\n", csrow->channels[0].ce_count);
700 }
701 return size;
702}
703
704static ssize_t csrow_ch1_ce_count_show(struct csrow_info *csrow, char *data)
705{
706 ssize_t size = 0;
707
708 if (csrow->nr_channels > 1) {
709 size = sprintf(data,"%u\n", csrow->channels[1].ce_count);
710 }
711 return size;
712}
713
714static ssize_t csrow_size_show(struct csrow_info *csrow, char *data)
715{
716 return sprintf(data,"%u\n", PAGES_TO_MiB(csrow->nr_pages));
717}
718
719static ssize_t csrow_mem_type_show(struct csrow_info *csrow, char *data)
720{
721 return sprintf(data,"%s\n", mem_types[csrow->mtype]);
722}
723
724static ssize_t csrow_dev_type_show(struct csrow_info *csrow, char *data)
725{
726 return sprintf(data,"%s\n", dev_types[csrow->dtype]);
727}
728
729static ssize_t csrow_edac_mode_show(struct csrow_info *csrow, char *data)
730{
731 return sprintf(data,"%s\n", edac_caps[csrow->edac_mode]);
732}
733
734struct csrowdev_attribute {
735 struct attribute attr;
736 ssize_t (*show)(struct csrow_info *,char *);
737 ssize_t (*store)(struct csrow_info *, const char *,size_t);
738};
739
740#define to_csrow(k) container_of(k, struct csrow_info, kobj)
741#define to_csrowdev_attr(a) container_of(a, struct csrowdev_attribute, attr)
742
743/* Set of show/store higher level functions for csrow objects */
744static ssize_t csrowdev_show(struct kobject *kobj, struct attribute *attr,
745 char *buffer)
746{
747 struct csrow_info *csrow = to_csrow(kobj);
748 struct csrowdev_attribute *csrowdev_attr = to_csrowdev_attr(attr);
749
750 if (csrowdev_attr->show)
751 return csrowdev_attr->show(csrow, buffer);
752 return -EIO;
753}
754
755static ssize_t csrowdev_store(struct kobject *kobj, struct attribute *attr,
756 const char *buffer, size_t count)
757{
758 struct csrow_info *csrow = to_csrow(kobj);
759 struct csrowdev_attribute * csrowdev_attr = to_csrowdev_attr(attr);
760
761 if (csrowdev_attr->store)
762 return csrowdev_attr->store(csrow, buffer, count);
763 return -EIO;
764}
765
766static struct sysfs_ops csrowfs_ops = {
767 .show = csrowdev_show,
768 .store = csrowdev_store
769};
770
771#define CSROWDEV_ATTR(_name,_mode,_show,_store) \
772struct csrowdev_attribute attr_##_name = { \
773 .attr = {.name = __stringify(_name), .mode = _mode }, \
774 .show = _show, \
775 .store = _store, \
776};
777
778/* cwrow<id>/attribute files */
779CSROWDEV_ATTR(size_mb,S_IRUGO,csrow_size_show,NULL);
780CSROWDEV_ATTR(dev_type,S_IRUGO,csrow_dev_type_show,NULL);
781CSROWDEV_ATTR(mem_type,S_IRUGO,csrow_mem_type_show,NULL);
782CSROWDEV_ATTR(edac_mode,S_IRUGO,csrow_edac_mode_show,NULL);
783CSROWDEV_ATTR(ue_count,S_IRUGO,csrow_ue_count_show,NULL);
784CSROWDEV_ATTR(ce_count,S_IRUGO,csrow_ce_count_show,NULL);
785CSROWDEV_ATTR(ch0_ce_count,S_IRUGO,csrow_ch0_ce_count_show,NULL);
786CSROWDEV_ATTR(ch1_ce_count,S_IRUGO,csrow_ch1_ce_count_show,NULL);
787
788/* control/attribute files */
789CSROWDEV_ATTR(ch0_dimm_label,S_IRUGO|S_IWUSR,
790 csrow_ch0_dimm_label_show,
791 csrow_ch0_dimm_label_store);
792CSROWDEV_ATTR(ch1_dimm_label,S_IRUGO|S_IWUSR,
793 csrow_ch1_dimm_label_show,
794 csrow_ch1_dimm_label_store);
795
796
797/* Attributes of the CSROW<id> object */
798static struct csrowdev_attribute *csrow_attr[] = {
799 &attr_dev_type,
800 &attr_mem_type,
801 &attr_edac_mode,
802 &attr_size_mb,
803 &attr_ue_count,
804 &attr_ce_count,
805 &attr_ch0_ce_count,
806 &attr_ch1_ce_count,
807 &attr_ch0_dimm_label,
808 &attr_ch1_dimm_label,
809 NULL,
810};
811
812
813/* No memory to release */
814static void edac_csrow_instance_release(struct kobject *kobj)
815{
Dave Peterson472678e2006-03-26 01:38:49 -0800816 struct csrow_info *cs;
817
Dave Peterson537fba22006-03-26 01:38:40 -0800818 debugf1("%s()\n", __func__);
Dave Peterson472678e2006-03-26 01:38:49 -0800819 cs = container_of(kobj, struct csrow_info, kobj);
820 complete(&cs->kobj_complete);
Alan Coxda9bb1d2006-01-18 17:44:13 -0800821}
822
823static struct kobj_type ktype_csrow = {
824 .release = edac_csrow_instance_release,
825 .sysfs_ops = &csrowfs_ops,
826 .default_attrs = (struct attribute **) csrow_attr,
827};
828
829/* Create a CSROW object under specifed edac_mc_device */
830static int edac_create_csrow_object(struct kobject *edac_mci_kobj,
831 struct csrow_info *csrow, int index )
832{
833 int err = 0;
834
Dave Peterson537fba22006-03-26 01:38:40 -0800835 debugf0("%s()\n", __func__);
Alan Coxda9bb1d2006-01-18 17:44:13 -0800836
837 memset(&csrow->kobj, 0, sizeof(csrow->kobj));
838
839 /* generate ..../edac/mc/mc<id>/csrow<index> */
840
Alan Coxda9bb1d2006-01-18 17:44:13 -0800841 csrow->kobj.parent = edac_mci_kobj;
842 csrow->kobj.ktype = &ktype_csrow;
843
844 /* name this instance of csrow<id> */
845 err = kobject_set_name(&csrow->kobj,"csrow%d",index);
846 if (!err) {
847 /* Instanstiate the csrow object */
848 err = kobject_register(&csrow->kobj);
849 if (err)
850 debugf0("Failed to register CSROW%d\n",index);
851 else
852 debugf0("Registered CSROW%d\n",index);
853 }
854
855 return err;
856}
857
858/* sysfs data structures and methods for the MCI kobjects */
859
860static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci,
861 const char *data, size_t count )
862{
863 int row, chan;
864
865 mci->ue_noinfo_count = 0;
866 mci->ce_noinfo_count = 0;
867 mci->ue_count = 0;
868 mci->ce_count = 0;
869 for (row = 0; row < mci->nr_csrows; row++) {
870 struct csrow_info *ri = &mci->csrows[row];
871
872 ri->ue_count = 0;
873 ri->ce_count = 0;
874 for (chan = 0; chan < ri->nr_channels; chan++)
875 ri->channels[chan].ce_count = 0;
876 }
877 mci->start_time = jiffies;
878
879 return count;
880}
881
882static ssize_t mci_ue_count_show(struct mem_ctl_info *mci, char *data)
883{
884 return sprintf(data,"%d\n", mci->ue_count);
885}
886
887static ssize_t mci_ce_count_show(struct mem_ctl_info *mci, char *data)
888{
889 return sprintf(data,"%d\n", mci->ce_count);
890}
891
892static ssize_t mci_ce_noinfo_show(struct mem_ctl_info *mci, char *data)
893{
894 return sprintf(data,"%d\n", mci->ce_noinfo_count);
895}
896
897static ssize_t mci_ue_noinfo_show(struct mem_ctl_info *mci, char *data)
898{
899 return sprintf(data,"%d\n", mci->ue_noinfo_count);
900}
901
902static ssize_t mci_seconds_show(struct mem_ctl_info *mci, char *data)
903{
904 return sprintf(data,"%ld\n", (jiffies - mci->start_time) / HZ);
905}
906
907static ssize_t mci_mod_name_show(struct mem_ctl_info *mci, char *data)
908{
909 return sprintf(data,"%s %s\n", mci->mod_name, mci->mod_ver);
910}
911
912static ssize_t mci_ctl_name_show(struct mem_ctl_info *mci, char *data)
913{
914 return sprintf(data,"%s\n", mci->ctl_name);
915}
916
917static int mci_output_edac_cap(char *buf, unsigned long edac_cap)
918{
919 char *p = buf;
920 int bit_idx;
921
922 for (bit_idx = 0; bit_idx < 8 * sizeof(edac_cap); bit_idx++) {
923 if ((edac_cap >> bit_idx) & 0x1)
924 p += sprintf(p, "%s ", edac_caps[bit_idx]);
925 }
926
927 return p - buf;
928}
929
930static ssize_t mci_edac_capability_show(struct mem_ctl_info *mci, char *data)
931{
932 char *p = data;
933
934 p += mci_output_edac_cap(p,mci->edac_ctl_cap);
935 p += sprintf(p, "\n");
936
937 return p - data;
938}
939
940static ssize_t mci_edac_current_capability_show(struct mem_ctl_info *mci,
941 char *data)
942{
943 char *p = data;
944
945 p += mci_output_edac_cap(p,mci->edac_cap);
946 p += sprintf(p, "\n");
947
948 return p - data;
949}
950
951static int mci_output_mtype_cap(char *buf, unsigned long mtype_cap)
952{
953 char *p = buf;
954 int bit_idx;
955
956 for (bit_idx = 0; bit_idx < 8 * sizeof(mtype_cap); bit_idx++) {
957 if ((mtype_cap >> bit_idx) & 0x1)
958 p += sprintf(p, "%s ", mem_types[bit_idx]);
959 }
960
961 return p - buf;
962}
963
964static ssize_t mci_supported_mem_type_show(struct mem_ctl_info *mci, char *data)
965{
966 char *p = data;
967
968 p += mci_output_mtype_cap(p,mci->mtype_cap);
969 p += sprintf(p, "\n");
970
971 return p - data;
972}
973
974static ssize_t mci_size_mb_show(struct mem_ctl_info *mci, char *data)
975{
976 int total_pages, csrow_idx;
977
978 for (total_pages = csrow_idx = 0; csrow_idx < mci->nr_csrows;
979 csrow_idx++) {
980 struct csrow_info *csrow = &mci->csrows[csrow_idx];
981
982 if (!csrow->nr_pages)
983 continue;
984 total_pages += csrow->nr_pages;
985 }
986
987 return sprintf(data,"%u\n", PAGES_TO_MiB(total_pages));
988}
989
990struct mcidev_attribute {
991 struct attribute attr;
992 ssize_t (*show)(struct mem_ctl_info *,char *);
993 ssize_t (*store)(struct mem_ctl_info *, const char *,size_t);
994};
995
996#define to_mci(k) container_of(k, struct mem_ctl_info, edac_mci_kobj)
997#define to_mcidev_attr(a) container_of(a, struct mcidev_attribute, attr)
998
999static ssize_t mcidev_show(struct kobject *kobj, struct attribute *attr,
1000 char *buffer)
1001{
1002 struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
1003 struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr);
1004
1005 if (mcidev_attr->show)
1006 return mcidev_attr->show(mem_ctl_info, buffer);
1007 return -EIO;
1008}
1009
1010static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr,
1011 const char *buffer, size_t count)
1012{
1013 struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
1014 struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr);
1015
1016 if (mcidev_attr->store)
1017 return mcidev_attr->store(mem_ctl_info, buffer, count);
1018 return -EIO;
1019}
1020
1021static struct sysfs_ops mci_ops = {
1022 .show = mcidev_show,
1023 .store = mcidev_store
1024};
1025
1026#define MCIDEV_ATTR(_name,_mode,_show,_store) \
1027struct mcidev_attribute mci_attr_##_name = { \
1028 .attr = {.name = __stringify(_name), .mode = _mode }, \
1029 .show = _show, \
1030 .store = _store, \
1031};
1032
1033/* Control file */
1034MCIDEV_ATTR(reset_counters,S_IWUSR,NULL,mci_reset_counters_store);
1035
1036/* Attribute files */
1037MCIDEV_ATTR(mc_name,S_IRUGO,mci_ctl_name_show,NULL);
1038MCIDEV_ATTR(module_name,S_IRUGO,mci_mod_name_show,NULL);
1039MCIDEV_ATTR(edac_capability,S_IRUGO,mci_edac_capability_show,NULL);
1040MCIDEV_ATTR(size_mb,S_IRUGO,mci_size_mb_show,NULL);
1041MCIDEV_ATTR(seconds_since_reset,S_IRUGO,mci_seconds_show,NULL);
1042MCIDEV_ATTR(ue_noinfo_count,S_IRUGO,mci_ue_noinfo_show,NULL);
1043MCIDEV_ATTR(ce_noinfo_count,S_IRUGO,mci_ce_noinfo_show,NULL);
1044MCIDEV_ATTR(ue_count,S_IRUGO,mci_ue_count_show,NULL);
1045MCIDEV_ATTR(ce_count,S_IRUGO,mci_ce_count_show,NULL);
1046MCIDEV_ATTR(edac_current_capability,S_IRUGO,
1047 mci_edac_current_capability_show,NULL);
1048MCIDEV_ATTR(supported_mem_type,S_IRUGO,
1049 mci_supported_mem_type_show,NULL);
1050
1051
1052static struct mcidev_attribute *mci_attr[] = {
1053 &mci_attr_reset_counters,
1054 &mci_attr_module_name,
1055 &mci_attr_mc_name,
1056 &mci_attr_edac_capability,
1057 &mci_attr_edac_current_capability,
1058 &mci_attr_supported_mem_type,
1059 &mci_attr_size_mb,
1060 &mci_attr_seconds_since_reset,
1061 &mci_attr_ue_noinfo_count,
1062 &mci_attr_ce_noinfo_count,
1063 &mci_attr_ue_count,
1064 &mci_attr_ce_count,
1065 NULL
1066};
1067
1068
1069/*
1070 * Release of a MC controlling instance
1071 */
1072static void edac_mci_instance_release(struct kobject *kobj)
1073{
1074 struct mem_ctl_info *mci;
Alan Coxda9bb1d2006-01-18 17:44:13 -08001075
Dave Peterson472678e2006-03-26 01:38:49 -08001076 mci = to_mci(kobj);
1077 debugf0("%s() idx=%d\n", __func__, mci->mc_idx);
1078 complete(&mci->kobj_complete);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001079}
1080
1081static struct kobj_type ktype_mci = {
1082 .release = edac_mci_instance_release,
1083 .sysfs_ops = &mci_ops,
1084 .default_attrs = (struct attribute **) mci_attr,
1085};
1086
Dave Petersonceb2ca92006-03-13 21:20:50 -08001087#endif /* DISABLE_EDAC_SYSFS */
1088
Alan Coxda9bb1d2006-01-18 17:44:13 -08001089#define EDAC_DEVICE_SYMLINK "device"
1090
1091/*
1092 * Create a new Memory Controller kobject instance,
1093 * mc<id> under the 'mc' directory
1094 *
1095 * Return:
1096 * 0 Success
1097 * !0 Failure
1098 */
1099static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
Dave Petersonceb2ca92006-03-13 21:20:50 -08001100#ifdef DISABLE_EDAC_SYSFS
1101{
1102 return 0;
1103}
1104#else
Alan Coxda9bb1d2006-01-18 17:44:13 -08001105{
1106 int i;
1107 int err;
1108 struct csrow_info *csrow;
1109 struct kobject *edac_mci_kobj=&mci->edac_mci_kobj;
1110
Dave Peterson537fba22006-03-26 01:38:40 -08001111 debugf0("%s() idx=%d\n", __func__, mci->mc_idx);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001112
1113 memset(edac_mci_kobj, 0, sizeof(*edac_mci_kobj));
Alan Coxda9bb1d2006-01-18 17:44:13 -08001114
1115 /* set the name of the mc<id> object */
1116 err = kobject_set_name(edac_mci_kobj,"mc%d",mci->mc_idx);
1117 if (err)
1118 return err;
1119
1120 /* link to our parent the '..../edac/mc' object */
1121 edac_mci_kobj->parent = &edac_memctrl_kobj;
1122 edac_mci_kobj->ktype = &ktype_mci;
1123
1124 /* register the mc<id> kobject */
1125 err = kobject_register(edac_mci_kobj);
1126 if (err)
1127 return err;
1128
1129 /* create a symlink for the device */
1130 err = sysfs_create_link(edac_mci_kobj, &mci->pdev->dev.kobj,
1131 EDAC_DEVICE_SYMLINK);
Dave Peterson6e5a8742006-03-26 01:38:48 -08001132 if (err)
1133 goto fail0;
Alan Coxda9bb1d2006-01-18 17:44:13 -08001134
1135 /* Make directories for each CSROW object
1136 * under the mc<id> kobject
1137 */
1138 for (i = 0; i < mci->nr_csrows; i++) {
1139
1140 csrow = &mci->csrows[i];
1141
1142 /* Only expose populated CSROWs */
1143 if (csrow->nr_pages > 0) {
1144 err = edac_create_csrow_object(edac_mci_kobj,csrow,i);
1145 if (err)
Dave Peterson6e5a8742006-03-26 01:38:48 -08001146 goto fail1;
Alan Coxda9bb1d2006-01-18 17:44:13 -08001147 }
1148 }
1149
Alan Coxda9bb1d2006-01-18 17:44:13 -08001150 return 0;
1151
1152
1153 /* CSROW error: backout what has already been registered, */
Dave Peterson6e5a8742006-03-26 01:38:48 -08001154fail1:
Alan Coxda9bb1d2006-01-18 17:44:13 -08001155 for ( i--; i >= 0; i--) {
Dave Peterson472678e2006-03-26 01:38:49 -08001156 if (csrow->nr_pages > 0) {
1157 init_completion(&csrow->kobj_complete);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001158 kobject_unregister(&mci->csrows[i].kobj);
Dave Peterson472678e2006-03-26 01:38:49 -08001159 wait_for_completion(&csrow->kobj_complete);
1160 }
Alan Coxda9bb1d2006-01-18 17:44:13 -08001161 }
1162
Dave Peterson6e5a8742006-03-26 01:38:48 -08001163fail0:
Dave Peterson472678e2006-03-26 01:38:49 -08001164 init_completion(&mci->kobj_complete);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001165 kobject_unregister(edac_mci_kobj);
Dave Peterson472678e2006-03-26 01:38:49 -08001166 wait_for_completion(&mci->kobj_complete);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001167
1168 return err;
1169}
Dave Petersonceb2ca92006-03-13 21:20:50 -08001170#endif /* DISABLE_EDAC_SYSFS */
Alan Coxda9bb1d2006-01-18 17:44:13 -08001171
1172/*
1173 * remove a Memory Controller instance
1174 */
1175static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
1176{
Dave Petersonceb2ca92006-03-13 21:20:50 -08001177#ifndef DISABLE_EDAC_SYSFS
Alan Coxda9bb1d2006-01-18 17:44:13 -08001178 int i;
1179
Dave Peterson537fba22006-03-26 01:38:40 -08001180 debugf0("%s()\n", __func__);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001181
1182 /* remove all csrow kobjects */
1183 for (i = 0; i < mci->nr_csrows; i++) {
Dave Peterson472678e2006-03-26 01:38:49 -08001184 if (mci->csrows[i].nr_pages > 0) {
1185 init_completion(&mci->csrows[i].kobj_complete);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001186 kobject_unregister(&mci->csrows[i].kobj);
Dave Peterson472678e2006-03-26 01:38:49 -08001187 wait_for_completion(&mci->csrows[i].kobj_complete);
1188 }
Alan Coxda9bb1d2006-01-18 17:44:13 -08001189 }
1190
1191 sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK);
Dave Peterson472678e2006-03-26 01:38:49 -08001192 init_completion(&mci->kobj_complete);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001193 kobject_unregister(&mci->edac_mci_kobj);
Dave Peterson472678e2006-03-26 01:38:49 -08001194 wait_for_completion(&mci->kobj_complete);
Dave Petersonceb2ca92006-03-13 21:20:50 -08001195#endif /* DISABLE_EDAC_SYSFS */
Alan Coxda9bb1d2006-01-18 17:44:13 -08001196}
1197
1198/* END OF sysfs data and methods */
1199
1200#ifdef CONFIG_EDAC_DEBUG
1201
1202EXPORT_SYMBOL(edac_mc_dump_channel);
1203
1204void edac_mc_dump_channel(struct channel_info *chan)
1205{
1206 debugf4("\tchannel = %p\n", chan);
1207 debugf4("\tchannel->chan_idx = %d\n", chan->chan_idx);
1208 debugf4("\tchannel->ce_count = %d\n", chan->ce_count);
1209 debugf4("\tchannel->label = '%s'\n", chan->label);
1210 debugf4("\tchannel->csrow = %p\n\n", chan->csrow);
1211}
1212
1213
1214EXPORT_SYMBOL(edac_mc_dump_csrow);
1215
1216void edac_mc_dump_csrow(struct csrow_info *csrow)
1217{
1218 debugf4("\tcsrow = %p\n", csrow);
1219 debugf4("\tcsrow->csrow_idx = %d\n", csrow->csrow_idx);
1220 debugf4("\tcsrow->first_page = 0x%lx\n",
1221 csrow->first_page);
1222 debugf4("\tcsrow->last_page = 0x%lx\n", csrow->last_page);
1223 debugf4("\tcsrow->page_mask = 0x%lx\n", csrow->page_mask);
1224 debugf4("\tcsrow->nr_pages = 0x%x\n", csrow->nr_pages);
1225 debugf4("\tcsrow->nr_channels = %d\n",
1226 csrow->nr_channels);
1227 debugf4("\tcsrow->channels = %p\n", csrow->channels);
1228 debugf4("\tcsrow->mci = %p\n\n", csrow->mci);
1229}
1230
1231
1232EXPORT_SYMBOL(edac_mc_dump_mci);
1233
1234void edac_mc_dump_mci(struct mem_ctl_info *mci)
1235{
1236 debugf3("\tmci = %p\n", mci);
1237 debugf3("\tmci->mtype_cap = %lx\n", mci->mtype_cap);
1238 debugf3("\tmci->edac_ctl_cap = %lx\n", mci->edac_ctl_cap);
1239 debugf3("\tmci->edac_cap = %lx\n", mci->edac_cap);
1240 debugf4("\tmci->edac_check = %p\n", mci->edac_check);
1241 debugf3("\tmci->nr_csrows = %d, csrows = %p\n",
1242 mci->nr_csrows, mci->csrows);
1243 debugf3("\tpdev = %p\n", mci->pdev);
1244 debugf3("\tmod_name:ctl_name = %s:%s\n",
1245 mci->mod_name, mci->ctl_name);
1246 debugf3("\tpvt_info = %p\n\n", mci->pvt_info);
1247}
1248
1249
1250#endif /* CONFIG_EDAC_DEBUG */
1251
1252/* 'ptr' points to a possibly unaligned item X such that sizeof(X) is 'size'.
1253 * Adjust 'ptr' so that its alignment is at least as stringent as what the
1254 * compiler would provide for X and return the aligned result.
1255 *
1256 * If 'size' is a constant, the compiler will optimize this whole function
1257 * down to either a no-op or the addition of a constant to the value of 'ptr'.
1258 */
1259static inline char * align_ptr (void *ptr, unsigned size)
1260{
1261 unsigned align, r;
1262
1263 /* Here we assume that the alignment of a "long long" is the most
1264 * stringent alignment that the compiler will ever provide by default.
1265 * As far as I know, this is a reasonable assumption.
1266 */
1267 if (size > sizeof(long))
1268 align = sizeof(long long);
1269 else if (size > sizeof(int))
1270 align = sizeof(long);
1271 else if (size > sizeof(short))
1272 align = sizeof(int);
1273 else if (size > sizeof(char))
1274 align = sizeof(short);
1275 else
1276 return (char *) ptr;
1277
1278 r = size % align;
1279
1280 if (r == 0)
1281 return (char *) ptr;
1282
1283 return (char *) (((unsigned long) ptr) + align - r);
1284}
1285
1286
1287EXPORT_SYMBOL(edac_mc_alloc);
1288
1289/**
1290 * edac_mc_alloc: Allocate a struct mem_ctl_info structure
1291 * @size_pvt: size of private storage needed
1292 * @nr_csrows: Number of CWROWS needed for this MC
1293 * @nr_chans: Number of channels for the MC
1294 *
1295 * Everything is kmalloc'ed as one big chunk - more efficient.
1296 * Only can be used if all structures have the same lifetime - otherwise
1297 * you have to allocate and initialize your own structures.
1298 *
1299 * Use edac_mc_free() to free mc structures allocated by this function.
1300 *
1301 * Returns:
1302 * NULL allocation failed
1303 * struct mem_ctl_info pointer
1304 */
1305struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
1306 unsigned nr_chans)
1307{
1308 struct mem_ctl_info *mci;
1309 struct csrow_info *csi, *csrow;
1310 struct channel_info *chi, *chp, *chan;
1311 void *pvt;
1312 unsigned size;
1313 int row, chn;
1314
1315 /* Figure out the offsets of the various items from the start of an mc
1316 * structure. We want the alignment of each item to be at least as
1317 * stringent as what the compiler would provide if we could simply
1318 * hardcode everything into a single struct.
1319 */
1320 mci = (struct mem_ctl_info *) 0;
1321 csi = (struct csrow_info *)align_ptr(&mci[1], sizeof(*csi));
1322 chi = (struct channel_info *)
1323 align_ptr(&csi[nr_csrows], sizeof(*chi));
1324 pvt = align_ptr(&chi[nr_chans * nr_csrows], sz_pvt);
1325 size = ((unsigned long) pvt) + sz_pvt;
1326
1327 if ((mci = kmalloc(size, GFP_KERNEL)) == NULL)
1328 return NULL;
1329
1330 /* Adjust pointers so they point within the memory we just allocated
1331 * rather than an imaginary chunk of memory located at address 0.
1332 */
1333 csi = (struct csrow_info *) (((char *) mci) + ((unsigned long) csi));
1334 chi = (struct channel_info *) (((char *) mci) + ((unsigned long) chi));
1335 pvt = sz_pvt ? (((char *) mci) + ((unsigned long) pvt)) : NULL;
1336
1337 memset(mci, 0, size); /* clear all fields */
1338
1339 mci->csrows = csi;
1340 mci->pvt_info = pvt;
1341 mci->nr_csrows = nr_csrows;
1342
1343 for (row = 0; row < nr_csrows; row++) {
1344 csrow = &csi[row];
1345 csrow->csrow_idx = row;
1346 csrow->mci = mci;
1347 csrow->nr_channels = nr_chans;
1348 chp = &chi[row * nr_chans];
1349 csrow->channels = chp;
1350
1351 for (chn = 0; chn < nr_chans; chn++) {
1352 chan = &chp[chn];
1353 chan->chan_idx = chn;
1354 chan->csrow = csrow;
1355 }
1356 }
1357
1358 return mci;
1359}
1360
1361
1362EXPORT_SYMBOL(edac_mc_free);
1363
1364/**
1365 * edac_mc_free: Free a previously allocated 'mci' structure
1366 * @mci: pointer to a struct mem_ctl_info structure
Alan Coxda9bb1d2006-01-18 17:44:13 -08001367 */
1368void edac_mc_free(struct mem_ctl_info *mci)
1369{
Dave Peterson472678e2006-03-26 01:38:49 -08001370 kfree(mci);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001371}
1372
1373
1374
1375EXPORT_SYMBOL(edac_mc_find_mci_by_pdev);
1376
1377struct mem_ctl_info *edac_mc_find_mci_by_pdev(struct pci_dev *pdev)
1378{
1379 struct mem_ctl_info *mci;
1380 struct list_head *item;
1381
Dave Peterson537fba22006-03-26 01:38:40 -08001382 debugf3("%s()\n", __func__);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001383
1384 list_for_each(item, &mc_devices) {
1385 mci = list_entry(item, struct mem_ctl_info, link);
1386
1387 if (mci->pdev == pdev)
1388 return mci;
1389 }
1390
1391 return NULL;
1392}
1393
1394static int add_mc_to_global_list (struct mem_ctl_info *mci)
1395{
1396 struct list_head *item, *insert_before;
1397 struct mem_ctl_info *p;
1398 int i;
1399
1400 if (list_empty(&mc_devices)) {
1401 mci->mc_idx = 0;
1402 insert_before = &mc_devices;
1403 } else {
1404 if (edac_mc_find_mci_by_pdev(mci->pdev)) {
Dave Peterson537fba22006-03-26 01:38:40 -08001405 edac_printk(KERN_WARNING, EDAC_MC,
1406 "%s (%s) %s %s already assigned %d\n",
1407 mci->pdev->dev.bus_id,
1408 pci_name(mci->pdev), mci->mod_name,
1409 mci->ctl_name, mci->mc_idx);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001410 return 1;
1411 }
1412
1413 insert_before = NULL;
1414 i = 0;
1415
1416 list_for_each(item, &mc_devices) {
1417 p = list_entry(item, struct mem_ctl_info, link);
1418
1419 if (p->mc_idx != i) {
1420 insert_before = item;
1421 break;
1422 }
1423
1424 i++;
1425 }
1426
1427 mci->mc_idx = i;
1428
1429 if (insert_before == NULL)
1430 insert_before = &mc_devices;
1431 }
1432
1433 list_add_tail_rcu(&mci->link, insert_before);
1434 return 0;
1435}
1436
1437
Dave Petersona1d03fc2006-03-26 01:38:46 -08001438static void complete_mc_list_del (struct rcu_head *head)
1439{
1440 struct mem_ctl_info *mci;
1441
1442 mci = container_of(head, struct mem_ctl_info, rcu);
1443 INIT_LIST_HEAD(&mci->link);
1444 complete(&mci->complete);
1445}
1446
1447
1448static void del_mc_from_global_list (struct mem_ctl_info *mci)
1449{
1450 list_del_rcu(&mci->link);
1451 init_completion(&mci->complete);
1452 call_rcu(&mci->rcu, complete_mc_list_del);
1453 wait_for_completion(&mci->complete);
1454}
1455
Alan Coxda9bb1d2006-01-18 17:44:13 -08001456
1457EXPORT_SYMBOL(edac_mc_add_mc);
1458
1459/**
Dave Peterson472678e2006-03-26 01:38:49 -08001460 * edac_mc_add_mc: Insert the 'mci' structure into the mci global list and
1461 * create sysfs entries associated with mci structure
Alan Coxda9bb1d2006-01-18 17:44:13 -08001462 * @mci: pointer to the mci structure to be added to the list
1463 *
1464 * Return:
1465 * 0 Success
1466 * !0 Failure
1467 */
1468
1469/* FIXME - should a warning be printed if no error detection? correction? */
1470int edac_mc_add_mc(struct mem_ctl_info *mci)
1471{
Dave Peterson537fba22006-03-26 01:38:40 -08001472 debugf0("%s()\n", __func__);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001473#ifdef CONFIG_EDAC_DEBUG
1474 if (edac_debug_level >= 3)
1475 edac_mc_dump_mci(mci);
1476 if (edac_debug_level >= 4) {
1477 int i;
1478
1479 for (i = 0; i < mci->nr_csrows; i++) {
1480 int j;
1481 edac_mc_dump_csrow(&mci->csrows[i]);
1482 for (j = 0; j < mci->csrows[i].nr_channels; j++)
1483 edac_mc_dump_channel(&mci->csrows[i].
1484 channels[j]);
1485 }
1486 }
1487#endif
1488 down(&mem_ctls_mutex);
1489
1490 if (add_mc_to_global_list(mci))
Dave Peterson028a7b62006-03-26 01:38:47 -08001491 goto fail0;
Alan Coxda9bb1d2006-01-18 17:44:13 -08001492
1493 /* set load time so that error rate can be tracked */
1494 mci->start_time = jiffies;
1495
1496 if (edac_create_sysfs_mci_device(mci)) {
Dave Peterson537fba22006-03-26 01:38:40 -08001497 edac_mc_printk(mci, KERN_WARNING,
1498 "failed to create sysfs device\n");
Dave Peterson028a7b62006-03-26 01:38:47 -08001499 goto fail1;
Alan Coxda9bb1d2006-01-18 17:44:13 -08001500 }
1501
1502 /* Report action taken */
Dave Peterson537fba22006-03-26 01:38:40 -08001503 edac_mc_printk(mci, KERN_INFO, "Giving out device to %s %s: PCI %s\n",
1504 mci->mod_name, mci->ctl_name, pci_name(mci->pdev));
Alan Coxda9bb1d2006-01-18 17:44:13 -08001505
Alan Coxda9bb1d2006-01-18 17:44:13 -08001506 up(&mem_ctls_mutex);
Dave Peterson028a7b62006-03-26 01:38:47 -08001507 return 0;
1508
1509fail1:
1510 del_mc_from_global_list(mci);
1511
1512fail0:
1513 up(&mem_ctls_mutex);
1514 return 1;
Alan Coxda9bb1d2006-01-18 17:44:13 -08001515}
1516
1517
Alan Coxda9bb1d2006-01-18 17:44:13 -08001518EXPORT_SYMBOL(edac_mc_del_mc);
1519
1520/**
Dave Peterson472678e2006-03-26 01:38:49 -08001521 * edac_mc_del_mc: Remove sysfs entries for specified mci structure and
1522 * remove mci structure from global list
Alan Coxda9bb1d2006-01-18 17:44:13 -08001523 * @mci: Pointer to struct mem_ctl_info structure
1524 *
1525 * Returns:
1526 * 0 Success
1527 * 1 Failure
1528 */
1529int edac_mc_del_mc(struct mem_ctl_info *mci)
1530{
1531 int rc = 1;
1532
Dave Peterson537fba22006-03-26 01:38:40 -08001533 debugf0("MC%d: %s()\n", mci->mc_idx, __func__);
Dave Peterson472678e2006-03-26 01:38:49 -08001534 edac_remove_sysfs_mci_device(mci);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001535 down(&mem_ctls_mutex);
1536 del_mc_from_global_list(mci);
Dave Peterson537fba22006-03-26 01:38:40 -08001537 edac_printk(KERN_INFO, EDAC_MC,
1538 "Removed device %d for %s %s: PCI %s\n", mci->mc_idx,
1539 mci->mod_name, mci->ctl_name, pci_name(mci->pdev));
Alan Coxda9bb1d2006-01-18 17:44:13 -08001540 rc = 0;
1541 up(&mem_ctls_mutex);
1542
1543 return rc;
1544}
1545
1546
1547EXPORT_SYMBOL(edac_mc_scrub_block);
1548
1549void edac_mc_scrub_block(unsigned long page, unsigned long offset,
1550 u32 size)
1551{
1552 struct page *pg;
1553 void *virt_addr;
1554 unsigned long flags = 0;
1555
Dave Peterson537fba22006-03-26 01:38:40 -08001556 debugf3("%s()\n", __func__);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001557
1558 /* ECC error page was not in our memory. Ignore it. */
1559 if(!pfn_valid(page))
1560 return;
1561
1562 /* Find the actual page structure then map it and fix */
1563 pg = pfn_to_page(page);
1564
1565 if (PageHighMem(pg))
1566 local_irq_save(flags);
1567
1568 virt_addr = kmap_atomic(pg, KM_BOUNCE_READ);
1569
1570 /* Perform architecture specific atomic scrub operation */
1571 atomic_scrub(virt_addr + offset, size);
1572
1573 /* Unmap and complete */
1574 kunmap_atomic(virt_addr, KM_BOUNCE_READ);
1575
1576 if (PageHighMem(pg))
1577 local_irq_restore(flags);
1578}
1579
1580
1581/* FIXME - should return -1 */
1582EXPORT_SYMBOL(edac_mc_find_csrow_by_page);
1583
1584int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
1585 unsigned long page)
1586{
1587 struct csrow_info *csrows = mci->csrows;
1588 int row, i;
1589
Dave Peterson537fba22006-03-26 01:38:40 -08001590 debugf1("MC%d: %s(): 0x%lx\n", mci->mc_idx, __func__, page);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001591 row = -1;
1592
1593 for (i = 0; i < mci->nr_csrows; i++) {
1594 struct csrow_info *csrow = &csrows[i];
1595
1596 if (csrow->nr_pages == 0)
1597 continue;
1598
Dave Peterson537fba22006-03-26 01:38:40 -08001599 debugf3("MC%d: %s(): first(0x%lx) page(0x%lx) last(0x%lx) "
1600 "mask(0x%lx)\n", mci->mc_idx, __func__,
1601 csrow->first_page, page, csrow->last_page,
1602 csrow->page_mask);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001603
1604 if ((page >= csrow->first_page) &&
1605 (page <= csrow->last_page) &&
1606 ((page & csrow->page_mask) ==
1607 (csrow->first_page & csrow->page_mask))) {
1608 row = i;
1609 break;
1610 }
1611 }
1612
1613 if (row == -1)
Dave Peterson537fba22006-03-26 01:38:40 -08001614 edac_mc_printk(mci, KERN_ERR,
1615 "could not look up page error address %lx\n",
1616 (unsigned long) page);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001617
1618 return row;
1619}
1620
1621
1622EXPORT_SYMBOL(edac_mc_handle_ce);
1623
1624/* FIXME - setable log (warning/emerg) levels */
1625/* FIXME - integrate with evlog: http://evlog.sourceforge.net/ */
1626void edac_mc_handle_ce(struct mem_ctl_info *mci,
1627 unsigned long page_frame_number,
1628 unsigned long offset_in_page,
1629 unsigned long syndrome, int row, int channel,
1630 const char *msg)
1631{
1632 unsigned long remapped_page;
1633
Dave Peterson537fba22006-03-26 01:38:40 -08001634 debugf3("MC%d: %s()\n", mci->mc_idx, __func__);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001635
1636 /* FIXME - maybe make panic on INTERNAL ERROR an option */
1637 if (row >= mci->nr_csrows || row < 0) {
1638 /* something is wrong */
Dave Peterson537fba22006-03-26 01:38:40 -08001639 edac_mc_printk(mci, KERN_ERR,
1640 "INTERNAL ERROR: row out of range "
1641 "(%d >= %d)\n", row, mci->nr_csrows);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001642 edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR");
1643 return;
1644 }
1645 if (channel >= mci->csrows[row].nr_channels || channel < 0) {
1646 /* something is wrong */
Dave Peterson537fba22006-03-26 01:38:40 -08001647 edac_mc_printk(mci, KERN_ERR,
1648 "INTERNAL ERROR: channel out of range "
1649 "(%d >= %d)\n", channel,
1650 mci->csrows[row].nr_channels);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001651 edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR");
1652 return;
1653 }
1654
1655 if (log_ce)
1656 /* FIXME - put in DIMM location */
Dave Peterson537fba22006-03-26 01:38:40 -08001657 edac_mc_printk(mci, KERN_WARNING,
1658 "CE page 0x%lx, offset 0x%lx, grain %d, syndrome "
1659 "0x%lx, row %d, channel %d, label \"%s\": %s\n",
1660 page_frame_number, offset_in_page,
1661 mci->csrows[row].grain, syndrome, row, channel,
1662 mci->csrows[row].channels[channel].label, msg);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001663
1664 mci->ce_count++;
1665 mci->csrows[row].ce_count++;
1666 mci->csrows[row].channels[channel].ce_count++;
1667
1668 if (mci->scrub_mode & SCRUB_SW_SRC) {
1669 /*
1670 * Some MC's can remap memory so that it is still available
1671 * at a different address when PCI devices map into memory.
1672 * MC's that can't do this lose the memory where PCI devices
1673 * are mapped. This mapping is MC dependant and so we call
1674 * back into the MC driver for it to map the MC page to
1675 * a physical (CPU) page which can then be mapped to a virtual
1676 * page - which can then be scrubbed.
1677 */
1678 remapped_page = mci->ctl_page_to_phys ?
1679 mci->ctl_page_to_phys(mci, page_frame_number) :
1680 page_frame_number;
1681
1682 edac_mc_scrub_block(remapped_page, offset_in_page,
1683 mci->csrows[row].grain);
1684 }
1685}
1686
1687
1688EXPORT_SYMBOL(edac_mc_handle_ce_no_info);
1689
1690void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci,
1691 const char *msg)
1692{
1693 if (log_ce)
Dave Peterson537fba22006-03-26 01:38:40 -08001694 edac_mc_printk(mci, KERN_WARNING,
1695 "CE - no information available: %s\n", msg);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001696 mci->ce_noinfo_count++;
1697 mci->ce_count++;
1698}
1699
1700
1701EXPORT_SYMBOL(edac_mc_handle_ue);
1702
1703void edac_mc_handle_ue(struct mem_ctl_info *mci,
1704 unsigned long page_frame_number,
1705 unsigned long offset_in_page, int row,
1706 const char *msg)
1707{
1708 int len = EDAC_MC_LABEL_LEN * 4;
1709 char labels[len + 1];
1710 char *pos = labels;
1711 int chan;
1712 int chars;
1713
Dave Peterson537fba22006-03-26 01:38:40 -08001714 debugf3("MC%d: %s()\n", mci->mc_idx, __func__);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001715
1716 /* FIXME - maybe make panic on INTERNAL ERROR an option */
1717 if (row >= mci->nr_csrows || row < 0) {
1718 /* something is wrong */
Dave Peterson537fba22006-03-26 01:38:40 -08001719 edac_mc_printk(mci, KERN_ERR,
1720 "INTERNAL ERROR: row out of range "
1721 "(%d >= %d)\n", row, mci->nr_csrows);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001722 edac_mc_handle_ue_no_info(mci, "INTERNAL ERROR");
1723 return;
1724 }
1725
1726 chars = snprintf(pos, len + 1, "%s",
1727 mci->csrows[row].channels[0].label);
1728 len -= chars;
1729 pos += chars;
1730 for (chan = 1; (chan < mci->csrows[row].nr_channels) && (len > 0);
1731 chan++) {
1732 chars = snprintf(pos, len + 1, ":%s",
1733 mci->csrows[row].channels[chan].label);
1734 len -= chars;
1735 pos += chars;
1736 }
1737
1738 if (log_ue)
Dave Peterson537fba22006-03-26 01:38:40 -08001739 edac_mc_printk(mci, KERN_EMERG,
1740 "UE page 0x%lx, offset 0x%lx, grain %d, row %d, "
1741 "labels \"%s\": %s\n", page_frame_number,
1742 offset_in_page, mci->csrows[row].grain, row, labels,
1743 msg);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001744
1745 if (panic_on_ue)
1746 panic
1747 ("EDAC MC%d: UE page 0x%lx, offset 0x%lx, grain %d, row %d,"
1748 " labels \"%s\": %s\n", mci->mc_idx,
1749 page_frame_number, offset_in_page,
1750 mci->csrows[row].grain, row, labels, msg);
1751
1752 mci->ue_count++;
1753 mci->csrows[row].ue_count++;
1754}
1755
1756
1757EXPORT_SYMBOL(edac_mc_handle_ue_no_info);
1758
1759void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci,
1760 const char *msg)
1761{
1762 if (panic_on_ue)
1763 panic("EDAC MC%d: Uncorrected Error", mci->mc_idx);
1764
1765 if (log_ue)
Dave Peterson537fba22006-03-26 01:38:40 -08001766 edac_mc_printk(mci, KERN_WARNING,
1767 "UE - no information available: %s\n", msg);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001768 mci->ue_noinfo_count++;
1769 mci->ue_count++;
1770}
1771
1772
1773#ifdef CONFIG_PCI
1774
1775static u16 get_pci_parity_status(struct pci_dev *dev, int secondary)
1776{
1777 int where;
1778 u16 status;
1779
1780 where = secondary ? PCI_SEC_STATUS : PCI_STATUS;
1781 pci_read_config_word(dev, where, &status);
1782
1783 /* If we get back 0xFFFF then we must suspect that the card has been pulled but
1784 the Linux PCI layer has not yet finished cleaning up. We don't want to report
1785 on such devices */
1786
1787 if (status == 0xFFFF) {
1788 u32 sanity;
1789 pci_read_config_dword(dev, 0, &sanity);
1790 if (sanity == 0xFFFFFFFF)
1791 return 0;
1792 }
1793 status &= PCI_STATUS_DETECTED_PARITY | PCI_STATUS_SIG_SYSTEM_ERROR |
1794 PCI_STATUS_PARITY;
1795
1796 if (status)
1797 /* reset only the bits we are interested in */
1798 pci_write_config_word(dev, where, status);
1799
1800 return status;
1801}
1802
1803typedef void (*pci_parity_check_fn_t) (struct pci_dev *dev);
1804
1805/* Clear any PCI parity errors logged by this device. */
1806static void edac_pci_dev_parity_clear( struct pci_dev *dev )
1807{
1808 u8 header_type;
1809
1810 get_pci_parity_status(dev, 0);
1811
1812 /* read the device TYPE, looking for bridges */
1813 pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type);
1814
1815 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE)
1816 get_pci_parity_status(dev, 1);
1817}
1818
1819/*
1820 * PCI Parity polling
1821 *
1822 */
1823static void edac_pci_dev_parity_test(struct pci_dev *dev)
1824{
1825 u16 status;
1826 u8 header_type;
1827
1828 /* read the STATUS register on this device
1829 */
1830 status = get_pci_parity_status(dev, 0);
1831
1832 debugf2("PCI STATUS= 0x%04x %s\n", status, dev->dev.bus_id );
1833
1834 /* check the status reg for errors */
1835 if (status) {
1836 if (status & (PCI_STATUS_SIG_SYSTEM_ERROR))
Dave Peterson537fba22006-03-26 01:38:40 -08001837 edac_printk(KERN_CRIT, EDAC_PCI,
Alan Coxda9bb1d2006-01-18 17:44:13 -08001838 "Signaled System Error on %s\n",
Dave Peterson537fba22006-03-26 01:38:40 -08001839 pci_name(dev));
Alan Coxda9bb1d2006-01-18 17:44:13 -08001840
1841 if (status & (PCI_STATUS_PARITY)) {
Dave Peterson537fba22006-03-26 01:38:40 -08001842 edac_printk(KERN_CRIT, EDAC_PCI,
Alan Coxda9bb1d2006-01-18 17:44:13 -08001843 "Master Data Parity Error on %s\n",
Dave Peterson537fba22006-03-26 01:38:40 -08001844 pci_name(dev));
Alan Coxda9bb1d2006-01-18 17:44:13 -08001845
1846 atomic_inc(&pci_parity_count);
1847 }
1848
1849 if (status & (PCI_STATUS_DETECTED_PARITY)) {
Dave Peterson537fba22006-03-26 01:38:40 -08001850 edac_printk(KERN_CRIT, EDAC_PCI,
Alan Coxda9bb1d2006-01-18 17:44:13 -08001851 "Detected Parity Error on %s\n",
Dave Peterson537fba22006-03-26 01:38:40 -08001852 pci_name(dev));
Alan Coxda9bb1d2006-01-18 17:44:13 -08001853
1854 atomic_inc(&pci_parity_count);
1855 }
1856 }
1857
1858 /* read the device TYPE, looking for bridges */
1859 pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type);
1860
1861 debugf2("PCI HEADER TYPE= 0x%02x %s\n", header_type, dev->dev.bus_id );
1862
1863 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
1864 /* On bridges, need to examine secondary status register */
1865 status = get_pci_parity_status(dev, 1);
1866
1867 debugf2("PCI SEC_STATUS= 0x%04x %s\n",
1868 status, dev->dev.bus_id );
1869
1870 /* check the secondary status reg for errors */
1871 if (status) {
1872 if (status & (PCI_STATUS_SIG_SYSTEM_ERROR))
Dave Peterson537fba22006-03-26 01:38:40 -08001873 edac_printk(KERN_CRIT, EDAC_PCI, "Bridge "
Alan Coxda9bb1d2006-01-18 17:44:13 -08001874 "Signaled System Error on %s\n",
Dave Peterson537fba22006-03-26 01:38:40 -08001875 pci_name(dev));
Alan Coxda9bb1d2006-01-18 17:44:13 -08001876
1877 if (status & (PCI_STATUS_PARITY)) {
Dave Peterson537fba22006-03-26 01:38:40 -08001878 edac_printk(KERN_CRIT, EDAC_PCI, "Bridge "
1879 "Master Data Parity Error on "
1880 "%s\n", pci_name(dev));
Alan Coxda9bb1d2006-01-18 17:44:13 -08001881
1882 atomic_inc(&pci_parity_count);
1883 }
1884
1885 if (status & (PCI_STATUS_DETECTED_PARITY)) {
Dave Peterson537fba22006-03-26 01:38:40 -08001886 edac_printk(KERN_CRIT, EDAC_PCI, "Bridge "
Alan Coxda9bb1d2006-01-18 17:44:13 -08001887 "Detected Parity Error on %s\n",
Dave Peterson537fba22006-03-26 01:38:40 -08001888 pci_name(dev));
Alan Coxda9bb1d2006-01-18 17:44:13 -08001889
1890 atomic_inc(&pci_parity_count);
1891 }
1892 }
1893 }
1894}
1895
1896/*
1897 * check_dev_on_list: Scan for a PCI device on a white/black list
1898 * @list: an EDAC &edac_pci_device_list white/black list pointer
1899 * @free_index: index of next free entry on the list
1900 * @pci_dev: PCI Device pointer
1901 *
1902 * see if list contains the device.
1903 *
1904 * Returns: 0 not found
1905 * 1 found on list
1906 */
1907static int check_dev_on_list(struct edac_pci_device_list *list, int free_index,
1908 struct pci_dev *dev)
1909{
1910 int i;
1911 int rc = 0; /* Assume not found */
1912 unsigned short vendor=dev->vendor;
1913 unsigned short device=dev->device;
1914
1915 /* Scan the list, looking for a vendor/device match
1916 */
1917 for (i = 0; i < free_index; i++, list++ ) {
1918 if ( (list->vendor == vendor ) &&
1919 (list->device == device )) {
1920 rc = 1;
1921 break;
1922 }
1923 }
1924
1925 return rc;
1926}
1927
1928/*
1929 * pci_dev parity list iterator
1930 * Scan the PCI device list for one iteration, looking for SERRORs
1931 * Master Parity ERRORS or Parity ERRORs on primary or secondary devices
1932 */
1933static inline void edac_pci_dev_parity_iterator(pci_parity_check_fn_t fn)
1934{
1935 struct pci_dev *dev=NULL;
1936
1937 /* request for kernel access to the next PCI device, if any,
1938 * and while we are looking at it have its reference count
1939 * bumped until we are done with it
1940 */
1941 while((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
1942
1943 /* if whitelist exists then it has priority, so only scan those
1944 * devices on the whitelist
1945 */
1946 if (pci_whitelist_count > 0 ) {
1947 if (check_dev_on_list(pci_whitelist,
1948 pci_whitelist_count, dev))
1949 fn(dev);
1950 } else {
1951 /*
1952 * if no whitelist, then check if this devices is
1953 * blacklisted
1954 */
1955 if (!check_dev_on_list(pci_blacklist,
1956 pci_blacklist_count, dev))
1957 fn(dev);
1958 }
1959 }
1960}
1961
1962static void do_pci_parity_check(void)
1963{
1964 unsigned long flags;
1965 int before_count;
1966
Dave Peterson537fba22006-03-26 01:38:40 -08001967 debugf3("%s()\n", __func__);
Alan Coxda9bb1d2006-01-18 17:44:13 -08001968
1969 if (!check_pci_parity)
1970 return;
1971
1972 before_count = atomic_read(&pci_parity_count);
1973
1974 /* scan all PCI devices looking for a Parity Error on devices and
1975 * bridges
1976 */
1977 local_irq_save(flags);
1978 edac_pci_dev_parity_iterator(edac_pci_dev_parity_test);
1979 local_irq_restore(flags);
1980
1981 /* Only if operator has selected panic on PCI Error */
1982 if (panic_on_pci_parity) {
1983 /* If the count is different 'after' from 'before' */
1984 if (before_count != atomic_read(&pci_parity_count))
1985 panic("EDAC: PCI Parity Error");
1986 }
1987}
1988
1989
1990static inline void clear_pci_parity_errors(void)
1991{
1992 /* Clear any PCI bus parity errors that devices initially have logged
1993 * in their registers.
1994 */
1995 edac_pci_dev_parity_iterator(edac_pci_dev_parity_clear);
1996}
1997
1998
1999#else /* CONFIG_PCI */
2000
2001
2002static inline void do_pci_parity_check(void)
2003{
2004 /* no-op */
2005}
2006
2007
2008static inline void clear_pci_parity_errors(void)
2009{
2010 /* no-op */
2011}
2012
2013
2014#endif /* CONFIG_PCI */
2015
2016/*
2017 * Iterate over all MC instances and check for ECC, et al, errors
2018 */
2019static inline void check_mc_devices (void)
2020{
2021 unsigned long flags;
2022 struct list_head *item;
2023 struct mem_ctl_info *mci;
2024
Dave Peterson537fba22006-03-26 01:38:40 -08002025 debugf3("%s()\n", __func__);
Alan Coxda9bb1d2006-01-18 17:44:13 -08002026
2027 /* during poll, have interrupts off */
2028 local_irq_save(flags);
2029
2030 list_for_each(item, &mc_devices) {
2031 mci = list_entry(item, struct mem_ctl_info, link);
2032
2033 if (mci->edac_check != NULL)
2034 mci->edac_check(mci);
2035 }
2036
2037 local_irq_restore(flags);
2038}
2039
2040
2041/*
2042 * Check MC status every poll_msec.
2043 * Check PCI status every poll_msec as well.
2044 *
2045 * This where the work gets done for edac.
2046 *
2047 * SMP safe, doesn't use NMI, and auto-rate-limits.
2048 */
2049static void do_edac_check(void)
2050{
Dave Peterson537fba22006-03-26 01:38:40 -08002051 debugf3("%s()\n", __func__);
Alan Coxda9bb1d2006-01-18 17:44:13 -08002052 check_mc_devices();
Alan Coxda9bb1d2006-01-18 17:44:13 -08002053 do_pci_parity_check();
2054}
2055
Alan Coxda9bb1d2006-01-18 17:44:13 -08002056static int edac_kernel_thread(void *arg)
2057{
Dave Petersonf2fe42a2006-03-26 01:38:38 -08002058 while (!kthread_should_stop()) {
2059 do_edac_check();
Alan Coxda9bb1d2006-01-18 17:44:13 -08002060
2061 /* goto sleep for the interval */
Dave Petersonf2fe42a2006-03-26 01:38:38 -08002062 schedule_timeout_interruptible((HZ * poll_msec) / 1000);
Alan Coxda9bb1d2006-01-18 17:44:13 -08002063 try_to_freeze();
2064 }
2065
Alan Coxda9bb1d2006-01-18 17:44:13 -08002066 return 0;
2067}
2068
2069/*
2070 * edac_mc_init
2071 * module initialization entry point
2072 */
2073static int __init edac_mc_init(void)
2074{
Dave Peterson537fba22006-03-26 01:38:40 -08002075 edac_printk(KERN_INFO, EDAC_MC, EDAC_MC_VERSION "\n");
Alan Coxda9bb1d2006-01-18 17:44:13 -08002076
2077 /*
2078 * Harvest and clear any boot/initialization PCI parity errors
2079 *
2080 * FIXME: This only clears errors logged by devices present at time of
2081 * module initialization. We should also do an initial clear
2082 * of each newly hotplugged device.
2083 */
2084 clear_pci_parity_errors();
2085
Alan Coxda9bb1d2006-01-18 17:44:13 -08002086 /* Create the MC sysfs entires */
2087 if (edac_sysfs_memctrl_setup()) {
Dave Peterson537fba22006-03-26 01:38:40 -08002088 edac_printk(KERN_ERR, EDAC_MC,
2089 "Error initializing sysfs code\n");
Alan Coxda9bb1d2006-01-18 17:44:13 -08002090 return -ENODEV;
2091 }
2092
2093 /* Create the PCI parity sysfs entries */
2094 if (edac_sysfs_pci_setup()) {
2095 edac_sysfs_memctrl_teardown();
Dave Peterson537fba22006-03-26 01:38:40 -08002096 edac_printk(KERN_ERR, EDAC_MC,
2097 "EDAC PCI: Error initializing sysfs code\n");
Alan Coxda9bb1d2006-01-18 17:44:13 -08002098 return -ENODEV;
2099 }
2100
Alan Coxda9bb1d2006-01-18 17:44:13 -08002101 /* create our kernel thread */
Dave Petersonf2fe42a2006-03-26 01:38:38 -08002102 edac_thread = kthread_run(edac_kernel_thread, NULL, "kedac");
2103 if (IS_ERR(edac_thread)) {
Alan Coxda9bb1d2006-01-18 17:44:13 -08002104 /* remove the sysfs entries */
2105 edac_sysfs_memctrl_teardown();
2106 edac_sysfs_pci_teardown();
Dave Petersonf2fe42a2006-03-26 01:38:38 -08002107 return PTR_ERR(edac_thread);
Alan Coxda9bb1d2006-01-18 17:44:13 -08002108 }
2109
Alan Coxda9bb1d2006-01-18 17:44:13 -08002110 return 0;
2111}
2112
2113
2114/*
2115 * edac_mc_exit()
2116 * module exit/termination functioni
2117 */
2118static void __exit edac_mc_exit(void)
2119{
Dave Peterson537fba22006-03-26 01:38:40 -08002120 debugf0("%s()\n", __func__);
Alan Coxda9bb1d2006-01-18 17:44:13 -08002121
Dave Petersonf2fe42a2006-03-26 01:38:38 -08002122 kthread_stop(edac_thread);
Alan Coxda9bb1d2006-01-18 17:44:13 -08002123
2124 /* tear down the sysfs device */
2125 edac_sysfs_memctrl_teardown();
2126 edac_sysfs_pci_teardown();
2127}
2128
2129
2130
2131
2132module_init(edac_mc_init);
2133module_exit(edac_mc_exit);
2134
2135MODULE_LICENSE("GPL");
2136MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh et al\n"
2137 "Based on.work by Dan Hollis et al");
2138MODULE_DESCRIPTION("Core library routines for MC reporting");
2139
2140module_param(panic_on_ue, int, 0644);
2141MODULE_PARM_DESC(panic_on_ue, "Panic on uncorrected error: 0=off 1=on");
2142module_param(check_pci_parity, int, 0644);
2143MODULE_PARM_DESC(check_pci_parity, "Check for PCI bus parity errors: 0=off 1=on");
2144module_param(panic_on_pci_parity, int, 0644);
2145MODULE_PARM_DESC(panic_on_pci_parity, "Panic on PCI Bus Parity error: 0=off 1=on");
2146module_param(log_ue, int, 0644);
2147MODULE_PARM_DESC(log_ue, "Log uncorrectable error to console: 0=off 1=on");
2148module_param(log_ce, int, 0644);
2149MODULE_PARM_DESC(log_ce, "Log correctable error to console: 0=off 1=on");
2150module_param(poll_msec, int, 0644);
2151MODULE_PARM_DESC(poll_msec, "Polling period in milliseconds");
2152#ifdef CONFIG_EDAC_DEBUG
2153module_param(edac_debug_level, int, 0644);
2154MODULE_PARM_DESC(edac_debug_level, "Debug level");
2155#endif