diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-10-31 12:46:11 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-02-21 12:16:03 -0500 |
commit | e7e248304c8ccf02b89e04c3b3b66006b993b5a7 (patch) | |
tree | 3c1e41ddd4f3f3c9a2dd9f686498a028cb816029 /drivers/edac | |
parent | c7ef7645544131b0750478d1cf94cdfa945c809d (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>
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/edac_core.h | 5 | ||||
-rw-r--r-- | drivers/edac/edac_mc.c | 64 |
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); | |||
453 | extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev); | 453 | extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev); |
454 | extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, | 454 | extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, |
455 | unsigned long page); | 455 | unsigned long page); |
456 | |||
457 | void 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 | |||
456 | void edac_mc_handle_error(const enum hw_event_mc_err_type type, | 461 | void 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 | */ | ||
1080 | void 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 | } | ||
1107 | EXPORT_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 | } |
1272 | EXPORT_SYMBOL_GPL(edac_mc_handle_error); | 1292 | EXPORT_SYMBOL_GPL(edac_mc_handle_error); |