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 | |
| 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>
| -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); |
