aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/edac/e7xxx_edac.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/drivers/edac/e7xxx_edac.c b/drivers/edac/e7xxx_edac.c
index 709aca216639..d4cfc24b2f8d 100644
--- a/drivers/edac/e7xxx_edac.c
+++ b/drivers/edac/e7xxx_edac.c
@@ -10,6 +10,9 @@
10 * Based on work by Dan Hollis <goemon at anime dot net> and others. 10 * Based on work by Dan Hollis <goemon at anime dot net> and others.
11 * http://www.anime.net/~goemon/linux-ecc/ 11 * http://www.anime.net/~goemon/linux-ecc/
12 * 12 *
13 * Datasheet:
14 * http://www.intel.com/content/www/us/en/chipsets/e7501-chipset-memory-controller-hub-datasheet.html
15 *
13 * Contributors: 16 * Contributors:
14 * Eric Biederman (Linux Networx) 17 * Eric Biederman (Linux Networx)
15 * Tom Zimmerman (Linux Networx) 18 * Tom Zimmerman (Linux Networx)
@@ -71,7 +74,7 @@
71#endif /* PCI_DEVICE_ID_INTEL_7505_1_ERR */ 74#endif /* PCI_DEVICE_ID_INTEL_7505_1_ERR */
72 75
73#define E7XXX_NR_CSROWS 8 /* number of csrows */ 76#define E7XXX_NR_CSROWS 8 /* number of csrows */
74#define E7XXX_NR_DIMMS 8 /* FIXME - is this correct? */ 77#define E7XXX_NR_DIMMS 8 /* 2 channels, 4 dimms/channel */
75 78
76/* E7XXX register addresses - device 0 function 0 */ 79/* E7XXX register addresses - device 0 function 0 */
77#define E7XXX_DRB 0x60 /* DRAM row boundary register (8b) */ 80#define E7XXX_DRB 0x60 /* DRAM row boundary register (8b) */
@@ -216,13 +219,15 @@ static void process_ce(struct mem_ctl_info *mci, struct e7xxx_error_info *info)
216 row = edac_mc_find_csrow_by_page(mci, page); 219 row = edac_mc_find_csrow_by_page(mci, page);
217 /* convert syndrome to channel */ 220 /* convert syndrome to channel */
218 channel = e7xxx_find_channel(syndrome); 221 channel = e7xxx_find_channel(syndrome);
219 edac_mc_handle_ce(mci, page, 0, syndrome, row, channel, "e7xxx CE"); 222 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, page, 0, syndrome,
223 row, channel, -1, "e7xxx CE", "", NULL);
220} 224}
221 225
222static void process_ce_no_info(struct mem_ctl_info *mci) 226static void process_ce_no_info(struct mem_ctl_info *mci)
223{ 227{
224 debugf3("%s()\n", __func__); 228 debugf3("%s()\n", __func__);
225 edac_mc_handle_ce_no_info(mci, "e7xxx CE log register overflow"); 229 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 0, 0, 0, -1, -1, -1,
230 "e7xxx CE log register overflow", "", NULL);
226} 231}
227 232
228static void process_ue(struct mem_ctl_info *mci, struct e7xxx_error_info *info) 233static void process_ue(struct mem_ctl_info *mci, struct e7xxx_error_info *info)
@@ -236,13 +241,17 @@ static void process_ue(struct mem_ctl_info *mci, struct e7xxx_error_info *info)
236 /* FIXME - should use PAGE_SHIFT */ 241 /* FIXME - should use PAGE_SHIFT */
237 block_page = error_2b >> 6; /* convert to 4k address */ 242 block_page = error_2b >> 6; /* convert to 4k address */
238 row = edac_mc_find_csrow_by_page(mci, block_page); 243 row = edac_mc_find_csrow_by_page(mci, block_page);
239 edac_mc_handle_ue(mci, block_page, 0, row, "e7xxx UE"); 244
245 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, block_page, 0, 0,
246 row, -1, -1, "e7xxx UE", "", NULL);
240} 247}
241 248
242static void process_ue_no_info(struct mem_ctl_info *mci) 249static void process_ue_no_info(struct mem_ctl_info *mci)
243{ 250{
244 debugf3("%s()\n", __func__); 251 debugf3("%s()\n", __func__);
245 edac_mc_handle_ue_no_info(mci, "e7xxx UE log register overflow"); 252
253 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 0, 0, 0, -1, -1, -1,
254 "e7xxx UE log register overflow", "", NULL);
246} 255}
247 256
248static void e7xxx_get_error_info(struct mem_ctl_info *mci, 257static void e7xxx_get_error_info(struct mem_ctl_info *mci,
@@ -413,6 +422,7 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx)
413{ 422{
414 u16 pci_data; 423 u16 pci_data;
415 struct mem_ctl_info *mci = NULL; 424 struct mem_ctl_info *mci = NULL;
425 struct edac_mc_layer layers[2];
416 struct e7xxx_pvt *pvt = NULL; 426 struct e7xxx_pvt *pvt = NULL;
417 u32 drc; 427 u32 drc;
418 int drc_chan; 428 int drc_chan;
@@ -423,8 +433,21 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx)
423 pci_read_config_dword(pdev, E7XXX_DRC, &drc); 433 pci_read_config_dword(pdev, E7XXX_DRC, &drc);
424 434
425 drc_chan = dual_channel_active(drc, dev_idx); 435 drc_chan = dual_channel_active(drc, dev_idx);
426 mci = edac_mc_alloc(sizeof(*pvt), E7XXX_NR_CSROWS, drc_chan + 1, 0); 436 /*
427 437 * According with the datasheet, this device has a maximum of
438 * 4 DIMMS per channel, either single-rank or dual-rank. So, the
439 * total amount of dimms is 8 (E7XXX_NR_DIMMS).
440 * That means that the DIMM is mapped as CSROWs, and the channel
441 * will map the rank. So, an error to either channel should be
442 * attributed to the same dimm.
443 */
444 layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
445 layers[0].size = E7XXX_NR_CSROWS;
446 layers[0].is_virt_csrow = true;
447 layers[1].type = EDAC_MC_LAYER_CHANNEL;
448 layers[1].size = drc_chan + 1;
449 layers[1].is_virt_csrow = false;
450 mci = new_edac_mc_alloc(0, ARRAY_SIZE(layers), layers, sizeof(*pvt));
428 if (mci == NULL) 451 if (mci == NULL)
429 return -ENOMEM; 452 return -ENOMEM;
430 453