root/drivers/edac/edac_device_sysfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. edac_device_ctl_log_ue_show
  2. edac_device_ctl_log_ue_store
  3. edac_device_ctl_log_ce_show
  4. edac_device_ctl_log_ce_store
  5. edac_device_ctl_panic_on_ue_show
  6. edac_device_ctl_panic_on_ue_store
  7. edac_device_ctl_poll_msec_show
  8. edac_device_ctl_poll_msec_store
  9. edac_dev_ctl_info_show
  10. edac_dev_ctl_info_store
  11. edac_device_ctrl_master_release
  12. edac_device_register_sysfs_main_kobj
  13. edac_device_unregister_sysfs_main_kobj
  14. instance_ue_count_show
  15. instance_ce_count_show
  16. edac_device_ctrl_instance_release
  17. edac_dev_instance_show
  18. edac_dev_instance_store
  19. block_ue_count_show
  20. block_ce_count_show
  21. edac_device_ctrl_block_release
  22. edac_dev_block_show
  23. edac_dev_block_store
  24. edac_device_create_block
  25. edac_device_delete_block
  26. edac_device_create_instance
  27. edac_device_delete_instance
  28. edac_device_create_instances
  29. edac_device_delete_instances
  30. edac_device_add_main_sysfs_attributes
  31. edac_device_remove_main_sysfs_attributes
  32. edac_device_create_sysfs
  33. edac_device_remove_sysfs

   1 /*
   2  * file for managing the edac_device subsystem of devices for EDAC
   3  *
   4  * (C) 2007 SoftwareBitMaker
   5  *
   6  * This file may be distributed under the terms of the
   7  * GNU General Public License.
   8  *
   9  * Written Doug Thompson <norsk5@xmission.com>
  10  *
  11  */
  12 
  13 #include <linux/ctype.h>
  14 #include <linux/module.h>
  15 #include <linux/slab.h>
  16 #include <linux/edac.h>
  17 
  18 #include "edac_device.h"
  19 #include "edac_module.h"
  20 
  21 #define EDAC_DEVICE_SYMLINK     "device"
  22 
  23 #define to_edacdev(k) container_of(k, struct edac_device_ctl_info, kobj)
  24 #define to_edacdev_attr(a) container_of(a, struct edacdev_attribute, attr)
  25 
  26 
  27 /*
  28  * Set of edac_device_ctl_info attribute store/show functions
  29  */
  30 
  31 /* 'log_ue' */
  32 static ssize_t edac_device_ctl_log_ue_show(struct edac_device_ctl_info
  33                                         *ctl_info, char *data)
  34 {
  35         return sprintf(data, "%u\n", ctl_info->log_ue);
  36 }
  37 
  38 static ssize_t edac_device_ctl_log_ue_store(struct edac_device_ctl_info
  39                                         *ctl_info, const char *data,
  40                                         size_t count)
  41 {
  42         /* if parameter is zero, turn off flag, if non-zero turn on flag */
  43         ctl_info->log_ue = (simple_strtoul(data, NULL, 0) != 0);
  44 
  45         return count;
  46 }
  47 
  48 /* 'log_ce' */
  49 static ssize_t edac_device_ctl_log_ce_show(struct edac_device_ctl_info
  50                                         *ctl_info, char *data)
  51 {
  52         return sprintf(data, "%u\n", ctl_info->log_ce);
  53 }
  54 
  55 static ssize_t edac_device_ctl_log_ce_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->log_ce = (simple_strtoul(data, NULL, 0) != 0);
  61 
  62         return count;
  63 }
  64 
  65 /* 'panic_on_ue' */
  66 static ssize_t edac_device_ctl_panic_on_ue_show(struct edac_device_ctl_info
  67                                                 *ctl_info, char *data)
  68 {
  69         return sprintf(data, "%u\n", ctl_info->panic_on_ue);
  70 }
  71 
  72 static ssize_t edac_device_ctl_panic_on_ue_store(struct edac_device_ctl_info
  73                                                  *ctl_info, const char *data,
  74                                                  size_t count)
  75 {
  76         /* if parameter is zero, turn off flag, if non-zero turn on flag */
  77         ctl_info->panic_on_ue = (simple_strtoul(data, NULL, 0) != 0);
  78 
  79         return count;
  80 }
  81 
  82 /* 'poll_msec' show and store functions*/
  83 static ssize_t edac_device_ctl_poll_msec_show(struct edac_device_ctl_info
  84                                         *ctl_info, char *data)
  85 {
  86         return sprintf(data, "%u\n", ctl_info->poll_msec);
  87 }
  88 
  89 static ssize_t edac_device_ctl_poll_msec_store(struct edac_device_ctl_info
  90                                         *ctl_info, const char *data,
  91                                         size_t count)
  92 {
  93         unsigned long value;
  94 
  95         /* get the value and enforce that it is non-zero, must be at least
  96          * one millisecond for the delay period, between scans
  97          * Then cancel last outstanding delay for the work request
  98          * and set a new one.
  99          */
 100         value = simple_strtoul(data, NULL, 0);
 101         edac_device_reset_delay_period(ctl_info, value);
 102 
 103         return count;
 104 }
 105 
 106 /* edac_device_ctl_info specific attribute structure */
 107 struct ctl_info_attribute {
 108         struct attribute attr;
 109         ssize_t(*show) (struct edac_device_ctl_info *, char *);
 110         ssize_t(*store) (struct edac_device_ctl_info *, const char *, size_t);
 111 };
 112 
 113 #define to_ctl_info(k) container_of(k, struct edac_device_ctl_info, kobj)
 114 #define to_ctl_info_attr(a) container_of(a,struct ctl_info_attribute,attr)
 115 
 116 /* Function to 'show' fields from the edac_dev 'ctl_info' structure */
 117 static ssize_t edac_dev_ctl_info_show(struct kobject *kobj,
 118                                 struct attribute *attr, char *buffer)
 119 {
 120         struct edac_device_ctl_info *edac_dev = to_ctl_info(kobj);
 121         struct ctl_info_attribute *ctl_info_attr = to_ctl_info_attr(attr);
 122 
 123         if (ctl_info_attr->show)
 124                 return ctl_info_attr->show(edac_dev, buffer);
 125         return -EIO;
 126 }
 127 
 128 /* Function to 'store' fields into the edac_dev 'ctl_info' structure */
 129 static ssize_t edac_dev_ctl_info_store(struct kobject *kobj,
 130                                 struct attribute *attr,
 131                                 const char *buffer, size_t count)
 132 {
 133         struct edac_device_ctl_info *edac_dev = to_ctl_info(kobj);
 134         struct ctl_info_attribute *ctl_info_attr = to_ctl_info_attr(attr);
 135 
 136         if (ctl_info_attr->store)
 137                 return ctl_info_attr->store(edac_dev, buffer, count);
 138         return -EIO;
 139 }
 140 
 141 /* edac_dev file operations for an 'ctl_info' */
 142 static const struct sysfs_ops device_ctl_info_ops = {
 143         .show = edac_dev_ctl_info_show,
 144         .store = edac_dev_ctl_info_store
 145 };
 146 
 147 #define CTL_INFO_ATTR(_name,_mode,_show,_store)        \
 148 static struct ctl_info_attribute attr_ctl_info_##_name = {      \
 149         .attr = {.name = __stringify(_name), .mode = _mode },   \
 150         .show   = _show,                                        \
 151         .store  = _store,                                       \
 152 };
 153 
 154 /* Declare the various ctl_info attributes here and their respective ops */
 155 CTL_INFO_ATTR(log_ue, S_IRUGO | S_IWUSR,
 156         edac_device_ctl_log_ue_show, edac_device_ctl_log_ue_store);
 157 CTL_INFO_ATTR(log_ce, S_IRUGO | S_IWUSR,
 158         edac_device_ctl_log_ce_show, edac_device_ctl_log_ce_store);
 159 CTL_INFO_ATTR(panic_on_ue, S_IRUGO | S_IWUSR,
 160         edac_device_ctl_panic_on_ue_show,
 161         edac_device_ctl_panic_on_ue_store);
 162 CTL_INFO_ATTR(poll_msec, S_IRUGO | S_IWUSR,
 163         edac_device_ctl_poll_msec_show, edac_device_ctl_poll_msec_store);
 164 
 165 /* Base Attributes of the EDAC_DEVICE ECC object */
 166 static struct ctl_info_attribute *device_ctrl_attr[] = {
 167         &attr_ctl_info_panic_on_ue,
 168         &attr_ctl_info_log_ue,
 169         &attr_ctl_info_log_ce,
 170         &attr_ctl_info_poll_msec,
 171         NULL,
 172 };
 173 
 174 /*
 175  * edac_device_ctrl_master_release
 176  *
 177  *      called when the reference count for the 'main' kobj
 178  *      for a edac_device control struct reaches zero
 179  *
 180  *      Reference count model:
 181  *              One 'main' kobject for each control structure allocated.
 182  *              That main kobj is initially set to one AND
 183  *              the reference count for the EDAC 'core' module is
 184  *              bumped by one, thus added 'keep in memory' dependency.
 185  *
 186  *              Each new internal kobj (in instances and blocks) then
 187  *              bumps the 'main' kobject.
 188  *
 189  *              When they are released their release functions decrement
 190  *              the 'main' kobj.
 191  *
 192  *              When the main kobj reaches zero (0) then THIS function
 193  *              is called which then decrements the EDAC 'core' module.
 194  *              When the module reference count reaches zero then the
 195  *              module no longer has dependency on keeping the release
 196  *              function code in memory and module can be unloaded.
 197  *
 198  *              This will support several control objects as well, each
 199  *              with its own 'main' kobj.
 200  */
 201 static void edac_device_ctrl_master_release(struct kobject *kobj)
 202 {
 203         struct edac_device_ctl_info *edac_dev = to_edacdev(kobj);
 204 
 205         edac_dbg(4, "control index=%d\n", edac_dev->dev_idx);
 206 
 207         /* decrement the EDAC CORE module ref count */
 208         module_put(edac_dev->owner);
 209 
 210         /* free the control struct containing the 'main' kobj
 211          * passed in to this routine
 212          */
 213         kfree(edac_dev);
 214 }
 215 
 216 /* ktype for the main (master) kobject */
 217 static struct kobj_type ktype_device_ctrl = {
 218         .release = edac_device_ctrl_master_release,
 219         .sysfs_ops = &device_ctl_info_ops,
 220         .default_attrs = (struct attribute **)device_ctrl_attr,
 221 };
 222 
 223 /*
 224  * edac_device_register_sysfs_main_kobj
 225  *
 226  *      perform the high level setup for the new edac_device instance
 227  *
 228  * Return:  0 SUCCESS
 229  *         !0 FAILURE
 230  */
 231 int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev)
 232 {
 233         struct bus_type *edac_subsys;
 234         int err;
 235 
 236         edac_dbg(1, "\n");
 237 
 238         /* get the /sys/devices/system/edac reference */
 239         edac_subsys = edac_get_sysfs_subsys();
 240 
 241         /* Point to the 'edac_subsys' this instance 'reports' to */
 242         edac_dev->edac_subsys = edac_subsys;
 243 
 244         /* Init the devices's kobject */
 245         memset(&edac_dev->kobj, 0, sizeof(struct kobject));
 246 
 247         /* Record which module 'owns' this control structure
 248          * and bump the ref count of the module
 249          */
 250         edac_dev->owner = THIS_MODULE;
 251 
 252         if (!try_module_get(edac_dev->owner)) {
 253                 err = -ENODEV;
 254                 goto err_out;
 255         }
 256 
 257         /* register */
 258         err = kobject_init_and_add(&edac_dev->kobj, &ktype_device_ctrl,
 259                                    &edac_subsys->dev_root->kobj,
 260                                    "%s", edac_dev->name);
 261         if (err) {
 262                 edac_dbg(1, "Failed to register '.../edac/%s'\n",
 263                          edac_dev->name);
 264                 goto err_kobj_reg;
 265         }
 266         kobject_uevent(&edac_dev->kobj, KOBJ_ADD);
 267 
 268         /* At this point, to 'free' the control struct,
 269          * edac_device_unregister_sysfs_main_kobj() must be used
 270          */
 271 
 272         edac_dbg(4, "Registered '.../edac/%s' kobject\n", edac_dev->name);
 273 
 274         return 0;
 275 
 276         /* Error exit stack */
 277 err_kobj_reg:
 278         module_put(edac_dev->owner);
 279 
 280 err_out:
 281         return err;
 282 }
 283 
 284 /*
 285  * edac_device_unregister_sysfs_main_kobj:
 286  *      the '..../edac/<name>' kobject
 287  */
 288 void edac_device_unregister_sysfs_main_kobj(struct edac_device_ctl_info *dev)
 289 {
 290         edac_dbg(0, "\n");
 291         edac_dbg(4, "name of kobject is: %s\n", kobject_name(&dev->kobj));
 292 
 293         /*
 294          * Unregister the edac device's kobject and
 295          * allow for reference count to reach 0 at which point
 296          * the callback will be called to:
 297          *   a) module_put() this module
 298          *   b) 'kfree' the memory
 299          */
 300         kobject_put(&dev->kobj);
 301 }
 302 
 303 /* edac_dev -> instance information */
 304 
 305 /*
 306  * Set of low-level instance attribute show functions
 307  */
 308 static ssize_t instance_ue_count_show(struct edac_device_instance *instance,
 309                                 char *data)
 310 {
 311         return sprintf(data, "%u\n", instance->counters.ue_count);
 312 }
 313 
 314 static ssize_t instance_ce_count_show(struct edac_device_instance *instance,
 315                                 char *data)
 316 {
 317         return sprintf(data, "%u\n", instance->counters.ce_count);
 318 }
 319 
 320 #define to_instance(k) container_of(k, struct edac_device_instance, kobj)
 321 #define to_instance_attr(a) container_of(a,struct instance_attribute,attr)
 322 
 323 /* DEVICE instance kobject release() function */
 324 static void edac_device_ctrl_instance_release(struct kobject *kobj)
 325 {
 326         struct edac_device_instance *instance;
 327 
 328         edac_dbg(1, "\n");
 329 
 330         /* map from this kobj to the main control struct
 331          * and then dec the main kobj count
 332          */
 333         instance = to_instance(kobj);
 334         kobject_put(&instance->ctl->kobj);
 335 }
 336 
 337 /* instance specific attribute structure */
 338 struct instance_attribute {
 339         struct attribute attr;
 340         ssize_t(*show) (struct edac_device_instance *, char *);
 341         ssize_t(*store) (struct edac_device_instance *, const char *, size_t);
 342 };
 343 
 344 /* Function to 'show' fields from the edac_dev 'instance' structure */
 345 static ssize_t edac_dev_instance_show(struct kobject *kobj,
 346                                 struct attribute *attr, char *buffer)
 347 {
 348         struct edac_device_instance *instance = to_instance(kobj);
 349         struct instance_attribute *instance_attr = to_instance_attr(attr);
 350 
 351         if (instance_attr->show)
 352                 return instance_attr->show(instance, buffer);
 353         return -EIO;
 354 }
 355 
 356 /* Function to 'store' fields into the edac_dev 'instance' structure */
 357 static ssize_t edac_dev_instance_store(struct kobject *kobj,
 358                                 struct attribute *attr,
 359                                 const char *buffer, size_t count)
 360 {
 361         struct edac_device_instance *instance = to_instance(kobj);
 362         struct instance_attribute *instance_attr = to_instance_attr(attr);
 363 
 364         if (instance_attr->store)
 365                 return instance_attr->store(instance, buffer, count);
 366         return -EIO;
 367 }
 368 
 369 /* edac_dev file operations for an 'instance' */
 370 static const struct sysfs_ops device_instance_ops = {
 371         .show = edac_dev_instance_show,
 372         .store = edac_dev_instance_store
 373 };
 374 
 375 #define INSTANCE_ATTR(_name,_mode,_show,_store)        \
 376 static struct instance_attribute attr_instance_##_name = {      \
 377         .attr = {.name = __stringify(_name), .mode = _mode },   \
 378         .show   = _show,                                        \
 379         .store  = _store,                                       \
 380 };
 381 
 382 /*
 383  * Define attributes visible for the edac_device instance object
 384  *      Each contains a pointer to a show and an optional set
 385  *      function pointer that does the low level output/input
 386  */
 387 INSTANCE_ATTR(ce_count, S_IRUGO, instance_ce_count_show, NULL);
 388 INSTANCE_ATTR(ue_count, S_IRUGO, instance_ue_count_show, NULL);
 389 
 390 /* list of edac_dev 'instance' attributes */
 391 static struct instance_attribute *device_instance_attr[] = {
 392         &attr_instance_ce_count,
 393         &attr_instance_ue_count,
 394         NULL,
 395 };
 396 
 397 /* The 'ktype' for each edac_dev 'instance' */
 398 static struct kobj_type ktype_instance_ctrl = {
 399         .release = edac_device_ctrl_instance_release,
 400         .sysfs_ops = &device_instance_ops,
 401         .default_attrs = (struct attribute **)device_instance_attr,
 402 };
 403 
 404 /* edac_dev -> instance -> block information */
 405 
 406 #define to_block(k) container_of(k, struct edac_device_block, kobj)
 407 #define to_block_attr(a) \
 408         container_of(a, struct edac_dev_sysfs_block_attribute, attr)
 409 
 410 /*
 411  * Set of low-level block attribute show functions
 412  */
 413 static ssize_t block_ue_count_show(struct kobject *kobj,
 414                                         struct attribute *attr, char *data)
 415 {
 416         struct edac_device_block *block = to_block(kobj);
 417 
 418         return sprintf(data, "%u\n", block->counters.ue_count);
 419 }
 420 
 421 static ssize_t block_ce_count_show(struct kobject *kobj,
 422                                         struct attribute *attr, char *data)
 423 {
 424         struct edac_device_block *block = to_block(kobj);
 425 
 426         return sprintf(data, "%u\n", block->counters.ce_count);
 427 }
 428 
 429 /* DEVICE block kobject release() function */
 430 static void edac_device_ctrl_block_release(struct kobject *kobj)
 431 {
 432         struct edac_device_block *block;
 433 
 434         edac_dbg(1, "\n");
 435 
 436         /* get the container of the kobj */
 437         block = to_block(kobj);
 438 
 439         /* map from 'block kobj' to 'block->instance->controller->main_kobj'
 440          * now 'release' the block kobject
 441          */
 442         kobject_put(&block->instance->ctl->kobj);
 443 }
 444 
 445 
 446 /* Function to 'show' fields from the edac_dev 'block' structure */
 447 static ssize_t edac_dev_block_show(struct kobject *kobj,
 448                                 struct attribute *attr, char *buffer)
 449 {
 450         struct edac_dev_sysfs_block_attribute *block_attr =
 451                                                 to_block_attr(attr);
 452 
 453         if (block_attr->show)
 454                 return block_attr->show(kobj, attr, buffer);
 455         return -EIO;
 456 }
 457 
 458 /* Function to 'store' fields into the edac_dev 'block' structure */
 459 static ssize_t edac_dev_block_store(struct kobject *kobj,
 460                                 struct attribute *attr,
 461                                 const char *buffer, size_t count)
 462 {
 463         struct edac_dev_sysfs_block_attribute *block_attr;
 464 
 465         block_attr = to_block_attr(attr);
 466 
 467         if (block_attr->store)
 468                 return block_attr->store(kobj, attr, buffer, count);
 469         return -EIO;
 470 }
 471 
 472 /* edac_dev file operations for a 'block' */
 473 static const struct sysfs_ops device_block_ops = {
 474         .show = edac_dev_block_show,
 475         .store = edac_dev_block_store
 476 };
 477 
 478 #define BLOCK_ATTR(_name,_mode,_show,_store)        \
 479 static struct edac_dev_sysfs_block_attribute attr_block_##_name = {     \
 480         .attr = {.name = __stringify(_name), .mode = _mode },   \
 481         .show   = _show,                                        \
 482         .store  = _store,                                       \
 483 };
 484 
 485 BLOCK_ATTR(ce_count, S_IRUGO, block_ce_count_show, NULL);
 486 BLOCK_ATTR(ue_count, S_IRUGO, block_ue_count_show, NULL);
 487 
 488 /* list of edac_dev 'block' attributes */
 489 static struct edac_dev_sysfs_block_attribute *device_block_attr[] = {
 490         &attr_block_ce_count,
 491         &attr_block_ue_count,
 492         NULL,
 493 };
 494 
 495 /* The 'ktype' for each edac_dev 'block' */
 496 static struct kobj_type ktype_block_ctrl = {
 497         .release = edac_device_ctrl_block_release,
 498         .sysfs_ops = &device_block_ops,
 499         .default_attrs = (struct attribute **)device_block_attr,
 500 };
 501 
 502 /* block ctor/dtor  code */
 503 
 504 /*
 505  * edac_device_create_block
 506  */
 507 static int edac_device_create_block(struct edac_device_ctl_info *edac_dev,
 508                                 struct edac_device_instance *instance,
 509                                 struct edac_device_block *block)
 510 {
 511         int i;
 512         int err;
 513         struct edac_dev_sysfs_block_attribute *sysfs_attrib;
 514         struct kobject *main_kobj;
 515 
 516         edac_dbg(4, "Instance '%s' inst_p=%p  block '%s'  block_p=%p\n",
 517                  instance->name, instance, block->name, block);
 518         edac_dbg(4, "block kobj=%p  block kobj->parent=%p\n",
 519                  &block->kobj, &block->kobj.parent);
 520 
 521         /* init this block's kobject */
 522         memset(&block->kobj, 0, sizeof(struct kobject));
 523 
 524         /* bump the main kobject's reference count for this controller
 525          * and this instance is dependent on the main
 526          */
 527         main_kobj = kobject_get(&edac_dev->kobj);
 528         if (!main_kobj) {
 529                 err = -ENODEV;
 530                 goto err_out;
 531         }
 532 
 533         /* Add this block's kobject */
 534         err = kobject_init_and_add(&block->kobj, &ktype_block_ctrl,
 535                                    &instance->kobj,
 536                                    "%s", block->name);
 537         if (err) {
 538                 edac_dbg(1, "Failed to register instance '%s'\n", block->name);
 539                 kobject_put(main_kobj);
 540                 err = -ENODEV;
 541                 goto err_out;
 542         }
 543 
 544         /* If there are driver level block attributes, then added them
 545          * to the block kobject
 546          */
 547         sysfs_attrib = block->block_attributes;
 548         if (sysfs_attrib && block->nr_attribs) {
 549                 for (i = 0; i < block->nr_attribs; i++, sysfs_attrib++) {
 550 
 551                         edac_dbg(4, "creating block attrib='%s' attrib->%p to kobj=%p\n",
 552                                  sysfs_attrib->attr.name,
 553                                  sysfs_attrib, &block->kobj);
 554 
 555                         /* Create each block_attribute file */
 556                         err = sysfs_create_file(&block->kobj,
 557                                 &sysfs_attrib->attr);
 558                         if (err)
 559                                 goto err_on_attrib;
 560                 }
 561         }
 562         kobject_uevent(&block->kobj, KOBJ_ADD);
 563 
 564         return 0;
 565 
 566         /* Error unwind stack */
 567 err_on_attrib:
 568         kobject_put(&block->kobj);
 569 
 570 err_out:
 571         return err;
 572 }
 573 
 574 /*
 575  * edac_device_delete_block(edac_dev,block);
 576  */
 577 static void edac_device_delete_block(struct edac_device_ctl_info *edac_dev,
 578                                 struct edac_device_block *block)
 579 {
 580         struct edac_dev_sysfs_block_attribute *sysfs_attrib;
 581         int i;
 582 
 583         /* if this block has 'attributes' then we need to iterate over the list
 584          * and 'remove' the attributes on this block
 585          */
 586         sysfs_attrib = block->block_attributes;
 587         if (sysfs_attrib && block->nr_attribs) {
 588                 for (i = 0; i < block->nr_attribs; i++, sysfs_attrib++) {
 589 
 590                         /* remove each block_attrib file */
 591                         sysfs_remove_file(&block->kobj,
 592                                 (struct attribute *) sysfs_attrib);
 593                 }
 594         }
 595 
 596         /* unregister this block's kobject, SEE:
 597          *      edac_device_ctrl_block_release() callback operation
 598          */
 599         kobject_put(&block->kobj);
 600 }
 601 
 602 /* instance ctor/dtor code */
 603 
 604 /*
 605  * edac_device_create_instance
 606  *      create just one instance of an edac_device 'instance'
 607  */
 608 static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev,
 609                                 int idx)
 610 {
 611         int i, j;
 612         int err;
 613         struct edac_device_instance *instance;
 614         struct kobject *main_kobj;
 615 
 616         instance = &edac_dev->instances[idx];
 617 
 618         /* Init the instance's kobject */
 619         memset(&instance->kobj, 0, sizeof(struct kobject));
 620 
 621         instance->ctl = edac_dev;
 622 
 623         /* bump the main kobject's reference count for this controller
 624          * and this instance is dependent on the main
 625          */
 626         main_kobj = kobject_get(&edac_dev->kobj);
 627         if (!main_kobj) {
 628                 err = -ENODEV;
 629                 goto err_out;
 630         }
 631 
 632         /* Formally register this instance's kobject under the edac_device */
 633         err = kobject_init_and_add(&instance->kobj, &ktype_instance_ctrl,
 634                                    &edac_dev->kobj, "%s", instance->name);
 635         if (err != 0) {
 636                 edac_dbg(2, "Failed to register instance '%s'\n",
 637                          instance->name);
 638                 kobject_put(main_kobj);
 639                 goto err_out;
 640         }
 641 
 642         edac_dbg(4, "now register '%d' blocks for instance %d\n",
 643                  instance->nr_blocks, idx);
 644 
 645         /* register all blocks of this instance */
 646         for (i = 0; i < instance->nr_blocks; i++) {
 647                 err = edac_device_create_block(edac_dev, instance,
 648                                                 &instance->blocks[i]);
 649                 if (err) {
 650                         /* If any fail, remove all previous ones */
 651                         for (j = 0; j < i; j++)
 652                                 edac_device_delete_block(edac_dev,
 653                                                         &instance->blocks[j]);
 654                         goto err_release_instance_kobj;
 655                 }
 656         }
 657         kobject_uevent(&instance->kobj, KOBJ_ADD);
 658 
 659         edac_dbg(4, "Registered instance %d '%s' kobject\n",
 660                  idx, instance->name);
 661 
 662         return 0;
 663 
 664         /* error unwind stack */
 665 err_release_instance_kobj:
 666         kobject_put(&instance->kobj);
 667 
 668 err_out:
 669         return err;
 670 }
 671 
 672 /*
 673  * edac_device_remove_instance
 674  *      remove an edac_device instance
 675  */
 676 static void edac_device_delete_instance(struct edac_device_ctl_info *edac_dev,
 677                                         int idx)
 678 {
 679         struct edac_device_instance *instance;
 680         int i;
 681 
 682         instance = &edac_dev->instances[idx];
 683 
 684         /* unregister all blocks in this instance */
 685         for (i = 0; i < instance->nr_blocks; i++)
 686                 edac_device_delete_block(edac_dev, &instance->blocks[i]);
 687 
 688         /* unregister this instance's kobject, SEE:
 689          *      edac_device_ctrl_instance_release() for callback operation
 690          */
 691         kobject_put(&instance->kobj);
 692 }
 693 
 694 /*
 695  * edac_device_create_instances
 696  *      create the first level of 'instances' for this device
 697  *      (ie  'cache' might have 'cache0', 'cache1', 'cache2', etc
 698  */
 699 static int edac_device_create_instances(struct edac_device_ctl_info *edac_dev)
 700 {
 701         int i, j;
 702         int err;
 703 
 704         edac_dbg(0, "\n");
 705 
 706         /* iterate over creation of the instances */
 707         for (i = 0; i < edac_dev->nr_instances; i++) {
 708                 err = edac_device_create_instance(edac_dev, i);
 709                 if (err) {
 710                         /* unwind previous instances on error */
 711                         for (j = 0; j < i; j++)
 712                                 edac_device_delete_instance(edac_dev, j);
 713                         return err;
 714                 }
 715         }
 716 
 717         return 0;
 718 }
 719 
 720 /*
 721  * edac_device_delete_instances(edac_dev);
 722  *      unregister all the kobjects of the instances
 723  */
 724 static void edac_device_delete_instances(struct edac_device_ctl_info *edac_dev)
 725 {
 726         int i;
 727 
 728         /* iterate over creation of the instances */
 729         for (i = 0; i < edac_dev->nr_instances; i++)
 730                 edac_device_delete_instance(edac_dev, i);
 731 }
 732 
 733 /* edac_dev sysfs ctor/dtor  code */
 734 
 735 /*
 736  * edac_device_add_main_sysfs_attributes
 737  *      add some attributes to this instance's main kobject
 738  */
 739 static int edac_device_add_main_sysfs_attributes(
 740                         struct edac_device_ctl_info *edac_dev)
 741 {
 742         struct edac_dev_sysfs_attribute *sysfs_attrib;
 743         int err = 0;
 744 
 745         sysfs_attrib = edac_dev->sysfs_attributes;
 746         if (sysfs_attrib) {
 747                 /* iterate over the array and create an attribute for each
 748                  * entry in the list
 749                  */
 750                 while (sysfs_attrib->attr.name != NULL) {
 751                         err = sysfs_create_file(&edac_dev->kobj,
 752                                 (struct attribute*) sysfs_attrib);
 753                         if (err)
 754                                 goto err_out;
 755 
 756                         sysfs_attrib++;
 757                 }
 758         }
 759 
 760 err_out:
 761         return err;
 762 }
 763 
 764 /*
 765  * edac_device_remove_main_sysfs_attributes
 766  *      remove any attributes to this instance's main kobject
 767  */
 768 static void edac_device_remove_main_sysfs_attributes(
 769                         struct edac_device_ctl_info *edac_dev)
 770 {
 771         struct edac_dev_sysfs_attribute *sysfs_attrib;
 772 
 773         /* if there are main attributes, defined, remove them. First,
 774          * point to the start of the array and iterate over it
 775          * removing each attribute listed from this device's instance's kobject
 776          */
 777         sysfs_attrib = edac_dev->sysfs_attributes;
 778         if (sysfs_attrib) {
 779                 while (sysfs_attrib->attr.name != NULL) {
 780                         sysfs_remove_file(&edac_dev->kobj,
 781                                         (struct attribute *) sysfs_attrib);
 782                         sysfs_attrib++;
 783                 }
 784         }
 785 }
 786 
 787 /*
 788  * edac_device_create_sysfs() Constructor
 789  *
 790  * accept a created edac_device control structure
 791  * and 'export' it to sysfs. The 'main' kobj should already have been
 792  * created. 'instance' and 'block' kobjects should be registered
 793  * along with any 'block' attributes from the low driver. In addition,
 794  * the main attributes (if any) are connected to the main kobject of
 795  * the control structure.
 796  *
 797  * Return:
 798  *      0       Success
 799  *      !0      Failure
 800  */
 801 int edac_device_create_sysfs(struct edac_device_ctl_info *edac_dev)
 802 {
 803         int err;
 804         struct kobject *edac_kobj = &edac_dev->kobj;
 805 
 806         edac_dbg(0, "idx=%d\n", edac_dev->dev_idx);
 807 
 808         /*  go create any main attributes callers wants */
 809         err = edac_device_add_main_sysfs_attributes(edac_dev);
 810         if (err) {
 811                 edac_dbg(0, "failed to add sysfs attribs\n");
 812                 goto err_out;
 813         }
 814 
 815         /* create a symlink from the edac device
 816          * to the platform 'device' being used for this
 817          */
 818         err = sysfs_create_link(edac_kobj,
 819                                 &edac_dev->dev->kobj, EDAC_DEVICE_SYMLINK);
 820         if (err) {
 821                 edac_dbg(0, "sysfs_create_link() returned err= %d\n", err);
 822                 goto err_remove_main_attribs;
 823         }
 824 
 825         /* Create the first level instance directories
 826          * In turn, the nested blocks beneath the instances will
 827          * be registered as well
 828          */
 829         err = edac_device_create_instances(edac_dev);
 830         if (err) {
 831                 edac_dbg(0, "edac_device_create_instances() returned err= %d\n",
 832                          err);
 833                 goto err_remove_link;
 834         }
 835 
 836 
 837         edac_dbg(4, "create-instances done, idx=%d\n", edac_dev->dev_idx);
 838 
 839         return 0;
 840 
 841         /* Error unwind stack */
 842 err_remove_link:
 843         /* remove the sym link */
 844         sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK);
 845 
 846 err_remove_main_attribs:
 847         edac_device_remove_main_sysfs_attributes(edac_dev);
 848 
 849 err_out:
 850         return err;
 851 }
 852 
 853 /*
 854  * edac_device_remove_sysfs() destructor
 855  *
 856  * given an edac_device struct, tear down the kobject resources
 857  */
 858 void edac_device_remove_sysfs(struct edac_device_ctl_info *edac_dev)
 859 {
 860         edac_dbg(0, "\n");
 861 
 862         /* remove any main attributes for this device */
 863         edac_device_remove_main_sysfs_attributes(edac_dev);
 864 
 865         /* remove the device sym link */
 866         sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK);
 867 
 868         /* walk the instance/block kobject tree, deconstructing it */
 869         edac_device_delete_instances(edac_dev);
 870 }

/* [<][>][^][v][top][bottom][index][help] */