@@ -63,10 +63,10 @@ static fs_user_mount_t* get_vfs(int lun) {
6363/* Inquiry Information */
6464// This is designed to handle the common case where we have an internal file
6565// system and an optional SD card.
66- static uint8_t inquiry_info [2 ][36 ];
66+ COMPILER_ALIGNED ( 4 ) static uint8_t inquiry_info [2 ][36 ];
6767
6868/* Capacities of Disk */
69- static uint8_t format_capa [2 ][8 ];
69+ COMPILER_ALIGNED ( 4 ) static uint8_t format_capa [2 ][8 ];
7070
7171/**
7272 * \brief Eject Disk
@@ -256,30 +256,34 @@ 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 -- ;
262- if (active_nblocks == 0 ) {
263- active_read = false;
264- }
265263 }
266264
267265 if (active_write ) {
268266 sector_loaded = true;
269267 }
270268 usb_busy = false;
269+ CRITICAL_SECTION_LEAVE ();
271270
272271 return ERR_NONE ;
273272}
274273
275274// The start_read callback begins a read transaction which we accept but delay our response until the "main thread" calls usb_msc_background. Once it does, we read immediately from the drive into our cache and trigger the USB DMA to output the sector. Once the sector is transmitted, xfer_done will be called.
276275void usb_msc_background (void ) {
277276 if (active_read && !usb_busy ) {
277+ if (active_nblocks == 0 ) {
278+ active_read = false;
279+ return ;
280+ }
278281 fs_user_mount_t * vfs = get_vfs (active_lun );
279282 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;
283+ CRITICAL_SECTION_ENTER ();
284+ int32_t result = mscdf_xfer_blocks (true, sector_buffer , 1 );
285+ usb_busy = result == ERR_NONE ;
286+ CRITICAL_SECTION_LEAVE ();
283287 }
284288 if (active_write && !usb_busy ) {
285289 if (sector_loaded ) {
@@ -306,8 +310,14 @@ void usb_msc_background(void) {
306310 }
307311 // Load more blocks from USB if they are needed.
308312 if (active_nblocks > 0 ) {
313+ // Turn off interrupts because with them on,
314+ // usb_msc_xfer_done could be called before we update
315+ // usb_busy. If that happened, we'd overwrite the fact that
316+ // the transfer actually already finished.
317+ CRITICAL_SECTION_ENTER ();
309318 int32_t result = mscdf_xfer_blocks (false, sector_buffer , 1 );
310- usb_busy = result != ERR_NONE ;
319+ usb_busy = result == ERR_NONE ;
320+ CRITICAL_SECTION_LEAVE ();
311321 } else {
312322 mscdf_xfer_blocks (false, NULL , 0 );
313323 active_write = false;
0 commit comments