linux/drivers/edac/edac_module.c
<<
>>
Prefs
   1/*
   2 * edac_module.c
   3 *
   4 * (C) 2007 www.softwarebitmaker.com
   5 *
   6 * This file is licensed under the terms of the GNU General Public
   7 * License version 2. This program is licensed "as is" without any
   8 * warranty of any kind, whether express or implied.
   9 *
  10 * Author: Doug Thompson <dougthompson@xmission.com>
  11 *
  12 */
  13#include <linux/edac.h>
  14
  15#include "edac_core.h"
  16#include "edac_module.h"
  17
  18#define EDAC_VERSION "Ver: 3.0.0"
  19
  20#ifdef CONFIG_EDAC_DEBUG
  21
  22static int edac_set_debug_level(const char *buf, struct kernel_param *kp)
  23{
  24        unsigned long val;
  25        int ret;
  26
  27        ret = kstrtoul(buf, 0, &val);
  28        if (ret)
  29                return ret;
  30
  31        if (val < 0 || val > 4)
  32                return -EINVAL;
  33
  34        return param_set_int(buf, kp);
  35}
  36
  37/* Values of 0 to 4 will generate output */
  38int edac_debug_level = 2;
  39EXPORT_SYMBOL_GPL(edac_debug_level);
  40
  41module_param_call(edac_debug_level, edac_set_debug_level, param_get_int,
  42                  &edac_debug_level, 0644);
  43MODULE_PARM_DESC(edac_debug_level, "EDAC debug level: [0-4], default: 2");
  44#endif
  45
  46/* scope is to module level only */
  47struct workqueue_struct *edac_workqueue;
  48
  49/*
  50 * edac_op_state_to_string()
  51 */
  52char *edac_op_state_to_string(int opstate)
  53{
  54        if (opstate == OP_RUNNING_POLL)
  55                return "POLLED";
  56        else if (opstate == OP_RUNNING_INTERRUPT)
  57                return "INTERRUPT";
  58        else if (opstate == OP_RUNNING_POLL_INTR)
  59                return "POLL-INTR";
  60        else if (opstate == OP_ALLOC)
  61                return "ALLOC";
  62        else if (opstate == OP_OFFLINE)
  63                return "OFFLINE";
  64
  65        return "UNKNOWN";
  66}
  67
  68/*
  69 * edac_workqueue_setup
  70 *      initialize the edac work queue for polling operations
  71 */
  72static int edac_workqueue_setup(void)
  73{
  74        edac_workqueue = create_singlethread_workqueue("edac-poller");
  75        if (edac_workqueue == NULL)
  76                return -ENODEV;
  77        else
  78                return 0;
  79}
  80
  81/*
  82 * edac_workqueue_teardown
  83 *      teardown the edac workqueue
  84 */
  85static void edac_workqueue_teardown(void)
  86{
  87        if (edac_workqueue) {
  88                flush_workqueue(edac_workqueue);
  89                destroy_workqueue(edac_workqueue);
  90                edac_workqueue = NULL;
  91        }
  92}
  93
  94/*
  95 * edac_init
  96 *      module initialization entry point
  97 */
  98static int __init edac_init(void)
  99{
 100        int err = 0;
 101
 102        edac_printk(KERN_INFO, EDAC_MC, EDAC_VERSION "\n");
 103
 104        /*
 105         * Harvest and clear any boot/initialization PCI parity errors
 106         *
 107         * FIXME: This only clears errors logged by devices present at time of
 108         *      module initialization.  We should also do an initial clear
 109         *      of each newly hotplugged device.
 110         */
 111        edac_pci_clear_parity_errors();
 112
 113        err = edac_mc_sysfs_init();
 114        if (err)
 115                goto error;
 116
 117        edac_debugfs_init();
 118
 119        /* Setup/Initialize the workq for this core */
 120        err = edac_workqueue_setup();
 121        if (err) {
 122                edac_printk(KERN_ERR, EDAC_MC, "init WorkQueue failure\n");
 123                goto error;
 124        }
 125
 126        return 0;
 127
 128error:
 129        return err;
 130}
 131
 132/*
 133 * edac_exit()
 134 *      module exit/termination function
 135 */
 136static void __exit edac_exit(void)
 137{
 138        edac_dbg(0, "\n");
 139
 140        /* tear down the various subsystems */
 141        edac_workqueue_teardown();
 142        edac_mc_sysfs_exit();
 143        edac_debugfs_exit();
 144}
 145
 146/*
 147 * Inform the kernel of our entry and exit points
 148 */
 149module_init(edac_init);
 150module_exit(edac_exit);
 151
 152MODULE_LICENSE("GPL");
 153MODULE_AUTHOR("Doug Thompson www.softwarebitmaker.com, et al");
 154MODULE_DESCRIPTION("Core library routines for EDAC reporting");
 155
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.