static int tpci200_pci_probe()

in carriers/tpci200.c [517:608]


static int tpci200_pci_probe(struct pci_dev *pdev,
			     const struct pci_device_id *id)
{
	int ret, i;
	struct tpci200_board *tpci200;
	u32 reg32;

	tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL);
	if (!tpci200)
		return -ENOMEM;

	tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL);
	if (!tpci200->info) {
		ret = -ENOMEM;
		goto err_tpci200;
	}

	pci_dev_get(pdev);

	/* Obtain a mapping of the carrier's PCI configuration registers */
	ret = pci_request_region(pdev, TPCI200_CFG_MEM_BAR,
				 KBUILD_MODNAME " Configuration Memory");
	if (ret) {
		dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory");
		ret = -EBUSY;
		goto err_tpci200_info;
	}
	tpci200->info->cfg_regs = ioremap(
			pci_resource_start(pdev, TPCI200_CFG_MEM_BAR),
			pci_resource_len(pdev, TPCI200_CFG_MEM_BAR));
	if (!tpci200->info->cfg_regs) {
		dev_err(&pdev->dev, "Failed to map PCI Configuration Memory");
		ret = -EFAULT;
		goto err_request_region;
	}

	/* Disable byte swapping for 16 bit IP module access. This will ensure
	 * that the Industrypack big endian byte order is preserved by the
	 * carrier. */
	reg32 = ioread32(tpci200->info->cfg_regs + LAS1_DESC);
	reg32 |= 1 << LAS_BIT_BIGENDIAN;
	iowrite32(reg32, tpci200->info->cfg_regs + LAS1_DESC);

	reg32 = ioread32(tpci200->info->cfg_regs + LAS2_DESC);
	reg32 |= 1 << LAS_BIT_BIGENDIAN;
	iowrite32(reg32, tpci200->info->cfg_regs + LAS2_DESC);

	/* Save struct pci_dev pointer */
	tpci200->info->pdev = pdev;
	tpci200->info->id_table = (struct pci_device_id *)id;

	/* register the device and initialize it */
	ret = tpci200_install(tpci200);
	if (ret) {
		dev_err(&pdev->dev, "error during tpci200 install\n");
		ret = -ENODEV;
		goto err_cfg_regs;
	}

	/* Register the carrier in the industry pack bus driver */
	tpci200->info->ipack_bus = ipack_bus_register(&pdev->dev,
						      TPCI200_NB_SLOT,
						      &tpci200_bus_ops,
						      THIS_MODULE);
	if (!tpci200->info->ipack_bus) {
		dev_err(&pdev->dev,
			"error registering the carrier on ipack driver\n");
		ret = -EFAULT;
		goto err_tpci200_install;
	}

	/* save the bus number given by ipack to logging purpose */
	tpci200->number = tpci200->info->ipack_bus->bus_nr;
	dev_set_drvdata(&pdev->dev, tpci200);

	for (i = 0; i < TPCI200_NB_SLOT; i++)
		tpci200_create_device(tpci200, i);
	return 0;

err_tpci200_install:
	tpci200_uninstall(tpci200);
err_cfg_regs:
	pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs);
err_request_region:
	pci_release_region(pdev, TPCI200_CFG_MEM_BAR);
err_tpci200_info:
	kfree(tpci200->info);
	pci_dev_put(pdev);
err_tpci200:
	kfree(tpci200);
	return ret;
}