27
27
28
28
#if CFG_TUD_MSC
29
29
30
+ // whether host does safe-eject
31
+ static bool ejected = false;
32
+
30
33
// Some MCU doesn't have enough 8KB SRAM to store the whole disk
31
34
// We will use Flash as read-only disk with board that has
32
35
// CFG_EXAMPLE_MSC_READONLY defined
@@ -136,7 +139,14 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun)
136
139
{
137
140
(void ) lun ;
138
141
139
- return true; // RAM disk is always ready
142
+ // RAM disk is ready until ejected
143
+ if (ejected ) {
144
+ // Additional Sense 3A-00 is NOT_FOUND
145
+ tud_msc_set_sense (lun , SCSI_SENSE_NOT_READY , 0x3a , 0x00 );
146
+ return false;
147
+ }
148
+
149
+ return true;
140
150
}
141
151
142
152
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
@@ -165,6 +175,7 @@ bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, boo
165
175
}else
166
176
{
167
177
// unload disk storage
178
+ ejected = true;
168
179
}
169
180
}
170
181
@@ -177,10 +188,24 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff
177
188
{
178
189
(void ) lun ;
179
190
191
+ // out of ramdisk
192
+ if ( lba >= DISK_BLOCK_NUM ) return -1 ;
193
+
180
194
uint8_t const * addr = msc_disk [lba ] + offset ;
181
195
memcpy (buffer , addr , bufsize );
182
196
183
- return bufsize ;
197
+ return (int32_t ) bufsize ;
198
+ }
199
+
200
+ bool tud_msc_is_writable_cb (uint8_t lun )
201
+ {
202
+ (void ) lun ;
203
+
204
+ #ifdef CFG_EXAMPLE_MSC_READONLY
205
+ return false;
206
+ #else
207
+ return true;
208
+ #endif
184
209
}
185
210
186
211
// Callback invoked when received WRITE10 command.
@@ -189,14 +214,17 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t*
189
214
{
190
215
(void ) lun ;
191
216
217
+ // out of ramdisk
218
+ if ( lba >= DISK_BLOCK_NUM ) return -1 ;
219
+
192
220
#ifndef CFG_EXAMPLE_MSC_READONLY
193
221
uint8_t * addr = msc_disk [lba ] + offset ;
194
222
memcpy (addr , buffer , bufsize );
195
223
#else
196
224
(void ) lba ; (void ) offset ; (void ) buffer ;
197
225
#endif
198
226
199
- return bufsize ;
227
+ return ( int32_t ) bufsize ;
200
228
}
201
229
202
230
// Callback invoked when received an SCSI command not in built-in list below
@@ -207,18 +235,13 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
207
235
// read10 & write10 has their own callback and MUST not be handled here
208
236
209
237
void const * response = NULL ;
210
- uint16_t resplen = 0 ;
238
+ int32_t resplen = 0 ;
211
239
212
240
// most scsi handled is input
213
241
bool in_xfer = true;
214
242
215
243
switch (scsi_cmd [0 ])
216
244
{
217
- case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL :
218
- // Host is about to read/write etc ... better not to disconnect disk
219
- resplen = 0 ;
220
- break ;
221
-
222
245
default :
223
246
// Set Sense = Invalid Command Operation
224
247
tud_msc_set_sense (lun , SCSI_SENSE_ILLEGAL_REQUEST , 0x20 , 0x00 );
@@ -235,14 +258,14 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
235
258
{
236
259
if (in_xfer )
237
260
{
238
- memcpy (buffer , response , resplen );
261
+ memcpy (buffer , response , ( size_t ) resplen );
239
262
}else
240
263
{
241
264
// SCSI output
242
265
}
243
266
}
244
267
245
- return resplen ;
268
+ return ( int32_t ) resplen ;
246
269
}
247
270
248
271
#endif
0 commit comments