summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2018-03-14 13:54:20 -0400
committerGitHub <noreply@github.com>2018-03-14 13:54:20 -0400
commit07dd26d722d2b455e22581635749037e5979fa04 (patch)
treea4b5821c9df0bc2b2c407ea6d9d807b9dffdf681
parentb64d56826743a58c1aede6cdbbbc86209f177dec (diff)
parent7a3f86d184c42a7957a135d9dfc23b1149e2708c (diff)
Merge pull request #679 from tannewt/usb_race3
Check usb_busy up front in usb background function.
-rw-r--r--ports/atmel-samd/usb_mass_storage.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/ports/atmel-samd/usb_mass_storage.c b/ports/atmel-samd/usb_mass_storage.c
index b337839d5..9b6715158 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);