aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/edac_core.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac/edac_core.h')
-rw-r--r--drivers/edac/edac_core.h252
1 files changed, 246 insertions, 6 deletions
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index 397f144791e..a3e4b97fe4f 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -32,9 +32,14 @@
32#include <linux/completion.h> 32#include <linux/completion.h>
33#include <linux/kobject.h> 33#include <linux/kobject.h>
34#include <linux/platform_device.h> 34#include <linux/platform_device.h>
35#include <linux/sysdev.h>
36#include <linux/workqueue.h>
37#include <linux/version.h>
35 38
36#define EDAC_MC_LABEL_LEN 31 39#define EDAC_MC_LABEL_LEN 31
37#define MC_PROC_NAME_MAX_LEN 7 40#define EDAC_DEVICE_NAME_LEN 31
41#define EDAC_ATTRIB_VALUE_LEN 15
42#define MC_PROC_NAME_MAX_LEN 7
38 43
39#if PAGE_SHIFT < 20 44#if PAGE_SHIFT < 20
40#define PAGES_TO_MiB( pages ) ( ( pages ) >> ( 20 - PAGE_SHIFT ) ) 45#define PAGES_TO_MiB( pages ) ( ( pages ) >> ( 20 - PAGE_SHIFT ) )
@@ -51,6 +56,10 @@
51#define edac_mc_chipset_printk(mci, level, prefix, fmt, arg...) \ 56#define edac_mc_chipset_printk(mci, level, prefix, fmt, arg...) \
52 printk(level "EDAC " prefix " MC%d: " fmt, mci->mc_idx, ##arg) 57 printk(level "EDAC " prefix " MC%d: " fmt, mci->mc_idx, ##arg)
53 58
59/* edac_device printk */
60#define edac_device_printk(ctl, level, fmt, arg...) \
61 printk(level "EDAC DEVICE%d: " fmt, ctl->dev_idx, ##arg)
62
54/* prefixes for edac_printk() and edac_mc_printk() */ 63/* prefixes for edac_printk() and edac_mc_printk() */
55#define EDAC_MC "MC" 64#define EDAC_MC "MC"
56#define EDAC_PCI "PCI" 65#define EDAC_PCI "PCI"
@@ -62,7 +71,7 @@ extern int edac_debug_level;
62#define edac_debug_printk(level, fmt, arg...) \ 71#define edac_debug_printk(level, fmt, arg...) \
63 do { \ 72 do { \
64 if (level <= edac_debug_level) \ 73 if (level <= edac_debug_level) \
65 edac_printk(KERN_DEBUG, EDAC_DEBUG, fmt, ##arg); \ 74 edac_printk(KERN_EMERG, EDAC_DEBUG, fmt, ##arg); \
66 } while(0) 75 } while(0)
67 76
68#define debugf0( ... ) edac_debug_printk(0, __VA_ARGS__ ) 77#define debugf0( ... ) edac_debug_printk(0, __VA_ARGS__ )
@@ -195,6 +204,8 @@ enum scrub_type {
195 204
196/* FIXME - should have notify capabilities: NMI, LOG, PROC, etc */ 205/* FIXME - should have notify capabilities: NMI, LOG, PROC, etc */
197 206
207extern char * edac_align_ptr(void *ptr, unsigned size);
208
198/* 209/*
199 * There are several things to be aware of that aren't at all obvious: 210 * There are several things to be aware of that aren't at all obvious:
200 * 211 *
@@ -376,6 +387,231 @@ struct mem_ctl_info {
376 struct completion kobj_complete; 387 struct completion kobj_complete;
377}; 388};
378 389
390/*
391 * The following are the structures to provide for a generice
392 * or abstract 'edac_device'. This set of structures and the
393 * code that implements the APIs for the same, provide for
394 * registering EDAC type devices which are NOT standard memory.
395 *
396 * CPU caches (L1 and L2)
397 * DMA engines
398 * Core CPU swithces
399 * Fabric switch units
400 * PCIe interface controllers
401 * other EDAC/ECC type devices that can be monitored for
402 * errors, etc.
403 *
404 * It allows for a 2 level set of hiearchry. For example:
405 *
406 * cache could be composed of L1, L2 and L3 levels of cache.
407 * Each CPU core would have its own L1 cache, while sharing
408 * L2 and maybe L3 caches.
409 *
410 * View them arranged, via the sysfs presentation:
411 * /sys/devices/system/edac/..
412 *
413 * mc/ <existing memory device directory>
414 * cpu/cpu0/.. <L1 and L2 block directory>
415 * /L1-cache/ce_count
416 * /ue_count
417 * /L2-cache/ce_count
418 * /ue_count
419 * cpu/cpu1/.. <L1 and L2 block directory>
420 * /L1-cache/ce_count
421 * /ue_count
422 * /L2-cache/ce_count
423 * /ue_count
424 * ...
425 *
426 * the L1 and L2 directories would be "edac_device_block's"
427 */
428
429struct edac_device_counter {
430 u32 ue_count;
431 u32 ce_count;
432};
433
434#define INC_COUNTER(cnt) (cnt++)
435
436/*
437 * An array of these is passed to the alloc() function
438 * to specify attributes of the edac_block
439 */
440struct edac_attrib_spec {
441 char name[EDAC_DEVICE_NAME_LEN + 1];
442
443 int type;
444#define EDAC_ATTR_INT 0x01
445#define EDAC_ATTR_CHAR 0x02
446};
447
448
449/* Attribute control structure
450 * In this structure is a pointer to the driver's edac_attrib_spec
451 * The life of this pointer is inclusive in the life of the driver's
452 * life cycle.
453 */
454struct edac_attrib {
455 struct edac_device_block *block; /* Up Pointer */
456
457 struct edac_attrib_spec *spec; /* ptr to module spec entry */
458
459 union { /* actual value */
460 int edac_attrib_int_value;
461 char edac_attrib_char_value[EDAC_ATTRIB_VALUE_LEN + 1];
462 } edac_attrib_value;
463};
464
465/* device block control structure */
466struct edac_device_block {
467 struct edac_device_instance *instance; /* Up Pointer */
468 char name[EDAC_DEVICE_NAME_LEN + 1];
469
470 struct edac_device_counter counters; /* basic UE and CE counters */
471
472 int nr_attribs; /* how many attributes */
473 struct edac_attrib *attribs; /* this block's attributes */
474
475 /* edac sysfs device control */
476 struct kobject kobj;
477 struct completion kobj_complete;
478};
479
480/* device instance control structure */
481struct edac_device_instance {
482 struct edac_device_ctl_info *ctl; /* Up pointer */
483 char name[EDAC_DEVICE_NAME_LEN + 4];
484
485 struct edac_device_counter counters; /* instance counters */
486
487 u32 nr_blocks; /* how many blocks */
488 struct edac_device_block *blocks; /* block array */
489
490 /* edac sysfs device control */
491 struct kobject kobj;
492 struct completion kobj_complete;
493};
494
495
496/*
497 * Abstract edac_device control info structure
498 *
499 */
500struct edac_device_ctl_info {
501 /* for global list of edac_device_ctl_info structs */
502 struct list_head link;
503
504 int dev_idx;
505
506 /* Per instance controls for this edac_device */
507 int log_ue; /* boolean for logging UEs */
508 int log_ce; /* boolean for logging CEs */
509 int panic_on_ue; /* boolean for panic'ing on an UE */
510 unsigned poll_msec; /* number of milliseconds to poll interval */
511 unsigned long delay; /* number of jiffies for poll_msec */
512
513 struct sysdev_class *edac_class; /* pointer to class */
514
515 /* the internal state of this controller instance */
516 int op_state;
517#define OP_ALLOC 0x100
518#define OP_RUNNING_POLL 0x201
519#define OP_RUNNING_INTERRUPT 0x202
520#define OP_RUNNING_POLL_INTR 0x203
521#define OP_OFFLINE 0x300
522
523 /* work struct for this instance */
524#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
525 struct delayed_work work;
526#else
527 struct work_struct work;
528#endif
529
530 /* pointer to edac polling checking routine:
531 * If NOT NULL: points to polling check routine
532 * If NULL: Then assumes INTERRUPT operation, where
533 * MC driver will receive events
534 */
535 void (*edac_check) (struct edac_device_ctl_info * edac_dev);
536
537 struct device *dev; /* pointer to device structure */
538
539 const char *mod_name; /* module name */
540 const char *ctl_name; /* edac controller name */
541
542 void *pvt_info; /* pointer to 'private driver' info */
543
544 unsigned long start_time;/* edac_device load start time (jiffies)*/
545
546 /* these are for safe removal of mc devices from global list while
547 * NMI handlers may be traversing list
548 */
549 struct rcu_head rcu;
550 struct completion complete;
551
552 /* sysfs top name under 'edac' directory
553 * and instance name:
554 * cpu/cpu0/...
555 * cpu/cpu1/...
556 * cpu/cpu2/...
557 * ...
558 */
559 char name[EDAC_DEVICE_NAME_LEN + 1];
560
561 /* Number of instances supported on this control structure
562 * and the array of those instances
563 */
564 u32 nr_instances;
565 struct edac_device_instance *instances;
566
567 /* Event counters for the this whole EDAC Device */
568 struct edac_device_counter counters;
569
570 /* edac sysfs device control for the 'name'
571 * device this structure controls
572 */
573 struct kobject kobj;
574 struct completion kobj_complete;
575};
576
577/* To get from the instance's wq to the beginning of the ctl structure */
578#define to_edac_device_ctl_work(w) \
579 container_of(w,struct edac_device_ctl_info,work)
580
581/* Function to calc the number of delay jiffies from poll_msec */
582static inline void edac_device_calc_delay(
583 struct edac_device_ctl_info *edac_dev)
584{
585 /* convert from msec to jiffies */
586 edac_dev->delay = edac_dev->poll_msec * HZ / 1000;
587}
588
589/*
590 * The alloc() and free() functions for the 'edac_device' control info
591 * structure. A MC driver will allocate one of these for each edac_device
592 * it is going to control/register with the EDAC CORE.
593 */
594extern struct edac_device_ctl_info *edac_device_alloc_ctl_info(
595 unsigned sizeof_private,
596 char *edac_device_name,
597 unsigned nr_instances,
598 char *edac_block_name,
599 unsigned nr_blocks,
600 unsigned offset_value,
601 struct edac_attrib_spec *attrib_spec,
602 unsigned nr_attribs
603);
604
605/* The offset value can be:
606 * -1 indicating no offset value
607 * 0 for zero-based block numbers
608 * 1 for 1-based block number
609 * other for other-based block number
610 */
611#define BLOCK_OFFSET_VALUE_OFF ((unsigned) -1)
612
613extern void edac_device_free_ctl_info( struct edac_device_ctl_info *ctl_info);
614
379#ifdef CONFIG_PCI 615#ifdef CONFIG_PCI
380 616
381/* write all or some bits in a byte-register*/ 617/* write all or some bits in a byte-register*/
@@ -466,13 +702,17 @@ extern void edac_mc_handle_fbd_ce(struct mem_ctl_info *mci,
466 char *msg); 702 char *msg);
467 703
468/* 704/*
469 * This kmalloc's and initializes all the structures. 705 * edac_device APIs
470 * Can't be used if all structures don't have the same lifetime.
471 */ 706 */
472extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, 707extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
473 unsigned nr_chans); 708 unsigned nr_chans);
474
475/* Free an mc previously allocated by edac_mc_alloc() */
476extern void edac_mc_free(struct mem_ctl_info *mci); 709extern void edac_mc_free(struct mem_ctl_info *mci);
710extern int edac_device_add_device(struct edac_device_ctl_info *edac_dev, int edac_idx);
711extern struct edac_device_ctl_info * edac_device_del_device(struct device *dev);
712extern void edac_device_handle_ue(struct edac_device_ctl_info *edac_dev,
713 int inst_nr, int block_nr, const char *msg);
714extern void edac_device_handle_ce(struct edac_device_ctl_info *edac_dev,
715 int inst_nr, int block_nr, const char *msg);
716
477 717
478#endif /* _EDAC_CORE_H_ */ 718#endif /* _EDAC_CORE_H_ */