diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c index 01b0eae2e10..0bf19c2b9b1 100644 --- a/supervisor/shared/usb/usb_msc_flash.c +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -202,10 +202,25 @@ static fs_user_mount_t *get_vfs(int lun) { return NULL; } +// Release the locks that USB MSC holds. Locks held by others (Python, workflows) are not touched. +static void release_msc_locks(void) { + for (uint8_t i = 0; i < LUN_COUNT; i++) { + if (!locked[i]) { + continue; + } + fs_user_mount_t *vfs = get_vfs(i); + if (vfs != NULL) { + blockdev_unlock((supervisor_vfs_t *)vfs); + } + locked[i] = false; + } +} + static void _usb_msc_uneject(void) { + // A bus reset doesn't call tud_umount_cb(), so USB MSC may still hold its locks. + // Keep them: tud_msc_is_writable_cb() sees locked[] and doesn't lock again. for (uint8_t i = 0; i < LUN_COUNT; i++) { ejected[i] = false; - locked[i] = false; } } @@ -214,14 +229,7 @@ void usb_msc_mount(void) { } void usb_msc_umount(void) { - for (uint8_t i = 0; i < LUN_COUNT; i++) { - fs_user_mount_t *vfs = get_vfs(i); - if (vfs == NULL) { - continue; - } - blockdev_unlock((supervisor_vfs_t *)vfs); - locked[i] = false; - } + release_msc_locks(); } // Release the USB MSC lock on CIRCUITPY (LUN 0), if USB MSC holds it. @@ -493,9 +501,13 @@ bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, boo if (disk_ioctl(current_mount, CTRL_SYNC, NULL) != RES_OK) { return false; } else { - blockdev_unlock((supervisor_vfs_t *)current_mount); + // Release the lock only if USB MSC holds it. Locks held by others + // (Python, workflows) are not touched. + if (locked[lun]) { + blockdev_unlock((supervisor_vfs_t *)current_mount); + locked[lun] = false; + } ejected[lun] = true; - locked[lun] = false; } } else { // We can only load if it hasn't been ejected.