From c4b01048c25247f9b61ee962257b24c5784e1ddb Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Tue, 22 Sep 2026 13:53:00 +0300 Subject: [PATCH 1/2] himci: finish the request when the FIFO reset times out 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 -- the block layer, any MMC_IOC_CMD passthrough, and the card's own rescan all block on the same claim. 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, while working out why an MMC_IOC_CMD passthrough had once been reported as hanging a camera unkillably. That report matches this signature exactly -- a data command on a card that did not answer -- but I could not re-trigger it to confirm, so this is offered as a correctness fix rather than a diagnosis. The path leaves "fifo reset is timeout!" in dmesg, which is the thing to grep for if it is ever seen in the field. Compile-tested for hi3516av300 (CONFIG_HIMCI=y, arm-openipc-linux-gnueabi, kernel 4.9.37); no new warnings. The same bare return is in the hisilicon-hi3516ev200, hisilicon-hi3516cv200, hisilicon-hi3516av100 and hisilicon-hi3536dv100 branches and wants the same one-line change there. --- 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 b8ab8a7ee6..10ae91669f 100644 --- a/drivers/mmc/host/himci/himci.c +++ b/drivers/mmc/host/himci/himci.c @@ -1032,7 +1032,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 4f5c7f0cd5aef170e01538d29dff88598c62eafa Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Tue, 22 Sep 2026 14:25:11 +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 10ae91669f..8ccceb212a 100644 --- a/drivers/mmc/host/himci/himci.c +++ b/drivers/mmc/host/himci/himci.c @@ -1044,9 +1044,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);