X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fedac%2Fi82443bxgx_edac.c;h=c5305e3ee4346932b44cc73074cb6718bd3a38ad;hb=4b1295b0df28cffd40e6c6d7c4b88dec7af1eb76;hp=c0070aba87bb0adc85e4c0757e936ba347b8d7c4;hpb=11116601092c42364892d3f59c8f4a8a30916867;p=linux-2.6 diff --git a/drivers/edac/i82443bxgx_edac.c b/drivers/edac/i82443bxgx_edac.c index c0070aba87..c5305e3ee4 100644 --- a/drivers/edac/i82443bxgx_edac.c +++ b/drivers/edac/i82443bxgx_edac.c @@ -29,6 +29,7 @@ #include +#include #include "edac_core.h" #define I82443_REVISION "0.1" @@ -111,9 +112,11 @@ struct i82443bxgx_edacmc_error_info { 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); @@ -149,17 +152,18 @@ static int i82443bxgx_edacmc_process_error_info(struct mem_ctl_info *mci, 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; @@ -175,9 +179,9 @@ static void i82443bxgx_edacmc_check(struct mem_ctl_info *mci) } 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; @@ -231,11 +235,12 @@ static int i82443bxgx_edacmc_probe1(struct pci_dev *pdev, int dev_idx) 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; @@ -256,8 +261,8 @@ static int i82443bxgx_edacmc_probe1(struct pci_dev *pdev, int dev_idx) 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; } @@ -269,10 +274,10 @@ static int i82443bxgx_edacmc_probe1(struct pci_dev *pdev, int dev_idx) 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: @@ -286,9 +291,8 @@ static int i82443bxgx_edacmc_probe1(struct pci_dev *pdev, int dev_idx) 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; } @@ -299,10 +303,10 @@ static int i82443bxgx_edacmc_probe1(struct pci_dev *pdev, int dev_idx) * 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; @@ -311,15 +315,26 @@ static int i82443bxgx_edacmc_probe1(struct pci_dev *pdev, int dev_idx) 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; } @@ -342,6 +357,9 @@ static void __devexit i82443bxgx_edacmc_remove_one(struct pci_dev *pdev) 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; @@ -369,6 +387,9 @@ static struct pci_driver i82443bxgx_edacmc_driver = { 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); } @@ -383,3 +404,6 @@ module_exit(i82443bxgx_edacmc_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Tim Small - 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");