#include <linux/slab.h>
+#include <linux/edac.h>
#include "edac_core.h"
#define I82443_REVISION "0.1"
u32 eap;
};
+static struct edac_pci_ctl_info *i82443bxgx_pci;
+
static void i82443bxgx_edacmc_get_error_info(struct mem_ctl_info *mci,
- struct i82443bxgx_edacmc_error_info
- *info)
+ struct i82443bxgx_edacmc_error_info
+ *info)
{
struct pci_dev *pdev;
pdev = to_pci_dev(mci->dev);
error_found = 1;
if (handle_errors)
edac_mc_handle_ce(mci, page, pageoffset,
- /* 440BX/GX don't make syndrome information available */
- 0, edac_mc_find_csrow_by_page(mci, page), 0, /* channel */
- mci->ctl_name);
+ /* 440BX/GX don't make syndrome information
+ * available */
+ 0, edac_mc_find_csrow_by_page(mci, page), 0,
+ mci->ctl_name);
}
if (info->eap & I82443BXGX_EAP_OFFSET_MBE) {
error_found = 1;
if (handle_errors)
edac_mc_handle_ue(mci, page, pageoffset,
- edac_mc_find_csrow_by_page(mci, page),
- mci->ctl_name);
+ edac_mc_find_csrow_by_page(mci, page),
+ mci->ctl_name);
}
return error_found;
}
static void i82443bxgx_init_csrows(struct mem_ctl_info *mci,
- struct pci_dev *pdev,
- enum edac_type edac_mode,
- enum mem_type mtype)
+ struct pci_dev *pdev,
+ enum edac_type edac_mode,
+ enum mem_type mtype)
{
struct csrow_info *csrow;
int index;
debugf0("MC: " __FILE__ ": %s()\n", __func__);
/* Something is really hosed if PCI config space reads from
- the MC aren't working. */
+ * the MC aren't working.
+ */
if (pci_read_config_dword(pdev, I82443BXGX_NBXCFG, &nbxcfg))
return -EIO;
- mci = edac_mc_alloc(0, I82443BXGX_NR_CSROWS, I82443BXGX_NR_CHANS);
+ mci = edac_mc_alloc(0, I82443BXGX_NR_CSROWS, I82443BXGX_NR_CHANS, 0);
if (mci == NULL)
return -ENOMEM;
mtype = MEM_RDR;
break;
default:
- debugf0
- ("Unknown/reserved DRAM type value in DRAMC register!\n");
+ debugf0("Unknown/reserved DRAM type value "
+ "in DRAMC register!\n");
mtype = -MEM_UNKNOWN;
}
mci->scrub_cap = SCRUB_FLAG_HW_SRC;
pci_read_config_dword(pdev, I82443BXGX_NBXCFG, &nbxcfg);
ecc_mode = ((nbxcfg >> I82443BXGX_NBXCFG_OFFSET_DRAM_INTEGRITY) &
- (BIT(0) | BIT(1)));
+ (BIT(0) | BIT(1)));
mci->scrub_mode = (ecc_mode == I82443BXGX_NBXCFG_INTEGRITY_SCRUB)
- ? SCRUB_HW_SRC : SCRUB_NONE;
+ ? SCRUB_HW_SRC : SCRUB_NONE;
switch (ecc_mode) {
case I82443BXGX_NBXCFG_INTEGRITY_NONE:
edac_mode = EDAC_SECDED;
break;
default:
- debugf0
- ("%s(): Unknown/reserved ECC state in NBXCFG register!\n",
- __func__);
+ debugf0("%s(): Unknown/reserved ECC state "
+ "in NBXCFG register!\n", __func__);
edac_mode = EDAC_UNKNOWN;
break;
}
* here, or we get "phantom" errors occuring at module-load
* time. */
pci_write_bits32(pdev, I82443BXGX_EAP,
- (I82443BXGX_EAP_OFFSET_SBE |
- I82443BXGX_EAP_OFFSET_MBE),
- (I82443BXGX_EAP_OFFSET_SBE |
- I82443BXGX_EAP_OFFSET_MBE));
+ (I82443BXGX_EAP_OFFSET_SBE |
+ I82443BXGX_EAP_OFFSET_MBE),
+ (I82443BXGX_EAP_OFFSET_SBE |
+ I82443BXGX_EAP_OFFSET_MBE));
mci->mod_name = EDAC_MOD_STR;
mci->mod_ver = I82443_REVISION;
mci->edac_check = i82443bxgx_edacmc_check;
mci->ctl_page_to_phys = NULL;
- if (edac_mc_add_mc(mci, 0)) {
+ if (edac_mc_add_mc(mci)) {
debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
goto fail;
}
+ /* allocating generic PCI control info */
+ i82443bxgx_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR);
+ if (!i82443bxgx_pci) {
+ printk(KERN_WARNING
+ "%s(): Unable to create PCI control\n",
+ __func__);
+ printk(KERN_WARNING
+ "%s(): PCI error report via EDAC not setup\n",
+ __func__);
+ }
+
debugf3("MC: " __FILE__ ": %s(): success\n", __func__);
return 0;
- fail:
+fail:
edac_mc_free(mci);
return -ENODEV;
}
debugf0(__FILE__ ": %s()\n", __func__);
+ if (i82443bxgx_pci)
+ edac_pci_release_generic_ctl(i82443bxgx_pci);
+
if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL)
return;
static int __init i82443bxgx_edacmc_init(void)
{
+ /* Ensure that the OPSTATE is set correctly for POLL or NMI */
+ opstate_init();
+
return pci_register_driver(&i82443bxgx_edacmc_driver);
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Tim Small <tim@buttersideup.com> - WPAD");
MODULE_DESCRIPTION("EDAC MC support for Intel 82443BX/GX memory controllers");
+
+module_param(edac_op_state, int, 0444);
+MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");