diff options
| author | Pengpeng Hou <pengpeng@iscas.ac.cn> | 2026-06-23 14:11:12 +0800 |
|---|---|---|
| committer | Ulf Hansson <ulfh@kernel.org> | 2026-07-06 16:13:25 +0200 |
| commit | e29e650077e01dddf69bc8fac31e0cd60043aa7c (patch) | |
| tree | 70f46e1227233afb99c9032c0d73788d04109463 | |
| parent | 1f8c98dc954debe776ee81f889a73b5522f2e5b2 (diff) | |
mmc: moxart: report DMA completion timeout
moxart_transfer_dma() waits for the DMA completion but ignores
wait_for_completion_interruptible_timeout(). It then unconditionally
reports the full transfer length in data->bytes_xfered.
Terminate the DMA channel and set data->error when the wait is
interrupted or times out. Only report host->data_len as transferred
after the completion is observed.
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
| -rw-r--r-- | drivers/mmc/host/moxart-mmc.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c index 3dd8f232052f..4a4d8b19b18c 100644 --- a/drivers/mmc/host/moxart-mmc.c +++ b/drivers/mmc/host/moxart-mmc.c @@ -264,6 +264,7 @@ static void moxart_transfer_dma(struct mmc_data *data, struct moxart_host *host) u32 len, dir_slave; struct dma_async_tx_descriptor *desc = NULL; struct dma_chan *dma_chan; + long timeout; if (host->data_len == data->bytes_xfered) return; @@ -296,11 +297,17 @@ static void moxart_transfer_dma(struct mmc_data *data, struct moxart_host *host) dma_async_issue_pending(dma_chan); } - wait_for_completion_interruptible_timeout(&host->dma_complete, - host->timeout); + timeout = wait_for_completion_interruptible_timeout(&host->dma_complete, + host->timeout); + if (timeout <= 0) { + dmaengine_terminate_sync(dma_chan); + data->error = timeout ?: -ETIMEDOUT; + goto unmap; + } data->bytes_xfered = host->data_len; +unmap: dma_unmap_sg(dma_chan->device->dev, data->sg, data->sg_len, mmc_get_dma_dir(data)); |
