edac: add support for raw error reports
authorMauro Carvalho Chehab <mchehab@redhat.com>
Wed, 31 Oct 2012 16:46:11 +0000 (13:46 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 21 Feb 2013 17:16:03 +0000 (14:16 -0300)
That allows APEI GHES driver to report errors directly, using
the EDAC error report API.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/edac/edac_core.h
drivers/edac/edac_mc.c

index 23bb99f..3c2625e 100644 (file)
@@ -453,6 +453,11 @@ extern struct mem_ctl_info *find_mci_by_dev(struct device *dev);
 extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev);
 extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
                                      unsigned long page);
+
+void edac_raw_mc_handle_error(const enum hw_event_mc_err_type type,
+                             struct mem_ctl_info *mci,
+                             struct edac_raw_error_desc *e);
+
 void edac_mc_handle_error(const enum hw_event_mc_err_type type,
                          struct mem_ctl_info *mci,
                          const u16 error_count,
index 4f18dd7..cdb81aa 100644 (file)
@@ -1065,6 +1065,46 @@ static void edac_ue_error(struct mem_ctl_info *mci,
        edac_inc_ue_error(mci, enable_per_layer_report, pos, error_count);
 }
 
+/**
+ * edac_raw_mc_handle_error - reports a memory event to userspace without doing
+ *                           anything to discover the error location
+ *
+ * @type:              severity of the error (CE/UE/Fatal)
+ * @mci:               a struct mem_ctl_info pointer
+ * @e:                 error description
+ *
+ * This raw function is used internally by edac_mc_handle_error(). It should
+ * only be called directly when the hardware error come directly from BIOS,
+ * like in the case of APEI GHES driver.
+ */
+void edac_raw_mc_handle_error(const enum hw_event_mc_err_type type,
+                             struct mem_ctl_info *mci,
+                             struct edac_raw_error_desc *e)
+{
+       char detail[80];
+       int pos[EDAC_MAX_LAYERS] = { e->top_layer, e->mid_layer, e->low_layer };
+
+       /* Memory type dependent details about the error */
+       if (type == HW_EVENT_ERR_CORRECTED) {
+               snprintf(detail, sizeof(detail),
+                       "page:0x%lx offset:0x%lx grain:%ld syndrome:0x%lx",
+                       e->page_frame_number, e->offset_in_page,
+                       e->grain, e->syndrome);
+               edac_ce_error(mci, e->error_count, pos, e->msg, e->location, e->label,
+                             detail, e->other_detail, e->enable_per_layer_report,
+                             e->page_frame_number, e->offset_in_page, e->grain);
+       } else {
+               snprintf(detail, sizeof(detail),
+                       "page:0x%lx offset:0x%lx grain:%ld",
+                       e->page_frame_number, e->offset_in_page, e->grain);
+
+               edac_ue_error(mci, e->error_count, pos, e->msg, e->location, e->label,
+                             detail, e->other_detail, e->enable_per_layer_report);
+       }
+
+
+}
+EXPORT_SYMBOL_GPL(edac_raw_mc_handle_error);
 
 /**
  * edac_mc_handle_error - reports a memory event to userspace
@@ -1096,7 +1136,6 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
                          const char *msg,
                          const char *other_detail)
 {
-       char detail[80];
        char *p;
        int row = -1, chan = -1;
        int pos[EDAC_MAX_LAYERS] = { top_layer, mid_layer, low_layer };
@@ -1246,27 +1285,8 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
        trace_mc_event(type, e->msg, e->label, e->error_count,
                       mci->mc_idx, e->top_layer, e->mid_layer, e->low_layer,
                       PAGES_TO_MiB(e->page_frame_number) | e->offset_in_page,
-                      grain_bits, e->syndrome, other_detail);
+                      grain_bits, e->syndrome, e->other_detail);
 
-       /* Memory type dependent details about the error */
-       if (type == HW_EVENT_ERR_CORRECTED) {
-               snprintf(detail, sizeof(detail),
-                       "page:0x%lx offset:0x%lx grain:%ld syndrome:0x%lx",
-                       e->page_frame_number, e->offset_in_page,
-                       e->grain, e->syndrome);
-               edac_ce_error(mci, e->error_count, pos, e->msg, e->location,
-                             e->label, detail, other_detail,
-                             e->enable_per_layer_report,
-                             e->page_frame_number, e->offset_in_page,
-                             e->grain);
-       } else {
-               snprintf(detail, sizeof(detail),
-                       "page:0x%lx offset:0x%lx grain:%ld",
-                       page_frame_number, offset_in_page, e->grain);
-
-               edac_ue_error(mci, e->error_count, pos, e->msg, e->location,
-                             e->label, detail, other_detail,
-                             e->enable_per_layer_report);
-       }
+       edac_raw_mc_handle_error(type, mci, e);
 }
 EXPORT_SYMBOL_GPL(edac_mc_handle_error);