in uio_sercos3.c [120:178]
static int sercos3_pci_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
struct uio_info *info;
struct sercos3_priv *priv;
int i;
info = devm_kzalloc(&dev->dev, sizeof(struct uio_info), GFP_KERNEL);
if (!info)
return -ENOMEM;
priv = devm_kzalloc(&dev->dev, sizeof(struct sercos3_priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
if (pci_enable_device(dev))
return -ENODEV;
if (pci_request_regions(dev, "sercos3"))
goto out_disable;
/* we only need PCI BAR's 0, 2, 3, 4, 5 */
if (sercos3_setup_iomem(dev, info, 0, 0))
goto out_unmap;
if (sercos3_setup_iomem(dev, info, 1, 2))
goto out_unmap;
if (sercos3_setup_iomem(dev, info, 2, 3))
goto out_unmap;
if (sercos3_setup_iomem(dev, info, 3, 4))
goto out_unmap;
if (sercos3_setup_iomem(dev, info, 4, 5))
goto out_unmap;
spin_lock_init(&priv->ier0_cache_lock);
info->priv = priv;
info->name = "Sercos_III_PCI";
info->version = "0.0.1";
info->irq = dev->irq;
info->irq_flags = IRQF_SHARED;
info->handler = sercos3_handler;
info->irqcontrol = sercos3_irqcontrol;
pci_set_drvdata(dev, info);
if (uio_register_device(&dev->dev, info))
goto out_unmap;
return 0;
out_unmap:
for (i = 0; i < 5; i++) {
if (info->mem[i].internal_addr)
iounmap(info->mem[i].internal_addr);
}
pci_release_regions(dev);
out_disable:
pci_disable_device(dev);
return -ENODEV;
}