Commit e7ecd891 authored by Dave Peterson's avatar Dave Peterson Committed by Linus Torvalds

[PATCH] EDAC: formatting cleanup

Cosmetic indentation/formatting cleanup for EDAC code.  Make sure we
are using tabs rather than spaces to indent, etc.
Signed-off-by: default avatarDavid S. Peterson <dsp@llnl.gov>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 54933ddd
...@@ -12,33 +12,26 @@ ...@@ -12,33 +12,26 @@
* *
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/pci_ids.h> #include <linux/pci_ids.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "edac_mc.h" #include "edac_mc.h"
#define amd76x_printk(level, fmt, arg...) \ #define amd76x_printk(level, fmt, arg...) \
edac_printk(level, "amd76x", fmt, ##arg) edac_printk(level, "amd76x", fmt, ##arg)
#define amd76x_mc_printk(mci, level, fmt, arg...) \ #define amd76x_mc_printk(mci, level, fmt, arg...) \
edac_mc_chipset_printk(mci, level, "amd76x", fmt, ##arg) edac_mc_chipset_printk(mci, level, "amd76x", fmt, ##arg)
#define AMD76X_NR_CSROWS 8 #define AMD76X_NR_CSROWS 8
#define AMD76X_NR_CHANS 1 #define AMD76X_NR_CHANS 1
#define AMD76X_NR_DIMMS 4 #define AMD76X_NR_DIMMS 4
/* AMD 76x register addresses - device 0 function 0 - PCI bridge */ /* AMD 76x register addresses - device 0 function 0 - PCI bridge */
#define AMD76X_ECC_MODE_STATUS 0x48 /* Mode and status of ECC (32b) #define AMD76X_ECC_MODE_STATUS 0x48 /* Mode and status of ECC (32b)
* *
* 31:16 reserved * 31:16 reserved
...@@ -50,6 +43,7 @@ ...@@ -50,6 +43,7 @@
* 7:4 UE cs row * 7:4 UE cs row
* 3:0 CE cs row * 3:0 CE cs row
*/ */
#define AMD76X_DRAM_MODE_STATUS 0x58 /* DRAM Mode and status (32b) #define AMD76X_DRAM_MODE_STATUS 0x58 /* DRAM Mode and status (32b)
* *
* 31:26 clock disable 5 - 0 * 31:26 clock disable 5 - 0
...@@ -64,6 +58,7 @@ ...@@ -64,6 +58,7 @@
* 15:8 reserved * 15:8 reserved
* 7:0 x4 mode enable 7 - 0 * 7:0 x4 mode enable 7 - 0
*/ */
#define AMD76X_MEM_BASE_ADDR 0xC0 /* Memory base address (8 x 32b) #define AMD76X_MEM_BASE_ADDR 0xC0 /* Memory base address (8 x 32b)
* *
* 31:23 chip-select base * 31:23 chip-select base
...@@ -74,29 +69,28 @@ ...@@ -74,29 +69,28 @@
* 0 chip-select enable * 0 chip-select enable
*/ */
struct amd76x_error_info { struct amd76x_error_info {
u32 ecc_mode_status; u32 ecc_mode_status;
}; };
enum amd76x_chips { enum amd76x_chips {
AMD761 = 0, AMD761 = 0,
AMD762 AMD762
}; };
struct amd76x_dev_info { struct amd76x_dev_info {
const char *ctl_name; const char *ctl_name;
}; };
static const struct amd76x_dev_info amd76x_devs[] = { static const struct amd76x_dev_info amd76x_devs[] = {
[AMD761] = {.ctl_name = "AMD761"}, [AMD761] = {
[AMD762] = {.ctl_name = "AMD762"}, .ctl_name = "AMD761"
},
[AMD762] = {
.ctl_name = "AMD762"
},
}; };
/** /**
* amd76x_get_error_info - fetch error information * amd76x_get_error_info - fetch error information
* @mci: Memory controller * @mci: Memory controller
...@@ -105,23 +99,21 @@ static const struct amd76x_dev_info amd76x_devs[] = { ...@@ -105,23 +99,21 @@ static const struct amd76x_dev_info amd76x_devs[] = {
* Fetch and store the AMD76x ECC status. Clear pending status * Fetch and store the AMD76x ECC status. Clear pending status
* on the chip so that further errors will be reported * on the chip so that further errors will be reported
*/ */
static void amd76x_get_error_info(struct mem_ctl_info *mci,
static void amd76x_get_error_info (struct mem_ctl_info *mci, struct amd76x_error_info *info)
struct amd76x_error_info *info)
{ {
pci_read_config_dword(mci->pdev, AMD76X_ECC_MODE_STATUS, pci_read_config_dword(mci->pdev, AMD76X_ECC_MODE_STATUS,
&info->ecc_mode_status); &info->ecc_mode_status);
if (info->ecc_mode_status & BIT(8)) if (info->ecc_mode_status & BIT(8))
pci_write_bits32(mci->pdev, AMD76X_ECC_MODE_STATUS, pci_write_bits32(mci->pdev, AMD76X_ECC_MODE_STATUS,
(u32) BIT(8), (u32) BIT(8)); (u32) BIT(8), (u32) BIT(8));
if (info->ecc_mode_status & BIT(9)) if (info->ecc_mode_status & BIT(9))
pci_write_bits32(mci->pdev, AMD76X_ECC_MODE_STATUS, pci_write_bits32(mci->pdev, AMD76X_ECC_MODE_STATUS,
(u32) BIT(9), (u32) BIT(9)); (u32) BIT(9), (u32) BIT(9));
} }
/** /**
* amd76x_process_error_info - Error check * amd76x_process_error_info - Error check
* @mci: Memory controller * @mci: Memory controller
...@@ -132,8 +124,7 @@ static void amd76x_get_error_info (struct mem_ctl_info *mci, ...@@ -132,8 +124,7 @@ static void amd76x_get_error_info (struct mem_ctl_info *mci,
* A return of 1 indicates an error. Also if handle_errors is true * A return of 1 indicates an error. Also if handle_errors is true
* then attempt to handle and clean up after the error * then attempt to handle and clean up after the error
*/ */
static int amd76x_process_error_info(struct mem_ctl_info *mci,
static int amd76x_process_error_info (struct mem_ctl_info *mci,
struct amd76x_error_info *info, int handle_errors) struct amd76x_error_info *info, int handle_errors)
{ {
int error_found; int error_found;
...@@ -149,9 +140,8 @@ static int amd76x_process_error_info (struct mem_ctl_info *mci, ...@@ -149,9 +140,8 @@ static int amd76x_process_error_info (struct mem_ctl_info *mci,
if (handle_errors) { if (handle_errors) {
row = (info->ecc_mode_status >> 4) & 0xf; row = (info->ecc_mode_status >> 4) & 0xf;
edac_mc_handle_ue(mci, edac_mc_handle_ue(mci, mci->csrows[row].first_page, 0,
mci->csrows[row].first_page, 0, row, row, mci->ctl_name);
mci->ctl_name);
} }
} }
...@@ -163,11 +153,11 @@ static int amd76x_process_error_info (struct mem_ctl_info *mci, ...@@ -163,11 +153,11 @@ static int amd76x_process_error_info (struct mem_ctl_info *mci,
if (handle_errors) { if (handle_errors) {
row = info->ecc_mode_status & 0xf; row = info->ecc_mode_status & 0xf;
edac_mc_handle_ce(mci, edac_mc_handle_ce(mci, mci->csrows[row].first_page, 0,
mci->csrows[row].first_page, 0, 0, row, 0, 0, row, 0, mci->ctl_name);
mci->ctl_name);
} }
} }
return error_found; return error_found;
} }
...@@ -178,7 +168,6 @@ static int amd76x_process_error_info (struct mem_ctl_info *mci, ...@@ -178,7 +168,6 @@ static int amd76x_process_error_info (struct mem_ctl_info *mci,
* Called by the poll handlers this function reads the status * Called by the poll handlers this function reads the status
* from the controller and checks for errors. * from the controller and checks for errors.
*/ */
static void amd76x_check(struct mem_ctl_info *mci) static void amd76x_check(struct mem_ctl_info *mci)
{ {
struct amd76x_error_info info; struct amd76x_error_info info;
...@@ -187,7 +176,6 @@ static void amd76x_check(struct mem_ctl_info *mci) ...@@ -187,7 +176,6 @@ static void amd76x_check(struct mem_ctl_info *mci)
amd76x_process_error_info(mci, &info, 1); amd76x_process_error_info(mci, &info, 1);
} }
/** /**
* amd76x_probe1 - Perform set up for detected device * amd76x_probe1 - Perform set up for detected device
* @pdev; PCI device detected * @pdev; PCI device detected
...@@ -197,7 +185,6 @@ static void amd76x_check(struct mem_ctl_info *mci) ...@@ -197,7 +185,6 @@ static void amd76x_check(struct mem_ctl_info *mci)
* controller status reporting. We configure and set up the * controller status reporting. We configure and set up the
* memory controller reporting and claim the device. * memory controller reporting and claim the device.
*/ */
static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) static int amd76x_probe1(struct pci_dev *pdev, int dev_idx)
{ {
int rc = -ENODEV; int rc = -ENODEV;
...@@ -214,10 +201,8 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -214,10 +201,8 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx)
struct amd76x_error_info discard; struct amd76x_error_info discard;
debugf0("%s()\n", __func__); debugf0("%s()\n", __func__);
pci_read_config_dword(pdev, AMD76X_ECC_MODE_STATUS, &ems); pci_read_config_dword(pdev, AMD76X_ECC_MODE_STATUS, &ems);
ems_mode = (ems >> 10) & 0x3; ems_mode = (ems >> 10) & 0x3;
mci = edac_mc_alloc(0, AMD76X_NR_CSROWS, AMD76X_NR_CHANS); mci = edac_mc_alloc(0, AMD76X_NR_CSROWS, AMD76X_NR_CHANS);
if (mci == NULL) { if (mci == NULL) {
...@@ -226,14 +211,11 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -226,14 +211,11 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx)
} }
debugf0("%s(): mci = %p\n", __func__, mci); debugf0("%s(): mci = %p\n", __func__, mci);
mci->pdev = pdev; mci->pdev = pdev;
mci->mtype_cap = MEM_FLAG_RDDR; mci->mtype_cap = MEM_FLAG_RDDR;
mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
mci->edac_cap = ems_mode ? mci->edac_cap = ems_mode ?
(EDAC_FLAG_EC | EDAC_FLAG_SECDED) : EDAC_FLAG_NONE; (EDAC_FLAG_EC | EDAC_FLAG_SECDED) : EDAC_FLAG_NONE;
mci->mod_name = EDAC_MOD_STR; mci->mod_name = EDAC_MOD_STR;
mci->mod_ver = "$Revision: 1.4.2.5 $"; mci->mod_ver = "$Revision: 1.4.2.5 $";
mci->ctl_name = amd76x_devs[dev_idx].ctl_name; mci->ctl_name = amd76x_devs[dev_idx].ctl_name;
...@@ -249,18 +231,15 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -249,18 +231,15 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx)
/* find the DRAM Chip Select Base address and mask */ /* find the DRAM Chip Select Base address and mask */
pci_read_config_dword(mci->pdev, pci_read_config_dword(mci->pdev,
AMD76X_MEM_BASE_ADDR + (index * 4), AMD76X_MEM_BASE_ADDR + (index * 4), &mba);
&mba);
if (!(mba & BIT(0))) if (!(mba & BIT(0)))
continue; continue;
mba_base = mba & 0xff800000UL; mba_base = mba & 0xff800000UL;
mba_mask = ((mba & 0xff80) << 16) | 0x7fffffUL; mba_mask = ((mba & 0xff80) << 16) | 0x7fffffUL;
pci_read_config_dword(mci->pdev, AMD76X_DRAM_MODE_STATUS, pci_read_config_dword(mci->pdev, AMD76X_DRAM_MODE_STATUS,
&dms); &dms);
csrow->first_page = mba_base >> PAGE_SHIFT; csrow->first_page = mba_base >> PAGE_SHIFT;
csrow->nr_pages = (mba_mask + 1) >> PAGE_SHIFT; csrow->nr_pages = (mba_mask + 1) >> PAGE_SHIFT;
csrow->last_page = csrow->first_page + csrow->nr_pages - 1; csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
...@@ -290,7 +269,7 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -290,7 +269,7 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx)
/* returns count (>= 0), or negative on error */ /* returns count (>= 0), or negative on error */
static int __devinit amd76x_init_one(struct pci_dev *pdev, static int __devinit amd76x_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
debugf0("%s()\n", __func__); debugf0("%s()\n", __func__);
...@@ -298,7 +277,6 @@ static int __devinit amd76x_init_one(struct pci_dev *pdev, ...@@ -298,7 +277,6 @@ static int __devinit amd76x_init_one(struct pci_dev *pdev,
return amd76x_probe1(pdev, ent->driver_data); return amd76x_probe1(pdev, ent->driver_data);
} }
/** /**
* amd76x_remove_one - driver shutdown * amd76x_remove_one - driver shutdown
* @pdev: PCI device being handed back * @pdev: PCI device being handed back
...@@ -307,7 +285,6 @@ static int __devinit amd76x_init_one(struct pci_dev *pdev, ...@@ -307,7 +285,6 @@ static int __devinit amd76x_init_one(struct pci_dev *pdev,
* structure for the device then delete the mci and free the * structure for the device then delete the mci and free the
* resources. * resources.
*/ */
static void __devexit amd76x_remove_one(struct pci_dev *pdev) static void __devexit amd76x_remove_one(struct pci_dev *pdev)
{ {
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
...@@ -320,18 +297,22 @@ static void __devexit amd76x_remove_one(struct pci_dev *pdev) ...@@ -320,18 +297,22 @@ static void __devexit amd76x_remove_one(struct pci_dev *pdev)
edac_mc_free(mci); edac_mc_free(mci);
} }
static const struct pci_device_id amd76x_pci_tbl[] __devinitdata = { static const struct pci_device_id amd76x_pci_tbl[] __devinitdata = {
{PCI_VEND_DEV(AMD, FE_GATE_700C), PCI_ANY_ID, PCI_ANY_ID, 0, 0, {
AMD762}, PCI_VEND_DEV(AMD, FE_GATE_700C), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
{PCI_VEND_DEV(AMD, FE_GATE_700E), PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD762
AMD761}, },
{0,} /* 0 terminated list. */ {
PCI_VEND_DEV(AMD, FE_GATE_700E), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
AMD761
},
{
0,
} /* 0 terminated list. */
}; };
MODULE_DEVICE_TABLE(pci, amd76x_pci_tbl); MODULE_DEVICE_TABLE(pci, amd76x_pci_tbl);
static struct pci_driver amd76x_driver = { static struct pci_driver amd76x_driver = {
.name = EDAC_MOD_STR, .name = EDAC_MOD_STR,
.probe = amd76x_init_one, .probe = amd76x_init_one,
......
...@@ -17,26 +17,19 @@ ...@@ -17,26 +17,19 @@
* *
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/pci_ids.h> #include <linux/pci_ids.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "edac_mc.h" #include "edac_mc.h"
#define e752x_printk(level, fmt, arg...) \ #define e752x_printk(level, fmt, arg...) \
edac_printk(level, "e752x", fmt, ##arg) edac_printk(level, "e752x", fmt, ##arg)
#define e752x_mc_printk(mci, level, fmt, arg...) \ #define e752x_mc_printk(mci, level, fmt, arg...) \
edac_mc_chipset_printk(mci, level, "e752x", fmt, ##arg) edac_mc_chipset_printk(mci, level, "e752x", fmt, ##arg)
#ifndef PCI_DEVICE_ID_INTEL_7520_0 #ifndef PCI_DEVICE_ID_INTEL_7520_0
#define PCI_DEVICE_ID_INTEL_7520_0 0x3590 #define PCI_DEVICE_ID_INTEL_7520_0 0x3590
...@@ -64,7 +57,6 @@ ...@@ -64,7 +57,6 @@
#define E752X_NR_CSROWS 8 /* number of csrows */ #define E752X_NR_CSROWS 8 /* number of csrows */
/* E752X register addresses - device 0 function 0 */ /* E752X register addresses - device 0 function 0 */
#define E752X_DRB 0x60 /* DRAM row boundary register (8b) */ #define E752X_DRB 0x60 /* DRAM row boundary register (8b) */
#define E752X_DRA 0x70 /* DRAM row attribute register (8b) */ #define E752X_DRA 0x70 /* DRAM row attribute register (8b) */
...@@ -164,7 +156,6 @@ enum e752x_chips { ...@@ -164,7 +156,6 @@ enum e752x_chips {
E7320 = 2 E7320 = 2
}; };
struct e752x_pvt { struct e752x_pvt {
struct pci_dev *bridge_ck; struct pci_dev *bridge_ck;
struct pci_dev *dev_d0f0; struct pci_dev *dev_d0f0;
...@@ -178,7 +169,6 @@ struct e752x_pvt { ...@@ -178,7 +169,6 @@ struct e752x_pvt {
const struct e752x_dev_info *dev_info; const struct e752x_dev_info *dev_info;
}; };
struct e752x_dev_info { struct e752x_dev_info {
u16 err_dev; u16 err_dev;
u16 ctl_dev; u16 ctl_dev;
...@@ -207,22 +197,24 @@ struct e752x_error_info { ...@@ -207,22 +197,24 @@ struct e752x_error_info {
static const struct e752x_dev_info e752x_devs[] = { static const struct e752x_dev_info e752x_devs[] = {
[E7520] = { [E7520] = {
.err_dev = PCI_DEVICE_ID_INTEL_7520_1_ERR, .err_dev = PCI_DEVICE_ID_INTEL_7520_1_ERR,
.ctl_dev = PCI_DEVICE_ID_INTEL_7520_0, .ctl_dev = PCI_DEVICE_ID_INTEL_7520_0,
.ctl_name = "E7520"}, .ctl_name = "E7520"
},
[E7525] = { [E7525] = {
.err_dev = PCI_DEVICE_ID_INTEL_7525_1_ERR, .err_dev = PCI_DEVICE_ID_INTEL_7525_1_ERR,
.ctl_dev = PCI_DEVICE_ID_INTEL_7525_0, .ctl_dev = PCI_DEVICE_ID_INTEL_7525_0,
.ctl_name = "E7525"}, .ctl_name = "E7525"
},
[E7320] = { [E7320] = {
.err_dev = PCI_DEVICE_ID_INTEL_7320_1_ERR, .err_dev = PCI_DEVICE_ID_INTEL_7320_1_ERR,
.ctl_dev = PCI_DEVICE_ID_INTEL_7320_0, .ctl_dev = PCI_DEVICE_ID_INTEL_7320_0,
.ctl_name = "E7320"}, .ctl_name = "E7320"
},
}; };
static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci, static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci,
unsigned long page) unsigned long page)
{ {
u32 remap; u32 remap;
struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info; struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info;
...@@ -231,17 +223,21 @@ static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci, ...@@ -231,17 +223,21 @@ static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci,
if (page < pvt->tolm) if (page < pvt->tolm)
return page; return page;
if ((page >= 0x100000) && (page < pvt->remapbase)) if ((page >= 0x100000) && (page < pvt->remapbase))
return page; return page;
remap = (page - pvt->tolm) + pvt->remapbase; remap = (page - pvt->tolm) + pvt->remapbase;
if (remap < pvt->remaplimit) if (remap < pvt->remaplimit)
return remap; return remap;
e752x_printk(KERN_ERR, "Invalid page %lx - out of range\n", page); e752x_printk(KERN_ERR, "Invalid page %lx - out of range\n", page);
return pvt->tolm - 1; return pvt->tolm - 1;
} }
static void do_process_ce(struct mem_ctl_info *mci, u16 error_one, static void do_process_ce(struct mem_ctl_info *mci, u16 error_one,
u32 sec1_add, u16 sec1_syndrome) u32 sec1_add, u16 sec1_syndrome)
{ {
u32 page; u32 page;
int row; int row;
...@@ -259,34 +255,36 @@ static void do_process_ce(struct mem_ctl_info *mci, u16 error_one, ...@@ -259,34 +255,36 @@ static void do_process_ce(struct mem_ctl_info *mci, u16 error_one,
/* chip select are bits 14 & 13 */ /* chip select are bits 14 & 13 */
row = ((page >> 1) & 3); row = ((page >> 1) & 3);
e752x_printk(KERN_WARNING, e752x_printk(KERN_WARNING,
"Test row %d Table %d %d %d %d %d %d %d %d\n", "Test row %d Table %d %d %d %d %d %d %d %d\n", row,
row, pvt->map[0], pvt->map[1], pvt->map[2], pvt->map[0], pvt->map[1], pvt->map[2], pvt->map[3],
pvt->map[3], pvt->map[4], pvt->map[5], pvt->map[4], pvt->map[5], pvt->map[6], pvt->map[7]);
pvt->map[6], pvt->map[7]);
/* test for channel remapping */ /* test for channel remapping */
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (pvt->map[i] == row) if (pvt->map[i] == row)
break; break;
} }
e752x_printk(KERN_WARNING, "Test computed row %d\n", i); e752x_printk(KERN_WARNING, "Test computed row %d\n", i);
if (i < 8) if (i < 8)
row = i; row = i;
else else
e752x_mc_printk(mci, KERN_WARNING, e752x_mc_printk(mci, KERN_WARNING,
"row %d not found in remap table\n", row); "row %d not found in remap table\n", row);
} else } else
row = edac_mc_find_csrow_by_page(mci, page); row = edac_mc_find_csrow_by_page(mci, page);
/* 0 = channel A, 1 = channel B */ /* 0 = channel A, 1 = channel B */
channel = !(error_one & 1); channel = !(error_one & 1);
if (!pvt->map_type) if (!pvt->map_type)
row = 7 - row; row = 7 - row;
edac_mc_handle_ce(mci, page, 0, sec1_syndrome, row, channel, edac_mc_handle_ce(mci, page, 0, sec1_syndrome, row, channel,
"e752x CE"); "e752x CE");
} }
static inline void process_ce(struct mem_ctl_info *mci, u16 error_one, static inline void process_ce(struct mem_ctl_info *mci, u16 error_one,
u32 sec1_add, u16 sec1_syndrome, int *error_found, u32 sec1_add, u16 sec1_syndrome, int *error_found,
int handle_error) int handle_error)
...@@ -297,8 +295,8 @@ static inline void process_ce(struct mem_ctl_info *mci, u16 error_one, ...@@ -297,8 +295,8 @@ static inline void process_ce(struct mem_ctl_info *mci, u16 error_one,
do_process_ce(mci, error_one, sec1_add, sec1_syndrome); do_process_ce(mci, error_one, sec1_add, sec1_syndrome);
} }
static void do_process_ue(struct mem_ctl_info *mci, u16 error_one, u32 ded_add, static void do_process_ue(struct mem_ctl_info *mci, u16 error_one,
u32 scrb_add) u32 ded_add, u32 scrb_add)
{ {
u32 error_2b, block_page; u32 error_2b, block_page;
int row; int row;
...@@ -308,25 +306,31 @@ static void do_process_ue(struct mem_ctl_info *mci, u16 error_one, u32 ded_add, ...@@ -308,25 +306,31 @@ static void do_process_ue(struct mem_ctl_info *mci, u16 error_one, u32 ded_add,
if (error_one & 0x0202) { if (error_one & 0x0202) {
error_2b = ded_add; error_2b = ded_add;
/* convert to 4k address */ /* convert to 4k address */
block_page = error_2b >> (PAGE_SHIFT - 4); block_page = error_2b >> (PAGE_SHIFT - 4);
row = pvt->mc_symmetric ? row = pvt->mc_symmetric ?
/* chip select are bits 14 & 13 */ /* chip select are bits 14 & 13 */
((block_page >> 1) & 3) : ((block_page >> 1) & 3) :
edac_mc_find_csrow_by_page(mci, block_page); edac_mc_find_csrow_by_page(mci, block_page);
edac_mc_handle_ue(mci, block_page, 0, row, edac_mc_handle_ue(mci, block_page, 0, row,
"e752x UE from Read"); "e752x UE from Read");
} }
if (error_one & 0x0404) { if (error_one & 0x0404) {
error_2b = scrb_add; error_2b = scrb_add;
/* convert to 4k address */ /* convert to 4k address */
block_page = error_2b >> (PAGE_SHIFT - 4); block_page = error_2b >> (PAGE_SHIFT - 4);
row = pvt->mc_symmetric ? row = pvt->mc_symmetric ?
/* chip select are bits 14 & 13 */ /* chip select are bits 14 & 13 */
((block_page >> 1) & 3) : ((block_page >> 1) & 3) :
edac_mc_find_csrow_by_page(mci, block_page); edac_mc_find_csrow_by_page(mci, block_page);
edac_mc_handle_ue(mci, block_page, 0, row, edac_mc_handle_ue(mci, block_page, 0, row,
"e752x UE from Scruber"); "e752x UE from Scruber");
} }
} }
...@@ -359,13 +363,13 @@ static void do_process_ded_retry(struct mem_ctl_info *mci, u16 error, ...@@ -359,13 +363,13 @@ static void do_process_ded_retry(struct mem_ctl_info *mci, u16 error,
struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info; struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info;
error_1b = retry_add; error_1b = retry_add;
page = error_1b >> (PAGE_SHIFT - 4); /* convert the addr to 4k page */ page = error_1b >> (PAGE_SHIFT - 4); /* convert the addr to 4k page */
row = pvt->mc_symmetric ? row = pvt->mc_symmetric ?
((page >> 1) & 3) : /* chip select are bits 14 & 13 */ ((page >> 1) & 3) : /* chip select are bits 14 & 13 */
edac_mc_find_csrow_by_page(mci, page); edac_mc_find_csrow_by_page(mci, page);
e752x_mc_printk(mci, KERN_WARNING, e752x_mc_printk(mci, KERN_WARNING,
"CE page 0x%lx, row %d : Memory read retry\n", "CE page 0x%lx, row %d : Memory read retry\n",
(long unsigned int) page, row); (long unsigned int) page, row);
} }
static inline void process_ded_retry(struct mem_ctl_info *mci, u16 error, static inline void process_ded_retry(struct mem_ctl_info *mci, u16 error,
...@@ -402,7 +406,7 @@ static void do_global_error(int fatal, u32 errors) ...@@ -402,7 +406,7 @@ static void do_global_error(int fatal, u32 errors)
for (i = 0; i < 11; i++) { for (i = 0; i < 11; i++) {
if (errors & (1 << i)) if (errors & (1 << i))
e752x_printk(KERN_WARNING, "%sError %s\n", e752x_printk(KERN_WARNING, "%sError %s\n",
fatal_message[fatal], global_message[i]); fatal_message[fatal], global_message[i]);
} }
} }
...@@ -429,7 +433,7 @@ static void do_hub_error(int fatal, u8 errors) ...@@ -429,7 +433,7 @@ static void do_hub_error(int fatal, u8 errors)
for (i = 0; i < 7; i++) { for (i = 0; i < 7; i++) {
if (errors & (1 << i)) if (errors & (1 << i))
e752x_printk(KERN_WARNING, "%sError %s\n", e752x_printk(KERN_WARNING, "%sError %s\n",
fatal_message[fatal], hub_message[i]); fatal_message[fatal], hub_message[i]);
} }
} }
...@@ -456,7 +460,7 @@ static void do_membuf_error(u8 errors) ...@@ -456,7 +460,7 @@ static void do_membuf_error(u8 errors)
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (errors & (1 << i)) if (errors & (1 << i))
e752x_printk(KERN_WARNING, "Non-Fatal Error %s\n", e752x_printk(KERN_WARNING, "Non-Fatal Error %s\n",
membuf_message[i]); membuf_message[i]);
} }
} }
...@@ -489,7 +493,7 @@ static void do_sysbus_error(int fatal, u32 errors) ...@@ -489,7 +493,7 @@ static void do_sysbus_error(int fatal, u32 errors)
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
if (errors & (1 << i)) if (errors & (1 << i))
e752x_printk(KERN_WARNING, "%sError System Bus %s\n", e752x_printk(KERN_WARNING, "%sError System Bus %s\n",
fatal_message[fatal], global_message[i]); fatal_message[fatal], global_message[i]);
} }
} }
...@@ -502,33 +506,42 @@ static inline void sysbus_error(int fatal, u32 errors, int *error_found, ...@@ -502,33 +506,42 @@ static inline void sysbus_error(int fatal, u32 errors, int *error_found,
do_sysbus_error(fatal, errors); do_sysbus_error(fatal, errors);
} }
static void e752x_check_hub_interface (struct e752x_error_info *info, static void e752x_check_hub_interface(struct e752x_error_info *info,
int *error_found, int handle_error) int *error_found, int handle_error)
{ {
u8 stat8; u8 stat8;
//pci_read_config_byte(dev,E752X_HI_FERR,&stat8); //pci_read_config_byte(dev,E752X_HI_FERR,&stat8);
stat8 = info->hi_ferr; stat8 = info->hi_ferr;
if(stat8 & 0x7f) { /* Error, so process */ if(stat8 & 0x7f) { /* Error, so process */
stat8 &= 0x7f; stat8 &= 0x7f;
if(stat8 & 0x2b) if(stat8 & 0x2b)
hub_error(1, stat8 & 0x2b, error_found, handle_error); hub_error(1, stat8 & 0x2b, error_found, handle_error);
if(stat8 & 0x54) if(stat8 & 0x54)
hub_error(0, stat8 & 0x54, error_found, handle_error); hub_error(0, stat8 & 0x54, error_found, handle_error);
} }
//pci_read_config_byte(dev,E752X_HI_NERR,&stat8); //pci_read_config_byte(dev,E752X_HI_NERR,&stat8);
stat8 = info->hi_nerr; stat8 = info->hi_nerr;
if(stat8 & 0x7f) { /* Error, so process */ if(stat8 & 0x7f) { /* Error, so process */
stat8 &= 0x7f; stat8 &= 0x7f;
if (stat8 & 0x2b) if (stat8 & 0x2b)
hub_error(1, stat8 & 0x2b, error_found, handle_error); hub_error(1, stat8 & 0x2b, error_found, handle_error);
if(stat8 & 0x54) if(stat8 & 0x54)
hub_error(0, stat8 & 0x54, error_found, handle_error); hub_error(0, stat8 & 0x54, error_found, handle_error);
} }
} }
static void e752x_check_sysbus (struct e752x_error_info *info, int *error_found, static void e752x_check_sysbus(struct e752x_error_info *info,
int handle_error) int *error_found, int handle_error)
{ {
u32 stat32, error32; u32 stat32, error32;
...@@ -540,27 +553,34 @@ static void e752x_check_sysbus (struct e752x_error_info *info, int *error_found, ...@@ -540,27 +553,34 @@ static void e752x_check_sysbus (struct e752x_error_info *info, int *error_found,
error32 = (stat32 >> 16) & 0x3ff; error32 = (stat32 >> 16) & 0x3ff;
stat32 = stat32 & 0x3ff; stat32 = stat32 & 0x3ff;
if(stat32 & 0x083) if(stat32 & 0x083)
sysbus_error(1, stat32 & 0x083, error_found, handle_error); sysbus_error(1, stat32 & 0x083, error_found, handle_error);
if(stat32 & 0x37c) if(stat32 & 0x37c)
sysbus_error(0, stat32 & 0x37c, error_found, handle_error); sysbus_error(0, stat32 & 0x37c, error_found, handle_error);
if(error32 & 0x083) if(error32 & 0x083)
sysbus_error(1, error32 & 0x083, error_found, handle_error); sysbus_error(1, error32 & 0x083, error_found, handle_error);
if(error32 & 0x37c) if(error32 & 0x37c)
sysbus_error(0, error32 & 0x37c, error_found, handle_error); sysbus_error(0, error32 & 0x37c, error_found, handle_error);
} }
static void e752x_check_membuf (struct e752x_error_info *info, int *error_found, static void e752x_check_membuf (struct e752x_error_info *info,
int handle_error) int *error_found, int handle_error)
{ {
u8 stat8; u8 stat8;
stat8 = info->buf_ferr; stat8 = info->buf_ferr;
if (stat8 & 0x0f) { /* Error, so process */ if (stat8 & 0x0f) { /* Error, so process */
stat8 &= 0x0f; stat8 &= 0x0f;
membuf_error(stat8, error_found, handle_error); membuf_error(stat8, error_found, handle_error);
} }
stat8 = info->buf_nerr; stat8 = info->buf_nerr;
if (stat8 & 0x0f) { /* Error, so process */ if (stat8 & 0x0f) { /* Error, so process */
stat8 &= 0x0f; stat8 &= 0x0f;
membuf_error(stat8, error_found, handle_error); membuf_error(stat8, error_found, handle_error);
...@@ -568,7 +588,8 @@ static void e752x_check_membuf (struct e752x_error_info *info, int *error_found, ...@@ -568,7 +588,8 @@ static void e752x_check_membuf (struct e752x_error_info *info, int *error_found,
} }
static void e752x_check_dram (struct mem_ctl_info *mci, static void e752x_check_dram (struct mem_ctl_info *mci,
struct e752x_error_info *info, int *error_found, int handle_error) struct e752x_error_info *info, int *error_found,
int handle_error)
{ {
u16 error_one, error_next; u16 error_one, error_next;
...@@ -618,7 +639,7 @@ static void e752x_check_dram (struct mem_ctl_info *mci, ...@@ -618,7 +639,7 @@ static void e752x_check_dram (struct mem_ctl_info *mci,
} }
static void e752x_get_error_info (struct mem_ctl_info *mci, static void e752x_get_error_info (struct mem_ctl_info *mci,
struct e752x_error_info *info) struct e752x_error_info *info)
{ {
struct pci_dev *dev; struct pci_dev *dev;
struct e752x_pvt *pvt; struct e752x_pvt *pvt;
...@@ -626,7 +647,6 @@ static void e752x_get_error_info (struct mem_ctl_info *mci, ...@@ -626,7 +647,6 @@ static void e752x_get_error_info (struct mem_ctl_info *mci,
memset(info, 0, sizeof(*info)); memset(info, 0, sizeof(*info));
pvt = (struct e752x_pvt *) mci->pvt_info; pvt = (struct e752x_pvt *) mci->pvt_info;
dev = pvt->dev_d0f1; dev = pvt->dev_d0f1;
pci_read_config_dword(dev, E752X_FERR_GLOBAL, &info->ferr_global); pci_read_config_dword(dev, E752X_FERR_GLOBAL, &info->ferr_global);
if (info->ferr_global) { if (info->ferr_global) {
...@@ -737,6 +757,7 @@ static int e752x_process_error_info (struct mem_ctl_info *mci, ...@@ -737,6 +757,7 @@ static int e752x_process_error_info (struct mem_ctl_info *mci,
static void e752x_check(struct mem_ctl_info *mci) static void e752x_check(struct mem_ctl_info *mci)
{ {
struct e752x_error_info info; struct e752x_error_info info;
debugf3("%s()\n", __func__); debugf3("%s()\n", __func__);
e752x_get_error_info(mci, &info); e752x_get_error_info(mci, &info);
e752x_process_error_info(mci, &info, 1); e752x_process_error_info(mci, &info, 1);
...@@ -752,9 +773,9 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -752,9 +773,9 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
struct e752x_pvt *pvt = NULL; struct e752x_pvt *pvt = NULL;
u16 ddrcsr; u16 ddrcsr;
u32 drc; u32 drc;
int drc_chan; /* Number of channels 0=1chan,1=2chan */ int drc_chan; /* Number of channels 0=1chan,1=2chan */
int drc_drbg; /* DRB granularity 0=64mb,1=128mb */ int drc_drbg; /* DRB granularity 0=64mb, 1=128mb */
int drc_ddim; /* DRAM Data Integrity Mode 0=none,2=edac */ int drc_ddim; /* DRAM Data Integrity Mode 0=none,2=edac */
u32 dra; u32 dra;
unsigned long last_cumul_size; unsigned long last_cumul_size;
struct pci_dev *dev = NULL; struct pci_dev *dev = NULL;
...@@ -785,7 +806,6 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -785,7 +806,6 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
} }
debugf3("%s(): init mci\n", __func__); debugf3("%s(): init mci\n", __func__);
mci->mtype_cap = MEM_FLAG_RDDR; mci->mtype_cap = MEM_FLAG_RDDR;
mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED | mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED |
EDAC_FLAG_S4ECD4ED; EDAC_FLAG_S4ECD4ED;
...@@ -798,19 +818,21 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -798,19 +818,21 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
pvt = (struct e752x_pvt *) mci->pvt_info; pvt = (struct e752x_pvt *) mci->pvt_info;
pvt->dev_info = &e752x_devs[dev_idx]; pvt->dev_info = &e752x_devs[dev_idx];
pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL, pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL,
pvt->dev_info->err_dev, pvt->dev_info->err_dev,
pvt->bridge_ck); pvt->bridge_ck);
if (pvt->bridge_ck == NULL) if (pvt->bridge_ck == NULL)
pvt->bridge_ck = pci_scan_single_device(pdev->bus, pvt->bridge_ck = pci_scan_single_device(pdev->bus,
PCI_DEVFN(0, 1)); PCI_DEVFN(0, 1));
if (pvt->bridge_ck == NULL) { if (pvt->bridge_ck == NULL) {
e752x_printk(KERN_ERR, "error reporting device not found:" e752x_printk(KERN_ERR, "error reporting device not found:"
"vendor %x device 0x%x (broken BIOS?)\n", "vendor %x device 0x%x (broken BIOS?)\n",
PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].err_dev); PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].err_dev);
goto fail; goto fail;
} }
pvt->mc_symmetric = ((ddrcsr & 0x10) != 0);
pvt->mc_symmetric = ((ddrcsr & 0x10) != 0);
debugf3("%s(): more mci init\n", __func__); debugf3("%s(): more mci init\n", __func__);
mci->ctl_name = pvt->dev_info->ctl_name; mci->ctl_name = pvt->dev_info->ctl_name;
mci->edac_check = e752x_check; mci->edac_check = e752x_check;
...@@ -828,6 +850,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -828,6 +850,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) { for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) {
u8 value; u8 value;
u32 cumul_size; u32 cumul_size;
/* mem_dev 0=x8, 1=x4 */ /* mem_dev 0=x8, 1=x4 */
int mem_dev = (dra >> (index * 4 + 2)) & 0x3; int mem_dev = (dra >> (index * 4 + 2)) & 0x3;
struct csrow_info *csrow = &mci->csrows[index]; struct csrow_info *csrow = &mci->csrows[index];
...@@ -838,15 +861,16 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -838,15 +861,16 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
cumul_size = value << (25 + drc_drbg - PAGE_SHIFT); cumul_size = value << (25 + drc_drbg - PAGE_SHIFT);
debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index,
cumul_size); cumul_size);
if (cumul_size == last_cumul_size) if (cumul_size == last_cumul_size)
continue; /* not populated */ continue; /* not populated */
csrow->first_page = last_cumul_size; csrow->first_page = last_cumul_size;
csrow->last_page = cumul_size - 1; csrow->last_page = cumul_size - 1;
csrow->nr_pages = cumul_size - last_cumul_size; csrow->nr_pages = cumul_size - last_cumul_size;
last_cumul_size = cumul_size; last_cumul_size = cumul_size;
csrow->grain = 1 << 12; /* 4KiB - resolution of CELOG */ csrow->grain = 1 << 12; /* 4KiB - resolution of CELOG */
csrow->mtype = MEM_RDDR; /* only one type supported */ csrow->mtype = MEM_RDDR; /* only one type supported */
csrow->dtype = mem_dev ? DEV_X4 : DEV_X8; csrow->dtype = mem_dev ? DEV_X4 : DEV_X8;
/* /*
...@@ -870,29 +894,32 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -870,29 +894,32 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
u8 value; u8 value;
u8 last = 0; u8 last = 0;
u8 row = 0; u8 row = 0;
for (index = 0; index < 8; index += 2) {
for (index = 0; index < 8; index += 2) {
pci_read_config_byte(mci->pdev, E752X_DRB + index, pci_read_config_byte(mci->pdev, E752X_DRB + index,
&value); &value);
/* test if there is a dimm in this slot */ /* test if there is a dimm in this slot */
if (value == last) { if (value == last) {
/* no dimm in the slot, so flag it as empty */ /* no dimm in the slot, so flag it as empty */
pvt->map[index] = 0xff; pvt->map[index] = 0xff;
pvt->map[index + 1] = 0xff; pvt->map[index + 1] = 0xff;
} else { /* there is a dimm in the slot */ } else { /* there is a dimm in the slot */
pvt->map[index] = row; pvt->map[index] = row;
row++; row++;
last = value; last = value;
/* test the next value to see if the dimm is /* test the next value to see if the dimm is
double sided */ double sided */
pci_read_config_byte(mci->pdev, pci_read_config_byte(mci->pdev,
E752X_DRB + index + 1, E752X_DRB + index + 1,
&value); &value);
pvt->map[index + 1] = (value == last) ? pvt->map[index + 1] = (value == last) ?
0xff : /* the dimm is single sided, 0xff : /* the dimm is single sided,
so flag as empty */ * so flag as empty
row; /* this is a double sided dimm */
to save the next row # */ row; /* this is a double sided dimm
* to save the next row #
*/
row++; row++;
last = value; last = value;
} }
...@@ -904,8 +931,8 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -904,8 +931,8 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
pvt->map_type = ((stat8 & 0x0f) > ((stat8 >> 4) & 0x0f)); pvt->map_type = ((stat8 & 0x0f) > ((stat8 >> 4) & 0x0f));
mci->edac_cap |= EDAC_FLAG_NONE; mci->edac_cap |= EDAC_FLAG_NONE;
debugf3("%s(): tolm, remapbase, remaplimit\n", __func__); debugf3("%s(): tolm, remapbase, remaplimit\n", __func__);
/* load the top of low memory, remap base, and remap limit vars */ /* load the top of low memory, remap base, and remap limit vars */
pci_read_config_word(mci->pdev, E752X_TOLM, &pci_data); pci_read_config_word(mci->pdev, E752X_TOLM, &pci_data);
pvt->tolm = ((u32) pci_data) << 4; pvt->tolm = ((u32) pci_data) << 4;
...@@ -914,8 +941,8 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -914,8 +941,8 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
pci_read_config_word(mci->pdev, E752X_REMAPLIMIT, &pci_data); pci_read_config_word(mci->pdev, E752X_REMAPLIMIT, &pci_data);
pvt->remaplimit = ((u32) pci_data) << 14; pvt->remaplimit = ((u32) pci_data) << 14;
e752x_printk(KERN_INFO, e752x_printk(KERN_INFO,
"tolm = %x, remapbase = %x, remaplimit = %x\n", "tolm = %x, remapbase = %x, remaplimit = %x\n", pvt->tolm,
pvt->tolm, pvt->remapbase, pvt->remaplimit); pvt->remapbase, pvt->remaplimit);
if (edac_mc_add_mc(mci)) { if (edac_mc_add_mc(mci)) {
debugf3("%s(): failed edac_mc_add_mc()\n", __func__); debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
...@@ -923,7 +950,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -923,7 +950,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
} }
dev = pci_get_device(PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].ctl_dev, dev = pci_get_device(PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].ctl_dev,
NULL); NULL);
pvt->dev_d0f0 = dev; pvt->dev_d0f0 = dev;
/* find the error reporting device and clear errors */ /* find the error reporting device and clear errors */
dev = pvt->dev_d0f1 = pci_dev_get(pvt->bridge_ck); dev = pvt->dev_d0f1 = pci_dev_get(pvt->bridge_ck);
...@@ -936,8 +963,8 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -936,8 +963,8 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
pci_write_config_byte(dev, E752X_BUF_SMICMD, 0x00); pci_write_config_byte(dev, E752X_BUF_SMICMD, 0x00);
pci_write_config_byte(dev, E752X_DRAM_ERRMASK, 0x00); pci_write_config_byte(dev, E752X_DRAM_ERRMASK, 0x00);
pci_write_config_byte(dev, E752X_DRAM_SMICMD, 0x00); pci_write_config_byte(dev, E752X_DRAM_SMICMD, 0x00);
/* clear other MCH errors */
e752x_get_error_info(mci, &discard); e752x_get_error_info(mci, &discard); /* clear other MCH errors */
/* get this far and it's successful */ /* get this far and it's successful */
debugf3("%s(): success\n", __func__); debugf3("%s(): success\n", __func__);
...@@ -947,28 +974,32 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -947,28 +974,32 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
if (mci) { if (mci) {
if (pvt->dev_d0f0) if (pvt->dev_d0f0)
pci_dev_put(pvt->dev_d0f0); pci_dev_put(pvt->dev_d0f0);
if (pvt->dev_d0f1) if (pvt->dev_d0f1)
pci_dev_put(pvt->dev_d0f1); pci_dev_put(pvt->dev_d0f1);
if (pvt->bridge_ck) if (pvt->bridge_ck)
pci_dev_put(pvt->bridge_ck); pci_dev_put(pvt->bridge_ck);
edac_mc_free(mci); edac_mc_free(mci);
} }
return rc; return rc;
} }
/* returns count (>= 0), or negative on error */ /* returns count (>= 0), or negative on error */
static int __devinit e752x_init_one(struct pci_dev *pdev, static int __devinit e752x_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
debugf0("%s()\n", __func__); debugf0("%s()\n", __func__);
/* wake up and enable device */ /* wake up and enable device */
if(pci_enable_device(pdev) < 0) if(pci_enable_device(pdev) < 0)
return -EIO; return -EIO;
return e752x_probe1(pdev, ent->driver_data); return e752x_probe1(pdev, ent->driver_data);
} }
static void __devexit e752x_remove_one(struct pci_dev *pdev) static void __devexit e752x_remove_one(struct pci_dev *pdev)
{ {
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
...@@ -986,20 +1017,26 @@ static void __devexit e752x_remove_one(struct pci_dev *pdev) ...@@ -986,20 +1017,26 @@ static void __devexit e752x_remove_one(struct pci_dev *pdev)
edac_mc_free(mci); edac_mc_free(mci);
} }
static const struct pci_device_id e752x_pci_tbl[] __devinitdata = { static const struct pci_device_id e752x_pci_tbl[] __devinitdata = {
{PCI_VEND_DEV(INTEL, 7520_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, {
E7520}, PCI_VEND_DEV(INTEL, 7520_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
{PCI_VEND_DEV(INTEL, 7525_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, E7520
E7525}, },
{PCI_VEND_DEV(INTEL, 7320_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, {
E7320}, PCI_VEND_DEV(INTEL, 7525_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
{0,} /* 0 terminated list. */ E7525
},
{
PCI_VEND_DEV(INTEL, 7320_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
E7320
},
{
0,
} /* 0 terminated list. */
}; };
MODULE_DEVICE_TABLE(pci, e752x_pci_tbl); MODULE_DEVICE_TABLE(pci, e752x_pci_tbl);
static struct pci_driver e752x_driver = { static struct pci_driver e752x_driver = {
.name = EDAC_MOD_STR, .name = EDAC_MOD_STR,
.probe = e752x_init_one, .probe = e752x_init_one,
...@@ -1007,7 +1044,6 @@ static struct pci_driver e752x_driver = { ...@@ -1007,7 +1044,6 @@ static struct pci_driver e752x_driver = {
.id_table = e752x_pci_tbl, .id_table = e752x_pci_tbl,
}; };
static int __init e752x_init(void) static int __init e752x_init(void)
{ {
int pci_rc; int pci_rc;
...@@ -1017,14 +1053,12 @@ static int __init e752x_init(void) ...@@ -1017,14 +1053,12 @@ static int __init e752x_init(void)
return (pci_rc < 0) ? pci_rc : 0; return (pci_rc < 0) ? pci_rc : 0;
} }
static void __exit e752x_exit(void) static void __exit e752x_exit(void)
{ {
debugf3("%s()\n", __func__); debugf3("%s()\n", __func__);
pci_unregister_driver(&e752x_driver); pci_unregister_driver(&e752x_driver);
} }
module_init(e752x_init); module_init(e752x_init);
module_exit(e752x_exit); module_exit(e752x_exit);
......
...@@ -11,9 +11,9 @@ ...@@ -11,9 +11,9 @@
* http://www.anime.net/~goemon/linux-ecc/ * http://www.anime.net/~goemon/linux-ecc/
* *
* Contributors: * Contributors:
* Eric Biederman (Linux Networx) * Eric Biederman (Linux Networx)
* Tom Zimmerman (Linux Networx) * Tom Zimmerman (Linux Networx)
* Jim Garlick (Lawrence Livermore National Labs) * Jim Garlick (Lawrence Livermore National Labs)
* Dave Peterson (Lawrence Livermore National Labs) * Dave Peterson (Lawrence Livermore National Labs)
* That One Guy (Some other place) * That One Guy (Some other place)
* Wang Zhenyu (intel.com) * Wang Zhenyu (intel.com)
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
* *
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -31,14 +30,11 @@ ...@@ -31,14 +30,11 @@
#include <linux/slab.h> #include <linux/slab.h>
#include "edac_mc.h" #include "edac_mc.h"
#define e7xxx_printk(level, fmt, arg...) \ #define e7xxx_printk(level, fmt, arg...) \
edac_printk(level, "e7xxx", fmt, ##arg) edac_printk(level, "e7xxx", fmt, ##arg)
#define e7xxx_mc_printk(mci, level, fmt, arg...) \ #define e7xxx_mc_printk(mci, level, fmt, arg...) \
edac_mc_chipset_printk(mci, level, "e7xxx", fmt, ##arg) edac_mc_chipset_printk(mci, level, "e7xxx", fmt, ##arg)
#ifndef PCI_DEVICE_ID_INTEL_7205_0 #ifndef PCI_DEVICE_ID_INTEL_7205_0
#define PCI_DEVICE_ID_INTEL_7205_0 0x255d #define PCI_DEVICE_ID_INTEL_7205_0 0x255d
...@@ -72,11 +68,9 @@ ...@@ -72,11 +68,9 @@
#define PCI_DEVICE_ID_INTEL_7505_1_ERR 0x2551 #define PCI_DEVICE_ID_INTEL_7505_1_ERR 0x2551
#endif /* PCI_DEVICE_ID_INTEL_7505_1_ERR */ #endif /* PCI_DEVICE_ID_INTEL_7505_1_ERR */
#define E7XXX_NR_CSROWS 8 /* number of csrows */ #define E7XXX_NR_CSROWS 8 /* number of csrows */
#define E7XXX_NR_DIMMS 8 /* FIXME - is this correct? */ #define E7XXX_NR_DIMMS 8 /* FIXME - is this correct? */
/* E7XXX register addresses - device 0 function 0 */ /* E7XXX register addresses - device 0 function 0 */
#define E7XXX_DRB 0x60 /* DRAM row boundary register (8b) */ #define E7XXX_DRB 0x60 /* DRAM row boundary register (8b) */
#define E7XXX_DRA 0x70 /* DRAM row attribute register (8b) */ #define E7XXX_DRA 0x70 /* DRAM row attribute register (8b) */
...@@ -126,7 +120,6 @@ enum e7xxx_chips { ...@@ -126,7 +120,6 @@ enum e7xxx_chips {
E7205, E7205,
}; };
struct e7xxx_pvt { struct e7xxx_pvt {
struct pci_dev *bridge_ck; struct pci_dev *bridge_ck;
u32 tolm; u32 tolm;
...@@ -135,13 +128,11 @@ struct e7xxx_pvt { ...@@ -135,13 +128,11 @@ struct e7xxx_pvt {
const struct e7xxx_dev_info *dev_info; const struct e7xxx_dev_info *dev_info;
}; };
struct e7xxx_dev_info { struct e7xxx_dev_info {
u16 err_dev; u16 err_dev;
const char *ctl_name; const char *ctl_name;
}; };
struct e7xxx_error_info { struct e7xxx_error_info {
u8 dram_ferr; u8 dram_ferr;
u8 dram_nerr; u8 dram_nerr;
...@@ -152,20 +143,23 @@ struct e7xxx_error_info { ...@@ -152,20 +143,23 @@ struct e7xxx_error_info {
static const struct e7xxx_dev_info e7xxx_devs[] = { static const struct e7xxx_dev_info e7xxx_devs[] = {
[E7500] = { [E7500] = {
.err_dev = PCI_DEVICE_ID_INTEL_7500_1_ERR, .err_dev = PCI_DEVICE_ID_INTEL_7500_1_ERR,
.ctl_name = "E7500"}, .ctl_name = "E7500"
},
[E7501] = { [E7501] = {
.err_dev = PCI_DEVICE_ID_INTEL_7501_1_ERR, .err_dev = PCI_DEVICE_ID_INTEL_7501_1_ERR,
.ctl_name = "E7501"}, .ctl_name = "E7501"
},
[E7505] = { [E7505] = {
.err_dev = PCI_DEVICE_ID_INTEL_7505_1_ERR, .err_dev = PCI_DEVICE_ID_INTEL_7505_1_ERR,
.ctl_name = "E7505"}, .ctl_name = "E7505"
},
[E7205] = { [E7205] = {
.err_dev = PCI_DEVICE_ID_INTEL_7205_1_ERR, .err_dev = PCI_DEVICE_ID_INTEL_7205_1_ERR,
.ctl_name = "E7205"}, .ctl_name = "E7205"
},
}; };
/* FIXME - is this valid for both SECDED and S4ECD4ED? */ /* FIXME - is this valid for both SECDED and S4ECD4ED? */
static inline int e7xxx_find_channel(u16 syndrome) static inline int e7xxx_find_channel(u16 syndrome)
{ {
...@@ -173,16 +167,18 @@ static inline int e7xxx_find_channel(u16 syndrome) ...@@ -173,16 +167,18 @@ static inline int e7xxx_find_channel(u16 syndrome)
if ((syndrome & 0xff00) == 0) if ((syndrome & 0xff00) == 0)
return 0; return 0;
if ((syndrome & 0x00ff) == 0) if ((syndrome & 0x00ff) == 0)
return 1; return 1;
if ((syndrome & 0xf000) == 0 || (syndrome & 0x0f00) == 0) if ((syndrome & 0xf000) == 0 || (syndrome & 0x0f00) == 0)
return 0; return 0;
return 1; return 1;
} }
static unsigned long ctl_page_to_phys(struct mem_ctl_info *mci,
static unsigned long unsigned long page)
ctl_page_to_phys(struct mem_ctl_info *mci, unsigned long page)
{ {
u32 remap; u32 remap;
struct e7xxx_pvt *pvt = (struct e7xxx_pvt *) mci->pvt_info; struct e7xxx_pvt *pvt = (struct e7xxx_pvt *) mci->pvt_info;
...@@ -190,17 +186,20 @@ ctl_page_to_phys(struct mem_ctl_info *mci, unsigned long page) ...@@ -190,17 +186,20 @@ ctl_page_to_phys(struct mem_ctl_info *mci, unsigned long page)
debugf3("%s()\n", __func__); debugf3("%s()\n", __func__);
if ((page < pvt->tolm) || if ((page < pvt->tolm) ||
((page >= 0x100000) && (page < pvt->remapbase))) ((page >= 0x100000) && (page < pvt->remapbase)))
return page; return page;
remap = (page - pvt->tolm) + pvt->remapbase; remap = (page - pvt->tolm) + pvt->remapbase;
if (remap < pvt->remaplimit) if (remap < pvt->remaplimit)
return remap; return remap;
e7xxx_printk(KERN_ERR, "Invalid page %lx - out of range\n", page); e7xxx_printk(KERN_ERR, "Invalid page %lx - out of range\n", page);
return pvt->tolm - 1; return pvt->tolm - 1;
} }
static void process_ce(struct mem_ctl_info *mci,
static void process_ce(struct mem_ctl_info *mci, struct e7xxx_error_info *info) struct e7xxx_error_info *info)
{ {
u32 error_1b, page; u32 error_1b, page;
u16 syndrome; u16 syndrome;
...@@ -208,52 +207,46 @@ static void process_ce(struct mem_ctl_info *mci, struct e7xxx_error_info *info) ...@@ -208,52 +207,46 @@ static void process_ce(struct mem_ctl_info *mci, struct e7xxx_error_info *info)
int channel; int channel;
debugf3("%s()\n", __func__); debugf3("%s()\n", __func__);
/* read the error address */ /* read the error address */
error_1b = info->dram_celog_add; error_1b = info->dram_celog_add;
/* FIXME - should use PAGE_SHIFT */ /* FIXME - should use PAGE_SHIFT */
page = error_1b >> 6; /* convert the address to 4k page */ page = error_1b >> 6; /* convert the address to 4k page */
/* read the syndrome */ /* read the syndrome */
syndrome = info->dram_celog_syndrome; syndrome = info->dram_celog_syndrome;
/* FIXME - check for -1 */ /* FIXME - check for -1 */
row = edac_mc_find_csrow_by_page(mci, page); row = edac_mc_find_csrow_by_page(mci, page);
/* convert syndrome to channel */ /* convert syndrome to channel */
channel = e7xxx_find_channel(syndrome); channel = e7xxx_find_channel(syndrome);
edac_mc_handle_ce(mci, page, 0, syndrome, row, channel, edac_mc_handle_ce(mci, page, 0, syndrome, row, channel, "e7xxx CE");
"e7xxx CE");
} }
static void process_ce_no_info(struct mem_ctl_info *mci) static void process_ce_no_info(struct mem_ctl_info *mci)
{ {
debugf3("%s()\n", __func__); debugf3("%s()\n", __func__);
edac_mc_handle_ce_no_info(mci, "e7xxx CE log register overflow"); edac_mc_handle_ce_no_info(mci, "e7xxx CE log register overflow");
} }
static void process_ue(struct mem_ctl_info *mci,
static void process_ue(struct mem_ctl_info *mci, struct e7xxx_error_info *info) struct e7xxx_error_info *info)
{ {
u32 error_2b, block_page; u32 error_2b, block_page;
int row; int row;
debugf3("%s()\n", __func__); debugf3("%s()\n", __func__);
/* read the error address */ /* read the error address */
error_2b = info->dram_uelog_add; error_2b = info->dram_uelog_add;
/* FIXME - should use PAGE_SHIFT */ /* FIXME - should use PAGE_SHIFT */
block_page = error_2b >> 6; /* convert to 4k address */ block_page = error_2b >> 6; /* convert to 4k address */
row = edac_mc_find_csrow_by_page(mci, block_page); row = edac_mc_find_csrow_by_page(mci, block_page);
edac_mc_handle_ue(mci, block_page, 0, row, "e7xxx UE"); edac_mc_handle_ue(mci, block_page, 0, row, "e7xxx UE");
} }
static void process_ue_no_info(struct mem_ctl_info *mci) static void process_ue_no_info(struct mem_ctl_info *mci)
{ {
debugf3("%s()\n", __func__); debugf3("%s()\n", __func__);
edac_mc_handle_ue_no_info(mci, "e7xxx UE log register overflow"); edac_mc_handle_ue_no_info(mci, "e7xxx UE log register overflow");
} }
static void e7xxx_get_error_info (struct mem_ctl_info *mci, static void e7xxx_get_error_info (struct mem_ctl_info *mci,
struct e7xxx_error_info *info) struct e7xxx_error_info *info)
{ {
...@@ -261,31 +254,29 @@ static void e7xxx_get_error_info (struct mem_ctl_info *mci, ...@@ -261,31 +254,29 @@ static void e7xxx_get_error_info (struct mem_ctl_info *mci,
pvt = (struct e7xxx_pvt *) mci->pvt_info; pvt = (struct e7xxx_pvt *) mci->pvt_info;
pci_read_config_byte(pvt->bridge_ck, E7XXX_DRAM_FERR, pci_read_config_byte(pvt->bridge_ck, E7XXX_DRAM_FERR,
&info->dram_ferr); &info->dram_ferr);
pci_read_config_byte(pvt->bridge_ck, E7XXX_DRAM_NERR, pci_read_config_byte(pvt->bridge_ck, E7XXX_DRAM_NERR,
&info->dram_nerr); &info->dram_nerr);
if ((info->dram_ferr & 1) || (info->dram_nerr & 1)) { if ((info->dram_ferr & 1) || (info->dram_nerr & 1)) {
pci_read_config_dword(pvt->bridge_ck, E7XXX_DRAM_CELOG_ADD, pci_read_config_dword(pvt->bridge_ck, E7XXX_DRAM_CELOG_ADD,
&info->dram_celog_add); &info->dram_celog_add);
pci_read_config_word(pvt->bridge_ck, pci_read_config_word(pvt->bridge_ck,
E7XXX_DRAM_CELOG_SYNDROME, &info->dram_celog_syndrome); E7XXX_DRAM_CELOG_SYNDROME,
&info->dram_celog_syndrome);
} }
if ((info->dram_ferr & 2) || (info->dram_nerr & 2)) if ((info->dram_ferr & 2) || (info->dram_nerr & 2))
pci_read_config_dword(pvt->bridge_ck, E7XXX_DRAM_UELOG_ADD, pci_read_config_dword(pvt->bridge_ck, E7XXX_DRAM_UELOG_ADD,
&info->dram_uelog_add); &info->dram_uelog_add);
if (info->dram_ferr & 3) if (info->dram_ferr & 3)
pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_FERR, 0x03, pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_FERR, 0x03, 0x03);
0x03);
if (info->dram_nerr & 3) if (info->dram_nerr & 3)
pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_NERR, 0x03, pci_write_bits8(pvt->bridge_ck, E7XXX_DRAM_NERR, 0x03, 0x03);
0x03);
} }
static int e7xxx_process_error_info (struct mem_ctl_info *mci, static int e7xxx_process_error_info (struct mem_ctl_info *mci,
struct e7xxx_error_info *info, int handle_errors) struct e7xxx_error_info *info, int handle_errors)
{ {
...@@ -333,7 +324,6 @@ static int e7xxx_process_error_info (struct mem_ctl_info *mci, ...@@ -333,7 +324,6 @@ static int e7xxx_process_error_info (struct mem_ctl_info *mci,
return error_found; return error_found;
} }
static void e7xxx_check(struct mem_ctl_info *mci) static void e7xxx_check(struct mem_ctl_info *mci)
{ {
struct e7xxx_error_info info; struct e7xxx_error_info info;
...@@ -343,7 +333,6 @@ static void e7xxx_check(struct mem_ctl_info *mci) ...@@ -343,7 +333,6 @@ static void e7xxx_check(struct mem_ctl_info *mci)
e7xxx_process_error_info(mci, &info, 1); e7xxx_process_error_info(mci, &info, 1);
} }
static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx)
{ {
int rc = -ENODEV; int rc = -ENODEV;
...@@ -363,13 +352,14 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -363,13 +352,14 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx)
/* need to find out the number of channels */ /* need to find out the number of channels */
pci_read_config_dword(pdev, E7XXX_DRC, &drc); pci_read_config_dword(pdev, E7XXX_DRC, &drc);
/* only e7501 can be single channel */ /* only e7501 can be single channel */
if (dev_idx == E7501) { if (dev_idx == E7501) {
drc_chan = ((drc >> 22) & 0x1); drc_chan = ((drc >> 22) & 0x1);
drc_drbg = (drc >> 18) & 0x3; drc_drbg = (drc >> 18) & 0x3;
} }
drc_ddim = (drc >> 20) & 0x3;
drc_ddim = (drc >> 20) & 0x3;
mci = edac_mc_alloc(sizeof(*pvt), E7XXX_NR_CSROWS, drc_chan + 1); mci = edac_mc_alloc(sizeof(*pvt), E7XXX_NR_CSROWS, drc_chan + 1);
if (mci == NULL) { if (mci == NULL) {
...@@ -378,10 +368,9 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -378,10 +368,9 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx)
} }
debugf3("%s(): init mci\n", __func__); debugf3("%s(): init mci\n", __func__);
mci->mtype_cap = MEM_FLAG_RDDR; mci->mtype_cap = MEM_FLAG_RDDR;
mci->edac_ctl_cap = mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED |
EDAC_FLAG_NONE | EDAC_FLAG_SECDED | EDAC_FLAG_S4ECD4ED; EDAC_FLAG_S4ECD4ED;
/* FIXME - what if different memory types are in different csrows? */ /* FIXME - what if different memory types are in different csrows? */
mci->mod_name = EDAC_MOD_STR; mci->mod_name = EDAC_MOD_STR;
mci->mod_ver = "$Revision: 1.5.2.9 $"; mci->mod_ver = "$Revision: 1.5.2.9 $";
...@@ -391,19 +380,18 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -391,19 +380,18 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx)
pvt = (struct e7xxx_pvt *) mci->pvt_info; pvt = (struct e7xxx_pvt *) mci->pvt_info;
pvt->dev_info = &e7xxx_devs[dev_idx]; pvt->dev_info = &e7xxx_devs[dev_idx];
pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL, pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL,
pvt->dev_info->err_dev, pvt->dev_info->err_dev,
pvt->bridge_ck); pvt->bridge_ck);
if (!pvt->bridge_ck) { if (!pvt->bridge_ck) {
e7xxx_printk(KERN_ERR, "error reporting device not found:" e7xxx_printk(KERN_ERR, "error reporting device not found:"
"vendor %x device 0x%x (broken BIOS?)\n", "vendor %x device 0x%x (broken BIOS?)\n",
PCI_VENDOR_ID_INTEL, PCI_VENDOR_ID_INTEL, e7xxx_devs[dev_idx].err_dev);
e7xxx_devs[dev_idx].err_dev);
goto fail; goto fail;
} }
debugf3("%s(): more mci init\n", __func__); debugf3("%s(): more mci init\n", __func__);
mci->ctl_name = pvt->dev_info->ctl_name; mci->ctl_name = pvt->dev_info->ctl_name;
mci->edac_check = e7xxx_check; mci->edac_check = e7xxx_check;
mci->ctl_page_to_phys = ctl_page_to_phys; mci->ctl_page_to_phys = ctl_page_to_phys;
...@@ -428,15 +416,16 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -428,15 +416,16 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx)
cumul_size = value << (25 + drc_drbg - PAGE_SHIFT); cumul_size = value << (25 + drc_drbg - PAGE_SHIFT);
debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index,
cumul_size); cumul_size);
if (cumul_size == last_cumul_size) if (cumul_size == last_cumul_size)
continue; /* not populated */ continue; /* not populated */
csrow->first_page = last_cumul_size; csrow->first_page = last_cumul_size;
csrow->last_page = cumul_size - 1; csrow->last_page = cumul_size - 1;
csrow->nr_pages = cumul_size - last_cumul_size; csrow->nr_pages = cumul_size - last_cumul_size;
last_cumul_size = cumul_size; last_cumul_size = cumul_size;
csrow->grain = 1 << 12; /* 4KiB - resolution of CELOG */ csrow->grain = 1 << 12; /* 4KiB - resolution of CELOG */
csrow->mtype = MEM_RDDR; /* only one type supported */ csrow->mtype = MEM_RDDR; /* only one type supported */
csrow->dtype = mem_dev ? DEV_X4 : DEV_X8; csrow->dtype = mem_dev ? DEV_X4 : DEV_X8;
/* /*
...@@ -466,8 +455,8 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -466,8 +455,8 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx)
pci_read_config_word(mci->pdev, E7XXX_REMAPLIMIT, &pci_data); pci_read_config_word(mci->pdev, E7XXX_REMAPLIMIT, &pci_data);
pvt->remaplimit = ((u32) pci_data) << 14; pvt->remaplimit = ((u32) pci_data) << 14;
e7xxx_printk(KERN_INFO, e7xxx_printk(KERN_INFO,
"tolm = %x, remapbase = %x, remaplimit = %x\n", "tolm = %x, remapbase = %x, remaplimit = %x\n", pvt->tolm,
pvt->tolm, pvt->remapbase, pvt->remaplimit); pvt->remapbase, pvt->remaplimit);
/* clear any pending errors, or initial state bits */ /* clear any pending errors, or initial state bits */
e7xxx_get_error_info(mci, &discard); e7xxx_get_error_info(mci, &discard);
...@@ -492,17 +481,16 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -492,17 +481,16 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx)
} }
/* returns count (>= 0), or negative on error */ /* returns count (>= 0), or negative on error */
static int __devinit static int __devinit e7xxx_init_one(struct pci_dev *pdev,
e7xxx_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
debugf0("%s()\n", __func__); debugf0("%s()\n", __func__);
/* wake up and enable device */ /* wake up and enable device */
return pci_enable_device(pdev) ? return pci_enable_device(pdev) ?
-EIO : e7xxx_probe1(pdev, ent->driver_data); -EIO : e7xxx_probe1(pdev, ent->driver_data);
} }
static void __devexit e7xxx_remove_one(struct pci_dev *pdev) static void __devexit e7xxx_remove_one(struct pci_dev *pdev)
{ {
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
...@@ -518,22 +506,30 @@ static void __devexit e7xxx_remove_one(struct pci_dev *pdev) ...@@ -518,22 +506,30 @@ static void __devexit e7xxx_remove_one(struct pci_dev *pdev)
edac_mc_free(mci); edac_mc_free(mci);
} }
static const struct pci_device_id e7xxx_pci_tbl[] __devinitdata = { static const struct pci_device_id e7xxx_pci_tbl[] __devinitdata = {
{PCI_VEND_DEV(INTEL, 7205_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, {
E7205}, PCI_VEND_DEV(INTEL, 7205_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
{PCI_VEND_DEV(INTEL, 7500_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, E7205
E7500}, },
{PCI_VEND_DEV(INTEL, 7501_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, {
E7501}, PCI_VEND_DEV(INTEL, 7500_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
{PCI_VEND_DEV(INTEL, 7505_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, E7500
E7505}, },
{0,} /* 0 terminated list. */ {
PCI_VEND_DEV(INTEL, 7501_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
E7501
},
{
PCI_VEND_DEV(INTEL, 7505_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
E7505
},
{
0,
} /* 0 terminated list. */
}; };
MODULE_DEVICE_TABLE(pci, e7xxx_pci_tbl); MODULE_DEVICE_TABLE(pci, e7xxx_pci_tbl);
static struct pci_driver e7xxx_driver = { static struct pci_driver e7xxx_driver = {
.name = EDAC_MOD_STR, .name = EDAC_MOD_STR,
.probe = e7xxx_init_one, .probe = e7xxx_init_one,
...@@ -541,13 +537,11 @@ static struct pci_driver e7xxx_driver = { ...@@ -541,13 +537,11 @@ static struct pci_driver e7xxx_driver = {
.id_table = e7xxx_pci_tbl, .id_table = e7xxx_pci_tbl,
}; };
static int __init e7xxx_init(void) static int __init e7xxx_init(void)
{ {
return pci_register_driver(&e7xxx_driver); return pci_register_driver(&e7xxx_driver);
} }
static void __exit e7xxx_exit(void) static void __exit e7xxx_exit(void)
{ {
pci_unregister_driver(&e7xxx_driver); pci_unregister_driver(&e7xxx_driver);
...@@ -556,8 +550,7 @@ static void __exit e7xxx_exit(void) ...@@ -556,8 +550,7 @@ static void __exit e7xxx_exit(void)
module_init(e7xxx_init); module_init(e7xxx_init);
module_exit(e7xxx_exit); module_exit(e7xxx_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh et al\n" MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh et al\n"
"Based on.work by Dan Hollis et al"); "Based on.work by Dan Hollis et al");
MODULE_DESCRIPTION("MC support for Intel e7xxx memory controllers"); MODULE_DESCRIPTION("MC support for Intel e7xxx memory controllers");
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
* *
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
...@@ -30,14 +29,12 @@ ...@@ -30,14 +29,12 @@
#include <linux/sysdev.h> #include <linux/sysdev.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/edac.h> #include <asm/edac.h>
#include "edac_mc.h" #include "edac_mc.h"
#define EDAC_MC_VERSION "Ver: 2.0.0 " __DATE__ #define EDAC_MC_VERSION "Ver: 2.0.0 " __DATE__
/* For now, disable the EDAC sysfs code. The sysfs interface that EDAC /* For now, disable the EDAC sysfs code. The sysfs interface that EDAC
* presents to user space needs more thought, and is likely to change * presents to user space needs more thought, and is likely to change
...@@ -73,7 +70,6 @@ struct edac_pci_device_list { ...@@ -73,7 +70,6 @@ struct edac_pci_device_list {
unsigned int device; /* Deviice ID */ unsigned int device; /* Deviice ID */
}; };
#define MAX_LISTED_PCI_DEVICES 32 #define MAX_LISTED_PCI_DEVICES 32
/* List of PCI devices (vendor-id:device-id) that should be skipped */ /* List of PCI devices (vendor-id:device-id) that should be skipped */
...@@ -126,7 +122,6 @@ static const char *edac_caps[] = { ...@@ -126,7 +122,6 @@ static const char *edac_caps[] = {
[EDAC_S16ECD16ED] = "S16ECD16ED" [EDAC_S16ECD16ED] = "S16ECD16ED"
}; };
/* sysfs object: /sys/devices/system/edac */ /* sysfs object: /sys/devices/system/edac */
static struct sysdev_class edac_class = { static struct sysdev_class edac_class = {
set_kset_name("edac"), set_kset_name("edac"),
...@@ -147,7 +142,7 @@ static struct completion edac_pci_kobj_complete; ...@@ -147,7 +142,7 @@ static struct completion edac_pci_kobj_complete;
/* /*
* /sys/devices/system/edac/mc; * /sys/devices/system/edac/mc;
* data structures and methods * data structures and methods
*/ */
#if 0 #if 0
static ssize_t memctrl_string_show(void *ptr, char *buffer) static ssize_t memctrl_string_show(void *ptr, char *buffer)
...@@ -174,33 +169,34 @@ static ssize_t memctrl_int_store(void *ptr, const char *buffer, size_t count) ...@@ -174,33 +169,34 @@ static ssize_t memctrl_int_store(void *ptr, const char *buffer, size_t count)
} }
struct memctrl_dev_attribute { struct memctrl_dev_attribute {
struct attribute attr; struct attribute attr;
void *value; void *value;
ssize_t (*show)(void *,char *); ssize_t (*show)(void *,char *);
ssize_t (*store)(void *, const char *, size_t); ssize_t (*store)(void *, const char *, size_t);
}; };
/* Set of show/store abstract level functions for memory control object */ /* Set of show/store abstract level functions for memory control object */
static ssize_t static ssize_t memctrl_dev_show(struct kobject *kobj,
memctrl_dev_show(struct kobject *kobj, struct attribute *attr, char *buffer) struct attribute *attr, char *buffer)
{ {
struct memctrl_dev_attribute *memctrl_dev; struct memctrl_dev_attribute *memctrl_dev;
memctrl_dev = (struct memctrl_dev_attribute*)attr; memctrl_dev = (struct memctrl_dev_attribute*)attr;
if (memctrl_dev->show) if (memctrl_dev->show)
return memctrl_dev->show(memctrl_dev->value, buffer); return memctrl_dev->show(memctrl_dev->value, buffer);
return -EIO; return -EIO;
} }
static ssize_t static ssize_t memctrl_dev_store(struct kobject *kobj, struct attribute *attr,
memctrl_dev_store(struct kobject *kobj, struct attribute *attr, const char *buffer, size_t count)
const char *buffer, size_t count)
{ {
struct memctrl_dev_attribute *memctrl_dev; struct memctrl_dev_attribute *memctrl_dev;
memctrl_dev = (struct memctrl_dev_attribute*)attr; memctrl_dev = (struct memctrl_dev_attribute*)attr;
if (memctrl_dev->store) if (memctrl_dev->store)
return memctrl_dev->store(memctrl_dev->value, buffer, count); return memctrl_dev->store(memctrl_dev->value, buffer, count);
return -EIO; return -EIO;
} }
...@@ -236,7 +232,6 @@ MEMCTRL_ATTR(log_ue,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store); ...@@ -236,7 +232,6 @@ MEMCTRL_ATTR(log_ue,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
MEMCTRL_ATTR(log_ce,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store); MEMCTRL_ATTR(log_ce,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
MEMCTRL_ATTR(poll_msec,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store); MEMCTRL_ATTR(poll_msec,S_IRUGO|S_IWUSR,memctrl_int_show,memctrl_int_store);
/* Base Attributes of the memory ECC object */ /* Base Attributes of the memory ECC object */
static struct memctrl_dev_attribute *memctrl_attr[] = { static struct memctrl_dev_attribute *memctrl_attr[] = {
&attr_panic_on_ue, &attr_panic_on_ue,
...@@ -254,9 +249,9 @@ static void edac_memctrl_master_release(struct kobject *kobj) ...@@ -254,9 +249,9 @@ static void edac_memctrl_master_release(struct kobject *kobj)
} }
static struct kobj_type ktype_memctrl = { static struct kobj_type ktype_memctrl = {
.release = edac_memctrl_master_release, .release = edac_memctrl_master_release,
.sysfs_ops = &memctrlfs_ops, .sysfs_ops = &memctrlfs_ops,
.default_attrs = (struct attribute **) memctrl_attr, .default_attrs = (struct attribute **) memctrl_attr,
}; };
#endif /* DISABLE_EDAC_SYSFS */ #endif /* DISABLE_EDAC_SYSFS */
...@@ -282,6 +277,7 @@ static int edac_sysfs_memctrl_setup(void) ...@@ -282,6 +277,7 @@ static int edac_sysfs_memctrl_setup(void)
/* create the /sys/devices/system/edac directory */ /* create the /sys/devices/system/edac directory */
err = sysdev_class_register(&edac_class); err = sysdev_class_register(&edac_class);
if (!err) { if (!err) {
/* Init the MC's kobject */ /* Init the MC's kobject */
memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj)); memset(&edac_memctrl_kobj, 0, sizeof (edac_memctrl_kobj));
...@@ -290,18 +286,18 @@ static int edac_sysfs_memctrl_setup(void) ...@@ -290,18 +286,18 @@ static int edac_sysfs_memctrl_setup(void)
/* generate sysfs "..../edac/mc" */ /* generate sysfs "..../edac/mc" */
err = kobject_set_name(&edac_memctrl_kobj,"mc"); err = kobject_set_name(&edac_memctrl_kobj,"mc");
if (!err) { if (!err) {
/* FIXME: maybe new sysdev_create_subdir() */ /* FIXME: maybe new sysdev_create_subdir() */
err = kobject_register(&edac_memctrl_kobj); err = kobject_register(&edac_memctrl_kobj);
if (err) {
if (err)
debugf1("Failed to register '.../edac/mc'\n"); debugf1("Failed to register '.../edac/mc'\n");
} else { else
debugf1("Registered '.../edac/mc' kobject\n"); debugf1("Registered '.../edac/mc' kobject\n");
}
} }
} else { } else
debugf1("%s() error=%d\n", __func__, err); debugf1("%s() error=%d\n", __func__, err);
}
return err; return err;
} }
...@@ -340,7 +336,6 @@ struct list_control { ...@@ -340,7 +336,6 @@ struct list_control {
int *count; int *count;
}; };
#if 0 #if 0
/* Output the list as: vendor_id:device:id<,vendor_id:device_id> */ /* Output the list as: vendor_id:device:id<,vendor_id:device_id> */
static ssize_t edac_pci_list_string_show(void *ptr, char *buffer) static ssize_t edac_pci_list_string_show(void *ptr, char *buffer)
...@@ -365,7 +360,6 @@ static ssize_t edac_pci_list_string_show(void *ptr, char *buffer) ...@@ -365,7 +360,6 @@ static ssize_t edac_pci_list_string_show(void *ptr, char *buffer)
} }
len += snprintf(p + len,(PAGE_SIZE-len), "\n"); len += snprintf(p + len,(PAGE_SIZE-len), "\n");
return (ssize_t) len; return (ssize_t) len;
} }
...@@ -387,7 +381,7 @@ static int parse_one_device(const char **s,const char **e, ...@@ -387,7 +381,7 @@ static int parse_one_device(const char **s,const char **e,
/* if null byte, we are done */ /* if null byte, we are done */
if (!**s) { if (!**s) {
(*s)++; /* keep *s moving */ (*s)++; /* keep *s moving */
return 0; return 0;
} }
...@@ -404,6 +398,7 @@ static int parse_one_device(const char **s,const char **e, ...@@ -404,6 +398,7 @@ static int parse_one_device(const char **s,const char **e,
/* parse vendor_id */ /* parse vendor_id */
runner = *s; runner = *s;
while (runner < *e) { while (runner < *e) {
/* scan for vendor:device delimiter */ /* scan for vendor:device delimiter */
if (*runner == ':') { if (*runner == ':') {
...@@ -411,6 +406,7 @@ static int parse_one_device(const char **s,const char **e, ...@@ -411,6 +406,7 @@ static int parse_one_device(const char **s,const char **e,
runner = p + 1; runner = p + 1;
break; break;
} }
runner++; runner++;
} }
...@@ -426,12 +422,11 @@ static int parse_one_device(const char **s,const char **e, ...@@ -426,12 +422,11 @@ static int parse_one_device(const char **s,const char **e,
} }
*s = runner; *s = runner;
return 1; return 1;
} }
static ssize_t edac_pci_list_string_store(void *ptr, const char *buffer, static ssize_t edac_pci_list_string_store(void *ptr, const char *buffer,
size_t count) size_t count)
{ {
struct list_control *listctl; struct list_control *listctl;
struct edac_pci_device_list *list; struct edac_pci_device_list *list;
...@@ -441,14 +436,12 @@ static ssize_t edac_pci_list_string_store(void *ptr, const char *buffer, ...@@ -441,14 +436,12 @@ static ssize_t edac_pci_list_string_store(void *ptr, const char *buffer,
s = (char*)buffer; s = (char*)buffer;
e = s + count; e = s + count;
listctl = ptr; listctl = ptr;
list = listctl->list; list = listctl->list;
index = listctl->count; index = listctl->count;
*index = 0; *index = 0;
while (*index < MAX_LISTED_PCI_DEVICES) {
while (*index < MAX_LISTED_PCI_DEVICES) {
if (parse_one_device(&s,&e,&vendor_id,&device_id)) { if (parse_one_device(&s,&e,&vendor_id,&device_id)) {
list[ *index ].vendor = vendor_id; list[ *index ].vendor = vendor_id;
list[ *index ].device = device_id; list[ *index ].device = device_id;
...@@ -481,15 +474,15 @@ static ssize_t edac_pci_int_store(void *ptr, const char *buffer, size_t count) ...@@ -481,15 +474,15 @@ static ssize_t edac_pci_int_store(void *ptr, const char *buffer, size_t count)
} }
struct edac_pci_dev_attribute { struct edac_pci_dev_attribute {
struct attribute attr; struct attribute attr;
void *value; void *value;
ssize_t (*show)(void *,char *); ssize_t (*show)(void *,char *);
ssize_t (*store)(void *, const char *,size_t); ssize_t (*store)(void *, const char *,size_t);
}; };
/* Set of show/store abstract level functions for PCI Parity object */ /* Set of show/store abstract level functions for PCI Parity object */
static ssize_t edac_pci_dev_show(struct kobject *kobj, struct attribute *attr, static ssize_t edac_pci_dev_show(struct kobject *kobj, struct attribute *attr,
char *buffer) char *buffer)
{ {
struct edac_pci_dev_attribute *edac_pci_dev; struct edac_pci_dev_attribute *edac_pci_dev;
edac_pci_dev= (struct edac_pci_dev_attribute*)attr; edac_pci_dev= (struct edac_pci_dev_attribute*)attr;
...@@ -499,8 +492,8 @@ static ssize_t edac_pci_dev_show(struct kobject *kobj, struct attribute *attr, ...@@ -499,8 +492,8 @@ static ssize_t edac_pci_dev_show(struct kobject *kobj, struct attribute *attr,
return -EIO; return -EIO;
} }
static ssize_t edac_pci_dev_store(struct kobject *kobj, struct attribute *attr, static ssize_t edac_pci_dev_store(struct kobject *kobj,
const char *buffer, size_t count) struct attribute *attr, const char *buffer, size_t count)
{ {
struct edac_pci_dev_attribute *edac_pci_dev; struct edac_pci_dev_attribute *edac_pci_dev;
edac_pci_dev= (struct edac_pci_dev_attribute*)attr; edac_pci_dev= (struct edac_pci_dev_attribute*)attr;
...@@ -515,7 +508,6 @@ static struct sysfs_ops edac_pci_sysfs_ops = { ...@@ -515,7 +508,6 @@ static struct sysfs_ops edac_pci_sysfs_ops = {
.store = edac_pci_dev_store .store = edac_pci_dev_store
}; };
#define EDAC_PCI_ATTR(_name,_mode,_show,_store) \ #define EDAC_PCI_ATTR(_name,_mode,_show,_store) \
struct edac_pci_dev_attribute edac_pci_attr_##_name = { \ struct edac_pci_dev_attribute edac_pci_attr_##_name = { \
.attr = {.name = __stringify(_name), .mode = _mode }, \ .attr = {.name = __stringify(_name), .mode = _mode }, \
...@@ -558,9 +550,11 @@ EDAC_PCI_STRING_ATTR(pci_parity_blacklist, ...@@ -558,9 +550,11 @@ EDAC_PCI_STRING_ATTR(pci_parity_blacklist,
#endif #endif
/* PCI Parity control files */ /* PCI Parity control files */
EDAC_PCI_ATTR(check_pci_parity,S_IRUGO|S_IWUSR,edac_pci_int_show,edac_pci_int_store); EDAC_PCI_ATTR(check_pci_parity, S_IRUGO|S_IWUSR, edac_pci_int_show,
EDAC_PCI_ATTR(panic_on_pci_parity,S_IRUGO|S_IWUSR,edac_pci_int_show,edac_pci_int_store); edac_pci_int_store);
EDAC_PCI_ATTR(pci_parity_count,S_IRUGO,edac_pci_int_show,NULL); EDAC_PCI_ATTR(panic_on_pci_parity, S_IRUGO|S_IWUSR, edac_pci_int_show,
edac_pci_int_store);
EDAC_PCI_ATTR(pci_parity_count, S_IRUGO, edac_pci_int_show, NULL);
/* Base Attributes of the memory ECC object */ /* Base Attributes of the memory ECC object */
static struct edac_pci_dev_attribute *edac_pci_attr[] = { static struct edac_pci_dev_attribute *edac_pci_attr[] = {
...@@ -578,9 +572,9 @@ static void edac_pci_release(struct kobject *kobj) ...@@ -578,9 +572,9 @@ static void edac_pci_release(struct kobject *kobj)
} }
static struct kobj_type ktype_edac_pci = { static struct kobj_type ktype_edac_pci = {
.release = edac_pci_release, .release = edac_pci_release,
.sysfs_ops = &edac_pci_sysfs_ops, .sysfs_ops = &edac_pci_sysfs_ops,
.default_attrs = (struct attribute **) edac_pci_attr, .default_attrs = (struct attribute **) edac_pci_attr,
}; };
#endif /* DISABLE_EDAC_SYSFS */ #endif /* DISABLE_EDAC_SYSFS */
...@@ -603,17 +597,19 @@ static int edac_sysfs_pci_setup(void) ...@@ -603,17 +597,19 @@ static int edac_sysfs_pci_setup(void)
memset(&edac_pci_kobj, 0, sizeof(edac_pci_kobj)); memset(&edac_pci_kobj, 0, sizeof(edac_pci_kobj));
edac_pci_kobj.parent = &edac_class.kset.kobj; edac_pci_kobj.parent = &edac_class.kset.kobj;
edac_pci_kobj.ktype = &ktype_edac_pci; edac_pci_kobj.ktype = &ktype_edac_pci;
err = kobject_set_name(&edac_pci_kobj, "pci"); err = kobject_set_name(&edac_pci_kobj, "pci");
if (!err) { if (!err) {
/* Instanstiate the csrow object */ /* Instanstiate the csrow object */
/* FIXME: maybe new sysdev_create_subdir() */ /* FIXME: maybe new sysdev_create_subdir() */
err = kobject_register(&edac_pci_kobj); err = kobject_register(&edac_pci_kobj);
if (err) if (err)
debugf1("Failed to register '.../edac/pci'\n"); debugf1("Failed to register '.../edac/pci'\n");
else else
debugf1("Registered '.../edac/pci' kobject\n"); debugf1("Registered '.../edac/pci' kobject\n");
} }
return err; return err;
} }
#endif /* DISABLE_EDAC_SYSFS */ #endif /* DISABLE_EDAC_SYSFS */
...@@ -641,6 +637,7 @@ static ssize_t csrow_ch0_dimm_label_show(struct csrow_info *csrow, char *data) ...@@ -641,6 +637,7 @@ static ssize_t csrow_ch0_dimm_label_show(struct csrow_info *csrow, char *data)
size = snprintf(data, EDAC_MC_LABEL_LEN,"%s\n", size = snprintf(data, EDAC_MC_LABEL_LEN,"%s\n",
csrow->channels[0].label); csrow->channels[0].label);
} }
return size; return size;
} }
...@@ -652,11 +649,12 @@ static ssize_t csrow_ch1_dimm_label_show(struct csrow_info *csrow, char *data) ...@@ -652,11 +649,12 @@ static ssize_t csrow_ch1_dimm_label_show(struct csrow_info *csrow, char *data)
size = snprintf(data, EDAC_MC_LABEL_LEN, "%s\n", size = snprintf(data, EDAC_MC_LABEL_LEN, "%s\n",
csrow->channels[1].label); csrow->channels[1].label);
} }
return size; return size;
} }
static ssize_t csrow_ch0_dimm_label_store(struct csrow_info *csrow, static ssize_t csrow_ch0_dimm_label_store(struct csrow_info *csrow,
const char *data, size_t size) const char *data, size_t size)
{ {
ssize_t max_size = 0; ssize_t max_size = 0;
...@@ -665,11 +663,12 @@ static ssize_t csrow_ch0_dimm_label_store(struct csrow_info *csrow, ...@@ -665,11 +663,12 @@ static ssize_t csrow_ch0_dimm_label_store(struct csrow_info *csrow,
strncpy(csrow->channels[0].label, data, max_size); strncpy(csrow->channels[0].label, data, max_size);
csrow->channels[0].label[max_size] = '\0'; csrow->channels[0].label[max_size] = '\0';
} }
return size; return size;
} }
static ssize_t csrow_ch1_dimm_label_store(struct csrow_info *csrow, static ssize_t csrow_ch1_dimm_label_store(struct csrow_info *csrow,
const char *data, size_t size) const char *data, size_t size)
{ {
ssize_t max_size = 0; ssize_t max_size = 0;
...@@ -678,6 +677,7 @@ static ssize_t csrow_ch1_dimm_label_store(struct csrow_info *csrow, ...@@ -678,6 +677,7 @@ static ssize_t csrow_ch1_dimm_label_store(struct csrow_info *csrow,
strncpy(csrow->channels[1].label, data, max_size); strncpy(csrow->channels[1].label, data, max_size);
csrow->channels[1].label[max_size] = '\0'; csrow->channels[1].label[max_size] = '\0';
} }
return max_size; return max_size;
} }
...@@ -698,6 +698,7 @@ static ssize_t csrow_ch0_ce_count_show(struct csrow_info *csrow, char *data) ...@@ -698,6 +698,7 @@ static ssize_t csrow_ch0_ce_count_show(struct csrow_info *csrow, char *data)
if (csrow->nr_channels > 0) { if (csrow->nr_channels > 0) {
size = sprintf(data,"%u\n", csrow->channels[0].ce_count); size = sprintf(data,"%u\n", csrow->channels[0].ce_count);
} }
return size; return size;
} }
...@@ -708,6 +709,7 @@ static ssize_t csrow_ch1_ce_count_show(struct csrow_info *csrow, char *data) ...@@ -708,6 +709,7 @@ static ssize_t csrow_ch1_ce_count_show(struct csrow_info *csrow, char *data)
if (csrow->nr_channels > 1) { if (csrow->nr_channels > 1) {
size = sprintf(data,"%u\n", csrow->channels[1].ce_count); size = sprintf(data,"%u\n", csrow->channels[1].ce_count);
} }
return size; return size;
} }
...@@ -732,7 +734,7 @@ static ssize_t csrow_edac_mode_show(struct csrow_info *csrow, char *data) ...@@ -732,7 +734,7 @@ static ssize_t csrow_edac_mode_show(struct csrow_info *csrow, char *data)
} }
struct csrowdev_attribute { struct csrowdev_attribute {
struct attribute attr; struct attribute attr;
ssize_t (*show)(struct csrow_info *,char *); ssize_t (*show)(struct csrow_info *,char *);
ssize_t (*store)(struct csrow_info *, const char *,size_t); ssize_t (*store)(struct csrow_info *, const char *,size_t);
}; };
...@@ -742,24 +744,26 @@ struct csrowdev_attribute { ...@@ -742,24 +744,26 @@ struct csrowdev_attribute {
/* Set of show/store higher level functions for csrow objects */ /* Set of show/store higher level functions for csrow objects */
static ssize_t csrowdev_show(struct kobject *kobj, struct attribute *attr, static ssize_t csrowdev_show(struct kobject *kobj, struct attribute *attr,
char *buffer) char *buffer)
{ {
struct csrow_info *csrow = to_csrow(kobj); struct csrow_info *csrow = to_csrow(kobj);
struct csrowdev_attribute *csrowdev_attr = to_csrowdev_attr(attr); struct csrowdev_attribute *csrowdev_attr = to_csrowdev_attr(attr);
if (csrowdev_attr->show) if (csrowdev_attr->show)
return csrowdev_attr->show(csrow, buffer); return csrowdev_attr->show(csrow, buffer);
return -EIO; return -EIO;
} }
static ssize_t csrowdev_store(struct kobject *kobj, struct attribute *attr, static ssize_t csrowdev_store(struct kobject *kobj, struct attribute *attr,
const char *buffer, size_t count) const char *buffer, size_t count)
{ {
struct csrow_info *csrow = to_csrow(kobj); struct csrow_info *csrow = to_csrow(kobj);
struct csrowdev_attribute * csrowdev_attr = to_csrowdev_attr(attr); struct csrowdev_attribute * csrowdev_attr = to_csrowdev_attr(attr);
if (csrowdev_attr->store) if (csrowdev_attr->store)
return csrowdev_attr->store(csrow, buffer, count); return csrowdev_attr->store(csrow, buffer, count);
return -EIO; return -EIO;
} }
...@@ -793,7 +797,6 @@ CSROWDEV_ATTR(ch1_dimm_label,S_IRUGO|S_IWUSR, ...@@ -793,7 +797,6 @@ CSROWDEV_ATTR(ch1_dimm_label,S_IRUGO|S_IWUSR,
csrow_ch1_dimm_label_show, csrow_ch1_dimm_label_show,
csrow_ch1_dimm_label_store); csrow_ch1_dimm_label_store);
/* Attributes of the CSROW<id> object */ /* Attributes of the CSROW<id> object */
static struct csrowdev_attribute *csrow_attr[] = { static struct csrowdev_attribute *csrow_attr[] = {
&attr_dev_type, &attr_dev_type,
...@@ -809,7 +812,6 @@ static struct csrowdev_attribute *csrow_attr[] = { ...@@ -809,7 +812,6 @@ static struct csrowdev_attribute *csrow_attr[] = {
NULL, NULL,
}; };
/* No memory to release */ /* No memory to release */
static void edac_csrow_instance_release(struct kobject *kobj) static void edac_csrow_instance_release(struct kobject *kobj)
{ {
...@@ -821,19 +823,18 @@ static void edac_csrow_instance_release(struct kobject *kobj) ...@@ -821,19 +823,18 @@ static void edac_csrow_instance_release(struct kobject *kobj)
} }
static struct kobj_type ktype_csrow = { static struct kobj_type ktype_csrow = {
.release = edac_csrow_instance_release, .release = edac_csrow_instance_release,
.sysfs_ops = &csrowfs_ops, .sysfs_ops = &csrowfs_ops,
.default_attrs = (struct attribute **) csrow_attr, .default_attrs = (struct attribute **) csrow_attr,
}; };
/* Create a CSROW object under specifed edac_mc_device */ /* Create a CSROW object under specifed edac_mc_device */
static int edac_create_csrow_object(struct kobject *edac_mci_kobj, static int edac_create_csrow_object(struct kobject *edac_mci_kobj,
struct csrow_info *csrow, int index ) struct csrow_info *csrow, int index)
{ {
int err = 0; int err = 0;
debugf0("%s()\n", __func__); debugf0("%s()\n", __func__);
memset(&csrow->kobj, 0, sizeof(csrow->kobj)); memset(&csrow->kobj, 0, sizeof(csrow->kobj));
/* generate ..../edac/mc/mc<id>/csrow<index> */ /* generate ..../edac/mc/mc<id>/csrow<index> */
...@@ -843,9 +844,11 @@ static int edac_create_csrow_object(struct kobject *edac_mci_kobj, ...@@ -843,9 +844,11 @@ static int edac_create_csrow_object(struct kobject *edac_mci_kobj,
/* name this instance of csrow<id> */ /* name this instance of csrow<id> */
err = kobject_set_name(&csrow->kobj,"csrow%d",index); err = kobject_set_name(&csrow->kobj,"csrow%d",index);
if (!err) { if (!err) {
/* Instanstiate the csrow object */ /* Instanstiate the csrow object */
err = kobject_register(&csrow->kobj); err = kobject_register(&csrow->kobj);
if (err) if (err)
debugf0("Failed to register CSROW%d\n",index); debugf0("Failed to register CSROW%d\n",index);
else else
...@@ -857,8 +860,8 @@ static int edac_create_csrow_object(struct kobject *edac_mci_kobj, ...@@ -857,8 +860,8 @@ static int edac_create_csrow_object(struct kobject *edac_mci_kobj,
/* sysfs data structures and methods for the MCI kobjects */ /* sysfs data structures and methods for the MCI kobjects */
static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci, static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci,
const char *data, size_t count ) const char *data, size_t count)
{ {
int row, chan; int row, chan;
...@@ -866,16 +869,18 @@ static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci, ...@@ -866,16 +869,18 @@ static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci,
mci->ce_noinfo_count = 0; mci->ce_noinfo_count = 0;
mci->ue_count = 0; mci->ue_count = 0;
mci->ce_count = 0; mci->ce_count = 0;
for (row = 0; row < mci->nr_csrows; row++) { for (row = 0; row < mci->nr_csrows; row++) {
struct csrow_info *ri = &mci->csrows[row]; struct csrow_info *ri = &mci->csrows[row];
ri->ue_count = 0; ri->ue_count = 0;
ri->ce_count = 0; ri->ce_count = 0;
for (chan = 0; chan < ri->nr_channels; chan++) for (chan = 0; chan < ri->nr_channels; chan++)
ri->channels[chan].ce_count = 0; ri->channels[chan].ce_count = 0;
} }
mci->start_time = jiffies;
mci->start_time = jiffies;
return count; return count;
} }
...@@ -933,18 +938,16 @@ static ssize_t mci_edac_capability_show(struct mem_ctl_info *mci, char *data) ...@@ -933,18 +938,16 @@ static ssize_t mci_edac_capability_show(struct mem_ctl_info *mci, char *data)
p += mci_output_edac_cap(p,mci->edac_ctl_cap); p += mci_output_edac_cap(p,mci->edac_ctl_cap);
p += sprintf(p, "\n"); p += sprintf(p, "\n");
return p - data; return p - data;
} }
static ssize_t mci_edac_current_capability_show(struct mem_ctl_info *mci, static ssize_t mci_edac_current_capability_show(struct mem_ctl_info *mci,
char *data) char *data)
{ {
char *p = data; char *p = data;
p += mci_output_edac_cap(p,mci->edac_cap); p += mci_output_edac_cap(p,mci->edac_cap);
p += sprintf(p, "\n"); p += sprintf(p, "\n");
return p - data; return p - data;
} }
...@@ -961,13 +964,13 @@ static int mci_output_mtype_cap(char *buf, unsigned long mtype_cap) ...@@ -961,13 +964,13 @@ static int mci_output_mtype_cap(char *buf, unsigned long mtype_cap)
return p - buf; return p - buf;
} }
static ssize_t mci_supported_mem_type_show(struct mem_ctl_info *mci, char *data) static ssize_t mci_supported_mem_type_show(struct mem_ctl_info *mci,
char *data)
{ {
char *p = data; char *p = data;
p += mci_output_mtype_cap(p,mci->mtype_cap); p += mci_output_mtype_cap(p,mci->mtype_cap);
p += sprintf(p, "\n"); p += sprintf(p, "\n");
return p - data; return p - data;
} }
...@@ -981,6 +984,7 @@ static ssize_t mci_size_mb_show(struct mem_ctl_info *mci, char *data) ...@@ -981,6 +984,7 @@ static ssize_t mci_size_mb_show(struct mem_ctl_info *mci, char *data)
if (!csrow->nr_pages) if (!csrow->nr_pages)
continue; continue;
total_pages += csrow->nr_pages; total_pages += csrow->nr_pages;
} }
...@@ -988,7 +992,7 @@ static ssize_t mci_size_mb_show(struct mem_ctl_info *mci, char *data) ...@@ -988,7 +992,7 @@ static ssize_t mci_size_mb_show(struct mem_ctl_info *mci, char *data)
} }
struct mcidev_attribute { struct mcidev_attribute {
struct attribute attr; struct attribute attr;
ssize_t (*show)(struct mem_ctl_info *,char *); ssize_t (*show)(struct mem_ctl_info *,char *);
ssize_t (*store)(struct mem_ctl_info *, const char *,size_t); ssize_t (*store)(struct mem_ctl_info *, const char *,size_t);
}; };
...@@ -997,30 +1001,32 @@ struct mcidev_attribute { ...@@ -997,30 +1001,32 @@ struct mcidev_attribute {
#define to_mcidev_attr(a) container_of(a, struct mcidev_attribute, attr) #define to_mcidev_attr(a) container_of(a, struct mcidev_attribute, attr)
static ssize_t mcidev_show(struct kobject *kobj, struct attribute *attr, static ssize_t mcidev_show(struct kobject *kobj, struct attribute *attr,
char *buffer) char *buffer)
{ {
struct mem_ctl_info *mem_ctl_info = to_mci(kobj); struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr); struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr);
if (mcidev_attr->show) if (mcidev_attr->show)
return mcidev_attr->show(mem_ctl_info, buffer); return mcidev_attr->show(mem_ctl_info, buffer);
return -EIO; return -EIO;
} }
static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr, static ssize_t mcidev_store(struct kobject *kobj, struct attribute *attr,
const char *buffer, size_t count) const char *buffer, size_t count)
{ {
struct mem_ctl_info *mem_ctl_info = to_mci(kobj); struct mem_ctl_info *mem_ctl_info = to_mci(kobj);
struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr); struct mcidev_attribute * mcidev_attr = to_mcidev_attr(attr);
if (mcidev_attr->store) if (mcidev_attr->store)
return mcidev_attr->store(mem_ctl_info, buffer, count); return mcidev_attr->store(mem_ctl_info, buffer, count);
return -EIO; return -EIO;
} }
static struct sysfs_ops mci_ops = { static struct sysfs_ops mci_ops = {
.show = mcidev_show, .show = mcidev_show,
.store = mcidev_store .store = mcidev_store
}; };
#define MCIDEV_ATTR(_name,_mode,_show,_store) \ #define MCIDEV_ATTR(_name,_mode,_show,_store) \
...@@ -1048,7 +1054,6 @@ MCIDEV_ATTR(edac_current_capability,S_IRUGO, ...@@ -1048,7 +1054,6 @@ MCIDEV_ATTR(edac_current_capability,S_IRUGO,
MCIDEV_ATTR(supported_mem_type,S_IRUGO, MCIDEV_ATTR(supported_mem_type,S_IRUGO,
mci_supported_mem_type_show,NULL); mci_supported_mem_type_show,NULL);
static struct mcidev_attribute *mci_attr[] = { static struct mcidev_attribute *mci_attr[] = {
&mci_attr_reset_counters, &mci_attr_reset_counters,
&mci_attr_module_name, &mci_attr_module_name,
...@@ -1065,7 +1070,6 @@ static struct mcidev_attribute *mci_attr[] = { ...@@ -1065,7 +1070,6 @@ static struct mcidev_attribute *mci_attr[] = {
NULL NULL
}; };
/* /*
* Release of a MC controlling instance * Release of a MC controlling instance
*/ */
...@@ -1079,9 +1083,9 @@ static void edac_mci_instance_release(struct kobject *kobj) ...@@ -1079,9 +1083,9 @@ static void edac_mci_instance_release(struct kobject *kobj)
} }
static struct kobj_type ktype_mci = { static struct kobj_type ktype_mci = {
.release = edac_mci_instance_release, .release = edac_mci_instance_release,
.sysfs_ops = &mci_ops, .sysfs_ops = &mci_ops,
.default_attrs = (struct attribute **) mci_attr, .default_attrs = (struct attribute **) mci_attr,
}; };
#endif /* DISABLE_EDAC_SYSFS */ #endif /* DISABLE_EDAC_SYSFS */
...@@ -1109,11 +1113,11 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) ...@@ -1109,11 +1113,11 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
struct kobject *edac_mci_kobj=&mci->edac_mci_kobj; struct kobject *edac_mci_kobj=&mci->edac_mci_kobj;
debugf0("%s() idx=%d\n", __func__, mci->mc_idx); debugf0("%s() idx=%d\n", __func__, mci->mc_idx);
memset(edac_mci_kobj, 0, sizeof(*edac_mci_kobj)); memset(edac_mci_kobj, 0, sizeof(*edac_mci_kobj));
/* set the name of the mc<id> object */ /* set the name of the mc<id> object */
err = kobject_set_name(edac_mci_kobj,"mc%d",mci->mc_idx); err = kobject_set_name(edac_mci_kobj,"mc%d",mci->mc_idx);
if (err) if (err)
return err; return err;
...@@ -1123,12 +1127,14 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) ...@@ -1123,12 +1127,14 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
/* register the mc<id> kobject */ /* register the mc<id> kobject */
err = kobject_register(edac_mci_kobj); err = kobject_register(edac_mci_kobj);
if (err) if (err)
return err; return err;
/* create a symlink for the device */ /* create a symlink for the device */
err = sysfs_create_link(edac_mci_kobj, &mci->pdev->dev.kobj, err = sysfs_create_link(edac_mci_kobj, &mci->pdev->dev.kobj,
EDAC_DEVICE_SYMLINK); EDAC_DEVICE_SYMLINK);
if (err) if (err)
goto fail0; goto fail0;
...@@ -1136,12 +1142,12 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) ...@@ -1136,12 +1142,12 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
* under the mc<id> kobject * under the mc<id> kobject
*/ */
for (i = 0; i < mci->nr_csrows; i++) { for (i = 0; i < mci->nr_csrows; i++) {
csrow = &mci->csrows[i]; csrow = &mci->csrows[i];
/* Only expose populated CSROWs */ /* Only expose populated CSROWs */
if (csrow->nr_pages > 0) { if (csrow->nr_pages > 0) {
err = edac_create_csrow_object(edac_mci_kobj,csrow,i); err = edac_create_csrow_object(edac_mci_kobj,csrow,i);
if (err) if (err)
goto fail1; goto fail1;
} }
...@@ -1149,7 +1155,6 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) ...@@ -1149,7 +1155,6 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
return 0; return 0;
/* CSROW error: backout what has already been registered, */ /* CSROW error: backout what has already been registered, */
fail1: fail1:
for ( i--; i >= 0; i--) { for ( i--; i >= 0; i--) {
...@@ -1164,7 +1169,6 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) ...@@ -1164,7 +1169,6 @@ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci)
init_completion(&mci->kobj_complete); init_completion(&mci->kobj_complete);
kobject_unregister(edac_mci_kobj); kobject_unregister(edac_mci_kobj);
wait_for_completion(&mci->kobj_complete); wait_for_completion(&mci->kobj_complete);
return err; return err;
} }
#endif /* DISABLE_EDAC_SYSFS */ #endif /* DISABLE_EDAC_SYSFS */
...@@ -1199,7 +1203,6 @@ static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) ...@@ -1199,7 +1203,6 @@ static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
#ifdef CONFIG_EDAC_DEBUG #ifdef CONFIG_EDAC_DEBUG
void edac_mc_dump_channel(struct channel_info *chan) void edac_mc_dump_channel(struct channel_info *chan)
{ {
debugf4("\tchannel = %p\n", chan); debugf4("\tchannel = %p\n", chan);
...@@ -1210,7 +1213,6 @@ void edac_mc_dump_channel(struct channel_info *chan) ...@@ -1210,7 +1213,6 @@ void edac_mc_dump_channel(struct channel_info *chan)
} }
EXPORT_SYMBOL(edac_mc_dump_channel); EXPORT_SYMBOL(edac_mc_dump_channel);
void edac_mc_dump_csrow(struct csrow_info *csrow) void edac_mc_dump_csrow(struct csrow_info *csrow)
{ {
debugf4("\tcsrow = %p\n", csrow); debugf4("\tcsrow = %p\n", csrow);
...@@ -1227,7 +1229,6 @@ void edac_mc_dump_csrow(struct csrow_info *csrow) ...@@ -1227,7 +1229,6 @@ void edac_mc_dump_csrow(struct csrow_info *csrow)
} }
EXPORT_SYMBOL(edac_mc_dump_csrow); EXPORT_SYMBOL(edac_mc_dump_csrow);
void edac_mc_dump_mci(struct mem_ctl_info *mci) void edac_mc_dump_mci(struct mem_ctl_info *mci)
{ {
debugf3("\tmci = %p\n", mci); debugf3("\tmci = %p\n", mci);
...@@ -1244,8 +1245,7 @@ void edac_mc_dump_mci(struct mem_ctl_info *mci) ...@@ -1244,8 +1245,7 @@ void edac_mc_dump_mci(struct mem_ctl_info *mci)
} }
EXPORT_SYMBOL(edac_mc_dump_mci); EXPORT_SYMBOL(edac_mc_dump_mci);
#endif /* CONFIG_EDAC_DEBUG */
#endif /* CONFIG_EDAC_DEBUG */
/* 'ptr' points to a possibly unaligned item X such that sizeof(X) is 'size'. /* 'ptr' points to a possibly unaligned item X such that sizeof(X) is 'size'.
* Adjust 'ptr' so that its alignment is at least as stringent as what the * Adjust 'ptr' so that its alignment is at least as stringent as what the
...@@ -1254,7 +1254,7 @@ EXPORT_SYMBOL(edac_mc_dump_mci); ...@@ -1254,7 +1254,7 @@ EXPORT_SYMBOL(edac_mc_dump_mci);
* If 'size' is a constant, the compiler will optimize this whole function * If 'size' is a constant, the compiler will optimize this whole function
* down to either a no-op or the addition of a constant to the value of 'ptr'. * down to either a no-op or the addition of a constant to the value of 'ptr'.
*/ */
static inline char * align_ptr (void *ptr, unsigned size) static inline char * align_ptr(void *ptr, unsigned size)
{ {
unsigned align, r; unsigned align, r;
...@@ -1281,7 +1281,6 @@ static inline char * align_ptr (void *ptr, unsigned size) ...@@ -1281,7 +1281,6 @@ static inline char * align_ptr (void *ptr, unsigned size)
return (char *) (((unsigned long) ptr) + align - r); return (char *) (((unsigned long) ptr) + align - r);
} }
/** /**
* edac_mc_alloc: Allocate a struct mem_ctl_info structure * edac_mc_alloc: Allocate a struct mem_ctl_info structure
* @size_pvt: size of private storage needed * @size_pvt: size of private storage needed
...@@ -1299,7 +1298,7 @@ static inline char * align_ptr (void *ptr, unsigned size) ...@@ -1299,7 +1298,7 @@ static inline char * align_ptr (void *ptr, unsigned size)
* struct mem_ctl_info pointer * struct mem_ctl_info pointer
*/ */
struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
unsigned nr_chans) unsigned nr_chans)
{ {
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
struct csrow_info *csi, *csrow; struct csrow_info *csi, *csrow;
...@@ -1330,8 +1329,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, ...@@ -1330,8 +1329,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
chi = (struct channel_info *) (((char *) mci) + ((unsigned long) chi)); chi = (struct channel_info *) (((char *) mci) + ((unsigned long) chi));
pvt = sz_pvt ? (((char *) mci) + ((unsigned long) pvt)) : NULL; pvt = sz_pvt ? (((char *) mci) + ((unsigned long) pvt)) : NULL;
memset(mci, 0, size); /* clear all fields */ memset(mci, 0, size); /* clear all fields */
mci->csrows = csi; mci->csrows = csi;
mci->pvt_info = pvt; mci->pvt_info = pvt;
mci->nr_csrows = nr_csrows; mci->nr_csrows = nr_csrows;
...@@ -1355,7 +1353,6 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows, ...@@ -1355,7 +1353,6 @@ struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
} }
EXPORT_SYMBOL(edac_mc_alloc); EXPORT_SYMBOL(edac_mc_alloc);
/** /**
* edac_mc_free: Free a previously allocated 'mci' structure * edac_mc_free: Free a previously allocated 'mci' structure
* @mci: pointer to a struct mem_ctl_info structure * @mci: pointer to a struct mem_ctl_info structure
...@@ -1383,7 +1380,7 @@ static struct mem_ctl_info *find_mci_by_pdev(struct pci_dev *pdev) ...@@ -1383,7 +1380,7 @@ static struct mem_ctl_info *find_mci_by_pdev(struct pci_dev *pdev)
return NULL; return NULL;
} }
static int add_mc_to_global_list (struct mem_ctl_info *mci) static int add_mc_to_global_list(struct mem_ctl_info *mci)
{ {
struct list_head *item, *insert_before; struct list_head *item, *insert_before;
struct mem_ctl_info *p; struct mem_ctl_info *p;
...@@ -1426,8 +1423,7 @@ static int add_mc_to_global_list (struct mem_ctl_info *mci) ...@@ -1426,8 +1423,7 @@ static int add_mc_to_global_list (struct mem_ctl_info *mci)
return 0; return 0;
} }
static void complete_mc_list_del(struct rcu_head *head)
static void complete_mc_list_del (struct rcu_head *head)
{ {
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
...@@ -1436,8 +1432,7 @@ static void complete_mc_list_del (struct rcu_head *head) ...@@ -1436,8 +1432,7 @@ static void complete_mc_list_del (struct rcu_head *head)
complete(&mci->complete); complete(&mci->complete);
} }
static void del_mc_from_global_list(struct mem_ctl_info *mci)
static void del_mc_from_global_list (struct mem_ctl_info *mci)
{ {
list_del_rcu(&mci->link); list_del_rcu(&mci->link);
init_completion(&mci->complete); init_completion(&mci->complete);
...@@ -1445,7 +1440,6 @@ static void del_mc_from_global_list (struct mem_ctl_info *mci) ...@@ -1445,7 +1440,6 @@ static void del_mc_from_global_list (struct mem_ctl_info *mci)
wait_for_completion(&mci->complete); wait_for_completion(&mci->complete);
} }
/** /**
* edac_mc_add_mc: Insert the 'mci' structure into the mci global list and * edac_mc_add_mc: Insert the 'mci' structure into the mci global list and
* create sysfs entries associated with mci structure * create sysfs entries associated with mci structure
...@@ -1463,15 +1457,17 @@ int edac_mc_add_mc(struct mem_ctl_info *mci) ...@@ -1463,15 +1457,17 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
#ifdef CONFIG_EDAC_DEBUG #ifdef CONFIG_EDAC_DEBUG
if (edac_debug_level >= 3) if (edac_debug_level >= 3)
edac_mc_dump_mci(mci); edac_mc_dump_mci(mci);
if (edac_debug_level >= 4) { if (edac_debug_level >= 4) {
int i; int i;
for (i = 0; i < mci->nr_csrows; i++) { for (i = 0; i < mci->nr_csrows; i++) {
int j; int j;
edac_mc_dump_csrow(&mci->csrows[i]); edac_mc_dump_csrow(&mci->csrows[i]);
for (j = 0; j < mci->csrows[i].nr_channels; j++) for (j = 0; j < mci->csrows[i].nr_channels; j++)
edac_mc_dump_channel(&mci->csrows[i]. edac_mc_dump_channel(
channels[j]); &mci->csrows[i].channels[j]);
} }
} }
#endif #endif
...@@ -1505,7 +1501,6 @@ int edac_mc_add_mc(struct mem_ctl_info *mci) ...@@ -1505,7 +1501,6 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
} }
EXPORT_SYMBOL(edac_mc_add_mc); EXPORT_SYMBOL(edac_mc_add_mc);
/** /**
* edac_mc_del_mc: Remove sysfs entries for specified mci structure and * edac_mc_del_mc: Remove sysfs entries for specified mci structure and
* remove mci structure from global list * remove mci structure from global list
...@@ -1535,9 +1530,7 @@ struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev) ...@@ -1535,9 +1530,7 @@ struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev)
} }
EXPORT_SYMBOL(edac_mc_del_mc); EXPORT_SYMBOL(edac_mc_del_mc);
void edac_mc_scrub_block(unsigned long page, unsigned long offset, u32 size)
void edac_mc_scrub_block(unsigned long page, unsigned long offset,
u32 size)
{ {
struct page *pg; struct page *pg;
void *virt_addr; void *virt_addr;
...@@ -1568,10 +1561,8 @@ void edac_mc_scrub_block(unsigned long page, unsigned long offset, ...@@ -1568,10 +1561,8 @@ void edac_mc_scrub_block(unsigned long page, unsigned long offset,
} }
EXPORT_SYMBOL(edac_mc_scrub_block); EXPORT_SYMBOL(edac_mc_scrub_block);
/* FIXME - should return -1 */ /* FIXME - should return -1 */
int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page)
unsigned long page)
{ {
struct csrow_info *csrows = mci->csrows; struct csrow_info *csrows = mci->csrows;
int row, i; int row, i;
...@@ -1608,14 +1599,11 @@ int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, ...@@ -1608,14 +1599,11 @@ int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
} }
EXPORT_SYMBOL(edac_mc_find_csrow_by_page); EXPORT_SYMBOL(edac_mc_find_csrow_by_page);
/* FIXME - setable log (warning/emerg) levels */ /* FIXME - setable log (warning/emerg) levels */
/* FIXME - integrate with evlog: http://evlog.sourceforge.net/ */ /* FIXME - integrate with evlog: http://evlog.sourceforge.net/ */
void edac_mc_handle_ce(struct mem_ctl_info *mci, void edac_mc_handle_ce(struct mem_ctl_info *mci,
unsigned long page_frame_number, unsigned long page_frame_number, unsigned long offset_in_page,
unsigned long offset_in_page, unsigned long syndrome, int row, int channel, const char *msg)
unsigned long syndrome, int row, int channel,
const char *msg)
{ {
unsigned long remapped_page; unsigned long remapped_page;
...@@ -1630,6 +1618,7 @@ void edac_mc_handle_ce(struct mem_ctl_info *mci, ...@@ -1630,6 +1618,7 @@ void edac_mc_handle_ce(struct mem_ctl_info *mci,
edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR"); edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR");
return; return;
} }
if (channel >= mci->csrows[row].nr_channels || channel < 0) { if (channel >= mci->csrows[row].nr_channels || channel < 0) {
/* something is wrong */ /* something is wrong */
edac_mc_printk(mci, KERN_ERR, edac_mc_printk(mci, KERN_ERR,
...@@ -1668,28 +1657,25 @@ void edac_mc_handle_ce(struct mem_ctl_info *mci, ...@@ -1668,28 +1657,25 @@ void edac_mc_handle_ce(struct mem_ctl_info *mci,
page_frame_number; page_frame_number;
edac_mc_scrub_block(remapped_page, offset_in_page, edac_mc_scrub_block(remapped_page, offset_in_page,
mci->csrows[row].grain); mci->csrows[row].grain);
} }
} }
EXPORT_SYMBOL(edac_mc_handle_ce); EXPORT_SYMBOL(edac_mc_handle_ce);
void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, const char *msg)
void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci,
const char *msg)
{ {
if (log_ce) if (log_ce)
edac_mc_printk(mci, KERN_WARNING, edac_mc_printk(mci, KERN_WARNING,
"CE - no information available: %s\n", msg); "CE - no information available: %s\n", msg);
mci->ce_noinfo_count++; mci->ce_noinfo_count++;
mci->ce_count++; mci->ce_count++;
} }
EXPORT_SYMBOL(edac_mc_handle_ce_no_info); EXPORT_SYMBOL(edac_mc_handle_ce_no_info);
void edac_mc_handle_ue(struct mem_ctl_info *mci, void edac_mc_handle_ue(struct mem_ctl_info *mci,
unsigned long page_frame_number, unsigned long page_frame_number, unsigned long offset_in_page,
unsigned long offset_in_page, int row, int row, const char *msg)
const char *msg)
{ {
int len = EDAC_MC_LABEL_LEN * 4; int len = EDAC_MC_LABEL_LEN * 4;
char labels[len + 1]; char labels[len + 1];
...@@ -1710,13 +1696,14 @@ void edac_mc_handle_ue(struct mem_ctl_info *mci, ...@@ -1710,13 +1696,14 @@ void edac_mc_handle_ue(struct mem_ctl_info *mci,
} }
chars = snprintf(pos, len + 1, "%s", chars = snprintf(pos, len + 1, "%s",
mci->csrows[row].channels[0].label); mci->csrows[row].channels[0].label);
len -= chars; len -= chars;
pos += chars; pos += chars;
for (chan = 1; (chan < mci->csrows[row].nr_channels) && (len > 0); for (chan = 1; (chan < mci->csrows[row].nr_channels) && (len > 0);
chan++) { chan++) {
chars = snprintf(pos, len + 1, ":%s", chars = snprintf(pos, len + 1, ":%s",
mci->csrows[row].channels[chan].label); mci->csrows[row].channels[chan].label);
len -= chars; len -= chars;
pos += chars; pos += chars;
} }
...@@ -1729,20 +1716,17 @@ void edac_mc_handle_ue(struct mem_ctl_info *mci, ...@@ -1729,20 +1716,17 @@ void edac_mc_handle_ue(struct mem_ctl_info *mci,
msg); msg);
if (panic_on_ue) if (panic_on_ue)
panic panic("EDAC MC%d: UE page 0x%lx, offset 0x%lx, grain %d, "
("EDAC MC%d: UE page 0x%lx, offset 0x%lx, grain %d, row %d," "row %d, labels \"%s\": %s\n", mci->mc_idx,
" labels \"%s\": %s\n", mci->mc_idx, page_frame_number, offset_in_page,
page_frame_number, offset_in_page, mci->csrows[row].grain, row, labels, msg);
mci->csrows[row].grain, row, labels, msg);
mci->ue_count++; mci->ue_count++;
mci->csrows[row].ue_count++; mci->csrows[row].ue_count++;
} }
EXPORT_SYMBOL(edac_mc_handle_ue); EXPORT_SYMBOL(edac_mc_handle_ue);
void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, const char *msg)
void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci,
const char *msg)
{ {
if (panic_on_ue) if (panic_on_ue)
panic("EDAC MC%d: Uncorrected Error", mci->mc_idx); panic("EDAC MC%d: Uncorrected Error", mci->mc_idx);
...@@ -1755,7 +1739,6 @@ void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, ...@@ -1755,7 +1739,6 @@ void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci,
} }
EXPORT_SYMBOL(edac_mc_handle_ue_no_info); EXPORT_SYMBOL(edac_mc_handle_ue_no_info);
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
static u16 get_pci_parity_status(struct pci_dev *dev, int secondary) static u16 get_pci_parity_status(struct pci_dev *dev, int secondary)
...@@ -1766,18 +1749,22 @@ static u16 get_pci_parity_status(struct pci_dev *dev, int secondary) ...@@ -1766,18 +1749,22 @@ static u16 get_pci_parity_status(struct pci_dev *dev, int secondary)
where = secondary ? PCI_SEC_STATUS : PCI_STATUS; where = secondary ? PCI_SEC_STATUS : PCI_STATUS;
pci_read_config_word(dev, where, &status); pci_read_config_word(dev, where, &status);
/* If we get back 0xFFFF then we must suspect that the card has been pulled but /* If we get back 0xFFFF then we must suspect that the card has been
the Linux PCI layer has not yet finished cleaning up. We don't want to report * pulled but the Linux PCI layer has not yet finished cleaning up.
on such devices */ * We don't want to report on such devices
*/
if (status == 0xFFFF) { if (status == 0xFFFF) {
u32 sanity; u32 sanity;
pci_read_config_dword(dev, 0, &sanity); pci_read_config_dword(dev, 0, &sanity);
if (sanity == 0xFFFFFFFF) if (sanity == 0xFFFFFFFF)
return 0; return 0;
} }
status &= PCI_STATUS_DETECTED_PARITY | PCI_STATUS_SIG_SYSTEM_ERROR | status &= PCI_STATUS_DETECTED_PARITY | PCI_STATUS_SIG_SYSTEM_ERROR |
PCI_STATUS_PARITY; PCI_STATUS_PARITY;
if (status) if (status)
/* reset only the bits we are interested in */ /* reset only the bits we are interested in */
...@@ -1789,7 +1776,7 @@ static u16 get_pci_parity_status(struct pci_dev *dev, int secondary) ...@@ -1789,7 +1776,7 @@ static u16 get_pci_parity_status(struct pci_dev *dev, int secondary)
typedef void (*pci_parity_check_fn_t) (struct pci_dev *dev); typedef void (*pci_parity_check_fn_t) (struct pci_dev *dev);
/* Clear any PCI parity errors logged by this device. */ /* Clear any PCI parity errors logged by this device. */
static void edac_pci_dev_parity_clear( struct pci_dev *dev ) static void edac_pci_dev_parity_clear(struct pci_dev *dev)
{ {
u8 header_type; u8 header_type;
...@@ -1890,58 +1877,55 @@ static void edac_pci_dev_parity_test(struct pci_dev *dev) ...@@ -1890,58 +1877,55 @@ static void edac_pci_dev_parity_test(struct pci_dev *dev)
* Returns: 0 not found * Returns: 0 not found
* 1 found on list * 1 found on list
*/ */
static int check_dev_on_list(struct edac_pci_device_list *list, int free_index, static int check_dev_on_list(struct edac_pci_device_list *list,
struct pci_dev *dev) int free_index, struct pci_dev *dev)
{ {
int i; int i;
int rc = 0; /* Assume not found */ int rc = 0; /* Assume not found */
unsigned short vendor=dev->vendor; unsigned short vendor=dev->vendor;
unsigned short device=dev->device; unsigned short device=dev->device;
/* Scan the list, looking for a vendor/device match /* Scan the list, looking for a vendor/device match */
*/ for (i = 0; i < free_index; i++, list++ ) {
for (i = 0; i < free_index; i++, list++ ) { if ((list->vendor == vendor ) && (list->device == device )) {
if ( (list->vendor == vendor ) && rc = 1;
(list->device == device )) { break;
rc = 1; }
break; }
}
}
return rc; return rc;
} }
/* /*
* pci_dev parity list iterator * pci_dev parity list iterator
* Scan the PCI device list for one iteration, looking for SERRORs * Scan the PCI device list for one iteration, looking for SERRORs
* Master Parity ERRORS or Parity ERRORs on primary or secondary devices * Master Parity ERRORS or Parity ERRORs on primary or secondary devices
*/ */
static inline void edac_pci_dev_parity_iterator(pci_parity_check_fn_t fn) static inline void edac_pci_dev_parity_iterator(pci_parity_check_fn_t fn)
{ {
struct pci_dev *dev=NULL; struct pci_dev *dev = NULL;
/* request for kernel access to the next PCI device, if any, /* request for kernel access to the next PCI device, if any,
* and while we are looking at it have its reference count * and while we are looking at it have its reference count
* bumped until we are done with it * bumped until we are done with it
*/ */
while((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { while((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
/* if whitelist exists then it has priority, so only scan
/* if whitelist exists then it has priority, so only scan those * those devices on the whitelist
* devices on the whitelist */
*/ if (pci_whitelist_count > 0 ) {
if (pci_whitelist_count > 0 ) { if (check_dev_on_list(pci_whitelist,
if (check_dev_on_list(pci_whitelist,
pci_whitelist_count, dev)) pci_whitelist_count, dev))
fn(dev); fn(dev);
} else { } else {
/* /*
* if no whitelist, then check if this devices is * if no whitelist, then check if this devices is
* blacklisted * blacklisted
*/ */
if (!check_dev_on_list(pci_blacklist, if (!check_dev_on_list(pci_blacklist,
pci_blacklist_count, dev)) pci_blacklist_count, dev))
fn(dev); fn(dev);
} }
} }
} }
...@@ -1972,7 +1956,6 @@ static void do_pci_parity_check(void) ...@@ -1972,7 +1956,6 @@ static void do_pci_parity_check(void)
} }
} }
static inline void clear_pci_parity_errors(void) static inline void clear_pci_parity_errors(void)
{ {
/* Clear any PCI bus parity errors that devices initially have logged /* Clear any PCI bus parity errors that devices initially have logged
...@@ -1981,34 +1964,29 @@ static inline void clear_pci_parity_errors(void) ...@@ -1981,34 +1964,29 @@ static inline void clear_pci_parity_errors(void)
edac_pci_dev_parity_iterator(edac_pci_dev_parity_clear); edac_pci_dev_parity_iterator(edac_pci_dev_parity_clear);
} }
#else /* CONFIG_PCI */ #else /* CONFIG_PCI */
static inline void do_pci_parity_check(void) static inline void do_pci_parity_check(void)
{ {
/* no-op */ /* no-op */
} }
static inline void clear_pci_parity_errors(void) static inline void clear_pci_parity_errors(void)
{ {
/* no-op */ /* no-op */
} }
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
/* /*
* Iterate over all MC instances and check for ECC, et al, errors * Iterate over all MC instances and check for ECC, et al, errors
*/ */
static inline void check_mc_devices (void) static inline void check_mc_devices(void)
{ {
struct list_head *item; struct list_head *item;
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
debugf3("%s()\n", __func__); debugf3("%s()\n", __func__);
down(&mem_ctls_mutex); down(&mem_ctls_mutex);
list_for_each(item, &mc_devices) { list_for_each(item, &mc_devices) {
...@@ -2021,7 +1999,6 @@ static inline void check_mc_devices (void) ...@@ -2021,7 +1999,6 @@ static inline void check_mc_devices (void)
up(&mem_ctls_mutex); up(&mem_ctls_mutex);
} }
/* /*
* Check MC status every poll_msec. * Check MC status every poll_msec.
* Check PCI status every poll_msec as well. * Check PCI status every poll_msec as well.
...@@ -2084,6 +2061,7 @@ static int __init edac_mc_init(void) ...@@ -2084,6 +2061,7 @@ static int __init edac_mc_init(void)
/* create our kernel thread */ /* create our kernel thread */
edac_thread = kthread_run(edac_kernel_thread, NULL, "kedac"); edac_thread = kthread_run(edac_kernel_thread, NULL, "kedac");
if (IS_ERR(edac_thread)) { if (IS_ERR(edac_thread)) {
/* remove the sysfs entries */ /* remove the sysfs entries */
edac_sysfs_memctrl_teardown(); edac_sysfs_memctrl_teardown();
...@@ -2094,7 +2072,6 @@ static int __init edac_mc_init(void) ...@@ -2094,7 +2072,6 @@ static int __init edac_mc_init(void)
return 0; return 0;
} }
/* /*
* edac_mc_exit() * edac_mc_exit()
* module exit/termination functioni * module exit/termination functioni
...@@ -2102,7 +2079,6 @@ static int __init edac_mc_init(void) ...@@ -2102,7 +2079,6 @@ static int __init edac_mc_init(void)
static void __exit edac_mc_exit(void) static void __exit edac_mc_exit(void)
{ {
debugf0("%s()\n", __func__); debugf0("%s()\n", __func__);
kthread_stop(edac_thread); kthread_stop(edac_thread);
/* tear down the sysfs device */ /* tear down the sysfs device */
...@@ -2110,15 +2086,12 @@ static void __exit edac_mc_exit(void) ...@@ -2110,15 +2086,12 @@ static void __exit edac_mc_exit(void)
edac_sysfs_pci_teardown(); edac_sysfs_pci_teardown();
} }
module_init(edac_mc_init); module_init(edac_mc_init);
module_exit(edac_mc_exit); module_exit(edac_mc_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh et al\n" MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh et al\n"
"Based on.work by Dan Hollis et al"); "Based on work by Dan Hollis et al");
MODULE_DESCRIPTION("Core library routines for MC reporting"); MODULE_DESCRIPTION("Core library routines for MC reporting");
module_param(panic_on_ue, int, 0644); module_param(panic_on_ue, int, 0644);
......
...@@ -15,11 +15,9 @@ ...@@ -15,11 +15,9 @@
* *
*/ */
#ifndef _EDAC_MC_H_ #ifndef _EDAC_MC_H_
#define _EDAC_MC_H_ #define _EDAC_MC_H_
#include <linux/config.h> #include <linux/config.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -33,7 +31,6 @@ ...@@ -33,7 +31,6 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/kobject.h> #include <linux/kobject.h>
#define EDAC_MC_LABEL_LEN 31 #define EDAC_MC_LABEL_LEN 31
#define MC_PROC_NAME_MAX_LEN 7 #define MC_PROC_NAME_MAX_LEN 7
...@@ -44,13 +41,13 @@ ...@@ -44,13 +41,13 @@
#endif #endif
#define edac_printk(level, prefix, fmt, arg...) \ #define edac_printk(level, prefix, fmt, arg...) \
printk(level "EDAC " prefix ": " fmt, ##arg) printk(level "EDAC " prefix ": " fmt, ##arg)
#define edac_mc_printk(mci, level, fmt, arg...) \ #define edac_mc_printk(mci, level, fmt, arg...) \
printk(level "EDAC MC%d: " fmt, mci->mc_idx, ##arg) printk(level "EDAC MC%d: " fmt, mci->mc_idx, ##arg)
#define edac_mc_chipset_printk(mci, level, prefix, fmt, arg...) \ #define edac_mc_chipset_printk(mci, level, prefix, fmt, arg...) \
printk(level "EDAC " prefix " MC%d: " fmt, mci->mc_idx, ##arg) printk(level "EDAC " prefix " MC%d: " fmt, mci->mc_idx, ##arg)
/* prefixes for edac_printk() and edac_mc_printk() */ /* prefixes for edac_printk() and edac_mc_printk() */
#define EDAC_MC "MC" #define EDAC_MC "MC"
...@@ -71,14 +68,16 @@ extern int edac_debug_level; ...@@ -71,14 +68,16 @@ extern int edac_debug_level;
#define debugf2( ... ) edac_debug_printk(2, __VA_ARGS__ ) #define debugf2( ... ) edac_debug_printk(2, __VA_ARGS__ )
#define debugf3( ... ) edac_debug_printk(3, __VA_ARGS__ ) #define debugf3( ... ) edac_debug_printk(3, __VA_ARGS__ )
#define debugf4( ... ) edac_debug_printk(4, __VA_ARGS__ ) #define debugf4( ... ) edac_debug_printk(4, __VA_ARGS__ )
#else /* !CONFIG_EDAC_DEBUG */
#else /* !CONFIG_EDAC_DEBUG */
#define debugf0( ... ) #define debugf0( ... )
#define debugf1( ... ) #define debugf1( ... )
#define debugf2( ... ) #define debugf2( ... )
#define debugf3( ... ) #define debugf3( ... )
#define debugf4( ... ) #define debugf4( ... )
#endif /* !CONFIG_EDAC_DEBUG */
#endif /* !CONFIG_EDAC_DEBUG */
#define edac_xstr(s) edac_str(s) #define edac_xstr(s) edac_str(s)
#define edac_str(s) #s #define edac_str(s) #s
...@@ -86,7 +85,8 @@ extern int edac_debug_level; ...@@ -86,7 +85,8 @@ extern int edac_debug_level;
#define BIT(x) (1 << (x)) #define BIT(x) (1 << (x))
#define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, PCI_DEVICE_ID_ ## vend ## _ ## dev #define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \
PCI_DEVICE_ID_ ## vend ## _ ## dev
/* memory devices */ /* memory devices */
enum dev_type { enum dev_type {
...@@ -136,7 +136,6 @@ enum mem_type { ...@@ -136,7 +136,6 @@ enum mem_type {
#define MEM_FLAG_RDDR BIT(MEM_RDDR) #define MEM_FLAG_RDDR BIT(MEM_RDDR)
#define MEM_FLAG_RMBS BIT(MEM_RMBS) #define MEM_FLAG_RMBS BIT(MEM_RMBS)
/* chipset Error Detection and Correction capabilities and mode */ /* chipset Error Detection and Correction capabilities and mode */
enum edac_type { enum edac_type {
EDAC_UNKNOWN = 0, /* Unknown if ECC is available */ EDAC_UNKNOWN = 0, /* Unknown if ECC is available */
...@@ -161,7 +160,6 @@ enum edac_type { ...@@ -161,7 +160,6 @@ enum edac_type {
#define EDAC_FLAG_S8ECD8ED BIT(EDAC_S8ECD8ED) #define EDAC_FLAG_S8ECD8ED BIT(EDAC_S8ECD8ED)
#define EDAC_FLAG_S16ECD16ED BIT(EDAC_S16ECD16ED) #define EDAC_FLAG_S16ECD16ED BIT(EDAC_S16ECD16ED)
/* scrubbing capabilities */ /* scrubbing capabilities */
enum scrub_type { enum scrub_type {
SCRUB_UNKNOWN = 0, /* Unknown if scrubber is available */ SCRUB_UNKNOWN = 0, /* Unknown if scrubber is available */
...@@ -269,20 +267,19 @@ enum scrub_type { ...@@ -269,20 +267,19 @@ enum scrub_type {
* PS - I enjoyed writing all that about as much as you enjoyed reading it. * PS - I enjoyed writing all that about as much as you enjoyed reading it.
*/ */
struct channel_info { struct channel_info {
int chan_idx; /* channel index */ int chan_idx; /* channel index */
u32 ce_count; /* Correctable Errors for this CHANNEL */ u32 ce_count; /* Correctable Errors for this CHANNEL */
char label[EDAC_MC_LABEL_LEN + 1]; /* DIMM label on motherboard */ char label[EDAC_MC_LABEL_LEN + 1]; /* DIMM label on motherboard */
struct csrow_info *csrow; /* the parent */ struct csrow_info *csrow; /* the parent */
}; };
struct csrow_info { struct csrow_info {
unsigned long first_page; /* first page number in dimm */ unsigned long first_page; /* first page number in dimm */
unsigned long last_page; /* last page number in dimm */ unsigned long last_page; /* last page number in dimm */
unsigned long page_mask; /* used for interleaving - unsigned long page_mask; /* used for interleaving -
0UL for non intlv */ * 0UL for non intlv
*/
u32 nr_pages; /* number of pages in csrow */ u32 nr_pages; /* number of pages in csrow */
u32 grain; /* granularity of reported error in bytes */ u32 grain; /* granularity of reported error in bytes */
int csrow_idx; /* the chip-select row */ int csrow_idx; /* the chip-select row */
...@@ -301,18 +298,18 @@ struct csrow_info { ...@@ -301,18 +298,18 @@ struct csrow_info {
struct channel_info *channels; struct channel_info *channels;
}; };
struct mem_ctl_info { struct mem_ctl_info {
struct list_head link; /* for global list of mem_ctl_info structs */ struct list_head link; /* for global list of mem_ctl_info structs */
unsigned long mtype_cap; /* memory types supported by mc */ unsigned long mtype_cap; /* memory types supported by mc */
unsigned long edac_ctl_cap; /* Mem controller EDAC capabilities */ unsigned long edac_ctl_cap; /* Mem controller EDAC capabilities */
unsigned long edac_cap; /* configuration capabilities - this is unsigned long edac_cap; /* configuration capabilities - this is
closely related to edac_ctl_cap. The * closely related to edac_ctl_cap. The
difference is that the controller * difference is that the controller may be
may be capable of s4ecd4ed which would * capable of s4ecd4ed which would be listed
be listed in edac_ctl_cap, but if * in edac_ctl_cap, but if channels aren't
channels aren't capable of s4ecd4ed then the * capable of s4ecd4ed then the edac_cap would
edac_cap would not have that capability. */ * not have that capability.
*/
unsigned long scrub_cap; /* chipset scrub capabilities */ unsigned long scrub_cap; /* chipset scrub capabilities */
enum scrub_type scrub_mode; /* current scrub mode */ enum scrub_type scrub_mode; /* current scrub mode */
...@@ -324,7 +321,7 @@ struct mem_ctl_info { ...@@ -324,7 +321,7 @@ struct mem_ctl_info {
*/ */
/* FIXME - why not send the phys page to begin with? */ /* FIXME - why not send the phys page to begin with? */
unsigned long (*ctl_page_to_phys) (struct mem_ctl_info * mci, unsigned long (*ctl_page_to_phys) (struct mem_ctl_info * mci,
unsigned long page); unsigned long page);
int mc_idx; int mc_idx;
int nr_csrows; int nr_csrows;
struct csrow_info *csrows; struct csrow_info *csrows;
...@@ -356,67 +353,66 @@ struct mem_ctl_info { ...@@ -356,67 +353,66 @@ struct mem_ctl_info {
struct completion kobj_complete; struct completion kobj_complete;
}; };
/* write all or some bits in a byte-register*/ /* write all or some bits in a byte-register*/
static inline void pci_write_bits8(struct pci_dev *pdev, int offset, static inline void pci_write_bits8(struct pci_dev *pdev, int offset, u8 value,
u8 value, u8 mask) u8 mask)
{ {
if (mask != 0xff) { if (mask != 0xff) {
u8 buf; u8 buf;
pci_read_config_byte(pdev, offset, &buf); pci_read_config_byte(pdev, offset, &buf);
value &= mask; value &= mask;
buf &= ~mask; buf &= ~mask;
value |= buf; value |= buf;
} }
pci_write_config_byte(pdev, offset, value); pci_write_config_byte(pdev, offset, value);
} }
/* write all or some bits in a word-register*/ /* write all or some bits in a word-register*/
static inline void pci_write_bits16(struct pci_dev *pdev, int offset, static inline void pci_write_bits16(struct pci_dev *pdev, int offset,
u16 value, u16 mask) u16 value, u16 mask)
{ {
if (mask != 0xffff) { if (mask != 0xffff) {
u16 buf; u16 buf;
pci_read_config_word(pdev, offset, &buf); pci_read_config_word(pdev, offset, &buf);
value &= mask; value &= mask;
buf &= ~mask; buf &= ~mask;
value |= buf; value |= buf;
} }
pci_write_config_word(pdev, offset, value); pci_write_config_word(pdev, offset, value);
} }
/* write all or some bits in a dword-register*/ /* write all or some bits in a dword-register*/
static inline void pci_write_bits32(struct pci_dev *pdev, int offset, static inline void pci_write_bits32(struct pci_dev *pdev, int offset,
u32 value, u32 mask) u32 value, u32 mask)
{ {
if (mask != 0xffff) { if (mask != 0xffff) {
u32 buf; u32 buf;
pci_read_config_dword(pdev, offset, &buf); pci_read_config_dword(pdev, offset, &buf);
value &= mask; value &= mask;
buf &= ~mask; buf &= ~mask;
value |= buf; value |= buf;
} }
pci_write_config_dword(pdev, offset, value); pci_write_config_dword(pdev, offset, value);
} }
#ifdef CONFIG_EDAC_DEBUG #ifdef CONFIG_EDAC_DEBUG
void edac_mc_dump_channel(struct channel_info *chan); void edac_mc_dump_channel(struct channel_info *chan);
void edac_mc_dump_mci(struct mem_ctl_info *mci); void edac_mc_dump_mci(struct mem_ctl_info *mci);
void edac_mc_dump_csrow(struct csrow_info *csrow); void edac_mc_dump_csrow(struct csrow_info *csrow);
#endif /* CONFIG_EDAC_DEBUG */ #endif /* CONFIG_EDAC_DEBUG */
extern int edac_mc_add_mc(struct mem_ctl_info *mci); extern int edac_mc_add_mc(struct mem_ctl_info *mci);
extern struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev); extern struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev);
extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
unsigned long page); unsigned long page);
extern void edac_mc_scrub_block(unsigned long page, unsigned long offset,
extern void edac_mc_scrub_block(unsigned long page, u32 size);
unsigned long offset, u32 size);
/* /*
* The no info errors are used when error overflows are reported. * The no info errors are used when error overflows are reported.
...@@ -429,31 +425,25 @@ extern void edac_mc_scrub_block(unsigned long page, ...@@ -429,31 +425,25 @@ extern void edac_mc_scrub_block(unsigned long page,
* statement clutter and extra function arguments. * statement clutter and extra function arguments.
*/ */
extern void edac_mc_handle_ce(struct mem_ctl_info *mci, extern void edac_mc_handle_ce(struct mem_ctl_info *mci,
unsigned long page_frame_number, unsigned long page_frame_number, unsigned long offset_in_page,
unsigned long offset_in_page, unsigned long syndrome, int row, int channel,
unsigned long syndrome, const char *msg);
int row, int channel, const char *msg);
extern void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, extern void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci,
const char *msg); const char *msg);
extern void edac_mc_handle_ue(struct mem_ctl_info *mci, extern void edac_mc_handle_ue(struct mem_ctl_info *mci,
unsigned long page_frame_number, unsigned long page_frame_number, unsigned long offset_in_page,
unsigned long offset_in_page, int row, const char *msg);
int row, const char *msg);
extern void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, extern void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci,
const char *msg); const char *msg);
/* /*
* This kmalloc's and initializes all the structures. * This kmalloc's and initializes all the structures.
* Can't be used if all structures don't have the same lifetime. * Can't be used if all structures don't have the same lifetime.
*/ */
extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
unsigned nr_csrows, unsigned nr_chans); unsigned nr_chans);
/* Free an mc previously allocated by edac_mc_alloc() */ /* Free an mc previously allocated by edac_mc_alloc() */
extern void edac_mc_free(struct mem_ctl_info *mci); extern void edac_mc_free(struct mem_ctl_info *mci);
#endif /* _EDAC_MC_H_ */ #endif /* _EDAC_MC_H_ */
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
* by Thayne Harbaugh of Linux Networx. (http://lnxi.com) * by Thayne Harbaugh of Linux Networx. (http://lnxi.com)
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -18,14 +17,11 @@ ...@@ -18,14 +17,11 @@
#include <linux/slab.h> #include <linux/slab.h>
#include "edac_mc.h" #include "edac_mc.h"
#define i82860_printk(level, fmt, arg...) \ #define i82860_printk(level, fmt, arg...) \
edac_printk(level, "i82860", fmt, ##arg) edac_printk(level, "i82860", fmt, ##arg)
#define i82860_mc_printk(mci, level, fmt, arg...) \ #define i82860_mc_printk(mci, level, fmt, arg...) \
edac_mc_chipset_printk(mci, level, "i82860", fmt, ##arg) edac_mc_chipset_printk(mci, level, "i82860", fmt, ##arg)
#ifndef PCI_DEVICE_ID_INTEL_82860_0 #ifndef PCI_DEVICE_ID_INTEL_82860_0
#define PCI_DEVICE_ID_INTEL_82860_0 0x2531 #define PCI_DEVICE_ID_INTEL_82860_0 0x2531
...@@ -56,13 +52,15 @@ struct i82860_error_info { ...@@ -56,13 +52,15 @@ struct i82860_error_info {
static const struct i82860_dev_info i82860_devs[] = { static const struct i82860_dev_info i82860_devs[] = {
[I82860] = { [I82860] = {
.ctl_name = "i82860"}, .ctl_name = "i82860"
},
}; };
static struct pci_dev *mci_pdev = NULL; /* init dev: in case that AGP code static struct pci_dev *mci_pdev = NULL; /* init dev: in case that AGP code
has already registered driver */ * has already registered driver
*/
static void i82860_get_error_info (struct mem_ctl_info *mci, static void i82860_get_error_info(struct mem_ctl_info *mci,
struct i82860_error_info *info) struct i82860_error_info *info)
{ {
/* /*
...@@ -84,14 +82,15 @@ static void i82860_get_error_info (struct mem_ctl_info *mci, ...@@ -84,14 +82,15 @@ static void i82860_get_error_info (struct mem_ctl_info *mci,
*/ */
if (!(info->errsts2 & 0x0003)) if (!(info->errsts2 & 0x0003))
return; return;
if ((info->errsts ^ info->errsts2) & 0x0003) { if ((info->errsts ^ info->errsts2) & 0x0003) {
pci_read_config_dword(mci->pdev, I82860_EAP, &info->eap); pci_read_config_dword(mci->pdev, I82860_EAP, &info->eap);
pci_read_config_word(mci->pdev, I82860_DERRCTL_STS, pci_read_config_word(mci->pdev, I82860_DERRCTL_STS,
&info->derrsyn); &info->derrsyn);
} }
} }
static int i82860_process_error_info (struct mem_ctl_info *mci, static int i82860_process_error_info(struct mem_ctl_info *mci,
struct i82860_error_info *info, int handle_errors) struct i82860_error_info *info, int handle_errors)
{ {
int row; int row;
...@@ -113,8 +112,8 @@ static int i82860_process_error_info (struct mem_ctl_info *mci, ...@@ -113,8 +112,8 @@ static int i82860_process_error_info (struct mem_ctl_info *mci,
if (info->errsts & 0x0002) if (info->errsts & 0x0002)
edac_mc_handle_ue(mci, info->eap, 0, row, "i82860 UE"); edac_mc_handle_ue(mci, info->eap, 0, row, "i82860 UE");
else else
edac_mc_handle_ce(mci, info->eap, 0, info->derrsyn, row, edac_mc_handle_ce(mci, info->eap, 0, info->derrsyn, row, 0,
0, "i82860 UE"); "i82860 UE");
return 1; return 1;
} }
...@@ -147,15 +146,14 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -147,15 +146,14 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx)
going to make 1 channel for group. going to make 1 channel for group.
*/ */
mci = edac_mc_alloc(0, 16, 1); mci = edac_mc_alloc(0, 16, 1);
if (!mci) if (!mci)
return -ENOMEM; return -ENOMEM;
debugf3("%s(): init mci\n", __func__); debugf3("%s(): init mci\n", __func__);
mci->pdev = pdev; mci->pdev = pdev;
mci->mtype_cap = MEM_FLAG_DDR; mci->mtype_cap = MEM_FLAG_DDR;
mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
/* I"m not sure about this but I think that all RDRAM is SECDED */ /* I"m not sure about this but I think that all RDRAM is SECDED */
mci->edac_cap = EDAC_FLAG_SECDED; mci->edac_cap = EDAC_FLAG_SECDED;
...@@ -182,12 +180,13 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -182,12 +180,13 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx)
struct csrow_info *csrow = &mci->csrows[index]; struct csrow_info *csrow = &mci->csrows[index];
pci_read_config_word(mci->pdev, I82860_GBA + index * 2, pci_read_config_word(mci->pdev, I82860_GBA + index * 2,
&value); &value);
cumul_size = (value & I82860_GBA_MASK) << cumul_size = (value & I82860_GBA_MASK) <<
(I82860_GBA_SHIFT - PAGE_SHIFT); (I82860_GBA_SHIFT - PAGE_SHIFT);
debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index,
cumul_size); cumul_size);
if (cumul_size == last_cumul_size) if (cumul_size == last_cumul_size)
continue; /* not populated */ continue; /* not populated */
...@@ -195,7 +194,7 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -195,7 +194,7 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx)
csrow->last_page = cumul_size - 1; csrow->last_page = cumul_size - 1;
csrow->nr_pages = cumul_size - last_cumul_size; csrow->nr_pages = cumul_size - last_cumul_size;
last_cumul_size = cumul_size; last_cumul_size = cumul_size;
csrow->grain = 1 << 12; /* I82860_EAP has 4KiB reolution */ csrow->grain = 1 << 12; /* I82860_EAP has 4KiB reolution */
csrow->mtype = MEM_RMBS; csrow->mtype = MEM_RMBS;
csrow->dtype = DEV_UNKNOWN; csrow->dtype = DEV_UNKNOWN;
csrow->edac_mode = mchcfg_ddim ? EDAC_SECDED : EDAC_NONE; csrow->edac_mode = mchcfg_ddim ? EDAC_SECDED : EDAC_NONE;
...@@ -211,23 +210,27 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -211,23 +210,27 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx)
debugf3("%s(): success\n", __func__); debugf3("%s(): success\n", __func__);
rc = 0; rc = 0;
} }
return rc; return rc;
} }
/* returns count (>= 0), or negative on error */ /* returns count (>= 0), or negative on error */
static int __devinit i82860_init_one(struct pci_dev *pdev, static int __devinit i82860_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
int rc; int rc;
debugf0("%s()\n", __func__); debugf0("%s()\n", __func__);
i82860_printk(KERN_INFO, "i82860 init one\n"); i82860_printk(KERN_INFO, "i82860 init one\n");
if(pci_enable_device(pdev) < 0)
if (pci_enable_device(pdev) < 0)
return -EIO; return -EIO;
rc = i82860_probe1(pdev, ent->driver_data); rc = i82860_probe1(pdev, ent->driver_data);
if(rc == 0)
if (rc == 0)
mci_pdev = pci_dev_get(pdev); mci_pdev = pci_dev_get(pdev);
return rc; return rc;
} }
...@@ -244,9 +247,13 @@ static void __devexit i82860_remove_one(struct pci_dev *pdev) ...@@ -244,9 +247,13 @@ static void __devexit i82860_remove_one(struct pci_dev *pdev)
} }
static const struct pci_device_id i82860_pci_tbl[] __devinitdata = { static const struct pci_device_id i82860_pci_tbl[] __devinitdata = {
{PCI_VEND_DEV(INTEL, 82860_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, {
I82860}, PCI_VEND_DEV(INTEL, 82860_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
{0,} /* 0 terminated list. */ I82860
},
{
0,
} /* 0 terminated list. */
}; };
MODULE_DEVICE_TABLE(pci, i82860_pci_tbl); MODULE_DEVICE_TABLE(pci, i82860_pci_tbl);
...@@ -263,24 +270,29 @@ static int __init i82860_init(void) ...@@ -263,24 +270,29 @@ static int __init i82860_init(void)
int pci_rc; int pci_rc;
debugf3("%s()\n", __func__); debugf3("%s()\n", __func__);
if ((pci_rc = pci_register_driver(&i82860_driver)) < 0) if ((pci_rc = pci_register_driver(&i82860_driver)) < 0)
goto fail0; goto fail0;
if (!mci_pdev) { if (!mci_pdev) {
mci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL, mci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82860_0, NULL); PCI_DEVICE_ID_INTEL_82860_0, NULL);
if (mci_pdev == NULL) { if (mci_pdev == NULL) {
debugf0("860 pci_get_device fail\n"); debugf0("860 pci_get_device fail\n");
pci_rc = -ENODEV; pci_rc = -ENODEV;
goto fail1; goto fail1;
} }
pci_rc = i82860_init_one(mci_pdev, i82860_pci_tbl); pci_rc = i82860_init_one(mci_pdev, i82860_pci_tbl);
if (pci_rc < 0) { if (pci_rc < 0) {
debugf0("860 init fail\n"); debugf0("860 init fail\n");
pci_rc = -ENODEV; pci_rc = -ENODEV;
goto fail1; goto fail1;
} }
} }
return 0; return 0;
fail1: fail1:
...@@ -307,6 +319,6 @@ module_init(i82860_init); ...@@ -307,6 +319,6 @@ module_init(i82860_init);
module_exit(i82860_exit); module_exit(i82860_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com) "
("Red Hat Inc. (http://www.redhat.com) Ben Woodard <woodard@redhat.com>"); "Ben Woodard <woodard@redhat.com>");
MODULE_DESCRIPTION("ECC support for Intel 82860 memory hub controllers"); MODULE_DESCRIPTION("ECC support for Intel 82860 memory hub controllers");
...@@ -13,26 +13,19 @@ ...@@ -13,26 +13,19 @@
* Note: E7210 appears same as D82875P - zhenyu.z.wang at intel.com * Note: E7210 appears same as D82875P - zhenyu.z.wang at intel.com
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/pci_ids.h> #include <linux/pci_ids.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "edac_mc.h" #include "edac_mc.h"
#define i82875p_printk(level, fmt, arg...) \ #define i82875p_printk(level, fmt, arg...) \
edac_printk(level, "i82875p", fmt, ##arg) edac_printk(level, "i82875p", fmt, ##arg)
#define i82875p_mc_printk(mci, level, fmt, arg...) \ #define i82875p_mc_printk(mci, level, fmt, arg...) \
edac_mc_chipset_printk(mci, level, "i82875p", fmt, ##arg) edac_mc_chipset_printk(mci, level, "i82875p", fmt, ##arg)
#ifndef PCI_DEVICE_ID_INTEL_82875_0 #ifndef PCI_DEVICE_ID_INTEL_82875_0
#define PCI_DEVICE_ID_INTEL_82875_0 0x2578 #define PCI_DEVICE_ID_INTEL_82875_0 0x2578
...@@ -42,11 +35,9 @@ ...@@ -42,11 +35,9 @@
#define PCI_DEVICE_ID_INTEL_82875_6 0x257e #define PCI_DEVICE_ID_INTEL_82875_6 0x257e
#endif /* PCI_DEVICE_ID_INTEL_82875_6 */ #endif /* PCI_DEVICE_ID_INTEL_82875_6 */
/* four csrows in dual channel, eight in single channel */ /* four csrows in dual channel, eight in single channel */
#define I82875P_NR_CSROWS(nr_chans) (8/(nr_chans)) #define I82875P_NR_CSROWS(nr_chans) (8/(nr_chans))
/* Intel 82875p register addresses - device 0 function 0 - DRAM Controller */ /* Intel 82875p register addresses - device 0 function 0 - DRAM Controller */
#define I82875P_EAP 0x58 /* Error Address Pointer (32b) #define I82875P_EAP 0x58 /* Error Address Pointer (32b)
* *
...@@ -95,7 +86,6 @@ ...@@ -95,7 +86,6 @@
* 0 reserved * 0 reserved
*/ */
/* Intel 82875p register addresses - device 6 function 0 - DRAM Controller */ /* Intel 82875p register addresses - device 6 function 0 - DRAM Controller */
#define I82875P_PCICMD6 0x04 /* PCI Command Register (16b) #define I82875P_PCICMD6 0x04 /* PCI Command Register (16b)
* *
...@@ -159,23 +149,19 @@ ...@@ -159,23 +149,19 @@
* 1:0 DRAM type 01=DDR * 1:0 DRAM type 01=DDR
*/ */
enum i82875p_chips { enum i82875p_chips {
I82875P = 0, I82875P = 0,
}; };
struct i82875p_pvt { struct i82875p_pvt {
struct pci_dev *ovrfl_pdev; struct pci_dev *ovrfl_pdev;
void __iomem *ovrfl_window; void __iomem *ovrfl_window;
}; };
struct i82875p_dev_info { struct i82875p_dev_info {
const char *ctl_name; const char *ctl_name;
}; };
struct i82875p_error_info { struct i82875p_error_info {
u16 errsts; u16 errsts;
u32 eap; u32 eap;
...@@ -184,17 +170,19 @@ struct i82875p_error_info { ...@@ -184,17 +170,19 @@ struct i82875p_error_info {
u16 errsts2; u16 errsts2;
}; };
static const struct i82875p_dev_info i82875p_devs[] = { static const struct i82875p_dev_info i82875p_devs[] = {
[I82875P] = { [I82875P] = {
.ctl_name = "i82875p"}, .ctl_name = "i82875p"
},
}; };
static struct pci_dev *mci_pdev = NULL; /* init dev: in case that AGP code static struct pci_dev *mci_pdev = NULL; /* init dev: in case that AGP code has
has already registered driver */ * already registered driver
*/
static int i82875p_registered = 1; static int i82875p_registered = 1;
static void i82875p_get_error_info (struct mem_ctl_info *mci, static void i82875p_get_error_info(struct mem_ctl_info *mci,
struct i82875p_error_info *info) struct i82875p_error_info *info)
{ {
/* /*
...@@ -218,15 +206,16 @@ static void i82875p_get_error_info (struct mem_ctl_info *mci, ...@@ -218,15 +206,16 @@ static void i82875p_get_error_info (struct mem_ctl_info *mci,
*/ */
if (!(info->errsts2 & 0x0081)) if (!(info->errsts2 & 0x0081))
return; return;
if ((info->errsts ^ info->errsts2) & 0x0081) { if ((info->errsts ^ info->errsts2) & 0x0081) {
pci_read_config_dword(mci->pdev, I82875P_EAP, &info->eap); pci_read_config_dword(mci->pdev, I82875P_EAP, &info->eap);
pci_read_config_byte(mci->pdev, I82875P_DES, &info->des); pci_read_config_byte(mci->pdev, I82875P_DES, &info->des);
pci_read_config_byte(mci->pdev, I82875P_DERRSYN, pci_read_config_byte(mci->pdev, I82875P_DERRSYN,
&info->derrsyn); &info->derrsyn);
} }
} }
static int i82875p_process_error_info (struct mem_ctl_info *mci, static int i82875p_process_error_info(struct mem_ctl_info *mci,
struct i82875p_error_info *info, int handle_errors) struct i82875p_error_info *info, int handle_errors)
{ {
int row, multi_chan; int row, multi_chan;
...@@ -251,13 +240,12 @@ static int i82875p_process_error_info (struct mem_ctl_info *mci, ...@@ -251,13 +240,12 @@ static int i82875p_process_error_info (struct mem_ctl_info *mci,
edac_mc_handle_ue(mci, info->eap, 0, row, "i82875p UE"); edac_mc_handle_ue(mci, info->eap, 0, row, "i82875p UE");
else else
edac_mc_handle_ce(mci, info->eap, 0, info->derrsyn, row, edac_mc_handle_ce(mci, info->eap, 0, info->derrsyn, row,
multi_chan ? (info->des & 0x1) : 0, multi_chan ? (info->des & 0x1) : 0,
"i82875p CE"); "i82875p CE");
return 1; return 1;
} }
static void i82875p_check(struct mem_ctl_info *mci) static void i82875p_check(struct mem_ctl_info *mci)
{ {
struct i82875p_error_info info; struct i82875p_error_info info;
...@@ -267,7 +255,6 @@ static void i82875p_check(struct mem_ctl_info *mci) ...@@ -267,7 +255,6 @@ static void i82875p_check(struct mem_ctl_info *mci)
i82875p_process_error_info(mci, &info, 1); i82875p_process_error_info(mci, &info, 1);
} }
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
extern int pci_proc_attach_device(struct pci_dev *); extern int pci_proc_attach_device(struct pci_dev *);
#endif #endif
...@@ -281,7 +268,6 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -281,7 +268,6 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx)
unsigned long last_cumul_size; unsigned long last_cumul_size;
struct pci_dev *ovrfl_pdev; struct pci_dev *ovrfl_pdev;
void __iomem *ovrfl_window = NULL; void __iomem *ovrfl_window = NULL;
u32 drc; u32 drc;
u32 drc_chan; /* Number of channels 0=1chan,1=2chan */ u32 drc_chan; /* Number of channels 0=1chan,1=2chan */
u32 nr_chans; u32 nr_chans;
...@@ -289,7 +275,6 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -289,7 +275,6 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx)
struct i82875p_error_info discard; struct i82875p_error_info discard;
debugf0("%s()\n", __func__); debugf0("%s()\n", __func__);
ovrfl_pdev = pci_get_device(PCI_VEND_DEV(INTEL, 82875_6), NULL); ovrfl_pdev = pci_get_device(PCI_VEND_DEV(INTEL, 82875_6), NULL);
if (!ovrfl_pdev) { if (!ovrfl_pdev) {
...@@ -301,22 +286,23 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -301,22 +286,23 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx)
*/ */
pci_write_bits8(pdev, 0xf4, 0x2, 0x2); pci_write_bits8(pdev, 0xf4, 0x2, 0x2);
ovrfl_pdev = ovrfl_pdev =
pci_scan_single_device(pdev->bus, PCI_DEVFN(6, 0)); pci_scan_single_device(pdev->bus, PCI_DEVFN(6, 0));
if (!ovrfl_pdev) if (!ovrfl_pdev)
return -ENODEV; return -ENODEV;
} }
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
if (!ovrfl_pdev->procent && pci_proc_attach_device(ovrfl_pdev)) { if (!ovrfl_pdev->procent && pci_proc_attach_device(ovrfl_pdev)) {
i82875p_printk(KERN_ERR, i82875p_printk(KERN_ERR,
"%s(): Failed to attach overflow device\n", "%s(): Failed to attach overflow device\n", __func__);
__func__);
return -ENODEV; return -ENODEV;
} }
#endif /* CONFIG_PROC_FS */ #endif
/* CONFIG_PROC_FS */
if (pci_enable_device(ovrfl_pdev)) { if (pci_enable_device(ovrfl_pdev)) {
i82875p_printk(KERN_ERR, i82875p_printk(KERN_ERR,
"%s(): Failed to enable overflow device\n", "%s(): Failed to enable overflow device\n", __func__);
__func__);
return -ENODEV; return -ENODEV;
} }
...@@ -325,13 +311,14 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -325,13 +311,14 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx)
goto fail0; goto fail0;
#endif #endif
} }
/* cache is irrelevant for PCI bus reads/writes */ /* cache is irrelevant for PCI bus reads/writes */
ovrfl_window = ioremap_nocache(pci_resource_start(ovrfl_pdev, 0), ovrfl_window = ioremap_nocache(pci_resource_start(ovrfl_pdev, 0),
pci_resource_len(ovrfl_pdev, 0)); pci_resource_len(ovrfl_pdev, 0));
if (!ovrfl_window) { if (!ovrfl_window) {
i82875p_printk(KERN_ERR, "%s(): Failed to ioremap bar6\n", i82875p_printk(KERN_ERR, "%s(): Failed to ioremap bar6\n",
__func__); __func__);
goto fail1; goto fail1;
} }
...@@ -339,10 +326,10 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -339,10 +326,10 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx)
drc = readl(ovrfl_window + I82875P_DRC); drc = readl(ovrfl_window + I82875P_DRC);
drc_chan = ((drc >> 21) & 0x1); drc_chan = ((drc >> 21) & 0x1);
nr_chans = drc_chan + 1; nr_chans = drc_chan + 1;
drc_ddim = (drc >> 18) & 0x1;
drc_ddim = (drc >> 18) & 0x1;
mci = edac_mc_alloc(sizeof(*pvt), I82875P_NR_CSROWS(nr_chans), mci = edac_mc_alloc(sizeof(*pvt), I82875P_NR_CSROWS(nr_chans),
nr_chans); nr_chans);
if (!mci) { if (!mci) {
rc = -ENOMEM; rc = -ENOMEM;
...@@ -350,10 +337,8 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -350,10 +337,8 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx)
} }
debugf3("%s(): init mci\n", __func__); debugf3("%s(): init mci\n", __func__);
mci->pdev = pdev; mci->pdev = pdev;
mci->mtype_cap = MEM_FLAG_DDR; mci->mtype_cap = MEM_FLAG_DDR;
mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
mci->edac_cap = EDAC_FLAG_UNKNOWN; mci->edac_cap = EDAC_FLAG_UNKNOWN;
/* adjust FLAGS */ /* adjust FLAGS */
...@@ -363,9 +348,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -363,9 +348,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx)
mci->ctl_name = i82875p_devs[dev_idx].ctl_name; mci->ctl_name = i82875p_devs[dev_idx].ctl_name;
mci->edac_check = i82875p_check; mci->edac_check = i82875p_check;
mci->ctl_page_to_phys = NULL; mci->ctl_page_to_phys = NULL;
debugf3("%s(): init pvt\n", __func__); debugf3("%s(): init pvt\n", __func__);
pvt = (struct i82875p_pvt *) mci->pvt_info; pvt = (struct i82875p_pvt *) mci->pvt_info;
pvt->ovrfl_pdev = ovrfl_pdev; pvt->ovrfl_pdev = ovrfl_pdev;
pvt->ovrfl_window = ovrfl_window; pvt->ovrfl_window = ovrfl_window;
...@@ -385,6 +368,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -385,6 +368,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx)
cumul_size = value << (I82875P_DRB_SHIFT - PAGE_SHIFT); cumul_size = value << (I82875P_DRB_SHIFT - PAGE_SHIFT);
debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index,
cumul_size); cumul_size);
if (cumul_size == last_cumul_size) if (cumul_size == last_cumul_size)
continue; /* not populated */ continue; /* not populated */
...@@ -392,7 +376,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -392,7 +376,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx)
csrow->last_page = cumul_size - 1; csrow->last_page = cumul_size - 1;
csrow->nr_pages = cumul_size - last_cumul_size; csrow->nr_pages = cumul_size - last_cumul_size;
last_cumul_size = cumul_size; last_cumul_size = cumul_size;
csrow->grain = 1 << 12; /* I82875P_EAP has 4KiB reolution */ csrow->grain = 1 << 12; /* I82875P_EAP has 4KiB reolution */
csrow->mtype = MEM_DDR; csrow->mtype = MEM_DDR;
csrow->dtype = DEV_UNKNOWN; csrow->dtype = DEV_UNKNOWN;
csrow->edac_mode = drc_ddim ? EDAC_SECDED : EDAC_NONE; csrow->edac_mode = drc_ddim ? EDAC_SECDED : EDAC_NONE;
...@@ -426,25 +410,26 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -426,25 +410,26 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx)
return rc; return rc;
} }
/* returns count (>= 0), or negative on error */ /* returns count (>= 0), or negative on error */
static int __devinit i82875p_init_one(struct pci_dev *pdev, static int __devinit i82875p_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
int rc; int rc;
debugf0("%s()\n", __func__); debugf0("%s()\n", __func__);
i82875p_printk(KERN_INFO, "i82875p init one\n"); i82875p_printk(KERN_INFO, "i82875p init one\n");
if(pci_enable_device(pdev) < 0)
if (pci_enable_device(pdev) < 0)
return -EIO; return -EIO;
rc = i82875p_probe1(pdev, ent->driver_data); rc = i82875p_probe1(pdev, ent->driver_data);
if (mci_pdev == NULL) if (mci_pdev == NULL)
mci_pdev = pci_dev_get(pdev); mci_pdev = pci_dev_get(pdev);
return rc; return rc;
} }
static void __devexit i82875p_remove_one(struct pci_dev *pdev) static void __devexit i82875p_remove_one(struct pci_dev *pdev)
{ {
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
...@@ -456,6 +441,7 @@ static void __devexit i82875p_remove_one(struct pci_dev *pdev) ...@@ -456,6 +441,7 @@ static void __devexit i82875p_remove_one(struct pci_dev *pdev)
return; return;
pvt = (struct i82875p_pvt *) mci->pvt_info; pvt = (struct i82875p_pvt *) mci->pvt_info;
if (pvt->ovrfl_window) if (pvt->ovrfl_window)
iounmap(pvt->ovrfl_window); iounmap(pvt->ovrfl_window);
...@@ -470,16 +456,18 @@ static void __devexit i82875p_remove_one(struct pci_dev *pdev) ...@@ -470,16 +456,18 @@ static void __devexit i82875p_remove_one(struct pci_dev *pdev)
edac_mc_free(mci); edac_mc_free(mci);
} }
static const struct pci_device_id i82875p_pci_tbl[] __devinitdata = { static const struct pci_device_id i82875p_pci_tbl[] __devinitdata = {
{PCI_VEND_DEV(INTEL, 82875_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0, {
I82875P}, PCI_VEND_DEV(INTEL, 82875_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
{0,} /* 0 terminated list. */ I82875P
},
{
0,
} /* 0 terminated list. */
}; };
MODULE_DEVICE_TABLE(pci, i82875p_pci_tbl); MODULE_DEVICE_TABLE(pci, i82875p_pci_tbl);
static struct pci_driver i82875p_driver = { static struct pci_driver i82875p_driver = {
.name = EDAC_MOD_STR, .name = EDAC_MOD_STR,
.probe = i82875p_init_one, .probe = i82875p_init_one,
...@@ -487,31 +475,35 @@ static struct pci_driver i82875p_driver = { ...@@ -487,31 +475,35 @@ static struct pci_driver i82875p_driver = {
.id_table = i82875p_pci_tbl, .id_table = i82875p_pci_tbl,
}; };
static int __init i82875p_init(void) static int __init i82875p_init(void)
{ {
int pci_rc; int pci_rc;
debugf3("%s()\n", __func__); debugf3("%s()\n", __func__);
pci_rc = pci_register_driver(&i82875p_driver); pci_rc = pci_register_driver(&i82875p_driver);
if (pci_rc < 0) if (pci_rc < 0)
goto fail0; goto fail0;
if (mci_pdev == NULL) { if (mci_pdev == NULL) {
mci_pdev = mci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_0, NULL);
PCI_DEVICE_ID_INTEL_82875_0, NULL);
if (!mci_pdev) { if (!mci_pdev) {
debugf0("875p pci_get_device fail\n"); debugf0("875p pci_get_device fail\n");
pci_rc = -ENODEV; pci_rc = -ENODEV;
goto fail1; goto fail1;
} }
pci_rc = i82875p_init_one(mci_pdev, i82875p_pci_tbl); pci_rc = i82875p_init_one(mci_pdev, i82875p_pci_tbl);
if (pci_rc < 0) { if (pci_rc < 0) {
debugf0("875p init fail\n"); debugf0("875p init fail\n");
pci_rc = -ENODEV; pci_rc = -ENODEV;
goto fail1; goto fail1;
} }
} }
return 0; return 0;
fail1: fail1:
...@@ -524,23 +516,21 @@ static int __init i82875p_init(void) ...@@ -524,23 +516,21 @@ static int __init i82875p_init(void)
return pci_rc; return pci_rc;
} }
static void __exit i82875p_exit(void) static void __exit i82875p_exit(void)
{ {
debugf3("%s()\n", __func__); debugf3("%s()\n", __func__);
pci_unregister_driver(&i82875p_driver); pci_unregister_driver(&i82875p_driver);
if (!i82875p_registered) { if (!i82875p_registered) {
i82875p_remove_one(mci_pdev); i82875p_remove_one(mci_pdev);
pci_dev_put(mci_pdev); pci_dev_put(mci_pdev);
} }
} }
module_init(i82875p_init); module_init(i82875p_init);
module_exit(i82875p_exit); module_exit(i82875p_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh"); MODULE_AUTHOR("Linux Networx (http://lnxi.com) Thayne Harbaugh");
MODULE_DESCRIPTION("MC support for Intel 82875 memory hub controllers"); MODULE_DESCRIPTION("MC support for Intel 82875 memory hub controllers");
...@@ -18,19 +18,16 @@ ...@@ -18,19 +18,16 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/pci_ids.h> #include <linux/pci_ids.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "edac_mc.h" #include "edac_mc.h"
#define r82600_printk(level, fmt, arg...) \ #define r82600_printk(level, fmt, arg...) \
edac_printk(level, "r82600", fmt, ##arg) edac_printk(level, "r82600", fmt, ##arg)
#define r82600_mc_printk(mci, level, fmt, arg...) \ #define r82600_mc_printk(mci, level, fmt, arg...) \
edac_mc_chipset_printk(mci, level, "r82600", fmt, ##arg) edac_mc_chipset_printk(mci, level, "r82600", fmt, ##arg)
/* Radisys say "The 82600 integrates a main memory SDRAM controller that /* Radisys say "The 82600 integrates a main memory SDRAM controller that
* supports up to four banks of memory. The four banks can support a mix of * supports up to four banks of memory. The four banks can support a mix of
...@@ -132,10 +129,8 @@ struct r82600_error_info { ...@@ -132,10 +129,8 @@ struct r82600_error_info {
u32 eapr; u32 eapr;
}; };
static unsigned int disable_hardware_scrub = 0; static unsigned int disable_hardware_scrub = 0;
static void r82600_get_error_info (struct mem_ctl_info *mci, static void r82600_get_error_info (struct mem_ctl_info *mci,
struct r82600_error_info *info) struct r82600_error_info *info)
{ {
...@@ -144,17 +139,16 @@ static void r82600_get_error_info (struct mem_ctl_info *mci, ...@@ -144,17 +139,16 @@ static void r82600_get_error_info (struct mem_ctl_info *mci,
if (info->eapr & BIT(0)) if (info->eapr & BIT(0))
/* Clear error to allow next error to be reported [p.62] */ /* Clear error to allow next error to be reported [p.62] */
pci_write_bits32(mci->pdev, R82600_EAP, pci_write_bits32(mci->pdev, R82600_EAP,
((u32) BIT(0) & (u32) BIT(1)), ((u32) BIT(0) & (u32) BIT(1)),
((u32) BIT(0) & (u32) BIT(1))); ((u32) BIT(0) & (u32) BIT(1)));
if (info->eapr & BIT(1)) if (info->eapr & BIT(1))
/* Clear error to allow next error to be reported [p.62] */ /* Clear error to allow next error to be reported [p.62] */
pci_write_bits32(mci->pdev, R82600_EAP, pci_write_bits32(mci->pdev, R82600_EAP,
((u32) BIT(0) & (u32) BIT(1)), ((u32) BIT(0) & (u32) BIT(1)),
((u32) BIT(0) & (u32) BIT(1))); ((u32) BIT(0) & (u32) BIT(1)));
} }
static int r82600_process_error_info (struct mem_ctl_info *mci, static int r82600_process_error_info (struct mem_ctl_info *mci,
struct r82600_error_info *info, int handle_errors) struct r82600_error_info *info, int handle_errors)
{ {
...@@ -173,26 +167,25 @@ static int r82600_process_error_info (struct mem_ctl_info *mci, ...@@ -173,26 +167,25 @@ static int r82600_process_error_info (struct mem_ctl_info *mci,
* granularity (upper 19 bits only) */ * granularity (upper 19 bits only) */
page = eapaddr >> PAGE_SHIFT; page = eapaddr >> PAGE_SHIFT;
if (info->eapr & BIT(0)) { /* CE? */ if (info->eapr & BIT(0)) { /* CE? */
error_found = 1; error_found = 1;
if (handle_errors) if (handle_errors)
edac_mc_handle_ce( edac_mc_handle_ce(mci, page, 0, /* not avail */
mci, page, 0, /* not avail */ syndrome,
syndrome, edac_mc_find_csrow_by_page(mci, page),
edac_mc_find_csrow_by_page(mci, page), 0, /* channel */
0, /* channel */ mci->ctl_name);
mci->ctl_name);
} }
if (info->eapr & BIT(1)) { /* UE? */ if (info->eapr & BIT(1)) { /* UE? */
error_found = 1; error_found = 1;
if (handle_errors) if (handle_errors)
/* 82600 doesn't give enough info */ /* 82600 doesn't give enough info */
edac_mc_handle_ue(mci, page, 0, edac_mc_handle_ue(mci, page, 0,
edac_mc_find_csrow_by_page(mci, page), edac_mc_find_csrow_by_page(mci, page),
mci->ctl_name); mci->ctl_name);
} }
return error_found; return error_found;
...@@ -222,21 +215,15 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -222,21 +215,15 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx)
struct r82600_error_info discard; struct r82600_error_info discard;
debugf0("%s()\n", __func__); debugf0("%s()\n", __func__);
pci_read_config_byte(pdev, R82600_DRAMC, &dramcr); pci_read_config_byte(pdev, R82600_DRAMC, &dramcr);
pci_read_config_dword(pdev, R82600_EAP, &eapr); pci_read_config_dword(pdev, R82600_EAP, &eapr);
ecc_on = dramcr & BIT(5); ecc_on = dramcr & BIT(5);
reg_sdram = dramcr & BIT(4); reg_sdram = dramcr & BIT(4);
scrub_disabled = eapr & BIT(31); scrub_disabled = eapr & BIT(31);
sdram_refresh_rate = dramcr & (BIT(0) | BIT(1)); sdram_refresh_rate = dramcr & (BIT(0) | BIT(1));
debugf2("%s(): sdram refresh rate = %#0x\n", __func__, debugf2("%s(): sdram refresh rate = %#0x\n", __func__,
sdram_refresh_rate); sdram_refresh_rate);
debugf2("%s(): DRAMC register = %#0x\n", __func__, dramcr); debugf2("%s(): DRAMC register = %#0x\n", __func__, dramcr);
mci = edac_mc_alloc(0, R82600_NR_CSROWS, R82600_NR_CHANS); mci = edac_mc_alloc(0, R82600_NR_CSROWS, R82600_NR_CHANS);
if (mci == NULL) { if (mci == NULL) {
...@@ -245,19 +232,19 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -245,19 +232,19 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx)
} }
debugf0("%s(): mci = %p\n", __func__, mci); debugf0("%s(): mci = %p\n", __func__, mci);
mci->pdev = pdev; mci->pdev = pdev;
mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR; mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR;
mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
/* FIXME try to work out if the chip leads have been * /* FIXME try to work out if the chip leads have been used for COM2
* used for COM2 instead on this board? [MA6?] MAYBE: */ * instead on this board? [MA6?] MAYBE:
*/
/* On the R82600, the pins for memory bits 72:65 - i.e. the * /* On the R82600, the pins for memory bits 72:65 - i.e. the *
* EC bits are shared with the pins for COM2 (!), so if COM2 * * EC bits are shared with the pins for COM2 (!), so if COM2 *
* is enabled, we assume COM2 is wired up, and thus no EDAC * * is enabled, we assume COM2 is wired up, and thus no EDAC *
* is possible. */ * is possible. */
mci->edac_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; mci->edac_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
if (ecc_on) { if (ecc_on) {
if (scrub_disabled) if (scrub_disabled)
debugf3("%s(): mci = %p - Scrubbing disabled! EAP: " debugf3("%s(): mci = %p - Scrubbing disabled! EAP: "
...@@ -295,7 +282,6 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -295,7 +282,6 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx)
continue; continue;
row_base = row_high_limit_last; row_base = row_high_limit_last;
csrow->first_page = row_base >> PAGE_SHIFT; csrow->first_page = row_base >> PAGE_SHIFT;
csrow->last_page = (row_high_limit >> PAGE_SHIFT) - 1; csrow->last_page = (row_high_limit >> PAGE_SHIFT) - 1;
csrow->nr_pages = csrow->last_page - csrow->first_page + 1; csrow->nr_pages = csrow->last_page - csrow->first_page + 1;
...@@ -338,7 +324,7 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) ...@@ -338,7 +324,7 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx)
/* returns count (>= 0), or negative on error */ /* returns count (>= 0), or negative on error */
static int __devinit r82600_init_one(struct pci_dev *pdev, static int __devinit r82600_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
debugf0("%s()\n", __func__); debugf0("%s()\n", __func__);
...@@ -346,7 +332,6 @@ static int __devinit r82600_init_one(struct pci_dev *pdev, ...@@ -346,7 +332,6 @@ static int __devinit r82600_init_one(struct pci_dev *pdev,
return r82600_probe1(pdev, ent->driver_data); return r82600_probe1(pdev, ent->driver_data);
} }
static void __devexit r82600_remove_one(struct pci_dev *pdev) static void __devexit r82600_remove_one(struct pci_dev *pdev)
{ {
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
...@@ -359,15 +344,17 @@ static void __devexit r82600_remove_one(struct pci_dev *pdev) ...@@ -359,15 +344,17 @@ static void __devexit r82600_remove_one(struct pci_dev *pdev)
edac_mc_free(mci); edac_mc_free(mci);
} }
static const struct pci_device_id r82600_pci_tbl[] __devinitdata = { static const struct pci_device_id r82600_pci_tbl[] __devinitdata = {
{PCI_DEVICE(PCI_VENDOR_ID_RADISYS, R82600_BRIDGE_ID)}, {
{0,} /* 0 terminated list. */ PCI_DEVICE(PCI_VENDOR_ID_RADISYS, R82600_BRIDGE_ID)
},
{
0,
} /* 0 terminated list. */
}; };
MODULE_DEVICE_TABLE(pci, r82600_pci_tbl); MODULE_DEVICE_TABLE(pci, r82600_pci_tbl);
static struct pci_driver r82600_driver = { static struct pci_driver r82600_driver = {
.name = EDAC_MOD_STR, .name = EDAC_MOD_STR,
.probe = r82600_init_one, .probe = r82600_init_one,
...@@ -375,26 +362,22 @@ static struct pci_driver r82600_driver = { ...@@ -375,26 +362,22 @@ static struct pci_driver r82600_driver = {
.id_table = r82600_pci_tbl, .id_table = r82600_pci_tbl,
}; };
static int __init r82600_init(void) static int __init r82600_init(void)
{ {
return pci_register_driver(&r82600_driver); return pci_register_driver(&r82600_driver);
} }
static void __exit r82600_exit(void) static void __exit r82600_exit(void)
{ {
pci_unregister_driver(&r82600_driver); pci_unregister_driver(&r82600_driver);
} }
module_init(r82600_init); module_init(r82600_init);
module_exit(r82600_exit); module_exit(r82600_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Tim Small <tim@buttersideup.com> - WPAD Ltd. " MODULE_AUTHOR("Tim Small <tim@buttersideup.com> - WPAD Ltd. "
"on behalf of EADS Astrium"); "on behalf of EADS Astrium");
MODULE_DESCRIPTION("MC support for Radisys 82600 memory controllers"); MODULE_DESCRIPTION("MC support for Radisys 82600 memory controllers");
module_param(disable_hardware_scrub, bool, 0644); module_param(disable_hardware_scrub, bool, 0644);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment