Commit f5d3ca6f authored by Bjorn Helgaas's avatar Bjorn Helgaas

Merge branch 'pci/errors'

- Add PCI_ERROR_RESPONSE and related definitions for signaling and checking
  for transaction errors on PCI (Naveen Naidu)

- Fabricate PCI_ERROR_RESPONSE data (~0) in config read wrappers, instead
  of in host controller drivers, when transactions fail on PCI (Naveen
  Naidu)

- Use PCI_POSSIBLE_ERROR() to check for possible failure of config reads
  (Naveen Naidu)

* pci/errors:
  PCI: xgene: Use PCI_ERROR_RESPONSE to identify config read errors
  PCI: hv: Use PCI_ERROR_RESPONSE to identify config read errors
  PCI: keystone: Use PCI_ERROR_RESPONSE to identify config read errors
  PCI: Use PCI_ERROR_RESPONSE to identify config read errors
  PCI: cpqphp: Use PCI_POSSIBLE_ERROR() to check config reads
  PCI/PME: Use PCI_POSSIBLE_ERROR() to check config reads
  PCI/DPC: Use PCI_POSSIBLE_ERROR() to check config reads
  PCI: pciehp: Use PCI_POSSIBLE_ERROR() to check config reads
  PCI: vmd: Use PCI_POSSIBLE_ERROR() to check config reads
  PCI/ERR: Use PCI_POSSIBLE_ERROR() to check config reads
  PCI: rockchip-host: Drop error data fabrication when config read fails
  PCI: rcar-host: Drop error data fabrication when config read fails
  PCI: altera: Drop error data fabrication when config read fails
  PCI: mvebu: Drop error data fabrication when config read fails
  PCI: aardvark: Drop error data fabrication when config read fails
  PCI: kirin: Drop error data fabrication when config read fails
  PCI: histb: Drop error data fabrication when config read fails
  PCI: exynos: Drop error data fabrication when config read fails
  PCI: mediatek: Drop error data fabrication when config read fails
  PCI: iproc: Drop error data fabrication when config read fails
  PCI: thunder: Drop error data fabrication when config read fails
  PCI: Drop error data fabrication when config read fails
  PCI: Use PCI_SET_ERROR_RESPONSE() for disconnected devices
  PCI: Set error response data when config read fails
  PCI: Add PCI_ERROR_RESPONSE and related definitions
