aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorNiklas Cassel <cassel@kernel.org>2025-09-08 18:19:42 +0200
committerBjorn Helgaas <bhelgaas@google.com>2025-09-12 15:09:32 -0500
commitf272210b28d050df56ec7dfaecb9fa3bebca6419 (patch)
tree17ec21719721ac85020189452589934cf681b8a9 /drivers/pci
parentPCI: endpoint: pci-epf-test: Limit PCIe BAR size for fixed BARs (diff)
downloadlinux-f272210b28d050df56ec7dfaecb9fa3bebca6419.tar.gz
linux-f272210b28d050df56ec7dfaecb9fa3bebca6419.zip
PCI: endpoint: pci-epf-test: Fix doorbell test support
The doorbell feature temporarily overrides the inbound translation to point to the address stored in epf_test->db_bar.phys_addr, i.e., it calls set_bar() twice without ever calling clear_bar(), as calling clear_bar() would clear the BAR's PCI address assigned by the host. Thus, when disabling the doorbell, restore the inbound translation to point to the memory allocated for the BAR. Without this, running the PCI endpoint kselftest doorbell test case more than once would fail. Fixes: eff0c286aa91 ("PCI: endpoint: pci-epf-test: Add doorbell test support") Signed-off-by: Niklas Cassel <cassel@kernel.org> Signed-off-by: Manivannan Sadhasivam <mani@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://patch.msgid.link/20250908161942.534799-2-cassel@kernel.org
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/endpoint/functions/pci-epf-test.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index 2418add64104..09e1b8b46b55 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -772,12 +772,24 @@ static void pci_epf_test_disable_doorbell(struct pci_epf_test *epf_test,
u32 status = le32_to_cpu(reg->status);
struct pci_epf *epf = epf_test->epf;
struct pci_epc *epc = epf->epc;
+ int ret;
if (bar < BAR_0)
goto set_status_err;
pci_epf_test_doorbell_cleanup(epf_test);
- pci_epc_clear_bar(epc, epf->func_no, epf->vfunc_no, &epf_test->db_bar);
+
+ /*
+ * The doorbell feature temporarily overrides the inbound translation
+ * to point to the address stored in epf_test->db_bar.phys_addr, i.e.,
+ * it calls set_bar() twice without ever calling clear_bar(), as
+ * calling clear_bar() would clear the BAR's PCI address assigned by
+ * the host. Thus, when disabling the doorbell, restore the inbound
+ * translation to point to the memory allocated for the BAR.
+ */
+ ret = pci_epc_set_bar(epc, epf->func_no, epf->vfunc_no, &epf->bar[bar]);
+ if (ret)
+ goto set_status_err;
status |= STATUS_DOORBELL_DISABLE_SUCCESS;
reg->status = cpu_to_le32(status);