aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-09-02 22:52:36 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-10 10:44:57 -0400
commit14d2c08343eecd13f6c6ec232c98b16762b97924 (patch)
treefa78da74556c7b945814c52643aa64559c0b209a /drivers/edac
parentb4e8f0b6eaa1e99f1a64e539466a8ee2fb521d62 (diff)
i7core: Use registered memories per processor
Instead of assuming that the entire machine has either registered or unregistered memories, do it at CPU socket based. While here, fix a bug at i7core_mce_output_error(), where the we're using m->cpu directly as if it would represent a socket. Instead, the proper socket_id is given by cpu_data[m->cpu].phys_proc_id. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com> ---
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/i7core_edac.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c
index 4758c208f39a..9f4e9d7d4dbf 100644
--- a/drivers/edac/i7core_edac.c
+++ b/drivers/edac/i7core_edac.c
@@ -29,6 +29,7 @@
29#include <linux/mmzone.h> 29#include <linux/mmzone.h>
30#include <linux/edac_mce.h> 30#include <linux/edac_mce.h>
31#include <linux/spinlock.h> 31#include <linux/spinlock.h>
32#include <asm/processor.h>
32 33
33#include "edac_core.h" 34#include "edac_core.h"
34 35
@@ -206,8 +207,6 @@ struct i7core_pvt {
206 struct i7core_inject inject; 207 struct i7core_inject inject;
207 struct i7core_channel channel[NUM_SOCKETS][NUM_CHANS]; 208 struct i7core_channel channel[NUM_SOCKETS][NUM_CHANS];
208 209
209 unsigned int is_registered:1; /* true if all memories are RDIMMs */
210
211 int sockets; /* Number of sockets */ 210 int sockets; /* Number of sockets */
212 int channels; /* Number of active channels */ 211 int channels; /* Number of active channels */
213 212
@@ -221,6 +220,8 @@ struct i7core_pvt {
221 unsigned long rdimm_ce_count[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS]; 220 unsigned long rdimm_ce_count[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS];
222 int rdimm_last_ce_count[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS]; 221 int rdimm_last_ce_count[NUM_SOCKETS][NUM_CHANS][MAX_DIMMS];
223 222
223 unsigned int is_registered[NUM_SOCKETS];
224
224 /* mcelog glue */ 225 /* mcelog glue */
225 struct edac_mce edac_mce; 226 struct edac_mce edac_mce;
226 struct mce mce_entry[MCE_LOG_LEN]; 227 struct mce mce_entry[MCE_LOG_LEN];
@@ -490,8 +491,6 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket)
490 numrow(pvt->info.max_dod >> 6), 491 numrow(pvt->info.max_dod >> 6),
491 numcol(pvt->info.max_dod >> 9)); 492 numcol(pvt->info.max_dod >> 9));
492 493
493 pvt->is_registered = 1;
494
495 for (i = 0; i < NUM_CHANS; i++) { 494 for (i = 0; i < NUM_CHANS; i++) {
496 u32 data, dimm_dod[3], value[8]; 495 u32 data, dimm_dod[3], value[8];
497 496
@@ -513,14 +512,8 @@ static int get_dimm_config(struct mem_ctl_info *mci, int *csrow, u8 socket)
513 512
514 if (data & REGISTERED_DIMM) 513 if (data & REGISTERED_DIMM)
515 mtype = MEM_RDDR3; 514 mtype = MEM_RDDR3;
516 else { 515 else
517 mtype = MEM_DDR3; 516 mtype = MEM_DDR3;
518 /*
519 * FIXME: Currently, the driver will use dev 3:2
520 * counter registers only if all memories are registered
521 */
522 pvt->is_registered = 0;
523 }
524#if 0 517#if 0
525 if (data & THREE_DIMMS_PRESENT) 518 if (data & THREE_DIMMS_PRESENT)
526 pvt->channel[i].dimms = 3; 519 pvt->channel[i].dimms = 3;
@@ -1068,7 +1061,7 @@ static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data)
1068 count = sprintf(data, "socket 0 data unavailable\n"); 1061 count = sprintf(data, "socket 0 data unavailable\n");
1069 continue; 1062 continue;
1070 } 1063 }
1071 if (!pvt->is_registered) 1064 if (!pvt->is_registered[i])
1072 count = sprintf(data, "socket %d, dimm0: %lu\n" 1065 count = sprintf(data, "socket %d, dimm0: %lu\n"
1073 "dimm1: %lu\ndimm2: %lu\n", 1066 "dimm1: %lu\ndimm2: %lu\n",
1074 i, 1067 i,
@@ -1310,7 +1303,9 @@ static int mci_bind_devs(struct mem_ctl_info *mci)
1310 struct pci_dev *pdev; 1303 struct pci_dev *pdev;
1311 int i, j, func, slot; 1304 int i, j, func, slot;
1312 1305
1306
1313 for (i = 0; i < pvt->sockets; i++) { 1307 for (i = 0; i < pvt->sockets; i++) {
1308 pvt->is_registered[i] = 0;
1314 for (j = 0; j < N_DEVS; j++) { 1309 for (j = 0; j < N_DEVS; j++) {
1315 pdev = pci_devs[j].pdev[i]; 1310 pdev = pci_devs[j].pdev[i];
1316 if (!pdev) 1311 if (!pdev)
@@ -1334,6 +1329,10 @@ static int mci_bind_devs(struct mem_ctl_info *mci)
1334 debugf0("Associated fn %d.%d, dev = %p, socket %d\n", 1329 debugf0("Associated fn %d.%d, dev = %p, socket %d\n",
1335 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), 1330 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
1336 pdev, i); 1331 pdev, i);
1332
1333 if (PCI_SLOT(pdev->devfn) == 3 &&
1334 PCI_FUNC(pdev->devfn) == 2)
1335 pvt->is_registered[i] = 1;
1337 } 1336 }
1338 } 1337 }
1339 1338
@@ -1533,6 +1532,11 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci,
1533 u32 syndrome = m->misc >> 32; 1532 u32 syndrome = m->misc >> 32;
1534 u32 errnum = find_first_bit(&error, 32); 1533 u32 errnum = find_first_bit(&error, 32);
1535 int csrow; 1534 int csrow;
1535#ifdef CONFIG_SMP
1536 u32 socket_id = cpu_data[m->cpu].phys_proc_id;
1537#else
1538 u32 socket_id = 0;
1539#endif
1536 1540
1537 if (m->mcgstatus & 1) 1541 if (m->mcgstatus & 1)
1538 type = "FATAL"; 1542 type = "FATAL";
@@ -1596,19 +1600,22 @@ static void i7core_mce_output_error(struct mem_ctl_info *mci,
1596 msg = kasprintf(GFP_ATOMIC, 1600 msg = kasprintf(GFP_ATOMIC,
1597 "%s (addr = 0x%08llx, socket=%d, Dimm=%d, Channel=%d, " 1601 "%s (addr = 0x%08llx, socket=%d, Dimm=%d, Channel=%d, "
1598 "syndrome=0x%08x, count=%d, Err=%08llx:%08llx (%s: %s))\n", 1602 "syndrome=0x%08x, count=%d, Err=%08llx:%08llx (%s: %s))\n",
1599 type, (long long) m->addr, m->cpu, dimm, channel, 1603 type, (long long) m->addr, socket_id, dimm, channel,
1600 syndrome, core_err_cnt, (long long)m->status, 1604 syndrome, core_err_cnt, (long long)m->status,
1601 (long long)m->misc, optype, err); 1605 (long long)m->misc, optype, err);
1602 1606
1603 debugf0("%s", msg); 1607 debugf0("%s", msg);
1604 1608
1605 csrow = pvt->csrow_map[m->cpu][channel][dimm]; 1609 if (socket_id < NUM_SOCKETS)
1610 csrow = pvt->csrow_map[socket_id][channel][dimm];
1611 else
1612 csrow = -1;
1606 1613
1607 /* Call the helper to output message */ 1614 /* Call the helper to output message */
1608 if (m->mcgstatus & 1) 1615 if (m->mcgstatus & 1)
1609 edac_mc_handle_fbd_ue(mci, csrow, 0, 1616 edac_mc_handle_fbd_ue(mci, csrow, 0,
1610 0 /* FIXME: should be channel here */, msg); 1617 0 /* FIXME: should be channel here */, msg);
1611 else if (!pvt->is_registered) 1618 else if (!pvt->is_registered[socket_id])
1612 edac_mc_handle_fbd_ce(mci, csrow, 1619 edac_mc_handle_fbd_ce(mci, csrow,
1613 0 /* FIXME: should be channel here */, msg); 1620 0 /* FIXME: should be channel here */, msg);
1614 1621
@@ -1647,7 +1654,7 @@ static void i7core_check_error(struct mem_ctl_info *mci)
1647 1654
1648 /* check memory count errors */ 1655 /* check memory count errors */
1649 for (i = 0; i < pvt->sockets; i++) 1656 for (i = 0; i < pvt->sockets; i++)
1650 if (!pvt->is_registered) 1657 if (!pvt->is_registered[i])
1651 i7core_udimm_check_mc_ecc_err(mci, i); 1658 i7core_udimm_check_mc_ecc_err(mci, i);
1652 else 1659 else
1653 i7core_rdimm_check_mc_ecc_err(mci, i); 1660 i7core_rdimm_check_mc_ecc_err(mci, i);