edac_device_sysfs.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  1. /*
  2. * file for managing the edac_device class of devices for EDAC
  3. *
  4. * (C) 2007 SoftwareBitMaker(http://www.softwarebitmaker.com)
  5. * This file may be distributed under the terms of the
  6. * GNU General Public License.
  7. *
  8. * Written Doug Thompson <norsk5@xmission.com>
  9. *
  10. */
  11. #include <linux/ctype.h>
  12. #include "edac_core.h"
  13. #include "edac_module.h"
  14. #define EDAC_DEVICE_SYMLINK "device"
  15. #define to_edacdev(k) container_of(k, struct edac_device_ctl_info, kobj)
  16. #define to_edacdev_attr(a) container_of(a, struct edacdev_attribute, attr)
  17. /************************** edac_device sysfs code and data **************/
  18. /*
  19. * Set of edac_device_ctl_info attribute store/show functions
  20. */
  21. /* 'log_ue' */
  22. static ssize_t edac_device_ctl_log_ue_show(struct edac_device_ctl_info
  23. *ctl_info, char *data)
  24. {
  25. return sprintf(data, "%u\n", ctl_info->log_ue);
  26. }
  27. static ssize_t edac_device_ctl_log_ue_store(struct edac_device_ctl_info
  28. *ctl_info, const char *data,
  29. size_t count)
  30. {
  31. /* if parameter is zero, turn off flag, if non-zero turn on flag */
  32. ctl_info->log_ue = (simple_strtoul(data, NULL, 0) != 0);
  33. return count;
  34. }
  35. /* 'log_ce' */
  36. static ssize_t edac_device_ctl_log_ce_show(struct edac_device_ctl_info
  37. *ctl_info, char *data)
  38. {
  39. return sprintf(data, "%u\n", ctl_info->log_ce);
  40. }
  41. static ssize_t edac_device_ctl_log_ce_store(struct edac_device_ctl_info
  42. *ctl_info, const char *data,
  43. size_t count)
  44. {
  45. /* if parameter is zero, turn off flag, if non-zero turn on flag */
  46. ctl_info->log_ce = (simple_strtoul(data, NULL, 0) != 0);
  47. return count;
  48. }
  49. /* 'panic_on_ue' */
  50. static ssize_t edac_device_ctl_panic_on_ue_show(struct edac_device_ctl_info
  51. *ctl_info, char *data)
  52. {
  53. return sprintf(data, "%u\n", ctl_info->panic_on_ue);
  54. }
  55. static ssize_t edac_device_ctl_panic_on_ue_store(struct edac_device_ctl_info
  56. *ctl_info, const char *data,
  57. size_t count)
  58. {
  59. /* if parameter is zero, turn off flag, if non-zero turn on flag */
  60. ctl_info->panic_on_ue = (simple_strtoul(data, NULL, 0) != 0);
  61. return count;
  62. }
  63. /* 'poll_msec' show and store functions*/
  64. static ssize_t edac_device_ctl_poll_msec_show(struct edac_device_ctl_info
  65. *ctl_info, char *data)
  66. {
  67. return sprintf(data, "%u\n", ctl_info->poll_msec);
  68. }
  69. static ssize_t edac_device_ctl_poll_msec_store(struct edac_device_ctl_info
  70. *ctl_info, const char *data,
  71. size_t count)
  72. {
  73. unsigned long value;
  74. /* get the value and enforce that it is non-zero, must be at least
  75. * one millisecond for the delay period, between scans
  76. * Then cancel last outstanding delay for the work request
  77. * and set a new one.
  78. */
  79. value = simple_strtoul(data, NULL, 0);
  80. edac_device_reset_delay_period(ctl_info, value);
  81. return count;
  82. }
  83. /* edac_device_ctl_info specific attribute structure */
  84. struct ctl_info_attribute {
  85. struct attribute attr;
  86. ssize_t(*show) (struct edac_device_ctl_info *, char *);
  87. ssize_t(*store) (struct edac_device_ctl_info *, const char *, size_t);
  88. };
  89. #define to_ctl_info(k) container_of(k, struct edac_device_ctl_info, kobj)
  90. #define to_ctl_info_attr(a) container_of(a,struct ctl_info_attribute,attr)
  91. /* Function to 'show' fields from the edac_dev 'ctl_info' structure */
  92. static ssize_t edac_dev_ctl_info_show(struct kobject *kobj,
  93. struct attribute *attr, char *buffer)
  94. {
  95. struct edac_device_ctl_info *edac_dev = to_ctl_info(kobj);
  96. struct ctl_info_attribute *ctl_info_attr = to_ctl_info_attr(attr);
  97. if (ctl_info_attr->show)
  98. return ctl_info_attr->show(edac_dev, buffer);
  99. return -EIO;
  100. }
  101. /* Function to 'store' fields into the edac_dev 'ctl_info' structure */
  102. static ssize_t edac_dev_ctl_info_store(struct kobject *kobj,
  103. struct attribute *attr,
  104. const char *buffer, size_t count)
  105. {
  106. struct edac_device_ctl_info *edac_dev = to_ctl_info(kobj);
  107. struct ctl_info_attribute *ctl_info_attr = to_ctl_info_attr(attr);
  108. if (ctl_info_attr->store)
  109. return ctl_info_attr->store(edac_dev, buffer, count);
  110. return -EIO;
  111. }
  112. /* edac_dev file operations for an 'ctl_info' */
  113. static struct sysfs_ops device_ctl_info_ops = {
  114. .show = edac_dev_ctl_info_show,
  115. .store = edac_dev_ctl_info_store
  116. };
  117. #define CTL_INFO_ATTR(_name,_mode,_show,_store) \
  118. static struct ctl_info_attribute attr_ctl_info_##_name = { \
  119. .attr = {.name = __stringify(_name), .mode = _mode }, \
  120. .show = _show, \
  121. .store = _store, \
  122. };
  123. /* Declare the various ctl_info attributes here and their respective ops */
  124. CTL_INFO_ATTR(log_ue, S_IRUGO | S_IWUSR,
  125. edac_device_ctl_log_ue_show, edac_device_ctl_log_ue_store);
  126. CTL_INFO_ATTR(log_ce, S_IRUGO | S_IWUSR,
  127. edac_device_ctl_log_ce_show, edac_device_ctl_log_ce_store);
  128. CTL_INFO_ATTR(panic_on_ue, S_IRUGO | S_IWUSR,
  129. edac_device_ctl_panic_on_ue_show,
  130. edac_device_ctl_panic_on_ue_store);
  131. CTL_INFO_ATTR(poll_msec, S_IRUGO | S_IWUSR,
  132. edac_device_ctl_poll_msec_show, edac_device_ctl_poll_msec_store);
  133. /* Base Attributes of the EDAC_DEVICE ECC object */
  134. static struct ctl_info_attribute *device_ctrl_attr[] = {
  135. &attr_ctl_info_panic_on_ue,
  136. &attr_ctl_info_log_ue,
  137. &attr_ctl_info_log_ce,
  138. &attr_ctl_info_poll_msec,
  139. NULL,
  140. };
  141. /* Main DEVICE kobject release() function */
  142. static void edac_device_ctrl_master_release(struct kobject *kobj)
  143. {
  144. struct edac_device_ctl_info *edac_dev;
  145. edac_dev = to_edacdev(kobj);
  146. debugf1("%s()\n", __func__);
  147. complete(&edac_dev->kobj_complete);
  148. }
  149. static struct kobj_type ktype_device_ctrl = {
  150. .release = edac_device_ctrl_master_release,
  151. .sysfs_ops = &device_ctl_info_ops,
  152. .default_attrs = (struct attribute **)device_ctrl_attr,
  153. };
  154. /**************** edac_device main kobj ctor/dtor code *********************/
  155. /*
  156. * edac_device_register_main_kobj
  157. *
  158. * perform the high level setup for the new edac_device instance
  159. *
  160. * Return: 0 SUCCESS
  161. * !0 FAILURE
  162. */
  163. static int edac_device_register_main_kobj(struct edac_device_ctl_info *edac_dev)
  164. {
  165. int err = 0;
  166. struct sysdev_class *edac_class;
  167. debugf1("%s()\n", __func__);
  168. /* get the /sys/devices/system/edac reference */
  169. edac_class = edac_get_edac_class();
  170. if (edac_class == NULL) {
  171. debugf1("%s() no edac_class error=%d\n", __func__, err);
  172. return err;
  173. }
  174. /* Point to the 'edac_class' this instance 'reports' to */
  175. edac_dev->edac_class = edac_class;
  176. /* Init the devices's kobject */
  177. memset(&edac_dev->kobj, 0, sizeof(struct kobject));
  178. edac_dev->kobj.ktype = &ktype_device_ctrl;
  179. /* set this new device under the edac_class kobject */
  180. edac_dev->kobj.parent = &edac_class->kset.kobj;
  181. /* generate sysfs "..../edac/<name>" */
  182. debugf1("%s() set name of kobject to: %s\n", __func__, edac_dev->name);
  183. err = kobject_set_name(&edac_dev->kobj, "%s", edac_dev->name);
  184. if (err)
  185. return err;
  186. err = kobject_register(&edac_dev->kobj);
  187. if (err) {
  188. debugf1("%s()Failed to register '.../edac/%s'\n",
  189. __func__, edac_dev->name);
  190. return err;
  191. }
  192. debugf1("%s() Registered '.../edac/%s' kobject\n",
  193. __func__, edac_dev->name);
  194. return 0;
  195. }
  196. /*
  197. * edac_device_unregister_main_kobj:
  198. * the '..../edac/<name>' kobject
  199. */
  200. static void edac_device_unregister_main_kobj(struct edac_device_ctl_info
  201. *edac_dev)
  202. {
  203. debugf0("%s()\n", __func__);
  204. debugf1("%s() name of kobject is: %s\n",
  205. __func__, kobject_name(&edac_dev->kobj));
  206. init_completion(&edac_dev->kobj_complete);
  207. /*
  208. * Unregister the edac device's kobject and
  209. * wait for reference count to reach 0.
  210. */
  211. kobject_unregister(&edac_dev->kobj);
  212. wait_for_completion(&edac_dev->kobj_complete);
  213. }
  214. /*************** edac_dev -> instance information ***********/
  215. /*
  216. * Set of low-level instance attribute show functions
  217. */
  218. static ssize_t instance_ue_count_show(struct edac_device_instance *instance,
  219. char *data)
  220. {
  221. return sprintf(data, "%u\n", instance->counters.ue_count);
  222. }
  223. static ssize_t instance_ce_count_show(struct edac_device_instance *instance,
  224. char *data)
  225. {
  226. return sprintf(data, "%u\n", instance->counters.ce_count);
  227. }
  228. #define to_instance(k) container_of(k, struct edac_device_instance, kobj)
  229. #define to_instance_attr(a) container_of(a,struct instance_attribute,attr)
  230. /* DEVICE instance kobject release() function */
  231. static void edac_device_ctrl_instance_release(struct kobject *kobj)
  232. {
  233. struct edac_device_instance *instance;
  234. debugf1("%s()\n", __func__);
  235. instance = to_instance(kobj);
  236. complete(&instance->kobj_complete);
  237. }
  238. /* instance specific attribute structure */
  239. struct instance_attribute {
  240. struct attribute attr;
  241. ssize_t(*show) (struct edac_device_instance *, char *);
  242. ssize_t(*store) (struct edac_device_instance *, const char *, size_t);
  243. };
  244. /* Function to 'show' fields from the edac_dev 'instance' structure */
  245. static ssize_t edac_dev_instance_show(struct kobject *kobj,
  246. struct attribute *attr, char *buffer)
  247. {
  248. struct edac_device_instance *instance = to_instance(kobj);
  249. struct instance_attribute *instance_attr = to_instance_attr(attr);
  250. if (instance_attr->show)
  251. return instance_attr->show(instance, buffer);
  252. return -EIO;
  253. }
  254. /* Function to 'store' fields into the edac_dev 'instance' structure */
  255. static ssize_t edac_dev_instance_store(struct kobject *kobj,
  256. struct attribute *attr,
  257. const char *buffer, size_t count)
  258. {
  259. struct edac_device_instance *instance = to_instance(kobj);
  260. struct instance_attribute *instance_attr = to_instance_attr(attr);
  261. if (instance_attr->store)
  262. return instance_attr->store(instance, buffer, count);
  263. return -EIO;
  264. }
  265. /* edac_dev file operations for an 'instance' */
  266. static struct sysfs_ops device_instance_ops = {
  267. .show = edac_dev_instance_show,
  268. .store = edac_dev_instance_store
  269. };
  270. #define INSTANCE_ATTR(_name,_mode,_show,_store) \
  271. static struct instance_attribute attr_instance_##_name = { \
  272. .attr = {.name = __stringify(_name), .mode = _mode }, \
  273. .show = _show, \
  274. .store = _store, \
  275. };
  276. /*
  277. * Define attributes visible for the edac_device instance object
  278. * Each contains a pointer to a show and an optional set
  279. * function pointer that does the low level output/input
  280. */
  281. INSTANCE_ATTR(ce_count, S_IRUGO, instance_ce_count_show, NULL);
  282. INSTANCE_ATTR(ue_count, S_IRUGO, instance_ue_count_show, NULL);
  283. /* list of edac_dev 'instance' attributes */
  284. static struct instance_attribute *device_instance_attr[] = {
  285. &attr_instance_ce_count,
  286. &attr_instance_ue_count,
  287. NULL,
  288. };
  289. /* The 'ktype' for each edac_dev 'instance' */
  290. static struct kobj_type ktype_instance_ctrl = {
  291. .release = edac_device_ctrl_instance_release,
  292. .sysfs_ops = &device_instance_ops,
  293. .default_attrs = (struct attribute **)device_instance_attr,
  294. };
  295. /*************** edac_dev -> instance -> block information *********/
  296. /*
  297. * Set of low-level block attribute show functions
  298. */
  299. static ssize_t block_ue_count_show(struct edac_device_block *block, char *data)
  300. {
  301. return sprintf(data, "%u\n", block->counters.ue_count);
  302. }
  303. static ssize_t block_ce_count_show(struct edac_device_block *block, char *data)
  304. {
  305. return sprintf(data, "%u\n", block->counters.ce_count);
  306. }
  307. #define to_block(k) container_of(k, struct edac_device_block, kobj)
  308. #define to_block_attr(a) container_of(a,struct block_attribute,attr)
  309. /* DEVICE block kobject release() function */
  310. static void edac_device_ctrl_block_release(struct kobject *kobj)
  311. {
  312. struct edac_device_block *block;
  313. debugf1("%s()\n", __func__);
  314. block = to_block(kobj);
  315. complete(&block->kobj_complete);
  316. }
  317. /* block specific attribute structure */
  318. struct block_attribute {
  319. struct attribute attr;
  320. ssize_t(*show) (struct edac_device_block *, char *);
  321. ssize_t(*store) (struct edac_device_block *, const char *, size_t);
  322. };
  323. /* Function to 'show' fields from the edac_dev 'block' structure */
  324. static ssize_t edac_dev_block_show(struct kobject *kobj,
  325. struct attribute *attr, char *buffer)
  326. {
  327. struct edac_device_block *block = to_block(kobj);
  328. struct block_attribute *block_attr = to_block_attr(attr);
  329. if (block_attr->show)
  330. return block_attr->show(block, buffer);
  331. return -EIO;
  332. }
  333. /* Function to 'store' fields into the edac_dev 'block' structure */
  334. static ssize_t edac_dev_block_store(struct kobject *kobj,
  335. struct attribute *attr,
  336. const char *buffer, size_t count)
  337. {
  338. struct edac_device_block *block = to_block(kobj);
  339. struct block_attribute *block_attr = to_block_attr(attr);
  340. if (block_attr->store)
  341. return block_attr->store(block, buffer, count);
  342. return -EIO;
  343. }
  344. /* edac_dev file operations for a 'block' */
  345. static struct sysfs_ops device_block_ops = {
  346. .show = edac_dev_block_show,
  347. .store = edac_dev_block_store
  348. };
  349. #define BLOCK_ATTR(_name,_mode,_show,_store) \
  350. static struct block_attribute attr_block_##_name = { \
  351. .attr = {.name = __stringify(_name), .mode = _mode }, \
  352. .show = _show, \
  353. .store = _store, \
  354. };
  355. BLOCK_ATTR(ce_count, S_IRUGO, block_ce_count_show, NULL);
  356. BLOCK_ATTR(ue_count, S_IRUGO, block_ue_count_show, NULL);
  357. /* list of edac_dev 'block' attributes */
  358. static struct block_attribute *device_block_attr[] = {
  359. &attr_block_ce_count,
  360. &attr_block_ue_count,
  361. NULL,
  362. };
  363. /* The 'ktype' for each edac_dev 'block' */
  364. static struct kobj_type ktype_block_ctrl = {
  365. .release = edac_device_ctrl_block_release,
  366. .sysfs_ops = &device_block_ops,
  367. .default_attrs = (struct attribute **)device_block_attr,
  368. };
  369. /************** block ctor/dtor code ************/
  370. /*
  371. * edac_device_create_block
  372. */
  373. static int edac_device_create_block(struct edac_device_ctl_info *edac_dev,
  374. struct edac_device_instance *instance,
  375. int idx)
  376. {
  377. int i;
  378. int err;
  379. struct edac_device_block *block;
  380. struct edac_dev_sysfs_block_attribute *sysfs_attrib;
  381. block = &instance->blocks[idx];
  382. debugf1("%s() Instance '%s' block[%d] '%s'\n",
  383. __func__, instance->name, idx, block->name);
  384. /* init this block's kobject */
  385. memset(&block->kobj, 0, sizeof(struct kobject));
  386. block->kobj.parent = &instance->kobj;
  387. block->kobj.ktype = &ktype_block_ctrl;
  388. err = kobject_set_name(&block->kobj, "%s", block->name);
  389. if (err)
  390. return err;
  391. err = kobject_register(&block->kobj);
  392. if (err) {
  393. debugf1("%s()Failed to register instance '%s'\n",
  394. __func__, block->name);
  395. return err;
  396. }
  397. /* If there are driver level block attributes, then added them
  398. * to the block kobject
  399. */
  400. sysfs_attrib = block->block_attributes;
  401. if (sysfs_attrib != NULL) {
  402. for (i = 0; i < block->nr_attribs; i++) {
  403. err = sysfs_create_file(&block->kobj,
  404. (struct attribute *) &sysfs_attrib[i]);
  405. if (err)
  406. goto err_on_attrib;
  407. sysfs_attrib++;
  408. }
  409. }
  410. return 0;
  411. err_on_attrib:
  412. kobject_unregister(&block->kobj);
  413. return err;
  414. }
  415. /*
  416. * edac_device_delete_block(edac_dev,j);
  417. */
  418. static void edac_device_delete_block(struct edac_device_ctl_info *edac_dev,
  419. struct edac_device_instance *instance,
  420. int idx)
  421. {
  422. struct edac_device_block *block;
  423. block = &instance->blocks[idx];
  424. /* unregister this block's kobject */
  425. init_completion(&block->kobj_complete);
  426. kobject_unregister(&block->kobj);
  427. wait_for_completion(&block->kobj_complete);
  428. }
  429. /************** instance ctor/dtor code ************/
  430. /*
  431. * edac_device_create_instance
  432. * create just one instance of an edac_device 'instance'
  433. */
  434. static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
  435. int idx)
  436. {
  437. int i, j;
  438. int err;
  439. struct edac_device_instance *instance;
  440. instance = &edac_dev->instances[idx];
  441. /* Init the instance's kobject */
  442. memset(&instance->kobj, 0, sizeof(struct kobject));
  443. /* set this new device under the edac_device main kobject */
  444. instance->kobj.parent = &edac_dev->kobj;
  445. instance->kobj.ktype = &ktype_instance_ctrl;
  446. err = kobject_set_name(&instance->kobj, "%s", instance->name);
  447. if (err)
  448. return err;
  449. err = kobject_register(&instance->kobj);
  450. if (err != 0) {
  451. debugf2("%s() Failed to register instance '%s'\n",
  452. __func__, instance->name);
  453. return err;
  454. }
  455. debugf1("%s() now register '%d' blocks for instance %d\n",
  456. __func__, instance->nr_blocks, idx);
  457. /* register all blocks of this instance */
  458. for (i = 0; i < instance->nr_blocks; i++) {
  459. err = edac_device_create_block(edac_dev, instance, i);
  460. if (err) {
  461. for (j = 0; j < i; j++)
  462. edac_device_delete_block(edac_dev, instance, j);
  463. return err;
  464. }
  465. }
  466. debugf1("%s() Registered instance %d '%s' kobject\n",
  467. __func__, idx, instance->name);
  468. return 0;
  469. }
  470. /*
  471. * edac_device_remove_instance
  472. * remove an edac_device instance
  473. */
  474. static void edac_device_delete_instance(struct edac_device_ctl_info *edac_dev,
  475. int idx)
  476. {
  477. int i;
  478. struct edac_device_instance *instance;
  479. instance = &edac_dev->instances[idx];
  480. /* unregister all blocks in this instance */
  481. for (i = 0; i < instance->nr_blocks; i++)
  482. edac_device_delete_block(edac_dev, instance, i);
  483. /* unregister this instance's kobject */
  484. init_completion(&instance->kobj_complete);
  485. kobject_unregister(&instance->kobj);
  486. wait_for_completion(&instance->kobj_complete);
  487. }
  488. /*
  489. * edac_device_create_instances
  490. * create the first level of 'instances' for this device
  491. * (ie 'cache' might have 'cache0', 'cache1', 'cache2', etc
  492. */
  493. static int edac_device_create_instances(struct edac_device_ctl_info *edac_dev)
  494. {
  495. int i, j;
  496. int err;
  497. debugf0("%s()\n", __func__);
  498. /* iterate over creation of the instances */
  499. for (i = 0; i < edac_dev->nr_instances; i++) {
  500. err = edac_device_create_instance(edac_dev, i);
  501. if (err) {
  502. /* unwind previous instances on error */
  503. for (j = 0; j < i; j++)
  504. edac_device_delete_instance(edac_dev, j);
  505. return err;
  506. }
  507. }
  508. return 0;
  509. }
  510. /*
  511. * edac_device_delete_instances(edac_dev);
  512. * unregister all the kobjects of the instances
  513. */
  514. static void edac_device_delete_instances(struct edac_device_ctl_info *edac_dev)
  515. {
  516. int i;
  517. /* iterate over creation of the instances */
  518. for (i = 0; i < edac_dev->nr_instances; i++)
  519. edac_device_delete_instance(edac_dev, i);
  520. }
  521. /******************* edac_dev sysfs ctor/dtor code *************/
  522. /*
  523. * edac_device_add_sysfs_attributes
  524. * add some attributes to this instance's main kobject
  525. */
  526. static int edac_device_add_sysfs_attributes(
  527. struct edac_device_ctl_info *edac_dev)
  528. {
  529. int err;
  530. struct edac_dev_sysfs_attribute *sysfs_attrib;
  531. /* point to the start of the array and iterate over it
  532. * adding each attribute listed to this mci instance's kobject
  533. */
  534. sysfs_attrib = edac_dev->sysfs_attributes;
  535. while (sysfs_attrib->attr.name != NULL) {
  536. err = sysfs_create_file(&edac_dev->kobj,
  537. (struct attribute*) sysfs_attrib);
  538. if (err)
  539. return err;
  540. sysfs_attrib++;
  541. }
  542. return 0;
  543. }
  544. /*
  545. * edac_device_create_sysfs() Constructor
  546. *
  547. * Create a new edac_device kobject instance,
  548. *
  549. * Return:
  550. * 0 Success
  551. * !0 Failure
  552. */
  553. int edac_device_create_sysfs(struct edac_device_ctl_info *edac_dev)
  554. {
  555. int err;
  556. struct kobject *edac_kobj = &edac_dev->kobj;
  557. /* register this instance's main kobj with the edac class kobj */
  558. err = edac_device_register_main_kobj(edac_dev);
  559. if (err)
  560. return err;
  561. debugf0("%s() idx=%d\n", __func__, edac_dev->dev_idx);
  562. /* If the low level driver requests some sysfs entries
  563. * then go create them here
  564. */
  565. if (edac_dev->sysfs_attributes != NULL) {
  566. err = edac_device_add_sysfs_attributes(edac_dev);
  567. if (err) {
  568. debugf0("%s() failed to add sysfs attribs\n",
  569. __func__);
  570. goto err_unreg_object;
  571. }
  572. }
  573. /* create a symlink from the edac device
  574. * to the platform 'device' being used for this
  575. */
  576. err = sysfs_create_link(edac_kobj,
  577. &edac_dev->dev->kobj, EDAC_DEVICE_SYMLINK);
  578. if (err) {
  579. debugf0("%s() sysfs_create_link() returned err= %d\n",
  580. __func__, err);
  581. goto err_unreg_object;
  582. }
  583. debugf0("%s() calling create-instances, idx=%d\n",
  584. __func__, edac_dev->dev_idx);
  585. /* Create the first level instance directories */
  586. err = edac_device_create_instances(edac_dev);
  587. if (err)
  588. goto err_remove_link;
  589. return 0;
  590. /* Error unwind stack */
  591. err_remove_link:
  592. /* remove the sym link */
  593. sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK);
  594. err_unreg_object:
  595. edac_device_unregister_main_kobj(edac_dev);
  596. return err;
  597. }
  598. /*
  599. * edac_device_remove_sysfs() destructor
  600. *
  601. * remove a edac_device instance
  602. */
  603. void edac_device_remove_sysfs(struct edac_device_ctl_info *edac_dev)
  604. {
  605. debugf0("%s()\n", __func__);
  606. edac_device_delete_instances(edac_dev);
  607. /* remove the sym link */
  608. sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK);
  609. /* unregister the instance's main kobj */
  610. edac_device_unregister_main_kobj(edac_dev);
  611. }