1 /*
2  * Copyright (c) 2022, sakumisu
3  * Copyright (c) 2024, zhihong chen
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 #include "usbd_core.h"
8 #include "usbd_msc.h"
9 #include "usb_scsi.h"
10 
11 #undef USB_DBG_TAG
12 #define USB_DBG_TAG "usbd_msc"
13 #include "usb_log.h"
14 
15 #define MSD_OUT_EP_IDX 0
16 #define MSD_IN_EP_IDX  1
17 
18 /* Describe EndPoints configuration */
19 static struct usbd_endpoint mass_ep_data[CONFIG_USBDEV_MAX_BUS][2];
20 
21 /* MSC Bulk-only Stage */
22 enum Stage {
23     MSC_READ_CBW = 0, /* Command Block Wrapper */
24     MSC_DATA_OUT = 1, /* Data Out Phase */
25     MSC_DATA_IN = 2,  /* Data In Phase */
26     MSC_SEND_CSW = 3, /* Command Status Wrapper */
27     MSC_WAIT_CSW = 4, /* Command Status Wrapper */
28 };
29 
30 /* Device data structure */
31 USB_NOCACHE_RAM_SECTION struct usbd_msc_priv {
32     /* state of the bulk-only state machine */
33     enum Stage stage;
34     USB_MEM_ALIGNX struct CBW cbw;
35     USB_MEM_ALIGNX struct CSW csw;
36 
37     USB_MEM_ALIGNX bool readonly;
38     bool popup;
39     uint8_t sKey; /* Sense key */
40     uint8_t ASC;  /* Additional Sense Code */
41     uint8_t ASQ;  /* Additional Sense Qualifier */
42     uint8_t max_lun;
43     uint32_t start_sector;
44     uint32_t nsectors;
45     uint32_t scsi_blk_size[CONFIG_USBDEV_MSC_MAX_LUN];
46     uint32_t scsi_blk_nbr[CONFIG_USBDEV_MSC_MAX_LUN];
47 
48     USB_MEM_ALIGNX uint8_t block_buffer[CONFIG_USBDEV_MSC_MAX_BUFSIZE];
49 
50 #if defined(CONFIG_USBDEV_MSC_THREAD)
51     usb_osal_mq_t usbd_msc_mq;
52     usb_osal_thread_t usbd_msc_thread;
53     uint32_t nbytes;
54 #elif defined(CONFIG_USBDEV_MSC_POLLING)
55     uint32_t event;
56     uint32_t nbytes;
57 #endif
58 } g_usbd_msc[CONFIG_USBDEV_MAX_BUS];
59 
60 #ifdef CONFIG_USBDEV_MSC_THREAD
61 static void usbdev_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
62 #endif
63 
usdb_msc_set_max_lun(uint8_t busid)64 static void usdb_msc_set_max_lun(uint8_t busid)
65 {
66     g_usbd_msc[busid].max_lun = CONFIG_USBDEV_MSC_MAX_LUN - 1u;
67 }
68 
usbd_msc_reset(uint8_t busid)69 static void usbd_msc_reset(uint8_t busid)
70 {
71     g_usbd_msc[busid].stage = MSC_READ_CBW;
72     g_usbd_msc[busid].readonly = false;
73 }
74 
msc_storage_class_interface_request_handler(uint8_t busid,struct usb_setup_packet * setup,uint8_t ** data,uint32_t * len)75 static int msc_storage_class_interface_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
76 {
77     USB_LOG_DBG("MSC Class request: "
78                 "bRequest 0x%02x\r\n",
79                 setup->bRequest);
80 
81     switch (setup->bRequest) {
82         case MSC_REQUEST_RESET:
83             usbd_msc_reset(busid);
84             break;
85 
86         case MSC_REQUEST_GET_MAX_LUN:
87             (*data)[0] = g_usbd_msc[busid].max_lun;
88             *len = 1;
89             break;
90 
91         default:
92             USB_LOG_WRN("Unhandled MSC Class bRequest 0x%02x\r\n", setup->bRequest);
93             return -1;
94     }
95 
96     return 0;
97 }
98 
msc_storage_notify_handler(uint8_t busid,uint8_t event,void * arg)99 void msc_storage_notify_handler(uint8_t busid, uint8_t event, void *arg)
100 {
101     (void)arg;
102 
103     switch (event) {
104         case USBD_EVENT_INIT:
105 #if defined(CONFIG_USBDEV_MSC_THREAD)
106             g_usbd_msc[busid].usbd_msc_mq = usb_osal_mq_create(1);
107             if (g_usbd_msc[busid].usbd_msc_mq == NULL) {
108                 USB_LOG_ERR("No memory to alloc for g_usbd_msc[busid].usbd_msc_mq\r\n");
109             }
110             g_usbd_msc[busid].usbd_msc_thread = usb_osal_thread_create("usbd_msc", CONFIG_USBDEV_MSC_STACKSIZE, CONFIG_USBDEV_MSC_PRIO, usbdev_msc_thread, (void *)(uint32_t)busid);
111             if (g_usbd_msc[busid].usbd_msc_thread == NULL) {
112                 USB_LOG_ERR("No memory to alloc for g_usbd_msc[busid].usbd_msc_thread\r\n");
113             }
114 #elif defined(CONFIG_USBDEV_MSC_POLLING)
115             g_usbd_msc[busid].event = 0;
116 #endif
117             break;
118         case USBD_EVENT_DEINIT:
119 #if defined(CONFIG_USBDEV_MSC_THREAD)
120             if (g_usbd_msc[busid].usbd_msc_mq) {
121                 usb_osal_mq_delete(g_usbd_msc[busid].usbd_msc_mq);
122             }
123             if (g_usbd_msc[busid].usbd_msc_thread) {
124                 usb_osal_thread_delete(g_usbd_msc[busid].usbd_msc_thread);
125             }
126 #endif
127             break;
128         case USBD_EVENT_RESET:
129             usbd_msc_reset(busid);
130             break;
131         case USBD_EVENT_CONFIGURED:
132             USB_LOG_DBG("Start reading cbw\r\n");
133             usbd_ep_start_read(busid, mass_ep_data[busid][MSD_OUT_EP_IDX].ep_addr, (uint8_t *)&g_usbd_msc[busid].cbw, USB_SIZEOF_MSC_CBW);
134             break;
135 
136         default:
137             break;
138     }
139 }
140 
usbd_msc_bot_abort(uint8_t busid)141 static void usbd_msc_bot_abort(uint8_t busid)
142 {
143     if ((g_usbd_msc[busid].cbw.bmFlags == 0) && (g_usbd_msc[busid].cbw.dDataLength != 0)) {
144         usbd_ep_set_stall(busid, mass_ep_data[busid][MSD_OUT_EP_IDX].ep_addr);
145     }
146     usbd_ep_set_stall(busid, mass_ep_data[busid][MSD_IN_EP_IDX].ep_addr);
147     usbd_ep_start_read(busid, mass_ep_data[busid][0].ep_addr, (uint8_t *)&g_usbd_msc[busid].cbw, USB_SIZEOF_MSC_CBW);
148 }
149 
usbd_msc_send_csw(uint8_t busid,uint8_t CSW_Status)150 static void usbd_msc_send_csw(uint8_t busid, uint8_t CSW_Status)
151 {
152     g_usbd_msc[busid].csw.dSignature = MSC_CSW_Signature;
153     g_usbd_msc[busid].csw.bStatus = CSW_Status;
154 
155     /* updating the State Machine , so that we wait CSW when this
156 	 * transfer is complete, ie when we get a bulk in callback
157 	 */
158     g_usbd_msc[busid].stage = MSC_WAIT_CSW;
159 
160     USB_LOG_DBG("Send csw\r\n");
161     usbd_ep_start_write(busid, mass_ep_data[busid][MSD_IN_EP_IDX].ep_addr, (uint8_t *)&g_usbd_msc[busid].csw, sizeof(struct CSW));
162 }
163 
usbd_msc_send_info(uint8_t busid,uint8_t * buffer,uint8_t size)164 static void usbd_msc_send_info(uint8_t busid, uint8_t *buffer, uint8_t size)
165 {
166     size = MIN(size, g_usbd_msc[busid].cbw.dDataLength);
167 
168     /* updating the State Machine , so that we send CSW when this
169 	 * transfer is complete, ie when we get a bulk in callback
170 	 */
171     g_usbd_msc[busid].stage = MSC_SEND_CSW;
172 
173     usbd_ep_start_write(busid, mass_ep_data[busid][MSD_IN_EP_IDX].ep_addr, buffer, size);
174 
175     g_usbd_msc[busid].csw.dDataResidue -= size;
176     g_usbd_msc[busid].csw.bStatus = CSW_STATUS_CMD_PASSED;
177 }
178 
179 static bool SCSI_processWrite(uint8_t busid, uint32_t nbytes);
180 static bool SCSI_processRead(uint8_t busid);
181 
182 /**
183 * @brief  SCSI_SetSenseData
184 *         Load the last error code in the error list
185 * @param  sKey: Sense Key
186 * @param  ASC: Additional Sense Code
187 * @retval none
188 
189 */
SCSI_SetSenseData(uint8_t busid,uint32_t KCQ)190 static void SCSI_SetSenseData(uint8_t busid, uint32_t KCQ)
191 {
192     g_usbd_msc[busid].sKey = (uint8_t)(KCQ >> 16);
193     g_usbd_msc[busid].ASC = (uint8_t)(KCQ >> 8);
194     g_usbd_msc[busid].ASQ = (uint8_t)(KCQ);
195 }
196 
197 /**
198  * @brief SCSI Command list
199  *
200  */
201 
SCSI_testUnitReady(uint8_t busid,uint8_t ** data,uint32_t * len)202 static bool SCSI_testUnitReady(uint8_t busid, uint8_t **data, uint32_t *len)
203 {
204     if (g_usbd_msc[busid].cbw.dDataLength != 0U) {
205         SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
206         return false;
207     }
208     *data = NULL;
209     *len = 0;
210     return true;
211 }
212 
SCSI_requestSense(uint8_t busid,uint8_t ** data,uint32_t * len)213 static bool SCSI_requestSense(uint8_t busid, uint8_t **data, uint32_t *len)
214 {
215     uint8_t data_len = SCSIRESP_FIXEDSENSEDATA_SIZEOF;
216     if (g_usbd_msc[busid].cbw.dDataLength == 0U) {
217         SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
218         return false;
219     }
220 
221     if (g_usbd_msc[busid].cbw.CB[4] < SCSIRESP_FIXEDSENSEDATA_SIZEOF) {
222         data_len = g_usbd_msc[busid].cbw.CB[4];
223     }
224 
225     uint8_t request_sense[SCSIRESP_FIXEDSENSEDATA_SIZEOF] = {
226         0x70,
227         0x00,
228         0x00, /* Sense Key */
229         0x00,
230         0x00,
231         0x00,
232         0x00,
233         SCSIRESP_FIXEDSENSEDATA_SIZEOF - 8,
234         0x00,
235         0x00,
236         0x00,
237         0x00,
238         0x00, /* Additional Sense Code */
239         0x00, /* Additional Sense Request */
240         0x00,
241         0x00,
242         0x00,
243         0x00,
244     };
245 
246     request_sense[2] = g_usbd_msc[busid].sKey;
247     request_sense[12] = g_usbd_msc[busid].ASC;
248     request_sense[13] = g_usbd_msc[busid].ASQ;
249 #if 0
250     request_sense[ 2] = 0x06;           /* UNIT ATTENTION */
251     request_sense[12] = 0x28;           /* Additional Sense Code: Not ready to ready transition */
252     request_sense[13] = 0x00;           /* Additional Sense Code Qualifier */
253 #endif
254 #if 0
255     request_sense[ 2] = 0x02;           /* NOT READY */
256     request_sense[12] = 0x3A;           /* Additional Sense Code: Medium not present */
257     request_sense[13] = 0x00;           /* Additional Sense Code Qualifier */
258 #endif
259 #if 0
260     request_sense[ 2] = 0x05;         /* ILLEGAL REQUEST */
261     request_sense[12] = 0x20;         /* Additional Sense Code: Invalid command */
262     request_sense[13] = 0x00;         /* Additional Sense Code Qualifier */
263 #endif
264 #if 0
265     request_sense[ 2] = 0x00;         /* NO SENSE */
266     request_sense[12] = 0x00;         /* Additional Sense Code: No additional code */
267     request_sense[13] = 0x00;         /* Additional Sense Code Qualifier */
268 #endif
269 
270     memcpy(*data, (uint8_t *)request_sense, data_len);
271     *len = data_len;
272     return true;
273 }
274 
SCSI_inquiry(uint8_t busid,uint8_t ** data,uint32_t * len)275 static bool SCSI_inquiry(uint8_t busid, uint8_t **data, uint32_t *len)
276 {
277     uint8_t data_len = SCSIRESP_INQUIRY_SIZEOF;
278 
279     uint8_t inquiry00[6] = {
280         0x00,
281         0x00,
282         0x00,
283         (0x06 - 4U),
284         0x00,
285         0x80
286     };
287 
288     /* USB Mass storage VPD Page 0x80 Inquiry Data for Unit Serial Number */
289     uint8_t inquiry80[8] = {
290         0x00,
291         0x80,
292         0x00,
293         0x08,
294         0x20, /* Put Product Serial number */
295         0x20,
296         0x20,
297         0x20
298     };
299 
300     uint8_t inquiry[SCSIRESP_INQUIRY_SIZEOF] = {
301         /* 36 */
302 
303         /* LUN 0 */
304         0x00,
305         0x80,
306         0x02,
307         0x02,
308         (SCSIRESP_INQUIRY_SIZEOF - 5),
309         0x00,
310         0x00,
311         0x00,
312         ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
313         ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', /* Product      : 16 Bytes */
314         ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
315         ' ', ' ', ' ', ' ' /* Version      : 4 Bytes */
316     };
317 
318     memcpy(&inquiry[8], CONFIG_USBDEV_MSC_MANUFACTURER_STRING, strlen(CONFIG_USBDEV_MSC_MANUFACTURER_STRING));
319     memcpy(&inquiry[16], CONFIG_USBDEV_MSC_PRODUCT_STRING, strlen(CONFIG_USBDEV_MSC_PRODUCT_STRING));
320     memcpy(&inquiry[32], CONFIG_USBDEV_MSC_VERSION_STRING, strlen(CONFIG_USBDEV_MSC_VERSION_STRING));
321 
322     if (g_usbd_msc[busid].cbw.dDataLength == 0U) {
323         SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
324         return false;
325     }
326 
327     if ((g_usbd_msc[busid].cbw.CB[1] & 0x01U) != 0U) { /* Evpd is set */
328         if (g_usbd_msc[busid].cbw.CB[2] == 0U) {       /* Request for Supported Vital Product Data Pages*/
329             data_len = 0x06;
330             memcpy(*data, (uint8_t *)inquiry00, data_len);
331         } else if (g_usbd_msc[busid].cbw.CB[2] == 0x80U) { /* Request for VPD page 0x80 Unit Serial Number */
332             data_len = 0x08;
333             memcpy(*data, (uint8_t *)inquiry80, data_len);
334         } else { /* Request Not supported */
335             SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDFIELDINCBA);
336             return false;
337         }
338     } else {
339         if (g_usbd_msc[busid].cbw.CB[4] < SCSIRESP_INQUIRY_SIZEOF) {
340             data_len = g_usbd_msc[busid].cbw.CB[4];
341         }
342         memcpy(*data, (uint8_t *)inquiry, data_len);
343     }
344 
345     *len = data_len;
346     return true;
347 }
348 
SCSI_startStopUnit(uint8_t busid,uint8_t ** data,uint32_t * len)349 static bool SCSI_startStopUnit(uint8_t busid, uint8_t **data, uint32_t *len)
350 {
351     if (g_usbd_msc[busid].cbw.dDataLength != 0U) {
352         SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
353         return false;
354     }
355 
356     if ((g_usbd_msc[busid].cbw.CB[4] & 0x3U) == 0x1U) /* START=1 */
357     {
358         //SCSI_MEDIUM_UNLOCKED;
359     } else if ((g_usbd_msc[busid].cbw.CB[4] & 0x3U) == 0x2U) /* START=0 and LOEJ Load Eject=1 */
360     {
361         //SCSI_MEDIUM_EJECTED;
362         g_usbd_msc[busid].popup = true;
363     } else if ((g_usbd_msc[busid].cbw.CB[4] & 0x3U) == 0x3U) /* START=1 and LOEJ Load Eject=1 */
364     {
365         //SCSI_MEDIUM_UNLOCKED;
366     } else {
367     }
368 
369     *data = NULL;
370     *len = 0;
371     return true;
372 }
373 
SCSI_preventAllowMediaRemoval(uint8_t busid,uint8_t ** data,uint32_t * len)374 static bool SCSI_preventAllowMediaRemoval(uint8_t busid, uint8_t **data, uint32_t *len)
375 {
376     if (g_usbd_msc[busid].cbw.dDataLength != 0U) {
377         SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
378         return false;
379     }
380     if (g_usbd_msc[busid].cbw.CB[4] == 0U) {
381         //SCSI_MEDIUM_UNLOCKED;
382     } else {
383         //SCSI_MEDIUM_LOCKED;
384     }
385     *data = NULL;
386     *len = 0;
387     return true;
388 }
389 
SCSI_modeSense6(uint8_t busid,uint8_t ** data,uint32_t * len)390 static bool SCSI_modeSense6(uint8_t busid, uint8_t **data, uint32_t *len)
391 {
392     uint8_t data_len = 4;
393     if (g_usbd_msc[busid].cbw.dDataLength == 0U) {
394         SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
395         return false;
396     }
397     if (g_usbd_msc[busid].cbw.CB[4] < SCSIRESP_MODEPARAMETERHDR6_SIZEOF) {
398         data_len = g_usbd_msc[busid].cbw.CB[4];
399     }
400 
401     uint8_t sense6[SCSIRESP_MODEPARAMETERHDR6_SIZEOF] = { 0x03, 0x00, 0x00, 0x00 };
402 
403     if (g_usbd_msc[busid].readonly) {
404         sense6[2] = 0x80;
405     }
406     memcpy(*data, (uint8_t *)sense6, data_len);
407     *len = data_len;
408     return true;
409 }
410 
SCSI_modeSense10(uint8_t busid,uint8_t ** data,uint32_t * len)411 static bool SCSI_modeSense10(uint8_t busid, uint8_t **data, uint32_t *len)
412 {
413     uint8_t data_len = 27;
414     if (g_usbd_msc[busid].cbw.dDataLength == 0U) {
415         SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
416         return false;
417     }
418 
419     if (g_usbd_msc[busid].cbw.CB[8] < 27) {
420         data_len = g_usbd_msc[busid].cbw.CB[8];
421     }
422 
423     uint8_t sense10[27] = {
424         0x00,
425         0x26,
426         0x00,
427         0x00,
428         0x00,
429         0x00,
430         0x00,
431         0x00,
432         0x08,
433         0x12,
434         0x00,
435         0x00,
436         0x00,
437         0x00,
438         0x00,
439         0x00,
440         0x00,
441         0x00,
442         0x00,
443         0x00,
444         0x00,
445         0x00,
446         0x00,
447         0x00,
448         0x00,
449         0x00,
450         0x00
451     };
452 
453     memcpy(*data, (uint8_t *)sense10, data_len);
454     *len = data_len;
455     return true;
456 }
457 
SCSI_readFormatCapacity(uint8_t busid,uint8_t ** data,uint32_t * len)458 static bool SCSI_readFormatCapacity(uint8_t busid, uint8_t **data, uint32_t *len)
459 {
460     if (g_usbd_msc[busid].cbw.dDataLength == 0U) {
461         SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
462         return false;
463     }
464     uint8_t format_capacity[SCSIRESP_READFORMATCAPACITIES_SIZEOF] = {
465         0x00,
466         0x00,
467         0x00,
468         0x08, /* Capacity List Length */
469         (uint8_t)((g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN] >> 24) & 0xff),
470         (uint8_t)((g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN] >> 16) & 0xff),
471         (uint8_t)((g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN] >> 8) & 0xff),
472         (uint8_t)((g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN] >> 0) & 0xff),
473 
474         0x02, /* Descriptor Code: Formatted Media */
475         0x00,
476         (uint8_t)((g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN] >> 8) & 0xff),
477         (uint8_t)((g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN] >> 0) & 0xff),
478     };
479 
480     memcpy(*data, (uint8_t *)format_capacity, SCSIRESP_READFORMATCAPACITIES_SIZEOF);
481     *len = SCSIRESP_READFORMATCAPACITIES_SIZEOF;
482     return true;
483 }
484 
SCSI_readCapacity10(uint8_t busid,uint8_t ** data,uint32_t * len)485 static bool SCSI_readCapacity10(uint8_t busid, uint8_t **data, uint32_t *len)
486 {
487     if (g_usbd_msc[busid].cbw.dDataLength == 0U) {
488         SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
489         return false;
490     }
491 
492     uint8_t capacity10[SCSIRESP_READCAPACITY10_SIZEOF] = {
493         (uint8_t)(((g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN] - 1) >> 24) & 0xff),
494         (uint8_t)(((g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN] - 1) >> 16) & 0xff),
495         (uint8_t)(((g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN] - 1) >> 8) & 0xff),
496         (uint8_t)(((g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN] - 1) >> 0) & 0xff),
497 
498         (uint8_t)((g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN] >> 24) & 0xff),
499         (uint8_t)((g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN] >> 16) & 0xff),
500         (uint8_t)((g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN] >> 8) & 0xff),
501         (uint8_t)((g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN] >> 0) & 0xff),
502     };
503 
504     memcpy(*data, (uint8_t *)capacity10, SCSIRESP_READCAPACITY10_SIZEOF);
505     *len = SCSIRESP_READCAPACITY10_SIZEOF;
506     return true;
507 }
508 
SCSI_read10(uint8_t busid,uint8_t ** data,uint32_t * len)509 static bool SCSI_read10(uint8_t busid, uint8_t **data, uint32_t *len)
510 {
511     (void)data;
512     (void)len;
513 
514     if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x80U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) {
515         SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
516         return false;
517     }
518 
519     g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
520     g_usbd_msc[busid].nsectors = GET_BE16(&g_usbd_msc[busid].cbw.CB[7]); /* Number of Blocks to transfer */
521 
522     if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
523         SCSI_SetSenseData(busid, SCSI_KCQIR_LBAOUTOFRANGE);
524         return false;
525     }
526 
527     if (g_usbd_msc[busid].cbw.dDataLength != (g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN])) {
528         return false;
529     }
530     g_usbd_msc[busid].stage = MSC_DATA_IN;
531 #if defined(CONFIG_USBDEV_MSC_THREAD)
532     usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_IN);
533     return true;
534 #elif defined(CONFIG_USBDEV_MSC_POLLING)
535     g_usbd_msc[busid].event = MSC_DATA_IN;
536     return true;
537 #else
538     return SCSI_processRead(busid);
539 #endif
540 }
541 
SCSI_read12(uint8_t busid,uint8_t ** data,uint32_t * len)542 static bool SCSI_read12(uint8_t busid, uint8_t **data, uint32_t *len)
543 {
544     (void)data;
545     (void)len;
546 
547     if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x80U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) {
548         SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
549         return false;
550     }
551 
552     g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
553     g_usbd_msc[busid].nsectors = GET_BE32(&g_usbd_msc[busid].cbw.CB[6]); /* Number of Blocks to transfer */
554 
555     if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
556         SCSI_SetSenseData(busid, SCSI_KCQIR_LBAOUTOFRANGE);
557         return false;
558     }
559 
560     if (g_usbd_msc[busid].cbw.dDataLength != (g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN])) {
561         return false;
562     }
563     g_usbd_msc[busid].stage = MSC_DATA_IN;
564 #if defined(CONFIG_USBDEV_MSC_THREAD)
565     usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_IN);
566     return true;
567 #elif defined(CONFIG_USBDEV_MSC_POLLING)
568     g_usbd_msc[busid].event = MSC_DATA_IN;
569     return true;
570 #else
571     return SCSI_processRead(busid);
572 #endif
573 }
574 
SCSI_write10(uint8_t busid,uint8_t ** data,uint32_t * len)575 static bool SCSI_write10(uint8_t busid, uint8_t **data, uint32_t *len)
576 {
577     uint32_t data_len = 0;
578 
579     (void)data;
580     (void)len;
581 
582     if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x00U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) {
583         SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
584         return false;
585     }
586 
587     g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
588     g_usbd_msc[busid].nsectors = GET_BE16(&g_usbd_msc[busid].cbw.CB[7]); /* Number of Blocks to transfer */
589 
590     data_len = g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN];
591     if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
592         return false;
593     }
594 
595     if (g_usbd_msc[busid].cbw.dDataLength != data_len) {
596         return false;
597     }
598     g_usbd_msc[busid].stage = MSC_DATA_OUT;
599     data_len = MIN(data_len, CONFIG_USBDEV_MSC_MAX_BUFSIZE);
600     usbd_ep_start_read(busid, mass_ep_data[busid][MSD_OUT_EP_IDX].ep_addr, g_usbd_msc[busid].block_buffer, data_len);
601     return true;
602 }
603 
SCSI_write12(uint8_t busid,uint8_t ** data,uint32_t * len)604 static bool SCSI_write12(uint8_t busid, uint8_t **data, uint32_t *len)
605 {
606     uint32_t data_len = 0;
607 
608     (void)data;
609     (void)len;
610 
611     if (((g_usbd_msc[busid].cbw.bmFlags & 0x80U) != 0x00U) || (g_usbd_msc[busid].cbw.dDataLength == 0U)) {
612         SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
613         return false;
614     }
615 
616     g_usbd_msc[busid].start_sector = GET_BE32(&g_usbd_msc[busid].cbw.CB[2]); /* Logical Block Address of First Block */
617     g_usbd_msc[busid].nsectors = GET_BE32(&g_usbd_msc[busid].cbw.CB[6]); /* Number of Blocks to transfer */
618 
619     data_len = g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN];
620     if ((g_usbd_msc[busid].start_sector + g_usbd_msc[busid].nsectors) > g_usbd_msc[busid].scsi_blk_nbr[g_usbd_msc[busid].cbw.bLUN]) {
621         return false;
622     }
623 
624     if (g_usbd_msc[busid].cbw.dDataLength != data_len) {
625         return false;
626     }
627     g_usbd_msc[busid].stage = MSC_DATA_OUT;
628     data_len = MIN(data_len, CONFIG_USBDEV_MSC_MAX_BUFSIZE);
629     usbd_ep_start_read(busid, mass_ep_data[busid][MSD_OUT_EP_IDX].ep_addr, g_usbd_msc[busid].block_buffer, data_len);
630     return true;
631 }
632 
SCSI_processRead(uint8_t busid)633 static bool SCSI_processRead(uint8_t busid)
634 {
635     uint32_t transfer_len;
636 
637     USB_LOG_DBG("read lba:%d\r\n", g_usbd_msc[busid].start_sector);
638 
639     transfer_len = MIN(g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN], CONFIG_USBDEV_MSC_MAX_BUFSIZE);
640 
641     if (usbd_msc_sector_read(busid, g_usbd_msc[busid].cbw.bLUN, g_usbd_msc[busid].start_sector, g_usbd_msc[busid].block_buffer, transfer_len) != 0) {
642         SCSI_SetSenseData(busid, SCSI_KCQHE_UREINRESERVEDAREA);
643         return false;
644     }
645 
646     g_usbd_msc[busid].start_sector += (transfer_len / g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN]);
647     g_usbd_msc[busid].nsectors -= (transfer_len / g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN]);
648     g_usbd_msc[busid].csw.dDataResidue -= transfer_len;
649 
650     if (g_usbd_msc[busid].nsectors == 0) {
651         g_usbd_msc[busid].stage = MSC_SEND_CSW;
652     }
653 
654     usbd_ep_start_write(busid, mass_ep_data[busid][MSD_IN_EP_IDX].ep_addr, g_usbd_msc[busid].block_buffer, transfer_len);
655 
656     return true;
657 }
658 
SCSI_processWrite(uint8_t busid,uint32_t nbytes)659 static bool SCSI_processWrite(uint8_t busid, uint32_t nbytes)
660 {
661     uint32_t data_len = 0;
662 
663     USB_LOG_DBG("write lba:%d\r\n", g_usbd_msc[busid].start_sector);
664 
665     if (usbd_msc_sector_write(busid, g_usbd_msc[busid].cbw.bLUN, g_usbd_msc[busid].start_sector, g_usbd_msc[busid].block_buffer, nbytes) != 0) {
666         SCSI_SetSenseData(busid, SCSI_KCQHE_WRITEFAULT);
667         return false;
668     }
669 
670     g_usbd_msc[busid].start_sector += (nbytes / g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN]);
671     g_usbd_msc[busid].nsectors -= (nbytes / g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN]);
672     g_usbd_msc[busid].csw.dDataResidue -= nbytes;
673 
674     if (g_usbd_msc[busid].nsectors == 0) {
675         usbd_msc_send_csw(busid, CSW_STATUS_CMD_PASSED);
676     } else {
677         data_len = MIN(g_usbd_msc[busid].nsectors * g_usbd_msc[busid].scsi_blk_size[g_usbd_msc[busid].cbw.bLUN], CONFIG_USBDEV_MSC_MAX_BUFSIZE);
678         usbd_ep_start_read(busid, mass_ep_data[busid][MSD_OUT_EP_IDX].ep_addr, g_usbd_msc[busid].block_buffer, data_len);
679     }
680 
681     return true;
682 }
683 
SCSI_CBWDecode(uint8_t busid,uint32_t nbytes)684 static bool SCSI_CBWDecode(uint8_t busid, uint32_t nbytes)
685 {
686     uint8_t *buf2send = g_usbd_msc[busid].block_buffer;
687     uint32_t len2send = 0;
688     bool ret = false;
689 
690     if (nbytes != sizeof(struct CBW)) {
691         USB_LOG_ERR("size != sizeof(cbw)\r\n");
692         SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
693         return false;
694     }
695 
696     g_usbd_msc[busid].csw.dTag = g_usbd_msc[busid].cbw.dTag;
697     g_usbd_msc[busid].csw.dDataResidue = g_usbd_msc[busid].cbw.dDataLength;
698 
699     if ((g_usbd_msc[busid].cbw.dSignature != MSC_CBW_Signature) || (g_usbd_msc[busid].cbw.bCBLength < 1) || (g_usbd_msc[busid].cbw.bCBLength > 16)) {
700         SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
701         return false;
702     } else {
703         USB_LOG_DBG("Decode CB:0x%02x\r\n", g_usbd_msc[busid].cbw.CB[0]);
704         switch (g_usbd_msc[busid].cbw.CB[0]) {
705             case SCSI_CMD_TESTUNITREADY:
706                 ret = SCSI_testUnitReady(busid, &buf2send, &len2send);
707                 break;
708             case SCSI_CMD_REQUESTSENSE:
709                 ret = SCSI_requestSense(busid, &buf2send, &len2send);
710                 break;
711             case SCSI_CMD_INQUIRY:
712                 ret = SCSI_inquiry(busid, &buf2send, &len2send);
713                 break;
714             case SCSI_CMD_STARTSTOPUNIT:
715                 ret = SCSI_startStopUnit(busid, &buf2send, &len2send);
716                 break;
717             case SCSI_CMD_PREVENTMEDIAREMOVAL:
718                 ret = SCSI_preventAllowMediaRemoval(busid, &buf2send, &len2send);
719                 break;
720             case SCSI_CMD_MODESENSE6:
721                 ret = SCSI_modeSense6(busid, &buf2send, &len2send);
722                 break;
723             case SCSI_CMD_MODESENSE10:
724                 ret = SCSI_modeSense10(busid, &buf2send, &len2send);
725                 break;
726             case SCSI_CMD_READFORMATCAPACITIES:
727                 ret = SCSI_readFormatCapacity(busid, &buf2send, &len2send);
728                 break;
729             case SCSI_CMD_READCAPACITY10:
730                 ret = SCSI_readCapacity10(busid, &buf2send, &len2send);
731                 break;
732             case SCSI_CMD_READ10:
733                 ret = SCSI_read10(busid, NULL, 0);
734                 break;
735             case SCSI_CMD_READ12:
736                 ret = SCSI_read12(busid, NULL, 0);
737                 break;
738             case SCSI_CMD_WRITE10:
739                 ret = SCSI_write10(busid, NULL, 0);
740                 break;
741             case SCSI_CMD_WRITE12:
742                 ret = SCSI_write12(busid, NULL, 0);
743                 break;
744             case SCSI_CMD_VERIFY10:
745                 ret = false;
746                 break;
747             case SCSI_CMD_SYNCHCACHE10:
748                 ret = true;
749                 break;
750             default:
751                 SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
752                 ret = false;
753                 break;
754         }
755     }
756     if (ret) {
757         if (g_usbd_msc[busid].stage == MSC_READ_CBW) {
758             if (len2send) {
759                 USB_LOG_DBG("Send info len: %d\r\n", len2send);
760                 usbd_msc_send_info(busid, buf2send, len2send);
761             } else {
762                 usbd_msc_send_csw(busid, CSW_STATUS_CMD_PASSED);
763             }
764         }
765     }
766     return ret;
767 }
768 
mass_storage_bulk_out(uint8_t busid,uint8_t ep,uint32_t nbytes)769 void mass_storage_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
770 {
771     (void)ep;
772 
773     switch (g_usbd_msc[busid].stage) {
774         case MSC_READ_CBW:
775             if (SCSI_CBWDecode(busid, nbytes) == false) {
776                 USB_LOG_ERR("Command: 0x%02x decode err\r\n", g_usbd_msc[busid].cbw.CB[0]);
777                 usbd_msc_bot_abort(busid);
778                 return;
779             }
780             break;
781         case MSC_DATA_OUT:
782             switch (g_usbd_msc[busid].cbw.CB[0]) {
783                 case SCSI_CMD_WRITE10:
784                 case SCSI_CMD_WRITE12:
785 #if defined(CONFIG_USBDEV_MSC_THREAD)
786                     g_usbd_msc[busid].nbytes = nbytes;
787                     usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_OUT);
788 #elif defined(CONFIG_USBDEV_MSC_POLLING)
789                     g_usbd_msc[busid].nbytes = nbytes;
790                     g_usbd_msc[busid].event = MSC_DATA_OUT;
791 #else
792                     if (SCSI_processWrite(busid, nbytes) == false) {
793                         usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
794                     }
795 #endif
796                     break;
797                 default:
798                     break;
799             }
800             break;
801         default:
802             break;
803     }
804 }
805 
mass_storage_bulk_in(uint8_t busid,uint8_t ep,uint32_t nbytes)806 void mass_storage_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
807 {
808     (void)ep;
809     (void)nbytes;
810 
811     switch (g_usbd_msc[busid].stage) {
812         case MSC_DATA_IN:
813             switch (g_usbd_msc[busid].cbw.CB[0]) {
814                 case SCSI_CMD_READ10:
815                 case SCSI_CMD_READ12:
816 #if defined(CONFIG_USBDEV_MSC_THREAD)
817                     usb_osal_mq_send(g_usbd_msc[busid].usbd_msc_mq, MSC_DATA_IN);
818 #elif defined(CONFIG_USBDEV_MSC_POLLING)
819                     g_usbd_msc[busid].event = MSC_DATA_IN;
820 #else
821                     if (SCSI_processRead(busid) == false) {
822                         usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
823                         return;
824                     }
825 #endif
826                     break;
827                 default:
828                     break;
829             }
830             break;
831         /*the device has to send a CSW*/
832         case MSC_SEND_CSW:
833             usbd_msc_send_csw(busid, CSW_STATUS_CMD_PASSED);
834             break;
835 
836         /*the host has received the CSW*/
837         case MSC_WAIT_CSW:
838             g_usbd_msc[busid].stage = MSC_READ_CBW;
839             USB_LOG_DBG("Start reading cbw\r\n");
840             usbd_ep_start_read(busid, mass_ep_data[busid][MSD_OUT_EP_IDX].ep_addr, (uint8_t *)&g_usbd_msc[busid].cbw, USB_SIZEOF_MSC_CBW);
841             break;
842 
843         default:
844             break;
845     }
846 }
847 
848 #if defined(CONFIG_USBDEV_MSC_THREAD)
usbdev_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)849 static void usbdev_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
850 {
851     uintptr_t event;
852     int ret;
853     uint8_t busid = (uint8_t)CONFIG_USB_OSAL_THREAD_GET_ARGV;
854 
855     while (1) {
856         ret = usb_osal_mq_recv(g_usbd_msc[busid].usbd_msc_mq, (uintptr_t *)&event, USB_OSAL_WAITING_FOREVER);
857         if (ret < 0) {
858             continue;
859         }
860         if (event == MSC_DATA_OUT) {
861             if (SCSI_processWrite(busid, g_usbd_msc[busid].nbytes) == false) {
862                 usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
863             }
864         } else if (event == MSC_DATA_IN) {
865             if (SCSI_processRead(busid) == false) {
866                 usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
867             }
868         } else {
869         }
870     }
871 }
872 #elif defined(CONFIG_USBDEV_MSC_POLLING)
usbd_msc_polling(uint8_t busid)873 void usbd_msc_polling(uint8_t busid)
874 {
875     uint8_t event;
876 
877     event = g_usbd_msc[busid].event;
878 
879     if (event != 0) {
880         g_usbd_msc[busid].event = 0;
881         if (event == MSC_DATA_OUT) {
882             if (SCSI_processWrite(busid, g_usbd_msc[busid].nbytes) == false) {
883                 usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
884             }
885         } else if (event == MSC_DATA_IN) {
886             if (SCSI_processRead(busid) == false) {
887                 usbd_msc_send_csw(busid, CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
888             }
889         } else {
890         }
891     }
892 }
893 #endif
894 
usbd_msc_init_intf(uint8_t busid,struct usbd_interface * intf,const uint8_t out_ep,const uint8_t in_ep)895 struct usbd_interface *usbd_msc_init_intf(uint8_t busid, struct usbd_interface *intf, const uint8_t out_ep, const uint8_t in_ep)
896 {
897     intf->class_interface_handler = msc_storage_class_interface_request_handler;
898     intf->class_endpoint_handler = NULL;
899     intf->vendor_handler = NULL;
900     intf->notify_handler = msc_storage_notify_handler;
901 
902     mass_ep_data[busid][MSD_OUT_EP_IDX].ep_addr = out_ep;
903     mass_ep_data[busid][MSD_OUT_EP_IDX].ep_cb = mass_storage_bulk_out;
904     mass_ep_data[busid][MSD_IN_EP_IDX].ep_addr = in_ep;
905     mass_ep_data[busid][MSD_IN_EP_IDX].ep_cb = mass_storage_bulk_in;
906 
907     usbd_add_endpoint(busid, &mass_ep_data[busid][MSD_OUT_EP_IDX]);
908     usbd_add_endpoint(busid, &mass_ep_data[busid][MSD_IN_EP_IDX]);
909 
910     memset((uint8_t *)&g_usbd_msc[busid], 0, sizeof(struct usbd_msc_priv));
911 
912     usdb_msc_set_max_lun(busid);
913     for (uint8_t i = 0u; i <= g_usbd_msc[busid].max_lun; i++) {
914         usbd_msc_get_cap(busid, i, &g_usbd_msc[busid].scsi_blk_nbr[i], &g_usbd_msc[busid].scsi_blk_size[i]);
915 
916         if (CONFIG_USBDEV_MSC_MAX_BUFSIZE % g_usbd_msc[busid].scsi_blk_size[i]) {
917             USB_LOG_ERR("CONFIG_USBDEV_MSC_MAX_BUFSIZE must be a multiple of block size\r\n");
918             while (1) {
919             }
920         }
921     }
922 
923     return intf;
924 }
925 
usbd_msc_set_readonly(uint8_t busid,bool readonly)926 void usbd_msc_set_readonly(uint8_t busid, bool readonly)
927 {
928     g_usbd_msc[busid].readonly = readonly;
929 }
930 
usbd_msc_get_popup(uint8_t busid)931 bool usbd_msc_get_popup(uint8_t busid)
932 {
933     return g_usbd_msc[busid].popup;
934 }
935 
usbd_msc_get_cap(uint8_t busid,uint8_t lun,uint32_t * block_num,uint32_t * block_size)936 __WEAK void usbd_msc_get_cap(uint8_t busid, uint8_t lun, uint32_t *block_num, uint32_t *block_size)
937 {
938     (void)busid;
939     (void)lun;
940 
941     *block_num = 0;
942     *block_size = 0;
943 }
944 
usbd_msc_sector_read(uint8_t busid,uint8_t lun,uint32_t sector,uint8_t * buffer,uint32_t length)945 __WEAK int usbd_msc_sector_read(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
946 {
947     (void)busid;
948     (void)lun;
949     (void)sector;
950     (void)buffer;
951     (void)length;
952 
953     return 0;
954 }
955 
usbd_msc_sector_write(uint8_t busid,uint8_t lun,uint32_t sector,uint8_t * buffer,uint32_t length)956 __WEAK int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
957 {
958     (void)busid;
959     (void)lun;
960     (void)sector;
961     (void)buffer;
962     (void)length;
963 
964     return 0;
965 }