Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sd: modify sdmmc_wait_ready to always decrement timeout #66243

Merged
merged 1 commit into from
Jan 24, 2024
Merged

sd: modify sdmmc_wait_ready to always decrement timeout #66243

merged 1 commit into from
Jan 24, 2024

Conversation

danieldegrasse
Copy link
Collaborator

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

Comment on lines 78 to 79
} while (timeout > 0);
return 1;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usual style

	} while (timeout > 0);

	return 1;

Would it make sense to return ret and not just 1? Otherwise it is a bit confusing that is_ready returns 1 when device is not ready.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about returning -EBUSY? The comment for sdmmc_wait_ready indicates it should return 0 if the card is ready (to indicate the wait succeeded).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change applied. I've also updated the timeout logic, so that the timeout duration is a bit closer to CONFIG_SD_DATA_TIMEOUT in the case where the card is detached.

} while (busy && (timeout > 0));
return busy;
/* Delay 125us before polling again */
k_busy_wait(125);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be configurable

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be but I don't think it's worth the extra Kconfig. Really this function is unlikely to wait exactly CONFIG_SD_DATA_TIMEOUT ms, because the actual delay will come down to how the SD host controller driver handles a slow card. The main goal here is simply that an SD card that is unresponsive (or dead) will timeout here, but a working but slow card will function

/* Delay 125us before polling again */
k_busy_wait(125);
timeout -= 125;
} while (timeout > 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CONFIG_SD_CMD_TIMEOUT being greater than ~22 seconds with CONFIG_SD_RETRY_COUNT something like 100 could result in integer overflow in this code, I'm not sure if this is a reasonably expected scenario though, it seems a little ridiculous, but I'm just pointing this out.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just in case if you think it's an issue you could use u32_add_overflow from math_extras.h

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$ west build -p always -b lpcxpresso55s69_cpu0 tests/drivers/disk/disk_access/ -DCONFIG_SD_CMD_TIMEOUT=22000 -DCONFIG_SD_RETRY_COUNT=10

[99/155] Building C object zephyr/subsys/sd/CMakeFiles/subsys__sd.dir/sd_ops.c.obj
/home/danieldegrasse/zephyr/zephyrproject/zephyr/subsys/sd/sd_ops.c: In function 'sdmmc_wait_ready':
/home/danieldegrasse/zephyr/zephyrproject/zephyr/subsys/sd/sd_ops.c:80:68: warning: integer overflow in expression of type 'int' results in '-2094967296' [-Woverflow]
   80 |                                             CONFIG_SD_RETRY_COUNT) * 1000;

Given that the compiler warns about it, I think we are ok to leave this as is.

Copy link
Member

@decsny decsny Jan 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, makes sense, this compiler option will probably be kept on by default

Copy link
Collaborator

@jfischer-no jfischer-no left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"As described in issue #65027, sdmmc_wait_ready can enter an"
Would be nice to have issue URL instead of Github reference.

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]>
@danieldegrasse
Copy link
Collaborator Author

"As described in issue #65027, sdmmc_wait_ready can enter an"
Would be nice to have issue URL instead of Github reference.

The github UI refuses to display it, but I've updated the commit to include the URL.

@danieldegrasse danieldegrasse requested a review from decsny January 19, 2024 23:41
@fabiobaltieri fabiobaltieri merged commit c1b7b81 into zephyrproject-rtos:main Jan 24, 2024
17 checks passed
@danieldegrasse danieldegrasse deleted the fix/sdmmc-wait-ready branch January 24, 2024 16:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

sd: sdmmc_wait_ready does not respect its timeout if the SD card is physically disconnected
5 participants