static int i82443bxgx_edacmc_probe1()

in i82443bxgx_edac.c [231:347]


static int i82443bxgx_edacmc_probe1(struct pci_dev *pdev, int dev_idx)
{
	struct mem_ctl_info *mci;
	struct edac_mc_layer layers[2];
	u8 dramc;
	u32 nbxcfg, ecc_mode;
	enum mem_type mtype;
	enum edac_type edac_mode;

	edac_dbg(0, "MC:\n");

	/* Something is really hosed if PCI config space reads from
	 * the MC aren't working.
	 */
	if (pci_read_config_dword(pdev, I82443BXGX_NBXCFG, &nbxcfg))
		return -EIO;

	layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
	layers[0].size = I82443BXGX_NR_CSROWS;
	layers[0].is_virt_csrow = true;
	layers[1].type = EDAC_MC_LAYER_CHANNEL;
	layers[1].size = I82443BXGX_NR_CHANS;
	layers[1].is_virt_csrow = false;
	mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, 0);
	if (mci == NULL)
		return -ENOMEM;

	edac_dbg(0, "MC: mci = %p\n", mci);
	mci->pdev = &pdev->dev;
	mci->mtype_cap = MEM_FLAG_EDO | MEM_FLAG_SDR | MEM_FLAG_RDR;
	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
	pci_read_config_byte(pdev, I82443BXGX_DRAMC, &dramc);
	switch ((dramc >> I82443BXGX_DRAMC_OFFSET_DT) & (BIT(0) | BIT(1))) {
	case I82443BXGX_DRAMC_DRAM_IS_EDO:
		mtype = MEM_EDO;
		break;
	case I82443BXGX_DRAMC_DRAM_IS_SDRAM:
		mtype = MEM_SDR;
		break;
	case I82443BXGX_DRAMC_DRAM_IS_RSDRAM:
		mtype = MEM_RDR;
		break;
	default:
		edac_dbg(0, "Unknown/reserved DRAM type value in DRAMC register!\n");
		mtype = -MEM_UNKNOWN;
	}

	if ((mtype == MEM_SDR) || (mtype == MEM_RDR))
		mci->edac_cap = mci->edac_ctl_cap;
	else
		mci->edac_cap = EDAC_FLAG_NONE;

	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)));

	mci->scrub_mode = (ecc_mode == I82443BXGX_NBXCFG_INTEGRITY_SCRUB)
		? SCRUB_HW_SRC : SCRUB_NONE;

	switch (ecc_mode) {
	case I82443BXGX_NBXCFG_INTEGRITY_NONE:
		edac_mode = EDAC_NONE;
		break;
	case I82443BXGX_NBXCFG_INTEGRITY_EC:
		edac_mode = EDAC_EC;
		break;
	case I82443BXGX_NBXCFG_INTEGRITY_ECC:
	case I82443BXGX_NBXCFG_INTEGRITY_SCRUB:
		edac_mode = EDAC_SECDED;
		break;
	default:
		edac_dbg(0, "Unknown/reserved ECC state in NBXCFG register!\n");
		edac_mode = EDAC_UNKNOWN;
		break;
	}

	i82443bxgx_init_csrows(mci, pdev, edac_mode, mtype);

	/* Many BIOSes don't clear error flags on boot, so do this
	 * here, or we get "phantom" errors occurring 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));

	mci->mod_name = EDAC_MOD_STR;
	mci->ctl_name = "I82443BXGX";
	mci->dev_name = pci_name(pdev);
	mci->edac_check = i82443bxgx_edacmc_check;
	mci->ctl_page_to_phys = NULL;

	if (edac_mc_add_mc(mci)) {
		edac_dbg(3, "failed edac_mc_add_mc()\n");
		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__);
	}

	edac_dbg(3, "MC: success\n");
	return 0;

fail:
	edac_mc_free(mci);
	return -ENODEV;
}