misc: pci_endpoint_test: Fail doorbell test when the trigger IRQ is missed

The doorbell test case was observed to pass even when the Endpoint had
clearly failed to handle the doorbell trigger.

  pci-endpoint-test 0000:01:00.0: Failed to trigger doorbell in endpoint
  ok 23 pcie_ep_doorbell.DOORBELL_TEST

The root cause turned out to be a buggy EPC driver that raised two IRQs
in response to a single ENABLE DOORBELL command. The extra IRQ left
test->irq_raised.done at a non zero value, so the next
wait_for_completion_timeout() after the writel() that rings the
doorbell returned immediately, before the Endpoint had set
STATUS_DOORBELL_SUCCESS and raised the IRQ that belongs to that write.

The status readback that followed therefore did not yet reflect the
doorbell trigger, and the test logged the failure but did not fail the
test case. Later on, after the doorbell was disabled, the status was
read again and STATUS_DOORBELL_SUCCESS had by then been set by the
Endpoint for the earlier trigger. The final check saw the bit set and
reported the test as passed.

Make the trigger step actually fail the test case when it detects a
problem. Record the failure in a local variable, keep going so that
the doorbell is still disabled and the Endpoint is left in a clean
state, and return the stored error at the end. The disable path still
returns its own error immediately when its wait times out, which is
unchanged.

Signed-off-by: Niklas Cassel <cassel@kernel.org>
[mani: change log]
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Link: https://patch.msgid.link/20260730122045.1382749-6-cassel@kernel.org
This commit is contained in:
Niklas Cassel 2026-07-30 14:20:48 +02:00 committed by Manivannan Sadhasivam
parent 37ddcce690
commit 0a6f72eda3

View File

@ -1094,7 +1094,7 @@ static int pci_endpoint_test_doorbell(struct pci_endpoint_test *test)
left = wait_for_completion_timeout(&test->irq_raised, msecs_to_jiffies(1000));
status = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
if (!left || (status & STATUS_DOORBELL_ENABLE_FAIL)) {
if (!left || !(status & STATUS_DOORBELL_ENABLE_SUCCESS)) {
dev_err(dev, "Failed to enable doorbell\n");
return -EINVAL;
}
@ -1133,7 +1133,7 @@ static int pci_endpoint_test_doorbell(struct pci_endpoint_test *test)
status |= pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
if (status & STATUS_DOORBELL_DISABLE_FAIL) {
if (!(status & STATUS_DOORBELL_DISABLE_SUCCESS)) {
dev_err(dev, "Failed to disable doorbell\n");
return -EINVAL;
}