Message ID | 20190822200551.129039-2-helgaas@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Bjorn Helgaas |
Headers | show |
Series | PCI: Add PCI_ERROR_RESPONSE, check for errors | expand |
On Thu, Aug 22, 2019 at 03:05:49PM -0500, Bjorn Helgaas wrote: > From: Bjorn Helgaas <bhelgaas@google.com> > > 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@google.com> > Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > --- > 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). There are some other areas in drivers/pci where comments also refer to ~0 and similar: $ git grep -i ffffffff drivers/pci/ | grep \* drivers/pci/access.c: * have been written as 0xFFFFFFFF if hardware error happens drivers/pci/controller/dwc/pci-keystone.c: * bus error instead of returning 0xffffffff. This handler always returns 0 drivers/pci/controller/pci-xgene.c: * ready") instead of 0xFFFFFFFF ("device does not exist"). This drivers/pci/controller/pcie-iproc.c: * eventually return the wrong data (0xffffffff). drivers/pci/pci.c: * FFFFFFFFs on the command line.) I've removed anything in the above list that doesn't look like a good candidate for PCI_ERROR_RESPONSE. Perhaps there is some value for replacing "~0" with "~0 (PCI_ERROR_RESPONSE)" in the comments too? > * > * 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)) The casts are necessary but slightly annoying. Have you considered something like: #define SET_PCI_ERROR_RESPONSE(val) (val = ((typeof(val))(~0ULL))) #define RESPONSE_IS_PCI_ERROR(val) (val == ((typeof(val))(~0ULL))) Thanks, Andrew Murray > 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.23.0.187.g17f5b7556c-goog >
On Fri, Aug 23, 2019 at 11:44:15AM +0100, Andrew Murray wrote: > On Thu, Aug 22, 2019 at 03:05:49PM -0500, Bjorn Helgaas wrote: > > From: Bjorn Helgaas <bhelgaas@google.com> > > > > 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. > > - * 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). > > There are some other areas in drivers/pci where comments also refer to ~0 > and similar: > > $ git grep -i ffffffff drivers/pci/ | grep \* > drivers/pci/access.c: * have been written as 0xFFFFFFFF if hardware error happens > drivers/pci/controller/dwc/pci-keystone.c: * bus error instead of returning 0xffffffff. This handler always returns 0 > drivers/pci/controller/pci-xgene.c: * ready") instead of 0xFFFFFFFF ("device does not exist"). This > drivers/pci/controller/pcie-iproc.c: * eventually return the wrong data (0xffffffff). > drivers/pci/pci.c: * FFFFFFFFs on the command line.) > > I've removed anything in the above list that doesn't look like a good candidate > for PCI_ERROR_RESPONSE. > > Perhaps there is some value for replacing "~0" with "~0 (PCI_ERROR_RESPONSE)" > in the comments too? Good idea, I'll take a look at those. > > 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)) > > The casts are necessary but slightly annoying. Have you considered something > like: > > #define SET_PCI_ERROR_RESPONSE(val) (val = ((typeof(val))(~0ULL))) > #define RESPONSE_IS_PCI_ERROR(val) (val == ((typeof(val))(~0ULL))) I hadn't thought of that, but I really like the idea. Thanks, I think I'll try that out! > > 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.23.0.187.g17f5b7556c-goog > >
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.