[PATCH 1/5] PCI: Add PCI_ERROR_RESPONSE definition

From: Bjorn Helgaas
Date: Mon Aug 05 2019 - 16:52:48 EST


From: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>

An MMIO read from a PCI device that doesn't exist or doesn't respond causes
a PCI error. There's no real data to return to satisfy the CPU read, so
most hardware fabricates ~0 data.

Add a PCI_ERROR_RESPONSE definition for that and use it where appropriate
to make these checks consistent and easier to find.

Note that successful reads *also* may return ~0 data, so additional
information (e.g., knowledge that ~0 is not a valid register value) is
needed to reliably identify errors.

Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
---
drivers/pci/access.c | 13 ++++++------
.../pci/controller/dwc/pcie-designware-host.c | 2 +-
drivers/pci/controller/pci-aardvark.c | 2 +-
drivers/pci/controller/pci-mvebu.c | 4 ++--
drivers/pci/controller/pci-thunder-ecam.c | 20 +++++++++----------
drivers/pci/controller/pci-thunder-pem.c | 2 +-
drivers/pci/controller/pcie-altera.c | 2 +-
drivers/pci/controller/pcie-iproc.c | 2 +-
drivers/pci/controller/pcie-mediatek.c | 4 ++--
drivers/pci/controller/pcie-rcar.c | 2 +-
drivers/pci/controller/pcie-rockchip-host.c | 2 +-
drivers/pci/controller/vmd.c | 2 +-
drivers/pci/hotplug/cpqphp_ctrl.c | 12 +++++------
drivers/pci/hotplug/cpqphp_pci.c | 20 +++++++++----------
drivers/pci/hotplug/pciehp_hpc.c | 6 +++---
drivers/pci/pci.c | 8 ++++----
drivers/pci/pcie/dpc.c | 3 ++-
drivers/pci/pcie/pme.c | 4 ++--
drivers/pci/probe.c | 4 ++--
drivers/pci/quirks.c | 2 +-
include/linux/pci.h | 7 +++++++
21 files changed, 65 insertions(+), 58 deletions(-)

diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 544922f097c0..02186f3471d8 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -81,7 +81,7 @@ int pci_generic_config_read(struct pci_bus *bus, unsigned int devfn,

addr = bus->ops->map_bus(bus, devfn, where);
if (!addr) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}

@@ -123,7 +123,7 @@ int pci_generic_config_read32(struct pci_bus *bus, unsigned int devfn,

addr = bus->ops->map_bus(bus, devfn, where & ~0x3);
if (!addr) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}

@@ -536,7 +536,7 @@ EXPORT_SYMBOL(pcie_capability_clear_and_set_dword);
int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val)
{
if (pci_dev_is_disconnected(dev)) {
- *val = ~0;
+ *val = (u8) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}
return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val);
@@ -546,18 +546,17 @@ EXPORT_SYMBOL(pci_read_config_byte);
int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val)
{
if (pci_dev_is_disconnected(dev)) {
- *val = ~0;
+ *val = (u16) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}
return pci_bus_read_config_word(dev->bus, dev->devfn, where, val);
}
EXPORT_SYMBOL(pci_read_config_word);

-int pci_read_config_dword(const struct pci_dev *dev, int where,
- u32 *val)
+int pci_read_config_dword(const struct pci_dev *dev, int where, u32 *val)
{
if (pci_dev_is_disconnected(dev)) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}
return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val);
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index f93252d0da5b..eb2e8b080a7d 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -594,7 +594,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
struct pcie_port *pp = bus->sysdata;

