diff options
author | Alex Williamson <alex.williamson@redhat.com> | 2014-02-03 16:27:33 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-02-11 15:49:56 -0500 |
commit | 2c74424470a0f98df8d6540642aff96d1a0b94b3 (patch) | |
tree | 61f24a066645ddd7884d8545b579e0754c2763ce /drivers/pci/pci.c | |
parent | 38dbfb59d1175ef458d006556061adeaa8751b72 (diff) |
PCI: Add device-specific PCI ACS enable
Some devices support PCI ACS-like features, but don't report it using the
standard PCIe capabilities. We already provide hooks for device-specific
testing of ACS, but not for device-specific enabling of ACS. This provides
that setup hook.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1febe90831b4..b89502ff3139 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -2180,21 +2180,18 @@ void pci_request_acs(void) | |||
2180 | } | 2180 | } |
2181 | 2181 | ||
2182 | /** | 2182 | /** |
2183 | * pci_enable_acs - enable ACS if hardware support it | 2183 | * pci_std_enable_acs - enable ACS on devices using standard ACS capabilites |
2184 | * @dev: the PCI device | 2184 | * @dev: the PCI device |
2185 | */ | 2185 | */ |
2186 | void pci_enable_acs(struct pci_dev *dev) | 2186 | static int pci_std_enable_acs(struct pci_dev *dev) |
2187 | { | 2187 | { |
2188 | int pos; | 2188 | int pos; |
2189 | u16 cap; | 2189 | u16 cap; |
2190 | u16 ctrl; | 2190 | u16 ctrl; |
2191 | 2191 | ||
2192 | if (!pci_acs_enable) | ||
2193 | return; | ||
2194 | |||
2195 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS); | 2192 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS); |
2196 | if (!pos) | 2193 | if (!pos) |
2197 | return; | 2194 | return -ENODEV; |
2198 | 2195 | ||
2199 | pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap); | 2196 | pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap); |
2200 | pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl); | 2197 | pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl); |
@@ -2212,6 +2209,23 @@ void pci_enable_acs(struct pci_dev *dev) | |||
2212 | ctrl |= (cap & PCI_ACS_UF); | 2209 | ctrl |= (cap & PCI_ACS_UF); |
2213 | 2210 | ||
2214 | pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl); | 2211 | pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl); |
2212 | |||
2213 | return 0; | ||
2214 | } | ||
2215 | |||
2216 | /** | ||
2217 | * pci_enable_acs - enable ACS if hardware support it | ||
2218 | * @dev: the PCI device | ||
2219 | */ | ||
2220 | void pci_enable_acs(struct pci_dev *dev) | ||
2221 | { | ||
2222 | if (!pci_acs_enable) | ||
2223 | return; | ||
2224 | |||
2225 | if (!pci_std_enable_acs(dev)) | ||
2226 | return; | ||
2227 | |||
2228 | pci_dev_specific_enable_acs(dev); | ||
2215 | } | 2229 | } |
2216 | 2230 | ||
2217 | static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags) | 2231 | static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags) |