diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-24 16:25:43 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-10 10:45:02 -0400 |
commit | f338d736910edf00e8426ee4322cfda585268d50 (patch) | |
tree | b3cd07c94cc5ef6eab9107b04cec94e2f422494e /drivers/edac | |
parent | c419d921e68c54232ce6d369a3b528cd7644b2ae (diff) |
i7core_edac: Convert UDIMM error counters into a proper sysfs group
Instead of displaying 3 values at the same var, break it into 3
different sysfs nodes:
/sys/devices/system/edac/mc/mc0/all_channel_counts/udimm0
/sys/devices/system/edac/mc/mc0/all_channel_counts/udimm1
/sys/devices/system/edac/mc/mc0/all_channel_counts/udimm2
For registered dimms, however, the error counters are already being
displayed at:
/sys/devices/system/edac/mc/mc0/csrow*/ce_count
So, there's no need to add any extra sysfs nodes.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/i7core_edac.c | 81 |
1 files changed, 44 insertions, 37 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index e013004745de..97f6d1759c99 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
@@ -1003,38 +1003,32 @@ static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci, | |||
1003 | return sprintf(data, "%d\n", pvt->inject.enable); | 1003 | return sprintf(data, "%d\n", pvt->inject.enable); |
1004 | } | 1004 | } |
1005 | 1005 | ||
1006 | static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data) | 1006 | #define DECLARE_COUNTER(param) \ |
1007 | { | 1007 | static ssize_t i7core_show_counter_##param( \ |
1008 | unsigned i, count, total = 0; | 1008 | struct mem_ctl_info *mci, \ |
1009 | struct i7core_pvt *pvt = mci->pvt_info; | 1009 | char *data) \ |
1010 | { \ | ||
1011 | struct i7core_pvt *pvt = mci->pvt_info; \ | ||
1012 | \ | ||
1013 | debugf1("%s() \n", __func__); \ | ||
1014 | if (!pvt->ce_count_available || (pvt->is_registered)) \ | ||
1015 | return sprintf(data, "data unavailable\n"); \ | ||
1016 | return sprintf(data, "%lu\n", \ | ||
1017 | pvt->udimm_ce_count[param]); \ | ||
1018 | } | ||
1010 | 1019 | ||
1011 | if (!pvt->ce_count_available) { | 1020 | #define ATTR_COUNTER(param) \ |
1012 | count = sprintf(data, "data unavailable\n"); | 1021 | { \ |
1013 | return 0; | 1022 | .attr = { \ |
1014 | } | 1023 | .name = __stringify(udimm##param), \ |
1015 | if (!pvt->is_registered) { | 1024 | .mode = (S_IRUGO | S_IWUSR) \ |
1016 | count = sprintf(data, "all channels " | 1025 | }, \ |
1017 | "UDIMM0: %lu UDIMM1: %lu UDIMM2: %lu\n", | 1026 | .show = i7core_show_counter_##param \ |
1018 | pvt->udimm_ce_count[0], | ||
1019 | pvt->udimm_ce_count[1], | ||
1020 | pvt->udimm_ce_count[2]); | ||
1021 | data += count; | ||
1022 | total += count; | ||
1023 | } else { | ||
1024 | for (i = 0; i < NUM_CHANS; i++) { | ||
1025 | count = sprintf(data, "channel %d RDIMM0: %lu " | ||
1026 | "RDIMM1: %lu RDIMM2: %lu\n", | ||
1027 | i, | ||
1028 | pvt->rdimm_ce_count[i][0], | ||
1029 | pvt->rdimm_ce_count[i][1], | ||
1030 | pvt->rdimm_ce_count[i][2]); | ||
1031 | data += count; | ||
1032 | total += count; | ||
1033 | } | ||
1034 | } | 1027 | } |
1035 | 1028 | ||
1036 | return total; | 1029 | DECLARE_COUNTER(0); |
1037 | } | 1030 | DECLARE_COUNTER(1); |
1031 | DECLARE_COUNTER(2); | ||
1038 | 1032 | ||
1039 | /* | 1033 | /* |
1040 | * Sysfs struct | 1034 | * Sysfs struct |
@@ -1051,12 +1045,22 @@ static struct mcidev_sysfs_attribute i7core_addrmatch_attrs[] = { | |||
1051 | { .attr = { .name = NULL } } | 1045 | { .attr = { .name = NULL } } |
1052 | }; | 1046 | }; |
1053 | 1047 | ||
1054 | |||
1055 | static struct mcidev_sysfs_group i7core_inject_addrmatch = { | 1048 | static struct mcidev_sysfs_group i7core_inject_addrmatch = { |
1056 | .name = "inject_addrmatch", | 1049 | .name = "inject_addrmatch", |
1057 | .mcidev_attr = i7core_addrmatch_attrs, | 1050 | .mcidev_attr = i7core_addrmatch_attrs, |
1058 | }; | 1051 | }; |
1059 | 1052 | ||
1053 | static struct mcidev_sysfs_attribute i7core_udimm_counters_attrs[] = { | ||
1054 | ATTR_COUNTER(0), | ||
1055 | ATTR_COUNTER(1), | ||
1056 | ATTR_COUNTER(2), | ||
1057 | }; | ||
1058 | |||
1059 | static struct mcidev_sysfs_group i7core_udimm_counters = { | ||
1060 | .name = "all_channel_counts", | ||
1061 | .mcidev_attr = i7core_udimm_counters_attrs, | ||
1062 | }; | ||
1063 | |||
1060 | static struct mcidev_sysfs_attribute i7core_sysfs_attrs[] = { | 1064 | static struct mcidev_sysfs_attribute i7core_sysfs_attrs[] = { |
1061 | { | 1065 | { |
1062 | .attr = { | 1066 | .attr = { |
@@ -1088,14 +1092,8 @@ static struct mcidev_sysfs_attribute i7core_sysfs_attrs[] = { | |||
1088 | }, | 1092 | }, |
1089 | .show = i7core_inject_enable_show, | 1093 | .show = i7core_inject_enable_show, |
1090 | .store = i7core_inject_enable_store, | 1094 | .store = i7core_inject_enable_store, |
1091 | }, { | ||
1092 | .attr = { | ||
1093 | .name = "corrected_error_counts", | ||
1094 | .mode = (S_IRUGO | S_IWUSR) | ||
1095 | }, | ||
1096 | .show = i7core_ce_regs_show, | ||
1097 | .store = NULL, | ||
1098 | }, | 1095 | }, |
1096 | { .attr = { .name = NULL } }, /* Reserved for udimm counters */ | ||
1099 | { .attr = { .name = NULL } } | 1097 | { .attr = { .name = NULL } } |
1100 | }; | 1098 | }; |
1101 | 1099 | ||
@@ -1323,6 +1321,15 @@ static int mci_bind_devs(struct mem_ctl_info *mci, | |||
1323 | pvt->is_registered = 1; | 1321 | pvt->is_registered = 1; |
1324 | } | 1322 | } |
1325 | 1323 | ||
1324 | /* | ||
1325 | * Add extra nodes to count errors on udimm | ||
1326 | * For registered memory, this is not needed, since the counters | ||
1327 | * are already displayed at the standard locations | ||
1328 | */ | ||
1329 | if (!pvt->is_registered) | ||
1330 | i7core_sysfs_attrs[ARRAY_SIZE(i7core_sysfs_attrs)-2].grp = | ||
1331 | &i7core_udimm_counters; | ||
1332 | |||
1326 | return 0; | 1333 | return 0; |
1327 | 1334 | ||
1328 | error: | 1335 | error: |