* [PATCH] mtd: rawnand: lpc32xx_slc: fail DMA transfer on completion timeout
@ 2026-06-24 14:41 Pengpeng Hou
2026-06-24 15:29 ` Vladimir Zapolskiy
0 siblings, 1 reply; 2+ messages in thread
From: Pengpeng Hou @ 2026-06-24 14:41 UTC (permalink / raw)
To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
Vladimir Zapolskiy, Piotr Wojtaszczyk
Cc: Pengpeng Hou, linux-mtd, linux-arm-kernel, linux-kernel
lpc32xx_xmit_dma() waits for the DMA completion callback but ignores
wait_for_completion_timeout(). A timed out DMA transfer is therefore
unmapped and reported as successful to the NAND read/write path.
Return -ETIMEDOUT when the completion wait expires. Terminate the DMA
channel before unmapping the scatterlist so the timed out transfer cannot
continue to access the buffer after the error is returned.
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
drivers/mtd/nand/raw/lpc32xx_slc.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/nand/raw/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c
index 3ca30e7dc..10c808020 100644
--- a/drivers/mtd/nand/raw/lpc32xx_slc.c
+++ b/drivers/mtd/nand/raw/lpc32xx_slc.c
@@ -430,6 +430,7 @@ static int lpc32xx_xmit_dma(struct mtd_info *mtd, dma_addr_t dma,
struct dma_async_tx_descriptor *desc;
int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
int res;
+ unsigned long time_left;
host->dma_slave_config.direction = dir;
host->dma_slave_config.src_addr = dma;
@@ -467,12 +468,19 @@ static int lpc32xx_xmit_dma(struct mtd_info *mtd, dma_addr_t dma,
dmaengine_submit(desc);
dma_async_issue_pending(host->dma_chan);
- wait_for_completion_timeout(&host->comp, msecs_to_jiffies(1000));
+ time_left = wait_for_completion_timeout(&host->comp,
+ msecs_to_jiffies(1000));
+ if (!time_left) {
+ dmaengine_terminate_sync(host->dma_chan);
+ res = -ETIMEDOUT;
+ } else {
+ res = 0;
+ }
dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
DMA_BIDIRECTIONAL);
- return 0;
+ return res;
out1:
dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
DMA_BIDIRECTIONAL);
--
2.50.1 (Apple Git-155)
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] mtd: rawnand: lpc32xx_slc: fail DMA transfer on completion timeout
2026-06-24 14:41 [PATCH] mtd: rawnand: lpc32xx_slc: fail DMA transfer on completion timeout Pengpeng Hou
@ 2026-06-24 15:29 ` Vladimir Zapolskiy
0 siblings, 0 replies; 2+ messages in thread
From: Vladimir Zapolskiy @ 2026-06-24 15:29 UTC (permalink / raw)
To: Pengpeng Hou, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra, Piotr Wojtaszczyk
Cc: linux-mtd, linux-arm-kernel, linux-kernel
On 6/24/26 17:41, Pengpeng Hou wrote:
> lpc32xx_xmit_dma() waits for the DMA completion callback but ignores
> wait_for_completion_timeout(). A timed out DMA transfer is therefore
> unmapped and reported as successful to the NAND read/write path.
>
> Return -ETIMEDOUT when the completion wait expires. Terminate the DMA
> channel before unmapping the scatterlist so the timed out transfer cannot
> continue to access the buffer after the error is returned.
>
> Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
> ---
> drivers/mtd/nand/raw/lpc32xx_slc.c | 12 ++++++++++--
> 1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c
> index 3ca30e7dc..10c808020 100644
> --- a/drivers/mtd/nand/raw/lpc32xx_slc.c
> +++ b/drivers/mtd/nand/raw/lpc32xx_slc.c
> @@ -430,6 +430,7 @@ static int lpc32xx_xmit_dma(struct mtd_info *mtd, dma_addr_t dma,
> struct dma_async_tx_descriptor *desc;
> int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
> int res;
> + unsigned long time_left;
>
> host->dma_slave_config.direction = dir;
> host->dma_slave_config.src_addr = dma;
> @@ -467,12 +468,19 @@ static int lpc32xx_xmit_dma(struct mtd_info *mtd, dma_addr_t dma,
> dmaengine_submit(desc);
> dma_async_issue_pending(host->dma_chan);
>
> - wait_for_completion_timeout(&host->comp, msecs_to_jiffies(1000));
> + time_left = wait_for_completion_timeout(&host->comp,
> + msecs_to_jiffies(1000));
> + if (!time_left) {
> + dmaengine_terminate_sync(host->dma_chan);
> + res = -ETIMEDOUT;
> + } else {
> + res = 0;
> + }
>
> dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
> DMA_BIDIRECTIONAL);
>
> - return 0;
> + return res;
> out1:
> dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
> DMA_BIDIRECTIONAL);
Thank you for the change.
Reviewed-by: Vladimir Zapolskiy <vz@kernel.org>
--
Best wishes,
Vladimir
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-06-24 15:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-24 14:41 [PATCH] mtd: rawnand: lpc32xx_slc: fail DMA transfer on completion timeout Pengpeng Hou
2026-06-24 15:29 ` Vladimir Zapolskiy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox