Branch data Line data Source code
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_mc.h" 16 : : #include "edac_module.h" 17 : : 18 : : #define EDAC_VERSION "Ver: 3.0.0" 19 : : 20 : : #ifdef CONFIG_EDAC_DEBUG 21 : : 22 : : static int edac_set_debug_level(const char *buf, 23 : : const struct kernel_param *kp) 24 : : { 25 : : unsigned long val; 26 : : int ret; 27 : : 28 : : ret = kstrtoul(buf, 0, &val); 29 : : if (ret) 30 : : return ret; 31 : : 32 : : if (val > 4) 33 : : return -EINVAL; 34 : : 35 : : return param_set_int(buf, kp); 36 : : } 37 : : 38 : : /* Values of 0 to 4 will generate output */ 39 : : int edac_debug_level = 2; 40 : : EXPORT_SYMBOL_GPL(edac_debug_level); 41 : : 42 : : module_param_call(edac_debug_level, edac_set_debug_level, param_get_int, 43 : : &edac_debug_level, 0644); 44 : : MODULE_PARM_DESC(edac_debug_level, "EDAC debug level: [0-4], default: 2"); 45 : : #endif 46 : : 47 : : /* 48 : : * edac_op_state_to_string() 49 : : */ 50 : 0 : char *edac_op_state_to_string(int opstate) 51 : : { 52 [ # # ]: 0 : if (opstate == OP_RUNNING_POLL) 53 : : return "POLLED"; 54 [ # # ]: 0 : else if (opstate == OP_RUNNING_INTERRUPT) 55 : : return "INTERRUPT"; 56 [ # # ]: 0 : else if (opstate == OP_RUNNING_POLL_INTR) 57 : : return "POLL-INTR"; 58 [ # # ]: 0 : else if (opstate == OP_ALLOC) 59 : : return "ALLOC"; 60 [ # # ]: 0 : else if (opstate == OP_OFFLINE) 61 : 0 : return "OFFLINE"; 62 : : 63 : : return "UNKNOWN"; 64 : : } 65 : : 66 : : /* 67 : : * sysfs object: /sys/devices/system/edac 68 : : * need to export to other files 69 : : */ 70 : : static struct bus_type edac_subsys = { 71 : : .name = "edac", 72 : : .dev_name = "edac", 73 : : }; 74 : : 75 : 28 : static int edac_subsys_init(void) 76 : : { 77 : 28 : int err; 78 : : 79 : : /* create the /sys/devices/system/edac directory */ 80 : 28 : err = subsys_system_register(&edac_subsys, NULL); 81 [ - + ]: 28 : if (err) 82 : 0 : printk(KERN_ERR "Error registering toplevel EDAC sysfs dir\n"); 83 : : 84 : 28 : return err; 85 : : } 86 : : 87 : 0 : static void edac_subsys_exit(void) 88 : : { 89 : 0 : bus_unregister(&edac_subsys); 90 : : } 91 : : 92 : : /* return pointer to the 'edac' node in sysfs */ 93 : 28 : struct bus_type *edac_get_sysfs_subsys(void) 94 : : { 95 : 28 : return &edac_subsys; 96 : : } 97 : : EXPORT_SYMBOL_GPL(edac_get_sysfs_subsys); 98 : : /* 99 : : * edac_init 100 : : * module initialization entry point 101 : : */ 102 : 28 : static int __init edac_init(void) 103 : : { 104 : 28 : int err = 0; 105 : : 106 : 28 : edac_printk(KERN_INFO, EDAC_MC, EDAC_VERSION "\n"); 107 : : 108 : 28 : err = edac_subsys_init(); 109 [ + - ]: 28 : if (err) 110 : : return err; 111 : : 112 : : /* 113 : : * Harvest and clear any boot/initialization PCI parity errors 114 : : * 115 : : * FIXME: This only clears errors logged by devices present at time of 116 : : * module initialization. We should also do an initial clear 117 : : * of each newly hotplugged device. 118 : : */ 119 : 28 : edac_pci_clear_parity_errors(); 120 : : 121 : 28 : err = edac_mc_sysfs_init(); 122 [ - + ]: 28 : if (err) 123 : 0 : goto err_sysfs; 124 : : 125 : 28 : edac_debugfs_init(); 126 : : 127 : 28 : err = edac_workqueue_setup(); 128 [ - + ]: 28 : if (err) { 129 : 0 : edac_printk(KERN_ERR, EDAC_MC, "Failure initializing workqueue\n"); 130 : 0 : goto err_wq; 131 : : } 132 : : 133 : : return 0; 134 : : 135 : : err_wq: 136 : 0 : edac_debugfs_exit(); 137 : 0 : edac_mc_sysfs_exit(); 138 : : 139 : 0 : err_sysfs: 140 : 0 : edac_subsys_exit(); 141 : : 142 : 0 : return err; 143 : : } 144 : : 145 : : /* 146 : : * edac_exit() 147 : : * module exit/termination function 148 : : */ 149 : 0 : static void __exit edac_exit(void) 150 : : { 151 : 0 : edac_dbg(0, "\n"); 152 : : 153 : : /* tear down the various subsystems */ 154 : 0 : edac_workqueue_teardown(); 155 : 0 : edac_mc_sysfs_exit(); 156 : 0 : edac_debugfs_exit(); 157 : 0 : edac_subsys_exit(); 158 : 0 : } 159 : : 160 : : /* 161 : : * Inform the kernel of our entry and exit points 162 : : */ 163 : : subsys_initcall(edac_init); 164 : : module_exit(edac_exit); 165 : : 166 : : MODULE_LICENSE("GPL"); 167 : : MODULE_AUTHOR("Doug Thompson www.softwarebitmaker.com, et al"); 168 : : MODULE_DESCRIPTION("Core library routines for EDAC reporting");