Skip to content

Commit c1b7b81

Browse files
danieldegrassefabiobaltieri
authored andcommitted
sd: modify sdmmc_wait_ready to always decrement timeout
As described in issue: #65027, sdmmc_wait_ready can enter an infinite loop if the card is removed while waiting for it to report an idle status. Fix this by always decrementing the timeout in sdmmc_wait_ready, regardless of whether the SD card is busy. Fixes #65027 Signed-off-by: Daniel DeGrasse <[email protected]>
1 parent d744719 commit c1b7b81

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

subsys/sd/sd_ops.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,21 +63,28 @@ int sdmmc_read_status(struct sd_card *card)
6363
int sdmmc_wait_ready(struct sd_card *card)
6464
{
6565
int ret, timeout = CONFIG_SD_DATA_TIMEOUT * 1000;
66-
bool busy = true;
6766

6867
do {
69-
busy = sdhc_card_busy(card->sdhc);
70-
if (!busy) {
68+
if (!sdhc_card_busy(card->sdhc)) {
7169
/* Check card status */
7270
ret = sd_retry(sdmmc_read_status, card, CONFIG_SD_RETRY_COUNT);
73-
busy = (ret != 0);
74-
} else {
75-
/* Delay 125us before polling again */
76-
k_busy_wait(125);
77-
timeout -= 125;
71+
if (ret == 0) {
72+
return 0;
73+
}
74+
if (ret == -ETIMEDOUT) {
75+
/* If this check timed out, then the total
76+
* time elapsed in microseconds is
77+
* SD_CMD_TIMEOUT * SD_RETRY_COUNT * 1000
78+
*/
79+
timeout -= (CONFIG_SD_CMD_TIMEOUT *
80+
CONFIG_SD_RETRY_COUNT) * 1000;
81+
}
7882
}
79-
} while (busy && (timeout > 0));
80-
return busy;
83+
/* Delay 125us before polling again */
84+
k_busy_wait(125);
85+
timeout -= 125;
86+
} while (timeout > 0);
87+
return -EBUSY;
8188
}
8289

8390
static inline void sdmmc_decode_csd(struct sd_csd *csd, uint32_t *raw_csd, uint32_t *blk_count,

0 commit comments

Comments
 (0)