if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn))) {
- *val = 0xffffffff;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index fc0fe4d4de49..77ad25ed7d38 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -520,7 +520,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn,
int ret;

if (!advk_pcie_valid_device(pcie, bus, devfn)) {
- *val = 0xffffffff;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index d3a0419e42f2..a45e45226790 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -648,7 +648,7 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,

port = mvebu_pcie_find_port(pcie, bus, devfn);
if (!port) {
- *val = 0xffffffff;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}

@@ -658,7 +658,7 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
size, val);

if (!mvebu_pcie_link_up(port)) {
- *val = 0xffffffff;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}

diff --git a/drivers/pci/controller/pci-thunder-ecam.c b/drivers/pci/controller/pci-thunder-ecam.c
index 32d1d7b81ef4..b0332f349863 100644
--- a/drivers/pci/controller/pci-thunder-ecam.c
+++ b/drivers/pci/controller/pci-thunder-ecam.c
@@ -42,7 +42,7 @@ static int handle_ea_bar(u32 e0, int bar, struct pci_bus *bus,
if (where_a == 0x4) {
addr = bus->ops->map_bus(bus, devfn, bar); /* BAR 0 */
if (!addr) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}
v = readl(addr);
@@ -57,7 +57,7 @@ static int handle_ea_bar(u32 e0, int bar, struct pci_bus *bus,

addr = bus->ops->map_bus(bus, devfn, bar); /* BAR 0 */
if (!addr) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}
barl_orig = readl(addr + 0);
@@ -73,7 +73,7 @@ static int handle_ea_bar(u32 e0, int bar, struct pci_bus *bus,
if (where_a == 0xc) {
addr = bus->ops->map_bus(bus, devfn, bar + 4); /* BAR 1 */
if (!addr) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}
v = readl(addr); /* EA entry-3. Base-H */
@@ -105,7 +105,7 @@ static int thunder_ecam_p2_config_read(struct pci_bus *bus, unsigned int devfn,

addr = bus->ops->map_bus(bus, devfn, where_a);
if (!addr) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}

@@ -136,7 +136,7 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn,

addr = bus->ops->map_bus(bus, devfn, 0xc);
if (!addr) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}

@@ -147,7 +147,7 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn,

addr = bus->ops->map_bus(bus, devfn, 8);
if (!addr) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}

@@ -177,7 +177,7 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn,

addr = bus->ops->map_bus(bus, devfn, 0);
if (!addr) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}

@@ -197,7 +197,7 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn,

addr = bus->ops->map_bus(bus, devfn, 0x70);
if (!addr) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}
/* E_CAP */
@@ -212,7 +212,7 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn,
if (where_a == 0xb0) {
addr = bus->ops->map_bus(bus, devfn, where_a);
if (!addr) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}
v = readl(addr);
@@ -269,7 +269,7 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn,
if (where_a == 0x70) {
addr = bus->ops->map_bus(bus, devfn, where_a);
if (!addr) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}
v = readl(addr);
diff --git a/drivers/pci/controller/pci-thunder-pem.c b/drivers/pci/controller/pci-thunder-pem.c
index f127ce8bd4ef..115e2c94d968 100644
--- a/drivers/pci/controller/pci-thunder-pem.c
+++ b/drivers/pci/controller/pci-thunder-pem.c
@@ -31,7 +31,7 @@ static int thunder_pem_bridge_read(struct pci_bus *bus, unsigned int devfn,
struct thunder_pem_pci *pem_pci = (struct thunder_pem_pci *)cfg->priv;

if (devfn != 0 || where >= 2048) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}

diff --git a/drivers/pci/controller/pcie-altera.c b/drivers/pci/controller/pcie-altera.c
index d2497ca43828..3bd63b507eb1 100644
--- a/drivers/pci/controller/pcie-altera.c
+++ b/drivers/pci/controller/pcie-altera.c
@@ -512,7 +512,7 @@ static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_BAD_REGISTER_NUMBER;

if (!altera_pcie_valid_device(pcie, bus, PCI_SLOT(devfn))) {
- *value = 0xffffffff;
+ *value = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}

diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c
index 2d457bfdaf66..1fafedb39c00 100644
--- a/drivers/pci/controller/pcie-iproc.c
+++ b/drivers/pci/controller/pcie-iproc.c
@@ -668,7 +668,7 @@ static int iproc_pci_raw_config_read32(struct iproc_pcie *pcie,

addr = iproc_pcie_map_cfg_bus(pcie, 0, devfn, where & ~0x3);
if (!addr) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}

diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
index 80601e1b939e..38f15a5e18ad 100644
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -361,13 +361,13 @@ static int mtk_pcie_config_read(struct pci_bus *bus, unsigned int devfn,

port = mtk_pcie_find_port(bus, devfn);
if (!port) {
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}

ret = mtk_pcie_hw_rd_cfg(port, bn, devfn, where, size, val);
if (ret)
- *val = ~0;
+ *val = (u32) PCI_ERROR_RESPONSE;

return ret;
}
diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c
index f6a669a9af41..ae8d95146351 100644
--- a/drivers/pci/controller/pcie-rcar.c
+++ b/drivers/pci/controller/pcie-rcar.c
@@ -277,7 +277,7 @@ static int rcar_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
ret = rcar_pcie_config_access(pcie, RCAR_PCI_ACCESS_READ,
bus, devfn, where, val);
if (ret != PCIBIOS_SUCCESSFUL) {
- *val = 0xffffffff;
+ *val = (u32) PCI_ERROR_RESPONSE;
return ret;
}

diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index 8d20f1793a61..48d85f648d79 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -226,7 +226,7 @@ static int rockchip_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
struct rockchip_pcie *rockchip = bus->sysdata;

if (!rockchip_pcie_valid_device(rockchip, bus, PCI_SLOT(devfn))) {
- *val = 0xffffffff;
+ *val = (u32) PCI_ERROR_RESPONSE;
return PCIBIOS_DEVICE_NOT_FOUND;
}

diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
index 4575e0c6dc4b..2af43b9e85db 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -578,7 +578,7 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)

membar2_offset = 0x2018;
ret = pci_read_config_dword(vmd->dev, PCI_REG_VMLOCK, &vmlock);
- if (ret || vmlock == ~0)
+ if (ret || vmlock == (u32) PCI_ERROR_RESPONSE)
return -ENODEV;

if (MB2_SHADOW_EN(vmlock)) {
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
index b7f4e1f099d9..e9d2bf4eeeef 100644
--- a/drivers/pci/hotplug/cpqphp_ctrl.c
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -1497,7 +1497,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
/* Check for a power fault */
if (func->status == 0xFF) {
/* power fault occurred, but it was benign */
- temp_register = 0xFFFFFFFF;
+ temp_register = (u32) PCI_ERROR_RESPONSE;
dbg("%s: temp register set to %x by power fault\n", __func__, temp_register);
rc = POWER_FAILURE;
func->status = 0;
@@ -1510,7 +1510,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)

if (rc != 0) {
/* Something's wrong here */
- temp_register = 0xFFFFFFFF;
+ temp_register = (u32) PCI_ERROR_RESPONSE;
dbg("%s: temp register set to %x by error\n", __func__, temp_register);
}
/* Preset return code. It will be changed later if things go okay. */
@@ -1518,7 +1518,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl)
}

