Przeglądaj źródła

RP2040: Fix regression in USBMassStoragePresentImages

After commit 5750279 (February 11 2025), the functionality where
each disk image was presented as a separate USB drive was broken
on some systems. Whether it worked depends on speed of SD card
initialization versus how fast the PC enumerates the USB device.

This commit forces USB re-enumeration if the number of MSC LUNs
changes.
Petteri Aimonen 6 miesięcy temu
rodzic
commit
2a6e66ab7f

+ 24 - 4
lib/ZuluSCSI_platform_RP2MCU/ZuluSCSI_platform_msc.cpp

@@ -60,6 +60,7 @@ static struct {
   uint8_t lun_count = 0;
   uint8_t unitReady = 0;
   uint8_t SDMode = 1;
+  uint8_t lun_count_prev_response = 0;
 } g_MSC;
 
 void platform_msc_lock_set(bool block)
@@ -209,6 +210,18 @@ void platform_enter_msc() {
 
   // MSC is ready for read/write
   g_MSC.unitReady = g_MSC.lun_count;
+
+  if (g_MSC.lun_count_prev_response != 0 &&
+      g_MSC.lun_count != g_MSC.lun_count_prev_response)
+  {
+    // Host has already queried us for the number of LUNs, but
+    // our response has now changed. We need to re-enumerate to
+    // update it.
+    g_MSC.lun_count_prev_response = 0;
+    tud_disconnect();
+    delay(250);
+    tud_connect();
+  }
 }
 
 /* perform any cleanup tasks for the MSC-specific functionality */
@@ -243,18 +256,25 @@ extern "C" void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8],
 extern "C" uint8_t tud_msc_get_maxlun_cb(void)
 {
   MSCScopedLock lock;
-  if (g_msc_initiator) return init_msc_get_maxlun_cb();
+  uint8_t result;
 
-  if (g_MSC.lun_count != 0)
+  if (g_msc_initiator)
   {
-    return g_MSC.lun_count; // number of LUNs supported
+    result = init_msc_get_maxlun_cb();
+  }
+  else if (g_MSC.lun_count != 0)
+  {
+    result = g_MSC.lun_count; // number of LUNs supported
   }
   else
   {
     // Returning 0 makes TU_VERIFY(maxlun); fail in tinyusb/src/class/msc/msc_device.c:378
     // This stalls the endpoint and causes an unnecessary enumeration delay on Windows.
-    return 1;
+    result = 1;
   }
+
+  g_MSC.lun_count_prev_response = result;
+  return result;
 }
 
 // return writable status