static int ivshmem_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct uio_info *info; struct ivshmem_info *ivshmem_info; int nvectors = 4; info = kzalloc(sizeof(struct uio_info), GFP_KERNEL); if (!info) return -ENOMEM; ivshmem_info = kzalloc(sizeof(struct ivshmem_info), GFP_KERNEL); if (!ivshmem_info) { kfree(info); return -ENOMEM; } if (pci_enable_device(dev)) goto out_free; if (pci_request_regions(dev, "ivshmem")) goto out_disable; info->mem[0].addr = pci_resource_start(dev, 0); if (!info->mem[0].addr) goto out_release; info->mem[0].size = (pci_resource_len(dev, 0) + PAGE_SIZE - 1) & PAGE_MASK; info->mem[0].internal_addr = pci_ioremap_bar(dev, 0); if (!info->mem[0].internal_addr) goto out_release; info->mem[0].memtype = UIO_MEM_PHYS; info->mem[0].name = "registers"; info->mem[1].addr = pci_resource_start(dev, 2); if (!info->mem[1].addr) goto out_unmap; info->mem[1].size = pci_resource_len(dev, 2); info->mem[1].memtype = UIO_MEM_PHYS; info->mem[1].name = "shmem"; ivshmem_info->uio = info; ivshmem_info->dev = dev; if (request_msix_vectors(ivshmem_info, nvectors) != 0) { dev_info(&ivshmem_info->dev->dev, "regular IRQs\n"); info->irq = dev->irq; info->irq_flags = IRQF_SHARED; info->handler = ivshmem_handler; writel(0xffffffff, info->mem[0].internal_addr + IntrMask); } else { dev_info(&ivshmem_info->dev->dev, "MSI-X enabled\n"); pci_set_master(dev); info->irq = -1; } info->name = "ivshmem"; info->version = "0.0.1"; if (uio_register_device(&dev->dev, info)) goto out_unmap; pci_set_drvdata(dev, ivshmem_info); return 0; out_unmap: iounmap(info->mem[0].internal_addr); out_release: pci_release_regions(dev); out_disable: pci_disable_device(dev); out_free: kfree(ivshmem_info); kfree(info); return -ENODEV; }
static int #if(LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) __devinit #endif ivshmem_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct uio_info *info; struct ivshmem_info * ivshmem_info; #ifdef IRQ_SUPPORT int nvectors = 4; #endif info = kzalloc(sizeof(struct uio_info), GFP_KERNEL); if (!info) return -ENOMEM; ivshmem_info = kzalloc(sizeof(struct ivshmem_info), GFP_KERNEL); if (!ivshmem_info) { kfree(info); return -ENOMEM; } if (pci_enable_device(dev)) goto out_free; if (pci_request_regions(dev, "ivshmem")) goto out_disable; info->mem[0].addr = pci_resource_start(dev, 0); if (!info->mem[0].addr) goto out_release; info->mem[0].size = pci_resource_len(dev, 0); info->mem[0].internal_addr = pci_ioremap_bar(dev, 0); if (!info->mem[0].internal_addr) { goto out_release; } info->mem[0].memtype = UIO_MEM_PHYS; info->mem[1].addr = pci_resource_start(dev, 2); if (!info->mem[1].addr) goto out_unmap; info->mem[1].internal_addr = ioremap_cache(pci_resource_start(dev, 2), pci_resource_len(dev, 2)); if (!info->mem[1].internal_addr) goto out_unmap; #if 0 info->mem[1].internal_addr = pci_ioremap_bar(dev, 2); if (!info->mem[1].internal_addr) goto out_unmap; #endif info->mem[1].size = pci_resource_len(dev, 2); info->mem[1].memtype = UIO_MEM_PHYS; ivshmem_info->uio = info; ivshmem_info->dev = dev; #ifdef IRQ_SUPPORT if (request_msix_vectors(ivshmem_info, nvectors) != 0) { printk(KERN_INFO "regular IRQs\n"); info->irq = dev->irq; info->irq_flags = IRQF_SHARED; info->handler = ivshmem_handler; writel(0xffffffff, info->mem[0].internal_addr + IntrMask); } else { printk(KERN_INFO "MSI-X enabled\n"); info->irq = -1; } #else info->irq = -1; #endif info->name = "ivshmem"; info->version = "0.0.1"; if (uio_register_device(&dev->dev, info)) goto out_unmap2; pci_set_drvdata(dev, info); return 0; out_unmap2: iounmap(info->mem[2].internal_addr); out_unmap: iounmap(info->mem[0].internal_addr); out_release: pci_release_regions(dev); out_disable: pci_disable_device(dev); out_free: kfree (info); return -ENODEV; }