in platform-pci.c [92:169]
static int platform_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
int i, ret;
long ioaddr;
long mmio_addr, mmio_len;
unsigned int max_nr_gframes;
unsigned long grant_frames;
if (!xen_domain())
return -ENODEV;
i = pci_enable_device(pdev);
if (i)
return i;
ioaddr = pci_resource_start(pdev, 0);
mmio_addr = pci_resource_start(pdev, 1);
mmio_len = pci_resource_len(pdev, 1);
if (mmio_addr == 0 || ioaddr == 0) {
dev_err(&pdev->dev, "no resources found\n");
ret = -ENOENT;
goto pci_out;
}
ret = pci_request_region(pdev, 1, DRV_NAME);
if (ret < 0)
goto pci_out;
ret = pci_request_region(pdev, 0, DRV_NAME);
if (ret < 0)
goto mem_out;
platform_mmio = mmio_addr;
platform_mmiolen = mmio_len;
if (!xen_have_vector_callback) {
ret = xen_allocate_irq(pdev);
if (ret) {
dev_warn(&pdev->dev, "request_irq failed err=%d\n", ret);
goto out;
}
/*
* It doesn't strictly *have* to run on CPU0 but it sure
* as hell better process the event channel ports delivered
* to CPU0.
*/
irq_set_affinity(pdev->irq, cpumask_of(0));
callback_via = get_callback_via(pdev);
ret = xen_set_callback_via(callback_via);
if (ret) {
dev_warn(&pdev->dev, "Unable to set the evtchn callback "
"err=%d\n", ret);
goto out;
}
}
max_nr_gframes = gnttab_max_grant_frames();
grant_frames = alloc_xen_mmio(PAGE_SIZE * max_nr_gframes);
ret = gnttab_setup_auto_xlat_frames(grant_frames);
if (ret)
goto out;
ret = gnttab_init();
if (ret)
goto grant_out;
return 0;
grant_out:
gnttab_free_auto_xlat_frames();
out:
pci_release_region(pdev, 0);
mem_out:
pci_release_region(pdev, 1);
pci_out:
pci_disable_device(pdev);
return ret;
}