Currently, there's no device driver documentation for the EDAC subsystem at the driver-api book. Fill in the blanks for the structures and functions that misses documentation, uniform the word on the existing ones, and add a new edac.rst file at driver-api, in order to document the EDAC subsystem. Signed-off-by: Mauro Carvalho Chehab <mchehab@xxxxxxxxxxxxxxxx> --- Documentation/driver-api/edac.rst | 70 +++++ Documentation/driver-api/index.rst | 1 + drivers/edac/edac_core.h | 534 ++++++++++++++++++++++--------------- 3 files changed, 386 insertions(+), 219 deletions(-) create mode 100644 Documentation/driver-api/edac.rst diff --git a/Documentation/driver-api/edac.rst b/Documentation/driver-api/edac.rst new file mode 100644 index 000000000000..7ab079d05af5 --- /dev/null +++ b/Documentation/driver-api/edac.rst @@ -0,0 +1,70 @@ +Error Detection And Correction (EDAC) Devices +============================================= + +Memory Controllers +------------------ + +Most of the EDAC core is focused on doing Memory Controller error detection. +The :c:func:`edac_mc_alloc`. It uses internally the struct ``mem_ctl_info`` +to describe the memory controllers, with is an opaque struct for the EDAC +drivers. Only the EDAC core is allowed to touch it. + +PCI Controllers +--------------- + +The EDAC subsystem provides a mechanism to handle PCI controllers by calling +the :c:func:`edac_pci_alloc_ctl_info`. It will use the struct +:c:type:`edac_pci_ctl_info` to describe the PCI controllers. + + +EDAC Blocks +----------- + +The EDAC subsystem also provides a generic mechanism to report errors on +other parts of the hardware via :c:func:`edac_device_alloc_ctl_info` function. + +The structures :c:type:`edac_dev_sysfs_block_attribute`, +:c:type:`edac_device_block`, :c:type:`edac_device_instance` and +:c:type:`edac_device_ctl_info` provide a generic or abstract 'edac_device' +representation at sysfs. + +This set of structures and the code that implements the APIs for the same, provide for registering EDAC type devices which are NOT standard memory or +PCI, like: + +- CPU caches (L1 and L2) +- DMA engines +- Core CPU switches +- Fabric switch units +- PCIe interface controllers +- other EDAC/ECC type devices that can be monitored for + errors, etc. + +It allows for a 2 level set of hierarchy. + +For example, a cache could be composed of L1, L2 and L3 levels of cache. +Each CPU core would have its own L1 cache, while sharing L2 and maybe L3 +caches. On such case, those can be represented via the following sysfs +nodes:: + + /sys/devices/system/edac/.. + + pci/ <existing pci directory (if available)> + mc/ <existing memory device directory> + cpu/cpu0/.. <L1 and L2 block directory> + /L1-cache/ce_count + /ue_count + /L2-cache/ce_count + /ue_count + cpu/cpu1/.. <L1 and L2 block directory> + /L1-cache/ce_count + /ue_count + /L2-cache/ce_count + /ue_count + ... + + the L1 and L2 directories would be "edac_device_block's" + +EDAC kAPI +--------- + +.. kernel-doc:: drivers/edac/edac_core.h diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst index b567907db350..2e1acd4d1c51 100644 --- a/Documentation/driver-api/index.rst +++ b/Documentation/driver-api/index.rst @@ -23,5 +23,6 @@ available subsections can be seen below. spi i2c hsi + edac miscellaneous vme diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index eeab781e22c0..9861357d4dbc 100644 --- a/drivers/edac/edac_core.h +++ b/drivers/edac/edac_core.h @@ -15,6 +15,8 @@ * Refactored for multi-source files: * Doug Thompson <norsk5@xxxxxxxxxxxx> * + * Please look at Documentation/driver-api/edac.rst for more info about + * EDAC core structs and functions. */ #ifndef _EDAC_CORE_H_ @@ -96,58 +98,30 @@ do { \ #define to_mci(k) container_of(k, struct mem_ctl_info, dev) -/* - * The following are the structures to provide for a generic - * or abstract 'edac_device'. This set of structures and the - * code that implements the APIs for the same, provide for - * registering EDAC type devices which are NOT standard memory. - * - * CPU caches (L1 and L2) - * DMA engines - * Core CPU switches - * Fabric switch units - * PCIe interface controllers - * other EDAC/ECC type devices that can be monitored for - * errors, etc. - * - * It allows for a 2 level set of hierarchy. For example: - * - * cache could be composed of L1, L2 and L3 levels of cache. - * Each CPU core would have its own L1 cache, while sharing - * L2 and maybe L3 caches. - * - * View them arranged, via the sysfs presentation: - * /sys/devices/system/edac/.. - * - * mc/ <existing memory device directory> - * cpu/cpu0/.. <L1 and L2 block directory> - * /L1-cache/ce_count - * /ue_count - * /L2-cache/ce_count - * /ue_count - * cpu/cpu1/.. <L1 and L2 block directory> - * /L1-cache/ce_count - * /ue_count - * /L2-cache/ce_count - * /ue_count - * ... - * - * the L1 and L2 directories would be "edac_device_block's" - */ - -struct edac_device_counter { - u32 ue_count; - u32 ce_count; -}; - /* forward reference */ struct edac_device_ctl_info; struct edac_device_block; -/* 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_device_counter - Ancillary struct to store the number of + * uncorrected and corrected errors. + * + * @ue_count: number of uncorrected errors + * @ce_count: number of corrected errors + */ +struct edac_device_counter { + u32 ue_count; + u32 ce_count; +}; + +/** + * struct edac_dev_sysfs_attribute structure - Used for driver sysfs attributes + * in struct &edac_device_ctl_info for extra controls and attributes like + * high level error injection controls. + * + * @attr: sysfs attribute + * @show: function to show a sysfs attribute + * @store: function to store a sysfs attribute */ struct edac_dev_sysfs_attribute { struct attribute attr; @@ -155,17 +129,20 @@ struct edac_dev_sysfs_attribute { ssize_t (*store)(struct edac_device_ctl_info *, const char *, size_t); }; -/* edac_dev_sysfs_block_attribute structure +/** + * struct edac_dev_sysfs_block_attribute structure - Used in leaf 'block' + * nodes for adding controls/attributes. * - * used in leaf 'block' nodes for adding controls/attributes + * @attr: sysfs attribute + * @show: function to show a sysfs attribute + * @store: function to store a sysfs attribute + * @block: pointer to struct &edac_device_block + * @value: actual value field used for counting * - * 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 + * 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. */ struct edac_dev_sysfs_block_attribute { struct attribute attr; @@ -177,107 +154,140 @@ struct edac_dev_sysfs_block_attribute { unsigned int value; }; -/* device block control structure */ +/** + * struct edac_device_block - EDAC device block control structure used for + * the sysfs ``/sys/devices/system/edac/instance/name?`` directory. + * + * @instance: up pointer to struct &edac_device_instance + * @name: name of the block at the sysfs under the block directory + * @counters: UE and CE counters for the directory + * @nr_attribs: how many attributes + * @block_attributes: this block's attributes, could be NULL + * @kobj: edac sysfs device control + */ struct edac_device_block { - struct edac_device_instance *instance; /* Up Pointer */ + struct edac_device_instance *instance; + char name[EDAC_DEVICE_NAME_LEN + 1]; - struct edac_device_counter counters; /* basic UE and CE counters */ + struct edac_device_counter counters; - int nr_attribs; /* how many attributes */ - - /* this block's attributes, could be NULL */ + int nr_attribs; struct edac_dev_sysfs_block_attribute *block_attributes; - /* edac sysfs device control */ struct kobject kobj; }; -/* device instance control structure */ +/** + * struct edac_device_instance - Device instance control structure used for + * the sysfs ``/sys/devices/system/edac/name`` directory. + * + * @ctl: up pointer to struct &edac_device_ctl_info + * @name: name of the instance + * @counters: instance counters + * @nr_blocks: how many blocks. Can be zero + * @blocks: struct &edac_device_block array + * @kobj: edac sysfs device control + */ struct edac_device_instance { - struct edac_device_ctl_info *ctl; /* Up pointer */ + struct edac_device_ctl_info *ctl; char name[EDAC_DEVICE_NAME_LEN + 4]; - struct edac_device_counter counters; /* instance counters */ + struct edac_device_counter counters; - u32 nr_blocks; /* how many blocks */ - struct edac_device_block *blocks; /* block array */ + u32 nr_blocks; + struct edac_device_block *blocks; - /* edac sysfs device control */ struct kobject kobj; }; - -/* - * Abstract edac_device control info structure +/** + * struct edac_device_ctl_info - Abstract edac_device control info structure. * + * @link: global list of edac_device_ctl_info structs + * @owner: Module owner of this control struct + * @dev_idx: device index + * @log_ue: boolean for logging UEs + * @log_ce: boolean for logging CEs + * @panic_on_ue: boolean for panic'ing on an UE + * @poll_msec: number of milliseconds to poll interval + * @delay: number of jiffies for poll_msec + * + * @sysfs_attributes: + * Additional top controller level attributes, but + * specified by the low level driver. + * Set by the low level driver to provide attributes at the + * controller level, same level as @ue_count and @ce_count. + * An array of structures, NULL terminated + * If attributes are desired, then set to array of attributes + * If no attributes are desired, leave NULL + * + * @edac_subsys: pointer to main 'edac' subsys in sysfs + * @op_state: the internal state of this controller instance + * @work: struct &work struct for this instance + * + * @edac_check: pointer to edac polling checking routine. + * If NOT %NULL: points to polling check routine. + * If %NULL: Then assumes INTERRUPT operation, where + * MC driver will receive events + * + * @dev: pointer to device structure + * @mod_name: module name + * @ctl_name: edac controller name + * @dev_name: ``pci/platform/etc...`` name + * @pvt_info: pointer to 'private driver' info + * @start_time: edac_device load start time (jiffies) + * @removal_complete: struct &completion pointer + * + * @name: sysfs top name under edac directory and instance name, e. g: + * cpu/cpu0/..., cpu/cpu1/..., cpu/cpu2/... + * + * @nr_instances: Number of instances supported on this control structure + * @instances: the array of those instances + * @counters: Event counters for the this whole EDAC Device + * @kobj: edac sysfs device control for the 'name' device this structure + * controls */ 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 */ + struct module *owner; int dev_idx; /* Per instance controls for this edac_device */ - int log_ue; /* boolean for logging UEs */ - int log_ce; /* boolean for logging CEs */ - int panic_on_ue; /* boolean for panic'ing on an UE */ - unsigned poll_msec; /* number of milliseconds to poll interval */ - unsigned long delay; /* number of jiffies for poll_msec */ + int log_ue; + int log_ce; + int panic_on_ue; + unsigned poll_msec; + unsigned long delay; - /* Additional top controller level attributes, but specified - * by the low level driver. - * - * Set by the low level driver to provide attributes at the - * controller level, same level as 'ue_count' and 'ce_count' above. - * An array of structures, NULL terminated - * - * If attributes are desired, then set to array of attributes - * If no attributes are desired, leave NULL - */ struct edac_dev_sysfs_attribute *sysfs_attributes; - /* pointer to main 'edac' subsys in sysfs */ struct bus_type *edac_subsys; - /* the internal state of this controller instance */ int op_state; - /* work struct for this instance */ struct delayed_work work; - /* pointer to edac polling checking routine: - * If NOT NULL: points to polling check routine - * If NULL: Then assumes INTERRUPT operation, where - * MC driver will receive events - */ + void (*edac_check) (struct edac_device_ctl_info * edac_dev); - struct device *dev; /* pointer to device structure */ + struct device *dev; - const char *mod_name; /* module name */ - const char *ctl_name; /* edac controller name */ - const char *dev_name; /* pci/platform/etc... name */ + const char *mod_name; + const char *ctl_name; + const char *dev_name; - void *pvt_info; /* pointer to 'private driver' info */ + void *pvt_info; - unsigned long start_time; /* edac_device load start time (jiffies) */ + unsigned long start_time; struct completion removal_complete; - /* sysfs top name under 'edac' directory - * and instance name: - * cpu/cpu0/... - * cpu/cpu1/... - * cpu/cpu2/... - * ... - */ + char name[EDAC_DEVICE_NAME_LEN + 1]; - /* Number of instances supported on this control structure - * and the array of those instances - */ + u32 nr_instances; struct edac_device_instance *instances; @@ -297,10 +307,42 @@ struct edac_device_ctl_info { #define to_edac_device_ctl_work(w) \ container_of(w,struct edac_device_ctl_info,work) -/* - * The alloc() and free() functions for the 'edac_device' control info - * structure. A MC driver will allocate one of these for each edac_device +/** + * edac_device_alloc_ctl_info() - Allocate and create a generic control + * info struct to represent non-memory EDAC sysfs nodes. + * + * @sizeof_private: size of &edac_device_ctl_info.pvt_info + * @edac_device_name: Name of this edac device + * @nr_instances: Number of device instances + * @edac_block_name: Base name for each block. A counter, starting from + * @offset_value is appended after the block name + * @nr_blocks: Number of blocks + * + * @offset_value: Number of the first block + * The offset value can be: + * -1 indicating no offset value; + * 0 for zero-based block numbers; + * 1 for 1-based block number; + * other for other-based block number. + * + * @block_attributes: pointer to struct &edac_dev_sysfs_block_attribute + * @nr_attribs: Number of attributes per block + * @device_index: Unique index for the device + * + * An EDAC driver will allocate one of these for each edac_device * it is going to control/register with the EDAC CORE. + * + * The control structure is allocated in complete chunk from the OS. It is + * in turn sub allocated to the various objects that compose the structure + * + * The structure has a @nr_instance array within itself. + * + * Each instance represents a major component + * Example: L1 cache and L2 cache are 2 instance components + * + * Within each instance is an array of @nr_blocks blockoffsets + * + * Returns: pointer to edac_device_alloc_ctl_info if success, %NULL otherwise. */ extern struct edac_device_ctl_info *edac_device_alloc_ctl_info( unsigned sizeof_private, @@ -311,14 +353,14 @@ extern struct edac_device_ctl_info *edac_device_alloc_ctl_info( unsigned nr_attribs, int device_index); -/* The offset value can be: - * -1 indicating no offset value - * 0 for zero-based block numbers - * 1 for 1-based block number - * other for other-based block number - */ #define BLOCK_OFFSET_VALUE_OFF ((unsigned) -1) +/** + * edac_device_free_ctl_info() - Frees a struct edac_device_ctl_info pointer + * allocated by the edac_device_alloc_ctl_info() function. + * + * @ctl_info: pointer to struct &edac_device_ctl_info. + */ extern void edac_device_free_ctl_info(struct edac_device_ctl_info *ctl_info); #ifdef CONFIG_PCI @@ -328,64 +370,81 @@ struct edac_pci_counter { atomic_t npe_count; }; -/* - * Abstract edac_pci control info structure +/** + * struct edac_pci_ctl_info - Abstract edac_pci control info structure. * + * @link: for global list of edac_pci_ctl_info structs + * @pci_idx: Unique index for the pci device + * @edac_subsys: pointer to subsystem + * @op_state: the internal state of this controller instance + * @work: struct &work for this instance + * + * @edac_check: pointer to edac polling checking routine. + * If NOT %NULL: points to polling check routine. + * If %NULL: Then assumes INTERRUPT operation, where + * MC driver will receive events + * + * @dev: pointer to struct &device + * @mod_name: module name + * @ctl_name: edac controller name + * @dev_name: pci/platform/etc... name + * @pvt_info: pointer to 'private driver' info + * @start_time: edac_pci load start time (jiffies) + * @complete: pointer to struct &completion + * + * + * @name: sysfs top name under edac directory and instance name, e. g: + * cpu/cpu0/..., cpu/cpu1/..., cpu/cpu2/... + * + * @counters: event counters for the this whole EDAC Device + * + * @kobj: edac sysfs device control for the 'name' device this + * structure controls */ struct edac_pci_ctl_info { - /* for global list of edac_pci_ctl_info structs */ struct list_head link; int pci_idx; - struct bus_type *edac_subsys; /* pointer to subsystem */ + struct bus_type *edac_subsys; - /* the internal state of this controller instance */ int op_state; - /* work struct for this instance */ struct delayed_work work; - /* pointer to edac polling checking routine: - * If NOT NULL: points to polling check routine - * If NULL: Then assumes INTERRUPT operation, where - * MC driver will receive events - */ void (*edac_check) (struct edac_pci_ctl_info * edac_dev); - struct device *dev; /* pointer to device structure */ + struct device *dev; - const char *mod_name; /* module name */ - const char *ctl_name; /* edac controller name */ - const char *dev_name; /* pci/platform/etc... name */ + const char *mod_name; + const char *ctl_name; + const char *dev_name; - void *pvt_info; /* pointer to 'private driver' info */ + void *pvt_info; - unsigned long start_time; /* edac_pci load start time (jiffies) */ + unsigned long start_time; struct completion complete; - /* sysfs top name under 'edac' directory - * and instance name: - * cpu/cpu0/... - * cpu/cpu1/... - * cpu/cpu2/... - * ... - */ char name[EDAC_DEVICE_NAME_LEN + 1]; - /* Event counters for the this whole EDAC Device */ struct edac_pci_counter counters; - /* edac sysfs device control for the 'name' - * device this structure controls - */ struct kobject kobj; }; #define to_edac_pci_ctl_work(w) \ container_of(w, struct edac_pci_ctl_info,work) -/* write all or some bits in a byte-register*/ +/** + * pci_write_bits8() - Ancillary routine to write all or some bits in a + * byte-register. + * + * @pdev: pointer to struct &pcidev + * @offset: offset to be used by pci_read_config_byte() + * @value: value to be written + * @mask: if different than 0xff, makes a PCI read and applies the + * bitmask before applying @value + */ static inline void pci_write_bits8(struct pci_dev *pdev, int offset, u8 value, u8 mask) { @@ -401,7 +460,16 @@ static inline void pci_write_bits8(struct pci_dev *pdev, int offset, u8 value, pci_write_config_byte(pdev, offset, value); } -/* write all or some bits in a word-register*/ +/** + * pci_write_bits16() - Ancillary routine to write all or some bits in a + * word-register. + * + * @pdev: pointer to struct &pcidev + * @offset: offset to be used by pci_read_config_byte() + * @value: value to be written + * @mask: if different than 0xffff, makes a PCI read and applies the + * bitmask before applying @value + */ static inline void pci_write_bits16(struct pci_dev *pdev, int offset, u16 value, u16 mask) { @@ -417,14 +485,15 @@ static inline void pci_write_bits16(struct pci_dev *pdev, int offset, pci_write_config_word(pdev, offset, value); } -/* - * pci_write_bits32 +/** + * pci_write_bits32() - Ancillary routine to write all or some bits in a + * dword-register. * - * 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 + * @pdev: pointer to struct &pcidev + * @offset: offset to be used by pci_read_config_byte() + * @value: value to be written + * @mask: if different than 0xffffffff, makes a PCI read and applies the + * bitmask before applying @value */ static inline void pci_write_bits32(struct pci_dev *pdev, int offset, u32 value, u32 mask) @@ -444,7 +513,8 @@ static inline void pci_write_bits32(struct pci_dev *pdev, int offset, #endif /* CONFIG_PCI */ /** - * edac_mc_alloc: Allocate and partially fill a struct mem_ctl_info structure + * edac_mc_alloc() - Allocate and partially fill a struct &mem_ctl_info. + * * @mc_num: Memory controller number * @n_layers: Number of MC hierarchy layers * @layers: Describes each layer as seen by the Memory Controller @@ -466,8 +536,8 @@ static inline void pci_write_bits32(struct pci_dev *pdev, int offset, * on such scenarios, as grouping the multiple ranks require drivers change. * * Returns: - * On failure: NULL - * On success: struct mem_ctl_info pointer + * On success, return a pointer to struct mem_ctl_info pointer; + * %NULL otherwise */ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num, unsigned n_layers, @@ -475,62 +545,73 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num, unsigned sz_pvt); /** - * edac_mc_add_mc_with_groups: Insert the 'mci' structure into the mci - * global list and create sysfs entries associated with mci structure + * edac_mc_add_mc_with_groups() - Insert the @mci structure into the mci + * global list and create sysfs entries associated with @mci structure. + * * @mci: pointer to the mci structure to be added to the list * @groups: optional attribute groups for the driver-specific sysfs entries * - * Return: - * 0 Success - * !0 Failure + * Returns: + * 0 on Success, or an error code on failure */ extern int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci, const struct attribute_group **groups); #define edac_mc_add_mc(mci) edac_mc_add_mc_with_groups(mci, NULL) /** - * edac_mc_free - * 'Free' a previously allocated 'mci' structure + * edac_mc_free() - Frees a previously allocated @mci structure + * * @mci: pointer to a struct mem_ctl_info structure */ extern void edac_mc_free(struct mem_ctl_info *mci); /** - * edac_mc_find: Search for a mem_ctl_info structure whose index is @idx. + * edac_mc_find() - Search for a mem_ctl_info structure whose index is @idx. * * @idx: index to be seek * - * If found, return a pointer to the structure. - * Else return NULL. + * .. note:: Caller must hold mem_ctls_mutex. * - * Caller must hold mem_ctls_mutex. + * Returns: If found, return a pointer to the structure; %NULL otherwise. */ extern struct mem_ctl_info *edac_mc_find(int idx); /** - * find_mci_by_dev + * find_mci_by_dev() - Scan list of controllers looking for the one that + * manages the @dev device. * - * scan list of controllers looking for the one that manages - * the 'dev' device * @dev: pointer to a struct device related with the MCI + * + * Returns: on success, returns a pointer to struct &mem_ctl_info; + * %NULL otherwise. */ extern struct mem_ctl_info *find_mci_by_dev(struct device *dev); /** - * edac_mc_del_mc: Remove sysfs entries for specified mci structure and - * remove mci structure from global list + * edac_mc_del_mc() - Remove sysfs entries for mci structure associated with + * @dev and remove mci structure from global list. * * @dev: Pointer to struct &device representing mci structure to remove. * - * Returns: pointer to removed mci structure, or NULL if device not found. + * Returns: pointer to removed mci structure, or %NULL if device not found. */ extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev); + +/** + * edac_mc_find_csrow_by_page() - Ancillary routine to identify what csrow + * contains a memory page. + * + * @mci: pointer to a struct mem_ctl_info structure + * @page: memory page to find + * + * Returns: on success, returns the csrow. -EINVAL otherwise. + */ extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page); /** - * edac_raw_mc_handle_error - reports a memory event to userspace without doing - * anything to discover the error location + * edac_raw_mc_handle_error() - Reports a memory event to userspace without + * doing anything to discover the error location. * * @type: severity of the error (CE/UE/Fatal) * @mci: a struct mem_ctl_info pointer @@ -545,7 +626,7 @@ void edac_raw_mc_handle_error(const enum hw_event_mc_err_type type, struct edac_raw_error_desc *e); /** - * edac_mc_handle_error - reports a memory event to userspace + * edac_mc_handle_error() - Reports a memory event to userspace. * * @type: severity of the error (CE/UE/Fatal) * @mci: a struct mem_ctl_info pointer @@ -579,7 +660,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type, */ /** - * edac_device_add_device: Insert the 'edac_dev' structure into the + * edac_device_add_device() - Insert the @edac_dev structure into the * edac_device global list and create sysfs entries associated with * edac_device structure. * @@ -592,23 +673,23 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type, extern int edac_device_add_device(struct edac_device_ctl_info *edac_dev); /** - * edac_device_del_device: - * Remove sysfs entries for specified edac_device structure and - * then remove edac_device structure from global list + * edac_device_del_device() - Remove sysfs entries for the struct + * &edac_device_ctl_info associated with @dev and then remove + * such structure from global list. * * @dev: * Pointer to struct &device representing the edac device * structure to remove. * * Returns: - * Pointer to removed edac_device structure, + * Pointer to removed struct &edac_device_ctl_info, * or %NULL if device not found. */ extern struct edac_device_ctl_info *edac_device_del_device(struct device *dev); /** - * edac_device_handle_ue(): - * perform a common output and handling of an 'edac_dev' UE event + * edac_device_handle_ue() - Perform a common output and handling of an + * @edac_dev UE event. * * @edac_dev: pointer to struct &edac_device_ctl_info * @inst_nr: number of the instance where the UE error happened @@ -618,8 +699,8 @@ 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); /** - * edac_device_handle_ce(): - * perform a common output and handling of an 'edac_dev' CE event + * edac_device_handle_ce() - Perform a common output and handling of an + * @edac_dev CE event. * * @edac_dev: pointer to struct &edac_device_ctl_info * @inst_nr: number of the instance where the CE error happened @@ -630,7 +711,7 @@ extern void edac_device_handle_ce(struct edac_device_ctl_info *edac_dev, int inst_nr, int block_nr, const char *msg); /** - * edac_device_alloc_index: Allocate a unique device index number + * edac_device_alloc_index(): Allocate a unique device index number. * * Returns: * allocated index number @@ -643,9 +724,8 @@ extern const char *edac_layer_name[]; */ /** - * edac_pci_alloc_ctl_info: - * The alloc() function for the 'edac_pci' control info - * structure. + * edac_pci_alloc_ctl_info() - The alloc function for the struct + * &edac_pci_ctl_info control info. * * @sz_pvt: size of the private info at struct &edac_pci_ctl_info * @edac_pci_name: name of the PCI device @@ -659,8 +739,7 @@ extern struct edac_pci_ctl_info *edac_pci_alloc_ctl_info(unsigned int sz_pvt, const char *edac_pci_name); /** - * edac_pci_free_ctl_info(): - * Last action on the pci control structure. + * edac_pci_free_ctl_info() - Last action on the pci control structure. * * @pci: pointer to struct &edac_pci_ctl_info * @@ -672,7 +751,7 @@ extern struct edac_pci_ctl_info *edac_pci_alloc_ctl_info(unsigned int sz_pvt, extern void edac_pci_free_ctl_info(struct edac_pci_ctl_info *pci); /** - * edac_pci_alloc_index: Allocate a unique PCI index number + * edac_pci_alloc_index() - Allocate a unique PCI index number. * * Returns: * allocated index number @@ -681,13 +760,13 @@ extern void edac_pci_free_ctl_info(struct edac_pci_ctl_info *pci); extern int edac_pci_alloc_index(void); /** - * edac_pci_add_device(): Insert the 'edac_dev' structure into the + * edac_pci_add_device() - Insert the @pci structure into the * edac_pci global list and create sysfs entries associated with * edac_pci structure. * * @pci: pointer to the edac_device structure to be added to the list * @edac_idx: A unique numeric identifier to be assigned to the - * 'edac_pci' structure. + * @edac_pci structure. * * Returns: * 0 on Success, or an error code on failure @@ -695,30 +774,32 @@ extern int edac_pci_alloc_index(void); extern int edac_pci_add_device(struct edac_pci_ctl_info *pci, int edac_idx); /** - * edac_pci_del_device() - * Remove sysfs entries for specified edac_pci structure and - * then remove edac_pci structure from global list + * edac_pci_del_device() - Remove sysfs entries for specified + * the struct edac_pci_ctl_info associated with @dev and + * then remove edac_pci structure from global list * * @dev: - * Pointer to 'struct device' representing edac_pci structure - * to remove + * Pointer to struct &device representing struct &edac_pci_ctl_info + * to remove * * Returns: - * Pointer to removed edac_pci structure, - * or %NULL if device not found + * Pointer to removed edac_pci structure, + * or %NULL if device not found */ extern struct edac_pci_ctl_info *edac_pci_del_device(struct device *dev); /** - * edac_pci_create_generic_ctl() - * A generic constructor for a PCI parity polling device - * Some systems have more than one domain of PCI busses. - * For systems with one domain, then this API will - * provide for a generic poller. + * edac_pci_create_generic_ctl() - A generic constructor for a PCI parity + * polling device. * * @dev: pointer to struct &device; * @mod_name: name of the PCI device * + * + * Some systems have more than one domain of PCI busses. + * For systems with one domain, then this API will + * provide for a generic poller. + * * This routine calls the edac_pci_alloc_ctl_info() for * the generic device, with default values * @@ -730,24 +811,27 @@ extern struct edac_pci_ctl_info *edac_pci_create_generic_ctl( const char *mod_name); /** - * edac_pci_release_generic_ctl - * The release function of a generic EDAC PCI polling device + * edac_pci_release_generic_ctl() - The release function of a generic EDAC + * PCI polling device. * * @pci: pointer to struct &edac_pci_ctl_info */ extern void edac_pci_release_generic_ctl(struct edac_pci_ctl_info *pci); /** - * edac_pci_create_sysfs - * Create the controls/attributes for the specified EDAC PCI device + * edac_pci_create_sysfs() - Create the controls/attributes for the specified + * @pci device. * * @pci: pointer to struct &edac_pci_ctl_info + * + * Returns: + * 0 on Success, or an error code on failure */ extern int edac_pci_create_sysfs(struct edac_pci_ctl_info *pci); /** - * edac_pci_remove_sysfs() - * remove the controls and attributes for this EDAC PCI device + * edac_pci_remove_sysfs() - Remove the controls and attributes for this + * @pci device. * * @pci: pointer to struct &edac_pci_ctl_info */ @@ -756,6 +840,18 @@ extern void edac_pci_remove_sysfs(struct edac_pci_ctl_info *pci); /* * edac misc APIs */ + +/** + * edac_op_state_to_string() - Ancillary function that returns the name of + * the @op_state. + * + * @op_state: Operational state name for the @op_state value + * + * Returns: + * A string with "POLLED", "INTERRUPT", "POLL-INTR", "ALLOC" or "OFFLINE", + * depending on the state. If the value is invalid, returns "UNKNOWN". + + */ extern char *edac_op_state_to_string(int op_state); #endif /* _EDAC_CORE_H_ */ -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html