Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/edac/edac_device_sysfs.c (Version 2.6.25) and /linux/drivers/edac/edac_device_sysfs.c (Version 2.6.31.13)


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