Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 767

kernel-2.6.18-238.el5.src.rpm

From: Mauro Carvalho Chehab <mchehab@redhat.com>
Date: Tue, 28 Sep 2010 14:34:12 -0400
Subject: [edac] i7300_edac: enrich FBD info for corrected errors
Message-id: <20100928113412.658b69e3@pedra>
Patchwork-id: 28449
O-Subject: [PATCH RHEL5 18/27] i7300_edac: enrich FBD error info for corrected
	errors
Bugzilla: 487428
RH-Acked-by: Prarit Bhargava <prarit@redhat.com>

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Jarod Wilson <jarod@redhat.com>

diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c
index e33c990..a06db65 100644
--- a/drivers/edac/i7300_edac.c
+++ b/drivers/edac/i7300_edac.c
@@ -277,6 +277,17 @@ static const char *ferr_global_lo_name[] = {
   #define NRECMEMB_CAS(v)	(((v) >> 16) & 0x1fff)
   #define NRECMEMB_RAS(v)	((v) & 0xffff)
 
+#define REDMEMA		0xdc
+
+#define RECMEMA		0xe0
+  #define RECMEMA_BANK(v)	(((v) >> 12) & 7)
+  #define RECMEMA_RANK(v)	(((v) >> 8) & 15)
+
+#define RECMEMB		0xe4
+  #define RECMEMB_IS_WR(v)	((v) & (1 << 31))
+  #define RECMEMB_CAS(v)	(((v) >> 16) & 0x1fff)
+  #define RECMEMB_RAS(v)	((v) & 0xffff)
+
 
 /* Device name and register DID (Device ID) */
 struct i7300_dev_info {
@@ -403,10 +414,12 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
 	struct i7300_pvt *pvt;
 	u32 errnum, value;
 	u16 val16;
-	int branch, bank, rank, cas, ras;
+	unsigned branch, bank, rank, cas, ras;
+	u32 syndrome;
+
 	unsigned long errors;
 	const char *specific;
-	bool is_fatal, is_wr;
+	bool is_wr;
 
 	pvt = mci->pvt_info;
 
@@ -418,7 +431,6 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
 		errnum = find_first_bit(&errors,
 					ARRAY_SIZE(ferr_fat_fbd_name));
 		specific = GET_ERR_FROM_TABLE(ferr_fat_fbd_name, errnum);
-		is_fatal = 1;
 
 		branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0;
 		pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map,
@@ -436,7 +448,7 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
 		snprintf(pvt->tmp_prt_buffer, PAGE_SIZE,
 			"FATAL (Branch=%d DRAM-Bank=%d %s "
 			"RAS=%d CAS=%d Err=0x%lx (%s))",
-			branch >> 1, bank,
+			branch, bank,
 			is_wr ? "RDWR" : "RD",
 			ras, cas,
 			errors, specific);
@@ -445,7 +457,6 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
 		edac_mc_handle_fbd_ue(mci, rank, branch << 1,
 				      (branch << 1) + 1,
 				      pvt->tmp_prt_buffer);
-		return;
 	}
 
 	/* read in the 1st NON-FATAL error register */
@@ -456,20 +467,48 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
 		errnum = find_first_bit(&errors,
 					ARRAY_SIZE(ferr_nf_fbd_name));
 		specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum);
-		is_fatal = 0;
 
 		/* Clear the error bit */
 		pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
 				       FERR_GLOBAL_LO, value);
 
-		goto error_fbd;
-	}
-	return;
+		pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
+			REDMEMA, &syndrome);
 
-error_fbd:
+		branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0;
+		pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map,
+				     RECMEMA, &val16);
+		bank = RECMEMA_BANK(val16);
+		rank = RECMEMA_RANK(val16);
 
-	i7300_mc_printk(mci, KERN_EMERG, "%s FBD error on branch %d: %s\n",
-			is_fatal ? "Fatal" : "NOT fatal", branch, specific);
+		pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
+				RECMEMB, &value);
+
+		is_wr = RECMEMB_IS_WR(value);
+		cas = RECMEMB_CAS(value);
+		ras = RECMEMB_RAS(value);
+
+		/* Form out message */
+		snprintf(pvt->tmp_prt_buffer, PAGE_SIZE,
+			"Corrected error (Branch=%d (channel %d or %d), "
+			" DRAM-Bank=%d %s "
+			"RAS=%d CAS=%d, CE Err=0x%lx, Syndrome=0x%08x(%s))",
+			branch, branch << 1, (branch << 1) + 1,
+			bank,
+			is_wr ? "RDWR" : "RD",
+			ras, cas,
+			errors, syndrome, specific);
+
+		/*
+		 * Call the helper to output message
+		 * NOTE: Errors are reported per-branch, and not per-channel
+		 *	 Currently, we don't know how to identify the right
+		 *	 channel.
+		 */
+		edac_mc_handle_fbd_ce(mci, rank, branch << 1,
+				      pvt->tmp_prt_buffer);
+	}
+	return;
 }
 
 /*