|
@@ -287,14 +287,27 @@ static struct pci_dev *get_isolation_root(struct pci_dev *pdev)
|
|
|
|
|
|
/*
|
|
|
* If it's a multifunction device that does not support our
|
|
|
- * required ACS flags, add to the same group as function 0.
|
|
|
+ * required ACS flags, add to the same group as lowest numbered
|
|
|
+ * function that also does not suport the required ACS flags.
|
|
|
*/
|
|
|
if (dma_pdev->multifunction &&
|
|
|
- !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS))
|
|
|
- swap_pci_ref(&dma_pdev,
|
|
|
- pci_get_slot(dma_pdev->bus,
|
|
|
- PCI_DEVFN(PCI_SLOT(dma_pdev->devfn),
|
|
|
- 0)));
|
|
|
+ !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) {
|
|
|
+ u8 i, slot = PCI_SLOT(dma_pdev->devfn);
|
|
|
+
|
|
|
+ for (i = 0; i < 8; i++) {
|
|
|
+ struct pci_dev *tmp;
|
|
|
+
|
|
|
+ tmp = pci_get_slot(dma_pdev->bus, PCI_DEVFN(slot, i));
|
|
|
+ if (!tmp)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (!pci_acs_enabled(tmp, REQ_ACS_FLAGS)) {
|
|
|
+ swap_pci_ref(&dma_pdev, tmp);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pci_dev_put(tmp);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
|
* Devices on the root bus go through the iommu. If that's not us,
|