X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fedac%2Fedac_core.h;h=001b2e797fb383a3c4f43f805a160d2bffc3b9d6;hb=f013574014816c7a557b3c52233f3620463f0b9b;hp=fa3ff8c25b3618ee88e3ad677665baa88972ac37;hpb=52490c8d07680a7ecc3c1a70a16841455d37e96a;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index fa3ff8c..001b2e7 100644 --- a/drivers/edac/edac_core.h +++ b/drivers/edac/edac_core.h @@ -34,7 +34,6 @@ #include #include #include -#include #define EDAC_MC_LABEL_LEN 31 #define EDAC_DEVICE_NAME_LEN 31 @@ -50,6 +49,10 @@ #define edac_printk(level, prefix, fmt, arg...) \ printk(level "EDAC " prefix ": " fmt, ##arg) +#define edac_printk_verbose(level, prefix, fmt, arg...) \ + printk(level "EDAC " prefix ": " "in %s, line at %d: " fmt, \ + __FILE__, __LINE__, ##arg) + #define edac_mc_printk(mci, level, fmt, arg...) \ printk(level "EDAC MC%d: " fmt, mci->mc_idx, ##arg) @@ -71,12 +74,23 @@ #ifdef CONFIG_EDAC_DEBUG extern int edac_debug_level; - +extern const char *edac_mem_types[]; + +#ifndef CONFIG_EDAC_DEBUG_VERBOSE +#define edac_debug_printk(level, fmt, arg...) \ + do { \ + if (level <= edac_debug_level) \ + edac_printk(KERN_DEBUG, EDAC_DEBUG, \ + "%s: " fmt, __func__, ##arg); \ + } while (0) +#else /* CONFIG_EDAC_DEBUG_VERBOSE */ #define edac_debug_printk(level, fmt, arg...) \ do { \ if (level <= edac_debug_level) \ - edac_printk(KERN_EMERG, EDAC_DEBUG, fmt, ##arg); \ - } while(0) + edac_printk_verbose(KERN_DEBUG, EDAC_DEBUG, fmt, \ + ##arg); \ + } while (0) +#endif #define debugf0( ... ) edac_debug_printk(0, __VA_ARGS__ ) #define debugf1( ... ) edac_debug_printk(1, __VA_ARGS__ ) @@ -94,12 +108,10 @@ extern int edac_debug_level; #endif /* !CONFIG_EDAC_DEBUG */ -#define BIT(x) (1 << (x)) - #define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \ PCI_DEVICE_ID_ ## vend ## _ ## dev -#define dev_name(dev) (dev)->dev_name +#define edac_dev_name(dev) (dev)->dev_name /* memory devices */ enum dev_type { @@ -138,6 +150,9 @@ enum mem_type { MEM_DDR2, /* DDR2 RAM */ MEM_FB_DDR2, /* fully buffered DDR2 */ MEM_RDDR2, /* Registered DDR2 RAM */ + MEM_XDR, /* Rambus XDR */ + MEM_DDR3, /* DDR3 RAM */ + MEM_RDDR3, /* Registered DDR3 RAM */ }; #define MEM_FLAG_EMPTY BIT(MEM_EMPTY) @@ -154,6 +169,9 @@ enum mem_type { #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) +#define MEM_FLAG_DDR3 BIT(MEM_DDR3) +#define MEM_FLAG_RDDR3 BIT(MEM_RDDR3) /* chipset Error Detection and Correction capabilities and mode */ enum edac_type { @@ -211,8 +229,6 @@ enum scrub_type { #define OP_RUNNING_POLL_INTR 0x203 #define OP_OFFLINE 0x300 -extern char *edac_align_ptr(void *ptr, unsigned size); - /* * There are several things to be aware of that aren't at all obvious: * @@ -271,7 +287,7 @@ extern char *edac_align_ptr(void *ptr, unsigned size); * is irrespective of the memory devices being mounted * on both sides of the memory stick. * - * Socket set: All of the memory sticks that are required for for + * Socket set: All of the memory sticks that are required for * a single memory access or all of the memory sticks * spanned by a chip-select row. A single socket set * has two chip-select rows and if double-sided sticks @@ -319,9 +335,8 @@ struct csrow_info { 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; }; @@ -340,6 +355,9 @@ struct mcidev_sysfs_attribute { */ 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 @@ -405,7 +423,6 @@ struct mem_ctl_info { /* 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. @@ -470,32 +487,41 @@ struct edac_device_counter { 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 */ @@ -506,11 +532,12 @@ struct edac_device_block { 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 */ @@ -525,18 +552,8 @@ struct edac_device_instance { /* 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 @@ -546,6 +563,8 @@ struct edac_device_ctl_info { /* 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 */ @@ -596,7 +615,7 @@ struct edac_device_ctl_info { * 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: @@ -620,7 +639,6 @@ struct edac_device_ctl_info { * 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 */ @@ -637,13 +655,12 @@ struct edac_device_ctl_info { */ 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 @@ -756,11 +773,19 @@ static inline void pci_write_bits16(struct pci_dev *pdev, int offset, pci_write_config_word(pdev, offset, value); } -/* write all or some bits in a dword-register*/ +/* + * pci_write_bits32 + * + * edac local routine to do pci_write_config_dword, but adds + * a mask parameter. If mask is all ones, ignore the mask. + * Otherwise utilize the mask to isolate specified bits + * + * write all or some bits in a dword-register + */ static inline void pci_write_bits32(struct pci_dev *pdev, int offset, u32 value, u32 mask) { - if (mask != 0xffff) { + if (mask != 0xffffffff) { u32 buf; pci_read_config_dword(pdev, offset, &buf); @@ -774,8 +799,11 @@ static inline void pci_write_bits32(struct pci_dev *pdev, int offset, #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); @@ -812,33 +840,32 @@ extern void edac_mc_handle_fbd_ce(struct mem_ctl_info *mci, unsigned int csrow, /* * 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); +extern int edac_device_alloc_index(void); /* * 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_alloc_index(void); 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); @@ -847,6 +874,6 @@ extern void edac_pci_remove_sysfs(struct edac_pci_ctl_info *pci); /* * edac misc APIs */ -extern char *edac_op_state_toString(int op_state); +extern char *edac_op_state_to_string(int op_state); #endif /* _EDAC_CORE_H_ */