embeddedzephyr-rtossdhc

Zephyr SD Card Remount Issue: fs_unmount vs. Disk Deinitialization Leading to EIO or Blocked Workqueue


I'm implementing SD card hot-plug functionality in a Zephyr RTOS application. My workflow for managing the SD card involves the following Zephyr APIs:

Problem Description:

When an SD card is inserted for the first time or on power-up, the sequence of disk_access_ioctl(DISK_IOCTL_CTRL_INIT) followed by fs_mount() works perfectly.

However, if I remove the SD card (triggering fs_unmount()) and then re-insert it, the re-initialization (disk_access_ioctl(DISK_IOCTL_CTRL_INIT)) succeeds, but the subsequent fs_mount() call fails consistently with an EIO (-5) error. The relevant log output is:

<err> sd: Failed to read from SDMMC -5
<err> sd: Card read failed
<err> fs: fs mount error (-5)

My understanding, based on the Zephyr documentation (e.g., the general usage of fs_unmount and the disk_access API), is that fs_unmount() should sufficiently deinitialize or prepare the disk for a future re-mount. There doesn't appear to be a DISK_IOCTL_CTRL_DEINIT explicitly documented or commonly used that would be called after fs_unmount.

Additional Observation (if I were to hypothetically force deinitialization):

If I manually deinit using disk_access_ioctl (assuming a DEINIT equivalent existed or by trying other IOCTLs that might reset the state), within a k_work item scheduled on the system workqueue, it causes that k_work item to become permanently blocked or never complete its execution after the first removal.

My questions are:

  1. What is the correct Zephyr API sequence or state management required to reliably remount an SD card after it has been fs_unmount'ed and then re-inserted?
  2. Why would disk_access_ioctl(DISK_IOCTL_CTRL_INIT) succeed on re-insertion, but fs_mount() subsequently fail with EIO? What internal states or resources might be improperly released or re-initialized?
  3. Are there specific disk_access_ioctl commands or other driver-level considerations that are necessary for a clean SD card "eject" and re-insertion cycle in Zephyr that are not immediately obvious from fs_unmount's description?

Any insights into successfully managing SD card hot-plugging in Zephyr, specifically regarding reliable re-mounting after unmounting, would be greatly appreciated.


Solution

  • This issue was resolved here: https://devzone.nordicsemi.com/f/nordic-q-a/123400/zephyr-sd-card-remount-issue-fs_unmount-vs-disk-deinitialization-leading-to-eio-or-blocked-workqueue

    I was able to solve it with these steps:

    1. Did not use either of the following:

    disk_access_ioctl("SD", DISK_IOCTL_CTRL_INIT, NULL);
    
    disk_access_ioctl("SD", DISK_IOCTL_CTRL_DEINIT, NULL);
    

    Earlier I would init the disk, mount, (do stuff) and then on pin triggered removal of SD card unmount and deinit. It seems I need to remove the init/deinit them altogether or deinit right after init if I need to access any parameters using the disk_access_ioctl command.

    2. Even with the above solution for some reason everything would get blocked after at unmount. This was resolved once I moved to a lower priority workqueue. I was using the system workqueue before and it would block forever.