aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/edac_device_sysfs.c
diff options
context:
space:
mode:
authorDouglas Thompson <dougthompson@xmission.com>2007-07-19 04:50:29 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-19 13:04:57 -0400
commit1c3631ff1f805cb72644fcde02b7c58950f21cd5 (patch)
tree2d0f8867f21cf2dedb7d94a262028898333583f4 /drivers/edac/edac_device_sysfs.c
parent8096cfafbb7ad3cb1a286ae7e8086167f4ebb4b6 (diff)
drivers/edac: fix edac_device sysfs completion code
With feedback, this patch corrects operation of the kobject release operation on kobjects, attributes and controls for the edac_device. Cc: Alan Cox alan@lxorguk.ukuu.org.uk Signed-off-by: Doug Thompson <dougthompson@xmission.com> Acked-by: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/edac/edac_device_sysfs.c')
-rw-r--r--drivers/edac/edac_device_sysfs.c341
1 files changed, 239 insertions, 102 deletions
diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c
index 235b4c79355d..52769ae69bd2 100644
--- a/drivers/edac/edac_device_sysfs.c
+++ b/drivers/edac/edac_device_sysfs.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * file for managing the edac_device class of devices for EDAC 2 * file for managing the edac_device class of devices for EDAC
3 * 3 *
4 * (C) 2007 SoftwareBitMaker(http://www.softwarebitmaker.com) 4 * (C) 2007 SoftwareBitMaker (http://www.softwarebitmaker.com)
5 *
5 * This file may be distributed under the terms of the 6 * This file may be distributed under the terms of the
6 * GNU General Public License. 7 * GNU General Public License.
7 * 8 *
@@ -10,6 +11,7 @@
10 */ 11 */
11 12
12#include <linux/ctype.h> 13#include <linux/ctype.h>
14#include <linux/module.h>
13 15
14#include "edac_core.h" 16#include "edac_core.h"
15#include "edac_module.h" 17#include "edac_module.h"
@@ -19,7 +21,6 @@
19#define to_edacdev(k) container_of(k, struct edac_device_ctl_info, kobj) 21#define to_edacdev(k) container_of(k, struct edac_device_ctl_info, kobj)
20#define to_edacdev_attr(a) container_of(a, struct edacdev_attribute, attr) 22#define to_edacdev_attr(a) container_of(a, struct edacdev_attribute, attr)
21 23
22/************************** edac_device sysfs code and data **************/
23 24
24/* 25/*
25 * Set of edac_device_ctl_info attribute store/show functions 26 * Set of edac_device_ctl_info attribute store/show functions
@@ -103,8 +104,8 @@ static ssize_t edac_device_ctl_poll_msec_store(struct edac_device_ctl_info
103/* edac_device_ctl_info specific attribute structure */ 104/* edac_device_ctl_info specific attribute structure */
104struct ctl_info_attribute { 105struct ctl_info_attribute {
105 struct attribute attr; 106 struct attribute attr;
106 ssize_t(*show) (struct edac_device_ctl_info *, char *); 107 ssize_t(*show) (struct edac_device_ctl_info *, char *);
107 ssize_t(*store) (struct edac_device_ctl_info *, const char *, size_t); 108 ssize_t(*store) (struct edac_device_ctl_info *, const char *, size_t);
108}; 109};
109 110
110#define to_ctl_info(k) container_of(k, struct edac_device_ctl_info, kobj) 111#define to_ctl_info(k) container_of(k, struct edac_device_ctl_info, kobj)
@@ -168,45 +169,76 @@ static struct ctl_info_attribute *device_ctrl_attr[] = {
168 NULL, 169 NULL,
169}; 170};
170 171
171/* Main DEVICE kobject release() function */ 172/*
173 * edac_device_ctrl_master_release
174 *
175 * called when the reference count for the 'main' kobj
176 * for a edac_device control struct reaches zero
177 *
178 * Reference count model:
179 * One 'main' kobject for each control structure allocated.
180 * That main kobj is initially set to one AND
181 * the reference count for the EDAC 'core' module is
182 * bumped by one, thus added 'keep in memory' dependency.
183 *
184 * Each new internal kobj (in instances and blocks) then
185 * bumps the 'main' kobject.
186 *
187 * When they are released their release functions decrement
188 * the 'main' kobj.
189 *
190 * When the main kobj reaches zero (0) then THIS function
191 * is called which then decrements the EDAC 'core' module.
192 * When the module reference count reaches zero then the
193 * module no longer has dependency on keeping the release
194 * function code in memory and module can be unloaded.
195 *
196 * This will support several control objects as well, each
197 * with its own 'main' kobj.
198 */
172static void edac_device_ctrl_master_release(struct kobject *kobj) 199static void edac_device_ctrl_master_release(struct kobject *kobj)
173{ 200{
174 struct edac_device_ctl_info *edac_dev; 201 struct edac_device_ctl_info *edac_dev = to_edacdev(kobj);
175 202
176 edac_dev = to_edacdev(kobj); 203 debugf1("%s() control index=%d\n", __func__, edac_dev->dev_idx);
177 204
178 debugf1("%s()\n", __func__); 205 /* decrement the EDAC CORE module ref count */
179 complete(&edac_dev->kobj_complete); 206 module_put(edac_dev->owner);
207
208 /* free the control struct containing the 'main' kobj
209 * passed in to this routine
210 */
211 kfree(edac_dev);
180} 212}
181 213
214/* ktype for the main (master) kobject */
182static struct kobj_type ktype_device_ctrl = { 215static struct kobj_type ktype_device_ctrl = {
183 .release = edac_device_ctrl_master_release, 216 .release = edac_device_ctrl_master_release,
184 .sysfs_ops = &device_ctl_info_ops, 217 .sysfs_ops = &device_ctl_info_ops,
185 .default_attrs = (struct attribute **)device_ctrl_attr, 218 .default_attrs = (struct attribute **)device_ctrl_attr,
186}; 219};
187 220
188/**************** edac_device main kobj ctor/dtor code *********************/
189
190/* 221/*
191 * edac_device_register_main_kobj 222 * edac_device_register_sysfs_main_kobj
192 * 223 *
193 * perform the high level setup for the new edac_device instance 224 * perform the high level setup for the new edac_device instance
194 * 225 *
195 * Return: 0 SUCCESS 226 * Return: 0 SUCCESS
196 * !0 FAILURE 227 * !0 FAILURE
197 */ 228 */
198static int edac_device_register_main_kobj(struct edac_device_ctl_info *edac_dev) 229int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
199{ 230{
200 int err = 0;
201 struct sysdev_class *edac_class; 231 struct sysdev_class *edac_class;
232 int err;
202 233
203 debugf1("%s()\n", __func__); 234 debugf1("%s()\n", __func__);
204 235
205 /* get the /sys/devices/system/edac reference */ 236 /* get the /sys/devices/system/edac reference */
206 edac_class = edac_get_edac_class(); 237 edac_class = edac_get_edac_class();
207 if (edac_class == NULL) { 238 if (edac_class == NULL) {
208 debugf1("%s() no edac_class error=%d\n", __func__, err); 239 debugf1("%s() no edac_class error\n", __func__);
209 return err; 240 err = -ENODEV;
241 goto err_out;
210 } 242 }
211 243
212 /* Point to the 'edac_class' this instance 'reports' to */ 244 /* Point to the 'edac_class' this instance 'reports' to */
@@ -223,42 +255,65 @@ static int edac_device_register_main_kobj(struct edac_device_ctl_info *edac_dev)
223 debugf1("%s() set name of kobject to: %s\n", __func__, edac_dev->name); 255 debugf1("%s() set name of kobject to: %s\n", __func__, edac_dev->name);
224 err = kobject_set_name(&edac_dev->kobj, "%s", edac_dev->name); 256 err = kobject_set_name(&edac_dev->kobj, "%s", edac_dev->name);
225 if (err) 257 if (err)
226 return err; 258 goto err_out;
259
260 /* Record which module 'owns' this control structure
261 * and bump the ref count of the module
262 */
263 edac_dev->owner = THIS_MODULE;
264
265 if (!try_module_get(edac_dev->owner)) {
266 err = -ENODEV;
267 goto err_out;
268 }
269
270 /* register */
227 err = kobject_register(&edac_dev->kobj); 271 err = kobject_register(&edac_dev->kobj);
228 if (err) { 272 if (err) {
229 debugf1("%s()Failed to register '.../edac/%s'\n", 273 debugf1("%s()Failed to register '.../edac/%s'\n",
230 __func__, edac_dev->name); 274 __func__, edac_dev->name);
231 return err; 275 goto err_kobj_reg;
232 } 276 }
233 277
278 /* At this point, to 'free' the control struct,
279 * edac_device_unregister_sysfs_main_kobj() must be used
280 */
281
234 debugf1("%s() Registered '.../edac/%s' kobject\n", 282 debugf1("%s() Registered '.../edac/%s' kobject\n",
235 __func__, edac_dev->name); 283 __func__, edac_dev->name);
236 284
237 return 0; 285 return 0;
286
287 /* Error exit stack */
288err_kobj_reg:
289 module_put(edac_dev->owner);
290
291err_out:
292 return err;
238} 293}
239 294
240/* 295/*
241 * edac_device_unregister_main_kobj: 296 * edac_device_unregister_sysfs_main_kobj:
242 * the '..../edac/<name>' kobject 297 * the '..../edac/<name>' kobject
243 */ 298 */
244static void edac_device_unregister_main_kobj(struct edac_device_ctl_info 299void edac_device_unregister_sysfs_main_kobj(
245 *edac_dev) 300 struct edac_device_ctl_info *edac_dev)
246{ 301{
247 debugf0("%s()\n", __func__); 302 debugf0("%s()\n", __func__);
248 debugf1("%s() name of kobject is: %s\n", 303 debugf1("%s() name of kobject is: %s\n",
249 __func__, kobject_name(&edac_dev->kobj)); 304 __func__, kobject_name(&edac_dev->kobj));
250 305
251 init_completion(&edac_dev->kobj_complete);
252
253 /* 306 /*
254 * Unregister the edac device's kobject and 307 * Unregister the edac device's kobject and
255 * wait for reference count to reach 0. 308 * allow for reference count to reach 0 at which point
309 * the callback will be called to:
310 * a) module_put() this module
311 * b) 'kfree' the memory
256 */ 312 */
257 kobject_unregister(&edac_dev->kobj); 313 kobject_unregister(&edac_dev->kobj);
258 wait_for_completion(&edac_dev->kobj_complete);
259} 314}
260 315
261/*************** edac_dev -> instance information ***********/ 316/* edac_dev -> instance information */
262 317
263/* 318/*
264 * Set of low-level instance attribute show functions 319 * Set of low-level instance attribute show functions
@@ -285,8 +340,11 @@ static void edac_device_ctrl_instance_release(struct kobject *kobj)
285 340
286 debugf1("%s()\n", __func__); 341 debugf1("%s()\n", __func__);
287 342
343 /* map from this kobj to the main control struct
344 * and then dec the main kobj count
345 */
288 instance = to_instance(kobj); 346 instance = to_instance(kobj);
289 complete(&instance->kobj_complete); 347 kobject_put(&instance->ctl->kobj);
290} 348}
291 349
292/* instance specific attribute structure */ 350/* instance specific attribute structure */
@@ -356,7 +414,7 @@ static struct kobj_type ktype_instance_ctrl = {
356 .default_attrs = (struct attribute **)device_instance_attr, 414 .default_attrs = (struct attribute **)device_instance_attr,
357}; 415};
358 416
359/*************** edac_dev -> instance -> block information *********/ 417/* edac_dev -> instance -> block information */
360 418
361/* 419/*
362 * Set of low-level block attribute show functions 420 * Set of low-level block attribute show functions
@@ -381,8 +439,13 @@ static void edac_device_ctrl_block_release(struct kobject *kobj)
381 439
382 debugf1("%s()\n", __func__); 440 debugf1("%s()\n", __func__);
383 441
442 /* get the container of the kobj */
384 block = to_block(kobj); 443 block = to_block(kobj);
385 complete(&block->kobj_complete); 444
445 /* map from 'block kobj' to 'block->instance->controller->main_kobj'
446 * now 'release' the block kobject
447 */
448 kobject_put(&block->instance->ctl->kobj);
386} 449}
387 450
388/* block specific attribute structure */ 451/* block specific attribute structure */
@@ -447,49 +510,60 @@ static struct kobj_type ktype_block_ctrl = {
447 .default_attrs = (struct attribute **)device_block_attr, 510 .default_attrs = (struct attribute **)device_block_attr,
448}; 511};
449 512
450/************** block ctor/dtor code ************/ 513/* block ctor/dtor code */
451 514
452/* 515/*
453 * edac_device_create_block 516 * edac_device_create_block
454 */ 517 */
455static int edac_device_create_block(struct edac_device_ctl_info *edac_dev, 518static int edac_device_create_block(struct edac_device_ctl_info *edac_dev,
456 struct edac_device_instance *instance, 519 struct edac_device_instance *instance,
457 int idx) 520 struct edac_device_block *block)
458{ 521{
459 int i; 522 int i;
460 int err; 523 int err;
461 struct edac_device_block *block;
462 struct edac_dev_sysfs_block_attribute *sysfs_attrib; 524 struct edac_dev_sysfs_block_attribute *sysfs_attrib;
525 struct kobject *main_kobj;
463 526
464 block = &instance->blocks[idx]; 527 debugf1("%s() Instance '%s' block '%s'\n",
465 528 __func__, instance->name, block->name);
466 debugf1("%s() Instance '%s' block[%d] '%s'\n",
467 __func__, instance->name, idx, block->name);
468 529
469 /* init this block's kobject */ 530 /* init this block's kobject */
470 memset(&block->kobj, 0, sizeof(struct kobject)); 531 memset(&block->kobj, 0, sizeof(struct kobject));
471 block->kobj.parent = &instance->kobj; 532 block->kobj.parent = &instance->kobj;
472 block->kobj.ktype = &ktype_block_ctrl; 533 block->kobj.ktype = &ktype_block_ctrl;
534 block->instance = instance;
473 535
474 err = kobject_set_name(&block->kobj, "%s", block->name); 536 err = kobject_set_name(&block->kobj, "%s", block->name);
475 if (err) 537 if (err)
476 return err; 538 return err;
477 539
540 /* bump the main kobject's reference count for this controller
541 * and this instance is dependant on the main
542 */
543 main_kobj = kobject_get(&edac_dev->kobj);
544 if (!main_kobj) {
545 err = -ENODEV;
546 goto err_out;
547 }
548
549 /* Add this block's kobject */
478 err = kobject_register(&block->kobj); 550 err = kobject_register(&block->kobj);
479 if (err) { 551 if (err) {
480 debugf1("%s()Failed to register instance '%s'\n", 552 debugf1("%s() Failed to register instance '%s'\n",
481 __func__, block->name); 553 __func__, block->name);
482 return err; 554 kobject_put(main_kobj);
555 err = -ENODEV;
556 goto err_out;
483 } 557 }
484 558
485 /* If there are driver level block attributes, then added them 559 /* If there are driver level block attributes, then added them
486 * to the block kobject 560 * to the block kobject
487 */ 561 */
488 sysfs_attrib = block->block_attributes; 562 sysfs_attrib = block->block_attributes;
489 if (sysfs_attrib != NULL) { 563 if (sysfs_attrib) {
490 for (i = 0; i < block->nr_attribs; i++) { 564 for (i = 0; i < block->nr_attribs; i++) {
491 err = sysfs_create_file(&block->kobj, 565 err = sysfs_create_file(&block->kobj,
492 (struct attribute *) &sysfs_attrib[i]); 566 (struct attribute *) sysfs_attrib);
493 if (err) 567 if (err)
494 goto err_on_attrib; 568 goto err_on_attrib;
495 569
@@ -499,30 +573,41 @@ static int edac_device_create_block(struct edac_device_ctl_info *edac_dev,
499 573
500 return 0; 574 return 0;
501 575
576 /* Error unwind stack */
502err_on_attrib: 577err_on_attrib:
503 kobject_unregister(&block->kobj); 578 kobject_unregister(&block->kobj);
504 579
580err_out:
505 return err; 581 return err;
506} 582}
507 583
508/* 584/*
509 * edac_device_delete_block(edac_dev,j); 585 * edac_device_delete_block(edac_dev,block);
510 */ 586 */
511static void edac_device_delete_block(struct edac_device_ctl_info *edac_dev, 587static void edac_device_delete_block(struct edac_device_ctl_info *edac_dev,
512 struct edac_device_instance *instance, 588 struct edac_device_block *block)
513 int idx)
514{ 589{
515 struct edac_device_block *block; 590 struct edac_dev_sysfs_block_attribute *sysfs_attrib;
591 int i;
516 592
517 block = &instance->blocks[idx]; 593 /* if this block has 'attributes' then we need to iterate over the list
594 * and 'remove' the attributes on this block
595 */
596 sysfs_attrib = block->block_attributes;
597 if (sysfs_attrib && block->nr_attribs) {
598 for (i = 0; i < block->nr_attribs; i++) {
599 sysfs_remove_file(&block->kobj,
600 (struct attribute *) sysfs_attrib);
601 }
602 }
518 603
519 /* unregister this block's kobject */ 604 /* unregister this block's kobject, SEE:
520 init_completion(&block->kobj_complete); 605 * edac_device_ctrl_block_release() callback operation
606 */
521 kobject_unregister(&block->kobj); 607 kobject_unregister(&block->kobj);
522 wait_for_completion(&block->kobj_complete);
523} 608}
524 609
525/************** instance ctor/dtor code ************/ 610/* instance ctor/dtor code */
526 611
527/* 612/*
528 * edac_device_create_instance 613 * edac_device_create_instance
@@ -534,6 +619,7 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
534 int i, j; 619 int i, j;
535 int err; 620 int err;
536 struct edac_device_instance *instance; 621 struct edac_device_instance *instance;
622 struct kobject *main_kobj;
537 623
538 instance = &edac_dev->instances[idx]; 624 instance = &edac_dev->instances[idx];
539 625
@@ -543,16 +629,28 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
543 /* set this new device under the edac_device main kobject */ 629 /* set this new device under the edac_device main kobject */
544 instance->kobj.parent = &edac_dev->kobj; 630 instance->kobj.parent = &edac_dev->kobj;
545 instance->kobj.ktype = &ktype_instance_ctrl; 631 instance->kobj.ktype = &ktype_instance_ctrl;
632 instance->ctl = edac_dev;
546 633
547 err = kobject_set_name(&instance->kobj, "%s", instance->name); 634 err = kobject_set_name(&instance->kobj, "%s", instance->name);
548 if (err) 635 if (err)
549 return err; 636 goto err_out;
637
638 /* bump the main kobject's reference count for this controller
639 * and this instance is dependant on the main
640 */
641 main_kobj = kobject_get(&edac_dev->kobj);
642 if (!main_kobj) {
643 err = -ENODEV;
644 goto err_out;
645 }
550 646
647 /* Formally register this instance's kobject */
551 err = kobject_register(&instance->kobj); 648 err = kobject_register(&instance->kobj);
552 if (err != 0) { 649 if (err != 0) {
553 debugf2("%s() Failed to register instance '%s'\n", 650 debugf2("%s() Failed to register instance '%s'\n",
554 __func__, instance->name); 651 __func__, instance->name);
555 return err; 652 kobject_put(main_kobj);
653 goto err_out;
556 } 654 }
557 655
558 debugf1("%s() now register '%d' blocks for instance %d\n", 656 debugf1("%s() now register '%d' blocks for instance %d\n",
@@ -560,11 +658,14 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
560 658
561 /* register all blocks of this instance */ 659 /* register all blocks of this instance */
562 for (i = 0; i < instance->nr_blocks; i++) { 660 for (i = 0; i < instance->nr_blocks; i++) {
563 err = edac_device_create_block(edac_dev, instance, i); 661 err = edac_device_create_block(edac_dev, instance,
662 &instance->blocks[i]);
564 if (err) { 663 if (err) {
664 /* If any fail, remove all previous ones */
565 for (j = 0; j < i; j++) 665 for (j = 0; j < i; j++)
566 edac_device_delete_block(edac_dev, instance, j); 666 edac_device_delete_block(edac_dev,
567 return err; 667 &instance->blocks[j]);
668 goto err_release_instance_kobj;
568 } 669 }
569 } 670 }
570 671
@@ -572,6 +673,13 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
572 __func__, idx, instance->name); 673 __func__, idx, instance->name);
573 674
574 return 0; 675 return 0;
676
677 /* error unwind stack */
678err_release_instance_kobj:
679 kobject_unregister(&instance->kobj);
680
681err_out:
682 return err;
575} 683}
576 684
577/* 685/*
@@ -581,19 +689,19 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
581static void edac_device_delete_instance(struct edac_device_ctl_info *edac_dev, 689static void edac_device_delete_instance(struct edac_device_ctl_info *edac_dev,
582 int idx) 690 int idx)
583{ 691{
584 int i;
585 struct edac_device_instance *instance; 692 struct edac_device_instance *instance;
693 int i;
586 694
587 instance = &edac_dev->instances[idx]; 695 instance = &edac_dev->instances[idx];
588 696
589 /* unregister all blocks in this instance */ 697 /* unregister all blocks in this instance */
590 for (i = 0; i < instance->nr_blocks; i++) 698 for (i = 0; i < instance->nr_blocks; i++)
591 edac_device_delete_block(edac_dev, instance, i); 699 edac_device_delete_block(edac_dev, &instance->blocks[i]);
592 700
593 /* unregister this instance's kobject */ 701 /* unregister this instance's kobject, SEE:
594 init_completion(&instance->kobj_complete); 702 * edac_device_ctrl_instance_release() for callback operation
703 */
595 kobject_unregister(&instance->kobj); 704 kobject_unregister(&instance->kobj);
596 wait_for_completion(&instance->kobj_complete);
597} 705}
598 706
599/* 707/*
@@ -635,39 +743,69 @@ static void edac_device_delete_instances(struct edac_device_ctl_info *edac_dev)
635 edac_device_delete_instance(edac_dev, i); 743 edac_device_delete_instance(edac_dev, i);
636} 744}
637 745
638/******************* edac_dev sysfs ctor/dtor code *************/ 746/* edac_dev sysfs ctor/dtor code */
639 747
640/* 748/*
641 * edac_device_add_sysfs_attributes 749 * edac_device_add_main_sysfs_attributes
642 * add some attributes to this instance's main kobject 750 * add some attributes to this instance's main kobject
643 */ 751 */
644static int edac_device_add_sysfs_attributes( 752static int edac_device_add_main_sysfs_attributes(
645 struct edac_device_ctl_info *edac_dev) 753 struct edac_device_ctl_info *edac_dev)
646{ 754{
647 int err;
648 struct edac_dev_sysfs_attribute *sysfs_attrib; 755 struct edac_dev_sysfs_attribute *sysfs_attrib;
756 int err = 0;
649 757
650 /* point to the start of the array and iterate over it
651 * adding each attribute listed to this mci instance's kobject
652 */
653 sysfs_attrib = edac_dev->sysfs_attributes; 758 sysfs_attrib = edac_dev->sysfs_attributes;
654 759 if (sysfs_attrib) {
655 while (sysfs_attrib->attr.name != NULL) { 760 /* iterate over the array and create an attribute for each
656 err = sysfs_create_file(&edac_dev->kobj, 761 * entry in the list
762 */
763 while (sysfs_attrib->attr.name != NULL) {
764 err = sysfs_create_file(&edac_dev->kobj,
657 (struct attribute*) sysfs_attrib); 765 (struct attribute*) sysfs_attrib);
658 if (err) 766 if (err)
659 return err; 767 goto err_out;
660 768
661 sysfs_attrib++; 769 sysfs_attrib++;
770 }
662 } 771 }
663 772
664 return 0; 773err_out:
774 return err;
775}
776
777/*
778 * edac_device_remove_main_sysfs_attributes
779 * remove any attributes to this instance's main kobject
780 */
781static void edac_device_remove_main_sysfs_attributes(
782 struct edac_device_ctl_info *edac_dev)
783{
784 struct edac_dev_sysfs_attribute *sysfs_attrib;
785
786 /* if there are main attributes, defined, remove them. First,
787 * point to the start of the array and iterate over it
788 * removing each attribute listed from this device's instance's kobject
789 */
790 sysfs_attrib = edac_dev->sysfs_attributes;
791 if (sysfs_attrib) {
792 while (sysfs_attrib->attr.name != NULL) {
793 sysfs_remove_file(&edac_dev->kobj,
794 (struct attribute *) sysfs_attrib);
795 sysfs_attrib++;
796 }
797 }
665} 798}
666 799
667/* 800/*
668 * edac_device_create_sysfs() Constructor 801 * edac_device_create_sysfs() Constructor
669 * 802 *
670 * Create a new edac_device kobject instance, 803 * accept a created edac_device control structure
804 * and 'export' it to sysfs. The 'main' kobj should already have been
805 * created. 'instance' and 'block' kobjects should be registered
806 * along with any 'block' attributes from the low driver. In addition,
807 * the main attributes (if any) are connected to the main kobject of
808 * the control structure.
671 * 809 *
672 * Return: 810 * Return:
673 * 0 Success 811 * 0 Success
@@ -678,23 +816,13 @@ int edac_device_create_sysfs(struct edac_device_ctl_info *edac_dev)
678 int err; 816 int err;
679 struct kobject *edac_kobj = &edac_dev->kobj; 817 struct kobject *edac_kobj = &edac_dev->kobj;
680 818
681 /* register this instance's main kobj with the edac class kobj */
682 err = edac_device_register_main_kobj(edac_dev);
683 if (err)
684 return err;
685
686 debugf0("%s() idx=%d\n", __func__, edac_dev->dev_idx); 819 debugf0("%s() idx=%d\n", __func__, edac_dev->dev_idx);
687 820
688 /* If the low level driver requests some sysfs entries 821 /* go create any main attributes callers wants */
689 * then go create them here 822 err = edac_device_add_main_sysfs_attributes(edac_dev);
690 */ 823 if (err) {
691 if (edac_dev->sysfs_attributes != NULL) { 824 debugf0("%s() failed to add sysfs attribs\n", __func__);
692 err = edac_device_add_sysfs_attributes(edac_dev); 825 goto err_out;
693 if (err) {
694 debugf0("%s() failed to add sysfs attribs\n",
695 __func__);
696 goto err_unreg_object;
697 }
698 } 826 }
699 827
700 /* create a symlink from the edac device 828 /* create a symlink from the edac device
@@ -705,16 +833,23 @@ int edac_device_create_sysfs(struct edac_device_ctl_info *edac_dev)
705 if (err) { 833 if (err) {
706 debugf0("%s() sysfs_create_link() returned err= %d\n", 834 debugf0("%s() sysfs_create_link() returned err= %d\n",
707 __func__, err); 835 __func__, err);
708 goto err_unreg_object; 836 goto err_remove_main_attribs;
709 } 837 }
710 838
711 debugf0("%s() calling create-instances, idx=%d\n", 839 /* Create the first level instance directories
712 __func__, edac_dev->dev_idx); 840 * In turn, the nested blocks beneath the instances will
713 841 * be registered as well
714 /* Create the first level instance directories */ 842 */
715 err = edac_device_create_instances(edac_dev); 843 err = edac_device_create_instances(edac_dev);
716 if (err) 844 if (err) {
845 debugf0("%s() edac_device_create_instances() "
846 "returned err= %d\n", __func__, err);
717 goto err_remove_link; 847 goto err_remove_link;
848 }
849
850
851 debugf0("%s() calling create-instances, idx=%d\n",
852 __func__, edac_dev->dev_idx);
718 853
719 return 0; 854 return 0;
720 855
@@ -723,26 +858,28 @@ err_remove_link:
723 /* remove the sym link */ 858 /* remove the sym link */
724 sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK); 859 sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK);
725 860
726err_unreg_object: 861err_remove_main_attribs:
727 edac_device_unregister_main_kobj(edac_dev); 862 edac_device_remove_main_sysfs_attributes(edac_dev);
728 863
864err_out:
729 return err; 865 return err;
730} 866}
731 867
732/* 868/*
733 * edac_device_remove_sysfs() destructor 869 * edac_device_remove_sysfs() destructor
734 * 870 *
735 * remove a edac_device instance 871 * given an edac_device struct, tear down the kobject resources
736 */ 872 */
737void edac_device_remove_sysfs(struct edac_device_ctl_info *edac_dev) 873void edac_device_remove_sysfs(struct edac_device_ctl_info *edac_dev)
738{ 874{
739 debugf0("%s()\n", __func__); 875 debugf0("%s()\n", __func__);
740 876
741 edac_device_delete_instances(edac_dev); 877 /* remove any main attributes for this device */
878 edac_device_remove_main_sysfs_attributes(edac_dev);
742 879
743 /* remove the sym link */ 880 /* remove the device sym link */
744 sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK); 881 sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK);
745 882
746 /* unregister the instance's main kobj */ 883 /* walk the instance/block kobject tree, deconstructing it */
747 edac_device_unregister_main_kobj(edac_dev); 884 edac_device_delete_instances(edac_dev);
748} 885}