/* All F's is an empty slot or an invalid board */
- if (temp_register != 0xFFFFFFFF) {
+ if (temp_register != (u32) PCI_ERROR_RESPONSE) {
res_lists.io_head = ctrl->io_head;
res_lists.mem_head = ctrl->mem_head;
res_lists.p_mem_head = ctrl->p_mem_head;
@@ -2277,7 +2277,7 @@ static u32 configure_new_device(struct controller *ctrl, struct pci_func *func
while ((function < max_functions) && (!stop_it)) {
pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);

- if (ID == 0xFFFFFFFF) {
+ if (ID == (u32) PCI_ERROR_RESPONSE) {
function++;
} else {
/* Setup slot structure. */
@@ -2516,12 +2516,12 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
for (device = 0; (device <= 0x1F) && !rc; device++) {
irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;

- ID = 0xFFFFFFFF;
+ ID = (u32) PCI_ERROR_RESPONSE;
pci_bus->number = hold_bus_node->base;
pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0), 0x00, &ID);
pci_bus->number = func->bus;

- if (ID != 0xFFFFFFFF) { /* device present */
+ if (ID != (u32) PCI_ERROR_RESPONSE) { /* device present */
/* Setup slot structure. */
new_slot = cpqhp_slot_create(hold_bus_node->base);

diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
index 1b2b3f3b648b..d6ab73b9b280 100644
--- a/drivers/pci/hotplug/cpqphp_pci.c
+++ b/drivers/pci/hotplug/cpqphp_pci.c
@@ -138,7 +138,7 @@ static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 o

if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendID) == -1)
return -1;
- if (vendID == 0xffffffff)
+ if (vendID == (u32) PCI_ERROR_RESPONSE)
return -1;
return pci_bus_read_config_dword(bus, devfn, offset, value);
}
@@ -251,7 +251,7 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
*dev_num = tdevice;
ctrl->pci_bus->number = tbus;
pci_bus_read_config_dword(ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
- if (!nobridge || (work == 0xffffffff))
+ if (!nobridge || (work == (u32) PCI_ERROR_RESPONSE))
return 0;

dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
@@ -330,10 +330,10 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
/* Save PCI configuration space for all devices in supported slots */
ctrl->pci_bus->number = busnumber;
for (device = FirstSupported; device <= LastSupported; device++) {
- ID = 0xFFFFFFFF;
+ ID = (u32) PCI_ERROR_RESPONSE;
rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);

- if (ID == 0xFFFFFFFF) {
+ if (ID == (u32) PCI_ERROR_RESPONSE) {
if (is_hot_plug) {
/* Setup slot structure with entry for empty
* slot
@@ -431,7 +431,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
*/
while ((function < max_functions) && (!stop_it)) {
rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID);
- if (ID == 0xFFFFFFFF) {
+ if (ID == (u32) PCI_ERROR_RESPONSE) {
function++;
continue;
}
@@ -474,12 +474,12 @@ int cpqhp_save_slot_config(struct controller *ctrl, struct pci_func *new_slot)
int cloop = 0;
int stop_it;

- ID = 0xFFFFFFFF;
+ ID = (u32) PCI_ERROR_RESPONSE;

ctrl->pci_bus->number = new_slot->bus;
pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID);

- if (ID == 0xFFFFFFFF)
+ if (ID == (u32) PCI_ERROR_RESPONSE)
return 2;

pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
@@ -522,7 +522,7 @@ int cpqhp_save_slot_config(struct controller *ctrl, struct pci_func *new_slot)
while ((function < max_functions) && (!stop_it)) {
pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID);

- if (ID == 0xFFFFFFFF)
+ if (ID == (u32) PCI_ERROR_RESPONSE)
function++;
else {
pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code);
@@ -1049,7 +1049,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func)
pci_bus_read_config_dword(pci_bus, devfn, PCI_VENDOR_ID, &temp_register);

/* No adapter present */
- if (temp_register == 0xFFFFFFFF)
+ if (temp_register == (u32) PCI_ERROR_RESPONSE)
return(NO_ADAPTER_PRESENT);

if (temp_register != func->config_space[0])
@@ -1267,7 +1267,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st
pci_bus_read_config_dword(ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
dbg("temp_D_word = %x\n", temp_dword);

- if (temp_dword != 0xFFFFFFFF) {
+ if (temp_dword != (u32) PCI_ERROR_RESPONSE) {
index = 0;
func = cpqhp_slot_find(primary_bus, dev_func >> 3, 0);

diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index bd990e3371e3..f0489f305ad7 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -70,7 +70,7 @@ static int pcie_poll_cmd(struct controller *ctrl, int timeout)

while (true) {
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
- if (slot_status == (u16) ~0) {
+ if (slot_status == (u16) PCI_ERROR_RESPONSE) {
ctrl_info(ctrl, "%s: no response from device\n",
__func__);
return 0;
@@ -148,7 +148,7 @@ static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd,
pcie_wait_cmd(ctrl);

pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl);
- if (slot_ctrl == (u16) ~0) {
+ if (slot_ctrl == (u16) PCI_ERROR_RESPONSE) {
ctrl_info(ctrl, "%s: no response from device\n", __func__);
goto out;
}
@@ -543,7 +543,7 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
}

pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &status);
- if (status == (u16) ~0) {
+ if (status == (u16) PCI_ERROR_RESPONSE) {
ctrl_info(ctrl, "%s: no response from device\n", __func__);
if (parent)
pm_runtime_put(parent);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 29ed5ec1ac27..bfc739dc6ada 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4434,16 +4434,16 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout)
* After reset, the device should not silently discard config
* requests, but it may still indicate that it needs more time by
* responding to them with CRS completions. The Root Port will
- * generally synthesize ~0 data to complete the read (except when
- * CRS SV is enabled and the read was for the Vendor ID; in that
- * case it synthesizes 0x0001 data).
+ * generally synthesize ~0 data (PCI_ERROR_RESPONSE) to complete
+ * the read (except when CRS SV is enabled and the read was for the
+ * Vendor ID; in that case it synthesizes 0x0001 data).
*
* Wait for the device to return a non-CRS completion. Read the
* Command register instead of Vendor ID so we don't have to
* contend with the CRS SV value.
*/
pci_read_config_dword(dev, PCI_COMMAND, &id);
- while (id == ~0) {
+ while (id == (u32) PCI_ERROR_RESPONSE) {
if (delay > timeout) {
pci_warn(dev, "not ready %dms after %s; giving up\n",
delay - 1, reset_type);
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index a32ec3487a8d..96b6b87a0af3 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -272,7 +272,8 @@ static irqreturn_t dpc_irq(int irq, void *context)

pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status);

- if (!(status & PCI_EXP_DPC_STATUS_INTERRUPT) || status == (u16)(~0))
+ if (!(status & PCI_EXP_DPC_STATUS_INTERRUPT) ||
+ status == (u16)(PCI_ERROR_RESPONSE))
return IRQ_NONE;

pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c
index f38e6c19dd50..3c46622e6c3f 100644
--- a/drivers/pci/pcie/pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -224,7 +224,7 @@ static void pcie_pme_work_fn(struct work_struct *work)
break;

pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta);
- if (rtsta == (u32) ~0)
+ if (rtsta == (u32) PCI_ERROR_RESPONSE)
break;

if (rtsta & PCI_EXP_RTSTA_PME) {
@@ -274,7 +274,7 @@ static irqreturn_t pcie_pme_irq(int irq, void *context)
spin_lock_irqsave(&data->lock, flags);
pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta);

- if (rtsta == (u32) ~0 || !(rtsta & PCI_EXP_RTSTA_PME)) {
+ if (rtsta == (u32) PCI_ERROR_RESPONSE || !(rtsta & PCI_EXP_RTSTA_PME)) {
spin_unlock_irqrestore(&data->lock, flags);
return IRQ_NONE;
}
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index a3c7338fad86..fb953f2666b9 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1549,7 +1549,7 @@ static int pci_cfg_space_size_ext(struct pci_dev *dev)

if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL)
return PCI_CFG_SPACE_SIZE;
- if (status == 0xffffffff || pci_ext_cfg_is_aliased(dev))
+ if (status == (u32) PCI_ERROR_RESPONSE || pci_ext_cfg_is_aliased(dev))
return PCI_CFG_SPACE_SIZE;

return PCI_CFG_SPACE_EXP_SIZE;
@@ -2488,7 +2488,7 @@ bool pci_bus_generic_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
return false;

/* Some broken boards return 0 or ~0 if a slot is empty: */
- if (*l == 0xffffffff || *l == 0x00000000 ||
+ if (*l == (u32) PCI_ERROR_RESPONSE || *l == 0x00000000 ||
*l == 0x0000ffff || *l == 0xffff0000)
return false;

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 208aacf39329..3d5c92b53310 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4854,7 +4854,7 @@ static void quirk_intel_qat_vf_cap(struct pci_dev *pdev)

pdev->cfg_size = PCI_CFG_SPACE_EXP_SIZE;
if (pci_read_config_dword(pdev, PCI_CFG_SPACE_SIZE, &status) !=
- PCIBIOS_SUCCESSFUL || (status == 0xffffffff))
+ PCIBIOS_SUCCESSFUL || (status == (u32) PCI_ERROR_RESPONSE))
pdev->cfg_size = PCI_CFG_SPACE_SIZE;

if (pci_find_saved_cap(pdev, PCI_CAP_ID_EXP))
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9e700d9f9f28..d64fd3788061 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -123,6 +123,13 @@ enum pci_interrupt_pin {
/* The number of legacy PCI INTx interrupts */
#define PCI_NUM_INTX 4

+/*
+ * Reading from a device that doesn't respond typically returns ~0. A
+ * successful read from a device may also return ~0, so you need additional
+ * information to reliably identify errors.
+ */
+#define PCI_ERROR_RESPONSE (~0ULL)
+
/*
* pci_power_t values must match the bits in the Capabilities PME_Support
* and Control/Status PowerState fields in the Power Management capability.
--
2.22.0.770.g0f2c4a37fd-goog