@@ -59,59 +59,18 @@ static fs_user_mount_t* get_vfs(int lun) {
5959}
6060
6161// 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
6363// - READ10 and WRITE10 have their own callbacks
6464int32_t tud_msc_scsi_cb (uint8_t lun , const uint8_t scsi_cmd [16 ], void * buffer , uint16_t bufsize ) {
6565 const void * response = NULL ;
6666 int32_t resplen = 0 ;
6767
6868 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-
8569 case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL :
8670 // Host is about to read/write etc ... better not to disconnect disk
8771 resplen = 0 ;
8872 break ;
8973
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-
11574 default :
11675 // Set Sense = Invalid Command Operation
11776 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,
12786 }
12887
12988 // copy response to stack's buffer if any
130- if ( response && resplen ) {
89+ if ( response && ( resplen > 0 ) ) {
13190 memcpy (buffer , response , resplen );
13291 }
13392
@@ -206,3 +165,54 @@ void tud_msc_write10_complete_cb (uint8_t lun) {
206165 // This write is complete, start the autoreload clock.
207166 autoreload_start ();
208167}
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