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); }