浏览代码

PCI: Reverse standard ACS vs device-specific ACS enabling

The original thought was that if a device implemented ACS, then surely
we want to use that... well, it turns out that devices can make an ACS
capability so broken that we still need to fall back to quirks.

Reverse the order of ACS enabling to give quirks first shot at it.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Alex Williamson 9 年之前
父节点
当前提交
c1d61c9bb1
共有 3 个文件被更改,包括 13 次插入10 次删除
  1. 4 6
      drivers/pci/pci.c
  2. 4 2
      drivers/pci/quirks.c
  3. 5 2
      include/linux/pci.h

+ 4 - 6
drivers/pci/pci.c

@@ -2547,7 +2547,7 @@ void pci_request_acs(void)
  * pci_std_enable_acs - enable ACS on devices using standard ACS capabilites
  * pci_std_enable_acs - enable ACS on devices using standard ACS capabilites
  * @dev: the PCI device
  * @dev: the PCI device
  */
  */
-static int pci_std_enable_acs(struct pci_dev *dev)
+static void pci_std_enable_acs(struct pci_dev *dev)
 {
 {
 	int pos;
 	int pos;
 	u16 cap;
 	u16 cap;
@@ -2555,7 +2555,7 @@ static int pci_std_enable_acs(struct pci_dev *dev)
 
 
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
 	if (!pos)
 	if (!pos)
-		return -ENODEV;
+		return;
 
 
 	pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap);
 	pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap);
 	pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl);
 	pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl);
@@ -2573,8 +2573,6 @@ static int pci_std_enable_acs(struct pci_dev *dev)
 	ctrl |= (cap & PCI_ACS_UF);
 	ctrl |= (cap & PCI_ACS_UF);
 
 
 	pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
 	pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
-
-	return 0;
 }
 }
 
 
 /**
 /**
@@ -2586,10 +2584,10 @@ void pci_enable_acs(struct pci_dev *dev)
 	if (!pci_acs_enable)
 	if (!pci_acs_enable)
 		return;
 		return;
 
 
-	if (!pci_std_enable_acs(dev))
+	if (!pci_dev_specific_enable_acs(dev))
 		return;
 		return;
 
 
-	pci_dev_specific_enable_acs(dev);
+	pci_std_enable_acs(dev);
 }
 }
 
 
 static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags)
 static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags)

+ 4 - 2
drivers/pci/quirks.c

@@ -4201,7 +4201,7 @@ static const struct pci_dev_enable_acs {
 	{ 0 }
 	{ 0 }
 };
 };
 
 
-void pci_dev_specific_enable_acs(struct pci_dev *dev)
+int pci_dev_specific_enable_acs(struct pci_dev *dev)
 {
 {
 	const struct pci_dev_enable_acs *i;
 	const struct pci_dev_enable_acs *i;
 	int ret;
 	int ret;
@@ -4213,9 +4213,11 @@ void pci_dev_specific_enable_acs(struct pci_dev *dev)
 		     i->device == (u16)PCI_ANY_ID)) {
 		     i->device == (u16)PCI_ANY_ID)) {
 			ret = i->enable_acs(dev);
 			ret = i->enable_acs(dev);
 			if (ret >= 0)
 			if (ret >= 0)
-				return;
+				return ret;
 		}
 		}
 	}
 	}
+
+	return -ENOTTY;
 }
 }
 
 
 /*
 /*

+ 5 - 2
include/linux/pci.h

@@ -1663,7 +1663,7 @@ enum pci_fixup_pass {
 #ifdef CONFIG_PCI_QUIRKS
 #ifdef CONFIG_PCI_QUIRKS
 void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
 void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
 int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags);
 int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags);
-void pci_dev_specific_enable_acs(struct pci_dev *dev);
+int pci_dev_specific_enable_acs(struct pci_dev *dev);
 #else
 #else
 static inline void pci_fixup_device(enum pci_fixup_pass pass,
 static inline void pci_fixup_device(enum pci_fixup_pass pass,
 				    struct pci_dev *dev) { }
 				    struct pci_dev *dev) { }
@@ -1672,7 +1672,10 @@ static inline int pci_dev_specific_acs_enabled(struct pci_dev *dev,
 {
 {
 	return -ENOTTY;
 	return -ENOTTY;
 }
 }
-static inline void pci_dev_specific_enable_acs(struct pci_dev *dev) { }
+static inline int pci_dev_specific_enable_acs(struct pci_dev *dev)
+{
+	return -ENOTTY;
+}
 #endif
 #endif
 
 
 void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);
 void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);