parents da43f08d c78b9a9c
...@@ -42,6 +42,9 @@ int noinline pci_bus_read_config_##size \ ...@@ -42,6 +42,9 @@ int noinline pci_bus_read_config_##size \
if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \ if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
pci_lock_config(flags); \ pci_lock_config(flags); \
res = bus->ops->read(bus, devfn, pos, len, &data); \ res = bus->ops->read(bus, devfn, pos, len, &data); \
if (res) \
PCI_SET_ERROR_RESPONSE(value); \
else \
*value = (type)data; \ *value = (type)data; \
pci_unlock_config(flags); \ pci_unlock_config(flags); \
return res; \ return res; \
...@@ -80,10 +83,8 @@ int pci_generic_config_read(struct pci_bus *bus, unsigned int devfn, ...@@ -80,10 +83,8 @@ int pci_generic_config_read(struct pci_bus *bus, unsigned int devfn,
void __iomem *addr; void __iomem *addr;
addr = bus->ops->map_bus(bus, devfn, where); addr = bus->ops->map_bus(bus, devfn, where);
if (!addr) { if (!addr)
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
if (size == 1) if (size == 1)
*val = readb(addr); *val = readb(addr);
...@@ -122,10 +123,8 @@ int pci_generic_config_read32(struct pci_bus *bus, unsigned int devfn, ...@@ -122,10 +123,8 @@ int pci_generic_config_read32(struct pci_bus *bus, unsigned int devfn,
void __iomem *addr; void __iomem *addr;
addr = bus->ops->map_bus(bus, devfn, where & ~0x3); addr = bus->ops->map_bus(bus, devfn, where & ~0x3);
if (!addr) { if (!addr)
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
*val = readl(addr); *val = readl(addr);
...@@ -228,6 +227,9 @@ int pci_user_read_config_##size \ ...@@ -228,6 +227,9 @@ int pci_user_read_config_##size \
ret = dev->bus->ops->read(dev->bus, dev->devfn, \ ret = dev->bus->ops->read(dev->bus, dev->devfn, \
pos, sizeof(type), &data); \ pos, sizeof(type), &data); \
raw_spin_unlock_irq(&pci_lock); \ raw_spin_unlock_irq(&pci_lock); \
if (ret) \
PCI_SET_ERROR_RESPONSE(val); \
else \
*val = (type)data; \ *val = (type)data; \
return pcibios_err_to_errno(ret); \ return pcibios_err_to_errno(ret); \
} \ } \
...@@ -410,9 +412,9 @@ int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val) ...@@ -410,9 +412,9 @@ int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val)
if (pcie_capability_reg_implemented(dev, pos)) { if (pcie_capability_reg_implemented(dev, pos)) {
ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val); ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val);
/* /*
* Reset *val to 0 if pci_read_config_word() fails, it may * Reset *val to 0 if pci_read_config_word() fails; it may
* have been written as 0xFFFF if hardware error happens * have been written as 0xFFFF (PCI_ERROR_RESPONSE) if the
* during pci_read_config_word(). * config read failed on PCI.
*/ */
if (ret) if (ret)
*val = 0; *val = 0;
...@@ -445,9 +447,9 @@ int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val) ...@@ -445,9 +447,9 @@ int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val)
if (pcie_capability_reg_implemented(dev, pos)) { if (pcie_capability_reg_implemented(dev, pos)) {
ret = pci_read_config_dword(dev, pci_pcie_cap(dev) + pos, val); ret = pci_read_config_dword(dev, pci_pcie_cap(dev) + pos, val);
/* /*
* Reset *val to 0 if pci_read_config_dword() fails, it may * Reset *val to 0 if pci_read_config_dword() fails; it may
* have been written as 0xFFFFFFFF if hardware error happens * have been written as 0xFFFFFFFF (PCI_ERROR_RESPONSE) if
* during pci_read_config_dword(). * the config read failed on PCI.
*/ */
if (ret) if (ret)
*val = 0; *val = 0;
...@@ -523,7 +525,7 @@ EXPORT_SYMBOL(pcie_capability_clear_and_set_dword); ...@@ -523,7 +525,7 @@ EXPORT_SYMBOL(pcie_capability_clear_and_set_dword);
int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val) int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val)
{ {
if (pci_dev_is_disconnected(dev)) { if (pci_dev_is_disconnected(dev)) {
*val = ~0; PCI_SET_ERROR_RESPONSE(val);
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
} }
return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val); return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val);
...@@ -533,7 +535,7 @@ EXPORT_SYMBOL(pci_read_config_byte); ...@@ -533,7 +535,7 @@ EXPORT_SYMBOL(pci_read_config_byte);
int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val) int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val)
{ {
if (pci_dev_is_disconnected(dev)) { if (pci_dev_is_disconnected(dev)) {
*val = ~0; PCI_SET_ERROR_RESPONSE(val);
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
} }
return pci_bus_read_config_word(dev->bus, dev->devfn, where, val); return pci_bus_read_config_word(dev->bus, dev->devfn, where, val);
...@@ -544,7 +546,7 @@ int pci_read_config_dword(const struct pci_dev *dev, int where, ...@@ -544,7 +546,7 @@ int pci_read_config_dword(const struct pci_dev *dev, int where,
u32 *val) u32 *val)
{ {
if (pci_dev_is_disconnected(dev)) { if (pci_dev_is_disconnected(dev)) {
*val = ~0; PCI_SET_ERROR_RESPONSE(val);
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
} }
return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val); return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val);
......
...@@ -216,10 +216,8 @@ static int exynos_pcie_rd_own_conf(struct pci_bus *bus, unsigned int devfn, ...@@ -216,10 +216,8 @@ static int exynos_pcie_rd_own_conf(struct pci_bus *bus, unsigned int devfn,
{ {
struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata); struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata);
if (PCI_SLOT(devfn)) { if (PCI_SLOT(devfn))
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
*val = dw_pcie_read_dbi(pci, where, size); *val = dw_pcie_read_dbi(pci, where, size);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
......
...@@ -747,9 +747,9 @@ static int ks_pcie_config_legacy_irq(struct keystone_pcie *ks_pcie) ...@@ -747,9 +747,9 @@ static int ks_pcie_config_legacy_irq(struct keystone_pcie *ks_pcie)
#ifdef CONFIG_ARM #ifdef CONFIG_ARM
/* /*
* When a PCI device does not exist during config cycles, keystone host gets a * When a PCI device does not exist during config cycles, keystone host
* bus error instead of returning 0xffffffff. This handler always returns 0 * gets a bus error instead of returning 0xffffffff (PCI_ERROR_RESPONSE).
* for this kind of faults. * This handler always returns 0 for this kind of fault.
*/ */
static int ks_pcie_fault(unsigned long addr, unsigned int fsr, static int ks_pcie_fault(unsigned long addr, unsigned int fsr,
struct pt_regs *regs) struct pt_regs *regs)
......
...@@ -127,10 +127,8 @@ static int histb_pcie_rd_own_conf(struct pci_bus *bus, unsigned int devfn, ...@@ -127,10 +127,8 @@ static int histb_pcie_rd_own_conf(struct pci_bus *bus, unsigned int devfn,
{ {
struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata); struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata);
if (PCI_SLOT(devfn)) { if (PCI_SLOT(devfn))
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
*val = dw_pcie_read_dbi(pci, where, size); *val = dw_pcie_read_dbi(pci, where, size);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
......
...@@ -530,10 +530,8 @@ static int kirin_pcie_rd_own_conf(struct pci_bus *bus, unsigned int devfn, ...@@ -530,10 +530,8 @@ static int kirin_pcie_rd_own_conf(struct pci_bus *bus, unsigned int devfn,
{ {
struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata); struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata);
if (PCI_SLOT(devfn)) { if (PCI_SLOT(devfn))
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
*val = dw_pcie_read_dbi(pci, where, size); *val = dw_pcie_read_dbi(pci, where, size);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
......
...@@ -1037,10 +1037,8 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, ...@@ -1037,10 +1037,8 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn,
u32 reg; u32 reg;
int ret; int ret;
if (!advk_pcie_valid_device(pcie, bus, devfn)) { if (!advk_pcie_valid_device(pcie, bus, devfn))
*val = 0xffffffff;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
if (pci_is_root_bus(bus)) if (pci_is_root_bus(bus))
return pci_bridge_emul_conf_read(&pcie->bridge, where, return pci_bridge_emul_conf_read(&pcie->bridge, where,
......
...@@ -2030,7 +2030,7 @@ static void prepopulate_bars(struct hv_pcibus_device *hbus) ...@@ -2030,7 +2030,7 @@ static void prepopulate_bars(struct hv_pcibus_device *hbus)
* If the memory enable bit is already set, Hyper-V silently ignores * If the memory enable bit is already set, Hyper-V silently ignores
* the below BAR updates, and the related PCI device driver can not * the below BAR updates, and the related PCI device driver can not
* work, because reading from the device register(s) always returns * work, because reading from the device register(s) always returns
* 0xFFFFFFFF. * 0xFFFFFFFF (PCI_ERROR_RESPONSE).
*/ */
list_for_each_entry(hpdev, &hbus->children, list_entry) { list_for_each_entry(hpdev, &hbus->children, list_entry) {
_hv_pcifront_read_config(hpdev, PCI_COMMAND, 2, &command); _hv_pcifront_read_config(hpdev, PCI_COMMAND, 2, &command);
......
...@@ -814,20 +814,16 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, ...@@ -814,20 +814,16 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
int ret; int ret;
port = mvebu_pcie_find_port(pcie, bus, devfn); port = mvebu_pcie_find_port(pcie, bus, devfn);
if (!port) { if (!port)
*val = 0xffffffff;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
/* Access the emulated PCI-to-PCI bridge */ /* Access the emulated PCI-to-PCI bridge */
if (bus->number == 0) if (bus->number == 0)
return pci_bridge_emul_conf_read(&port->bridge, where, return pci_bridge_emul_conf_read(&port->bridge, where,
size, val); size, val);
if (!mvebu_pcie_link_up(port)) { if (!mvebu_pcie_link_up(port))
*val = 0xffffffff;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
/* Access the real PCIe interface */ /* Access the real PCIe interface */
ret = mvebu_pcie_hw_rd_conf(port, bus, devfn, ret = mvebu_pcie_hw_rd_conf(port, bus, devfn,
......
...@@ -41,10 +41,9 @@ static int handle_ea_bar(u32 e0, int bar, struct pci_bus *bus, ...@@ -41,10 +41,9 @@ static int handle_ea_bar(u32 e0, int bar, struct pci_bus *bus,
} }
if (where_a == 0x4) { if (where_a == 0x4) {
addr = bus->ops->map_bus(bus, devfn, bar); /* BAR 0 */ addr = bus->ops->map_bus(bus, devfn, bar); /* BAR 0 */
if (!addr) { if (!addr)
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
v = readl(addr); v = readl(addr);
v &= ~0xf; v &= ~0xf;
v |= 2; /* EA entry-1. Base-L */ v |= 2; /* EA entry-1. Base-L */
...@@ -56,10 +55,9 @@ static int handle_ea_bar(u32 e0, int bar, struct pci_bus *bus, ...@@ -56,10 +55,9 @@ static int handle_ea_bar(u32 e0, int bar, struct pci_bus *bus,
u32 barl_rb; u32 barl_rb;
addr = bus->ops->map_bus(bus, devfn, bar); /* BAR 0 */ addr = bus->ops->map_bus(bus, devfn, bar); /* BAR 0 */
if (!addr) { if (!addr)
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
barl_orig = readl(addr + 0); barl_orig = readl(addr + 0);
writel(0xffffffff, addr + 0); writel(0xffffffff, addr + 0);
barl_rb = readl(addr + 0); barl_rb = readl(addr + 0);
...@@ -72,10 +70,9 @@ static int handle_ea_bar(u32 e0, int bar, struct pci_bus *bus, ...@@ -72,10 +70,9 @@ static int handle_ea_bar(u32 e0, int bar, struct pci_bus *bus,
} }
if (where_a == 0xc) { if (where_a == 0xc) {
addr = bus->ops->map_bus(bus, devfn, bar + 4); /* BAR 1 */ addr = bus->ops->map_bus(bus, devfn, bar + 4); /* BAR 1 */
if (!addr) { if (!addr)
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
v = readl(addr); /* EA entry-3. Base-H */ v = readl(addr); /* EA entry-3. Base-H */
set_val(v, where, size, val); set_val(v, where, size, val);
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
...@@ -104,10 +101,8 @@ static int thunder_ecam_p2_config_read(struct pci_bus *bus, unsigned int devfn, ...@@ -104,10 +101,8 @@ static int thunder_ecam_p2_config_read(struct pci_bus *bus, unsigned int devfn,
} }
addr = bus->ops->map_bus(bus, devfn, where_a); addr = bus->ops->map_bus(bus, devfn, where_a);
if (!addr) { if (!addr)
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
v = readl(addr); v = readl(addr);
...@@ -135,10 +130,8 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn, ...@@ -135,10 +130,8 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn,
int where_a = where & ~3; int where_a = where & ~3;
addr = bus->ops->map_bus(bus, devfn, 0xc); addr = bus->ops->map_bus(bus, devfn, 0xc);
if (!addr) { if (!addr)
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
v = readl(addr); v = readl(addr);
...@@ -146,10 +139,8 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn, ...@@ -146,10 +139,8 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn,
cfg_type = (v >> 16) & 0x7f; cfg_type = (v >> 16) & 0x7f;
addr = bus->ops->map_bus(bus, devfn, 8); addr = bus->ops->map_bus(bus, devfn, 8);
if (!addr) { if (!addr)
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
class_rev = readl(addr); class_rev = readl(addr);
if (class_rev == 0xffffffff) if (class_rev == 0xffffffff)
...@@ -176,10 +167,8 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn, ...@@ -176,10 +167,8 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn,
} }
addr = bus->ops->map_bus(bus, devfn, 0); addr = bus->ops->map_bus(bus, devfn, 0);
if (!addr) { if (!addr)
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
vendor_device = readl(addr); vendor_device = readl(addr);
if (vendor_device == 0xffffffff) if (vendor_device == 0xffffffff)
...@@ -196,10 +185,9 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn, ...@@ -196,10 +185,9 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn,
bool is_tns = (vendor_device == 0xa01f177d); bool is_tns = (vendor_device == 0xa01f177d);
addr = bus->ops->map_bus(bus, devfn, 0x70); addr = bus->ops->map_bus(bus, devfn, 0x70);
if (!addr) { if (!addr)
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
/* E_CAP */ /* E_CAP */
v = readl(addr); v = readl(addr);
has_msix = (v & 0xff00) != 0; has_msix = (v & 0xff00) != 0;
...@@ -211,10 +199,9 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn, ...@@ -211,10 +199,9 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn,
} }
if (where_a == 0xb0) { if (where_a == 0xb0) {
addr = bus->ops->map_bus(bus, devfn, where_a); addr = bus->ops->map_bus(bus, devfn, where_a);
if (!addr) { if (!addr)
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
v = readl(addr); v = readl(addr);
if (v & 0xff00) if (v & 0xff00)
pr_err("Bad MSIX cap header: %08x\n", v); pr_err("Bad MSIX cap header: %08x\n", v);
...@@ -268,10 +255,9 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn, ...@@ -268,10 +255,9 @@ static int thunder_ecam_config_read(struct pci_bus *bus, unsigned int devfn,
if (where_a == 0x70) { if (where_a == 0x70) {
addr = bus->ops->map_bus(bus, devfn, where_a); addr = bus->ops->map_bus(bus, devfn, where_a);
if (!addr) { if (!addr)
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
v = readl(addr); v = readl(addr);
if (v & 0xff00) if (v & 0xff00)
pr_err("Bad PCIe cap header: %08x\n", v); pr_err("Bad PCIe cap header: %08x\n", v);
......
...@@ -41,10 +41,8 @@ static int thunder_pem_bridge_read(struct pci_bus *bus, unsigned int devfn, ...@@ -41,10 +41,8 @@ static int thunder_pem_bridge_read(struct pci_bus *bus, unsigned int devfn,
struct pci_config_window *cfg = bus->sysdata; struct pci_config_window *cfg = bus->sysdata;
struct thunder_pem_pci *pem_pci = (struct thunder_pem_pci *)cfg->priv; struct thunder_pem_pci *pem_pci = (struct thunder_pem_pci *)cfg->priv;
if (devfn != 0 || where >= 2048) { if (devfn != 0 || where >= 2048)
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
/* /*
* 32-bit accesses only. Write the address to the low order * 32-bit accesses only. Write the address to the low order
......
...@@ -171,11 +171,11 @@ static int xgene_pcie_config_read32(struct pci_bus *bus, unsigned int devfn, ...@@ -171,11 +171,11 @@ static int xgene_pcie_config_read32(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
/* /*
* The v1 controller has a bug in its Configuration Request * The v1 controller has a bug in its Configuration Request Retry
* Retry Status (CRS) logic: when CRS Software Visibility is * Status (CRS) logic: when CRS Software Visibility is enabled and
* enabled and we read the Vendor and Device ID of a non-existent * we read the Vendor and Device ID of a non-existent device, the
* device, the controller fabricates return data of 0xFFFF0001 * controller fabricates return data of 0xFFFF0001 ("device exists
* ("device exists but is not ready") instead of 0xFFFFFFFF * but is not ready") instead of 0xFFFFFFFF (PCI_ERROR_RESPONSE)
* ("device does not exist"). This causes the PCI core to retry * ("device does not exist"). This causes the PCI core to retry
* the read until it times out. Avoid this by not claiming to * the read until it times out. Avoid this by not claiming to
* support CRS SV. * support CRS SV.
......
...@@ -510,10 +510,8 @@ static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn, ...@@ -510,10 +510,8 @@ static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn,
if (altera_pcie_hide_rc_bar(bus, devfn, where)) if (altera_pcie_hide_rc_bar(bus, devfn, where))
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
if (!altera_pcie_valid_device(pcie, bus, PCI_SLOT(devfn))) { if (!altera_pcie_valid_device(pcie, bus, PCI_SLOT(devfn)))
*value = 0xffffffff;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
return _altera_pcie_cfg_read(pcie, bus->number, devfn, where, size, return _altera_pcie_cfg_read(pcie, bus->number, devfn, where, size,
value); value);
......
...@@ -659,10 +659,8 @@ static int iproc_pci_raw_config_read32(struct iproc_pcie *pcie, ...@@ -659,10 +659,8 @@ static int iproc_pci_raw_config_read32(struct iproc_pcie *pcie,
void __iomem *addr; void __iomem *addr;
addr = iproc_pcie_map_cfg_bus(pcie, 0, devfn, where & ~0x3); addr = iproc_pcie_map_cfg_bus(pcie, 0, devfn, where & ~0x3);
if (!addr) { if (!addr)
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
*val = readl(addr); *val = readl(addr);
......
...@@ -365,19 +365,12 @@ static int mtk_pcie_config_read(struct pci_bus *bus, unsigned int devfn, ...@@ -365,19 +365,12 @@ static int mtk_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
{ {
struct mtk_pcie_port *port; struct mtk_pcie_port *port;
u32 bn = bus->number; u32 bn = bus->number;
int ret;
port = mtk_pcie_find_port(bus, devfn); port = mtk_pcie_find_port(bus, devfn);
if (!port) { if (!port)
*val = ~0;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
ret = mtk_pcie_hw_rd_cfg(port, bn, devfn, where, size, val); return mtk_pcie_hw_rd_cfg(port, bn, devfn, where, size, val);
if (ret)
*val = ~0;
return ret;
} }
static int mtk_pcie_config_write(struct pci_bus *bus, unsigned int devfn, static int mtk_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
......
...@@ -159,10 +159,8 @@ static int rcar_pcie_read_conf(struct pci_bus *bus, unsigned int devfn, ...@@ -159,10 +159,8 @@ static int rcar_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
ret = rcar_pcie_config_access(host, RCAR_PCI_ACCESS_READ, ret = rcar_pcie_config_access(host, RCAR_PCI_ACCESS_READ,
bus, devfn, where, val); bus, devfn, where, val);
if (ret != PCIBIOS_SUCCESSFUL) { if (ret != PCIBIOS_SUCCESSFUL)
*val = 0xffffffff;
return ret; return ret;
}
if (size == 1) if (size == 1)
*val = (*val >> (BITS_PER_BYTE * (where & 3))) & 0xff; *val = (*val >> (BITS_PER_BYTE * (where & 3))) & 0xff;
......
...@@ -221,10 +221,8 @@ static int rockchip_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, ...@@ -221,10 +221,8 @@ static int rockchip_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
{ {
struct rockchip_pcie *rockchip = bus->sysdata; struct rockchip_pcie *rockchip = bus->sysdata;
if (!rockchip_pcie_valid_device(rockchip, bus, PCI_SLOT(devfn))) { if (!rockchip_pcie_valid_device(rockchip, bus, PCI_SLOT(devfn)))
*val = 0xffffffff;
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
}
if (pci_is_root_bus(bus)) if (pci_is_root_bus(bus))
return rockchip_pcie_rd_own_conf(rockchip, where, size, val); return rockchip_pcie_rd_own_conf(rockchip, where, size, val);
......
...@@ -575,7 +575,7 @@ static int vmd_get_phys_offsets(struct vmd_dev *vmd, bool native_hint, ...@@ -575,7 +575,7 @@ static int vmd_get_phys_offsets(struct vmd_dev *vmd, bool native_hint,
int ret; int ret;
ret = pci_read_config_dword(dev, PCI_REG_VMLOCK, &vmlock); ret = pci_read_config_dword(dev, PCI_REG_VMLOCK, &vmlock);
if (ret || vmlock == ~0) if (ret || PCI_POSSIBLE_ERROR(vmlock))
return -ENODEV; return -ENODEV;
if (MB2_SHADOW_EN(vmlock)) { if (MB2_SHADOW_EN(vmlock)) {
......
...@@ -2273,7 +2273,7 @@ static u32 configure_new_device(struct controller *ctrl, struct pci_func *func ...@@ -2273,7 +2273,7 @@ static u32 configure_new_device(struct controller *ctrl, struct pci_func *func
while ((function < max_functions) && (!stop_it)) { while ((function < max_functions) && (!stop_it)) {
pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID); pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
if (ID == 0xFFFFFFFF) { if (PCI_POSSIBLE_ERROR(ID)) {
function++; function++;
} else { } else {
/* Setup slot structure. */ /* Setup slot structure. */
...@@ -2517,7 +2517,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func ...@@ -2517,7 +2517,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func
pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0), 0x00, &ID); pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0), 0x00, &ID);
pci_bus->number = func->bus; pci_bus->number = func->bus;
if (ID != 0xFFFFFFFF) { /* device present */ if (!PCI_POSSIBLE_ERROR(ID)) { /* device present */
/* Setup slot structure. */ /* Setup slot structure. */
new_slot = cpqhp_slot_create(hold_bus_node->base); new_slot = cpqhp_slot_create(hold_bus_node->base);
......
...@@ -89,7 +89,7 @@ static int pcie_poll_cmd(struct controller *ctrl, int timeout) ...@@ -89,7 +89,7 @@ static int pcie_poll_cmd(struct controller *ctrl, int timeout)
do { do {
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
if (slot_status == (u16) ~0) { if (PCI_POSSIBLE_ERROR(slot_status)) {
ctrl_info(ctrl, "%s: no response from device\n", ctrl_info(ctrl, "%s: no response from device\n",
__func__); __func__);
return 0; return 0;
...@@ -165,7 +165,7 @@ static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd, ...@@ -165,7 +165,7 @@ static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd,
pcie_wait_cmd(ctrl); pcie_wait_cmd(ctrl);
pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl); pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl);
if (slot_ctrl == (u16) ~0) { if (PCI_POSSIBLE_ERROR(slot_ctrl)) {
ctrl_info(ctrl, "%s: no response from device\n", __func__); ctrl_info(ctrl, "%s: no response from device\n", __func__);
goto out; goto out;
} }
...@@ -236,7 +236,7 @@ int pciehp_check_link_active(struct controller *ctrl) ...@@ -236,7 +236,7 @@ int pciehp_check_link_active(struct controller *ctrl)
int ret; int ret;
ret = pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status); ret = pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status);
if (ret == PCIBIOS_DEVICE_NOT_FOUND || lnk_status == (u16)~0) if (ret == PCIBIOS_DEVICE_NOT_FOUND || PCI_POSSIBLE_ERROR(lnk_status))
return -ENODEV; return -ENODEV;
ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA); ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA);
...@@ -443,7 +443,7 @@ int pciehp_card_present(struct controller *ctrl) ...@@ -443,7 +443,7 @@ int pciehp_card_present(struct controller *ctrl)
int ret; int ret;
ret = pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); ret = pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
if (ret == PCIBIOS_DEVICE_NOT_FOUND || slot_status == (u16)~0) if (ret == PCIBIOS_DEVICE_NOT_FOUND || PCI_POSSIBLE_ERROR(slot_status))
return -ENODEV; return -ENODEV;
return !!(slot_status & PCI_EXP_SLTSTA_PDS); return !!(slot_status & PCI_EXP_SLTSTA_PDS);
...@@ -621,7 +621,7 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id) ...@@ -621,7 +621,7 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
read_status: read_status:
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &status); pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &status);
if (status == (u16) ~0) { if (PCI_POSSIBLE_ERROR(status)) {
ctrl_info(ctrl, "%s: no response from device\n", __func__); ctrl_info(ctrl, "%s: no response from device\n", __func__);
if (parent) if (parent)
pm_runtime_put(parent); pm_runtime_put(parent);
......
...@@ -1115,7 +1115,7 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) ...@@ -1115,7 +1115,7 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
return -EIO; return -EIO;
pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
if (pmcsr == (u16) ~0) { if (PCI_POSSIBLE_ERROR(pmcsr)) {
pci_err(dev, "can't change power state from %s to %s (config space inaccessible)\n", pci_err(dev, "can't change power state from %s to %s (config space inaccessible)\n",
pci_power_name(dev->current_state), pci_power_name(dev->current_state),
pci_power_name(state)); pci_power_name(state));
...@@ -1271,16 +1271,16 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout) ...@@ -1271,16 +1271,16 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout)
* After reset, the device should not silently discard config * After reset, the device should not silently discard config
* requests, but it may still indicate that it needs more time by * requests, but it may still indicate that it needs more time by
* responding to them with CRS completions. The Root Port will * responding to them with CRS completions. The Root Port will
* generally synthesize ~0 data to complete the read (except when * generally synthesize ~0 (PCI_ERROR_RESPONSE) data to complete
* CRS SV is enabled and the read was for the Vendor ID; in that * the read (except when CRS SV is enabled and the read was for the
* case it synthesizes 0x0001 data). * Vendor ID; in that case it synthesizes 0x0001 data).
* *
* Wait for the device to return a non-CRS completion. Read the * Wait for the device to return a non-CRS completion. Read the
* Command register instead of Vendor ID so we don't have to * Command register instead of Vendor ID so we don't have to
* contend with the CRS SV value. * contend with the CRS SV value.
*/ */
pci_read_config_dword(dev, PCI_COMMAND, &id); pci_read_config_dword(dev, PCI_COMMAND, &id);
while (id == ~0) { while (PCI_POSSIBLE_ERROR(id)) {
if (delay > timeout) { if (delay > timeout) {
pci_warn(dev, "not ready %dms after %s; giving up\n", pci_warn(dev, "not ready %dms after %s; giving up\n",
delay - 1, reset_type); delay - 1, reset_type);
......
...@@ -79,7 +79,7 @@ static bool dpc_completed(struct pci_dev *pdev) ...@@ -79,7 +79,7 @@ static bool dpc_completed(struct pci_dev *pdev)
u16 status; u16 status;
pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_STATUS, &status); pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_STATUS, &status);
if ((status != 0xffff) && (status & PCI_EXP_DPC_STATUS_TRIGGER)) if ((!PCI_POSSIBLE_ERROR(status)) && (status & PCI_EXP_DPC_STATUS_TRIGGER))
return false; return false;
if (test_bit(PCI_DPC_RECOVERING, &pdev->priv_flags)) if (test_bit(PCI_DPC_RECOVERING, &pdev->priv_flags))
...@@ -312,7 +312,7 @@ static irqreturn_t dpc_irq(int irq, void *context) ...@@ -312,7 +312,7 @@ static irqreturn_t dpc_irq(int irq, void *context)
pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status); 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) || PCI_POSSIBLE_ERROR(status))
return IRQ_NONE; return IRQ_NONE;
pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS, pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
......
...@@ -224,7 +224,7 @@ static void pcie_pme_work_fn(struct work_struct *work) ...@@ -224,7 +224,7 @@ static void pcie_pme_work_fn(struct work_struct *work)
break; break;
pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta); pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta);
if (rtsta == (u32) ~0) if (PCI_POSSIBLE_ERROR(rtsta))
break; break;
if (rtsta & PCI_EXP_RTSTA_PME) { if (rtsta & PCI_EXP_RTSTA_PME) {
...@@ -274,7 +274,7 @@ static irqreturn_t pcie_pme_irq(int irq, void *context) ...@@ -274,7 +274,7 @@ static irqreturn_t pcie_pme_irq(int irq, void *context)
spin_lock_irqsave(&data->lock, flags); spin_lock_irqsave(&data->lock, flags);
pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta); pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta);
if (rtsta == (u32) ~0 || !(rtsta & PCI_EXP_RTSTA_PME)) { if (PCI_POSSIBLE_ERROR(rtsta) || !(rtsta & PCI_EXP_RTSTA_PME)) {
spin_unlock_irqrestore(&data->lock, flags); spin_unlock_irqrestore(&data->lock, flags);
return IRQ_NONE; return IRQ_NONE;
} }
......
...@@ -206,14 +206,14 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, ...@@ -206,14 +206,14 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
* memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit
* 1 must be clear. * 1 must be clear.
*/ */
if (sz == 0xffffffff) if (PCI_POSSIBLE_ERROR(sz))
sz = 0; sz = 0;
/* /*
* I don't know how l can have all bits set. Copied from old code. * I don't know how l can have all bits set. Copied from old code.
* Maybe it fixes a bug on some ancient platform. * Maybe it fixes a bug on some ancient platform.
*/ */
if (l == 0xffffffff) if (PCI_POSSIBLE_ERROR(l))
l = 0; l = 0;
if (type == pci_bar_unknown) { if (type == pci_bar_unknown) {
...@@ -1675,7 +1675,7 @@ static int pci_cfg_space_size_ext(struct pci_dev *dev) ...@@ -1675,7 +1675,7 @@ static int pci_cfg_space_size_ext(struct pci_dev *dev)
if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL) if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL)
return PCI_CFG_SPACE_SIZE; return PCI_CFG_SPACE_SIZE;
if (status == 0xffffffff || pci_ext_cfg_is_aliased(dev)) if (PCI_POSSIBLE_ERROR(status) || pci_ext_cfg_is_aliased(dev))
return PCI_CFG_SPACE_SIZE; return PCI_CFG_SPACE_SIZE;
return PCI_CFG_SPACE_EXP_SIZE; return PCI_CFG_SPACE_EXP_SIZE;
...@@ -2363,8 +2363,8 @@ bool pci_bus_generic_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l, ...@@ -2363,8 +2363,8 @@ bool pci_bus_generic_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l)) if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l))
return false; return false;
/* Some broken boards return 0 or ~0 if a slot is empty: */ /* Some broken boards return 0 or ~0 (PCI_ERROR_RESPONSE) if a slot is empty: */
if (*l == 0xffffffff || *l == 0x00000000 || if (PCI_POSSIBLE_ERROR(*l) || *l == 0x00000000 ||
*l == 0x0000ffff || *l == 0xffff0000) *l == 0x0000ffff || *l == 0xffff0000)
return false; return false;
......
...@@ -154,6 +154,15 @@ enum pci_interrupt_pin { ...@@ -154,6 +154,15 @@ enum pci_interrupt_pin {
/* The number of legacy PCI INTx interrupts */ /* The number of legacy PCI INTx interrupts */
#define PCI_NUM_INTX 4 #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)
#define PCI_SET_ERROR_RESPONSE(val) (*(val) = ((typeof(*(val))) PCI_ERROR_RESPONSE))
#define PCI_POSSIBLE_ERROR(val) ((val) == ((typeof(val)) PCI_ERROR_RESPONSE))
/* /*
* pci_power_t values must match the bits in the Capabilities PME_Support * pci_power_t values must match the bits in the Capabilities PME_Support
* and Control/Status PowerState fields in the Power Management capability. * and Control/Status PowerState fields in the Power Management capability.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment