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