Skip to content

Commit 971bd7e

Browse files
committed
atmel-samd: Improve MSC reliability.
* Be more liberal with critical sections to ensure ordering. * Correct usb_busy so that it is busy when no errors occur on transfer. I believe it worked before because it would be false momentarily until a second transfer was attempted and a busy error was returned, therefore setting usb_busy to true. That risks the first "failed" transfer completing before a second one is attempted.
1 parent 7a901cf commit 971bd7e

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

ports/atmel-samd/usb_mass_storage.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ int32_t usb_msc_xfer_done(uint8_t lun) {
256256
return ERR_DENIED;
257257
}
258258

259+
CRITICAL_SECTION_ENTER();
259260
if (active_read) {
260261
active_addr += 1;
261262
active_nblocks--;
@@ -268,6 +269,7 @@ int32_t usb_msc_xfer_done(uint8_t lun) {
268269
sector_loaded = true;
269270
}
270271
usb_busy = false;
272+
CRITICAL_SECTION_LEAVE();
271273

272274
return ERR_NONE;
273275
}
@@ -277,9 +279,10 @@ void usb_msc_background(void) {
277279
if (active_read && !usb_busy) {
278280
fs_user_mount_t * vfs = get_vfs(active_lun);
279281
disk_read(vfs, sector_buffer, active_addr, 1);
280-
// TODO(tannewt): Check the read result.
281-
mscdf_xfer_blocks(true, sector_buffer, 1);
282-
usb_busy = true;
282+
CRITICAL_SECTION_ENTER();
283+
int32_t result = mscdf_xfer_blocks(true, sector_buffer, 1);
284+
usb_busy = result == ERR_NONE;
285+
CRITICAL_SECTION_LEAVE();
283286
}
284287
if (active_write && !usb_busy) {
285288
if (sector_loaded) {
@@ -306,8 +309,14 @@ void usb_msc_background(void) {
306309
}
307310
// Load more blocks from USB if they are needed.
308311
if (active_nblocks > 0) {
312+
// Turn off interrupts because with them on,
313+
// usb_msc_xfer_done could be called before we update
314+
// usb_busy. If that happened, we'd overwrite the fact that
315+
// the transfer actually already finished.
316+
CRITICAL_SECTION_ENTER();
309317
int32_t result = mscdf_xfer_blocks(false, sector_buffer, 1);
310-
usb_busy = result != ERR_NONE;
318+
usb_busy = result == ERR_NONE;
319+
CRITICAL_SECTION_LEAVE();
311320
} else {
312321
mscdf_xfer_blocks(false, NULL, 0);
313322
active_write = false;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy