i7core_edac: Convert UDIMM error counters into a proper sysfs group
authorMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 24 Sep 2009 20:25:43 +0000 (17:25 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 10 May 2010 14:45:02 +0000 (11:45 -0300)
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>
drivers/edac/i7core_edac.c

index e013004..97f6d17 100644 (file)
@@ -1003,38 +1003,32 @@ static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci,
        return sprintf(data, "%d\n", pvt->inject.enable);
 }
 
-static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data)
-{
-       unsigned i, count, total = 0;
-       struct i7core_pvt *pvt = mci->pvt_info;
+#define DECLARE_COUNTER(param)                                 \
+static ssize_t i7core_show_counter_##param(                    \
+               struct mem_ctl_info *mci,                       \
+               char *data)                                     \
+{                                                              \
+       struct i7core_pvt *pvt = mci->pvt_info;                 \
+                                                               \
+       debugf1("%s() \n", __func__);                           \
+       if (!pvt->ce_count_available || (pvt->is_registered))   \
+               return sprintf(data, "data unavailable\n");     \
+       return sprintf(data, "%lu\n",                           \
+                       pvt->udimm_ce_count[param]);            \
+}
 
-       if (!pvt->ce_count_available) {
-               count = sprintf(data, "data unavailable\n");
-               return 0;
-       }
-       if (!pvt->is_registered) {
-               count = sprintf(data, "all channels "
-                               "UDIMM0: %lu UDIMM1: %lu UDIMM2: %lu\n",
-                               pvt->udimm_ce_count[0],
-                               pvt->udimm_ce_count[1],
-                               pvt->udimm_ce_count[2]);
-               data  += count;
-               total += count;
-       } else {
-               for (i = 0; i < NUM_CHANS; i++) {
-                       count = sprintf(data, "channel %d RDIMM0: %lu "
-                                       "RDIMM1: %lu RDIMM2: %lu\n",
-                                       i,
-                                       pvt->rdimm_ce_count[i][0],
-                                       pvt->rdimm_ce_count[i][1],
-                                       pvt->rdimm_ce_count[i][2]);
-                       data  += count;
-                       total += count;
-               }
+#define ATTR_COUNTER(param)                                    \
+       {                                                       \
+               .attr = {                                       \
+                       .name = __stringify(udimm##param),      \
+                       .mode = (S_IRUGO | S_IWUSR)             \
+               },                                              \
+               .show  = i7core_show_counter_##param            \
        }
 
-       return total;
-}
+DECLARE_COUNTER(0);
+DECLARE_COUNTER(1);
+DECLARE_COUNTER(2);
 
 /*
  * Sysfs struct
@@ -1051,12 +1045,22 @@ static struct mcidev_sysfs_attribute i7core_addrmatch_attrs[] = {
        { .attr = { .name = NULL } }
 };
 
-
 static struct mcidev_sysfs_group i7core_inject_addrmatch = {
        .name  = "inject_addrmatch",
        .mcidev_attr = i7core_addrmatch_attrs,
 };
 
+static struct mcidev_sysfs_attribute i7core_udimm_counters_attrs[] = {
+       ATTR_COUNTER(0),
+       ATTR_COUNTER(1),
+       ATTR_COUNTER(2),
+};
+
+static struct mcidev_sysfs_group i7core_udimm_counters = {
+       .name  = "all_channel_counts",
+       .mcidev_attr = i7core_udimm_counters_attrs,
+};
+
 static struct mcidev_sysfs_attribute i7core_sysfs_attrs[] = {
        {
                .attr = {
@@ -1088,14 +1092,8 @@ static struct mcidev_sysfs_attribute i7core_sysfs_attrs[] = {
                },
                .show  = i7core_inject_enable_show,
                .store = i7core_inject_enable_store,
-       }, {
-               .attr = {
-                       .name = "corrected_error_counts",
-                       .mode = (S_IRUGO | S_IWUSR)
-               },
-               .show  = i7core_ce_regs_show,
-               .store = NULL,
        },
+       { .attr = { .name = NULL } },   /* Reserved for udimm counters */
        { .attr = { .name = NULL } }
 };
 
@@ -1323,6 +1321,15 @@ static int mci_bind_devs(struct mem_ctl_info *mci,
                        pvt->is_registered = 1;
        }
 
+       /*
+        * Add extra nodes to count errors on udimm
+        * For registered memory, this is not needed, since the counters
+        * are already displayed at the standard locations
+        */
+       if (!pvt->is_registered)
+               i7core_sysfs_attrs[ARRAY_SIZE(i7core_sysfs_attrs)-2].grp =
+                       &i7core_udimm_counters;
+
        return 0;
 
 error: