static int i82975x_probe1()

in i82975x_edac.c [463:586]


static int i82975x_probe1(struct pci_dev *pdev, int dev_idx)
{
	int rc = -ENODEV;
	struct mem_ctl_info *mci;
	struct edac_mc_layer layers[2];
	struct i82975x_pvt *pvt;
	void __iomem *mch_window;
	u32 mchbar;
	u32 drc[2];
	struct i82975x_error_info discard;
	int	chans;
#ifdef i82975x_DEBUG_IOMEM
	u8 c0drb[4];
	u8 c1drb[4];
#endif

	edac_dbg(0, "\n");

	pci_read_config_dword(pdev, I82975X_MCHBAR, &mchbar);
	if (!(mchbar & 1)) {
		edac_dbg(3, "failed, MCHBAR disabled!\n");
		goto fail0;
	}
	mchbar &= 0xffffc000;	/* bits 31:14 used for 16K window */
	mch_window = ioremap(mchbar, 0x1000);
	if (!mch_window) {
		edac_dbg(3, "error ioremapping MCHBAR!\n");
		goto fail0;
	}

#ifdef i82975x_DEBUG_IOMEM
	i82975x_printk(KERN_INFO, "MCHBAR real = %0x, remapped = %p\n",
					mchbar, mch_window);

	c0drb[0] = readb(mch_window + I82975X_DRB_CH0R0);
	c0drb[1] = readb(mch_window + I82975X_DRB_CH0R1);
	c0drb[2] = readb(mch_window + I82975X_DRB_CH0R2);
	c0drb[3] = readb(mch_window + I82975X_DRB_CH0R3);
	c1drb[0] = readb(mch_window + I82975X_DRB_CH1R0);
	c1drb[1] = readb(mch_window + I82975X_DRB_CH1R1);
	c1drb[2] = readb(mch_window + I82975X_DRB_CH1R2);
	c1drb[3] = readb(mch_window + I82975X_DRB_CH1R3);
	i82975x_printk(KERN_INFO, "DRBCH0R0 = 0x%02x\n", c0drb[0]);
	i82975x_printk(KERN_INFO, "DRBCH0R1 = 0x%02x\n", c0drb[1]);
	i82975x_printk(KERN_INFO, "DRBCH0R2 = 0x%02x\n", c0drb[2]);
	i82975x_printk(KERN_INFO, "DRBCH0R3 = 0x%02x\n", c0drb[3]);
	i82975x_printk(KERN_INFO, "DRBCH1R0 = 0x%02x\n", c1drb[0]);
	i82975x_printk(KERN_INFO, "DRBCH1R1 = 0x%02x\n", c1drb[1]);
	i82975x_printk(KERN_INFO, "DRBCH1R2 = 0x%02x\n", c1drb[2]);
	i82975x_printk(KERN_INFO, "DRBCH1R3 = 0x%02x\n", c1drb[3]);
#endif

	drc[0] = readl(mch_window + I82975X_DRC_CH0M0);
	drc[1] = readl(mch_window + I82975X_DRC_CH1M0);
#ifdef i82975x_DEBUG_IOMEM
	i82975x_printk(KERN_INFO, "DRC_CH0 = %0x, %s\n", drc[0],
			((drc[0] >> 21) & 3) == 1 ?
				"ECC enabled" : "ECC disabled");
	i82975x_printk(KERN_INFO, "DRC_CH1 = %0x, %s\n", drc[1],
			((drc[1] >> 21) & 3) == 1 ?
				"ECC enabled" : "ECC disabled");

	i82975x_printk(KERN_INFO, "C0 BNKARC = %0x\n",
		readw(mch_window + I82975X_C0BNKARC));
	i82975x_printk(KERN_INFO, "C1 BNKARC = %0x\n",
		readw(mch_window + I82975X_C1BNKARC));
	i82975x_print_dram_timings(mch_window);
	goto fail1;
#endif
	if (!(((drc[0] >> 21) & 3) == 1 || ((drc[1] >> 21) & 3) == 1)) {
		i82975x_printk(KERN_INFO, "ECC disabled on both channels.\n");
		goto fail1;
	}

	chans = dual_channel_active(mch_window) + 1;

	/* assuming only one controller, index thus is 0 */
	layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
	layers[0].size = I82975X_NR_DIMMS;
	layers[0].is_virt_csrow = true;
	layers[1].type = EDAC_MC_LAYER_CHANNEL;
	layers[1].size = I82975X_NR_CSROWS(chans);
	layers[1].is_virt_csrow = false;
	mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, sizeof(*pvt));
	if (!mci) {
		rc = -ENOMEM;
		goto fail1;
	}

	edac_dbg(3, "init mci\n");
	mci->pdev = &pdev->dev;
	mci->mtype_cap = MEM_FLAG_DDR2;
	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
	mci->edac_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
	mci->mod_name = EDAC_MOD_STR;
	mci->ctl_name = i82975x_devs[dev_idx].ctl_name;
	mci->dev_name = pci_name(pdev);
	mci->edac_check = i82975x_check;
	mci->ctl_page_to_phys = NULL;
	edac_dbg(3, "init pvt\n");
	pvt = (struct i82975x_pvt *) mci->pvt_info;
	pvt->mch_window = mch_window;
	i82975x_init_csrows(mci, pdev, mch_window);
	mci->scrub_mode = SCRUB_HW_SRC;
	i82975x_get_error_info(mci, &discard);  /* clear counters */

	/* finalize this instance of memory controller with edac core */
	if (edac_mc_add_mc(mci)) {
		edac_dbg(3, "failed edac_mc_add_mc()\n");
		goto fail2;
	}

	/* get this far and it's successful */
	edac_dbg(3, "success\n");
	return 0;

fail2:
	edac_mc_free(mci);

fail1:
	iounmap(mch_window);
fail0:
	return rc;
}