This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 62b41ad9b40 arch/arm/src/common/stm32: Bound SDIO command response 
wait by time.
62b41ad9b40 is described below

commit 62b41ad9b40d5a513486a3b7f9be86ed8cdfe0e5
Author: Luka Filipović <[email protected]>
AuthorDate: Mon Aug 10 20:47:00 2026 +0200

    arch/arm/src/common/stm32: Bound SDIO command response wait by time.
    
    stm32_waitresponse() polls SDIO_STA bounded only by an iteration
    counter, set to 0x7fffffff for all R1/R1B/R2/R4/R5/R6 commands.  The
    hardware CTIMEOUT flag is the intended exit for a missing response,
    but it is only generated while the card clock is running and the CPSM
    has reached its Wait state.  If the card clock stops or the peripheral
    fails, SDIO_STA never updates and the loop spins for INT32_MAX
    iterations while holding the FAT filesystem lock, at the caller's
    priority-inheritance boosted priority if higher priority tasks block
    on the filesystem.  Since the mmcsd layer retries failed commands,
    the driver's recovery paths are never reached and the system never
    recovers.
    
    Bound the wait by time instead: 250 ms for response-bearing commands
    (the largest timeout the SD specification allows for any operation)
    and 10 ms for the no-response/R3/R7 cases.  CTIMEOUT remains the
    normal error exit within microseconds; the software bound only fires
    when the peripheral itself is dead, converting an unbounded spin into
    -ETIMEDOUT so the existing mmcsd retry logic can run.
    
    Signed-off-by: Luka Filipović <[email protected]>
    Assisted-by: Claude Code:claude-fable-5
---
 arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c 
b/arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c
index 47b7b7a02c1..e14de3221ca 100644
--- a/arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c
+++ b/arch/arm/src/common/stm32/stm32_sdio_m3m4_v1.c
@@ -174,8 +174,8 @@
 
 /* Timing */
 
-#define SDIO_CMDTIMEOUT          (100000)
-#define SDIO_LONGTIMEOUT         (0x7fffffff)
+#define SDIO_CMDTIMEOUT_MS       (10)
+#define SDIO_LONGTIMEOUT_MS      (250)
 
 /* DTIMER setting */
 
@@ -2155,14 +2155,15 @@ static int stm32_cancel(struct sdio_dev_s *dev)
 
 static int stm32_waitresponse(struct sdio_dev_s *dev, uint32_t cmd)
 {
-  int32_t timeout;
+  clock_t timeout;
+  clock_t start;
   uint32_t events;
 
   switch (cmd & MMCSD_RESPONSE_MASK)
     {
     case MMCSD_NO_RESPONSE:
       events  = SDIO_CMDDONE_STA;
-      timeout = SDIO_CMDTIMEOUT;
+      timeout = MSEC2TICK(SDIO_CMDTIMEOUT_MS);
       break;
 
     case MMCSD_R1_RESPONSE:
@@ -2172,13 +2173,13 @@ static int stm32_waitresponse(struct sdio_dev_s *dev, 
uint32_t cmd)
     case MMCSD_R5_RESPONSE:
     case MMCSD_R6_RESPONSE:
       events  = SDIO_RESPDONE_STA;
-      timeout = SDIO_LONGTIMEOUT;
+      timeout = MSEC2TICK(SDIO_LONGTIMEOUT_MS);
       break;
 
     case MMCSD_R3_RESPONSE:
     case MMCSD_R7_RESPONSE:
       events  = SDIO_RESPDONE_STA;
-      timeout = SDIO_CMDTIMEOUT;
+      timeout = MSEC2TICK(SDIO_CMDTIMEOUT_MS);
       break;
 
     default:
@@ -2187,9 +2188,11 @@ static int stm32_waitresponse(struct sdio_dev_s *dev, 
uint32_t cmd)
 
   /* Then wait for the response (or timeout) */
 
+  start = clock_systime_ticks();
+
   while ((getreg32(STM32_SDIO_STA) & events) == 0)
     {
-      if (--timeout <= 0)
+      if (clock_systime_ticks() - start > timeout)
         {
           mcerr("ERROR: Timeout cmd: %08" PRIx32 " events: %08" PRIx32
                 " STA: %08" PRIx32 "\n",

Reply via email to