X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fedac%2Fedac_mc.h;h=13ddfd94025c50af09e7d572f5c94457d2c864ef;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=75ecf484a43a8ddc3985fda1841357d8c24f9d02;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/drivers/edac/edac_mc.h b/drivers/edac/edac_mc.h index 75ecf484a..13ddfd940 100644 --- a/drivers/edac/edac_mc.h +++ b/drivers/edac/edac_mc.h @@ -15,12 +15,9 @@ * */ - #ifndef _EDAC_MC_H_ #define _EDAC_MC_H_ - -#include #include #include #include @@ -32,7 +29,7 @@ #include #include #include - +#include #define EDAC_MC_LABEL_LEN 31 #define MC_PROC_NAME_MAX_LEN 7 @@ -43,31 +40,55 @@ #define PAGES_TO_MiB( pages ) ( ( pages ) << ( PAGE_SHIFT - 20 ) ) #endif +#define edac_printk(level, prefix, fmt, arg...) \ + printk(level "EDAC " prefix ": " fmt, ##arg) + +#define edac_mc_printk(mci, level, fmt, arg...) \ + printk(level "EDAC MC%d: " fmt, mci->mc_idx, ##arg) + +#define edac_mc_chipset_printk(mci, level, prefix, fmt, arg...) \ + printk(level "EDAC " prefix " MC%d: " fmt, mci->mc_idx, ##arg) + +/* prefixes for edac_printk() and edac_mc_printk() */ +#define EDAC_MC "MC" +#define EDAC_PCI "PCI" +#define EDAC_DEBUG "DEBUG" + #ifdef CONFIG_EDAC_DEBUG extern int edac_debug_level; -#define edac_debug_printk(level, fmt, args...) \ -do { if (level <= edac_debug_level) printk(KERN_DEBUG fmt, ##args); } while(0) + +#define edac_debug_printk(level, fmt, arg...) \ + do { \ + if (level <= edac_debug_level) \ + edac_printk(KERN_DEBUG, EDAC_DEBUG, fmt, ##arg); \ + } while(0) + #define debugf0( ... ) edac_debug_printk(0, __VA_ARGS__ ) #define debugf1( ... ) edac_debug_printk(1, __VA_ARGS__ ) #define debugf2( ... ) edac_debug_printk(2, __VA_ARGS__ ) #define debugf3( ... ) edac_debug_printk(3, __VA_ARGS__ ) #define debugf4( ... ) edac_debug_printk(4, __VA_ARGS__ ) -#else /* !CONFIG_EDAC_DEBUG */ + +#else /* !CONFIG_EDAC_DEBUG */ + #define debugf0( ... ) #define debugf1( ... ) #define debugf2( ... ) #define debugf3( ... ) #define debugf4( ... ) -#endif /* !CONFIG_EDAC_DEBUG */ - -#define bs_xstr(s) bs_str(s) -#define bs_str(s) #s -#define BS_MOD_STR bs_xstr(KBUILD_BASENAME) +#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 PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \ + PCI_DEVICE_ID_ ## vend ## _ ## dev + +#if defined(CONFIG_X86) && defined(CONFIG_PCI) +#define dev_name(dev) pci_name(to_pci_dev(dev)) +#else +#define dev_name(dev) to_platform_device(dev)->name +#endif /* memory devices */ enum dev_type { @@ -102,7 +123,10 @@ enum mem_type { MEM_RDR, /* Registered single data rate SDRAM */ MEM_DDR, /* Double data rate SDRAM */ MEM_RDDR, /* Registered Double data rate SDRAM */ - MEM_RMBS /* Rambus DRAM */ + MEM_RMBS, /* Rambus DRAM */ + MEM_DDR2, /* DDR2 RAM */ + MEM_FB_DDR2, /* fully buffered DDR2 */ + MEM_RDDR2, /* Registered DDR2 RAM */ }; #define MEM_FLAG_EMPTY BIT(MEM_EMPTY) @@ -116,7 +140,9 @@ enum mem_type { #define MEM_FLAG_DDR BIT(MEM_DDR) #define MEM_FLAG_RDDR BIT(MEM_RDDR) #define MEM_FLAG_RMBS BIT(MEM_RMBS) - +#define MEM_FLAG_DDR2 BIT(MEM_DDR2) +#define MEM_FLAG_FB_DDR2 BIT(MEM_FB_DDR2) +#define MEM_FLAG_RDDR2 BIT(MEM_RDDR2) /* chipset Error Detection and Correction capabilities and mode */ enum edac_type { @@ -142,7 +168,6 @@ enum edac_type { #define EDAC_FLAG_S8ECD8ED BIT(EDAC_S8ECD8ED) #define EDAC_FLAG_S16ECD16ED BIT(EDAC_S16ECD16ED) - /* scrubbing capabilities */ enum scrub_type { SCRUB_UNKNOWN = 0, /* Unknown if scrubber is available */ @@ -166,11 +191,6 @@ enum scrub_type { #define SCRUB_FLAG_HW_PROG_SRC BIT(SCRUB_HW_PROG_SRC_CORR) #define SCRUB_FLAG_HW_TUN BIT(SCRUB_HW_TUNABLE) -enum mci_sysfs_status { - MCI_SYSFS_INACTIVE = 0, /* sysfs entries NOT registered */ - MCI_SYSFS_ACTIVE /* sysfs entries ARE registered */ -}; - /* FIXME - should have notify capabilities: NMI, LOG, PROC, etc */ /* @@ -255,20 +275,19 @@ enum mci_sysfs_status { * PS - I enjoyed writing all that about as much as you enjoyed reading it. */ - struct channel_info { int chan_idx; /* channel index */ u32 ce_count; /* Correctable Errors for this CHANNEL */ - char label[EDAC_MC_LABEL_LEN + 1]; /* DIMM label on motherboard */ + char label[EDAC_MC_LABEL_LEN + 1]; /* DIMM label on motherboard */ struct csrow_info *csrow; /* the parent */ }; - struct csrow_info { unsigned long first_page; /* first page number in dimm */ unsigned long last_page; /* last page number in dimm */ unsigned long page_mask; /* used for interleaving - - 0UL for non intlv */ + * 0UL for non intlv + */ u32 nr_pages; /* number of pages in csrow */ u32 grain; /* granularity of reported error in bytes */ int csrow_idx; /* the chip-select row */ @@ -280,29 +299,28 @@ 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 */ u32 nr_channels; struct channel_info *channels; }; - struct mem_ctl_info { struct list_head link; /* for global list of mem_ctl_info structs */ 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 - closely related to edac_ctl_cap. The - difference is that the controller - may be capable of s4ecd4ed which would - be listed in edac_ctl_cap, but if - channels aren't capable of s4ecd4ed then the - edac_cap would not have that capability. */ + * closely related to edac_ctl_cap. The + * difference is that the controller may be + * capable of s4ecd4ed which would be listed + * in edac_ctl_cap, but if channels aren't + * capable of s4ecd4ed then the edac_cap would + * not have that capability. + */ unsigned long scrub_cap; /* chipset scrub capabilities */ enum scrub_type scrub_mode; /* current scrub mode */ - enum mci_sysfs_status sysfs_active; /* status of sysfs */ - /* pointer to edac checking routine */ void (*edac_check) (struct mem_ctl_info * mci); /* @@ -311,16 +329,16 @@ struct mem_ctl_info { */ /* FIXME - why not send the phys page to begin with? */ unsigned long (*ctl_page_to_phys) (struct mem_ctl_info * mci, - unsigned long page); + unsigned long page); int mc_idx; int nr_csrows; struct csrow_info *csrows; /* * FIXME - what about controllers on other busses? - IDs must be - * unique. pdev pointer should be sufficiently unique, but + * unique. dev pointer should be sufficiently unique, but * BUS:SLOT.FUNC numbers may not be unique. */ - struct pci_dev *pdev; + struct device *dev; const char *mod_name; const char *mod_ver; const char *ctl_name; @@ -340,72 +358,74 @@ struct mem_ctl_info { /* edac sysfs device control */ struct kobject edac_mci_kobj; + struct completion kobj_complete; }; - +#ifdef CONFIG_PCI /* write all or some bits in a byte-register*/ -static inline void pci_write_bits8(struct pci_dev *pdev, int offset, - u8 value, u8 mask) +static inline void pci_write_bits8(struct pci_dev *pdev, int offset, u8 value, + u8 mask) { if (mask != 0xff) { u8 buf; + pci_read_config_byte(pdev, offset, &buf); value &= mask; buf &= ~mask; value |= buf; } + pci_write_config_byte(pdev, offset, value); } - /* write all or some bits in a word-register*/ static inline void pci_write_bits16(struct pci_dev *pdev, int offset, - u16 value, u16 mask) + u16 value, u16 mask) { if (mask != 0xffff) { u16 buf; + pci_read_config_word(pdev, offset, &buf); value &= mask; buf &= ~mask; value |= buf; } + pci_write_config_word(pdev, offset, value); } - /* 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) + u32 value, u32 mask) { if (mask != 0xffff) { u32 buf; + pci_read_config_dword(pdev, offset, &buf); value &= mask; buf &= ~mask; value |= buf; } + pci_write_config_dword(pdev, offset, value); } +#endif /* CONFIG_PCI */ #ifdef CONFIG_EDAC_DEBUG void edac_mc_dump_channel(struct channel_info *chan); void edac_mc_dump_mci(struct mem_ctl_info *mci); void edac_mc_dump_csrow(struct csrow_info *csrow); -#endif /* CONFIG_EDAC_DEBUG */ - -extern int edac_mc_add_mc(struct mem_ctl_info *mci); -extern int edac_mc_del_mc(struct mem_ctl_info *mci); +#endif /* CONFIG_EDAC_DEBUG */ +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); - -extern struct mem_ctl_info *edac_mc_find_mci_by_pdev(struct pci_dev - *pdev); - -extern void edac_mc_scrub_block(unsigned long page, - unsigned long offset, u32 size); + unsigned long page); +extern void edac_mc_scrub_block(unsigned long page, unsigned long offset, + u32 size); /* * The no info errors are used when error overflows are reported. @@ -418,31 +438,25 @@ extern void edac_mc_scrub_block(unsigned long page, * statement clutter and extra function arguments. */ extern void edac_mc_handle_ce(struct mem_ctl_info *mci, - unsigned long page_frame_number, - unsigned long offset_in_page, - unsigned long syndrome, - int row, int channel, const char *msg); - + unsigned long page_frame_number, unsigned long offset_in_page, + unsigned long syndrome, int row, int channel, + const char *msg); extern void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, - const char *msg); - + const char *msg); extern void edac_mc_handle_ue(struct mem_ctl_info *mci, - unsigned long page_frame_number, - unsigned long offset_in_page, - int row, const char *msg); - + unsigned long page_frame_number, unsigned long offset_in_page, + int row, const char *msg); extern void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, - const char *msg); + const char *msg); /* * This kmalloc's and initializes all the structures. * Can't be used if all structures don't have the same lifetime. */ -extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, - unsigned nr_csrows, unsigned nr_chans); +extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, + unsigned nr_chans); /* Free an mc previously allocated by edac_mc_alloc() */ extern void edac_mc_free(struct mem_ctl_info *mci); - #endif /* _EDAC_MC_H_ */