edac_module.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #include <linux/freezer.h>
  2. #include <linux/kthread.h>
  3. #include "edac_mc.h"
  4. #include "edac_module.h"
  5. #define EDAC_MC_VERSION "Ver: 2.0.3" __DATE__
  6. #ifdef CONFIG_EDAC_DEBUG
  7. /* Values of 0 to 4 will generate output */
  8. int edac_debug_level = 1;
  9. EXPORT_SYMBOL_GPL(edac_debug_level);
  10. #endif
  11. /* scope is to module level only */
  12. struct workqueue_struct *edac_workqueue;
  13. /* private to this file */
  14. static struct task_struct *edac_thread;
  15. /*
  16. * sysfs object: /sys/devices/system/edac
  17. * need to export to other files in this modules
  18. */
  19. static struct sysdev_class edac_class = {
  20. set_kset_name("edac"),
  21. };
  22. static int edac_class_valid = 0;
  23. /*
  24. * edac_get_edac_class()
  25. *
  26. * return pointer to the edac class of 'edac'
  27. */
  28. struct sysdev_class *edac_get_edac_class(void)
  29. {
  30. struct sysdev_class *classptr=NULL;
  31. if (edac_class_valid)
  32. classptr = &edac_class;
  33. return classptr;
  34. }
  35. /*
  36. * edac_register_sysfs_edac_name()
  37. *
  38. * register the 'edac' into /sys/devices/system
  39. *
  40. * return:
  41. * 0 success
  42. * !0 error
  43. */
  44. static int edac_register_sysfs_edac_name(void)
  45. {
  46. int err;
  47. /* create the /sys/devices/system/edac directory */
  48. err = sysdev_class_register(&edac_class);
  49. if (err) {
  50. debugf1("%s() error=%d\n", __func__, err);
  51. return err;
  52. }
  53. edac_class_valid = 1;
  54. return 0;
  55. }
  56. /*
  57. * sysdev_class_unregister()
  58. *
  59. * unregister the 'edac' from /sys/devices/system
  60. */
  61. static void edac_unregister_sysfs_edac_name(void)
  62. {
  63. /* only if currently registered, then unregister it */
  64. if (edac_class_valid)
  65. sysdev_class_unregister(&edac_class);
  66. edac_class_valid = 0;
  67. }
  68. /*
  69. * Check MC status every edac_get_poll_msec().
  70. * Check PCI status every edac_get_poll_msec() as well.
  71. *
  72. * This where the work gets done for edac.
  73. *
  74. * SMP safe, doesn't use NMI, and auto-rate-limits.
  75. */
  76. static void do_edac_check(void)
  77. {
  78. debugf3("%s()\n", __func__);
  79. /* perform the poll activities */
  80. edac_check_mc_devices();
  81. edac_pci_do_parity_check();
  82. }
  83. /*
  84. * Action thread for EDAC to perform the POLL operations
  85. */
  86. static int edac_kernel_thread(void *arg)
  87. {
  88. int msec;
  89. while (!kthread_should_stop()) {
  90. do_edac_check();
  91. /* goto sleep for the interval */
  92. msec = (HZ * edac_get_poll_msec()) / 1000;
  93. schedule_timeout_interruptible(msec);
  94. try_to_freeze();
  95. }
  96. return 0;
  97. }
  98. /*
  99. * edac_workqueue_setup
  100. * initialize the edac work queue for polling operations
  101. */
  102. static int edac_workqueue_setup(void)
  103. {
  104. edac_workqueue = create_singlethread_workqueue("edac-poller");
  105. if (edac_workqueue == NULL)
  106. return -ENODEV;
  107. else
  108. return 0;
  109. }
  110. /*
  111. * edac_workqueue_teardown
  112. * teardown the edac workqueue
  113. */
  114. static void edac_workqueue_teardown(void)
  115. {
  116. if (edac_workqueue) {
  117. flush_workqueue(edac_workqueue);
  118. destroy_workqueue(edac_workqueue);
  119. edac_workqueue = NULL;
  120. }
  121. }
  122. /*
  123. * edac_init
  124. * module initialization entry point
  125. */
  126. static int __init edac_init(void)
  127. {
  128. int err = 0;
  129. edac_printk(KERN_INFO, EDAC_MC, EDAC_MC_VERSION "\n");
  130. /*
  131. * Harvest and clear any boot/initialization PCI parity errors
  132. *
  133. * FIXME: This only clears errors logged by devices present at time of
  134. * module initialization. We should also do an initial clear
  135. * of each newly hotplugged device.
  136. */
  137. edac_pci_clear_parity_errors();
  138. /*
  139. * perform the registration of the /sys/devices/system/edac object
  140. */
  141. if (edac_register_sysfs_edac_name()) {
  142. edac_printk(KERN_ERR, EDAC_MC,
  143. "Error initializing 'edac' kobject\n");
  144. err = -ENODEV;
  145. goto error;
  146. }
  147. /* Create the MC sysfs entries, must be first
  148. */
  149. if (edac_sysfs_memctrl_setup()) {
  150. edac_printk(KERN_ERR, EDAC_MC,
  151. "Error initializing sysfs code\n");
  152. err = -ENODEV;
  153. goto error_sysfs;
  154. }
  155. /* Create the PCI parity sysfs entries */
  156. if (edac_sysfs_pci_setup()) {
  157. edac_printk(KERN_ERR, EDAC_MC,
  158. "PCI: Error initializing sysfs code\n");
  159. err = -ENODEV;
  160. goto error_mem;
  161. }
  162. /* Setup/Initialize the edac_device system */
  163. err = edac_workqueue_setup();
  164. if (err) {
  165. edac_printk(KERN_ERR, EDAC_MC, "init WorkQueue failure\n");
  166. goto error_pci;
  167. }
  168. /* create our kernel thread */
  169. edac_thread = kthread_run(edac_kernel_thread, NULL, "kedac");
  170. if (IS_ERR(edac_thread)) {
  171. err = PTR_ERR(edac_thread);
  172. goto error_work;
  173. }
  174. return 0;
  175. /* Error teardown stack */
  176. error_work:
  177. edac_workqueue_teardown();
  178. error_pci:
  179. edac_sysfs_pci_teardown();
  180. error_mem:
  181. edac_sysfs_memctrl_teardown();
  182. error_sysfs:
  183. edac_unregister_sysfs_edac_name();
  184. error:
  185. return err;
  186. }
  187. /*
  188. * edac_exit()
  189. * module exit/termination function
  190. */
  191. static void __exit edac_exit(void)
  192. {
  193. debugf0("%s()\n", __func__);
  194. kthread_stop(edac_thread);
  195. /* tear down the various subsystems*/
  196. edac_workqueue_teardown();
  197. edac_sysfs_memctrl_teardown();
  198. edac_sysfs_pci_teardown();
  199. edac_unregister_sysfs_edac_name();
  200. }
  201. /*
  202. * Inform the kernel of our entry and exit points
  203. */
  204. module_init(edac_init);
  205. module_exit(edac_exit);
  206. MODULE_LICENSE("GPL");
  207. MODULE_AUTHOR("Doug Thompson www.softwarebitmaker.com, et al");
  208. MODULE_DESCRIPTION("Core library routines for EDAC reporting");
  209. /* refer to *_sysfs.c files for parameters that are exported via sysfs */
  210. #ifdef CONFIG_EDAC_DEBUG
  211. module_param(edac_debug_level, int, 0644);
  212. MODULE_PARM_DESC(edac_debug_level, "Debug level");
  213. #endif