From 7a3f86d184c42a7957a135d9dfc23b1149e2708c Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 14 Mar 2018 10:32:41 -0700 Subject: [PATCH] Check usb_busy up front in usb background function. Waiting to do so risks accidentally queueing another response. Hopefully fixes #655 but we'll let @jerryneedell confirm. --- ports/atmel-samd/usb_mass_storage.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ports/atmel-samd/usb_mass_storage.c b/ports/atmel-samd/usb_mass_storage.c index b337839d5d..9b6715158c 100644 --- a/ports/atmel-samd/usb_mass_storage.c +++ b/ports/atmel-samd/usb_mass_storage.c @@ -280,7 +280,14 @@ int32_t usb_msc_xfer_done(uint8_t lun) { // drive into our cache and trigger the USB DMA to output the // sector. Once the sector is transmitted, xfer_done will be called. void usb_msc_background(void) { - if (active_read && !usb_busy) { + // Check USB busy first because we never want to queue another transfer if it is. Checking + // active_read or active_write first leaves the possibility that they are true, an xfer done + // interrupt occurs (setting them false), turning off usb_busy and causing us to queue a + // spurious transfer. + if (usb_busy) { + return; + } + if (active_read) { fs_user_mount_t * vfs = get_vfs(active_lun); disk_read(vfs, sector_buffer, active_addr, 1); CRITICAL_SECTION_ENTER(); @@ -288,7 +295,7 @@ void usb_msc_background(void) { usb_busy = result == ERR_NONE; CRITICAL_SECTION_LEAVE(); } - if (active_write && !usb_busy) { + if (active_write) { if (sector_loaded) { fs_user_mount_t * vfs = get_vfs(active_lun); disk_write(vfs, sector_buffer, active_addr, 1);