linux/drivers/edac/i5100_edac.c

/*
 * Intel 5100 Memory Controllers kernel module
 *
 * This file may be distributed under the terms of the
 * GNU General Public License.
 *
 * This module is based on the following document:
 *
 * Intel 5100X Chipset Memory Controller Hub (MCH) - Datasheet
 *      http://download.intel.com/design/chipsets/datashts/318378.pdf
 *
 * The intel 5100 has two independent channels. EDAC core currently
 * can not reflect this configuration so instead the chip-select
 * rows for each respective channel are laid out one after another,
 * the first half belonging to channel 0, the second half belonging
 * to channel 1.
 *
 * This driver is for DDR2 DIMMs, and it uses chip select to select among the
 * several ranks. However, instead of showing memories as ranks, it outputs
 * them as DIMM's. An internal table creates the association between ranks
 * and DIMM's.
 */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
#include <linux/edac.h>
#include <linux/delay.h>
#include <linux/mmzone.h>
#include <linux/debugfs.h>

#include "edac_module.h"

/* register addresses */

/* device 16, func 1 */
#define I5100_MC
#define I5100_MC_SCRBEN_MASK
#define I5100_MC_SCRBDONE_MASK
#define I5100_MS
#define I5100_SPDDATA
#define I5100_SPDCMD
#define I5100_TOLM
#define I5100_MIR0
#define I5100_MIR1
#define I5100_AMIR_0
#define I5100_AMIR_1
#define I5100_FERR_NF_MEM
#define I5100_FERR_NF_MEM_M16ERR_MASK
#define I5100_FERR_NF_MEM_M15ERR_MASK
#define I5100_FERR_NF_MEM_M14ERR_MASK
#define I5100_FERR_NF_MEM_M12ERR_MASK
#define I5100_FERR_NF_MEM_M11ERR_MASK
#define I5100_FERR_NF_MEM_M10ERR_MASK
#define I5100_FERR_NF_MEM_M6ERR_MASK
#define I5100_FERR_NF_MEM_M5ERR_MASK
#define I5100_FERR_NF_MEM_M4ERR_MASK
#define I5100_FERR_NF_MEM_M1ERR_MASK
#define I5100_FERR_NF_MEM_ANY_MASK
#define I5100_NERR_NF_MEM
#define I5100_EMASK_MEM
#define I5100_MEM0EINJMSK0
#define I5100_MEM1EINJMSK0
#define I5100_MEMXEINJMSK0_EINJEN
#define I5100_MEM0EINJMSK1
#define I5100_MEM1EINJMSK1

/* Device 19, Function 0 */
#define I5100_DINJ0

/* device 21 and 22, func 0 */
#define I5100_MTR_0
#define I5100_DMIR
#define I5100_VALIDLOG
#define I5100_NRECMEMA
#define I5100_NRECMEMB
#define I5100_REDMEMA
#define I5100_REDMEMB
#define I5100_RECMEMA
#define I5100_RECMEMB
#define I5100_MTR_4

/* bit field accessors */

static inline u32 i5100_mc_scrben(u32 mc)
{}

static inline u32 i5100_mc_errdeten(u32 mc)
{}

static inline u32 i5100_mc_scrbdone(u32 mc)
{}

static inline u16 i5100_spddata_rdo(u16 a)
{}

static inline u16 i5100_spddata_sbe(u16 a)
{}

static inline u16 i5100_spddata_busy(u16 a)
{}

static inline u16 i5100_spddata_data(u16 a)
{}

static inline u32 i5100_spdcmd_create(u32 dti, u32 ckovrd, u32 sa, u32 ba,
				      u32 data, u32 cmd)
{}

static inline u16 i5100_tolm_tolm(u16 a)
{}

static inline u16 i5100_mir_limit(u16 a)
{}

static inline u16 i5100_mir_way1(u16 a)
{}

static inline u16 i5100_mir_way0(u16 a)
{}

static inline u32 i5100_ferr_nf_mem_chan_indx(u32 a)
{}

static inline u32 i5100_ferr_nf_mem_any(u32 a)
{}

static inline u32 i5100_nerr_nf_mem_any(u32 a)
{}

static inline u32 i5100_dmir_limit(u32 a)
{}

static inline u32 i5100_dmir_rank(u32 a, u32 i)
{}

static inline u16 i5100_mtr_present(u16 a)
{}

static inline u16 i5100_mtr_ethrottle(u16 a)
{}

static inline u16 i5100_mtr_width(u16 a)
{}

static inline u16 i5100_mtr_numbank(u16 a)
{}

static inline u16 i5100_mtr_numrow(u16 a)
{}

static inline u16 i5100_mtr_numcol(u16 a)
{}


static inline u32 i5100_validlog_redmemvalid(u32 a)
{}

static inline u32 i5100_validlog_recmemvalid(u32 a)
{}

static inline u32 i5100_validlog_nrecmemvalid(u32 a)
{}

static inline u32 i5100_nrecmema_merr(u32 a)
{}

static inline u32 i5100_nrecmema_bank(u32 a)
{}

static inline u32 i5100_nrecmema_rank(u32 a)
{}

static inline u32 i5100_nrecmemb_cas(u32 a)
{}

static inline u32 i5100_nrecmemb_ras(u32 a)
{}

static inline u32 i5100_recmema_merr(u32 a)
{}

static inline u32 i5100_recmema_bank(u32 a)
{}

static inline u32 i5100_recmema_rank(u32 a)
{}

static inline u32 i5100_recmemb_cas(u32 a)
{}

static inline u32 i5100_recmemb_ras(u32 a)
{}

/* some generic limits */
#define I5100_MAX_RANKS_PER_CHAN
#define I5100_CHANNELS
#define I5100_MAX_RANKS_PER_DIMM
#define I5100_DIMM_ADDR_LINES
#define I5100_MAX_DIMM_SLOTS_PER_CHAN
#define I5100_MAX_RANK_INTERLEAVE
#define I5100_MAX_DMIRS
#define I5100_SCRUB_REFRESH_RATE

struct i5100_priv {};

static struct dentry *i5100_debugfs;

/* map a rank/chan to a slot number on the mainboard */
static int i5100_rank_to_slot(const struct mem_ctl_info *mci,
			      int chan, int rank)
{}

static const char *i5100_err_msg(unsigned err)
{}

/* convert csrow index into a rank (per channel -- 0..5) */
static unsigned int i5100_csrow_to_rank(const struct mem_ctl_info *mci,
					unsigned int csrow)
{}

/* convert csrow index into a channel (0..1) */
static unsigned int i5100_csrow_to_chan(const struct mem_ctl_info *mci,
					unsigned int csrow)
{}

static void i5100_handle_ce(struct mem_ctl_info *mci,
			    int chan,
			    unsigned bank,
			    unsigned rank,
			    unsigned long syndrome,
			    unsigned cas,
			    unsigned ras,
			    const char *msg)
{}

static void i5100_handle_ue(struct mem_ctl_info *mci,
			    int chan,
			    unsigned bank,
			    unsigned rank,
			    unsigned long syndrome,
			    unsigned cas,
			    unsigned ras,
			    const char *msg)
{}

static void i5100_read_log(struct mem_ctl_info *mci, int chan,
			   u32 ferr, u32 nerr)
{}

static void i5100_check_error(struct mem_ctl_info *mci)
{}

/* The i5100 chipset will scrub the entire memory once, then
 * set a done bit. Continuous scrubbing is achieved by enqueing
 * delayed work to a workqueue, checking every few minutes if
 * the scrubbing has completed and if so reinitiating it.
 */

static void i5100_refresh_scrubbing(struct work_struct *work)
{}
/*
 * The bandwidth is based on experimentation, feel free to refine it.
 */
static int i5100_set_scrub_rate(struct mem_ctl_info *mci, u32 bandwidth)
{}

static int i5100_get_scrub_rate(struct mem_ctl_info *mci)
{}

static struct pci_dev *pci_get_device_func(unsigned vendor,
					   unsigned device,
					   unsigned func)
{}

static unsigned long i5100_npages(struct mem_ctl_info *mci, unsigned int csrow)
{}

static void i5100_init_mtr(struct mem_ctl_info *mci)
{}

/*
 * FIXME: make this into a real i2c adapter (so that dimm-decode
 * will work)?
 */
static int i5100_read_spd_byte(const struct mem_ctl_info *mci,
			       u8 ch, u8 slot, u8 addr, u8 *byte)
{}

/*
 * fill dimm chip select map
 *
 * FIXME:
 *   o not the only way to may chip selects to dimm slots
 *   o investigate if there is some way to obtain this map from the bios
 */
static void i5100_init_dimm_csmap(struct mem_ctl_info *mci)
{}

static void i5100_init_dimm_layout(struct pci_dev *pdev,
				   struct mem_ctl_info *mci)
{}

static void i5100_init_interleaving(struct pci_dev *pdev,
				    struct mem_ctl_info *mci)
{}

static void i5100_init_csrows(struct mem_ctl_info *mci)
{}

/****************************************************************************
 *                       Error injection routines
 ****************************************************************************/

static void i5100_do_inject(struct mem_ctl_info *mci)
{}

#define to_mci(k)
static ssize_t inject_enable_write(struct file *file, const char __user *data,
		size_t count, loff_t *ppos)
{}

static const struct file_operations i5100_inject_enable_fops =;

static int i5100_setup_debugfs(struct mem_ctl_info *mci)
{}

static int i5100_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{}

static void i5100_remove_one(struct pci_dev *pdev)
{}

static const struct pci_device_id i5100_pci_tbl[] =;
MODULE_DEVICE_TABLE(pci, i5100_pci_tbl);

static struct pci_driver i5100_driver =;

static int __init i5100_init(void)
{}

static void __exit i5100_exit(void)
{}

module_init();
module_exit(i5100_exit);

MODULE_LICENSE();
MODULE_AUTHOR();
MODULE_DESCRIPTION();