@@ -59,59 +59,18 @@ static fs_user_mount_t* get_vfs(int lun) {
59
59
}
60
60
61
61
// Callback invoked when received an SCSI command not in built-in list below
62
- // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
62
+ // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, TEST_UNIT_READY, START_STOP_UNIT, MODE_SENSE6, REQUEST_SENSE
63
63
// - READ10 and WRITE10 have their own callbacks
64
64
int32_t tud_msc_scsi_cb (uint8_t lun , const uint8_t scsi_cmd [16 ], void * buffer , uint16_t bufsize ) {
65
65
const void * response = NULL ;
66
66
int32_t resplen = 0 ;
67
67
68
68
switch ( scsi_cmd [0 ] ) {
69
- case SCSI_CMD_TEST_UNIT_READY :
70
- // Command that host uses to check our readiness before sending other commands
71
- resplen = 0 ;
72
- if (lun > 1 ) {
73
- resplen = -1 ;
74
- } else {
75
- fs_user_mount_t * current_mount = get_vfs (lun );
76
- if (current_mount == NULL ) {
77
- resplen = -1 ;
78
- }
79
- if (ejected [lun ]) {
80
- resplen = -1 ;
81
- }
82
- }
83
- break ;
84
-
85
69
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL :
86
70
// Host is about to read/write etc ... better not to disconnect disk
87
71
resplen = 0 ;
88
72
break ;
89
73
90
- case SCSI_CMD_START_STOP_UNIT :
91
- {
92
- // Host try to eject/safe remove/poweroff us. We could safely disconnect with disk storage, or go into lower power
93
- const scsi_start_stop_unit_t * start_stop = (const scsi_start_stop_unit_t * ) scsi_cmd ;
94
- // Start bit = 0 : low power mode, if load_eject = 1 : unmount disk storage as well
95
- // Start bit = 1 : Ready mode, if load_eject = 1 : mount disk storage
96
- resplen = 0 ;
97
- if (start_stop -> load_eject == 1 ) {
98
- if (lun > 1 ) {
99
- resplen = -1 ;
100
- } else {
101
- fs_user_mount_t * current_mount = get_vfs (lun );
102
- if (current_mount == NULL ) {
103
- resplen = -1 ;
104
- }
105
- if (disk_ioctl (current_mount , CTRL_SYNC , NULL ) != RES_OK ) {
106
- resplen = -1 ;
107
- } else {
108
- ejected [lun ] = true;
109
- }
110
- }
111
- }
112
- }
113
- break ;
114
-
115
74
default :
116
75
// Set Sense = Invalid Command Operation
117
76
tud_msc_set_sense (lun , SCSI_SENSE_ILLEGAL_REQUEST , 0x20 , 0x00 );
@@ -127,7 +86,7 @@ int32_t tud_msc_scsi_cb (uint8_t lun, const uint8_t scsi_cmd[16], void* buffer,
127
86
}
128
87
129
88
// copy response to stack's buffer if any
130
- if ( response && resplen ) {
89
+ if ( response && ( resplen > 0 ) ) {
131
90
memcpy (buffer , response , resplen );
132
91
}
133
92
@@ -206,3 +165,54 @@ void tud_msc_write10_complete_cb (uint8_t lun) {
206
165
// This write is complete, start the autoreload clock.
207
166
autoreload_start ();
208
167
}
168
+
169
+ // Invoked when received SCSI_CMD_INQUIRY
170
+ // Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
171
+ void tud_msc_inquiry_cb (uint8_t lun , uint8_t vendor_id [8 ], uint8_t product_id [16 ], uint8_t product_rev [4 ]) {
172
+ (void ) lun ;
173
+
174
+ memcpy (vendor_id , CFG_TUD_MSC_VENDOR , strlen (CFG_TUD_MSC_VENDOR ));
175
+ memcpy (product_id , CFG_TUD_MSC_PRODUCT , strlen (CFG_TUD_MSC_PRODUCT ));
176
+ memcpy (product_rev , CFG_TUD_MSC_PRODUCT_REV , strlen (CFG_TUD_MSC_PRODUCT_REV ));
177
+ }
178
+
179
+ // Invoked when received Test Unit Ready command.
180
+ // return true allowing host to read/write this LUN e.g SD card inserted
181
+ bool tud_msc_test_unit_ready_cb (uint8_t lun ) {
182
+ if (lun > 1 ) {
183
+ return false;
184
+ }
185
+
186
+ fs_user_mount_t * current_mount = get_vfs (lun );
187
+ if (current_mount == NULL ) {
188
+ return false;
189
+ }
190
+ if (ejected [lun ]) {
191
+ return false;
192
+ }
193
+
194
+ return true;
195
+ }
196
+
197
+ // Invoked when received Start Stop Unit command
198
+ // - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
199
+ // - Start = 1 : active mode, if load_eject = 1 : load disk storage
200
+ bool tud_msc_start_stop_cb (uint8_t lun , uint8_t power_condition , bool start , bool load_eject ) {
201
+ if (load_eject ) {
202
+ if (lun > 1 ) {
203
+ return false;
204
+ } else {
205
+ fs_user_mount_t * current_mount = get_vfs (lun );
206
+ if (current_mount == NULL ) {
207
+ return false;
208
+ }
209
+ if (disk_ioctl (current_mount , CTRL_SYNC , NULL ) != RES_OK ) {
210
+ return false;
211
+ } else {
212
+ ejected [lun ] = true;
213
+ }
214
+ }
215
+ }
216
+
217
+ return true;
218
+ }
0 commit comments