summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pci.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 3c1ff63aa56d..a599a6bbdf37 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2362,12 +2362,20 @@ void pci_enable_acs(struct pci_dev *dev)
static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags)
{
int pos;
- u16 ctrl;
+ u16 cap, ctrl;
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ACS);
if (!pos)
return false;
+ /*
+ * Except for egress control, capabilities are either required
+ * or only required if controllable. Features missing from the
+ * capability field can therefore be assumed as hard-wired enabled.
+ */
+ pci_read_config_word(pdev, pos + PCI_ACS_CAP, &cap);
+ acs_flags &= (cap | PCI_ACS_EC);
+
pci_read_config_word(pdev, pos + PCI_ACS_CTRL, &ctrl);
return (ctrl & acs_flags) == acs_flags;
}
@@ -2442,9 +2450,6 @@ bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags)
if (!pdev->multifunction)
break;
- acs_flags &= (PCI_ACS_RR | PCI_ACS_CR |
- PCI_ACS_EC | PCI_ACS_DT);
-
return pci_acs_flags_enabled(pdev, acs_flags);
}