]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
PCI: endpoint: pci-epf-vntb: Report 0-based doorbell vector via ntb_db_event()
authorKoichiro Den <den@valinux.co.jp>
Wed, 13 May 2026 02:49:14 +0000 (11:49 +0900)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 22 Jun 2026 20:31:11 +0000 (15:31 -0500)
ntb_db_event() expects the vector number to be relative to the first
doorbell vector starting at 0.

pci-epf-vntb reserves vector 0 for link events and uses higher vector
indices for doorbells. By passing the raw slot index to ntb_db_event(),
it effectively assumes that doorbell 0 maps to vector 1.

However, because the host uses a legacy slot layout and writes doorbell
0 into the third slot, doorbell 0 ultimately appears as vector 2 from
the NTB core perspective.

Adjust pci-epf-vntb to:

  - skip the unused second slot, and

  - report doorbells as 0-based vectors (DB#0 -> vector 0).

This change does not introduce a behavioral difference until
.db_vector_count()/.db_vector_mask() are implemented, because without
those callbacks NTB clients effectively ignore the vector number.

Fixes: e35f56bb0330 ("PCI: endpoint: Support NTB transfer between RC and EP")
Signed-off-by: Koichiro Den <den@valinux.co.jp>
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/20260513024923.451765-4-den@valinux.co.jp
drivers/pci/endpoint/functions/pci-epf-vntb.c

index cc0b356973f3a13dddd2ade40c0a8521073b464f..d31e2eee086991067fecbab47faf5f0601de2a5e 100644 (file)
@@ -83,6 +83,12 @@ enum epf_ntb_bar {
        VNTB_BAR_NUM,
 };
 
+enum epf_irq_slot {
+       EPF_IRQ_LINK = 0,
+       EPF_IRQ_RESERVED_DB, /* Historically skipped slot */
+       EPF_IRQ_DB_START,
+};
+
 /*
  * +--------------------------------------------------+ Base
  * |                                                  |
@@ -272,10 +278,11 @@ static void epf_ntb_cmd_handler(struct work_struct *work)
 
        ntb = container_of(work, struct epf_ntb, cmd_handler.work);
 
-       for (i = 1; i < ntb->db_count && !ntb->msi_doorbell; i++) {
+       for (i = EPF_IRQ_DB_START; i < ntb->db_count && !ntb->msi_doorbell;
+            i++) {
                if (ntb->epf_db[i]) {
-                       atomic64_or(1 << (i - 1), &ntb->db);
-                       ntb_db_event(&ntb->ntb, i);
+                       atomic64_or(1 << (i - EPF_IRQ_DB_START), &ntb->db);
+                       ntb_db_event(&ntb->ntb, i - EPF_IRQ_DB_START);
                        ntb->epf_db[i] = 0;
                }
        }
@@ -341,10 +348,10 @@ static irqreturn_t epf_ntb_doorbell_handler(int irq, void *data)
        struct epf_ntb *ntb = data;
        int i;
 
-       for (i = 1; i < ntb->db_count; i++)
+       for (i = EPF_IRQ_DB_START; i < ntb->db_count; i++)
                if (irq == ntb->epf->db_msg[i].virq) {
-                       atomic64_or(1 << (i - 1), &ntb->db);
-                       ntb_db_event(&ntb->ntb, i);
+                       atomic64_or(1 << (i - EPF_IRQ_DB_START), &ntb->db);
+                       ntb_db_event(&ntb->ntb, i - EPF_IRQ_DB_START);
                }
 
        return IRQ_HANDLED;
@@ -1450,8 +1457,8 @@ static void vntb_epf_peer_db_work(struct work_struct *work)
                while (db_bits) {
                        /*
                         * pci_epc_raise_irq() for MSI expects a 1-based
-                        * interrupt number. db_bit is zero-based, so add 3 to
-                        * preserve the historical slot offset.
+                        * interrupt number. The first usable doorbell starts
+                        * at EPF_IRQ_DB_START in the legacy slot layout.
                         *
                         * Legacy mapping (kept for compatibility):
                         *
@@ -1465,7 +1472,7 @@ static void vntb_epf_peer_db_work(struct work_struct *work)
                         * interoperability with older peers.
                         */
                        db_bit = __ffs64(db_bits);
-                       interrupt_num = db_bit + 3;
+                       interrupt_num = db_bit + EPF_IRQ_DB_START + 1;
                        db_bits &= ~BIT_ULL(db_bit);
 
                        ret = pci_epc_raise_irq(epf->epc, func_no, vfunc_no,