[PATCH RFC 1/2] pci: Make return value of pcie_capability_*() consistent

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Bolarinwa Olayemi Saheed <refactormyself@xxxxxxxxx>

pcie_capability_{read|write}_*() could return 0, -EINVAL, or any of the
PCIBIOS_* error codes. This is behaviour is now changed to ONLY return a
PCIBIOS_* error code or -ERANGE on error.
This has now been made consistent across all accessors. Callers now have
a consistent way for checking which error has occurred.

An audit of the callers of these functions was made and no contradicting
case was found in the examined call chains.

Signed-off-by: Bolarinwa Olayemi Saheed <refactormyself@xxxxxxxxx>
Suggested-by: Bjorn Helgaas <bjorn@xxxxxxxxxxx>
---
 drivers/pci/access.c | 64 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 51 insertions(+), 13 deletions(-)

diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 79c4a2ef269a..10c771079e35 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -402,6 +402,8 @@ static bool pcie_capability_reg_implemented(struct pci_dev *dev, int pos)
  * Note that these accessor functions are only for the "PCI Express
  * Capability" (see PCIe spec r3.0, sec 7.8).  They do not apply to the
  * other "PCI Express Extended Capabilities" (AER, VC, ACS, MFVC, etc.)
+ *
+ * Return 0 on success, otherwise a negative value
  */
 int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val)
 {
@@ -409,7 +411,7 @@ int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val)
 
 	*val = 0;
 	if (pos & 1)
-		return -EINVAL;
+		return PCIBIOS_BAD_REGISTER_NUMBER;
 
 	if (pcie_capability_reg_implemented(dev, pos)) {
 		ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val);
@@ -444,7 +446,7 @@ int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val)
 
 	*val = 0;
 	if (pos & 3)
-		return -EINVAL;
+		return PCIBIOS_BAD_REGISTER_NUMBER;
 
 	if (pcie_capability_reg_implemented(dev, pos)) {
 		ret = pci_read_config_dword(dev, pci_pcie_cap(dev) + pos, val);
@@ -453,9 +455,9 @@ int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val)
 		 * have been written as 0xFFFFFFFF if hardware error happens
 		 * during pci_read_config_dword().
 		 */
-		if (ret)
-			*val = 0;
-		return ret;
+		if (ret)
+			*val = 0;
+		return ret;
 	}
 
 	if (pci_is_pcie(dev) && pcie_downstream_port(dev) &&
@@ -469,7 +471,7 @@ EXPORT_SYMBOL(pcie_capability_read_dword);
 int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val)
 {
 	if (pos & 1)
-		return -EINVAL;
+		return PCIBIOS_BAD_REGISTER_NUMBER;
 
 	if (!pcie_capability_reg_implemented(dev, pos))
 		return 0;
@@ -481,7 +483,7 @@ EXPORT_SYMBOL(pcie_capability_write_word);
 int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val)
 {
 	if (pos & 3)
-		return -EINVAL;
+		return PCIBIOS_BAD_REGISTER_NUMBER;
 
 	if (!pcie_capability_reg_implemented(dev, pos))
 		return 0;
@@ -526,56 +528,92 @@ EXPORT_SYMBOL(pcie_capability_clear_and_set_dword);
 
 int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val)
 {
+	int ret;
 	if (pci_dev_is_disconnected(dev)) {
 		*val = ~0;
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	}
-	return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val);
+
+	ret = pci_bus_read_config_byte(dev->bus, dev->devfn, where, val);
+
+	if (ret > 0)
+		ret = -ERANGE;
+	return ret;
 }
 EXPORT_SYMBOL(pci_read_config_byte);
 
 int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val)
 {
+	int ret;
 	if (pci_dev_is_disconnected(dev)) {
 		*val = ~0;
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	}
-	return pci_bus_read_config_word(dev->bus, dev->devfn, where, val);
+
+	ret = pci_bus_read_config_word(dev->bus, dev->devfn, where, val);
+
+	if (ret > 0)
+		ret = -ERANGE;
+	return ret;
 }
 EXPORT_SYMBOL(pci_read_config_word);
 
 int pci_read_config_dword(const struct pci_dev *dev, int where,
 					u32 *val)
 {
+	int ret;
 	if (pci_dev_is_disconnected(dev)) {
 		*val = ~0;
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	}
-	return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val);
+
+	ret = pci_bus_read_config_dword(dev->bus, dev->devfn, where, val);
+
+	if (ret > 0)
+		ret = -ERANGE;
+	return ret;
 }
 EXPORT_SYMBOL(pci_read_config_dword);
 
 int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val)
 {
+	int ret;
 	if (pci_dev_is_disconnected(dev))
 		return PCIBIOS_DEVICE_NOT_FOUND;
-	return pci_bus_write_config_byte(dev->bus, dev->devfn, where, val);
+
+	ret = pci_bus_write_config_byte(dev->bus, dev->devfn, where, val);
+
+	if (ret > 0)
+		ret = -ERANGE;
+	return ret;
 }
 EXPORT_SYMBOL(pci_write_config_byte);
 
 int pci_write_config_word(const struct pci_dev *dev, int where, u16 val)
 {
+	int ret;
 	if (pci_dev_is_disconnected(dev))
 		return PCIBIOS_DEVICE_NOT_FOUND;
-	return pci_bus_write_config_word(dev->bus, dev->devfn, where, val);
+
+	ret = pci_bus_write_config_word(dev->bus, dev->devfn, where, val);
+
+	if (ret > 0)
+		ret = -ERANGE;
+	return ret;
 }
 EXPORT_SYMBOL(pci_write_config_word);
 
 int pci_write_config_dword(const struct pci_dev *dev, int where,
 					 u32 val)
 {
+	int ret;
 	if (pci_dev_is_disconnected(dev))
 		return PCIBIOS_DEVICE_NOT_FOUND;
-	return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val);
+
+	ret = pci_bus_write_config_dword(dev->bus, dev->devfn, where, val);
+
+	if (ret > 0)
+		ret = -ERANGE;
+	return ret;
 }
 EXPORT_SYMBOL(pci_write_config_dword);
-- 
2.18.2




[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux