DMA Engine development
 help / color / mirror / Atom feed
* [PATCH] dmaengine: pl330: report a failed transfer through callback_result
@ 2026-11-11 15:21 Sungho Kim
  2026-11-11 16:17 ` sashiko-bot
  0 siblings, 1 reply; 2+ messages in thread
From: Sungho Kim @ 2026-11-11 15:21 UTC (permalink / raw)
  To: Vinod Koul; +Cc: Frank Li, dmaengine, linux-kernel, Sungho Kim

A channel fault still completes the descriptor as a success, and the
callback is invoked with a NULL result. Record the outcome and pass
DMA_TRANS_ABORTED to callback_result on a fault, an abort or a rejected
request, reporting it on the last descriptor of the transaction.

Signed-off-by: Sungho Kim <sungho.kim@furiosa.ai>
---
 drivers/dma/pl330.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index c2d0b473b..d479d73cb 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -458,6 +458,12 @@ struct dma_pl330_chan {
 	/* for cyclic capability */
 	bool cyclic;
 
+	/*
+	 * First failure among the completed descriptors of a transaction,
+	 * reported once its last descriptor completes.
+	 */
+	enum dmaengine_tx_result result;
+
 	/* for runtime pm tracking */
 	bool active;
 };
@@ -534,6 +540,8 @@ struct dma_pl330_desc {
 	struct pl330_reqcfg rqcfg;
 
 	enum desc_status status;
+	/* How the transfer of this descriptor ended */
+	enum dmaengine_tx_result result;
 
 	int bytes_requested;
 	bool last;
@@ -1572,6 +1580,8 @@ static void dma_pl330_rqcb(struct dma_pl330_desc *desc, enum pl330_op_err err)
 	spin_lock_irqsave(&pch->lock, flags);
 
 	desc->status = DONE;
+	if (err != PL330_ERR_NONE)
+		desc->result = DMA_TRANS_ABORTED;
 
 	spin_unlock_irqrestore(&pch->lock, flags);
 
@@ -2059,6 +2069,7 @@ static inline void fill_queue(struct dma_pl330_chan *pch)
 		} else {
 			/* Unacceptable request */
 			desc->status = DONE;
+			desc->result = DMA_TRANS_ABORTED;
 			dev_err(pch->dmac->ddma.dev, "%s:%d Bad Desc(%d)\n",
 					__func__, __LINE__, desc->txd.cookie);
 			tasklet_schedule(&pch->task);
@@ -2101,12 +2112,26 @@ static void pl330_tasklet(struct tasklet_struct *t)
 
 	while (!list_empty(&pch->completed_list)) {
 		struct dmaengine_desc_callback cb;
+		struct dmaengine_result res = { .residue = 0 };
 
 		desc = list_first_entry(&pch->completed_list,
 					struct dma_pl330_desc, node);
 
 		dmaengine_desc_get_callback(&desc->txd, &cb);
 
+		/*
+		 * callback_result is only on the last descriptor of a transaction
+		 * (tx_submit copies just callback to the periods of a cyclic
+		 * one), so a failure of an earlier descriptor is held on the
+		 * channel until the last one completes.
+		 */
+		if (pch->result == DMA_TRANS_NOERROR)
+			pch->result = desc->result;
+		res.result = pch->result;
+		if (desc->last)
+			pch->result = DMA_TRANS_NOERROR;
+		desc->result = DMA_TRANS_NOERROR;
+
 		if (pch->cyclic) {
 			desc->status = PREP;
 			list_move_tail(&desc->node, &pch->work_list);
@@ -2126,7 +2151,7 @@ static void pl330_tasklet(struct tasklet_struct *t)
 
 		if (dmaengine_desc_callback_valid(&cb)) {
 			spin_unlock_irqrestore(&pch->lock, flags);
-			dmaengine_desc_callback_invoke(&cb, NULL);
+			dmaengine_desc_callback_invoke(&cb, &res);
 			spin_lock_irqsave(&pch->lock, flags);
 		}
 	}
@@ -2167,6 +2192,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
 
 	dma_cookie_init(chan);
 	pch->cyclic = false;
+	pch->result = DMA_TRANS_NOERROR;
 
 	pch->thread = pl330_request_channel(pl330);
 	if (!pch->thread) {
@@ -2295,6 +2321,7 @@ static int pl330_terminate_all(struct dma_chan *chan)
 
 	power_down = pch->active;
 	pch->active = false;
+	pch->result = DMA_TRANS_NOERROR;
 
 	/* Mark all desc done */
 	list_for_each_entry(desc, &pch->submitted_list, node) {
@@ -2579,6 +2606,7 @@ static struct dma_pl330_desc *pluck_desc(struct list_head *pool,
 		list_del_init(&desc->node);
 
 		desc->status = PREP;
+		desc->result = DMA_TRANS_NOERROR;
 		desc->txd.callback = NULL;
 		desc->txd.callback_result = NULL;
 	}
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-11-11 16:17 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-11 15:21 [PATCH] dmaengine: pl330: report a failed transfer through callback_result Sungho Kim
2026-11-11 16:17 ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox