1 /*******************************************************************************
2  * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * PolarFire SoC MSS USB Driver Stack
7  *      USB Logical Layer (USB-LL)
8  *          USBH-MSC class driver.
9  *
10  *
11  *  This file implements Host side MSC class specific initialization
12  *  and request handling.
13  *
14  */
15 
16 #include "mss_usb_host_msc.h"
17 #include "mss_usb_host.h"
18 #include "mss_usb_std_def.h"
19 
20 #include <string.h>
21 #include <stdio.h>
22 #include "mpfs_hal/mss_hal.h"
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 #ifdef MSS_USB_HOST_ENABLED
29 
30 /***************************************************************************//**
31   Constant values internally used by USBH-MSC driver.
32  */
33 #define MSS_USBH_MSC_CLASS_ID                               0x08u
34 #define MSS_USBH_MSC_SUBCLASS_ID                            0x06u
35 #define MSS_USBH_MSC_PROTOCOL_ID                            0x50u
36 
37 #define MSS_USBH_MSC_DRIVER_ID       (uint32_t)((MSS_USBH_MSC_CLASS_ID << 16) |\
38                                                (MSS_USBH_MSC_SUBCLASS_ID << 8)|\
39                                                (MSS_USBH_MSC_PROTOCOL_ID) )
40 
41 #define SCSI_COMMAND_PASSED                                 0x01u
42 #define SCSI_COMMAND_FAILED                                 0x02u
43 #define SCSI_COMMAND_PHASE_ERR                              0x03u
44 
45 #define USBH_MSC_BULK_TX_PIPE                               MSS_USB_TX_EP_1
46 #define USBH_MSC_BULK_RX_PIPE                               MSS_USB_RX_EP_1
47 
48 #define USBH_MSC_BULK_TX_PIPE_FIFOADDR                      0x100u
49 #define USBH_MSC_BULK_RX_PIPE_FIFOADDR                      0x300u
50 
51 #define USBH_MSC_BULK_TX_PIPE_FIFOSZ                        0x200u
52 #define USBH_MSC_BULK_RX_PIPE_FIFOSZ                        0x200u
53 
54 /***************************************************************************//**
55   Types internally used by USBH-MSC driver.
56  */
57 typedef enum {
58     MSC_BOT_IDLE,
59     MSC_BOT_COMMAND_PHASE,
60     MSC_BOT_DATA_PHASE,
61     MSC_BOT_STATUS_PHASE,
62     MSC_BOT_STATUS_WAITCOMPLETE,
63     MSC_BOT_ERROR
64 }g_msc_bot_state_t;
65 
66 typedef struct {
67     uint8_t num;
68     uint16_t maxpktsz;
69 } msd_tdev_ep_t;
70 
71 typedef struct {
72     uint8_t* cbuf; /* always31bytes */
73     uint8_t* dbuf;
74     uint32_t dbuf_len;
75     uint8_t* sbuf; /* statusalways 13bytes */
76     uint8_t volatile st;
77 } scsi_command_t;
78 
79 /***************************************************************************//**
80   Private functions declarations for USBH-MSC driver.
81  */
82 static scsi_command_t g_scsi_command = {0};
83 static volatile uint8_t g_usbh_msc_alloc_event = 0u;
84 static uint8_t g_usbh_msc_release_event = 0u;
85 static volatile uint8_t g_usbh_msc_cep_event = 0u;
86 static volatile uint8_t g_usbh_msc_tx_event = 0u;
87 static volatile uint8_t g_usbh_msc_rx_event = 0u;
88 
89 #if defined(__GNUC__)
90 static msd_cbw_t g_bot_cbw __attribute__ ((aligned (4))) = {0};
91 static uint8_t g_bot_csw[13] __attribute__ ((aligned (4))) = {0};
92 
93 /* Store Inquiry response */
94 static uint8_t g_bot_inquiry[36] __attribute__ ((aligned (4))) = {0};
95 
96 /* Store Read_capacity response */
97 static uint8_t g_bot_readcap[8] __attribute__ ((aligned (4)))= {0};
98 
99 #elif defined(__ICCARM__)
100 #pragma data_alignment = 4
101 static msd_cbw_t g_bot_cbw = {0};
102 static uint8_t g_bot_csw[13] = {0};
103 static uint8_t g_bot_inquiry[36] = {0};
104 static uint8_t g_bot_readcap[8] = {0};
105 
106 #elif defined(__CC_ARM)
107 __align(4) static msd_cbw_t g_bot_cbw = {0};
108 __align(4) static uint8_t g_bot_csw[13] = {0};
109 __align(4) static uint8_t g_bot_inquiry[36] = {0};
110 __align(4) static uint8_t g_bot_readcap[8] = {0};
111 #endif
112 
113 static volatile g_msc_bot_state_t g_msc_bot_state = MSC_BOT_IDLE;
114 
115 static uint8_t g_msd_tdev_addr = 0u;
116 static mss_usb_state_t msd_tdev_state = MSS_USB_NOT_ATTACHED_STATE;
117 static uint8_t g_msd_conf_desc[32] = {0};
118 
119 /* Data type changed from uint8_t since ASSERT in start_control_xfr() */
120 static uint32_t g_tdev_max_lun_idx = 0u;
121 static msd_tdev_ep_t g_tdev_in_ep = {0};
122 static msd_tdev_ep_t g_tdev_out_ep = {0};
123 
124 static volatile mss_usbh_msc_state_t g_msc_state = USBH_MSC_IDLE;
125 static mss_usbh_msc_err_code_t g_msch_error_code = USBH_MSC_NO_ERROR;
126 
127 static mss_usbh_msc_user_cb_t* g_msch_user_cb;
128 
129 static uint8_t usbh_msc_allocate_cb(uint8_t tdev_addr);
130 static uint8_t usbh_msc_release_cb(uint8_t tdev_addr);
131 static uint8_t usbh_msc_cep_done_cb(uint8_t tdev_addr, uint8_t status, uint32_t count);
132 
133 static uint8_t usbh_msc_tx_complete_cb(uint8_t tdev_addr,
134                                        uint8_t status,
135                                        uint32_t count);
136 
137 static uint8_t usbh_msc_rx_cb(uint8_t tdev_addr, uint8_t status, uint32_t count);
138 static mss_usbh_msc_err_code_t MSS_USBH_MSC_validate_class_desc(uint8_t* p_cd);
139 static mss_usbh_msc_err_code_t MSS_USBH_MSC_extract_tdev_ep_desc(void);
140 
141 static void usbh_msc_construct_class_req(uint8_t* buf,
142                                          uint8_t req,
143                                          uint8_t bInterfaceNumber);
144 
145 /***************************************************************************//**
146   Definition of Class call-back functions used by USBH driver.
147  */
148 mss_usbh_class_cb_t msd_class =
149 {
150     MSS_USBH_MSC_DRIVER_ID,
151     usbh_msc_allocate_cb,
152     usbh_msc_release_cb,
153     usbh_msc_cep_done_cb,
154     usbh_msc_tx_complete_cb,
155     usbh_msc_rx_cb,
156     0
157 };
158 
159 /*******************************************************************************
160  * EXPORTED API Functions
161  ******************************************************************************/
162 
163 /******************************************************************************
164  * See mss_usb_host_msc.h for details of how to use this function.
165  */
166 void
MSS_USBH_MSC_init(mss_usbh_msc_user_cb_t * user_sb)167 MSS_USBH_MSC_init
168 (
169     mss_usbh_msc_user_cb_t* user_sb
170 )
171 {
172     g_msc_state = USBH_MSC_IDLE;
173     g_msc_bot_state = MSC_BOT_IDLE;
174     g_tdev_max_lun_idx = 0u;
175     memset(g_msd_conf_desc, 0u, sizeof(g_msd_conf_desc));
176     memset(g_bot_inquiry, 0u, sizeof(g_bot_inquiry));
177     memset(&g_bot_csw, 0u, sizeof(g_bot_csw));
178     g_tdev_in_ep.maxpktsz = 0u;
179     g_tdev_in_ep.num = 0u;
180     g_tdev_out_ep.maxpktsz = 0u;
181     g_tdev_out_ep.num = 0u;
182     g_msd_tdev_addr = 0u;
183     g_msch_user_cb = user_sb;
184 
185     g_scsi_command.cbuf = (uint8_t*)0;
186     g_scsi_command.dbuf = (uint8_t*)0;
187     g_scsi_command.sbuf = (uint8_t*)0;
188     g_scsi_command.dbuf_len = 0u;
189     g_scsi_command.st = 0u;
190     memset(g_bot_readcap, 0u, sizeof(g_bot_readcap));
191 }
192 
193 /******************************************************************************
194  * See mss_usb_host_msc.h for details of how to use this function.
195  */
MSS_USBH_MSC_get_handle(void)196 void* MSS_USBH_MSC_get_handle
197 (
198     void
199 )
200 {
201     return ((void*)&msd_class);
202 }
203 
204 /******************************************************************************
205  * See mss_usb_host_msc.h for details of how to use this function.
206  */
207 void
MSS_USBH_MSC_task(void)208 MSS_USBH_MSC_task
209 (
210     void
211 )
212 {
213     uint8_t std_req_buf[USB_SETUP_PKT_LEN] = {0};
214     static volatile uint32_t wait_mili = 0u;
215 
216     switch (g_msc_state)
217     {
218         case USBH_MSC_IDLE:
219             if (g_usbh_msc_alloc_event)
220             {
221                 g_usbh_msc_alloc_event = 0u;
222                 g_msc_state = USBH_MSC_GET_CLASS_DESCR;
223             }
224         break;
225 
226         case USBH_MSC_GET_CLASS_DESCR:
227             msd_tdev_state = MSS_USBH_get_tdev_state(g_msd_tdev_addr);
228             if (MSS_USB_ADDRESS_STATE == msd_tdev_state)
229             {
230                 mss_usb_ep_state_t cep_st;
231                 cep_st = MSS_USBH_get_cep_state();
232                 if (MSS_USB_CEP_IDLE == cep_st)
233                 {
234                     MSS_USBH_configure_control_pipe(g_msd_tdev_addr);
235                     memset(std_req_buf, 0u, 8*(sizeof(uint8_t)));
236                     MSS_USBH_construct_get_descr_command(std_req_buf,
237                                                          USB_STD_REQ_DATA_DIR_IN,
238                                                          USB_STANDARD_REQUEST,
239                                                          USB_STD_REQ_RECIPIENT_DEVICE,
240                                                          USB_STD_REQ_GET_DESCRIPTOR,
241                                                          USB_CONFIGURATION_DESCRIPTOR_TYPE,
242                                                          0u, /*stringID*/
243                                                          32u);/* config_Desc_length */
244 
245                     g_msc_state = USBH_MSC_WAIT_GET_CLASS_DESCR;
246                     MSS_USBH_start_control_xfr(std_req_buf,
247                                                (uint8_t*)&g_msd_conf_desc,
248                                                USB_STD_REQ_DATA_DIR_IN,
249                                                32u);        /* config_Desc_length */
250                 }
251             }
252         break;
253 
254         case USBH_MSC_WAIT_GET_CLASS_DESCR:
255             if (g_usbh_msc_cep_event)
256             {
257                 mss_usbh_msc_err_code_t res = USBH_MSC_NO_ERROR;
258                 g_usbh_msc_cep_event = 0u;
259                 res = MSS_USBH_MSC_validate_class_desc(0);
260 
261                 if (res == 0u)
262                 {
263                     g_msc_state = USBH_MSC_SET_CONFIG;
264                 }
265                 else
266                 {
267                     g_msc_state = USBH_MSC_ERROR;
268                     g_msch_error_code = res;
269                 }
270 
271                 res = MSS_USBH_MSC_extract_tdev_ep_desc();
272 
273                 if (res == 0u)
274                 {
275                     g_msc_state = USBH_MSC_SET_CONFIG;
276                 }
277                 else
278                 {
279                     g_msc_state = USBH_MSC_ERROR;
280                     g_msch_error_code = res;
281                 }
282             }
283         break;
284 
285         case USBH_MSC_SET_CONFIG:
286             if (0 != g_msch_user_cb->msch_valid_config)
287             {
288                 g_msch_user_cb->msch_valid_config();
289             }
290 
291             memset(std_req_buf, 0u, 8*(sizeof(uint8_t)));
292             std_req_buf[1] = USB_STD_REQ_SET_CONFIG;
293 
294             /* bConfigurationValue*/
295             std_req_buf[2] = g_msd_conf_desc[5];
296             g_msc_state = USBH_MSC_WAIT_SET_CONFIG;
297 
298             MSS_USBH_start_control_xfr(std_req_buf,
299                                        (uint8_t*)&g_msd_conf_desc,
300                                        USB_STD_REQ_DATA_DIR_IN,
301                                        0u);
302         break;
303         case USBH_MSC_WAIT_SET_CONFIG:
304             if (g_usbh_msc_cep_event)
305             {
306                 g_usbh_msc_cep_event = 0u;
307                 wait_mili = MSS_USBH_get_milis();
308                 g_msc_state = USBH_MSC_WAIT_DEV_SETTLE;
309             }
310         break;
311 
312         case USBH_MSC_WAIT_DEV_SETTLE:
313             /* After SET_CONFIG command, we must give time for device to settle
314              * down as per spec
315              */
316             if ((MSS_USBH_get_milis() - wait_mili) > 60u)
317             {
318                 g_msc_state = USBH_MSC_GET_MAX_LUN;
319             }
320         break;
321 
322         case USBH_MSC_GET_MAX_LUN:
323             usbh_msc_construct_class_req(std_req_buf,
324                                          USB_MSC_BOT_REQ_GET_MAX_LUN,
325                                          g_msd_conf_desc[11]);/* bInterfaceNum */
326 
327             MSS_USBH_configure_control_pipe(g_msd_tdev_addr);
328 
329             g_msc_state = USBH_MSC_WAIT_GET_MAX_LUN;
330 
331             MSS_USBH_start_control_xfr(std_req_buf,
332                                        (uint8_t*)&g_tdev_max_lun_idx,
333                                        USB_STD_REQ_DATA_DIR_IN,
334                                        1u);
335         break;
336 
337         case USBH_MSC_WAIT_GET_MAX_LUN:
338             if (g_usbh_msc_cep_event)
339             {
340                 if (MSS_USB_EP_XFR_SUCCESS == g_usbh_msc_cep_event)
341                 {
342                     g_msc_state = USBH_MSC_CONFIG_BULK_ENDPOINTS;
343                 }
344                 else if (MSS_USB_EP_STALL_RCVD == g_usbh_msc_cep_event)
345                 {
346                     /* Stall for this command means single LUN support by Target */
347                     g_tdev_max_lun_idx = 0u;
348                     g_msc_state = USBH_MSC_CLR_CEP_STALL;
349 
350                     /* Clear Stall using CLR_FEATURE Command */
351                 }
352                 else
353                 {
354                     ASSERT(0); /* Invalid CEP event */
355                 }
356 
357                 g_usbh_msc_cep_event = 0u;
358             }
359         break;
360 
361         case USBH_MSC_CLR_CEP_STALL:
362         {
363             /* Std clear CEP STALL command */
364             uint8_t temp_buf[8u] = {0x02u,
365                                     0x01u,
366                                     0x00u, 0x00u,
367                                     0x00u, 0x00u,
368                                     0x00u, 0x00u};
369 
370             g_msc_state = USBH_MSC_WAIT_CLR_CEP_STALL;
371 
372             /* clear feature Endpoint halt on Tdev Out EP */
373             MSS_USBH_start_control_xfr(temp_buf,
374                                        (uint8_t*)&g_tdev_max_lun_idx,
375                                        USB_STD_REQ_DATA_DIR_IN,
376                                        0u);
377             break;
378         }
379         case USBH_MSC_WAIT_CLR_CEP_STALL:
380             if (g_usbh_msc_cep_event)
381             {
382                 if (MSS_USB_EP_XFR_SUCCESS == g_usbh_msc_cep_event)
383                 {
384                     g_msc_state = USBH_MSC_CONFIG_BULK_ENDPOINTS;
385                 }
386                 else if (MSS_USB_EP_STALL_RCVD == g_usbh_msc_cep_event)
387                 {
388                     g_msc_state = USBH_MSC_ERROR;
389                     g_msch_error_code = USBH_MSC_CLR_CEP_STALL_ERROR;
390                 }
391                 else
392                 {
393                     ASSERT(0);/* Invalid CEP event */
394                 }
395                 g_usbh_msc_cep_event = 0u;
396             }
397         break;
398 
399         case USBH_MSC_CONFIG_BULK_ENDPOINTS:
400             /* Configure BULK TX/RX Endpoints */
401             MSS_USBH_configure_out_pipe(g_msd_tdev_addr,
402                                         USBH_MSC_BULK_TX_PIPE,
403                                         g_tdev_out_ep.num,  /* Targeted OUTEP Num */
404                                         USBH_MSC_BULK_TX_PIPE_FIFOADDR,
405                                         USBH_MSC_BULK_TX_PIPE_FIFOSZ,
406                                         g_tdev_out_ep.maxpktsz,
407                                         1,
408                                         DMA_DISABLE,
409                                         MSS_USB_DMA_CHANNEL1,
410                                         MSS_USB_XFR_BULK,
411                                         NO_ZLP_TO_XFR,
412                                         32768);/* Max NAKLimit value */
413 
414             MSS_USBH_configure_in_pipe(g_msd_tdev_addr,
415                                        USBH_MSC_BULK_RX_PIPE,
416                                        g_tdev_in_ep.num,    /* Targeted OutEP Num */
417                                        USBH_MSC_BULK_RX_PIPE_FIFOADDR,
418                                        USBH_MSC_BULK_RX_PIPE_FIFOSZ,
419                                        g_tdev_in_ep.maxpktsz,
420                                        1,
421                                        DMA_DISABLE,
422                                        MSS_USB_DMA_CHANNEL2,
423                                        MSS_USB_XFR_BULK,
424                                        NO_ZLP_TO_XFR,
425                                        32768);/* Max NAKLimit value */
426 
427             g_msc_state = USBH_MSC_TEST_UNIT_READY_CPHASE;
428         break;
429 
430 
431         case USBH_MSC_TEST_UNIT_READY_CPHASE:
432             MSS_USBH_MSC_construct_cbw_cb6byte(USB_MSC_SCSI_TEST_UNIT_READY,
433                                                0u,
434                                                &g_bot_cbw);
435 
436             MSS_USBH_write_out_pipe(g_msd_tdev_addr,
437                                     USBH_MSC_BULK_TX_PIPE,
438                                     g_tdev_out_ep.num,
439                                     g_tdev_out_ep.maxpktsz,
440                                     (uint8_t*)&g_bot_cbw,
441                                     31u); /* std_cbw_len */
442 
443             g_msc_state = USBH_MSC_TEST_UNIT_READY_SPHASE;
444         break;
445 
446         case USBH_MSC_TEST_UNIT_READY_SPHASE:
447             if (g_usbh_msc_tx_event)
448             {
449                 g_usbh_msc_tx_event = 0u;
450                 g_msc_state = USBH_MSC_TEST_UNIT_READY_WAITCOMPLETE;
451                 MSS_USBH_read_in_pipe(g_msd_tdev_addr,
452                                       USBH_MSC_BULK_RX_PIPE,
453                                       g_tdev_in_ep.num,
454                                       g_tdev_in_ep.maxpktsz,
455                                       (uint8_t*)&g_bot_csw,
456                                       13u);/* standard status msg */
457             }
458         break;
459 
460         case USBH_MSC_TEST_UNIT_READY_WAITCOMPLETE:
461             if (g_usbh_msc_rx_event)
462             {
463                 g_usbh_msc_rx_event = 0u;
464 
465                 /* decode the received status */
466                 if (g_bot_csw[12] == 0x00u)       /* PASSED */
467                 {
468                     g_msc_state = USBH_MSC_SCSI_INQUIRY_CPHASE;
469                 }
470                 else if (g_bot_csw[12] == 0x01u)  /* FAILED */
471                 {
472                     g_msc_state = USBH_MSC_SCSI_REQSENSE_CPHASE;
473                 }
474                 else if (g_bot_csw[12] == 0x02u)
475                 {
476                     ASSERT(0);            /* phase error, reset recovery required */
477                 }
478             }
479 
480         break;
481         case USBH_MSC_SCSI_INQUIRY_CPHASE:
482             MSS_USBH_MSC_construct_cbw_cb6byte(USB_MSC_SCSI_INQUIRY,
483                                                36u, /*standard INQUIRY response size */
484                                                &g_bot_cbw);
485 
486             g_msc_state = USBH_MSC_SCSI_INQUIRY_DPHASE;
487 
488             MSS_USBH_write_out_pipe(g_msd_tdev_addr,
489                                     USBH_MSC_BULK_TX_PIPE,
490                                     g_tdev_out_ep.num,
491                                     g_tdev_out_ep.maxpktsz,
492                                     (uint8_t*)&g_bot_cbw,
493                                     31u); /* std_cbw_len */
494         break;
495 
496         case USBH_MSC_SCSI_INQUIRY_DPHASE:
497             if (g_usbh_msc_tx_event)
498             {
499                 g_usbh_msc_tx_event = 0u;
500                 g_msc_state = USBH_MSC_SCSI_INQUIRY_SPHASE;
501 
502                 MSS_USBH_read_in_pipe(g_msd_tdev_addr,
503                                       USBH_MSC_BULK_RX_PIPE,
504                                       g_tdev_in_ep.num,
505                                       g_tdev_in_ep.maxpktsz,
506                                       g_bot_inquiry,
507                                       36u);/* standard INQUIRY response size */
508             }
509         break;
510 
511         case USBH_MSC_SCSI_INQUIRY_SPHASE:
512             if (g_usbh_msc_rx_event)
513             {
514                 g_usbh_msc_rx_event = 0u;
515                 g_msc_state = USBH_MSC_SCSI_INQUIRY_WAITCOMPLETE;
516 
517                 MSS_USBH_read_in_pipe(g_msd_tdev_addr,
518                                       USBH_MSC_BULK_RX_PIPE,
519                                       g_tdev_in_ep.num,
520                                       g_tdev_in_ep.maxpktsz,
521                                       (uint8_t*)&g_bot_csw,
522                                       13u);/* standard status msg */
523             }
524         break;
525 
526         case USBH_MSC_SCSI_INQUIRY_WAITCOMPLETE:
527             if (g_usbh_msc_rx_event)
528             {
529                 g_usbh_msc_rx_event = 0x0U;
530                 g_msc_state = USBH_MSC_SCSI_READ_CAPACITY_CPHASE;
531             }
532         break;
533 
534         case USBH_MSC_SCSI_REQSENSE_CPHASE:
535         {
536             /* This is a standard command buffer for REQUEST SENSE command */
537             uint8_t cbuf[] = {0x55U, 0x53U, 0x42U, 0x43U, 0x28U, 0x2EU, 0x59U, 0xAFU,
538                               0x12U, 0x00U, 0x00U, 0x00U, 0x80U, 0x00U, 0x0CU, 0x03U,
539                               0x00U, 0x00U, 0x00U, 0x12U, 0x00U, 0x00U, 0x00U, 0x00U,
540                               0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U};
541 
542             g_msc_state = USBH_MSC_SCSI_REQSENSE_DPHASE;
543 
544             MSS_USBH_write_out_pipe(g_msd_tdev_addr,
545                                     USBH_MSC_BULK_TX_PIPE,
546                                     g_tdev_out_ep.num,
547                                     g_tdev_out_ep.maxpktsz,
548                                     (uint8_t*)&cbuf,
549                                     31u);                          /*std_cbw_len */
550 
551         }
552         break;
553         case USBH_MSC_SCSI_REQSENSE_DPHASE:
554         if (g_usbh_msc_tx_event)
555         {
556             /* standard response from device for REQUEST sense command is 18 bytes */
557             static uint8_t reqsense_buf[18];
558             g_usbh_msc_tx_event = 0u;
559             g_msc_state = USBH_MSC_SCSI_REQSENSE_SPHASE;
560 
561             MSS_USBH_read_in_pipe(g_msd_tdev_addr,
562                                   USBH_MSC_BULK_RX_PIPE,
563                                   g_tdev_in_ep.num,
564                                   g_tdev_in_ep.maxpktsz,
565                                   reqsense_buf,
566                                   18u);
567         }
568         break;
569         case USBH_MSC_SCSI_REQSENSE_SPHASE:
570             if (g_usbh_msc_rx_event)
571             {
572                 g_usbh_msc_rx_event = 0u;
573                 g_msc_state = USBH_MSC_SCSI_REQSENSE_WAITCOMPLETE;
574 
575                 MSS_USBH_read_in_pipe(g_msd_tdev_addr,
576                                       USBH_MSC_BULK_RX_PIPE,
577                                       g_tdev_in_ep.num,
578                                       g_tdev_in_ep.maxpktsz,
579                                       (uint8_t*)&g_bot_csw,
580                                       13u);/* standard status msg */
581             }
582 
583         break;
584         case USBH_MSC_SCSI_REQSENSE_WAITCOMPLETE:
585             if (g_usbh_msc_rx_event)
586             {
587                 g_usbh_msc_rx_event = 0u;
588                 g_msc_state = USBH_MSC_TEST_UNIT_READY_CPHASE;
589             }
590         break;
591 
592         case USBH_MSC_SCSI_READ_CAPACITY_CPHASE:
593 
594             MSS_USBH_MSC_construct_cbw_cb10byte(USB_MSC_SCSI_READ_CAPACITY_10,
595                                                 0u,
596                                                 0u,
597                                                 0u,
598                                                 0u,
599                                                 &g_bot_cbw);
600 
601             g_msc_state = USBH_MSC_SCSI_READ_CAPACITY_DPHASE;
602 
603             MSS_USBH_write_out_pipe(g_msd_tdev_addr,
604                                     USBH_MSC_BULK_TX_PIPE,
605                                     g_tdev_out_ep.num,
606                                     g_tdev_out_ep.maxpktsz,
607                                     (uint8_t*)&g_bot_cbw,
608                                     31u);                          /* std_cbw_len */
609         break;
610 
611         case USBH_MSC_SCSI_READ_CAPACITY_DPHASE:
612             if (g_usbh_msc_tx_event)
613             {
614                 g_usbh_msc_rx_event = 0u;
615                 g_msc_state = USBH_MSC_SCSI_READ_CAPACITY_SPHASE;
616 
617                 /* standard Read Capacity response size is 8bytes.
618                  * We need this info later so keep it in g_bot_readcap
619                  */
620                 MSS_USBH_read_in_pipe(g_msd_tdev_addr,
621                                       USBH_MSC_BULK_RX_PIPE,
622                                       g_tdev_in_ep.num,
623                                       g_tdev_in_ep.maxpktsz,
624                                       g_bot_readcap,
625                                       8u);
626             }
627 
628         break;
629 
630         case USBH_MSC_SCSI_READ_CAPACITY_SPHASE:
631             if (g_usbh_msc_rx_event)
632             {
633                 g_usbh_msc_rx_event = 0u;
634                 g_msc_state = USBH_MSC_SCSI_READ_CAPACITY_WAITCOMPLETE;
635 
636                 MSS_USBH_read_in_pipe(g_msd_tdev_addr,
637                                       USBH_MSC_BULK_RX_PIPE,
638                                       g_tdev_in_ep.num,
639                                       g_tdev_in_ep.maxpktsz,
640                                       (uint8_t*)&g_bot_csw,
641                                       13u);/* standard status msg */
642             }
643         break;
644 
645         case USBH_MSC_SCSI_READ_CAPACITY_WAITCOMPLETE:
646             if (g_usbh_msc_rx_event)
647             {
648                 uint32_t sector_size = 0u;
649                 g_usbh_msc_rx_event = 0u;
650 
651                 sector_size = ((g_bot_readcap[4u] << 24u) |          /*sector size */
652                                (g_bot_readcap[5u] << 16u) |
653                                (g_bot_readcap[6u] << 8u) |
654                                g_bot_readcap[7u]);
655 
656                 if (sector_size != 512u)
657                 {
658                     g_msc_state = USBH_MSC_ERROR;
659                     g_msch_error_code = USBH_MSC_SECTOR_SIZE_NOT_SUPPORTED;
660                 }
661                 else
662                 {
663                     g_msc_state = USBH_MSC_DEVICE_READY;
664 
665                     if (0 != g_msch_user_cb->msch_tdev_ready)
666                     {
667                         g_msch_user_cb->msch_tdev_ready();
668                     }
669                 }
670             }
671         break;
672 
673         case USBH_MSC_DEVICE_READY:
674             /*
675              * The USBH-MSC driver will stay in this state.
676              * Being in this state, the SCSI requests will be executed as
677              * user the user makes those requests through the APIs of this driver.
678              */
679         break;
680 
681         case USBH_MSC_ERROR:
682         {
683             static uint8_t error = 0u;
684             if (0u == error)
685             {
686                 error = 1u;
687                 if (0 != g_msch_user_cb->msch_error)
688                 {
689                     g_msch_user_cb->msch_error(g_msch_error_code);
690                 }
691             }
692         }
693         break;
694 
695         case USBH_MSC_BOT_RETRY:
696         {
697             static uint32_t first_mili = 0;
698             static uint32_t crrent_mili = 0;
699 
700             if (0u == first_mili)
701             {
702                 first_mili = MSS_USBH_get_milis();
703             }
704 
705             crrent_mili = MSS_USBH_get_milis();
706 
707             /* Found that the Sandisc devices are reporting NAKTIMEOUT error.
708              * This is mostly happening when moving from DATA phase to Status
709              * phase of the SCSI read/write command. At this stage restarting
710              * the status phase is able to get the device to respond properly.
711              * The NAKLIMIT is device specific. The WIndows hosts allow up to
712              * 5Sec before declaring NAKTIMOUT. MSS USB allows to wait up to
713              * ~4Sec. Hence waiting for another 1 Sec here hoping that the
714              * device is recovered by then.
715              */
716             if (MSC_BOT_STATUS_WAITCOMPLETE == g_msc_bot_state)
717             {
718                 if ((crrent_mili - first_mili) >= 1000u)
719                 {
720                     first_mili = 0u;
721                     crrent_mili = 0u;
722                     MSS_USBH_abort_in_pipe(USBH_MSC_BULK_RX_PIPE);
723 
724                     MSS_USBH_read_in_pipe(g_msd_tdev_addr,
725                                           USBH_MSC_BULK_RX_PIPE,
726                                           g_tdev_in_ep.num,
727                                           g_tdev_in_ep.maxpktsz,
728                                           g_scsi_command.sbuf,
729                                           13u);
730                     g_msc_state = USBH_MSC_DEVICE_READY;
731                 }
732             }
733         }
734         break;
735 
736         default:
737         {
738             ASSERT(0);  /*Reset recovery should be tried.*/
739         }
740         break;
741     }
742 }
743 
744 /*******************************************************************************
745  * See mss_usb_host_msc.h for details of how to use this function.
746  */
747 static void
usbh_msc_construct_class_req(uint8_t * buf,uint8_t req,uint8_t bInterfaceNumber)748 usbh_msc_construct_class_req
749 (
750     uint8_t* buf,
751     uint8_t req,
752     uint8_t bInterfaceNumber
753 )
754 {
755     /* This implementation is as per MSC class spec */
756     buf[0] = 0x21u;                                     /* bmRequestType */
757     buf[1] = req;                                       /* bmRequest */
758 
759     buf[2] = 0x00u;
760     buf[3] = 0x00u;                                      /* wValue */
761 
762     buf[4] = bInterfaceNumber;
763     buf[5] = 0x00u;                                      /* wIndex */
764 
765     if (req == USB_MSC_BOT_REQ_GET_MAX_LUN)
766     {
767         buf[6] = 0x01u;
768         buf[0] = 0xA1u;                                     /* bmRequestType */
769     }
770     else if (req == USB_MSC_BOT_REQ_BMS_RESET)
771     {
772         buf[6] = 0x00u;
773         buf[0] = 0x21u;                                     /* bmRequestType */
774     }
775     else
776     {
777         ASSERT(0);/* invalid MSC class class request */
778     }
779 
780     buf[7] = 0x00u;
781 }
782 
783 /*******************************************************************************
784  * See mss_usb_host_msc.h for details of how to use this function.
785  */
786 void
MSS_USBH_MSC_construct_cbw_cb6byte(uint8_t command_opcode,uint32_t data_xfr_len,msd_cbw_t * buf)787 MSS_USBH_MSC_construct_cbw_cb6byte
788 (
789     uint8_t command_opcode,
790     uint32_t data_xfr_len,
791     msd_cbw_t* buf
792 )
793 {
794     /* This implementation is as per MSC class spec*/
795 
796     /* Inquiry, Request_sense, Test_unit_ready commands (cb10 byte commands) */
797     memset(buf, 0u, 31*(sizeof(uint8_t)));
798     buf->dCBWSignature = USB_MSC_BOT_CBW_SIGNATURE;
799     buf->dCBWTag = 0x20304050U;
800 
801     buf->dCBWDataTransferLength = data_xfr_len;
802 
803     if (USB_MSC_SCSI_TEST_UNIT_READY == command_opcode)
804     {
805         buf->bCBWFlags = 0x00u;
806     }
807     else if ((USB_MSC_SCSI_INQUIRY == command_opcode) ||
808              (USB_MSC_SCSI_REQUEST_SENSE == command_opcode))
809     {
810         buf->bCBWFlags = 0x80u;
811     }
812     else
813     {
814         ASSERT(0);/* invalid cb6byte command */
815     }
816 
817     buf->bCBWCBLength = 0x06u;
818     buf->CBWCB[0] = command_opcode;
819     buf->CBWCB[4] = data_xfr_len;
820 }
821 
822 /*******************************************************************************
823  * See mss_usb_host_msc.h for details of how to use this function.
824  */
825 void
MSS_USBH_MSC_construct_cbw_cb10byte(uint8_t command_opcode,uint8_t lun,uint32_t lb_addr,uint16_t num_of_lb,uint16_t lb_size,msd_cbw_t * buf)826 MSS_USBH_MSC_construct_cbw_cb10byte
827 (
828     uint8_t command_opcode,
829     uint8_t lun,
830     uint32_t lb_addr,
831     uint16_t num_of_lb,
832     uint16_t lb_size,
833     msd_cbw_t* buf
834 )
835 {
836     /* This implementation is as per MSC class spec */
837 
838     /* Read_capacity, Read10, Write10 commands (cb10 byte commands) */
839     memset(buf, 0u, 31*(sizeof(uint8_t)));
840     buf->dCBWSignature = USB_MSC_BOT_CBW_SIGNATURE;
841     buf->dCBWTag = 0x20304050U;
842 
843     if (USB_MSC_SCSI_WRITE_10 == command_opcode)
844     {
845         buf->bCBWFlags = 0x00u;     /* H2D */
846     }
847     else if ((USB_MSC_SCSI_READ_10 == command_opcode) ||
848              (USB_MSC_SCSI_READ_CAPACITY_10 == command_opcode))
849     {
850         buf->bCBWFlags = 0x80u;     /* D2H */
851     }
852 
853     buf->bCBWCBLength = 0x0Au;
854     buf->CBWCB[0] = command_opcode;
855 
856     if ((USB_MSC_SCSI_READ_10 == command_opcode) ||
857         (USB_MSC_SCSI_WRITE_10 == command_opcode))
858     {
859         buf->dCBWDataTransferLength = (num_of_lb * lb_size);    /* Transfer length */
860         buf->CBWCB[1] = lun;                                    /* Lun Number */
861         buf->CBWCB[2] = (uint8_t)((lb_addr >> 24) & 0xFFU);     /* MSB first */
862         buf->CBWCB[3] = (uint8_t)((lb_addr >> 16) & 0xFFU);
863         buf->CBWCB[4] = (uint8_t)((lb_addr >> 8) & 0xFFU);
864         buf->CBWCB[5] = (uint8_t)(lb_addr & 0xFFU);
865 
866         buf->CBWCB[7] = (uint8_t)((num_of_lb >> 8) & 0xFFU);    /* MSB first */
867         buf->CBWCB[8] = (uint8_t)(num_of_lb & 0xFFU);
868     }
869     else if ((USB_MSC_SCSI_READ_CAPACITY_10 == command_opcode))
870     {
871         buf->dCBWDataTransferLength = 0x08u;    /* Read Capacity Transfer length */
872     }
873     else
874     {
875         ASSERT(0);/* invalid cb10byte command */
876     }
877 }
878 
879 /*******************************************************************************
880  * See mss_usb_host_msc.h for details of how to use this function.
881  */
882 mss_usbh_msc_state_t
MSS_USBH_MSC_get_state(void)883 MSS_USBH_MSC_get_state
884 (
885     void
886 )
887 {
888    return(g_msc_state);
889 }
890 
891 uint8_t
MSS_USBH_MSC_scsi_req(uint8_t * command_buf,uint8_t * data_buf,uint32_t data_buf_len,uint8_t * status_buf)892 MSS_USBH_MSC_scsi_req
893 (
894     uint8_t* command_buf, /* always31bytes */
895     uint8_t* data_buf,
896     uint32_t data_buf_len,
897     uint8_t* status_buf /* status always 13bytes */
898 )
899 {
900     g_scsi_command.cbuf = command_buf;
901     g_scsi_command.dbuf = data_buf;
902     g_scsi_command.dbuf_len = data_buf_len;
903     g_scsi_command.sbuf = status_buf;
904 
905     g_msc_bot_state = MSC_BOT_COMMAND_PHASE;
906 
907     MSS_USBH_write_out_pipe(g_msd_tdev_addr,
908                             USBH_MSC_BULK_TX_PIPE,
909                             g_tdev_out_ep.num,
910                             g_tdev_out_ep.maxpktsz,
911                             g_scsi_command.cbuf,
912                             31u); /* std_cbw_len */
913 
914     return(0);
915 }
916 
917 /*******************************************************************************
918  * See mss_usb_host_msc.h for details of how to use this function.
919  */
920 uint8_t
MSS_USBH_MSC_is_scsi_req_complete(void)921 MSS_USBH_MSC_is_scsi_req_complete
922 (
923     void
924 )
925 {
926     return (g_scsi_command.st);
927 }
928 
929 /*******************************************************************************
930  * See mss_usb_host_msc.h for details of how to use this function.
931  */
932 uint32_t
MSS_USBH_MSC_get_sector_count(void)933 MSS_USBH_MSC_get_sector_count
934 (
935     void
936 )
937 {
938     /*
939      * TODO:Check this
940      * Read_capacity_10 command returns the Last LAB i.e. Address of the
941      * last Logical block. Hence Number of logical blocks(sectors) is (Last LBA+1)
942      */
943     return ((g_bot_readcap[0u] << 24u) |
944             (g_bot_readcap[1u] << 16u) |
945             (g_bot_readcap[2u] << 8u) |
946             g_bot_readcap[3u]);
947 }
948 
949 /*******************************************************************************
950  * See mss_usb_host_msc.h for details of how to use this function.
951  */
952 uint32_t
MSS_USBH_MSC_get_sector_size(void)953 MSS_USBH_MSC_get_sector_size
954 (
955     void
956 )
957 {
958     /*
959      * Return the logical block(sector) size in bytes.
960      */
961     return ((g_bot_readcap[4u] << 24u) |
962             (g_bot_readcap[5u] << 16u) |
963             (g_bot_readcap[6u] << 8u) |
964              g_bot_readcap[7u]);
965 }
966 
967 /*******************************************************************************
968  * See mss_usb_host_msc.h for details of how to use this function.
969  */
970 int8_t
MSS_USBH_MSC_read(uint8_t * buf,uint32_t sector,uint32_t count)971 MSS_USBH_MSC_read
972 (
973     uint8_t* buf,
974     uint32_t sector,
975     uint32_t count
976 )
977 {
978     if (0u == g_scsi_command.st)
979     {
980         g_scsi_command.st = 1u;
981         MSS_USBH_MSC_construct_cbw_cb10byte(USB_MSC_SCSI_READ_10,
982                                             0u,
983                                             sector,
984                                             count,
985                                             512u,
986                                             &g_bot_cbw);
987 
988         MSS_USBH_MSC_scsi_req((uint8_t*)&g_bot_cbw,
989                               buf,
990                               (count*512u),
991                               (uint8_t*)&g_bot_csw);
992         return (0);
993     }
994     else
995     {
996         return (-1); /* previous command is in progress */
997     }
998 }
999 
1000 /*******************************************************************************
1001  * See mss_usb_host_msc.h for details of how to use this function.
1002  */
1003 int8_t
MSS_USBH_MSC_write(uint8_t * buf,uint32_t sector,uint32_t count)1004 MSS_USBH_MSC_write
1005 (
1006     uint8_t* buf,
1007     uint32_t sector,
1008     uint32_t count
1009 )
1010 {
1011     if (0u == g_scsi_command.st)
1012     {
1013         g_scsi_command.st = 1u;
1014         MSS_USBH_MSC_construct_cbw_cb10byte(USB_MSC_SCSI_WRITE_10,
1015                                             0u,
1016                                             sector,
1017                                             count,
1018                                             512u,
1019                                             &g_bot_cbw);
1020 
1021         MSS_USBH_MSC_scsi_req((uint8_t*)&g_bot_cbw,
1022                               buf,
1023                               (count*512u),
1024                               (uint8_t*)&g_bot_csw);
1025         return (0);
1026     }
1027     else
1028     {
1029         return (-1); /* Previous command is in progress */
1030     }
1031 }
1032 
1033 /*******************************************************************************
1034  * Internal Functions
1035  ******************************************************************************/
1036 
1037 /*
1038  * This Call-back function is executed when the USBH-MSC driver is allocated
1039  * to the attached device by USBH driver.
1040  */
1041 uint8_t
usbh_msc_allocate_cb(uint8_t tdev_addr)1042 usbh_msc_allocate_cb
1043 (
1044     uint8_t tdev_addr
1045 )
1046 {
1047     g_msd_tdev_addr = tdev_addr;
1048     g_usbh_msc_alloc_event = 1u;
1049     return(USB_SUCCESS);
1050 }
1051 
1052 /*
1053  * This Call-back function is executed when the USBH-MSC driver is released
1054  * from the attached device by USBH driver.
1055  */
1056 uint8_t
usbh_msc_release_cb(uint8_t tdev_addr)1057 usbh_msc_release_cb
1058 (
1059     uint8_t tdev_addr
1060 )
1061 {
1062     g_msc_state = USBH_MSC_IDLE;
1063     g_msc_bot_state = MSC_BOT_IDLE;
1064     g_tdev_max_lun_idx = 0u;
1065     memset(g_msd_conf_desc, 0u, sizeof(g_msd_conf_desc));
1066     memset(g_bot_inquiry, 0u, sizeof(g_bot_inquiry));
1067     memset(&g_bot_csw, 0u, sizeof(g_bot_csw));
1068     g_tdev_in_ep.maxpktsz = 0u;
1069     g_tdev_in_ep.num = 0u;
1070     g_tdev_out_ep.maxpktsz = 0u;
1071     g_tdev_out_ep.num = 0u;
1072     g_msd_tdev_addr = 0u;
1073 
1074     g_scsi_command.cbuf = (uint8_t*)0;
1075     g_scsi_command.dbuf = (uint8_t*)0;
1076     g_scsi_command.sbuf = (uint8_t*)0;
1077     g_scsi_command.dbuf_len = 0u;
1078     g_scsi_command.st = 0u;
1079     memset(g_bot_readcap, 0u, sizeof(g_bot_readcap));
1080 
1081     MSS_USB_CIF_tx_ep_disable_irq(USBH_MSC_BULK_RX_PIPE);
1082     MSS_USB_CIF_tx_ep_clr_csrreg(USBH_MSC_BULK_RX_PIPE);
1083     MSS_USB_CIF_dma_clr_ctrlreg(MSS_USB_DMA_CHANNEL2);
1084 
1085     MSS_USB_CIF_rx_ep_disable_irq(USBH_MSC_BULK_TX_PIPE);
1086     MSS_USB_CIF_rx_ep_clr_csrreg(USBH_MSC_BULK_TX_PIPE);
1087     MSS_USB_CIF_dma_clr_ctrlreg(MSS_USB_DMA_CHANNEL1);
1088 
1089     if (0 != g_msch_user_cb->msch_driver_released)
1090     {
1091         g_msch_user_cb->msch_driver_released();
1092     }
1093 
1094     return(USB_SUCCESS);
1095 }
1096 
1097 /*
1098  * This Call-back function is executed when the control transfer initiated by this
1099  * driver is complete.
1100  */
1101 uint8_t
usbh_msc_cep_done_cb(uint8_t tdev_addr,uint8_t status,uint32_t count)1102 usbh_msc_cep_done_cb
1103 (
1104     uint8_t tdev_addr,
1105     uint8_t status,
1106     uint32_t count
1107 )
1108 {
1109     g_usbh_msc_cep_event = status;
1110 
1111     return (USB_SUCCESS);
1112 }
1113 
1114 /*
1115  * This Call-back function is executed when the data OUT transfer initiated by
1116  * this driver is complete.
1117  */
1118 uint8_t
usbh_msc_tx_complete_cb(uint8_t tdev_addr,uint8_t status,uint32_t count)1119 usbh_msc_tx_complete_cb
1120 (
1121     uint8_t tdev_addr,
1122     uint8_t status,
1123     uint32_t count
1124 )
1125 {
1126     if (g_msc_state < USBH_MSC_DEVICE_READY)
1127     {
1128         g_usbh_msc_tx_event = 1u;
1129     }
1130     else
1131     {
1132         if (0u == status)
1133         {
1134             switch (g_msc_bot_state)
1135             {
1136                 case MSC_BOT_COMMAND_PHASE:
1137                 if (0u == g_scsi_command.dbuf_len)/* zdl request */
1138                 {
1139                     g_msc_bot_state = MSC_BOT_STATUS_WAITCOMPLETE;
1140                     MSS_USBH_read_in_pipe(g_msd_tdev_addr,
1141                                           USBH_MSC_BULK_RX_PIPE,
1142                                           g_tdev_in_ep.num,
1143                                           g_tdev_in_ep.maxpktsz,
1144                                           g_scsi_command.sbuf,
1145                                           13u);
1146                 }
1147                 else
1148                 {
1149                     g_msc_bot_state = MSC_BOT_DATA_PHASE;
1150                     if (g_scsi_command.cbuf[12] & 0x80U)  /* bmCBWFLags field -- Read Command */
1151                     {
1152                         MSS_USBH_read_in_pipe(g_msd_tdev_addr,
1153                                               USBH_MSC_BULK_RX_PIPE,
1154                                               g_tdev_in_ep.num,
1155                                               g_tdev_in_ep.maxpktsz,
1156                                               g_scsi_command.dbuf,
1157                                               g_scsi_command.dbuf_len);
1158                     }
1159                     else /* write command */
1160                     {
1161                         MSS_USBH_write_out_pipe(g_msd_tdev_addr,
1162                                                 USBH_MSC_BULK_TX_PIPE,
1163                                                 g_tdev_out_ep.num,
1164                                                 g_tdev_out_ep.maxpktsz,
1165                                                 g_scsi_command.dbuf,
1166                                                 g_scsi_command.dbuf_len); /* data_length */
1167                     }
1168                 }
1169                 break;
1170 
1171                 case MSC_BOT_DATA_PHASE:
1172                 if (count == g_scsi_command.dbuf_len)
1173                 {
1174                     g_msc_bot_state = MSC_BOT_STATUS_WAITCOMPLETE;
1175 
1176                     MSS_USBH_read_in_pipe(g_msd_tdev_addr,
1177                                           USBH_MSC_BULK_RX_PIPE,
1178                                           g_tdev_in_ep.num,
1179                                           g_tdev_in_ep.maxpktsz,
1180                                           g_scsi_command.sbuf,
1181                                           13u);
1182                 }
1183                 else
1184                 {
1185                     ASSERT(0);  /* at this point all data must be transfered */
1186                 }
1187                 break;
1188 
1189                 case MSC_BOT_STATUS_WAITCOMPLETE:
1190                 break;
1191 
1192                 default:
1193                     ASSERT(0);  /* g_msc_bot_state must not be in any other state */
1194                 break;
1195             }
1196         }
1197         else if (MSS_USB_EP_NAK_TOUT & status)
1198         {
1199             /* Device responding with NAKs. Retry */
1200             g_msc_state = USBH_MSC_BOT_RETRY;
1201         }
1202         else
1203         {
1204             ASSERT(0);/* Handling any other error. Not yet supported */
1205         }
1206 
1207     }
1208     return (USB_SUCCESS);
1209 }
1210 
1211 /*
1212  * This Call-back function is executed when the data IN transfer initiated by
1213  * this driver is complete.
1214 */
1215 uint8_t
usbh_msc_rx_cb(uint8_t tdev_addr,uint8_t status,uint32_t count)1216 usbh_msc_rx_cb
1217 (
1218     uint8_t tdev_addr,
1219     uint8_t status,
1220     uint32_t count
1221 )
1222 {
1223     if (g_msc_state < USBH_MSC_DEVICE_READY)
1224     {
1225         g_usbh_msc_rx_event = 1u;
1226     }
1227     else
1228     {
1229         if (0x0U == status)
1230         {
1231             switch (g_msc_bot_state)
1232             {
1233             case MSC_BOT_DATA_PHASE:
1234                 if (count == g_scsi_command.dbuf_len)
1235                 {
1236                     g_msc_bot_state = MSC_BOT_STATUS_WAITCOMPLETE;
1237 
1238                     MSS_USBH_read_in_pipe(g_msd_tdev_addr,
1239                                           USBH_MSC_BULK_RX_PIPE,
1240                                           g_tdev_in_ep.num,
1241                                           g_tdev_in_ep.maxpktsz,
1242                                           g_scsi_command.sbuf,
1243                                           13u);
1244                 }
1245                 else
1246                 {
1247                     ASSERT(0);/* at this point all data must be transferred */
1248                 }
1249             break;
1250 
1251             case MSC_BOT_STATUS_WAITCOMPLETE:
1252                 g_usbh_msc_rx_event = 0u;
1253                 g_scsi_command.st = 0u;
1254                 g_msc_bot_state = MSC_BOT_IDLE;
1255             break;
1256 
1257             default:
1258                 ASSERT(0);/*g_msc_bot_state must not be in any other state */
1259             break;
1260             }
1261         }
1262         else if (MSS_USB_EP_NAK_TOUT & status)
1263         {
1264             /* Device responding with NAKs. Retry */
1265             g_msc_state = USBH_MSC_BOT_RETRY;
1266         }
1267         else
1268         {
1269             ASSERT(0);/* Handling any other error. Not yet supported */
1270         }
1271     }
1272 
1273     return (USB_SUCCESS);
1274 }
1275 
1276 /*
1277  * This function validates the MSC class descriptors.
1278  */
1279 mss_usbh_msc_err_code_t
MSS_USBH_MSC_validate_class_desc(uint8_t * p_cd)1280 MSS_USBH_MSC_validate_class_desc
1281 (
1282     uint8_t* p_cd
1283 )
1284 {
1285     return(USBH_MSC_NO_ERROR);
1286 }
1287 
1288 /*
1289  * This function extract the endpoint information from the Config Descriptor.
1290  */
1291 mss_usbh_msc_err_code_t
MSS_USBH_MSC_extract_tdev_ep_desc(void)1292 MSS_USBH_MSC_extract_tdev_ep_desc
1293 (
1294     void
1295 )
1296 {
1297     mss_usbh_msc_err_code_t error = USBH_MSC_NO_ERROR;
1298 
1299     if (!(g_msd_conf_desc[21u] & USB_EP_DESCR_ATTR_BULK))      /* FirstEP Attributes Not BulkEP */
1300     {
1301         error = USBH_MSC_WRONG_DESCR;
1302     }
1303     if (!(g_msd_conf_desc[28u] & USB_EP_DESCR_ATTR_BULK))      /*SecondEP Attributes Not BulkEP */
1304     {
1305         error = USBH_MSC_WRONG_DESCR;
1306     }
1307 
1308     if (g_msd_conf_desc[20u] & USB_STD_REQ_DATA_DIR_MASK)     /* TdevEP is IN type */
1309     {
1310         g_tdev_in_ep.num = (g_msd_conf_desc[20u] & 0x7fu);
1311         g_tdev_in_ep.maxpktsz = (uint16_t)((g_msd_conf_desc[23u] << 8u) |
1312                                            (g_msd_conf_desc[22u]));
1313 
1314         g_tdev_out_ep.num = (g_msd_conf_desc[27u] & 0x7fu);
1315         g_tdev_out_ep.maxpktsz = (uint16_t)((g_msd_conf_desc[30u] << 8u) |
1316                                             (g_msd_conf_desc[29u]));
1317 
1318     }
1319     else if (g_msd_conf_desc[27u] & USB_STD_REQ_DATA_DIR_MASK)
1320     {
1321         g_tdev_in_ep.num = (g_msd_conf_desc[27u] & 0x7fu);
1322         g_tdev_in_ep.maxpktsz = (uint16_t)((g_msd_conf_desc[30u] << 8u) |
1323                                            (g_msd_conf_desc[29u]));
1324 
1325         g_tdev_out_ep.num = (g_msd_conf_desc[20u] & 0x7fu);
1326         g_tdev_out_ep.maxpktsz = (uint16_t)((g_msd_conf_desc[23u] << 8u) |
1327                                             (g_msd_conf_desc[22u]));
1328     }
1329     else
1330     {
1331         error = USBH_MSC_WRONG_DESCR;
1332     }
1333 
1334     return(error);
1335 }
1336 
1337 #endif /* MSS_USB_HOST_ENABLED */
1338 
1339 #ifdef __cplusplus
1340 }
1341 #endif
1342