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