^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Defines, structures, APIs for edac_mc module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * (C) 2007 Linux Networx (http://lnxi.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This file may be distributed under the terms of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * GNU General Public License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Written by Thayne Harbaugh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Based on work by Dan Hollis <goemon at anime dot net> and others.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * http://www.anime.net/~goemon/linux-ecc/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * NMI handling support added by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Refactored for multi-source files:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Doug Thompson <norsk5@xmission.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Please look at Documentation/driver-api/edac.rst for more info about
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * EDAC core structs and functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #ifndef _EDAC_MC_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define _EDAC_MC_H_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/nmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/kobject.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/edac.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #if PAGE_SHIFT < 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define PAGES_TO_MiB(pages) ((pages) >> (20 - PAGE_SHIFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define MiB_TO_PAGES(mb) ((mb) << (20 - PAGE_SHIFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #else /* PAGE_SHIFT > 20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define PAGES_TO_MiB(pages) ((pages) << (PAGE_SHIFT - 20))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define MiB_TO_PAGES(mb) ((mb) >> (PAGE_SHIFT - 20))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define edac_printk(level, prefix, fmt, arg...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) printk(level "EDAC " prefix ": " fmt, ##arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define edac_mc_printk(mci, level, fmt, arg...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) printk(level "EDAC MC%d: " fmt, mci->mc_idx, ##arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define edac_mc_chipset_printk(mci, level, prefix, fmt, arg...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) printk(level "EDAC " prefix " MC%d: " fmt, mci->mc_idx, ##arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define edac_device_printk(ctl, level, fmt, arg...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) printk(level "EDAC DEVICE%d: " fmt, ctl->dev_idx, ##arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define edac_pci_printk(ctl, level, fmt, arg...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) printk(level "EDAC PCI%d: " fmt, ctl->pci_idx, ##arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* prefixes for edac_printk() and edac_mc_printk() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define EDAC_MC "MC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define EDAC_PCI "PCI"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define EDAC_DEBUG "DEBUG"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) extern const char * const edac_mem_types[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #ifdef CONFIG_EDAC_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) extern int edac_debug_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define edac_dbg(level, fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (level <= edac_debug_level) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) edac_printk(KERN_DEBUG, EDAC_DEBUG, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) "%s: " fmt, __func__, ##__VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #else /* !CONFIG_EDAC_DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define edac_dbg(level, fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (0) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) edac_printk(KERN_DEBUG, EDAC_DEBUG, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) "%s: " fmt, __func__, ##__VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #endif /* !CONFIG_EDAC_DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) PCI_DEVICE_ID_ ## vend ## _ ## dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define edac_dev_name(dev) (dev)->dev_name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define to_mci(k) container_of(k, struct mem_ctl_info, dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * edac_mc_alloc() - Allocate and partially fill a struct &mem_ctl_info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @mc_num: Memory controller number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * @n_layers: Number of MC hierarchy layers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * @layers: Describes each layer as seen by the Memory Controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * @sz_pvt: size of private storage needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * Everything is kmalloc'ed as one big chunk - more efficient.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * Only can be used if all structures have the same lifetime - otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * you have to allocate and initialize your own structures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * Use edac_mc_free() to free mc structures allocated by this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * .. note::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * drivers handle multi-rank memories in different ways: in some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * drivers, one multi-rank memory stick is mapped as one entry, while, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * others, a single multi-rank memory stick would be mapped into several
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * entries. Currently, this function will allocate multiple struct dimm_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * on such scenarios, as grouping the multiple ranks require drivers change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * On success, return a pointer to struct mem_ctl_info pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * %NULL otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned int n_layers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct edac_mc_layer *layers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) unsigned int sz_pvt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * edac_get_owner - Return the owner's mod_name of EDAC MC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * Pointer to mod_name string when EDAC MC is owned. NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) extern const char *edac_get_owner(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * edac_mc_add_mc_with_groups() - Insert the @mci structure into the mci
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * global list and create sysfs entries associated with @mci structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * @mci: pointer to the mci structure to be added to the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * @groups: optional attribute groups for the driver-specific sysfs entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * 0 on Success, or an error code on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) extern int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) const struct attribute_group **groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define edac_mc_add_mc(mci) edac_mc_add_mc_with_groups(mci, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * edac_mc_free() - Frees a previously allocated @mci structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * @mci: pointer to a struct mem_ctl_info structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) extern void edac_mc_free(struct mem_ctl_info *mci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * edac_has_mcs() - Check if any MCs have been allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * True if MC instances have been registered successfully.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * False otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) extern bool edac_has_mcs(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * edac_mc_find() - Search for a mem_ctl_info structure whose index is @idx.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * @idx: index to be seek
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * If found, return a pointer to the structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * Else return NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) extern struct mem_ctl_info *edac_mc_find(int idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * find_mci_by_dev() - Scan list of controllers looking for the one that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * manages the @dev device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * @dev: pointer to a struct device related with the MCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * Returns: on success, returns a pointer to struct &mem_ctl_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * %NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) extern struct mem_ctl_info *find_mci_by_dev(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * edac_mc_del_mc() - Remove sysfs entries for mci structure associated with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * @dev and remove mci structure from global list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * @dev: Pointer to struct &device representing mci structure to remove.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * Returns: pointer to removed mci structure, or %NULL if device not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * edac_mc_find_csrow_by_page() - Ancillary routine to identify what csrow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * contains a memory page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * @mci: pointer to a struct mem_ctl_info structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * @page: memory page to find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * Returns: on success, returns the csrow. -1 if not found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) unsigned long page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * edac_raw_mc_handle_error() - Reports a memory event to userspace without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * doing anything to discover the error location.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * @e: error description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * This raw function is used internally by edac_mc_handle_error(). It should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * only be called directly when the hardware error come directly from BIOS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * like in the case of APEI GHES driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) void edac_raw_mc_handle_error(struct edac_raw_error_desc *e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * edac_mc_handle_error() - Reports a memory event to userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * @type: severity of the error (CE/UE/Fatal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * @mci: a struct mem_ctl_info pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * @error_count: Number of errors of the same type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * @page_frame_number: mem page where the error occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * @offset_in_page: offset of the error inside the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * @syndrome: ECC syndrome
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * @top_layer: Memory layer[0] position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * @mid_layer: Memory layer[1] position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * @low_layer: Memory layer[2] position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * @msg: Message meaningful to the end users that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * explains the event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * @other_detail: Technical details about the event that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * may help hardware manufacturers and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * EDAC developers to analyse the event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) void edac_mc_handle_error(const enum hw_event_mc_err_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct mem_ctl_info *mci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) const u16 error_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) const unsigned long page_frame_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) const unsigned long offset_in_page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) const unsigned long syndrome,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) const int top_layer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) const int mid_layer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) const int low_layer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) const char *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) const char *other_detail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * edac misc APIs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) extern char *edac_op_state_to_string(int op_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #endif /* _EDAC_MC_H_ */