35bcf926017fdad37e929e0da556498f6fdf2c5e
[safe/jmp/linux-2.6] / drivers / edac / edac_mc_sysfs.c
1 /*
2  * edac_mc kernel module
3  * (C) 2005, 2006 Linux Networx (http://lnxi.com)
4  * This file may be distributed under the terms of the
5  * GNU General Public License.
6  *
7  * Written Doug Thompson <norsk5@xmission.com>
8  *
9  */
10
11 #include <linux/module.h>
12 #include <linux/sysdev.h>
13 #include <linux/ctype.h>
14
15 #include "edac_mc.h"
16 #include "edac_module.h"
17
18 /* MC EDAC Controls, setable by module parameter, and sysfs */
19 static int log_ue = 1;
20 static int log_ce = 1;
21 static int panic_on_ue;
22 static int poll_msec = 1000;
23
24 /* Getter functions for above */
25 int edac_get_log_ue()
26 {
27         return log_ue;
28 }
29
30 int edac_get_log_ce()
31 {
32         return log_ce;
33 }
34
35 int edac_get_panic_on_ue()
36 {
37         return panic_on_ue;
38 }
39
40 int edac_get_poll_msec()
41 {
42         return poll_msec;
43 }
44
45 /* Parameter declarations for above */
46 module_param(panic_on_ue, int, 0644);
47 MODULE_PARM_DESC(panic_on_ue, "Panic on uncorrected error: 0=off 1=on");
48 module_param(log_ue, int, 0644);
49 MODULE_PARM_DESC(log_ue, "Log uncorrectable error to console: 0=off 1=on");
50 module_param(log_ce, int, 0644);
51 MODULE_PARM_DESC(log_ce, "Log correctable error to console: 0=off 1=on");
52 module_param(poll_msec, int, 0644);
53 MODULE_PARM_DESC(poll_msec, "Polling period in milliseconds");
54
55
56 /*
57  * various constants for Memory Controllers
58  */
59 static const char *mem_types[] = {
60         [MEM_EMPTY] = "Empty",
61         [MEM_RESERVED] = "Reserved",
62         [MEM_UNKNOWN] = "Unknown",
63         [MEM_FPM] = "FPM",
64         [MEM_EDO] = "EDO",
65         [MEM_BEDO] = "BEDO",
66         [MEM_SDR] = "Unbuffered-SDR",
67         [MEM_RDR] = "Registered-SDR",
68         [MEM_DDR] = "Unbuffered-DDR",
69         [MEM_RDDR] = "Registered-DDR",
70         [MEM_RMBS] = "RMBS"
71 };
72
73 static const char *dev_types[] = {
74         [DEV_UNKNOWN] = "Unknown",
75         [DEV_X1] = "x1",
76         [DEV_X2] = "x2",
77         [DEV_X4] = "x4",
78         [DEV_X8] = "x8",
79         [DEV_X16] = "x16",
80         [DEV_X32] = "x32",
81         [DEV_X64] = "x64"
82 };
83
84 static const char *edac_caps[] = {
85         [EDAC_UNKNOWN] = "Unknown",
86         [EDAC_NONE] = "None",
87         [EDAC_RESERVED] = "Reserved",
88         [EDAC_PARITY] = "PARITY",
89         [EDAC_EC] = "EC",
90         [EDAC_SECDED] = "SECDED",
91         [EDAC_S2ECD2ED] = "S2ECD2ED",
92         [EDAC_S4ECD4ED] = "S4ECD4ED",
93         [EDAC_S8ECD8ED] = "S8ECD8ED",
94         [EDAC_S16ECD16ED] = "S16ECD16ED"
95 };
96
97 /* sysfs object:
98  *      /sys/devices/system/edac/mc
99  */
100 static struct kobject edac_memctrl_kobj;
101
102 /* We use these to wait for the reference counts on edac_memctrl_kobj and
103  * edac_pci_kobj to reach 0.
104  */
105 static struct completion edac_memctrl_kobj_complete;
106
107 /*
108  * /sys/devices/system/edac/mc;
109  *      data structures and methods
110  */
111 static ssize_t memctrl_int_show(void *ptr, char *buffer)
112 {
113         int *value = (int*) ptr;
114         return sprintf(buffer, "%u\n", *value);
115 }
116
117 static ssize_t memctrl_int_store(void *ptr, const char *buffer, size_t count)
118 {
119         int *value = (int*) ptr;
120
121         if (isdigit(*buffer))
122                 *value = simple_strtoul(buffer, NULL, 0);
123
124         return count;
125 }
126
127 struct memctrl_dev_attribute {
128         struct attribute attr;
129         void *value;
130         ssize_t (*show)(void *,char *);
131         ssize_t (*store)(void *, const char *, size_t);
132 };
133
134 /* Set of show/store abstract level functions for memory control object */
135 static ssize_t memctrl_dev_show(struct kobject *kobj,
136                 struct attribute *attr, char *buffer)
137 {
138         struct memctrl_dev_attribute *memctrl_dev;
139         memctrl_dev = (struct memctrl_dev_attribute*)attr;
140
141         if (memctrl_dev->show)
142                 return memctrl_dev->show(memctrl_dev->value, buffer);
143
144         return -EIO;
145 }
146
147 static ssize_t memctrl_dev_store(struct kobject *kobj, struct attribute *attr,
148                 const char *buffer, size_t count)
149 {
150         struct memctrl_dev_attribute *memctrl_dev;
151         memctrl_dev = (struct memctrl_dev_attribute*)attr;
152
153         if (memctrl_dev->store)
154                 return memctrl_dev->store(memctrl_dev->value, buffer, count);
155
156         return -EIO;
157 }
158
159 static struct sysfs_ops memctrlfs_ops = {
160         .show   = memctrl_dev_show,
161         .store  = memctrl_dev_store
162 };
163
164 #define MEMCTRL_ATTR(_name,_mode,_show,_store)                  \
165 static struct memctrl_dev_attribute attr_##_name = {                    \
166         .attr = {.name = __stringify(_name), .mode = _mode },   \
167         .value  = &_name,                                       \
168         .show   = _show,                                        \
169         .store  = _store,                                       \
170 };
171
172 #define MEMCTRL_STRING_ATTR(_name,_data,_mode,_show,_store)     \
173 static struct memctrl_dev_attribute attr_##_name = {                    \
174         .attr = {.name = __stringify(_name), .mode = _mode },   \
175         .value  = _data,                                        \
176         .show   = _show,                                        \
177         .store  = _store,                                       \
178 };
179
180 /* csrow<id> control files */
181 MEMCTRL_ATTR(panic_on_ue,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
182 MEMCTRL_ATTR(log_ue,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
183 MEMCTRL_ATTR(log_ce,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
184 MEMCTRL_ATTR(poll_msec,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
185
186 /* Base Attributes of the memory ECC object */
187 static struct memctrl_dev_attribute *memctrl_attr[] = {
188         &attr_panic_on_ue,
189         &attr_log_ue,
190         &attr_log_ce,
191         &attr_poll_msec,
192         NULL,
193 };
194
195 /* Main MC kobject release() function */
196 static void edac_memctrl_master_release(struct kobject *kobj)
197 {
198         debugf1("%s()\n", __func__);
199         complete(&edac_memctrl_kobj_complete);
200 }
201
202 static struct kobj_type ktype_memctrl = {
203         .release = edac_memctrl_master_release,
204         .sysfs_ops = &memctrlfs_ops,
205         .default_attrs = (struct attribute **) memctrl_attr,
206 };
207
208 /* Initialize the main sysfs entries for edac:
209  *   /sys/devices/system/edac
210  *
211  * and children
212  *
213  * Return:  0 SUCCESS
214  *         !0 FAILURE
215  */
216 int edac_sysfs_memctrl_setup(void)
217 {
218         int err = 0;
219         struct sysdev_class *edac_class;
220
221         debugf1("%s()\n", __func__);
222
223         /* get the /sys/devices/system/edac class reference */
224         edac_class = edac_get_edac_class();
225         if (edac_class == NULL) {
226                 debugf1("%s() no edac_class error=%d\n", __func__, err);
227                 return err;
228         }
229
230         /* Init the MC's kobject */
231         memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj));
232         edac_memctrl_kobj.parent = &edac_class->kset.kobj;
233         edac_memctrl_kobj.ktype = &ktype_memctrl;
234
235         /* generate sysfs "..../edac/mc"   */
236         err = kobject_set_name(&edac_memctrl_kobj,"mc");
237         if (err) {
238                 debugf1("%s() Failed to set name '.../edac/mc'\n", __func__ );
239                 return err;
240         }
241
242         /* FIXME: maybe new sysdev_create_subdir() */
243         err = kobject_register(&edac_memctrl_kobj);
244         if (err) {
245                 debugf1("%s() Failed to register '.../edac/mc'\n", __func__ );
246                 return err;
247         }
248
249         debugf1("%s() Registered '.../edac/mc' kobject\n",__func__);
250         return 0;
251 }
252
253 /*
254  * MC teardown:
255  *      the '..../edac/mc' kobject followed by '..../edac' itself
256  */
257 void edac_sysfs_memctrl_teardown(void)
258 {
259         debugf0("MC: " __FILE__ ": %s()\n", __func__);
260
261         /* Unregister the MC's kobject and wait for reference count to reach 0.
262          */
263         init_completion(&edac_memctrl_kobj_complete);
264         kobject_unregister(&edac_memctrl_kobj);
265         wait_for_completion(&edac_memctrl_kobj_complete);
266 }
267
268
269 /* EDAC sysfs CSROW data structures and methods
270  */
271
272 /* Set of more default csrow<id> attribute show/store functions */
273 static ssize_t csrow_ue_count_show(struct csrow_info *csrow, char *data,
274                         int private)
275 {
276         return sprintf(data,"%u\n", csrow->ue_count);
277 }
278
279 static ssize_t csrow_ce_count_show(struct csrow_info *csrow, char *data,
280                         int private)
281 {
282         return sprintf(data,"%u\n", csrow->ce_count);
283 }
284
285 static ssize_t csrow_size_show(struct csrow_info *csrow, char *data,
286                         int private)
287 {
288         return sprintf(data,"%u\n", PAGES_TO_MiB(csrow->nr_pages));
289 }
290
291 static ssize_t csrow_mem_type_show(struct csrow_info *csrow, char *data,
292                         int private)
293 {
294         return sprintf(data,"%s\n", mem_types[csrow->mtype]);
295 }
296
297 static ssize_t csrow_dev_type_show(struct csrow_info *csrow, char *data,
298                         int private)
299 {
300         return sprintf(data,"%s\n", dev_types[csrow->dtype]);
301 }
302
303 static ssize_t csrow_edac_mode_show(struct csrow_info *csrow, char *data,
304                         int private)
305 {
306         return sprintf(data,"%s\n", edac_caps[csrow->edac_mode]);
307 }
308
309 /* show/store functions for DIMM Label attributes */
310 static ssize_t channel_dimm_label_show(struct csrow_info *csrow,
311                 char *data, int channel)
312 {
313         return snprintf(data, EDAC_MC_LABEL_LEN,"%s",
314                         csrow->channels[channel].label);
315 }
316
317 static ssize_t channel_dimm_label_store(struct csrow_info *csrow,
318                                 const char *data,
319                                 size_t count,
320                                 int channel)
321 {
322         ssize_t max_size = 0;
323
324         max_size = min((ssize_t)count,(ssize_t)EDAC_MC_LABEL_LEN-1);
325         strncpy(csrow->channels[channel].label, data, max_size);
326         csrow->channels[channel].label[max_size] = '\0';
327
328         return max_size;
329 }
330
331 /* show function for dynamic chX_ce_count attribute */
332 static ssize_t channel_ce_count_show(struct csrow_info *csrow,
333                                 char *data,
334                                 int channel)
335 {
336         return sprintf(data, "%u\n", csrow->channels[channel].ce_count);
337 }
338
339 /* csrow specific attribute structure */
340 struct csrowdev_attribute {
341         struct attribute attr;
342         ssize_t (*show)(struct csrow_info *,char *,int);
343         ssize_t (*store)(struct csrow_info *, const char *,size_t,int);
344         int    private;
345 };
346
347 #define to_csrow(k) container_of(k, struct csrow_info, kobj)
348 #define to_csrowdev_attr(a) container_of(a, struct csrowdev_attribute, attr)
349
350 /* Set of show/store higher level functions for default csrow attributes */
351 static ssize_t csrowdev_show(struct kobject *kobj,
352                         struct attribute *attr,
353                         char *buffer)
354 {
355         struct csrow_info *csrow = to_csrow(kobj);
356         struct csrowdev_attribute *csrowdev_attr = to_csrowdev_attr(attr);
357
358         if (csrowdev_attr->show)
359                 return csrowdev_attr->show(csrow,
360                                         buffer,
361                                         csrowdev_attr->private);
362         return -EIO;
363 }
364
365 static ssize_t csrowdev_store(struct kobject *kobj, struct attribute *attr,
366                 const char *buffer, size_t count)
367 {
368         struct csrow_info *csrow = to_csrow(kobj);
369         struct csrowdev_attribute * csrowdev_attr = to_csrowdev_attr(attr);
370
371         if (csrowdev_attr->store)
372                 return csrowdev_attr->store(csrow,
373                                         buffer,
374                                         count,
375                                         csrowdev_attr->private);
376         return -EIO;
377 }
378
379 static struct sysfs_ops csrowfs_ops = {
380         .show   = csrowdev_show,
381         .store  = csrowdev_store
382 };
383
384 #define CSROWDEV_ATTR(_name,_mode,_show,_store,_private)        \
385 static struct csrowdev_attribute attr_##_name = {                       \
386         .attr = {.name = __stringify(_name), .mode = _mode },   \
387         .show   = _show,                                        \
388         .store  = _store,                                       \
389         .private = _private,                                    \
390 };
391
392 /* default cwrow<id>/attribute files */
393 CSROWDEV_ATTR(size_mb,S_IRUGO,csrow_size_show,NULL,0);
394 CSROWDEV_ATTR(dev_type,S_IRUGO,csrow_dev_type_show,NULL,0);
395 CSROWDEV_ATTR(mem_type,S_IRUGO,csrow_mem_type_show,NULL,0);
396 CSROWDEV_ATTR(edac_mode,S_IRUGO,csrow_edac_mode_show,NULL,0);
397 CSROWDEV_ATTR(ue_count,S_IRUGO,csrow_ue_count_show,NULL,0);
398 CSROWDEV_ATTR(ce_count,S_IRUGO,csrow_ce_count_show,NULL,0);
399
400 /* default attributes of the CSROW<id> object */
401 static struct csrowdev_attribute *default_csrow_attr[] = {
402         &attr_dev_type,
403         &attr_mem_type,
404         &attr_edac_mode,
405         &attr_size_mb,
406         &attr_ue_count,
407         &attr_ce_count,
408         NULL,
409 };
410
411
412 /* possible dynamic channel DIMM Label attribute files */
413 CSROWDEV_ATTR(ch0_dimm_label,S_IRUGO|S_IWUSR,
414                 channel_dimm_label_show,
415                 channel_dimm_label_store,
416                 0 );
417 CSROWDEV_ATTR(ch1_dimm_label,S_IRUGO|S_IWUSR,
418                 channel_dimm_label_show,
419                 channel_dimm_label_store,
420                 1 );
421 CSROWDEV_ATTR(ch2_dimm_label,S_IRUGO|S_IWUSR,
422                 channel_dimm_label_show,
423                 channel_dimm_label_store,
424                 2 );
425 CSROWDEV_ATTR(ch3_dimm_label,S_IRUGO|S_IWUSR,
426                 channel_dimm_label_show,
427                 channel_dimm_label_store,
428                 3 );
429 CSROWDEV_ATTR(ch4_dimm_label,S_IRUGO|S_IWUSR,
430                 channel_dimm_label_show,
431                 channel_dimm_label_store,
432                 4 );
433 CSROWDEV_ATTR(ch5_dimm_label,S_IRUGO|S_IWUSR,
434                 channel_dimm_label_show,
435                 channel_dimm_label_store,
436                 5 );
437
438 /* Total possible dynamic DIMM Label attribute file table */
439 static struct csrowdev_attribute *dynamic_csrow_dimm_attr[] = {
440                 &attr_ch0_dimm_label,
441                 &attr_ch1_dimm_label,
442                 &attr_ch2_dimm_label,
443                 &attr_ch3_dimm_label,
444                 &attr_ch4_dimm_label,
445                 &attr_ch5_dimm_label
446 };
447
448 /* possible dynamic channel ce_count attribute files */
449 CSROWDEV_ATTR(ch0_ce_count,S_IRUGO|S_IWUSR,
450                 channel_ce_count_show,
451                 NULL,
452                 0 );
453 CSROWDEV_ATTR(ch1_ce_count,S_IRUGO|S_IWUSR,
454                 channel_ce_count_show,
455                 NULL,
456                 1 );
457 CSROWDEV_ATTR(ch2_ce_count,S_IRUGO|S_IWUSR,
458                 channel_ce_count_show,
459                 NULL,
460                 2 );
461 CSROWDEV_ATTR(ch3_ce_count,S_IRUGO|S_IWUSR,
462                 channel_ce_count_show,
463                 NULL,
464                 3 );
465 CSROWDEV_ATTR(ch4_ce_count,S_IRUGO|S_IWUSR,
466                 channel_ce_count_show,
467                 NULL,
468                 4 );
469 CSROWDEV_ATTR(ch5_ce_count,S_IRUGO|S_IWUSR,
470                 channel_ce_count_show,
471                 NULL,
472                 5 );
473
474 /* Total possible dynamic ce_count attribute file table */
475 static struct csrowdev_attribute *dynamic_csrow_ce_count_attr[] = {
476                 &attr_ch0_ce_count,
477                 &attr_ch1_ce_count,
478                 &attr_ch2_ce_count,
479                 &attr_ch3_ce_count,
480                 &attr_ch4_ce_count,
481                 &attr_ch5_ce_count
482 };
483
484
485 #define EDAC_NR_CHANNELS        6
486
487 /* Create dynamic CHANNEL files, indexed by 'chan',  under specifed CSROW */
488 static int edac_create_channel_files(struct kobject *kobj, int chan)
489 {
490         int err=-ENODEV;
491
492         if (chan >= EDAC_NR_CHANNELS)
493                 return err;
494
495         /* create the DIMM label attribute file */
496         err = sysfs_create_file(kobj,
497                         (struct attribute *) dynamic_csrow_dimm_attr[chan]);
498
499         if (!err) {
500                 /* create the CE Count attribute file */
501                 err = sysfs_create_file(kobj,
502                         (struct attribute *)dynamic_csrow_ce_count_attr[chan]);
503         } else {
504                 debugf1("%s()  dimm labels and ce_count files created",
505                         __func__);
506         }
507
508         return err;
509 }
510
511 /* No memory to release for this kobj */
512 static void edac_csrow_instance_release(struct kobject *kobj)
513 {
514         struct csrow_info *cs;
515
516         cs = container_of(kobj, struct csrow_info, kobj);
517         complete(&cs->kobj_complete);
518 }
519
520 /* the kobj_type instance for a CSROW */
521 static struct kobj_type ktype_csrow = {
522         .release = edac_csrow_instance_release,
523         .sysfs_ops = &csrowfs_ops,
524         .default_attrs = (struct attribute **) default_csrow_attr,
525 };
526
527 /* Create a CSROW object under specifed edac_mc_device */
528 static int edac_create_csrow_object(
529                 struct kobject *edac_mci_kobj,
530                 struct csrow_info *csrow,
531                 int index)
532 {
533         int err = 0;
534         int chan;
535
536         memset(&csrow->kobj, 0, sizeof(csrow->kobj));
537
538         /* generate ..../edac/mc/mc<id>/csrow<index>   */
539
540         csrow->kobj.parent = edac_mci_kobj;
541         csrow->kobj.ktype = &ktype_csrow;
542
543         /* name this instance of csrow<id> */
544         err = kobject_set_name(&csrow->kobj,"csrow%d",index);
545         if (err)
546                 goto error_exit;
547
548         /* Instanstiate the csrow object */
549         err = kobject_register(&csrow->kobj);
550         if (!err) {
551                 /* Create the dyanmic attribute files on this csrow,
552                  * namely, the DIMM labels and the channel ce_count
553                  */
554                 for (chan = 0; chan < csrow->nr_channels; chan++) {
555                         err = edac_create_channel_files(&csrow->kobj,chan);
556                         if (err)
557                                 break;
558                 }
559         }
560
561 error_exit:
562         return err;
563 }
564
565 /* default sysfs methods and data structures for the main MCI kobject */
566
567 static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci,
568                 const char *data, size_t count)
569 {
570         int row, chan;
571
572         mci->ue_noinfo_count = 0;
573         mci->ce_noinfo_count = 0;
574         mci->ue_count = 0;
575         mci->ce_count = 0;
576
577         for (row = 0; row < mci->nr_csrows; row++) {
578                 struct csrow_info *ri = &mci->csrows[row];
579
580                 ri->ue_count = 0;
581                 ri->ce_count = 0;
582
583                 for (chan = 0; chan < ri->nr_channels; chan++)
584                         ri->channels[chan].ce_count = 0;
585         }
586
587         mci->start_time = jiffies;
588         return count;
589 }
590
591 /* memory scrubbing */
592 static ssize_t mci_sdram_scrub_rate_store(struct mem_ctl_info *mci,
593                                         const char *data, size_t count)
594 {
595         u32 bandwidth = -1;
596
597         if (mci->set_sdram_scrub_rate) {
598
599                 memctrl_int_store(&bandwidth, data, count);
600
601                 if (!(*mci->set_sdram_scrub_rate)(mci, &bandwidth)) {
602                         edac_printk(KERN_DEBUG, EDAC_MC,
603                                 "Scrub rate set successfully, applied: %d\n",
604                                 bandwidth);
605                 } else {
606                         /* FIXME: error codes maybe? */
607                         edac_printk(KERN_DEBUG, EDAC_MC,
608                                 "Scrub rate set FAILED, could not apply: %d\n",
609                                 bandwidth);
610                 }
611         } else {
612                 /* FIXME: produce "not implemented" ERROR for user-side. */
613                 edac_printk(KERN_WARNING, EDAC_MC,
614                         "Memory scrubbing 'set'control is not implemented!\n");
615         }
616         return count;
617 }
618
619 static ssize_t mci_sdram_scrub_rate_show(struct mem_ctl_info *mci, char *data)
620 {
621         u32 bandwidth = -1;
622
623         if (mci->get_sdram_scrub_rate) {
624                 if (!(*mci->get_sdram_scrub_rate)(mci, &bandwidth)) {
625                         edac_printk(KERN_DEBUG, EDAC_MC,
626                                 "Scrub rate successfully, fetched: %d\n",
627                                 bandwidth);
628                 } else {
629                         /* FIXME: error codes maybe? */
630                         edac_printk(KERN_DEBUG, EDAC_MC,
631                                 "Scrub rate fetch FAILED, got: %d\n",
632                                 bandwidth);
633                 }
634         } else {
635                 /* FIXME: produce "not implemented" ERROR for user-side.  */
636                 edac_printk(KERN_WARNING, EDAC_MC,
637                         "Memory scrubbing 'get' control is not implemented\n");
638         }
639         return sprintf(data, "%d\n", bandwidth);
640 }
641
642 /* default attribute files for the MCI object */
643 static ssize_t mci_ue_count_show(struct mem_ctl_info *mci, char *data)
644 {
645         return sprintf(data,"%d\n", mci->ue_count);
646 }
647
648 static ssize_t mci_ce_count_show(struct mem_ctl_info *mci, char *data)
649 {
650         return sprintf(data,"%d\n", mci->ce_count);
651 }
652
653 static ssize_t mci_ce_noinfo_show(struct mem_ctl_info *mci, char *data)
654 {
655         return sprintf(data,"%d\n", mci->ce_noinfo_count);
656 }
657
658 static ssize_t mci_ue_noinfo_show(struct mem_ctl_info *mci, char *data)
659 {
660         return sprintf(data,"%d\n", mci->ue_noinfo_count);
661 }
662
663 static ssize_t mci_seconds_show(struct mem_ctl_info *mci, char *data)
664 {
665         return sprintf(data,"%ld\n", (jiffies - mci->start_time) / HZ);
666 }
667
668 static ssize_t mci_ctl_name_show(struct mem_ctl_info *mci, char *data)
669 {
670         return sprintf(data,"%s\n", mci->ctl_name);
671 }
672
673 static ssize_t mci_size_mb_show(struct mem_ctl_info *mci, char *data)
674 {
675         int total_pages, csrow_idx;
676
677         for (total_pages = csrow_idx = 0; csrow_idx < mci->nr_csrows;
678                         csrow_idx++) {
679                 struct csrow_info *csrow = &mci->csrows[csrow_idx];
680
681                 if (!csrow->nr_pages)
682                         continue;
683
684                 total_pages += csrow->nr_pages;
685         }
686
687         return sprintf(data,"%u\n", PAGES_TO_MiB(total_pages));
688 }
689
690 struct mcidev_attribute {
691         struct attribute attr;
692         ssize_t (*show)(struct mem_ctl_info *,char *);
693         ssize_t (*store)(struct mem_ctl_info *, const char *,size_t);
694 };
695
696 #define to_mci(k) container_of(k, struct mem_ctl_info, edac_mci_kobj)
697 #define to_mcidev_attr(a) container_of(a, struct mcidev_attribute, attr)
698
699 /* MCI show/store functions for top most object */
700 static ssize_t mcidev_show(struct kobject *kobj, struct attribute *attr,
701                 char *buffer)
702 {
703         struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
704         struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr);
705
706         if (mcidev_attr->show)
707                 return mcidev_attr->show(mem_ctl_info, buffer);
708
709         return -EIO;
710 }
711
712 static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr,
713                 const char *buffer, size_t count)
714 {
715         struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
716         struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr);
717
718         if (mcidev_attr->store)
719                 return mcidev_attr->store(mem_ctl_info, buffer, count);
720
721         return -EIO;
722 }
723
724 static struct sysfs_ops mci_ops = {
725         .show = mcidev_show,
726         .store = mcidev_store
727 };
728
729 #define MCIDEV_ATTR(_name,_mode,_show,_store)                   \
730 static struct mcidev_attribute mci_attr_##_name = {                     \
731         .attr = {.name = __stringify(_name), .mode = _mode },   \
732         .show   = _show,                                        \
733         .store  = _store,                                       \
734 };
735
736 /* default Control file */
737 MCIDEV_ATTR(reset_counters,S_IWUSR,NULL,mci_reset_counters_store);
738
739 /* default Attribute files */
740 MCIDEV_ATTR(mc_name,S_IRUGO,mci_ctl_name_show,NULL);
741 MCIDEV_ATTR(size_mb,S_IRUGO,mci_size_mb_show,NULL);
742 MCIDEV_ATTR(seconds_since_reset,S_IRUGO,mci_seconds_show,NULL);
743 MCIDEV_ATTR(ue_noinfo_count,S_IRUGO,mci_ue_noinfo_show,NULL);
744 MCIDEV_ATTR(ce_noinfo_count,S_IRUGO,mci_ce_noinfo_show,NULL);
745 MCIDEV_ATTR(ue_count,S_IRUGO,mci_ue_count_show,NULL);
746 MCIDEV_ATTR(ce_count,S_IRUGO,mci_ce_count_show,NULL);
747
748 /* memory scrubber attribute file */
749 MCIDEV_ATTR(sdram_scrub_rate,S_IRUGO|S_IWUSR,mci_sdram_scrub_rate_show,\
750                         mci_sdram_scrub_rate_store);
751
752 static struct mcidev_attribute *mci_attr[] = {
753         &mci_attr_reset_counters,
754         &mci_attr_mc_name,
755         &mci_attr_size_mb,
756         &mci_attr_seconds_since_reset,
757         &mci_attr_ue_noinfo_count,
758         &mci_attr_ce_noinfo_count,
759         &mci_attr_ue_count,
760         &mci_attr_ce_count,
761         &mci_attr_sdram_scrub_rate,
762         NULL
763 };
764
765 /*
766  * Release of a MC controlling instance
767  */
768 static void edac_mci_instance_release(struct kobject *kobj)
769 {
770         struct mem_ctl_info *mci;
771
772         mci = to_mci(kobj);
773         debugf0("%s() idx=%d\n", __func__, mci->mc_idx);
774         complete(&mci->kobj_complete);
775 }
776
777 static struct kobj_type ktype_mci = {
778         .release = edac_mci_instance_release,
779         .sysfs_ops = &mci_ops,
780         .default_attrs = (struct attribute **) mci_attr,
781 };
782
783
784 #define EDAC_DEVICE_SYMLINK     "device"
785
786 /*
787  * Create a new Memory Controller kobject instance,
788  *      mc<id> under the 'mc' directory
789  *
790  * Return:
791  *      0       Success
792  *      !0      Failure
793  */
794 int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
795 {
796         int i;
797         int err;
798         struct csrow_info *csrow;
799         struct kobject *edac_mci_kobj=&mci->edac_mci_kobj;
800
801         debugf0("%s() idx=%d\n", __func__, mci->mc_idx);
802         memset(edac_mci_kobj, 0, sizeof(*edac_mci_kobj));
803
804         /* set the name of the mc<id> object */
805         err = kobject_set_name(edac_mci_kobj,"mc%d",mci->mc_idx);
806         if (err)
807                 return err;
808
809         /* link to our parent the '..../edac/mc' object */
810         edac_mci_kobj->parent = &edac_memctrl_kobj;
811         edac_mci_kobj->ktype = &ktype_mci;
812
813         /* register the mc<id> kobject */
814         err = kobject_register(edac_mci_kobj);
815         if (err)
816                 return err;
817
818         /* create a symlink for the device */
819         err = sysfs_create_link(edac_mci_kobj, &mci->dev->kobj,
820                                 EDAC_DEVICE_SYMLINK);
821         if (err)
822                 goto fail0;
823
824         /* Make directories for each CSROW object
825          * under the mc<id> kobject
826          */
827         for (i = 0; i < mci->nr_csrows; i++) {
828                 csrow = &mci->csrows[i];
829
830                 /* Only expose populated CSROWs */
831                 if (csrow->nr_pages > 0) {
832                         err = edac_create_csrow_object(edac_mci_kobj,csrow,i);
833                         if (err)
834                                 goto fail1;
835                 }
836         }
837
838         return 0;
839
840         /* CSROW error: backout what has already been registered,  */
841 fail1:
842         for ( i--; i >= 0; i--) {
843                 if (csrow->nr_pages > 0) {
844                         init_completion(&csrow->kobj_complete);
845                         kobject_unregister(&mci->csrows[i].kobj);
846                         wait_for_completion(&csrow->kobj_complete);
847                 }
848         }
849
850 fail0:
851         init_completion(&mci->kobj_complete);
852         kobject_unregister(edac_mci_kobj);
853         wait_for_completion(&mci->kobj_complete);
854         return err;
855 }
856
857 /*
858  * remove a Memory Controller instance
859  */
860 void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
861 {
862         int i;
863
864         debugf0("%s()\n", __func__);
865
866         /* remove all csrow kobjects */
867         for (i = 0; i < mci->nr_csrows; i++) {
868                 if (mci->csrows[i].nr_pages > 0) {
869                         init_completion(&mci->csrows[i].kobj_complete);
870                         kobject_unregister(&mci->csrows[i].kobj);
871                         wait_for_completion(&mci->csrows[i].kobj_complete);
872                 }
873         }
874
875         sysfs_remove_link(&mci->edac_mci_kobj, EDAC_DEVICE_SYMLINK);
876         init_completion(&mci->kobj_complete);
877         kobject_unregister(&mci->edac_mci_kobj);
878         wait_for_completion(&mci->kobj_complete);
879 }
880
881