static void i7core_mce_output_error()

in i7core_edac.c [1694:1785]


static void i7core_mce_output_error(struct mem_ctl_info *mci,
				    const struct mce *m)
{
	struct i7core_pvt *pvt = mci->pvt_info;
	char *optype, *err;
	enum hw_event_mc_err_type tp_event;
	unsigned long error = m->status & 0x1ff0000l;
	bool uncorrected_error = m->mcgstatus & 1ll << 61;
	bool ripv = m->mcgstatus & 1;
	u32 optypenum = (m->status >> 4) & 0x07;
	u32 core_err_cnt = (m->status >> 38) & 0x7fff;
	u32 dimm = (m->misc >> 16) & 0x3;
	u32 channel = (m->misc >> 18) & 0x3;
	u32 syndrome = m->misc >> 32;
	u32 errnum = find_first_bit(&error, 32);

	if (uncorrected_error) {
		core_err_cnt = 1;
		if (ripv)
			tp_event = HW_EVENT_ERR_UNCORRECTED;
		else
			tp_event = HW_EVENT_ERR_FATAL;
	} else {
		tp_event = HW_EVENT_ERR_CORRECTED;
	}

	switch (optypenum) {
	case 0:
		optype = "generic undef request";
		break;
	case 1:
		optype = "read error";
		break;
	case 2:
		optype = "write error";
		break;
	case 3:
		optype = "addr/cmd error";
		break;
	case 4:
		optype = "scrubbing error";
		break;
	default:
		optype = "reserved";
		break;
	}

	switch (errnum) {
	case 16:
		err = "read ECC error";
		break;
	case 17:
		err = "RAS ECC error";
		break;
	case 18:
		err = "write parity error";
		break;
	case 19:
		err = "redundancy loss";
		break;
	case 20:
		err = "reserved";
		break;
	case 21:
		err = "memory range error";
		break;
	case 22:
		err = "RTID out of range";
		break;
	case 23:
		err = "address parity error";
		break;
	case 24:
		err = "byte enable parity error";
		break;
	default:
		err = "unknown";
	}

	/*
	 * Call the helper to output message
	 * FIXME: what to do if core_err_cnt > 1? Currently, it generates
	 * only one event
	 */
	if (uncorrected_error || !pvt->is_registered)
		edac_mc_handle_error(tp_event, mci, core_err_cnt,
				     m->addr >> PAGE_SHIFT,
				     m->addr & ~PAGE_MASK,
				     syndrome,
				     channel, dimm, -1,
				     err, optype);
}