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