From 4b13b742e22d70409869e5a93cbbaf1cb4bba280 Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Tue, 22 Sep 2026 14:09:18 +0300 Subject: [PATCH 1/2] himci: finish the request when the FIFO reset times out Same one-line fault as OpenIPC/linux#57 on hisilicon-hi3516cv500, in this branch's copy of the driver. himci_request() has ten ways out and nine of them reach request_end, which calls himci_finish_request() and through it mmc_request_done(). The tenth, in the FIFO-reset loop on the data path, is a bare return. Nothing else completes the request. The MMC core is sitting in mmc_wait_for_req() on an uninterruptible wait_for_completion(), so the caller becomes an unkillable D state, and because the host is never released every later request queues behind it. On a camera that is recording stopping and staying stopped until someone cuts the power. Set the data error the way every other timeout in this driver does and jump to request_end. There is no DMA to unwind: himci_idma_start() is below this point. Found by reading, not by triggering it; see #57 for why forcing the path costs a board nobody can reach. The path leaves "fifo reset is timeout!" in dmesg, which is what to grep for if it is ever seen in the field. Compile-tested with hi3516av100 and hi3516dv100' kernel config (CONFIG_HIMCI=y, arm-openipc-linux-musleabi, make drivers/mmc/host/himci/himci.o) with no new warnings. --- drivers/mmc/host/himci/himci.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/himci/himci.c b/drivers/mmc/host/himci/himci.c index cbf72ae25b3..d2d8f442276 100644 --- a/drivers/mmc/host/himci/himci.c +++ b/drivers/mmc/host/himci/himci.c @@ -853,7 +853,22 @@ static void himci_request(struct mmc_host *mmc, struct mmc_request *mrq) fifo_count++; if (fifo_count >= retry_count) { pr_info("fifo reset is timeout!"); - return; + /* + * Every other way out of this function reaches + * request_end, and it has to: himci_finish_request() + * is what calls mmc_request_done(). Returning here + * instead left the core parked in mmc_wait_for_req()'s + * uninterruptible wait_for_completion() with nothing + * left to complete it -- an unkillable D state for the + * caller, and the host still claimed, so every later + * request blocked behind it. On a camera that means + * recording stops and only a power cycle brings it + * back. + * + * No DMA to unwind: himci_idma_start() is below. + */ + mrq->data->error = -ETIMEDOUT; + goto request_end; } } while (tmp_reg & FIFO_RESET); From a63972879a30053ef7cced5e3b86f387eb0ef005 Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Tue, 22 Sep 2026 14:25:18 +0300 Subject: [PATCH 2/2] himci: give the mapping back before completing the timed-out request From review of the previous commit, and a fault in it. himci_setup_data() does two things that have to be undone: it maps the scatterlist for the device, and it takes host->data. himci_data_done() is the only thing that gives either back. Jumping to request_end from the FIFO-reset timeout skipped it, so the buffer went back to the MMC core still mapped for the device, and host->data was left pointing at a request that had just been completed. Call it, with no status bits, so it unmaps, clears host->data, zeroes bytes_xfered and keeps the -ETIMEDOUT set above rather than deciding an error of its own. Still no himci_idma_stop(): the engine is genuinely not running there, because himci_idma_start() is below this point. Worth noting while this is open: the command-error paths further down have the same shape. When himci_exec_cmd() fails or the command completes with an error, the data branch calls himci_idma_stop() and falls through to request_end without himci_data_done(), so those leak the mapping too. That is older than this change and is left alone here rather than folded into a one-line fix. Compile-tested as before, no new warnings. --- drivers/mmc/host/himci/himci.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/himci/himci.c b/drivers/mmc/host/himci/himci.c index d2d8f442276..f4b95b3ca5c 100644 --- a/drivers/mmc/host/himci/himci.c +++ b/drivers/mmc/host/himci/himci.c @@ -865,9 +865,19 @@ static void himci_request(struct mmc_host *mmc, struct mmc_request *mrq) * recording stops and only a power cycle brings it * back. * - * No DMA to unwind: himci_idma_start() is below. + * The engine is not running yet -- himci_idma_start() + * is below this point -- but himci_setup_data() has + * already mapped the scatterlist and taken + * host->data, and himci_data_done() is the only thing + * that gives either back. Without it the buffer goes + * back to the core still mapped for the device, and + * host->data is left pointing at a request that has + * been completed. Called with no status bits set, so + * it keeps the error above rather than deciding its + * own. */ mrq->data->error = -ETIMEDOUT; + himci_data_done(host, 0); goto request_end; } } while (tmp_reg & FIFO_RESET);