@@ -204,25 +204,25 @@ uint8_t tud_msc_get_maxlun_cb(void) {
204204 return LUN_COUNT ;
205205}
206206
207+ // PREVENT ALLOW MEDIUM REMOVAL: TinyUSB routes this to its own dedicated callback,
208+ // NOT tud_msc_scsi_cb. Reply unsupported on all LUNs so the host keeps TUR polling
209+ // on every LUN — eject/storage.remount() works uniformly across CIRCUITPY, SAVES, SD.
210+ bool tud_msc_prevent_allow_medium_removal_cb (uint8_t lun , uint8_t prohibit_removal , uint8_t control ) {
211+ (void )prohibit_removal ;
212+ (void )control ;
213+ tud_msc_set_sense (lun , SCSI_SENSE_ILLEGAL_REQUEST , 0x20 , 0x00 );
214+ return false;
215+ }
216+
207217// Callback invoked when received an SCSI command not in built-in list below
208218// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, TEST_UNIT_READY, START_STOP_UNIT, MODE_SENSE6, REQUEST_SENSE
209- // - READ10 and WRITE10 have their own callbacks
219+ // - PREVENT_ALLOW_MEDIUM_REMOVAL, READ10, WRITE10 have their own callbacks
210220int32_t tud_msc_scsi_cb (uint8_t lun , const uint8_t scsi_cmd [16 ], void * buffer , uint16_t bufsize ) {
211221 // Note that no command uses a response right now.
212222 const void * response = NULL ;
213223 int32_t resplen = 0 ;
214224
215225 switch (scsi_cmd [0 ]) {
216- case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL :
217- // All LUNs advertise is_removable=1 in INQUIRY (tinyusb default).
218- // Reply "unsupported" so the host keeps polling TUR and can
219- // re-mount after an eject. Responding OK tells the host to skip
220- // TUR polling, which breaks re-mount and can miss SD insertion
221- // events at boot. See adafruit/circuitpython#6555.
222- tud_msc_set_sense (lun , SCSI_SENSE_ILLEGAL_REQUEST , 0x20 , 0x00 );
223- resplen = -1 ;
224- break ;
225-
226226 default :
227227 // Set Sense = Invalid Command Operation
228228 tud_msc_set_sense (lun , SCSI_SENSE_ILLEGAL_REQUEST , 0x20 , 0x00 );
0 commit comments