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