summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pci.c3
-rw-r--r--drivers/pci/pci.h5
-rw-r--r--drivers/pci/quirks.c43
3 files changed, 43 insertions, 8 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 822577d9b39e..17d8de109556 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3023,6 +3023,9 @@ static void pci_disable_acs_redir(struct pci_dev *dev)
if (ret != 1)
return;
+ if (!pci_dev_specific_disable_acs_redir(dev))
+ return;
+
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
if (!pos) {
pci_warn(dev, "cannot disable ACS redirect for this hardware as it does not have ACS capabilities\n");
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index a1224fef3409..04f5035d12c6 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -355,6 +355,7 @@ void pci_enable_acs(struct pci_dev *dev);
#ifdef CONFIG_PCI_QUIRKS
int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags);
int pci_dev_specific_enable_acs(struct pci_dev *dev);
+int pci_dev_specific_disable_acs_redir(struct pci_dev *dev);
#else
static inline int pci_dev_specific_acs_enabled(struct pci_dev *dev,
u16 acs_flags)
@@ -365,6 +366,10 @@ static inline int pci_dev_specific_enable_acs(struct pci_dev *dev)
{
return -ENOTTY;
}
+static inline int pci_dev_specific_disable_acs_redir(struct pci_dev *dev)
+{
+ return -ENOTTY;
+}
#endif
/* PCI error reporting and recovery */
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 823d8e4b4b37..4f79631159eb 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4553,26 +4553,32 @@ static int pci_quirk_enable_intel_spt_pch_acs(struct pci_dev *dev)
return 0;
}
-static const struct pci_dev_enable_acs {
+static const struct pci_dev_acs_ops {
u16 vendor;
u16 device;
int (*enable_acs)(struct pci_dev *dev);
-} pci_dev_enable_acs[] = {
- { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_enable_intel_pch_acs },
- { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_enable_intel_spt_pch_acs },
+ int (*disable_acs_redir)(struct pci_dev *dev);
+} pci_dev_acs_ops[] = {
+ { PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
+ .enable_acs = pci_quirk_enable_intel_pch_acs,
+ },
+ { PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
+ .enable_acs = pci_quirk_enable_intel_spt_pch_acs,
+ },
};
int pci_dev_specific_enable_acs(struct pci_dev *dev)
{
- const struct pci_dev_enable_acs *p;
+ const struct pci_dev_acs_ops *p;
int i, ret;
- for (i = 0; i < ARRAY_SIZE(pci_dev_enable_acs); i++) {
- p = &pci_dev_enable_acs[i];
+ for (i = 0; i < ARRAY_SIZE(pci_dev_acs_ops); i++) {
+ p = &pci_dev_acs_ops[i];
if ((p->vendor == dev->vendor ||
p->vendor == (u16)PCI_ANY_ID) &&
(p->device == dev->device ||
- p->device == (u16)PCI_ANY_ID)) {
+ p->device == (u16)PCI_ANY_ID) &&
+ p->enable_acs) {
ret = p->enable_acs(dev);
if (ret >= 0)
return ret;
@@ -4582,6 +4588,27 @@ int pci_dev_specific_enable_acs(struct pci_dev *dev)
return -ENOTTY;
}
+int pci_dev_specific_disable_acs_redir(struct pci_dev *dev)
+{
+ const struct pci_dev_acs_ops *p;
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(pci_dev_acs_ops); i++) {
+ p = &pci_dev_acs_ops[i];
+ if ((p->vendor == dev->vendor ||
+ p->vendor == (u16)PCI_ANY_ID) &&
+ (p->device == dev->device ||
+ p->device == (u16)PCI_ANY_ID) &&
+ p->disable_acs_redir) {
+ ret = p->disable_acs_redir(dev);
+ if (ret >= 0)
+ return ret;
+ }
+ }
+
+ return -ENOTTY;
+}
+
/*
* The PCI capabilities list for Intel DH895xCC VFs (device ID 0x0443) with
* QuickAssist Technology (QAT) is prematurely terminated in hardware. The