fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / edac / edac_mc.h
index 75ecf48..13ddfd9 100644 (file)
  *
  */
 
-
 #ifndef _EDAC_MC_H_
 #define _EDAC_MC_H_
 
-
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/module.h>
@@ -32,7 +29,7 @@
 #include <linux/rcupdate.h>
 #include <linux/completion.h>
 #include <linux/kobject.h>
-
+#include <linux/platform_device.h>
 
 #define EDAC_MC_LABEL_LEN      31
 #define MC_PROC_NAME_MAX_LEN 7
 #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_ */