aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/pci/controller/dwc/pcie-designware-ep.c
diff options
context:
space:
mode:
authorSerge Semin <Sergey.Semin@baikalelectronics.ru>2022-06-24 17:39:46 +0300
committerBjorn Helgaas <bhelgaas@google.com>2022-08-01 15:15:32 -0500
commitce06bf570390fb8b41d581e5d594727b51367179 (patch)
tree8715233edb39eceeb51eb418b8b118e0516a900c /drivers/pci/controller/dwc/pcie-designware-ep.c
parentPCI: dwc: Validate iATU outbound mappings against hardware constraints (diff)
downloadwireguard-linux-ce06bf570390fb8b41d581e5d594727b51367179.tar.xz
wireguard-linux-ce06bf570390fb8b41d581e5d594727b51367179.zip
PCI: dwc: Check iATU in/outbound range setup status
Make the DWC PCIe RC/EP safer and more verbose for invalid or failed inbound and outbound iATU window setups. Silently ignoring iATU regions setup errors may cause unpredictable errors. For instance if a cfg or IO window fails to be activated, then any CFG/IO requested won't reach target PCIe devices and the corresponding accessors will return platform-specific random values. [bhelgaas: trim commit log] Link: https://lore.kernel.org/r/20220624143947.8991-15-Sergey.Semin@baikalelectronics.ru Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rob Herring <robh@kernel.org> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Diffstat (limited to 'drivers/pci/controller/dwc/pcie-designware-ep.c')
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-ep.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 2e91222f7c98..627c4b69878c 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -184,8 +184,9 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, u8 func_no,
phys_addr_t phys_addr,
u64 pci_addr, size_t size)
{
- u32 free_win;
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+ u32 free_win;
+ int ret;
free_win = find_first_zero_bit(ep->ob_window_map, pci->num_ob_windows);
if (free_win >= pci->num_ob_windows) {
@@ -193,8 +194,10 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, u8 func_no,
return -EINVAL;
}
- dw_pcie_prog_ep_outbound_atu(pci, func_no, free_win, PCIE_ATU_TYPE_MEM,
- phys_addr, pci_addr, size);
+ ret = dw_pcie_prog_ep_outbound_atu(pci, func_no, free_win, PCIE_ATU_TYPE_MEM,
+ phys_addr, pci_addr, size);
+ if (ret)
+ return ret;
set_bit(free_win, ep->ob_window_map);
ep->outbound_addr[free_win] = phys_addr;