#define edac_debug_printk(level, fmt, arg...) \
do { \
if (level <= edac_debug_level) \
- edac_printk(KERN_EMERG, EDAC_DEBUG, fmt, ##arg); \
+ edac_printk(KERN_DEBUG, EDAC_DEBUG, fmt, ##arg); \
} while(0)
#define debugf0( ... ) edac_debug_printk(0, __VA_ARGS__ )
#endif /* !CONFIG_EDAC_DEBUG */
-#define BIT(x) (1 << (x))
-
#define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \
PCI_DEVICE_ID_ ## vend ## _ ## dev
MEM_DDR2, /* DDR2 RAM */
MEM_FB_DDR2, /* fully buffered DDR2 */
MEM_RDDR2, /* Registered DDR2 RAM */
+ MEM_XDR, /* Rambus XDR */
};
#define MEM_FLAG_EMPTY BIT(MEM_EMPTY)
#define MEM_FLAG_DDR2 BIT(MEM_DDR2)
#define MEM_FLAG_FB_DDR2 BIT(MEM_FB_DDR2)
#define MEM_FLAG_RDDR2 BIT(MEM_RDDR2)
+#define MEM_FLAG_XDR BIT(MEM_XDR)
/* chipset Error Detection and Correction capabilities and mode */
enum edac_type {
struct mem_ctl_info *mci; /* the parent */
struct kobject kobj; /* sysfs kobject for this csrow */
- struct completion kobj_complete;
- /* FIXME the number of CHANNELs might need to become dynamic */
+ /* channel information for this csrow */
u32 nr_channels;
struct channel_info *channels;
};
*/
struct mem_ctl_info {
struct list_head link; /* for global list of mem_ctl_info structs */
+
+ struct module *owner; /* Module owner of this control struct */
+
unsigned long mtype_cap; /* memory types supported by mc */
unsigned long edac_ctl_cap; /* Mem controller EDAC capabilities */
unsigned long edac_cap; /* configuration capabilities - this is
/* edac sysfs device control */
struct kobject edac_mci_kobj;
- struct completion kobj_complete;
/* Additional top controller level attributes, but specified
* by the low level driver.
u32 ce_count;
};
-/*
- * An array of these is passed to the alloc() function
- * to specify attributes of the edac_block
- */
-struct edac_attrib_spec {
- char name[EDAC_DEVICE_NAME_LEN + 1];
+/* forward reference */
+struct edac_device_ctl_info;
+struct edac_device_block;
- int type;
-#define EDAC_ATTR_INT 0x01
-#define EDAC_ATTR_CHAR 0x02
+/* edac_dev_sysfs_attribute structure
+ * used for driver sysfs attributes in mem_ctl_info
+ * for extra controls and attributes:
+ * like high level error Injection controls
+ */
+struct edac_dev_sysfs_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct edac_device_ctl_info *, char *);
+ ssize_t (*store)(struct edac_device_ctl_info *, const char *, size_t);
};
-/* Attribute control structure
- * In this structure is a pointer to the driver's edac_attrib_spec
- * The life of this pointer is inclusive in the life of the driver's
- * life cycle.
+/* edac_dev_sysfs_block_attribute structure
+ *
+ * used in leaf 'block' nodes for adding controls/attributes
+ *
+ * each block in each instance of the containing control structure
+ * can have an array of the following. The show and store functions
+ * will be filled in with the show/store function in the
+ * low level driver.
+ *
+ * The 'value' field will be the actual value field used for
+ * counting
*/
-struct edac_attrib {
- struct edac_device_block *block; /* Up Pointer */
-
- struct edac_attrib_spec *spec; /* ptr to module spec entry */
+struct edac_dev_sysfs_block_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct kobject *, struct attribute *, char *);
+ ssize_t (*store)(struct kobject *, struct attribute *,
+ const char *, size_t);
+ struct edac_device_block *block;
- union { /* actual value */
- int edac_attrib_int_value;
- char edac_attrib_char_value[EDAC_ATTRIB_VALUE_LEN + 1];
- } edac_attrib_value;
+ unsigned int value;
};
/* device block control structure */
struct edac_device_counter counters; /* basic UE and CE counters */
int nr_attribs; /* how many attributes */
- struct edac_attrib *attribs; /* this block's attributes */
+
+ /* this block's attributes, could be NULL */
+ struct edac_dev_sysfs_block_attribute *block_attributes;
/* edac sysfs device control */
struct kobject kobj;
- struct completion kobj_complete;
};
/* device instance control structure */
/* edac sysfs device control */
struct kobject kobj;
- struct completion kobj_complete;
};
-/* edac_dev_sysfs_attribute structure
- * used for driver sysfs attributes and in mem_ctl_info
- * sysfs top level entries
- */
-struct edac_dev_sysfs_attribute {
- struct attribute attr;
- ssize_t (*show)(struct edac_device_ctl_info *,char *);
- ssize_t (*store)(struct edac_device_ctl_info *, const char *,size_t);
-};
/*
* Abstract edac_device control info structure
/* for global list of edac_device_ctl_info structs */
struct list_head link;
+ struct module *owner; /* Module owner of this control struct */
+
int dev_idx;
/* Per instance controls for this edac_device */
* NMI handlers may be traversing list
*/
struct rcu_head rcu;
- struct completion complete;
+ struct completion removal_complete;
/* sysfs top name under 'edac' directory
* and instance name:
* device this structure controls
*/
struct kobject kobj;
- struct completion kobj_complete;
};
/* To get from the instance's wq to the beginning of the ctl structure */
*/
extern struct edac_device_ctl_info *edac_device_alloc_ctl_info(
unsigned sizeof_private,
- char *edac_device_name,
- unsigned nr_instances,
- char *edac_block_name,
- unsigned nr_blocks,
+ char *edac_device_name, unsigned nr_instances,
+ char *edac_block_name, unsigned nr_blocks,
unsigned offset_value,
- struct edac_attrib_spec *attrib_spec,
- unsigned nr_attribs);
+ struct edac_dev_sysfs_block_attribute *block_attributes,
+ unsigned nr_attribs,
+ int device_index);
/* The offset value can be:
* -1 indicating no offset value
#endif /* CONFIG_PCI */
+extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
+ unsigned nr_chans, int edac_index);
+extern int edac_mc_add_mc(struct mem_ctl_info *mci);
+extern void edac_mc_free(struct mem_ctl_info *mci);
extern struct mem_ctl_info *edac_mc_find(int idx);
-extern int edac_mc_add_mc(struct mem_ctl_info *mci, int mc_idx);
extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev);
extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
unsigned long page);
/*
* edac_device APIs
*/
-extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
- unsigned nr_chans);
-extern void edac_mc_free(struct mem_ctl_info *mci);
-extern int edac_device_add_device(struct edac_device_ctl_info *edac_dev,
- int edac_idx);
+extern int edac_device_add_device(struct edac_device_ctl_info *edac_dev);
extern struct edac_device_ctl_info *edac_device_del_device(struct device *dev);
extern void edac_device_handle_ue(struct edac_device_ctl_info *edac_dev,
- int inst_nr, int block_nr, const char *msg);
+ int inst_nr, int block_nr, const char *msg);
extern void edac_device_handle_ce(struct edac_device_ctl_info *edac_dev,
- int inst_nr, int block_nr, const char *msg);
+ int inst_nr, int block_nr, const char *msg);
/*
* edac_pci APIs
*/
-extern struct edac_pci_ctl_info *edac_pci_alloc_ctl_info(unsigned int sz_pvt, const char
- *edac_pci_name);
+extern struct edac_pci_ctl_info *edac_pci_alloc_ctl_info(unsigned int sz_pvt,
+ const char *edac_pci_name);
extern void edac_pci_free_ctl_info(struct edac_pci_ctl_info *pci);
-extern void
-edac_pci_reset_delay_period(struct edac_pci_ctl_info *pci, unsigned long value);
+extern void edac_pci_reset_delay_period(struct edac_pci_ctl_info *pci,
+ unsigned long value);
extern int edac_pci_add_device(struct edac_pci_ctl_info *pci, int edac_idx);
extern struct edac_pci_ctl_info *edac_pci_del_device(struct device *dev);
-extern struct edac_pci_ctl_info *edac_pci_create_generic_ctl(struct device *dev, const char
- *mod_name);
+extern struct edac_pci_ctl_info *edac_pci_create_generic_ctl(
+ struct device *dev,
+ const char *mod_name);
extern void edac_pci_release_generic_ctl(struct edac_pci_ctl_info *pci);
extern int edac_pci_create_sysfs(struct edac_pci_ctl_info *pci);