[PATCH v4 04/12] dmaengine: switchtec-dma: halt channel on alloc_chan_resources error

From: Logan Gunthorpe

Date: Tue Jul 28 2026 - 13:30:19 EST


The error-unwind path called disable_channel() before freeing the
descriptor rings, but that only clears the enable bit with an
unflushed write -- it doesn't halt the channel or clear its DMA base
address registers. If unhalt_channel() timed out, the channel's actual
state is unknown at that point, so nothing guarantees the hardware
isn't still touching the rings when they're freed.

Call switchtec_dma_chan_stop() first, matching what
switchtec_dma_free_chan_resources() already does before freeing
descriptors on the normal teardown path: it synchronously halts the
channel and zeroes the DMA base registers. If the halt itself can't be
confirmed, skip freeing the descriptor rings (leaking them instead).

Fixes: 30eba9df76ad ("dmaengine: switchtec-dma: Implement hardware initialization and cleanup")
Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
Link: https://lore.kernel.org/dmaengine/20260717223647.F0A051F000E9@xxxxxxxxxxxxxxx
Link: https://lore.kernel.org/dmaengine/20260727185101.D221C1F000E9@xxxxxxxxxxxxxxx
Signed-off-by: Logan Gunthorpe <logang@xxxxxxxxxxxx>
---
drivers/dma/switchtec_dma.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/dma/switchtec_dma.c b/drivers/dma/switchtec_dma.c
index cbbc9ad08247..25b988e9b4af 100644
--- a/drivers/dma/switchtec_dma.c
+++ b/drivers/dma/switchtec_dma.c
@@ -1047,6 +1047,10 @@ static int switchtec_dma_alloc_chan_resources(struct dma_chan *chan)
swdma_chan->comp_ring_active = false;
spin_unlock_bh(&swdma_chan->complete_lock);
err_disable_channel:
+ if (switchtec_dma_chan_stop(swdma_chan)) {
+ disable_channel(swdma_chan);
+ return rc;
+ }
disable_channel(swdma_chan);
err_free_desc:
switchtec_dma_free_desc(swdma_chan);
--
2.47.3