Instead, use scan_pci_devices() just like VT-d does. This at once allows making {alloc,free}_pdev() static. I have no machine to test this on, which is why I'm sending this as RFC. Signed-off-by: Jan Beulich --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c @@ -121,38 +121,28 @@ static void __init amd_iommu_setup_dom0_ { struct amd_iommu *iommu; struct pci_dev *pdev; - int bus, dev, func; - u32 l; - int bdf; + int bus, devfn, bdf; spin_lock(&pcidevs_lock); for ( bus = 0; bus < 256; bus++ ) { - for ( dev = 0; dev < 32; dev++ ) + for ( devfn = 0; devfn < 256; devfn++ ) { - for ( func = 0; func < 8; func++ ) - { - l = pci_conf_read32(bus, dev, func, PCI_VENDOR_ID); - /* some broken boards return 0 or ~0 if a slot is empty: */ - if ( (l == 0xffffffff) || (l == 0x00000000) || - (l == 0x0000ffff) || (l == 0xffff0000) ) - continue; - - pdev = alloc_pdev(bus, PCI_DEVFN(dev, func)); - pdev->domain = d; - list_add(&pdev->domain_list, &d->arch.pdev_list); - - bdf = (bus << 8) | pdev->devfn; - iommu = find_iommu_for_device(bdf); - - if ( !iommu ) - { - AMD_IOMMU_DEBUG("Fail to find iommu for device" - "%02x:%02x.%x\n", bus, dev, func); - continue; - } + pdev = pci_get_pdev(bus, devfn); + if ( !pdev ) + continue; + + pdev->domain = d; + list_add(&pdev->domain_list, &d->arch.pdev_list); + + bdf = (bus << 8) | devfn; + iommu = find_iommu_for_device(bdf); + + if ( likely(iommu != NULL) ) amd_iommu_setup_domain_device(d, iommu, bdf); - } + else + AMD_IOMMU_DEBUG("No iommu for device %02x:%02x.%x\n", + bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); } } spin_unlock(&pcidevs_lock); @@ -173,7 +163,8 @@ int __init amd_iov_detect(void) printk("Error initialization\n"); return -ENODEV; } - return 0; + + return scan_pci_devices(); } static int allocate_domain_resources(struct hvm_iommu *hd) --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -43,7 +43,7 @@ static struct { /* bus2bridge_lock protects bus2bridge array */ static DEFINE_SPINLOCK(bus2bridge_lock); -struct pci_dev *alloc_pdev(u8 bus, u8 devfn) +static struct pci_dev *alloc_pdev(u8 bus, u8 devfn) { struct pci_dev *pdev; @@ -66,7 +66,7 @@ struct pci_dev *alloc_pdev(u8 bus, u8 de return pdev; } -void free_pdev(struct pci_dev *pdev) +static void free_pdev(struct pci_dev *pdev) { list_del(&pdev->alldevs_list); xfree(pdev); @@ -383,8 +383,7 @@ int pci_device_detect(u8 bus, u8 dev, u8 /* * scan pci devices to add all existed PCI devices to alldevs_list, - * and setup pci hierarchy in array bus2bridge. This function is only - * called in VT-d hardware setup + * and setup pci hierarchy in array bus2bridge. */ int __init scan_pci_devices(void) { --- a/xen/include/xen/pci.h +++ b/xen/include/xen/pci.h @@ -82,8 +82,6 @@ int pci_device_detect(u8 bus, u8 dev, u8 int scan_pci_devices(void); int pdev_type(u8 bus, u8 devfn); int find_upstream_bridge(u8 *bus, u8 *devfn, u8 *secbus); -struct pci_dev *alloc_pdev(u8 bus, u8 devfn); -void free_pdev(struct pci_dev *pdev); struct pci_dev *pci_lock_pdev(int bus, int devfn); struct pci_dev *pci_lock_domain_pdev(struct domain *d, int bus, int devfn);