aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2018-08-15 15:58:58 -0400
committerBjorn Helgaas <bhelgaas@google.com>2018-08-15 15:58:58 -0400
commitc689209be23166b340c224df8ecd5deea163da56 (patch)
tree3e7a5ec634d0db624644a79c08e983e38d3ad736
parenteadf3d3209435faa500a8e39ff6181c41ecea29d (diff)
parent10dbc9fedcf151ab794f5e22d4f34f1eff01a08f (diff)
Merge branch 'pci/peer-to-peer'
- Add "pci=disable_acs_redir=" parameter to disable ACS redirection for peer-to-peer DMA support (we don't have the peer-to-peer support yet; this is just one piece) (Logan Gunthorpe) * pci/peer-to-peer: PCI: Add ACS Redirect disable quirk for Intel Sunrise Point PCI: Add device-specific ACS Redirect disable infrastructure PCI: Convert device-specific ACS quirks from NULL termination to ARRAY_SIZE PCI: Add "pci=disable_acs_redir=" parameter for peer-to-peer support PCI: Allow specifying devices using a base bus and path of devfns PCI: Make specifying PCI devices in kernel parameters reusable PCI: Hide ACS quirk declarations inside PCI core
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt41
-rw-r--r--drivers/pci/pci.c309
-rw-r--r--drivers/pci/pci.h19
-rw-r--r--drivers/pci/quirks.c78
-rw-r--r--include/linux/pci.h11
5 files changed, 373 insertions, 85 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index efc7aa7a0670..d5c27d947c2e 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2994,7 +2994,30 @@
2994 See header of drivers/block/paride/pcd.c. 2994 See header of drivers/block/paride/pcd.c.
2995 See also Documentation/blockdev/paride.txt. 2995 See also Documentation/blockdev/paride.txt.
2996 2996
2997 pci=option[,option...] [PCI] various PCI subsystem options: 2997 pci=option[,option...] [PCI] various PCI subsystem options.
2998
2999 Some options herein operate on a specific device
3000 or a set of devices (<pci_dev>). These are
3001 specified in one of the following formats:
3002
3003 [<domain>:]<bus>:<dev>.<func>[/<dev>.<func>]*
3004 pci:<vendor>:<device>[:<subvendor>:<subdevice>]
3005
3006 Note: the first format specifies a PCI
3007 bus/device/function address which may change
3008 if new hardware is inserted, if motherboard
3009 firmware changes, or due to changes caused
3010 by other kernel parameters. If the
3011 domain is left unspecified, it is
3012 taken to be zero. Optionally, a path
3013 to a device through multiple device/function
3014 addresses can be specified after the base
3015 address (this is more robust against
3016 renumbering issues). The second format
3017 selects devices using IDs from the
3018 configuration space which may match multiple
3019 devices in the system.
3020
2998 earlydump [X86] dump PCI config space before the kernel 3021 earlydump [X86] dump PCI config space before the kernel
2999 changes anything 3022 changes anything
3000 off [X86] don't probe for the PCI bus 3023 off [X86] don't probe for the PCI bus
@@ -3123,11 +3146,10 @@
3123 window. The default value is 64 megabytes. 3146 window. The default value is 64 megabytes.
3124 resource_alignment= 3147 resource_alignment=
3125 Format: 3148 Format:
3126 [<order of align>@][<domain>:]<bus>:<slot>.<func>[; ...] 3149 [<order of align>@]<pci_dev>[; ...]
3127 [<order of align>@]pci:<vendor>:<device>\
3128 [:<subvendor>:<subdevice>][; ...]
3129 Specifies alignment and device to reassign 3150 Specifies alignment and device to reassign
3130 aligned memory resources. 3151 aligned memory resources. How to
3152 specify the device is described above.
3131 If <order of align> is not specified, 3153 If <order of align> is not specified,
3132 PAGE_SIZE is used as alignment. 3154 PAGE_SIZE is used as alignment.
3133 PCI-PCI bridge can be specified, if resource 3155 PCI-PCI bridge can be specified, if resource
@@ -3170,6 +3192,15 @@
3170 Adding the window is slightly risky (it may 3192 Adding the window is slightly risky (it may
3171 conflict with unreported devices), so this 3193 conflict with unreported devices), so this
3172 taints the kernel. 3194 taints the kernel.
3195 disable_acs_redir=<pci_dev>[; ...]
3196 Specify one or more PCI devices (in the format
3197 specified above) separated by semicolons.
3198 Each device specified will have the PCI ACS
3199 redirect capabilities forced off which will
3200 allow P2P traffic between devices through
3201 bridges without forcing it upstream. Note:
3202 this removes isolation between devices and
3203 may put more devices in an IOMMU group.
3173 3204
3174 pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power 3205 pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
3175 Management. 3206 Management.
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 0306fa44653a..f68217abc1ef 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -190,6 +190,168 @@ void __iomem *pci_ioremap_wc_bar(struct pci_dev *pdev, int bar)
190EXPORT_SYMBOL_GPL(pci_ioremap_wc_bar); 190EXPORT_SYMBOL_GPL(pci_ioremap_wc_bar);
191#endif 191#endif
192 192
193/**
194 * pci_dev_str_match_path - test if a path string matches a device
195 * @dev: the PCI device to test
196 * @p: string to match the device against
197 * @endptr: pointer to the string after the match
198 *
199 * Test if a string (typically from a kernel parameter) formatted as a
200 * path of device/function addresses matches a PCI device. The string must
201 * be of the form:
202 *
203 * [<domain>:]<bus>:<device>.<func>[/<device>.<func>]*
204 *
205 * A path for a device can be obtained using 'lspci -t'. Using a path
206 * is more robust against bus renumbering than using only a single bus,
207 * device and function address.
208 *
209 * Returns 1 if the string matches the device, 0 if it does not and
210 * a negative error code if it fails to parse the string.
211 */
212static int pci_dev_str_match_path(struct pci_dev *dev, const char *path,
213 const char **endptr)
214{
215 int ret;
216 int seg, bus, slot, func;
217 char *wpath, *p;
218 char end;
219
220 *endptr = strchrnul(path, ';');
221
222 wpath = kmemdup_nul(path, *endptr - path, GFP_KERNEL);
223 if (!wpath)
224 return -ENOMEM;
225
226 while (1) {
227 p = strrchr(wpath, '/');
228 if (!p)
229 break;
230 ret = sscanf(p, "/%x.%x%c", &slot, &func, &end);
231 if (ret != 2) {
232 ret = -EINVAL;
233 goto free_and_exit;
234 }
235
236 if (dev->devfn != PCI_DEVFN(slot, func)) {
237 ret = 0;
238 goto free_and_exit;
239 }
240
241 /*
242 * Note: we don't need to get a reference to the upstream
243 * bridge because we hold a reference to the top level
244 * device which should hold a reference to the bridge,
245 * and so on.
246 */
247 dev = pci_upstream_bridge(dev);
248 if (!dev) {
249 ret = 0;
250 goto free_and_exit;
251 }
252
253 *p = 0;
254 }
255
256 ret = sscanf(wpath, "%x:%x:%x.%x%c", &seg, &bus, &slot,
257 &func, &end);
258 if (ret != 4) {
259 seg = 0;
260 ret = sscanf(wpath, "%x:%x.%x%c", &bus, &slot, &func, &end);
261 if (ret != 3) {
262 ret = -EINVAL;
263 goto free_and_exit;
264 }
265 }
266
267 ret = (seg == pci_domain_nr(dev->bus) &&
268 bus == dev->bus->number &&
269 dev->devfn == PCI_DEVFN(slot, func));
270
271free_and_exit:
272 kfree(wpath);
273 return ret;
274}
275
276/**
277 * pci_dev_str_match - test if a string matches a device
278 * @dev: the PCI device to test
279 * @p: string to match the device against
280 * @endptr: pointer to the string after the match
281 *
282 * Test if a string (typically from a kernel parameter) matches a specified
283 * PCI device. The string may be of one of the following formats:
284 *
285 * [<domain>:]<bus>:<device>.<func>[/<device>.<func>]*
286 * pci:<vendor>:<device>[:<subvendor>:<subdevice>]
287 *
288 * The first format specifies a PCI bus/device/function address which
289 * may change if new hardware is inserted, if motherboard firmware changes,
290 * or due to changes caused in kernel parameters. If the domain is
291 * left unspecified, it is taken to be 0. In order to be robust against
292 * bus renumbering issues, a path of PCI device/function numbers may be used
293 * to address the specific device. The path for a device can be determined
294 * through the use of 'lspci -t'.
295 *
296 * The second format matches devices using IDs in the configuration
297 * space which may match multiple devices in the system. A value of 0
298 * for any field will match all devices. (Note: this differs from
299 * in-kernel code that uses PCI_ANY_ID which is ~0; this is for
300 * legacy reasons and convenience so users don't have to specify
301 * FFFFFFFFs on the command line.)
302 *
303 * Returns 1 if the string matches the device, 0 if it does not and
304 * a negative error code if the string cannot be parsed.
305 */
306static int pci_dev_str_match(struct pci_dev *dev, const char *p,
307 const char **endptr)
308{
309 int ret;
310 int count;
311 unsigned short vendor, device, subsystem_vendor, subsystem_device;
312
313 if (strncmp(p, "pci:", 4) == 0) {
314 /* PCI vendor/device (subvendor/subdevice) IDs are specified */
315 p += 4;
316 ret = sscanf(p, "%hx:%hx:%hx:%hx%n", &vendor, &device,
317 &subsystem_vendor, &subsystem_device, &count);
318 if (ret != 4) {
319 ret = sscanf(p, "%hx:%hx%n", &vendor, &device, &count);
320 if (ret != 2)
321 return -EINVAL;
322
323 subsystem_vendor = 0;
324 subsystem_device = 0;
325 }
326
327 p += count;
328
329 if ((!vendor || vendor == dev->vendor) &&
330 (!device || device == dev->device) &&
331 (!subsystem_vendor ||
332 subsystem_vendor == dev->subsystem_vendor) &&
333 (!subsystem_device ||
334 subsystem_device == dev->subsystem_device))
335 goto found;
336 } else {
337 /*
338 * PCI Bus, Device, Function IDs are specified
339 * (optionally, may include a path of devfns following it)
340 */
341 ret = pci_dev_str_match_path(dev, p, &p);
342 if (ret < 0)
343 return ret;
344 else if (ret)
345 goto found;
346 }
347
348 *endptr = p;
349 return 0;
350
351found:
352 *endptr = p;
353 return 1;
354}
193 355
194static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn, 356static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
195 u8 pos, int cap, int *ttl) 357 u8 pos, int cap, int *ttl)
@@ -2829,6 +2991,66 @@ void pci_request_acs(void)
2829 pci_acs_enable = 1; 2991 pci_acs_enable = 1;
2830} 2992}
2831 2993
2994static const char *disable_acs_redir_param;
2995
2996/**
2997 * pci_disable_acs_redir - disable ACS redirect capabilities
2998 * @dev: the PCI device
2999 *
3000 * For only devices specified in the disable_acs_redir parameter.
3001 */
3002static void pci_disable_acs_redir(struct pci_dev *dev)
3003{
3004 int ret = 0;
3005 const char *p;
3006 int pos;
3007 u16 ctrl;
3008
3009 if (!disable_acs_redir_param)
3010 return;
3011
3012 p = disable_acs_redir_param;
3013 while (*p) {
3014 ret = pci_dev_str_match(dev, p, &p);
3015 if (ret < 0) {
3016 pr_info_once("PCI: Can't parse disable_acs_redir parameter: %s\n",
3017 disable_acs_redir_param);
3018
3019 break;
3020 } else if (ret == 1) {
3021 /* Found a match */
3022 break;
3023 }
3024
3025 if (*p != ';' && *p != ',') {
3026 /* End of param or invalid format */
3027 break;
3028 }
3029 p++;
3030 }
3031
3032 if (ret != 1)
3033 return;
3034
3035 if (!pci_dev_specific_disable_acs_redir(dev))
3036 return;
3037
3038 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
3039 if (!pos) {
3040 pci_warn(dev, "cannot disable ACS redirect for this hardware as it does not have ACS capabilities\n");
3041 return;
3042 }
3043
3044 pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl);
3045
3046 /* P2P Request & Completion Redirect */
3047 ctrl &= ~(PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC);
3048
3049 pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
3050
3051 pci_info(dev, "disabled ACS redirect\n");
3052}
3053
2832/** 3054/**
2833 * pci_std_enable_acs - enable ACS on devices using standard ACS capabilites 3055 * pci_std_enable_acs - enable ACS on devices using standard ACS capabilites
2834 * @dev: the PCI device 3056 * @dev: the PCI device
@@ -2868,12 +3090,22 @@ static void pci_std_enable_acs(struct pci_dev *dev)
2868void pci_enable_acs(struct pci_dev *dev) 3090void pci_enable_acs(struct pci_dev *dev)
2869{ 3091{
2870 if (!pci_acs_enable) 3092 if (!pci_acs_enable)
2871 return; 3093 goto disable_acs_redir;
2872 3094
2873 if (!pci_dev_specific_enable_acs(dev)) 3095 if (!pci_dev_specific_enable_acs(dev))
2874 return; 3096 goto disable_acs_redir;
2875 3097
2876 pci_std_enable_acs(dev); 3098 pci_std_enable_acs(dev);
3099
3100disable_acs_redir:
3101 /*
3102 * Note: pci_disable_acs_redir() must be called even if ACS was not
3103 * enabled by the kernel because it may have been enabled by
3104 * platform firmware. So if we are told to disable it, we should
3105 * always disable it after setting the kernel's default
3106 * preferences.
3107 */
3108 pci_disable_acs_redir(dev);
2877} 3109}
2878 3110
2879static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags) 3111static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags)
@@ -5514,10 +5746,10 @@ static DEFINE_SPINLOCK(resource_alignment_lock);
5514static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev, 5746static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev,
5515 bool *resize) 5747 bool *resize)
5516{ 5748{
5517 int seg, bus, slot, func, align_order, count; 5749 int align_order, count;
5518 unsigned short vendor, device, subsystem_vendor, subsystem_device;
5519 resource_size_t align = pcibios_default_alignment(); 5750 resource_size_t align = pcibios_default_alignment();
5520 char *p; 5751 const char *p;
5752 int ret;
5521 5753
5522 spin_lock(&resource_alignment_lock); 5754 spin_lock(&resource_alignment_lock);
5523 p = resource_alignment_param; 5755 p = resource_alignment_param;
@@ -5537,58 +5769,21 @@ static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev,
5537 } else { 5769 } else {
5538 align_order = -1; 5770 align_order = -1;
5539 } 5771 }
5540 if (strncmp(p, "pci:", 4) == 0) { 5772
5541 /* PCI vendor/device (subvendor/subdevice) ids are specified */ 5773 ret = pci_dev_str_match(dev, p, &p);
5542 p += 4; 5774 if (ret == 1) {
5543 if (sscanf(p, "%hx:%hx:%hx:%hx%n", 5775 *resize = true;
5544 &vendor, &device, &subsystem_vendor, &subsystem_device, &count) != 4) { 5776 if (align_order == -1)
5545 if (sscanf(p, "%hx:%hx%n", &vendor, &device, &count) != 2) { 5777 align = PAGE_SIZE;
5546 printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: pci:%s\n", 5778 else
5547 p); 5779 align = 1 << align_order;
5548 break; 5780 break;
5549 } 5781 } else if (ret < 0) {
5550 subsystem_vendor = subsystem_device = 0; 5782 pr_err("PCI: Can't parse resource_alignment parameter: %s\n",
5551 } 5783 p);
5552 p += count; 5784 break;
5553 if ((!vendor || (vendor == dev->vendor)) &&
5554 (!device || (device == dev->device)) &&
5555 (!subsystem_vendor || (subsystem_vendor == dev->subsystem_vendor)) &&
5556 (!subsystem_device || (subsystem_device == dev->subsystem_device))) {
5557 *resize = true;
5558 if (align_order == -1)
5559 align = PAGE_SIZE;
5560 else
5561 align = 1 << align_order;
5562 /* Found */
5563 break;
5564 }
5565 }
5566 else {
5567 if (sscanf(p, "%x:%x:%x.%x%n",
5568 &seg, &bus, &slot, &func, &count) != 4) {
5569 seg = 0;
5570 if (sscanf(p, "%x:%x.%x%n",
5571 &bus, &slot, &func, &count) != 3) {
5572 /* Invalid format */
5573 printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: %s\n",
5574 p);
5575 break;
5576 }
5577 }
5578 p += count;
5579 if (seg == pci_domain_nr(dev->bus) &&
5580 bus == dev->bus->number &&
5581 slot == PCI_SLOT(dev->devfn) &&
5582 func == PCI_FUNC(dev->devfn)) {
5583 *resize = true;
5584 if (align_order == -1)
5585 align = PAGE_SIZE;
5586 else
5587 align = 1 << align_order;
5588 /* Found */
5589 break;
5590 }
5591 } 5785 }
5786
5592 if (*p != ';' && *p != ',') { 5787 if (*p != ';' && *p != ',') {
5593 /* End of param or invalid format */ 5788 /* End of param or invalid format */
5594 break; 5789 break;
@@ -5901,6 +6096,8 @@ static int __init pci_setup(char *str)
5901 pcie_bus_config = PCIE_BUS_PEER2PEER; 6096 pcie_bus_config = PCIE_BUS_PEER2PEER;
5902 } else if (!strncmp(str, "pcie_scan_all", 13)) { 6097 } else if (!strncmp(str, "pcie_scan_all", 13)) {
5903 pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS); 6098 pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS);
6099 } else if (!strncmp(str, "disable_acs_redir=", 18)) {
6100 disable_acs_redir_param = str + 18;
5904 } else { 6101 } else {
5905 printk(KERN_ERR "PCI: Unknown option `%s'\n", 6102 printk(KERN_ERR "PCI: Unknown option `%s'\n",
5906 str); 6103 str);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index ccb0537d5d89..8907ceb88233 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -400,6 +400,25 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev,
400} 400}
401 401
402void pci_enable_acs(struct pci_dev *dev); 402void pci_enable_acs(struct pci_dev *dev);
403#ifdef CONFIG_PCI_QUIRKS
404int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags);
405int pci_dev_specific_enable_acs(struct pci_dev *dev);
406int pci_dev_specific_disable_acs_redir(struct pci_dev *dev);
407#else
408static inline int pci_dev_specific_acs_enabled(struct pci_dev *dev,
409 u16 acs_flags)
410{
411 return -ENOTTY;
412}
413static inline int pci_dev_specific_enable_acs(struct pci_dev *dev)
414{
415 return -ENOTTY;
416}
417static inline int pci_dev_specific_disable_acs_redir(struct pci_dev *dev)
418{
419 return -ENOTTY;
420}
421#endif
403 422
404/* PCI error reporting and recovery */ 423/* PCI error reporting and recovery */
405void pcie_do_fatal_recovery(struct pci_dev *dev, u32 service); 424void pcie_do_fatal_recovery(struct pci_dev *dev, u32 service);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 2c6d987c271f..eb57d8b610fe 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4555,27 +4555,79 @@ static int pci_quirk_enable_intel_spt_pch_acs(struct pci_dev *dev)
4555 return 0; 4555 return 0;
4556} 4556}
4557 4557
4558static const struct pci_dev_enable_acs { 4558static int pci_quirk_disable_intel_spt_pch_acs_redir(struct pci_dev *dev)
4559{
4560 int pos;
4561 u32 cap, ctrl;
4562
4563 if (!pci_quirk_intel_spt_pch_acs_match(dev))
4564 return -ENOTTY;
4565
4566 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
4567 if (!pos)
4568 return -ENOTTY;
4569
4570 pci_read_config_dword(dev, pos + PCI_ACS_CAP, &cap);
4571 pci_read_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, &ctrl);
4572
4573 ctrl &= ~(PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC);
4574
4575 pci_write_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, ctrl);
4576
4577 pci_info(dev, "Intel SPT PCH root port workaround: disabled ACS redirect\n");
4578
4579 return 0;
4580}
4581
4582static const struct pci_dev_acs_ops {
4559 u16 vendor; 4583 u16 vendor;
4560 u16 device; 4584 u16 device;
4561 int (*enable_acs)(struct pci_dev *dev); 4585 int (*enable_acs)(struct pci_dev *dev);
4562} pci_dev_enable_acs[] = { 4586 int (*disable_acs_redir)(struct pci_dev *dev);
4563 { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_enable_intel_pch_acs }, 4587} pci_dev_acs_ops[] = {
4564 { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_enable_intel_spt_pch_acs }, 4588 { PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
4565 { 0 } 4589 .enable_acs = pci_quirk_enable_intel_pch_acs,
4590 },
4591 { PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
4592 .enable_acs = pci_quirk_enable_intel_spt_pch_acs,
4593 .disable_acs_redir = pci_quirk_disable_intel_spt_pch_acs_redir,
4594 },
4566}; 4595};
4567 4596
4568int pci_dev_specific_enable_acs(struct pci_dev *dev) 4597int pci_dev_specific_enable_acs(struct pci_dev *dev)
4569{ 4598{
4570 const struct pci_dev_enable_acs *i; 4599 const struct pci_dev_acs_ops *p;
4571 int ret; 4600 int i, ret;
4601
4602 for (i = 0; i < ARRAY_SIZE(pci_dev_acs_ops); i++) {
4603 p = &pci_dev_acs_ops[i];
4604 if ((p->vendor == dev->vendor ||
4605 p->vendor == (u16)PCI_ANY_ID) &&
4606 (p->device == dev->device ||
4607 p->device == (u16)PCI_ANY_ID) &&
4608 p->enable_acs) {
4609 ret = p->enable_acs(dev);
4610 if (ret >= 0)
4611 return ret;
4612 }
4613 }
4572 4614
4573 for (i = pci_dev_enable_acs; i->enable_acs; i++) { 4615 return -ENOTTY;
4574 if ((i->vendor == dev->vendor || 4616}
4575 i->vendor == (u16)PCI_ANY_ID) && 4617
4576 (i->device == dev->device || 4618int pci_dev_specific_disable_acs_redir(struct pci_dev *dev)
4577 i->device == (u16)PCI_ANY_ID)) { 4619{
4578 ret = i->enable_acs(dev); 4620 const struct pci_dev_acs_ops *p;
4621 int i, ret;
4622
4623 for (i = 0; i < ARRAY_SIZE(pci_dev_acs_ops); i++) {
4624 p = &pci_dev_acs_ops[i];
4625 if ((p->vendor == dev->vendor ||
4626 p->vendor == (u16)PCI_ANY_ID) &&
4627 (p->device == dev->device ||
4628 p->device == (u16)PCI_ANY_ID) &&
4629 p->disable_acs_redir) {
4630 ret = p->disable_acs_redir(dev);
4579 if (ret >= 0) 4631 if (ret >= 0)
4580 return ret; 4632 return ret;
4581 } 4633 }
diff --git a/include/linux/pci.h b/include/linux/pci.h
index b37f2734f9a2..3dd5b871b895 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1890,20 +1890,9 @@ enum pci_fixup_pass {
1890 1890
1891#ifdef CONFIG_PCI_QUIRKS 1891#ifdef CONFIG_PCI_QUIRKS
1892void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); 1892void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
1893int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags);
1894int pci_dev_specific_enable_acs(struct pci_dev *dev);
1895#else 1893#else
1896static inline void pci_fixup_device(enum pci_fixup_pass pass, 1894static inline void pci_fixup_device(enum pci_fixup_pass pass,
1897 struct pci_dev *dev) { } 1895 struct pci_dev *dev) { }
1898static inline int pci_dev_specific_acs_enabled(struct pci_dev *dev,
1899 u16 acs_flags)
1900{
1901 return -ENOTTY;
1902}
1903static inline int pci_dev_specific_enable_acs(struct pci_dev *dev)
1904{
1905 return -ENOTTY;
1906}
1907#endif 1896#endif
1908 1897
1909void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen); 1898void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);