Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/edac/edac_mc_sysfs.c
29266 views
1
/*
2
* edac_mc kernel module
3
* (C) 2005-2007 Linux Networx (http://lnxi.com)
4
*
5
* This file may be distributed under the terms of the
6
* GNU General Public License.
7
*
8
* Written Doug Thompson <[email protected]> www.softwarebitmaker.com
9
*
10
* (c) 2012-2013 - Mauro Carvalho Chehab
11
* The entire API were re-written, and ported to use struct device
12
*
13
*/
14
15
#include <linux/ctype.h>
16
#include <linux/slab.h>
17
#include <linux/edac.h>
18
#include <linux/bug.h>
19
#include <linux/pm_runtime.h>
20
#include <linux/uaccess.h>
21
22
#include "edac_mc.h"
23
#include "edac_module.h"
24
25
/* MC EDAC Controls, setable by module parameter, and sysfs */
26
static int edac_mc_log_ue = 1;
27
static int edac_mc_log_ce = 1;
28
static int edac_mc_panic_on_ue;
29
static unsigned int edac_mc_poll_msec = 1000;
30
31
/* Getter functions for above */
32
int edac_mc_get_log_ue(void)
33
{
34
return edac_mc_log_ue;
35
}
36
37
int edac_mc_get_log_ce(void)
38
{
39
return edac_mc_log_ce;
40
}
41
42
int edac_mc_get_panic_on_ue(void)
43
{
44
return edac_mc_panic_on_ue;
45
}
46
47
/* this is temporary */
48
unsigned int edac_mc_get_poll_msec(void)
49
{
50
return edac_mc_poll_msec;
51
}
52
53
static int edac_set_poll_msec(const char *val, const struct kernel_param *kp)
54
{
55
unsigned int i;
56
int ret;
57
58
if (!val)
59
return -EINVAL;
60
61
ret = kstrtouint(val, 0, &i);
62
if (ret)
63
return ret;
64
65
if (i < 1000)
66
return -EINVAL;
67
68
*((unsigned int *)kp->arg) = i;
69
70
/* notify edac_mc engine to reset the poll period */
71
edac_mc_reset_delay_period(i);
72
73
return 0;
74
}
75
76
/* Parameter declarations for above */
77
module_param(edac_mc_panic_on_ue, int, 0644);
78
MODULE_PARM_DESC(edac_mc_panic_on_ue, "Panic on uncorrected error: 0=off 1=on");
79
module_param(edac_mc_log_ue, int, 0644);
80
MODULE_PARM_DESC(edac_mc_log_ue,
81
"Log uncorrectable error to console: 0=off 1=on");
82
module_param(edac_mc_log_ce, int, 0644);
83
MODULE_PARM_DESC(edac_mc_log_ce,
84
"Log correctable error to console: 0=off 1=on");
85
module_param_call(edac_mc_poll_msec, edac_set_poll_msec, param_get_uint,
86
&edac_mc_poll_msec, 0644);
87
MODULE_PARM_DESC(edac_mc_poll_msec, "Polling period in milliseconds");
88
89
static struct device *mci_pdev;
90
91
/*
92
* various constants for Memory Controllers
93
*/
94
static const char * const dev_types[] = {
95
[DEV_UNKNOWN] = "Unknown",
96
[DEV_X1] = "x1",
97
[DEV_X2] = "x2",
98
[DEV_X4] = "x4",
99
[DEV_X8] = "x8",
100
[DEV_X16] = "x16",
101
[DEV_X32] = "x32",
102
[DEV_X64] = "x64"
103
};
104
105
static const char * const edac_caps[] = {
106
[EDAC_UNKNOWN] = "Unknown",
107
[EDAC_NONE] = "None",
108
[EDAC_RESERVED] = "Reserved",
109
[EDAC_PARITY] = "PARITY",
110
[EDAC_EC] = "EC",
111
[EDAC_SECDED] = "SECDED",
112
[EDAC_S2ECD2ED] = "S2ECD2ED",
113
[EDAC_S4ECD4ED] = "S4ECD4ED",
114
[EDAC_S8ECD8ED] = "S8ECD8ED",
115
[EDAC_S16ECD16ED] = "S16ECD16ED"
116
};
117
118
#ifdef CONFIG_EDAC_LEGACY_SYSFS
119
/*
120
* EDAC sysfs CSROW data structures and methods
121
*/
122
123
#define to_csrow(k) container_of(k, struct csrow_info, dev)
124
125
/*
126
* We need it to avoid namespace conflicts between the legacy API
127
* and the per-dimm/per-rank one
128
*/
129
#define DEVICE_ATTR_LEGACY(_name, _mode, _show, _store) \
130
static struct device_attribute dev_attr_legacy_##_name = __ATTR(_name, _mode, _show, _store)
131
132
struct dev_ch_attribute {
133
struct device_attribute attr;
134
unsigned int channel;
135
};
136
137
#define DEVICE_CHANNEL(_name, _mode, _show, _store, _var) \
138
static struct dev_ch_attribute dev_attr_legacy_##_name = \
139
{ __ATTR(_name, _mode, _show, _store), (_var) }
140
141
#define to_channel(k) (container_of(k, struct dev_ch_attribute, attr)->channel)
142
143
/* Set of more default csrow<id> attribute show/store functions */
144
static ssize_t csrow_ue_count_show(struct device *dev,
145
struct device_attribute *mattr, char *data)
146
{
147
struct csrow_info *csrow = to_csrow(dev);
148
149
return sysfs_emit(data, "%u\n", csrow->ue_count);
150
}
151
152
static ssize_t csrow_ce_count_show(struct device *dev,
153
struct device_attribute *mattr, char *data)
154
{
155
struct csrow_info *csrow = to_csrow(dev);
156
157
return sysfs_emit(data, "%u\n", csrow->ce_count);
158
}
159
160
static ssize_t csrow_size_show(struct device *dev,
161
struct device_attribute *mattr, char *data)
162
{
163
struct csrow_info *csrow = to_csrow(dev);
164
int i;
165
u32 nr_pages = 0;
166
167
for (i = 0; i < csrow->nr_channels; i++)
168
nr_pages += csrow->channels[i]->dimm->nr_pages;
169
return sysfs_emit(data, "%u\n", PAGES_TO_MiB(nr_pages));
170
}
171
172
static ssize_t csrow_mem_type_show(struct device *dev,
173
struct device_attribute *mattr, char *data)
174
{
175
struct csrow_info *csrow = to_csrow(dev);
176
177
return sysfs_emit(data, "%s\n", edac_mem_types[csrow->channels[0]->dimm->mtype]);
178
}
179
180
static ssize_t csrow_dev_type_show(struct device *dev,
181
struct device_attribute *mattr, char *data)
182
{
183
struct csrow_info *csrow = to_csrow(dev);
184
185
return sysfs_emit(data, "%s\n", dev_types[csrow->channels[0]->dimm->dtype]);
186
}
187
188
static ssize_t csrow_edac_mode_show(struct device *dev,
189
struct device_attribute *mattr,
190
char *data)
191
{
192
struct csrow_info *csrow = to_csrow(dev);
193
194
return sysfs_emit(data, "%s\n", edac_caps[csrow->channels[0]->dimm->edac_mode]);
195
}
196
197
/* show/store functions for DIMM Label attributes */
198
static ssize_t channel_dimm_label_show(struct device *dev,
199
struct device_attribute *mattr,
200
char *data)
201
{
202
struct csrow_info *csrow = to_csrow(dev);
203
unsigned int chan = to_channel(mattr);
204
struct rank_info *rank = csrow->channels[chan];
205
206
/* if field has not been initialized, there is nothing to send */
207
if (!rank->dimm->label[0])
208
return 0;
209
210
return sysfs_emit(data, "%s\n", rank->dimm->label);
211
}
212
213
static ssize_t channel_dimm_label_store(struct device *dev,
214
struct device_attribute *mattr,
215
const char *data, size_t count)
216
{
217
struct csrow_info *csrow = to_csrow(dev);
218
unsigned int chan = to_channel(mattr);
219
struct rank_info *rank = csrow->channels[chan];
220
size_t copy_count = count;
221
222
if (count == 0)
223
return -EINVAL;
224
225
if (data[count - 1] == '\0' || data[count - 1] == '\n')
226
copy_count -= 1;
227
228
if (copy_count == 0 || copy_count >= sizeof(rank->dimm->label))
229
return -EINVAL;
230
231
memcpy(rank->dimm->label, data, copy_count);
232
rank->dimm->label[copy_count] = '\0';
233
234
return count;
235
}
236
237
/* show function for dynamic chX_ce_count attribute */
238
static ssize_t channel_ce_count_show(struct device *dev,
239
struct device_attribute *mattr, char *data)
240
{
241
struct csrow_info *csrow = to_csrow(dev);
242
unsigned int chan = to_channel(mattr);
243
struct rank_info *rank = csrow->channels[chan];
244
245
return sysfs_emit(data, "%u\n", rank->ce_count);
246
}
247
248
/* cwrow<id>/attribute files */
249
DEVICE_ATTR_LEGACY(size_mb, S_IRUGO, csrow_size_show, NULL);
250
DEVICE_ATTR_LEGACY(dev_type, S_IRUGO, csrow_dev_type_show, NULL);
251
DEVICE_ATTR_LEGACY(mem_type, S_IRUGO, csrow_mem_type_show, NULL);
252
DEVICE_ATTR_LEGACY(edac_mode, S_IRUGO, csrow_edac_mode_show, NULL);
253
DEVICE_ATTR_LEGACY(ue_count, S_IRUGO, csrow_ue_count_show, NULL);
254
DEVICE_ATTR_LEGACY(ce_count, S_IRUGO, csrow_ce_count_show, NULL);
255
256
/* default attributes of the CSROW<id> object */
257
static struct attribute *csrow_attrs[] = {
258
&dev_attr_legacy_dev_type.attr,
259
&dev_attr_legacy_mem_type.attr,
260
&dev_attr_legacy_edac_mode.attr,
261
&dev_attr_legacy_size_mb.attr,
262
&dev_attr_legacy_ue_count.attr,
263
&dev_attr_legacy_ce_count.attr,
264
NULL,
265
};
266
267
static const struct attribute_group csrow_attr_grp = {
268
.attrs = csrow_attrs,
269
};
270
271
static const struct attribute_group *csrow_attr_groups[] = {
272
&csrow_attr_grp,
273
NULL
274
};
275
276
static const struct device_type csrow_attr_type = {
277
.groups = csrow_attr_groups,
278
};
279
280
/*
281
* possible dynamic channel DIMM Label attribute files
282
*
283
*/
284
DEVICE_CHANNEL(ch0_dimm_label, S_IRUGO | S_IWUSR,
285
channel_dimm_label_show, channel_dimm_label_store, 0);
286
DEVICE_CHANNEL(ch1_dimm_label, S_IRUGO | S_IWUSR,
287
channel_dimm_label_show, channel_dimm_label_store, 1);
288
DEVICE_CHANNEL(ch2_dimm_label, S_IRUGO | S_IWUSR,
289
channel_dimm_label_show, channel_dimm_label_store, 2);
290
DEVICE_CHANNEL(ch3_dimm_label, S_IRUGO | S_IWUSR,
291
channel_dimm_label_show, channel_dimm_label_store, 3);
292
DEVICE_CHANNEL(ch4_dimm_label, S_IRUGO | S_IWUSR,
293
channel_dimm_label_show, channel_dimm_label_store, 4);
294
DEVICE_CHANNEL(ch5_dimm_label, S_IRUGO | S_IWUSR,
295
channel_dimm_label_show, channel_dimm_label_store, 5);
296
DEVICE_CHANNEL(ch6_dimm_label, S_IRUGO | S_IWUSR,
297
channel_dimm_label_show, channel_dimm_label_store, 6);
298
DEVICE_CHANNEL(ch7_dimm_label, S_IRUGO | S_IWUSR,
299
channel_dimm_label_show, channel_dimm_label_store, 7);
300
DEVICE_CHANNEL(ch8_dimm_label, S_IRUGO | S_IWUSR,
301
channel_dimm_label_show, channel_dimm_label_store, 8);
302
DEVICE_CHANNEL(ch9_dimm_label, S_IRUGO | S_IWUSR,
303
channel_dimm_label_show, channel_dimm_label_store, 9);
304
DEVICE_CHANNEL(ch10_dimm_label, S_IRUGO | S_IWUSR,
305
channel_dimm_label_show, channel_dimm_label_store, 10);
306
DEVICE_CHANNEL(ch11_dimm_label, S_IRUGO | S_IWUSR,
307
channel_dimm_label_show, channel_dimm_label_store, 11);
308
DEVICE_CHANNEL(ch12_dimm_label, S_IRUGO | S_IWUSR,
309
channel_dimm_label_show, channel_dimm_label_store, 12);
310
DEVICE_CHANNEL(ch13_dimm_label, S_IRUGO | S_IWUSR,
311
channel_dimm_label_show, channel_dimm_label_store, 13);
312
DEVICE_CHANNEL(ch14_dimm_label, S_IRUGO | S_IWUSR,
313
channel_dimm_label_show, channel_dimm_label_store, 14);
314
DEVICE_CHANNEL(ch15_dimm_label, S_IRUGO | S_IWUSR,
315
channel_dimm_label_show, channel_dimm_label_store, 15);
316
317
/* Total possible dynamic DIMM Label attribute file table */
318
static struct attribute *dynamic_csrow_dimm_attr[] = {
319
&dev_attr_legacy_ch0_dimm_label.attr.attr,
320
&dev_attr_legacy_ch1_dimm_label.attr.attr,
321
&dev_attr_legacy_ch2_dimm_label.attr.attr,
322
&dev_attr_legacy_ch3_dimm_label.attr.attr,
323
&dev_attr_legacy_ch4_dimm_label.attr.attr,
324
&dev_attr_legacy_ch5_dimm_label.attr.attr,
325
&dev_attr_legacy_ch6_dimm_label.attr.attr,
326
&dev_attr_legacy_ch7_dimm_label.attr.attr,
327
&dev_attr_legacy_ch8_dimm_label.attr.attr,
328
&dev_attr_legacy_ch9_dimm_label.attr.attr,
329
&dev_attr_legacy_ch10_dimm_label.attr.attr,
330
&dev_attr_legacy_ch11_dimm_label.attr.attr,
331
&dev_attr_legacy_ch12_dimm_label.attr.attr,
332
&dev_attr_legacy_ch13_dimm_label.attr.attr,
333
&dev_attr_legacy_ch14_dimm_label.attr.attr,
334
&dev_attr_legacy_ch15_dimm_label.attr.attr,
335
NULL
336
};
337
338
/* possible dynamic channel ce_count attribute files */
339
DEVICE_CHANNEL(ch0_ce_count, S_IRUGO,
340
channel_ce_count_show, NULL, 0);
341
DEVICE_CHANNEL(ch1_ce_count, S_IRUGO,
342
channel_ce_count_show, NULL, 1);
343
DEVICE_CHANNEL(ch2_ce_count, S_IRUGO,
344
channel_ce_count_show, NULL, 2);
345
DEVICE_CHANNEL(ch3_ce_count, S_IRUGO,
346
channel_ce_count_show, NULL, 3);
347
DEVICE_CHANNEL(ch4_ce_count, S_IRUGO,
348
channel_ce_count_show, NULL, 4);
349
DEVICE_CHANNEL(ch5_ce_count, S_IRUGO,
350
channel_ce_count_show, NULL, 5);
351
DEVICE_CHANNEL(ch6_ce_count, S_IRUGO,
352
channel_ce_count_show, NULL, 6);
353
DEVICE_CHANNEL(ch7_ce_count, S_IRUGO,
354
channel_ce_count_show, NULL, 7);
355
DEVICE_CHANNEL(ch8_ce_count, S_IRUGO,
356
channel_ce_count_show, NULL, 8);
357
DEVICE_CHANNEL(ch9_ce_count, S_IRUGO,
358
channel_ce_count_show, NULL, 9);
359
DEVICE_CHANNEL(ch10_ce_count, S_IRUGO,
360
channel_ce_count_show, NULL, 10);
361
DEVICE_CHANNEL(ch11_ce_count, S_IRUGO,
362
channel_ce_count_show, NULL, 11);
363
DEVICE_CHANNEL(ch12_ce_count, S_IRUGO,
364
channel_ce_count_show, NULL, 12);
365
DEVICE_CHANNEL(ch13_ce_count, S_IRUGO,
366
channel_ce_count_show, NULL, 13);
367
DEVICE_CHANNEL(ch14_ce_count, S_IRUGO,
368
channel_ce_count_show, NULL, 14);
369
DEVICE_CHANNEL(ch15_ce_count, S_IRUGO,
370
channel_ce_count_show, NULL, 15);
371
372
/* Total possible dynamic ce_count attribute file table */
373
static struct attribute *dynamic_csrow_ce_count_attr[] = {
374
&dev_attr_legacy_ch0_ce_count.attr.attr,
375
&dev_attr_legacy_ch1_ce_count.attr.attr,
376
&dev_attr_legacy_ch2_ce_count.attr.attr,
377
&dev_attr_legacy_ch3_ce_count.attr.attr,
378
&dev_attr_legacy_ch4_ce_count.attr.attr,
379
&dev_attr_legacy_ch5_ce_count.attr.attr,
380
&dev_attr_legacy_ch6_ce_count.attr.attr,
381
&dev_attr_legacy_ch7_ce_count.attr.attr,
382
&dev_attr_legacy_ch8_ce_count.attr.attr,
383
&dev_attr_legacy_ch9_ce_count.attr.attr,
384
&dev_attr_legacy_ch10_ce_count.attr.attr,
385
&dev_attr_legacy_ch11_ce_count.attr.attr,
386
&dev_attr_legacy_ch12_ce_count.attr.attr,
387
&dev_attr_legacy_ch13_ce_count.attr.attr,
388
&dev_attr_legacy_ch14_ce_count.attr.attr,
389
&dev_attr_legacy_ch15_ce_count.attr.attr,
390
NULL
391
};
392
393
static umode_t csrow_dev_is_visible(struct kobject *kobj,
394
struct attribute *attr, int idx)
395
{
396
struct device *dev = kobj_to_dev(kobj);
397
struct csrow_info *csrow = container_of(dev, struct csrow_info, dev);
398
399
if (idx >= csrow->nr_channels)
400
return 0;
401
402
if (idx >= ARRAY_SIZE(dynamic_csrow_ce_count_attr) - 1) {
403
WARN_ONCE(1, "idx: %d\n", idx);
404
return 0;
405
}
406
407
/* Only expose populated DIMMs */
408
if (!csrow->channels[idx]->dimm->nr_pages)
409
return 0;
410
411
return attr->mode;
412
}
413
414
415
static const struct attribute_group csrow_dev_dimm_group = {
416
.attrs = dynamic_csrow_dimm_attr,
417
.is_visible = csrow_dev_is_visible,
418
};
419
420
static const struct attribute_group csrow_dev_ce_count_group = {
421
.attrs = dynamic_csrow_ce_count_attr,
422
.is_visible = csrow_dev_is_visible,
423
};
424
425
static const struct attribute_group *csrow_dev_groups[] = {
426
&csrow_dev_dimm_group,
427
&csrow_dev_ce_count_group,
428
NULL
429
};
430
431
static void csrow_release(struct device *dev)
432
{
433
/*
434
* Nothing to do, just unregister sysfs here. The mci
435
* device owns the data and will also release it.
436
*/
437
}
438
439
static inline int nr_pages_per_csrow(struct csrow_info *csrow)
440
{
441
int chan, nr_pages = 0;
442
443
for (chan = 0; chan < csrow->nr_channels; chan++)
444
nr_pages += csrow->channels[chan]->dimm->nr_pages;
445
446
return nr_pages;
447
}
448
449
/* Create a CSROW object under specified edac_mc_device */
450
static int edac_create_csrow_object(struct mem_ctl_info *mci,
451
struct csrow_info *csrow, int index)
452
{
453
int err;
454
455
csrow->dev.type = &csrow_attr_type;
456
csrow->dev.groups = csrow_dev_groups;
457
csrow->dev.release = csrow_release;
458
device_initialize(&csrow->dev);
459
csrow->dev.parent = &mci->dev;
460
csrow->mci = mci;
461
dev_set_name(&csrow->dev, "csrow%d", index);
462
dev_set_drvdata(&csrow->dev, csrow);
463
464
err = device_add(&csrow->dev);
465
if (err) {
466
edac_dbg(1, "failure: create device %s\n", dev_name(&csrow->dev));
467
put_device(&csrow->dev);
468
return err;
469
}
470
471
edac_dbg(0, "device %s created\n", dev_name(&csrow->dev));
472
473
return 0;
474
}
475
476
/* Create a CSROW object under specified edac_mc_device */
477
static int edac_create_csrow_objects(struct mem_ctl_info *mci)
478
{
479
int err, i;
480
struct csrow_info *csrow;
481
482
for (i = 0; i < mci->nr_csrows; i++) {
483
csrow = mci->csrows[i];
484
if (!nr_pages_per_csrow(csrow))
485
continue;
486
err = edac_create_csrow_object(mci, mci->csrows[i], i);
487
if (err < 0)
488
goto error;
489
}
490
return 0;
491
492
error:
493
for (--i; i >= 0; i--) {
494
if (device_is_registered(&mci->csrows[i]->dev))
495
device_unregister(&mci->csrows[i]->dev);
496
}
497
498
return err;
499
}
500
501
static void edac_delete_csrow_objects(struct mem_ctl_info *mci)
502
{
503
int i;
504
505
for (i = 0; i < mci->nr_csrows; i++) {
506
if (device_is_registered(&mci->csrows[i]->dev))
507
device_unregister(&mci->csrows[i]->dev);
508
}
509
}
510
511
#endif
512
513
/*
514
* Per-dimm (or per-rank) devices
515
*/
516
517
#define to_dimm(k) container_of(k, struct dimm_info, dev)
518
519
/* show/store functions for DIMM Label attributes */
520
static ssize_t dimmdev_location_show(struct device *dev,
521
struct device_attribute *mattr, char *data)
522
{
523
struct dimm_info *dimm = to_dimm(dev);
524
ssize_t count;
525
526
count = edac_dimm_info_location(dimm, data, PAGE_SIZE);
527
count += scnprintf(data + count, PAGE_SIZE - count, "\n");
528
529
return count;
530
}
531
532
static ssize_t dimmdev_label_show(struct device *dev,
533
struct device_attribute *mattr, char *data)
534
{
535
struct dimm_info *dimm = to_dimm(dev);
536
537
/* if field has not been initialized, there is nothing to send */
538
if (!dimm->label[0])
539
return 0;
540
541
return sysfs_emit(data, "%s\n", dimm->label);
542
}
543
544
static ssize_t dimmdev_label_store(struct device *dev,
545
struct device_attribute *mattr,
546
const char *data,
547
size_t count)
548
{
549
struct dimm_info *dimm = to_dimm(dev);
550
size_t copy_count = count;
551
552
if (count == 0)
553
return -EINVAL;
554
555
if (data[count - 1] == '\0' || data[count - 1] == '\n')
556
copy_count -= 1;
557
558
if (copy_count == 0 || copy_count >= sizeof(dimm->label))
559
return -EINVAL;
560
561
memcpy(dimm->label, data, copy_count);
562
dimm->label[copy_count] = '\0';
563
564
return count;
565
}
566
567
static ssize_t dimmdev_size_show(struct device *dev,
568
struct device_attribute *mattr, char *data)
569
{
570
struct dimm_info *dimm = to_dimm(dev);
571
572
return sysfs_emit(data, "%u\n", PAGES_TO_MiB(dimm->nr_pages));
573
}
574
575
static ssize_t dimmdev_mem_type_show(struct device *dev,
576
struct device_attribute *mattr, char *data)
577
{
578
struct dimm_info *dimm = to_dimm(dev);
579
580
return sysfs_emit(data, "%s\n", edac_mem_types[dimm->mtype]);
581
}
582
583
static ssize_t dimmdev_dev_type_show(struct device *dev,
584
struct device_attribute *mattr, char *data)
585
{
586
struct dimm_info *dimm = to_dimm(dev);
587
588
return sysfs_emit(data, "%s\n", dev_types[dimm->dtype]);
589
}
590
591
static ssize_t dimmdev_edac_mode_show(struct device *dev,
592
struct device_attribute *mattr,
593
char *data)
594
{
595
struct dimm_info *dimm = to_dimm(dev);
596
597
return sysfs_emit(data, "%s\n", edac_caps[dimm->edac_mode]);
598
}
599
600
static ssize_t dimmdev_ce_count_show(struct device *dev,
601
struct device_attribute *mattr,
602
char *data)
603
{
604
struct dimm_info *dimm = to_dimm(dev);
605
606
return sysfs_emit(data, "%u\n", dimm->ce_count);
607
}
608
609
static ssize_t dimmdev_ue_count_show(struct device *dev,
610
struct device_attribute *mattr,
611
char *data)
612
{
613
struct dimm_info *dimm = to_dimm(dev);
614
615
return sysfs_emit(data, "%u\n", dimm->ue_count);
616
}
617
618
/* dimm/rank attribute files */
619
static DEVICE_ATTR(dimm_label, S_IRUGO | S_IWUSR,
620
dimmdev_label_show, dimmdev_label_store);
621
static DEVICE_ATTR(dimm_location, S_IRUGO, dimmdev_location_show, NULL);
622
static DEVICE_ATTR(size, S_IRUGO, dimmdev_size_show, NULL);
623
static DEVICE_ATTR(dimm_mem_type, S_IRUGO, dimmdev_mem_type_show, NULL);
624
static DEVICE_ATTR(dimm_dev_type, S_IRUGO, dimmdev_dev_type_show, NULL);
625
static DEVICE_ATTR(dimm_edac_mode, S_IRUGO, dimmdev_edac_mode_show, NULL);
626
static DEVICE_ATTR(dimm_ce_count, S_IRUGO, dimmdev_ce_count_show, NULL);
627
static DEVICE_ATTR(dimm_ue_count, S_IRUGO, dimmdev_ue_count_show, NULL);
628
629
/* attributes of the dimm<id>/rank<id> object */
630
static struct attribute *dimm_attrs[] = {
631
&dev_attr_dimm_label.attr,
632
&dev_attr_dimm_location.attr,
633
&dev_attr_size.attr,
634
&dev_attr_dimm_mem_type.attr,
635
&dev_attr_dimm_dev_type.attr,
636
&dev_attr_dimm_edac_mode.attr,
637
&dev_attr_dimm_ce_count.attr,
638
&dev_attr_dimm_ue_count.attr,
639
NULL,
640
};
641
642
static const struct attribute_group dimm_attr_grp = {
643
.attrs = dimm_attrs,
644
};
645
646
static const struct attribute_group *dimm_attr_groups[] = {
647
&dimm_attr_grp,
648
NULL
649
};
650
651
static const struct device_type dimm_attr_type = {
652
.groups = dimm_attr_groups,
653
};
654
655
static void dimm_release(struct device *dev)
656
{
657
/*
658
* Nothing to do, just unregister sysfs here. The mci
659
* device owns the data and will also release it.
660
*/
661
}
662
663
/* Create a DIMM object under specified memory controller device */
664
static int edac_create_dimm_object(struct mem_ctl_info *mci,
665
struct dimm_info *dimm)
666
{
667
int err;
668
dimm->mci = mci;
669
670
dimm->dev.type = &dimm_attr_type;
671
dimm->dev.release = dimm_release;
672
device_initialize(&dimm->dev);
673
674
dimm->dev.parent = &mci->dev;
675
if (mci->csbased)
676
dev_set_name(&dimm->dev, "rank%d", dimm->idx);
677
else
678
dev_set_name(&dimm->dev, "dimm%d", dimm->idx);
679
dev_set_drvdata(&dimm->dev, dimm);
680
pm_runtime_forbid(&mci->dev);
681
682
err = device_add(&dimm->dev);
683
if (err) {
684
edac_dbg(1, "failure: create device %s\n", dev_name(&dimm->dev));
685
put_device(&dimm->dev);
686
return err;
687
}
688
689
if (IS_ENABLED(CONFIG_EDAC_DEBUG)) {
690
char location[80];
691
692
edac_dimm_info_location(dimm, location, sizeof(location));
693
edac_dbg(0, "device %s created at location %s\n",
694
dev_name(&dimm->dev), location);
695
}
696
697
return 0;
698
}
699
700
/*
701
* Memory controller device
702
*/
703
704
#define to_mci(k) container_of(k, struct mem_ctl_info, dev)
705
706
static ssize_t mci_reset_counters_store(struct device *dev,
707
struct device_attribute *mattr,
708
const char *data, size_t count)
709
{
710
struct mem_ctl_info *mci = to_mci(dev);
711
struct dimm_info *dimm;
712
int row, chan;
713
714
mci->ue_mc = 0;
715
mci->ce_mc = 0;
716
mci->ue_noinfo_count = 0;
717
mci->ce_noinfo_count = 0;
718
719
for (row = 0; row < mci->nr_csrows; row++) {
720
struct csrow_info *ri = mci->csrows[row];
721
722
ri->ue_count = 0;
723
ri->ce_count = 0;
724
725
for (chan = 0; chan < ri->nr_channels; chan++)
726
ri->channels[chan]->ce_count = 0;
727
}
728
729
mci_for_each_dimm(mci, dimm) {
730
dimm->ue_count = 0;
731
dimm->ce_count = 0;
732
}
733
734
mci->start_time = jiffies;
735
return count;
736
}
737
738
/* Memory scrubbing interface:
739
*
740
* A MC driver can limit the scrubbing bandwidth based on the CPU type.
741
* Therefore, ->set_sdram_scrub_rate should be made to return the actual
742
* bandwidth that is accepted or 0 when scrubbing is to be disabled.
743
*
744
* Negative value still means that an error has occurred while setting
745
* the scrub rate.
746
*/
747
static ssize_t mci_sdram_scrub_rate_store(struct device *dev,
748
struct device_attribute *mattr,
749
const char *data, size_t count)
750
{
751
struct mem_ctl_info *mci = to_mci(dev);
752
unsigned long bandwidth = 0;
753
int new_bw = 0;
754
755
if (kstrtoul(data, 10, &bandwidth) < 0)
756
return -EINVAL;
757
758
new_bw = mci->set_sdram_scrub_rate(mci, bandwidth);
759
if (new_bw < 0) {
760
edac_printk(KERN_WARNING, EDAC_MC,
761
"Error setting scrub rate to: %lu\n", bandwidth);
762
return -EINVAL;
763
}
764
765
return count;
766
}
767
768
/*
769
* ->get_sdram_scrub_rate() return value semantics same as above.
770
*/
771
static ssize_t mci_sdram_scrub_rate_show(struct device *dev,
772
struct device_attribute *mattr,
773
char *data)
774
{
775
struct mem_ctl_info *mci = to_mci(dev);
776
int bandwidth = 0;
777
778
bandwidth = mci->get_sdram_scrub_rate(mci);
779
if (bandwidth < 0) {
780
edac_printk(KERN_DEBUG, EDAC_MC, "Error reading scrub rate\n");
781
return bandwidth;
782
}
783
784
return sysfs_emit(data, "%d\n", bandwidth);
785
}
786
787
/* default attribute files for the MCI object */
788
static ssize_t mci_ue_count_show(struct device *dev,
789
struct device_attribute *mattr,
790
char *data)
791
{
792
struct mem_ctl_info *mci = to_mci(dev);
793
794
return sysfs_emit(data, "%u\n", mci->ue_mc);
795
}
796
797
static ssize_t mci_ce_count_show(struct device *dev,
798
struct device_attribute *mattr,
799
char *data)
800
{
801
struct mem_ctl_info *mci = to_mci(dev);
802
803
return sysfs_emit(data, "%u\n", mci->ce_mc);
804
}
805
806
static ssize_t mci_ce_noinfo_show(struct device *dev,
807
struct device_attribute *mattr,
808
char *data)
809
{
810
struct mem_ctl_info *mci = to_mci(dev);
811
812
return sysfs_emit(data, "%u\n", mci->ce_noinfo_count);
813
}
814
815
static ssize_t mci_ue_noinfo_show(struct device *dev,
816
struct device_attribute *mattr,
817
char *data)
818
{
819
struct mem_ctl_info *mci = to_mci(dev);
820
821
return sysfs_emit(data, "%u\n", mci->ue_noinfo_count);
822
}
823
824
static ssize_t mci_seconds_show(struct device *dev,
825
struct device_attribute *mattr,
826
char *data)
827
{
828
struct mem_ctl_info *mci = to_mci(dev);
829
830
return sysfs_emit(data, "%ld\n", (jiffies - mci->start_time) / HZ);
831
}
832
833
static ssize_t mci_ctl_name_show(struct device *dev,
834
struct device_attribute *mattr,
835
char *data)
836
{
837
struct mem_ctl_info *mci = to_mci(dev);
838
839
return sysfs_emit(data, "%s\n", mci->ctl_name);
840
}
841
842
static ssize_t mci_size_mb_show(struct device *dev,
843
struct device_attribute *mattr,
844
char *data)
845
{
846
struct mem_ctl_info *mci = to_mci(dev);
847
int total_pages = 0, csrow_idx, j;
848
849
for (csrow_idx = 0; csrow_idx < mci->nr_csrows; csrow_idx++) {
850
struct csrow_info *csrow = mci->csrows[csrow_idx];
851
852
for (j = 0; j < csrow->nr_channels; j++) {
853
struct dimm_info *dimm = csrow->channels[j]->dimm;
854
855
total_pages += dimm->nr_pages;
856
}
857
}
858
859
return sysfs_emit(data, "%u\n", PAGES_TO_MiB(total_pages));
860
}
861
862
static ssize_t mci_max_location_show(struct device *dev,
863
struct device_attribute *mattr,
864
char *data)
865
{
866
struct mem_ctl_info *mci = to_mci(dev);
867
int len = PAGE_SIZE;
868
char *p = data;
869
int i, n;
870
871
for (i = 0; i < mci->n_layers; i++) {
872
n = scnprintf(p, len, "%s %d ",
873
edac_layer_name[mci->layers[i].type],
874
mci->layers[i].size - 1);
875
len -= n;
876
if (len <= 0)
877
goto out;
878
879
p += n;
880
}
881
882
p += scnprintf(p, len, "\n");
883
out:
884
return p - data;
885
}
886
887
/* default Control file */
888
static DEVICE_ATTR(reset_counters, S_IWUSR, NULL, mci_reset_counters_store);
889
890
/* default Attribute files */
891
static DEVICE_ATTR(mc_name, S_IRUGO, mci_ctl_name_show, NULL);
892
static DEVICE_ATTR(size_mb, S_IRUGO, mci_size_mb_show, NULL);
893
static DEVICE_ATTR(seconds_since_reset, S_IRUGO, mci_seconds_show, NULL);
894
static DEVICE_ATTR(ue_noinfo_count, S_IRUGO, mci_ue_noinfo_show, NULL);
895
static DEVICE_ATTR(ce_noinfo_count, S_IRUGO, mci_ce_noinfo_show, NULL);
896
static DEVICE_ATTR(ue_count, S_IRUGO, mci_ue_count_show, NULL);
897
static DEVICE_ATTR(ce_count, S_IRUGO, mci_ce_count_show, NULL);
898
static DEVICE_ATTR(max_location, S_IRUGO, mci_max_location_show, NULL);
899
900
/* memory scrubber attribute file */
901
static DEVICE_ATTR(sdram_scrub_rate, 0, mci_sdram_scrub_rate_show,
902
mci_sdram_scrub_rate_store); /* umode set later in is_visible */
903
904
static struct attribute *mci_attrs[] = {
905
&dev_attr_reset_counters.attr,
906
&dev_attr_mc_name.attr,
907
&dev_attr_size_mb.attr,
908
&dev_attr_seconds_since_reset.attr,
909
&dev_attr_ue_noinfo_count.attr,
910
&dev_attr_ce_noinfo_count.attr,
911
&dev_attr_ue_count.attr,
912
&dev_attr_ce_count.attr,
913
&dev_attr_max_location.attr,
914
&dev_attr_sdram_scrub_rate.attr,
915
NULL
916
};
917
918
static umode_t mci_attr_is_visible(struct kobject *kobj,
919
struct attribute *attr, int idx)
920
{
921
struct device *dev = kobj_to_dev(kobj);
922
struct mem_ctl_info *mci = to_mci(dev);
923
umode_t mode = 0;
924
925
if (attr != &dev_attr_sdram_scrub_rate.attr)
926
return attr->mode;
927
if (mci->get_sdram_scrub_rate)
928
mode |= S_IRUGO;
929
if (mci->set_sdram_scrub_rate)
930
mode |= S_IWUSR;
931
return mode;
932
}
933
934
static const struct attribute_group mci_attr_grp = {
935
.attrs = mci_attrs,
936
.is_visible = mci_attr_is_visible,
937
};
938
939
static const struct attribute_group *mci_attr_groups[] = {
940
&mci_attr_grp,
941
NULL
942
};
943
944
static const struct device_type mci_attr_type = {
945
.groups = mci_attr_groups,
946
};
947
948
/*
949
* Create a new Memory Controller kobject instance,
950
* mc<id> under the 'mc' directory
951
*
952
* Return:
953
* 0 Success
954
* !0 Failure
955
*/
956
int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
957
const struct attribute_group **groups)
958
{
959
struct dimm_info *dimm;
960
int err;
961
962
/* get the /sys/devices/system/edac subsys reference */
963
mci->dev.type = &mci_attr_type;
964
mci->dev.parent = mci_pdev;
965
mci->dev.groups = groups;
966
dev_set_name(&mci->dev, "mc%d", mci->mc_idx);
967
dev_set_drvdata(&mci->dev, mci);
968
pm_runtime_forbid(&mci->dev);
969
970
err = device_add(&mci->dev);
971
if (err < 0) {
972
edac_dbg(1, "failure: create device %s\n", dev_name(&mci->dev));
973
/* no put_device() here, free mci with _edac_mc_free() */
974
return err;
975
}
976
977
edac_dbg(0, "device %s created\n", dev_name(&mci->dev));
978
979
/*
980
* Create the dimm/rank devices
981
*/
982
mci_for_each_dimm(mci, dimm) {
983
/* Only expose populated DIMMs */
984
if (!dimm->nr_pages)
985
continue;
986
987
err = edac_create_dimm_object(mci, dimm);
988
if (err)
989
goto fail;
990
}
991
992
#ifdef CONFIG_EDAC_LEGACY_SYSFS
993
err = edac_create_csrow_objects(mci);
994
if (err < 0)
995
goto fail;
996
#endif
997
998
edac_create_debugfs_nodes(mci);
999
return 0;
1000
1001
fail:
1002
edac_remove_sysfs_mci_device(mci);
1003
1004
return err;
1005
}
1006
1007
/*
1008
* remove a Memory Controller instance
1009
*/
1010
void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
1011
{
1012
struct dimm_info *dimm;
1013
1014
if (!device_is_registered(&mci->dev))
1015
return;
1016
1017
edac_dbg(0, "\n");
1018
1019
#ifdef CONFIG_EDAC_DEBUG
1020
edac_debugfs_remove_recursive(mci->debugfs);
1021
#endif
1022
#ifdef CONFIG_EDAC_LEGACY_SYSFS
1023
edac_delete_csrow_objects(mci);
1024
#endif
1025
1026
mci_for_each_dimm(mci, dimm) {
1027
if (!device_is_registered(&dimm->dev))
1028
continue;
1029
edac_dbg(1, "unregistering device %s\n", dev_name(&dimm->dev));
1030
device_unregister(&dimm->dev);
1031
}
1032
1033
/* only remove the device, but keep mci */
1034
device_del(&mci->dev);
1035
}
1036
1037
static void mc_attr_release(struct device *dev)
1038
{
1039
/*
1040
* There's no container structure here, as this is just the mci
1041
* parent device, used to create the /sys/devices/mc sysfs node.
1042
* So, there are no attributes on it.
1043
*/
1044
edac_dbg(1, "device %s released\n", dev_name(dev));
1045
kfree(dev);
1046
}
1047
1048
/*
1049
* Init/exit code for the module. Basically, creates/removes /sys/class/rc
1050
*/
1051
int __init edac_mc_sysfs_init(void)
1052
{
1053
int err;
1054
1055
mci_pdev = kzalloc(sizeof(*mci_pdev), GFP_KERNEL);
1056
if (!mci_pdev)
1057
return -ENOMEM;
1058
1059
mci_pdev->bus = edac_get_sysfs_subsys();
1060
mci_pdev->release = mc_attr_release;
1061
mci_pdev->init_name = "mc";
1062
1063
err = device_register(mci_pdev);
1064
if (err < 0) {
1065
edac_dbg(1, "failure: create device %s\n", dev_name(mci_pdev));
1066
put_device(mci_pdev);
1067
return err;
1068
}
1069
1070
edac_dbg(0, "device %s created\n", dev_name(mci_pdev));
1071
1072
return 0;
1073
}
1074
1075
void edac_mc_sysfs_exit(void)
1076
{
1077
device_unregister(mci_pdev);
1078
}
1079
1080