@@ -45,6 +45,11 @@ static bool ejected[LUN_COUNT] = { [0 ... (LUN_COUNT - 1)] = true};
45
45
static bool eject_once [LUN_COUNT ] = { [0 ... (LUN_COUNT - 1 )] = false};
46
46
static bool locked [LUN_COUNT ] = { [0 ... (LUN_COUNT - 1 )] = false};
47
47
48
+ // Set to true if a write was in a file data or metadata area,
49
+ // as opposed to in the filesystem metadata area (e.g., dirty bit).
50
+ // Used to determine if an auto-reload is warranted.
51
+ static bool content_write [LUN_COUNT ] = { [0 ... (LUN_COUNT - 1 )] = false};
52
+
48
53
#include "tusb.h"
49
54
50
55
static const uint8_t usb_msc_descriptor_template [] = {
@@ -141,6 +146,7 @@ static fs_user_mount_t *get_vfs(int lun) {
141
146
if (lun == SDCARD_LUN ) {
142
147
const char * path_under_mount ;
143
148
fs_user_mount_t * sdcard = filesystem_for_path ("/sd" , & path_under_mount );
149
+ // If "/sd" is on the root filesystem, nothing has been mounted there.
144
150
if (sdcard != root && (sdcard -> blockdev .flags & MP_BLOCKDEV_FLAG_NATIVE ) != 0 ) {
145
151
return sdcard ;
146
152
} else {
@@ -290,34 +296,50 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t *
290
296
if (vfs == NULL ) {
291
297
return -1 ;
292
298
}
299
+
293
300
disk_write (vfs , buffer , lba , block_count );
294
301
// Since by getting here we assume the mount is read-only to
295
- // MicroPython let's update the cached FatFs sector if it's the one
302
+ // CircuitPython let's update the cached FatFs sector if it's the one
296
303
// we just wrote.
304
+ if
297
305
#if FF_MAX_SS != FF_MIN_SS
298
- if (vfs -> fatfs .ssize == MSC_FLASH_BLOCK_SIZE ) {
306
+ (vfs -> fatfs .ssize == MSC_FLASH_BLOCK_SIZE )
299
307
#else
300
308
// The compiler can optimize this away.
301
- if (FF_MAX_SS == FILESYSTEM_BLOCK_SIZE ) {
302
- #endif
309
+ (FF_MAX_SS == FILESYSTEM_BLOCK_SIZE )
310
+ #endif
311
+ {
303
312
if (lba == vfs -> fatfs .winsect && lba > 0 ) {
304
313
memcpy (vfs -> fatfs .win ,
305
314
buffer + MSC_FLASH_BLOCK_SIZE * (vfs -> fatfs .winsect - lba ),
306
315
MSC_FLASH_BLOCK_SIZE );
307
316
}
308
317
}
309
318
319
+ // A write to an lba below fatbase is in the filesystem metadata (BPB) area or the "Reserved Region",
320
+ // and is probably setting or clearing the dirty bit. This should not trigger auto-reload.
321
+ // All other writes will trigger auto-reload.
322
+ if (lba >= vfs -> fatfs .fatbase ) {
323
+ content_write [lun ] = true;
324
+ }
325
+
310
326
return block_count * MSC_FLASH_BLOCK_SIZE ;
311
327
}
312
328
313
329
// Callback invoked when WRITE10 command is completed (status received and accepted by host).
314
330
// used to flush any pending cache.
315
331
void tud_msc_write10_complete_cb (uint8_t lun ) {
316
- (void )lun ;
317
-
318
- // This write is complete; initiate an autoreload.
319
332
autoreload_resume (AUTORELOAD_SUSPEND_USB );
320
- autoreload_trigger ();
333
+
334
+ // This write is complete; initiate an autoreload if this was a file data or metadata write,
335
+ // not just a dirty-bit write.
336
+ if (content_write [lun ] &&
337
+ // Fast path: lun == 0 is CIRCUITPY, which can always trigger auto-reload if enabled.
338
+ // Don't autoreload if this lun was mounted by the user: that will cause a VM stop and an unmount.
339
+ (lun == 0 || !gc_ptr_on_heap (get_vfs (lun )))) {
340
+ autoreload_trigger ();
341
+ content_write [lun ] = false;
342
+ }
321
343
}
322
344
323
345
// Invoked when received SCSI_CMD_INQUIRY
@@ -337,7 +359,7 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun) {
337
359
return false;
338
360
}
339
361
340
- #if CIRCUITPY_SDCARDIO
362
+ #if CIRCUITPY_SDCARD_USB
341
363
if (lun == SDCARD_LUN ) {
342
364
automount_sd_card ();
343
365
}
0 commit comments