priv = devm_kzalloc(&pdev->dev, sizeof(struct priv), GFP_KERNEL); if (!priv) return -ENOMEM;
ret = pci_enable_device(pdev); if (ret) {
dev_err(&pdev->dev, "Failed to enable PCI device\n"); return -ENODEV;
}
pci_set_master(pdev);
flags = pci_resource_flags(pdev, 0); if (flags & IORESOURCE_IO) {
ret = -ENOTSUPP;
dev_err(&pdev->dev, "IO mapped PCI devices are not supported\n"); goto out_disable;
}
priv->mapbase = pci_resource_start(pdev, 0); if (!priv->mapbase) {
dev_err(&pdev->dev, "No PCI resource\n");
ret = -ENODEV; goto out_disable;
}
res = devm_request_mem_region(&pdev->dev, priv->mapbase,
CHAM_HEADER_SIZE,
KBUILD_MODNAME); if (!res) {
dev_err(&pdev->dev, "Failed to request PCI memory\n");
ret = -EBUSY; goto out_disable;
}
priv->base = devm_ioremap(&pdev->dev, priv->mapbase, CHAM_HEADER_SIZE); if (!priv->base) {
dev_err(&pdev->dev, "Cannot ioremap\n");
ret = -ENOMEM; goto out_disable;
}
pci_set_drvdata(pdev, priv);
priv->bus = mcb_alloc_bus(&pdev->dev); if (IS_ERR(priv->bus)) {
ret = PTR_ERR(priv->bus); goto out_disable;
}
priv->bus->get_irq = mcb_pci_get_irq;
ret = chameleon_parse_cells(priv->bus, priv->mapbase, priv->base); if (ret < 0) goto out_mcb_bus;
table_size = ret;
if (table_size < CHAM_HEADER_SIZE) { /* Release the previous resources */
devm_iounmap(&pdev->dev, priv->base);
devm_release_mem_region(&pdev->dev, priv->mapbase, CHAM_HEADER_SIZE);
/* Then, allocate it again with the actual chameleon table size */
res = devm_request_mem_region(&pdev->dev, priv->mapbase,
table_size,
KBUILD_MODNAME); if (!res) {
dev_err(&pdev->dev, "Failed to request PCI memory\n");
ret = -EBUSY; goto out_mcb_bus;
}
priv->base = devm_ioremap(&pdev->dev, priv->mapbase, table_size); if (!priv->base) {
dev_err(&pdev->dev, "Cannot ioremap\n");
ret = -ENOMEM; goto out_mcb_bus;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.