]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
i3c: mipi-i3c-hci: Complete transfer lists immediately on error
authorAdrian Hunter <adrian.hunter@intel.com>
Wed, 3 Jun 2026 09:07:44 +0000 (12:07 +0300)
committerAlexandre Belloni <alexandre.belloni@bootlin.com>
Sun, 14 Jun 2026 15:21:34 +0000 (17:21 +0200)
In DMA mode, transfer lists are currently completed only when the final
transfer in the list completes. If an earlier transfer fails, the list is
left incomplete and callers wait until timeout.

There is no need to wait for a timeout, as the completion path in
i3c_hci_process_xfer() already checks for error status. Complete the
transfer list as soon as any transfer in the list reports an error.

This avoids unnecessary delays and spurious timeouts on error.

Complete a transfer list completion immediately there is an error.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260603090754.16252-8-adrian.hunter@intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
drivers/i3c/master/mipi-i3c-hci/dma.c
drivers/i3c/master/mipi-i3c-hci/hci.h

index de0f17706ac8a5983dd9533640d55dcf2c2250ea..83b553e1ab0b01cfe58da6f5d7773ebfdb1f63b4 100644 (file)
@@ -502,6 +502,8 @@ static int hci_dma_queue_xfer(struct i3c_hci *hci,
                struct hci_xfer *xfer = xfer_list + i;
                u32 *ring_data = rh->xfer + rh->xfer_struct_sz * enqueue_ptr;
 
+               xfer->final_xfer = xfer_list + n - 1;
+
                /* store cmd descriptor */
                *ring_data++ = xfer->cmd_desc[0];
                *ring_data++ = xfer->cmd_desc[1];
@@ -576,8 +578,8 @@ static void hci_dma_xfer_done(struct i3c_hci *hci, struct hci_rh_data *rh)
                                        tid, xfer->cmd_tid);
                                /* TODO: do something about it? */
                        }
-                       if (xfer->completion)
-                               complete(xfer->completion);
+                       if (xfer == xfer->final_xfer || RESP_STATUS(resp))
+                               complete(xfer->final_xfer->completion);
                        if (RESP_STATUS(resp))
                                hci->enqueue_blocked = true;
                }
index d630400ec94590104f45732bb3513ba5c47c1fac..f07fc627d4d2f0f131735438937d1b0a0ecefa82 100644 (file)
@@ -104,6 +104,7 @@ struct hci_xfer {
                struct {
                        /* DMA specific */
                        struct i3c_dma *dma;
+                       struct hci_xfer *final_xfer;
                        int ring_number;
                        int ring_entry;
                };