aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-10-31 12:46:11 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-02-21 12:16:03 -0500
commite7e248304c8ccf02b89e04c3b3b66006b993b5a7 (patch)
tree3c1e41ddd4f3f3c9a2dd9f686498a028cb816029
parentc7ef7645544131b0750478d1cf94cdfa945c809d (diff)
edac: add support for raw error reports
That allows APEI GHES driver to report errors directly, using the EDAC error report API. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/edac/edac_core.h5
-rw-r--r--drivers/edac/edac_mc.c64
2 files changed, 47 insertions, 22 deletions
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index 23bb99fa44f1..3c2625e7980d 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -453,6 +453,11 @@ extern struct mem_ctl_info *find_mci_by_dev(struct device *dev);
453extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev); 453extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev);
454extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, 454extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
455 unsigned long page); 455 unsigned long page);
456
457void edac_raw_mc_handle_error(const enum hw_event_mc_err_type type,
458 struct mem_ctl_info *mci,
459 struct edac_raw_error_desc *e);
460
456void edac_mc_handle_error(const enum hw_event_mc_err_type type, 461void edac_mc_handle_error(const enum hw_event_mc_err_type type,
457 struct mem_ctl_info *mci, 462 struct mem_ctl_info *mci,
458 const u16 error_count, 463 const u16 error_count,
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 4f18dd755939..cdb81aa73ab7 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -1065,6 +1065,46 @@ static void edac_ue_error(struct mem_ctl_info *mci,
1065 edac_inc_ue_error(mci, enable_per_layer_report, pos, error_count); 1065 edac_inc_ue_error(mci, enable_per_layer_report, pos, error_count);
1066} 1066}
1067 1067
1068/**
1069 * edac_raw_mc_handle_error - reports a memory event to userspace without doing
1070 * anything to discover the error location
1071 *
1072 * @type: severity of the error (CE/UE/Fatal)
1073 * @mci: a struct mem_ctl_info pointer
1074 * @e: error description
1075 *
1076 * This raw function is used internally by edac_mc_handle_error(). It should
1077 * only be called directly when the hardware error come directly from BIOS,
1078 * like in the case of APEI GHES driver.
1079 */
1080void edac_raw_mc_handle_error(const enum hw_event_mc_err_type type,
1081 struct mem_ctl_info *mci,
1082 struct edac_raw_error_desc *e)
1083{
1084 char detail[80];
1085 int pos[EDAC_MAX_LAYERS] = { e->top_layer, e->mid_layer, e->low_layer };
1086
1087 /* Memory type dependent details about the error */
1088 if (type == HW_EVENT_ERR_CORRECTED) {
1089 snprintf(detail, sizeof(detail),
1090 "page:0x%lx offset:0x%lx grain:%ld syndrome:0x%lx",
1091 e->page_frame_number, e->offset_in_page,
1092 e->grain, e->syndrome);
1093 edac_ce_error(mci, e->error_count, pos, e->msg, e->location, e->label,
1094 detail, e->other_detail, e->enable_per_layer_report,
1095 e->page_frame_number, e->offset_in_page, e->grain);
1096 } else {
1097 snprintf(detail, sizeof(detail),
1098 "page:0x%lx offset:0x%lx grain:%ld",
1099 e->page_frame_number, e->offset_in_page, e->grain);
1100
1101 edac_ue_error(mci, e->error_count, pos, e->msg, e->location, e->label,
1102 detail, e->other_detail, e->enable_per_layer_report);
1103 }
1104
1105
1106}
1107EXPORT_SYMBOL_GPL(edac_raw_mc_handle_error);
1068 1108
1069/** 1109/**
1070 * edac_mc_handle_error - reports a memory event to userspace 1110 * 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,
1096 const char *msg, 1136 const char *msg,
1097 const char *other_detail) 1137 const char *other_detail)
1098{ 1138{
1099 char detail[80];
1100 char *p; 1139 char *p;
1101 int row = -1, chan = -1; 1140 int row = -1, chan = -1;
1102 int pos[EDAC_MAX_LAYERS] = { top_layer, mid_layer, low_layer }; 1141 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,
1246 trace_mc_event(type, e->msg, e->label, e->error_count, 1285 trace_mc_event(type, e->msg, e->label, e->error_count,
1247 mci->mc_idx, e->top_layer, e->mid_layer, e->low_layer, 1286 mci->mc_idx, e->top_layer, e->mid_layer, e->low_layer,
1248 PAGES_TO_MiB(e->page_frame_number) | e->offset_in_page, 1287 PAGES_TO_MiB(e->page_frame_number) | e->offset_in_page,
1249 grain_bits, e->syndrome, other_detail); 1288 grain_bits, e->syndrome, e->other_detail);
1250 1289
1251 /* Memory type dependent details about the error */ 1290 edac_raw_mc_handle_error(type, mci, e);
1252 if (type == HW_EVENT_ERR_CORRECTED) {
1253 snprintf(detail, sizeof(detail),
1254 "page:0x%lx offset:0x%lx grain:%ld syndrome:0x%lx",
1255 e->page_frame_number, e->offset_in_page,
1256 e->grain, e->syndrome);
1257 edac_ce_error(mci, e->error_count, pos, e->msg, e->location,
1258 e->label, detail, other_detail,
1259 e->enable_per_layer_report,
1260 e->page_frame_number, e->offset_in_page,
1261 e->grain);
1262 } else {
1263 snprintf(detail, sizeof(detail),
1264 "page:0x%lx offset:0x%lx grain:%ld",
1265 page_frame_number, offset_in_page, e->grain);
1266
1267 edac_ue_error(mci, e->error_count, pos, e->msg, e->location,
1268 e->label, detail, other_detail,
1269 e->enable_per_layer_report);
1270 }
1271} 1291}
1272EXPORT_SYMBOL_GPL(edac_mc_handle_error); 1292EXPORT_SYMBOL_GPL(edac_mc_handle_error);