1 /*
2 * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016 - 2017,2019 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "usb_device_config.h"
10 #include "usb.h"
11 #include "usb_device.h"
12
13 #include "usb_device_class.h"
14
15 #if ((defined(USB_DEVICE_CONFIG_MSC)) && (USB_DEVICE_CONFIG_MSC > 0U))
16 #include "usb_device_msc.h"
17 /*******************************************************************************
18 * Definitions
19 ******************************************************************************/
20
21 /*******************************************************************************
22 * Prototypes
23 ******************************************************************************/
24 usb_status_t USB_DeviceMscRecv(usb_device_msc_struct_t *mscHandle);
25 usb_status_t USB_DeviceMscSend(usb_device_msc_struct_t *mscHandle);
26 usb_status_t USB_DeviceMscEndpointsInit(usb_device_msc_struct_t *mscHandle);
27 usb_status_t USB_DeviceMscEndpointsDeinit(usb_device_msc_struct_t *mscHandle);
28
29 /*******************************************************************************
30 * Variables
31 ******************************************************************************/
32
33 #if (USB_DEVICE_CONFIG_MSC == 1U)
34 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_msc_cbw_t s_MscCbw1;
35 #define MSCCBW_ARRAY \
36 { \
37 &s_MscCbw1 \
38 }
39 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_msc_csw_t s_MscCsw1;
40 #define MSCCSW_ARRAY \
41 { \
42 &s_MscCsw1 \
43 }
44 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_request_sense_data_struct_t requestSense1;
45 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_read_capacity_struct_t readCapacity1;
46 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_read_capacity16_data_struct_t
47 readCapacity161;
48 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint8_t
49 formatCapacityData1[sizeof(usb_device_capacity_list_header_struct_t) +
50 sizeof(usb_device_current_max_capacity_descriptor_struct_t) +
51 sizeof(usb_device_formattable_capacity_descriptor_struct_t) * 3];
52 #define MSCSENSE_ARRAY \
53 { \
54 &requestSense1 \
55 }
56 #define MSCCPAP_ARRAY \
57 { \
58 &readCapacity1 \
59 }
60 #define MSCCAPA16_ARRAY \
61 { \
62 &readCapacity161 \
63 }
64 #define MSCFORMAT_ARRAY \
65 { \
66 &formatCapacityData1[0] \
67 }
68 #elif (USB_DEVICE_CONFIG_MSC == 2U)
69 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_msc_cbw_t s_MscCbw1;
70 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_msc_cbw_t s_MscCbw2;
71 #define MSCCBW_ARRAY \
72 { \
73 &s_MscCbw1, &s_MscCbw2 \
74 }
75 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_msc_csw_t s_MscCsw1;
76 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_msc_csw_t s_MscCsw2;
77 #define MSCCSW_ARRAY \
78 { \
79 &s_MscCsw1, &s_MscCsw2 \
80 }
81 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_request_sense_data_struct_t requestSense1;
82 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_read_capacity_struct_t readCapacity1;
83 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_read_capacity16_data_struct_t
84 readCapacity161;
85 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint8_t
86 formatCapacityData1[sizeof(usb_device_capacity_list_header_struct_t) +
87 sizeof(usb_device_current_max_capacity_descriptor_struct_t) +
88 sizeof(usb_device_formattable_capacity_descriptor_struct_t) * 3];
89 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_request_sense_data_struct_t requestSense2;
90 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_read_capacity_struct_t readCapacity2;
91 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) usb_device_read_capacity16_data_struct_t readCapacity162;
92 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) uint8_t
93 formatCapacityData2[sizeof(usb_device_capacity_list_header_struct_t) +
94 sizeof(usb_device_current_max_capacity_descriptor_struct_t) +
95 sizeof(usb_device_formattable_capacity_descriptor_struct_t) * 3];
96 #define MSCSENSE_ARRAY \
97 { \
98 &requestSense1, &requestSense2 \
99 }
100 #define MSCCPAP_ARRAY \
101 { \
102 &readCapacity1, &readCapacity2 \
103 }
104 #define MSCCAPA16_ARRAY \
105 { \
106 &readCapacity161, &readCapacity162 \
107 }
108 #define MSCFORMAT_ARRAY \
109 { \
110 &formatCapacityData1[0], &formatCapacityData2[0] \
111 }
112 #elif (USB_DEVICE_CONFIG_MSC == 3U)
113 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_msc_cbw_t s_MscCbw1;
114 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_msc_cbw_t s_MscCbw2;
115 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_msc_cbw_t s_MscCbw3;
116 #define MSCCBW_ARRAY \
117 { \
118 &s_MscCbw1, &s_MscCbw2, &s_MscCbw3 \
119 }
120 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_msc_csw_t s_MscCsw1;
121 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_msc_csw_t s_MscCsw2;
122 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_msc_csw_t s_MscCsw3;
123 #define MSCCSW_ARRAY \
124 { \
125 &s_MscCsw1, &s_MscCsw2, &s_MscCsw3 \
126 }
127 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_request_sense_data_struct_t requestSense1;
128 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_read_capacity_struct_t readCapacity1;
129 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_read_capacity16_data_struct_t
130 readCapacity161;
131 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint8_t
132 formatCapacityData1[sizeof(usb_device_capacity_list_header_struct_t) +
133 sizeof(usb_device_current_max_capacity_descriptor_struct_t) +
134 sizeof(usb_device_formattable_capacity_descriptor_struct_t) * 3];
135 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_request_sense_data_struct_t requestSense2;
136 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_read_capacity_struct_t readCapacity2;
137 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_read_capacity16_data_struct_t
138 readCapacity162;
139 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint8_t
140 formatCapacityData2[sizeof(usb_device_capacity_list_header_struct_t) +
141 sizeof(usb_device_current_max_capacity_descriptor_struct_t) +
142 sizeof(usb_device_formattable_capacity_descriptor_struct_t) * 3];
143 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_request_sense_data_struct_t requestSense3;
144 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_read_capacity_struct_t readCapacity3;
145 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_read_capacity16_data_struct_t
146 readCapacity163;
147 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static uint8_t
148 formatCapacityData3[sizeof(usb_device_capacity_list_header_struct_t) +
149 sizeof(usb_device_current_max_capacity_descriptor_struct_t) +
150 sizeof(usb_device_formattable_capacity_descriptor_struct_t) * 3];
151 #define MSCSENSE_ARRAY \
152 { \
153 &requestSense1, &requestSense2, &requestSense3 \
154 }
155 #define MSCCPAP_ARRAY \
156 { \
157 &readCapacity1, &readCapacity2, &readCapacity3 \
158 }
159 #define MSCCAPA16_ARRAY \
160 { \
161 &readCapacity161, &readCapacity162, &readCapacity163 \
162 }
163 #define MSCFORMAT_ARRAY \
164 { \
165 &formatCapacityData1[0], &formatCapacityData2[0], &formatCapacityData3[0] \
166 }
167 #else
168 #error "the max support USB_DEVICE_CONFIG_MSC is 3"
169 #endif
170
USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE)171 USB_GLOBAL USB_RAM_ADDRESS_ALIGNMENT(USB_DATA_ALIGN_SIZE) static usb_device_msc_struct_t
172 g_msc_handle[USB_DEVICE_CONFIG_MSC];
173 /*******************************************************************************
174 * Code
175 ******************************************************************************/
176
177 /*!
178 * @brief Allocate a device msc class handle.
179 *
180 * This function allocates a device msc class handle.
181 *
182 * @param handle It is out parameter, is used to return pointer of the device msc class handle to the caller.
183 *
184 * @retval kStatus_USB_Success Get a device msc class handle successfully.
185 * @retval kStatus_USB_Busy Cannot allocate a device msc class handle.
186 */
187
188 static usb_status_t USB_DeviceMscAllocateHandle(usb_device_msc_struct_t **handle)
189 {
190 uint32_t count;
191 usb_device_msc_cbw_t *cbw_array[] = MSCCBW_ARRAY;
192 usb_device_msc_csw_t *csw_array[] = MSCCSW_ARRAY;
193 usb_device_request_sense_data_struct_t *sense[] = MSCSENSE_ARRAY;
194 usb_device_read_capacity_struct_t *capacity_array[] = MSCCPAP_ARRAY;
195 usb_device_read_capacity16_data_struct_t *capacity16_array[] = MSCCAPA16_ARRAY;
196 uint8_t *formatCapacityData[] = MSCFORMAT_ARRAY;
197
198 for (count = 0; count < USB_DEVICE_CONFIG_MSC; count++)
199 {
200 if (NULL == g_msc_handle[count].handle)
201 {
202 g_msc_handle[count].mscCbw = (cbw_array[count]);
203 g_msc_handle[count].mscCsw = (csw_array[count]);
204 g_msc_handle[count].mscUfi.requestSense = (sense[count]);
205 g_msc_handle[count].mscUfi.readCapacity = (capacity_array[count]);
206 g_msc_handle[count].mscUfi.readCapacity16 = (capacity16_array[count]);
207 g_msc_handle[count].mscUfi.formatCapacityData = (formatCapacityData[count]);
208 *handle = &g_msc_handle[count];
209 return kStatus_USB_Success;
210 }
211 }
212
213 return kStatus_USB_Busy;
214 }
215
216 /*!
217 * @brief Free a device msc class handle.
218 *
219 * This function frees a device msc class handle.
220 *
221 * @param handle The device msc class handle.
222 *
223 * @retval kStatus_USB_Success Free device msc class handle successfully.
224 */
USB_DeviceMscFreeHandle(usb_device_msc_struct_t * handle)225 static usb_status_t USB_DeviceMscFreeHandle(usb_device_msc_struct_t *handle)
226 {
227 handle->handle = NULL;
228 handle->configurationStruct = (usb_device_class_config_struct_t *)NULL;
229 handle->configuration = 0;
230 handle->alternate = 0;
231 return kStatus_USB_Success;
232 }
233
234 /*!
235 * @brief Process usb msc ufi command.
236 *
237 * This function analyse the cbw , get the command code.
238 *
239 * @param handle The device msc class handle.
240 *
241 * @retval kStatus_USB_Success Free device msc class handle successfully.
242 */
USB_DeviceMscProcessUfiCommand(usb_device_msc_struct_t * mscHandle)243 static usb_status_t USB_DeviceMscProcessUfiCommand(usb_device_msc_struct_t *mscHandle)
244 {
245 usb_status_t status;
246 usb_device_msc_ufi_struct_t *ufi = NULL;
247
248 ufi = &mscHandle->mscUfi;
249 if (USB_DEVICE_MSC_REQUEST_SENSE_COMMAND != mscHandle->mscCbw->cbwcb[0])
250 {
251 ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_NO_SENSE;
252 ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_NO_SENSE;
253 ufi->requestSense->additionalSenseQualifer = USB_DEVICE_MSC_UFI_NO_SENSE;
254 }
255 ufi->thirteenCase.hostExpectedDataLength = mscHandle->mscCbw->dataTransferLength;
256 ufi->thirteenCase.hostExpectedDirection = (uint8_t)(mscHandle->mscCbw->flags >> USB_DEVICE_MSC_CBW_DIRECTION_SHIFT);
257 /*The first byte of all ufi command blocks shall contain an Operation Code, refer to ufi spec*/
258 switch (mscHandle->mscCbw->cbwcb[0])
259 {
260 /* ufi command operation code*/
261 case USB_DEVICE_MSC_INQUIRY_COMMAND: /*operation code : 0x12*/
262 status = USB_DeviceMscUfiInquiryCommand(mscHandle);
263 break;
264 case USB_DEVICE_MSC_READ_10_COMMAND: /*operation code : 0x28 */
265 case USB_DEVICE_MSC_READ_12_COMMAND: /*operation code : 0xA8 */
266 status = USB_DeviceMscUfiReadCommand(mscHandle);
267 break;
268 case USB_DEVICE_MSC_REQUEST_SENSE_COMMAND: /*operation code : 0x03*/
269 status = USB_DeviceMscUfiRequestSenseCommand(mscHandle);
270 break;
271 case USB_DEVICE_MSC_TEST_UNIT_READY_COMMAND: /*operation code : 0x00 */
272 status = USB_DeviceMscUfiTestUnitReadyCommand(mscHandle);
273 break;
274 case USB_DEVICE_MSC_WRITE_10_COMMAND: /*operation code : 0x2A */
275 case USB_DEVICE_MSC_WRITE_12_COMMAND: /*operation code : 0xAA */
276 status = USB_DeviceMscUfiWriteCommand(mscHandle);
277 break;
278 case USB_DEVICE_MSC_PREVENT_ALLOW_MEDIUM_REM_COMMAND: /*operation code :0x1E */
279 status = USB_DeviceMscUfiPreventAllowMediumCommand(mscHandle);
280 break;
281 case USB_DEVICE_MSC_FORMAT_UNIT_COMMAND: /*operation code : 0x04*/
282 status = USB_DeviceMscUfiFormatUnitCommand(mscHandle);
283 break;
284 case USB_DEVICE_MSC_READ_CAPACITY_10_COMMAND: /*operation code : 0x25*/
285 case USB_DEVICE_MSC_READ_CAPACITY_16_COMMAND: /*operation code : 0x9E*/
286 status = USB_DeviceMscUfiReadCapacityCommand(mscHandle);
287 break;
288 case USB_DEVICE_MSC_MODE_SENSE_10_COMMAND: /* operation code :0x5A*/
289 case USB_DEVICE_MSC_MODE_SENSE_6_COMMAND: /* operation code : 0x1A */
290 status = USB_DeviceMscUfiModeSenseCommand(mscHandle);
291 break;
292 case USB_DEVICE_MSC_MODE_SELECT_10_COMMAND: /*operation code : 0x55 */
293 case USB_DEVICE_MSC_MODE_SELECT_6_COMMAND: /*operation code : 0x15 */
294 status = USB_DeviceMscUfiModeSelectCommand(mscHandle);
295 break;
296 case USB_DEVICE_MSC_READ_FORMAT_CAPACITIES_COMMAND: /*operation code : 0x23 */
297 status = USB_DeviceMscUfiReadFormatCapacityCommand(mscHandle);
298 break;
299 case USB_DEVICE_MSC_SEND_DIAGNOSTIC_COMMAND: /*operation code : 0x1D*/
300 status = USB_DeviceMscUfiSendDiagnosticCommand(mscHandle);
301 break;
302 case USB_DEVICE_MSC_VERIFY_COMMAND: /*operation code : 0x2F*/
303 status = USB_DeviceMscUfiVerifyCommand(mscHandle);
304 break;
305 case USB_DEVICE_MSC_START_STOP_UNIT_COMMAND: /*operation code : 0x1B*/
306 status = USB_DeviceMscUfiStartStopUnitCommand(mscHandle);
307 break;
308 default:
309 status = USB_DeviceMscUfiUnsupportCommand(mscHandle);
310 break;
311 }
312 if ((USB_DEVICE_MSC_UFI_NO_SENSE != ufi->requestSense->senseKey) &&
313 (USB_DEVICE_MSC_COMMAND_PASSED == mscHandle->mscCsw->cswStatus) &&
314 (USB_DEVICE_MSC_REQUEST_SENSE_COMMAND != mscHandle->mscCbw->cbwcb[0]))
315 {
316 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED;
317 }
318 return status;
319 }
320
321 /*!
322 * @brief Bulk IN endpoint callback function.
323 *
324 * This callback function is used to notify upper layer the transfer result of a transfer.
325 * This callback pointer is passed when the Bulk IN pipe initialized.
326 *
327 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
328 * @param message The result of the Bulk IN pipe transfer.
329 * @param callbackParam The parameter for this callback. It is same with
330 * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the MSC class handle.
331 *
332 * @return A USB error code or kStatus_USB_Success.
333 */
USB_DeviceMscBulkIn(usb_device_handle handle,usb_device_endpoint_callback_message_struct_t * message,void * callbackParam)334 static usb_status_t USB_DeviceMscBulkIn(usb_device_handle handle,
335 usb_device_endpoint_callback_message_struct_t *message,
336 void *callbackParam)
337 {
338 usb_device_msc_struct_t *mscHandle = (usb_device_msc_struct_t *)callbackParam;
339 usb_device_msc_csw_t *csw = NULL;
340 void *temp;
341 usb_status_t error = kStatus_USB_Error;
342 /* endpoint callback length is USB_CANCELLED_TRANSFER_LENGTH (0xFFFFFFFFU) when transfer is canceled */
343 if (message->length == USB_CANCELLED_TRANSFER_LENGTH)
344 {
345 /*this code is called when stack cancel the transfer, app should release the buffer it use */
346 if ((0U != mscHandle->dataInFlag) && (mscHandle->configurationStruct->classCallback != NULL) &&
347 ((USB_DEVICE_MSC_READ_10_COMMAND == mscHandle->mscCbw->cbwcb[0]) ||
348 (USB_DEVICE_MSC_READ_12_COMMAND == mscHandle->mscCbw->cbwcb[0])))
349 {
350 usb_device_lba_app_struct_t lbaData;
351
352 lbaData.size = 0;
353 lbaData.buffer = message->buffer;
354 lbaData.offset = 0;
355 lbaData.lun = mscHandle->mscCbw->logicalUnitNumber;
356 /*classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
357 it is from the second parameter of classInit */
358 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
359 if (kStatus_USB_Success != mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle,
360 kUSB_DeviceMscEventReadResponse,
361 (void *)&lbaData))
362 {
363 return kStatus_USB_Error;
364 }
365 #else
366 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle,
367 kUSB_DeviceMscEventReadResponse, (void *)&lbaData);
368 #endif
369 }
370 if (mscHandle->inEndpointCswCancelFlag == 1U)
371 {
372 mscHandle->inEndpointCswCancelFlag = 0U;
373 /*cancel the transfer and wait for the calcel to be complete in bulk in callback*/
374 /*send csw*/
375 mscHandle->mscCsw->dataResidue = USB_LONG_TO_LITTLE_ENDIAN(mscHandle->mscCsw->dataResidue);
376 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
377 if (kStatus_USB_Success != USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint,
378 (uint8_t *)mscHandle->mscCsw, USB_DEVICE_MSC_CSW_LENGTH))
379 {
380 return kStatus_USB_Error;
381 }
382 #else
383 (void)USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, (uint8_t *)mscHandle->mscCsw,
384 USB_DEVICE_MSC_CSW_LENGTH);
385 #endif
386 mscHandle->cswPrimeFlag = 1;
387 mscHandle->stallStatus = 0;
388 }
389 return error;
390 }
391 if (mscHandle->transferRemaining >= message->length)
392 {
393 mscHandle->transferRemaining -= message->length;
394 }
395
396 if (mscHandle->needInStallFlag == 1U)
397 {
398 mscHandle->needInStallFlag = 0U;
399 mscHandle->inEndpointStallFlag = 1U;
400 mscHandle->dataInFlag = 0U;
401 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
402 if (kStatus_USB_Success != USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkInEndpoint))
403 {
404 return kStatus_USB_Error;
405 }
406 #else
407 (void)USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkInEndpoint);
408 #endif
409 return error;
410 }
411 if ((0U == mscHandle->dataInFlag) && (message->length == USB_DEVICE_MSC_CSW_LENGTH))
412 {
413 temp = (void *)(message->buffer);
414 csw = (usb_device_msc_csw_t *)temp;
415 }
416
417 if (0U != mscHandle->dataInFlag)
418 {
419 if ((mscHandle->configurationStruct->classCallback != NULL))
420 {
421 usb_device_lba_app_struct_t lbaData;
422
423 lbaData.size = message->length;
424 lbaData.buffer = message->buffer;
425 lbaData.offset = mscHandle->currentOffset;
426 lbaData.lun = mscHandle->mscCbw->logicalUnitNumber;
427
428 if ((USB_DEVICE_MSC_READ_10_COMMAND == mscHandle->mscCbw->cbwcb[0]) ||
429 (USB_DEVICE_MSC_READ_12_COMMAND == mscHandle->mscCbw->cbwcb[0]))
430 {
431 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
432 it is from the second parameter of classInit */
433 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
434 if (kStatus_USB_Success !=
435 mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle,
436 kUSB_DeviceMscEventReadResponse, (void *)&lbaData))
437 {
438 return kStatus_USB_Error;
439 }
440 #else
441 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle,
442 kUSB_DeviceMscEventReadResponse, (void *)&lbaData);
443 #endif
444 }
445
446 if (0U != mscHandle->transferRemaining)
447 {
448 mscHandle->currentOffset +=
449 (message->length / mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].lengthOfEachLba);
450 error = USB_DeviceMscSend(mscHandle);
451 }
452 if (0U == mscHandle->transferRemaining)
453 {
454 mscHandle->dataInFlag = 0U;
455 /*data transfer has been done, send the csw to host */
456 mscHandle->cswPrimeFlag = 1U;
457 mscHandle->mscCsw->dataResidue = USB_LONG_TO_LITTLE_ENDIAN(mscHandle->mscCsw->dataResidue);
458 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
459 if (kStatus_USB_Success != USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint,
460 (uint8_t *)mscHandle->mscCsw,
461 USB_DEVICE_MSC_CSW_LENGTH))
462 {
463 return kStatus_USB_Error;
464 }
465 #else
466 (void)USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, (uint8_t *)mscHandle->mscCsw,
467 USB_DEVICE_MSC_CSW_LENGTH);
468 #endif
469 }
470 }
471 }
472 else if ((message->length == USB_DEVICE_MSC_CSW_LENGTH) && (USB_DEVICE_MSC_DCSWSIGNATURE == csw->signature))
473 {
474 mscHandle->cbwValidFlag = 1U;
475 mscHandle->cswPrimeFlag = 0U;
476 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
477 if (kStatus_USB_Success != USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint,
478 (uint8_t *)mscHandle->mscCbw, USB_DEVICE_MSC_CBW_LENGTH))
479 {
480 return kStatus_USB_Error;
481 }
482 #else
483 (void)USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, (uint8_t *)mscHandle->mscCbw,
484 USB_DEVICE_MSC_CBW_LENGTH);
485 #endif
486 mscHandle->cbwPrimeFlag = 1U;
487 }
488 else
489 {
490 /*no action*/
491 }
492 return error;
493 }
494
495 /*!
496 * @brief Bulk OUT endpoint callback function.
497 *
498 * This callback function is used to notify upper layer the transfer result of a transfer.
499 * This callback pointer is passed when the Bulk OUT pipe initialized.
500 *
501 * @param handle The device handle. It equals the value returned from USB_DeviceInit.
502 * @param message The result of the Bulk OUT pipe transfer.
503 * @param callbackParam The parameter for this callback. It is same with
504 * usb_device_endpoint_callback_struct_t::callbackParam. In the class, the value is the MSC class handle.
505 *
506 * @return A USB error code or kStatus_USB_Success.
507 */
USB_DeviceMscBulkOut(usb_device_handle handle,usb_device_endpoint_callback_message_struct_t * message,void * callbackParam)508 static usb_status_t USB_DeviceMscBulkOut(usb_device_handle handle,
509 usb_device_endpoint_callback_message_struct_t *message,
510 void *callbackParam)
511 {
512 usb_device_msc_struct_t *mscHandle = (usb_device_msc_struct_t *)callbackParam;
513 usb_status_t error = kStatus_USB_Success;
514
515 /* endpoint callback length is USB_CANCELLED_TRANSFER_LENGTH (0xFFFFFFFFU) when transfer is canceled */
516 if (message->length == USB_CANCELLED_TRANSFER_LENGTH)
517 {
518 /*this code is called when stack cancel the transfer, app should release the buffer it use*/
519 if ((0U != mscHandle->dataOutFlag) && (mscHandle->configurationStruct->classCallback != NULL) &&
520 ((USB_DEVICE_MSC_WRITE_10_COMMAND == mscHandle->mscCbw->cbwcb[0]) ||
521 (USB_DEVICE_MSC_WRITE_12_COMMAND == mscHandle->mscCbw->cbwcb[0])))
522 {
523 usb_device_lba_app_struct_t lbaData;
524
525 lbaData.size = 0;
526 lbaData.buffer = message->buffer;
527 lbaData.offset = 0;
528 lbaData.lun = mscHandle->mscCbw->logicalUnitNumber;
529 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
530 it is from the second parameter of classInit */
531 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
532 if (kStatus_USB_Success != mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle,
533 kUSB_DeviceMscEventWriteResponse,
534 (void *)&lbaData))
535 {
536 return kStatus_USB_Error;
537 }
538 #else
539 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle,
540 kUSB_DeviceMscEventWriteResponse, (void *)&lbaData);
541 #endif
542 }
543 if ((mscHandle->cbwPrimeFlag == 0U) && (mscHandle->inEndpointStallFlag == 0U) &&
544 (mscHandle->outEndpointStallFlag == 0U))
545 {
546 /*prime cbw*/
547 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
548 if (kStatus_USB_Success != USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint,
549 (uint8_t *)mscHandle->mscCbw, USB_DEVICE_MSC_CBW_LENGTH))
550 {
551 return kStatus_USB_Error;
552 }
553 #else
554 (void)USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, (uint8_t *)mscHandle->mscCbw,
555 USB_DEVICE_MSC_CBW_LENGTH);
556 #endif
557 mscHandle->cbwPrimeFlag = 1U;
558 }
559 return error;
560 }
561
562 if (mscHandle->transferRemaining >= message->length)
563 {
564 mscHandle->transferRemaining -= message->length;
565 }
566
567 if ((USB_DEVICE_MSC_MODE_SELECT_10_COMMAND == mscHandle->mscCbw->cbwcb[0]) ||
568 (USB_DEVICE_MSC_MODE_SELECT_6_COMMAND == mscHandle->mscCbw->cbwcb[0]))
569 {
570 if ((mscHandle->configurationStruct->classCallback != NULL))
571 {
572 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
573 it is from the second parameter of classInit */
574 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
575 if (kStatus_USB_Success !=
576 mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle,
577 kUSB_DeviceMscEventModeSelectResponse, (void *)NULL))
578 {
579 return kStatus_USB_Error;
580 }
581 #else
582 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle,
583 kUSB_DeviceMscEventModeSelectResponse, (void *)NULL);
584 #endif
585 }
586 }
587 if (mscHandle->needOutStallFlag == 1U)
588 {
589 mscHandle->needOutStallFlag = 0U;
590 mscHandle->outEndpointStallFlag = 1U;
591 mscHandle->dataOutFlag = 0U;
592 mscHandle->cbwPrimeFlag = 0U;
593 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
594 if (kStatus_USB_Success != USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkOutEndpoint))
595 {
596 return kStatus_USB_Error;
597 }
598 #else
599 (void)USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkOutEndpoint);
600 #endif
601 return error;
602 }
603
604 if (0U != mscHandle->dataOutFlag)
605 {
606 usb_device_lba_app_struct_t lbaData;
607
608 lbaData.size = message->length;
609 lbaData.buffer = message->buffer;
610 lbaData.offset = mscHandle->currentOffset;
611 lbaData.lun = mscHandle->mscCbw->logicalUnitNumber;
612
613 if ((mscHandle->configurationStruct->classCallback != NULL))
614 {
615 if ((USB_DEVICE_MSC_WRITE_10_COMMAND == mscHandle->mscCbw->cbwcb[0]) ||
616 (USB_DEVICE_MSC_WRITE_12_COMMAND == mscHandle->mscCbw->cbwcb[0]))
617 {
618 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
619 it is from the second parameter of classInit */
620 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
621 if (kStatus_USB_Success !=
622 mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle,
623 kUSB_DeviceMscEventWriteResponse, (void *)&lbaData))
624 {
625 return kStatus_USB_Error;
626 }
627 #else
628 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle,
629 kUSB_DeviceMscEventWriteResponse, (void *)&lbaData);
630 #endif
631 }
632
633 if (0U != mscHandle->transferRemaining)
634 {
635 mscHandle->currentOffset +=
636 (message->length / mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].lengthOfEachLba);
637 error = USB_DeviceMscRecv(mscHandle);
638 }
639 }
640
641 if (0U == mscHandle->transferRemaining)
642 {
643 mscHandle->dataOutFlag = 0U;
644 {
645 mscHandle->mscCsw->dataResidue = USB_LONG_TO_LITTLE_ENDIAN(mscHandle->mscCsw->dataResidue);
646 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
647 if (kStatus_USB_Success != USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint,
648 (uint8_t *)mscHandle->mscCsw,
649 USB_DEVICE_MSC_CSW_LENGTH))
650 {
651 return kStatus_USB_Error;
652 }
653 #else
654 (void)USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, (uint8_t *)mscHandle->mscCsw,
655 USB_DEVICE_MSC_CSW_LENGTH);
656 #endif
657 mscHandle->cswPrimeFlag = 1U;
658 }
659 }
660 }
661 else if ((0U != mscHandle->cbwValidFlag) && (message->length == USB_DEVICE_MSC_CBW_LENGTH) &&
662 (USB_DEVICE_MSC_DCBWSIGNATURE == mscHandle->mscCbw->signature) &&
663 (!((0U != (mscHandle->mscCbw->logicalUnitNumber & 0xF0U)) ||
664 (0U != (mscHandle->mscCbw->cbLength & 0xE0U)))) &&
665 (mscHandle->mscCbw->logicalUnitNumber < (mscHandle->logicalUnitNumber + 1U)) &&
666 ((mscHandle->mscCbw->cbLength >= 0x01U) && (mscHandle->mscCbw->cbLength <= 0x10U)))
667 {
668 mscHandle->cbwPrimeFlag = 0U;
669 mscHandle->transferRemaining = 0U;
670
671 mscHandle->mscCsw->signature = USB_DEVICE_MSC_DCSWSIGNATURE;
672 mscHandle->mscCsw->dataResidue = 0U;
673 mscHandle->mscCsw->tag = mscHandle->mscCbw->tag;
674
675 mscHandle->cbwValidFlag = 0U;
676
677 mscHandle->mscCbw->dataTransferLength = USB_LONG_FROM_LITTLE_ENDIAN(mscHandle->mscCbw->dataTransferLength);
678
679 mscHandle->dataOutFlag = (uint8_t)(((0U == (mscHandle->mscCbw->flags & USB_DEVICE_MSC_CBW_DIRECTION_BIT)) &&
680 (0U != mscHandle->mscCbw->dataTransferLength)) ?
681 1U :
682 0U);
683
684 mscHandle->dataInFlag = (uint8_t)(((0U != (mscHandle->mscCbw->flags & USB_DEVICE_MSC_CBW_DIRECTION_BIT)) &&
685 (0U != mscHandle->mscCbw->dataTransferLength)) ?
686 1U :
687 0U);
688
689 if ((0U != mscHandle->dataInFlag) && (0U != mscHandle->inEndpointStallFlag))
690 {
691 error = kStatus_USB_Error;
692 return error;
693 }
694 error = USB_DeviceMscProcessUfiCommand(mscHandle);
695 if (error == kStatus_USB_InvalidRequest)
696 {
697 if (mscHandle->dataOutFlag == 1U)
698 {
699 if (mscHandle->outEndpointStallFlag == 0U)
700 {
701 mscHandle->needOutStallFlag = 1U;
702 }
703 mscHandle->dataOutFlag = 0U;
704 }
705 else if (mscHandle->dataInFlag == 1U)
706 {
707 if (mscHandle->inEndpointStallFlag == 0U)
708 {
709 mscHandle->needInStallFlag = 1U;
710 }
711 mscHandle->dataInFlag = 0U;
712 }
713 else
714 {
715 /*no action*/
716 }
717 mscHandle->stallStatus = (uint8_t)USB_DEVICE_MSC_STALL_IN_DATA;
718 }
719
720 if (!((0U != mscHandle->dataOutFlag) || ((0U != mscHandle->dataInFlag) || (0U != mscHandle->needInStallFlag))))
721 {
722 mscHandle->mscCsw->dataResidue = USB_LONG_TO_LITTLE_ENDIAN(mscHandle->mscCsw->dataResidue);
723 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
724 if (kStatus_USB_Success != USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint,
725 (uint8_t *)mscHandle->mscCsw, USB_DEVICE_MSC_CSW_LENGTH))
726 {
727 return kStatus_USB_Error;
728 }
729 #else
730 (void)USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, (uint8_t *)mscHandle->mscCsw,
731 USB_DEVICE_MSC_CSW_LENGTH);
732 #endif
733 mscHandle->cswPrimeFlag = 1U;
734 }
735 }
736 else
737 {
738 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
739 if ((kStatus_USB_Success != USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkOutEndpoint)) ||
740 (kStatus_USB_Success != USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkInEndpoint)))
741 {
742 return kStatus_USB_Error;
743 }
744 #else
745 (void)USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkOutEndpoint);
746 (void)USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkInEndpoint);
747 #endif
748 mscHandle->cbwPrimeFlag = 0U;
749 mscHandle->cbwValidFlag = 0U;
750 mscHandle->outEndpointStallFlag = 1U;
751 mscHandle->inEndpointStallFlag = 1U;
752 mscHandle->stallStatus = (uint8_t)USB_DEVICE_MSC_STALL_IN_CBW;
753 mscHandle->performResetRecover = 1;
754 }
755 return error;
756 }
757
758 /*!
759 * @brief Initialize the endpoints of the msc class.
760 *
761 * This callback function is used to initialize the endpoints of the msc class.
762 *
763 * @param mscHandle The device msc class handle. It equals the value returned from
764 * usb_device_class_config_struct_t::classHandle.
765 *
766 * @return A USB error code or kStatus_USB_Success.
767 */
USB_DeviceMscEndpointsInit(usb_device_msc_struct_t * mscHandle)768 usb_status_t USB_DeviceMscEndpointsInit(usb_device_msc_struct_t *mscHandle)
769 {
770 usb_device_interface_list_t *interfaceList;
771 usb_device_interface_struct_t *interface = (usb_device_interface_struct_t *)NULL;
772 usb_status_t error = kStatus_USB_Error;
773 uint32_t count;
774 uint32_t index;
775
776 /* Check the configuration is valid or not. */
777 if ((0U == mscHandle->configuration) ||
778 (mscHandle->configuration > mscHandle->configurationStruct->classInfomation->configurations))
779 {
780 return error;
781 }
782
783 /* Get the interface list of the new configuration. */
784 /* Check the interface list is valid or not. */
785 if (NULL == mscHandle->configurationStruct->classInfomation->interfaceList)
786 {
787 return error;
788 }
789 interfaceList = &mscHandle->configurationStruct->classInfomation->interfaceList[mscHandle->configuration - 1U];
790
791 /* Find interface by using the alternate setting of the interface. */
792 for (count = 0; count < interfaceList->count; count++)
793 {
794 if (USB_DEVICE_CONFIG_MSC_CLASS_CODE == interfaceList->interfaces[count].classCode)
795 {
796 for (index = 0; index < interfaceList->interfaces[count].count; index++)
797 {
798 if (interfaceList->interfaces[count].interface[index].alternateSetting == mscHandle->alternate)
799 {
800 interface = &interfaceList->interfaces[count].interface[index];
801 break;
802 }
803 }
804 mscHandle->interfaceNumber = interfaceList->interfaces[count].interfaceNumber;
805 break;
806 }
807 }
808 if (NULL == interface)
809 {
810 /* Return error if the interface is not found. */
811 return error;
812 }
813
814 /* Keep new interface handle. */
815 mscHandle->interfaceHandle = interface;
816 /* Initialize the endpoints of the new interface. */
817 for (count = 0; count < interface->endpointList.count; count++)
818 {
819 usb_device_endpoint_init_struct_t epInitStruct;
820 usb_device_endpoint_callback_struct_t epCallback;
821 epInitStruct.zlt = 0U;
822 epInitStruct.interval = interface->endpointList.endpoint[count].interval;
823 epInitStruct.endpointAddress = interface->endpointList.endpoint[count].endpointAddress;
824 epInitStruct.maxPacketSize = interface->endpointList.endpoint[count].maxPacketSize;
825 epInitStruct.transferType = interface->endpointList.endpoint[count].transferType;
826
827 if (USB_IN == ((epInitStruct.endpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) >>
828 USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT))
829 {
830 mscHandle->bulkInEndpoint = epInitStruct.endpointAddress;
831 epCallback.callbackFn = USB_DeviceMscBulkIn;
832 }
833 else
834 {
835 mscHandle->bulkOutEndpoint = epInitStruct.endpointAddress;
836 epCallback.callbackFn = USB_DeviceMscBulkOut;
837 }
838 epCallback.callbackParam = mscHandle;
839
840 error = USB_DeviceInitEndpoint(mscHandle->handle, &epInitStruct, &epCallback);
841 }
842
843 mscHandle->dataOutFlag = 0U;
844 mscHandle->dataInFlag = 0U;
845 mscHandle->outEndpointStallFlag = 0U;
846 mscHandle->inEndpointStallFlag = 0U;
847 mscHandle->needOutStallFlag = 0U;
848 mscHandle->needInStallFlag = 0U;
849 mscHandle->cbwValidFlag = 1U;
850 mscHandle->transferRemaining = 0U;
851 mscHandle->performResetRecover = 0U;
852 mscHandle->performResetDoneFlag = 0U;
853 mscHandle->stallStatus = 0U;
854 mscHandle->inEndpointCswCancelFlag = 0U;
855 return error;
856 }
857
858 /*!
859 * @brief De-initialize the endpoints of the msc class.
860 *
861 * This callback function is used to de-initialize the endpoints of the msc class.
862 *
863 * @param mscHandle The device msc class handle. It equals the value returned from
864 * usb_device_class_config_struct_t::classHandle.
865 *
866 * @return A USB error code or kStatus_USB_Success.
867 */
USB_DeviceMscEndpointsDeinit(usb_device_msc_struct_t * mscHandle)868 usb_status_t USB_DeviceMscEndpointsDeinit(usb_device_msc_struct_t *mscHandle)
869 {
870 usb_status_t status = kStatus_USB_Error;
871 uint32_t count;
872
873 if (NULL == mscHandle->interfaceHandle)
874 {
875 return status;
876 }
877 /* De-initialize all endpoints of the interface */
878 for (count = 0; count < mscHandle->interfaceHandle->endpointList.count; count++)
879 {
880 status = USB_DeviceDeinitEndpoint(mscHandle->handle,
881 mscHandle->interfaceHandle->endpointList.endpoint[count].endpointAddress);
882 }
883 mscHandle->interfaceHandle = NULL;
884 return status;
885 }
886
887 /*!
888 * @brief Initialize the msc class.
889 *
890 * This function is used to initialize the msc class.
891 *
892 * @param controllerId The controller id of the USB IP. Please refer to the enumeration usb_controller_index_t.
893 * @param config The class configuration information.
894 * @param handle It is out parameter, is used to return pointer of the msc class handle to the caller.
895 *
896 * @return A USB error code or kStatus_USB_Success.
897 */
USB_DeviceMscInit(uint8_t controllerId,usb_device_class_config_struct_t * config,class_handle_t * handle)898 usb_status_t USB_DeviceMscInit(uint8_t controllerId, usb_device_class_config_struct_t *config, class_handle_t *handle)
899 {
900 usb_device_msc_struct_t *mscHandle;
901 usb_status_t error;
902 uint32_t implementingDiskDrive = USB_DEVICE_CONFIG_MSC_IMPLEMENTING_DISK_DRIVE;
903 usb_device_msc_ufi_struct_t *ufi = NULL;
904
905 /* Allocate a msc class handle. */
906 error = USB_DeviceMscAllocateHandle(&mscHandle);
907
908 if (kStatus_USB_Success != error)
909 {
910 return error;
911 }
912
913 /* Get the device handle according to the controller id. */
914 error = USB_DeviceClassGetDeviceHandle(controllerId, &mscHandle->handle);
915
916 if (kStatus_USB_Success != error)
917 {
918 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
919 if (kStatus_USB_Success != USB_DeviceMscFreeHandle(mscHandle))
920 {
921 return kStatus_USB_Error;
922 }
923 #else
924 (void)USB_DeviceMscFreeHandle(mscHandle);
925 #endif
926 return error;
927 }
928 if (NULL == mscHandle->handle)
929 {
930 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
931 if (kStatus_USB_Success != USB_DeviceMscFreeHandle(mscHandle))
932 {
933 return kStatus_USB_Error;
934 }
935 #else
936 (void)USB_DeviceMscFreeHandle(mscHandle);
937 #endif
938 return kStatus_USB_InvalidHandle;
939 }
940 /* Save the configuration of the class. */
941 mscHandle->configurationStruct = config;
942 /* Clear the configuration value. */
943 mscHandle->configuration = 0U;
944 mscHandle->alternate = 0xffU;
945
946 ufi = &mscHandle->mscUfi;
947
948 mscHandle->implementingDiskDrive = implementingDiskDrive;
949
950 ufi->requestSense->validErrorCode = USB_DEVICE_MSC_UFI_REQ_SENSE_VALID_ERROR_CODE;
951 ufi->requestSense->additionalSenseLength = USB_DEVICE_MSC_UFI_REQ_SENSE_ADDITIONAL_SENSE_LEN;
952 ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_NO_SENSE;
953 ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_NO_SENSE;
954 ufi->requestSense->additionalSenseQualifer = USB_DEVICE_MSC_UFI_NO_SENSE;
955
956 mscHandle->cbwPrimeFlag = 0U;
957 mscHandle->cswPrimeFlag = 0U;
958
959 *handle = (class_handle_t)mscHandle;
960 return error;
961 }
962
963 /*!
964 * @brief De-initialize the device msc class.
965 *
966 * The function de-initializes the device msc class.
967 *
968 * @param handle The msc class handle got from usb_device_class_config_struct_t::classHandle.
969 *
970 * @return A USB error code or kStatus_USB_Success.
971 */
USB_DeviceMscDeinit(class_handle_t handle)972 usb_status_t USB_DeviceMscDeinit(class_handle_t handle)
973 {
974 usb_device_msc_struct_t *mscHandle;
975 usb_status_t status = kStatus_USB_Error;
976
977 mscHandle = (usb_device_msc_struct_t *)handle;
978
979 if (NULL == mscHandle)
980 {
981 return kStatus_USB_InvalidHandle;
982 }
983 status = USB_DeviceMscEndpointsDeinit(mscHandle);
984 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
985 if (kStatus_USB_Success != USB_DeviceMscFreeHandle(mscHandle))
986 {
987 return kStatus_USB_Error;
988 }
989 #else
990 (void)USB_DeviceMscFreeHandle(mscHandle);
991 #endif
992 return status;
993 }
994
995 /*!
996 * @brief Handle the event passed to the msc class.
997 *
998 * This function handles the event passed to the msc class.
999 *
1000 * @param handle The msc class handle, got from the usb_device_class_config_struct_t::classHandle.
1001 * @param event The event codes. Please refer to the enumeration usb_device_class_event_t.
1002 * @param param The param type is determined by the event code.
1003 *
1004 * @return A USB error code or kStatus_USB_Success.
1005 * @retval kStatus_USB_Success Free device handle successfully.
1006 * @retval kStatus_USB_InvalidParameter The device handle not be found.
1007 * @retval kStatus_USB_InvalidRequest The request is invalid, and the control pipe will be stalled by the caller.
1008 */
USB_DeviceMscEvent(void * handle,uint32_t event,void * param)1009 usb_status_t USB_DeviceMscEvent(void *handle, uint32_t event, void *param)
1010 {
1011 usb_status_t error = kStatus_USB_Error;
1012 usb_device_msc_ufi_struct_t *ufi = NULL;
1013 usb_device_msc_struct_t *mscHandle;
1014 usb_device_lba_information_struct_t diskInformation;
1015 uint16_t interfaceAlternate;
1016 uint8_t *temp8;
1017 uint8_t alternate;
1018 uint8_t index;
1019 usb_device_class_event_t eventCode = (usb_device_class_event_t)event;
1020 if ((NULL == param) || (NULL == handle))
1021 {
1022 return kStatus_USB_InvalidHandle;
1023 }
1024
1025 /* Get the msc class handle. */
1026 mscHandle = (usb_device_msc_struct_t *)handle;
1027 switch (eventCode)
1028 {
1029 case kUSB_DeviceClassEventDeviceReset:
1030 /* Bus reset, clear the configuration. */
1031 mscHandle->configuration = 0U;
1032 /* Get device information. classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
1033 it is from the second parameter of classInit */
1034 error = mscHandle->configurationStruct->classCallback(
1035 (class_handle_t)mscHandle, kUSB_DeviceMscEventGetLbaInformation, (void *)&diskInformation);
1036 if (0U >= diskInformation.logicalUnitNumberSupported)
1037 {
1038 diskInformation.logicalUnitNumberSupported = 0U;
1039 }
1040 else
1041 {
1042 mscHandle->logicalUnitNumber = (uint8_t)diskInformation.logicalUnitNumberSupported - 1U;
1043 }
1044 /*add for misra2.2*/
1045 if (0U == diskInformation.logicalUnitNumberSupported)
1046 {
1047 error = kStatus_USB_InvalidParameter;
1048 break;
1049 }
1050 /*initialize the basic device information*/
1051 for (index = 0U; (index <= mscHandle->logicalUnitNumber) && (index < USB_DEVICE_MSC_MAX_LUN); ++index)
1052 {
1053 if (((0U == diskInformation.logicalUnitInformations[index].lengthOfEachLba) ||
1054 (0U == diskInformation.logicalUnitInformations[index].totalLbaNumberSupports)))
1055 {
1056 error = kStatus_USB_Error;
1057 }
1058 else
1059 {
1060 mscHandle->luInformations[index] = diskInformation.logicalUnitInformations[index];
1061 }
1062 }
1063 ufi = &mscHandle->mscUfi;
1064 ufi->requestSense->validErrorCode = USB_DEVICE_MSC_UFI_REQ_SENSE_VALID_ERROR_CODE;
1065 ufi->requestSense->additionalSenseLength = USB_DEVICE_MSC_UFI_REQ_SENSE_ADDITIONAL_SENSE_LEN;
1066 ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_NO_SENSE;
1067 ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_NO_SENSE;
1068 ufi->requestSense->additionalSenseQualifer = USB_DEVICE_MSC_UFI_NO_SENSE;
1069
1070 mscHandle->cbwPrimeFlag = 0U;
1071 mscHandle->cswPrimeFlag = 0U;
1072 break;
1073 case kUSB_DeviceClassEventSetConfiguration:
1074 /* Get the new configuration. */
1075 temp8 = ((uint8_t *)param);
1076 if (NULL == mscHandle->configurationStruct)
1077 {
1078 break;
1079 }
1080 if (*temp8 == mscHandle->configuration)
1081 {
1082 error = kStatus_USB_Success;
1083 break;
1084 }
1085
1086 if (0U != mscHandle->configuration)
1087 {
1088 /* De-initialize the endpoints when current configuration is none zero. */
1089 error = USB_DeviceMscEndpointsDeinit(mscHandle);
1090 }
1091 /* Save new configuration. */
1092 mscHandle->configuration = *temp8;
1093 /* Clear the alternate setting value. */
1094 mscHandle->alternate = 0;
1095 /* Initialize the endpoints of the new current configuration by using the alternate setting 0. */
1096 error = USB_DeviceMscEndpointsInit(mscHandle);
1097 if (kStatus_USB_Success == error)
1098 {
1099 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1100 if (kStatus_USB_Success != USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint,
1101 (uint8_t *)mscHandle->mscCbw,
1102 USB_DEVICE_MSC_CBW_LENGTH))
1103 {
1104 return kStatus_USB_Error;
1105 }
1106 #else
1107 (void)USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, (uint8_t *)mscHandle->mscCbw,
1108 USB_DEVICE_MSC_CBW_LENGTH);
1109 #endif
1110 mscHandle->cbwPrimeFlag = 1U;
1111 }
1112 break;
1113 case kUSB_DeviceClassEventSetInterface:
1114
1115 if (NULL == mscHandle->configurationStruct)
1116 {
1117 break;
1118 }
1119 /* Get the new alternate setting of the interface */
1120 interfaceAlternate = *((uint16_t *)param);
1121 /* Get the alternate setting value */
1122 alternate = (uint8_t)(interfaceAlternate & 0xFFU);
1123
1124 /* Whether the interface belongs to the class. */
1125 if (mscHandle->interfaceNumber != ((uint8_t)(interfaceAlternate >> 8)))
1126 {
1127 break;
1128 }
1129 /* Only handle new alternate setting. */
1130 if (alternate == mscHandle->alternate)
1131 {
1132 error = kStatus_USB_Success;
1133 break;
1134 }
1135 error = USB_DeviceMscEndpointsDeinit(mscHandle);
1136 /* Initialize new endpoints */
1137 error = USB_DeviceMscEndpointsInit(mscHandle);
1138 if (kStatus_USB_Success == error)
1139 {
1140 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1141 if (kStatus_USB_Success != USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint,
1142 (uint8_t *)mscHandle->mscCbw,
1143 USB_DEVICE_MSC_CBW_LENGTH))
1144 {
1145 return kStatus_USB_Error;
1146 }
1147 #else
1148 (void)USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, (uint8_t *)mscHandle->mscCbw,
1149 USB_DEVICE_MSC_CBW_LENGTH);
1150 #endif
1151 mscHandle->cbwPrimeFlag = 1U;
1152 }
1153 mscHandle->alternate = alternate;
1154
1155 break;
1156 case kUSB_DeviceClassEventSetEndpointHalt:
1157 if ((NULL == mscHandle->configurationStruct) || (NULL == mscHandle->interfaceHandle))
1158 {
1159 break;
1160 }
1161 /* Get the endpoint address */
1162 temp8 = ((uint8_t *)param);
1163
1164 if ((mscHandle->inEndpointStallFlag == 0U) && (*temp8 == mscHandle->bulkInEndpoint))
1165 {
1166 /* Only stall the endpoint belongs to the class */
1167 mscHandle->inEndpointStallFlag = 1U;
1168 mscHandle->cswPrimeFlag = 0U;
1169 error = USB_DeviceStallEndpoint(mscHandle->handle, *temp8);
1170 }
1171 if ((mscHandle->outEndpointStallFlag == 0U) && (*temp8 == mscHandle->bulkOutEndpoint))
1172 {
1173 mscHandle->outEndpointStallFlag = 1U;
1174 mscHandle->cbwPrimeFlag = 0U;
1175 error = USB_DeviceStallEndpoint(mscHandle->handle, *temp8);
1176 }
1177
1178 break;
1179 case kUSB_DeviceClassEventClearEndpointHalt:
1180 if ((NULL == mscHandle->configurationStruct) || (NULL == mscHandle->interfaceHandle) ||
1181 (mscHandle->performResetRecover == 1U))
1182 {
1183 break;
1184 }
1185 /* Get the endpoint address */
1186 temp8 = ((uint8_t *)param);
1187 /* Only un-stall the endpoint belongs to the class , If the endpoint is in stall status ,then
1188 * un-stall it*/
1189 if ((mscHandle->inEndpointStallFlag == 1U) && (*temp8 == mscHandle->bulkInEndpoint))
1190 {
1191 mscHandle->inEndpointStallFlag = 0;
1192 mscHandle->cswPrimeFlag = 0;
1193 error = USB_DeviceUnstallEndpoint(mscHandle->handle, *temp8);
1194 }
1195 if ((mscHandle->outEndpointStallFlag == 1U) && (*temp8 == mscHandle->bulkOutEndpoint))
1196 {
1197 mscHandle->outEndpointStallFlag = 0U;
1198 mscHandle->cbwPrimeFlag = 0U;
1199 error = USB_DeviceUnstallEndpoint(mscHandle->handle, *temp8);
1200 }
1201 if (((mscHandle->stallStatus == (uint8_t)USB_DEVICE_MSC_STALL_IN_CSW) ||
1202 (mscHandle->stallStatus == (uint8_t)USB_DEVICE_MSC_STALL_IN_DATA)) &&
1203 (mscHandle->performResetDoneFlag != 1U))
1204 {
1205 if (mscHandle->cswPrimeFlag == 1U)
1206 {
1207 /*cancel the transfer , after the cancel to be complete, and then prime csw in bulk in callback, */
1208 mscHandle->inEndpointCswCancelFlag = 1U;
1209 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1210 if (kStatus_USB_Success != USB_DeviceCancel(mscHandle->handle, mscHandle->bulkInEndpoint))
1211 {
1212 return kStatus_USB_Error;
1213 }
1214 #else
1215 (void)USB_DeviceCancel(mscHandle->handle, mscHandle->bulkInEndpoint);
1216 #endif
1217 }
1218 else
1219 {
1220 /*send csw*/
1221 mscHandle->mscCsw->dataResidue = USB_LONG_TO_LITTLE_ENDIAN(mscHandle->mscCsw->dataResidue);
1222 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1223 if (kStatus_USB_Success != USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint,
1224 (uint8_t *)mscHandle->mscCsw,
1225 USB_DEVICE_MSC_CSW_LENGTH))
1226 {
1227 return kStatus_USB_Error;
1228 }
1229 #else
1230 (void)USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint,
1231 (uint8_t *)mscHandle->mscCsw, USB_DEVICE_MSC_CSW_LENGTH);
1232 #endif
1233 mscHandle->cswPrimeFlag = 1U;
1234 }
1235 mscHandle->stallStatus = 0U;
1236 }
1237 if ((mscHandle->performResetDoneFlag == 1U) && (mscHandle->inEndpointStallFlag == 0U) &&
1238 (mscHandle->outEndpointStallFlag == 0U))
1239 {
1240 mscHandle->performResetDoneFlag = 0U;
1241 if (mscHandle->cbwPrimeFlag == 1U)
1242 {
1243 mscHandle->cbwPrimeFlag = 0U;
1244 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1245 if (kStatus_USB_Success != USB_DeviceCancel(mscHandle->handle, mscHandle->bulkOutEndpoint))
1246 {
1247 return kStatus_USB_Error;
1248 }
1249 #else
1250 (void)USB_DeviceCancel(mscHandle->handle, mscHandle->bulkOutEndpoint);
1251 #endif
1252 }
1253 else
1254 {
1255 /*prime cbw for new transfer*/
1256 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1257 if (kStatus_USB_Success != USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint,
1258 (uint8_t *)mscHandle->mscCbw,
1259 USB_DEVICE_MSC_CBW_LENGTH))
1260 {
1261 return kStatus_USB_Error;
1262 }
1263 #else
1264 (void)USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint,
1265 (uint8_t *)mscHandle->mscCbw, USB_DEVICE_MSC_CBW_LENGTH);
1266 #endif
1267 mscHandle->cbwPrimeFlag = 1U;
1268 }
1269 mscHandle->stallStatus = 0;
1270 }
1271 break;
1272 case kUSB_DeviceClassEventClassRequest:
1273 {
1274 /* Handle the msc class specific request. */
1275 usb_device_control_request_struct_t *control_request = (usb_device_control_request_struct_t *)param;
1276
1277 if ((control_request->setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) !=
1278 USB_REQUEST_TYPE_RECIPIENT_INTERFACE)
1279 {
1280 break;
1281 }
1282
1283 if ((control_request->setup->wIndex & 0xFFU) != mscHandle->interfaceNumber)
1284 {
1285 break;
1286 }
1287
1288 error = kStatus_USB_InvalidRequest;
1289 switch (control_request->setup->bRequest)
1290 {
1291 case USB_DEVICE_MSC_GET_MAX_LUN:
1292 /*Get Max LUN */
1293 if ((0U == control_request->setup->wValue) && (control_request->setup->wLength == 0x0001U) &&
1294 ((control_request->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) ==
1295 USB_REQUEST_TYPE_DIR_IN))
1296 {
1297 control_request->buffer = &mscHandle->logicalUnitNumber;
1298 control_request->length = sizeof(mscHandle->logicalUnitNumber);
1299 error = kStatus_USB_Success;
1300 }
1301
1302 break;
1303 case USB_DEVICE_MSC_BULK_ONLY_MASS_STORAGE_RESET:
1304 /*Bulk-Only Mass Storage Reset (class-specific request)*/
1305 if ((0U == control_request->setup->wValue) && (0U == control_request->setup->wLength) &&
1306 ((control_request->setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) ==
1307 USB_REQUEST_TYPE_DIR_OUT))
1308 {
1309 /*Need to go to stall process, because reset recovery contains reset command and clare
1310 * feature command*/
1311 mscHandle->outEndpointStallFlag = 1U;
1312 mscHandle->inEndpointStallFlag = 1U;
1313
1314 mscHandle->cbwValidFlag = 1U;
1315 mscHandle->performResetRecover = 0U;
1316 mscHandle->performResetDoneFlag = 1U;
1317 error = kStatus_USB_Success;
1318 }
1319
1320 break;
1321 default:
1322 /* no action, return kStatus_USB_InvalidRequest */
1323 break;
1324 }
1325 }
1326 break;
1327 default:
1328 /*no action*/
1329 break;
1330 }
1331
1332 return error;
1333 }
1334
1335 /*!
1336 * @brief Send data through a specified endpoint.
1337 *
1338 * The function is used to send data through a specified endpoint.
1339 * The function calls USB_DeviceSendRequest internally.
1340 *
1341 * @param handle The msc class handle got from usb_device_class_config_struct_t::classHandle.
1342 *
1343 * @return A USB error code or kStatus_USB_Success.
1344 *
1345 * @note The return value just means if the sending request is successful or not; the transfer done is notified by
1346 * USB_DeviceMscBulkIn.
1347 * Currently, only one transfer request can be supported for one specific endpoint.
1348 * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
1349 * should implement a queue in the application level.
1350 * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
1351 * callback).
1352 */
USB_DeviceMscSend(usb_device_msc_struct_t * mscHandle)1353 usb_status_t USB_DeviceMscSend(usb_device_msc_struct_t *mscHandle)
1354 {
1355 usb_status_t status = kStatus_USB_Success;
1356 usb_device_lba_app_struct_t lba;
1357
1358 lba.offset = mscHandle->currentOffset;
1359 /*bulkInBufferSize is the application buffer size, USB_DEVICE_MSC_MAX_SEND_TRANSFER_LENGTH is the max transfer
1360 length by the hardware,
1361 lba.size is the data pending for transfer ,select the minimum size to transfer ,the remaining will be transfer
1362 next time*/
1363 lba.size = (mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].bulkInBufferSize >
1364 USB_DEVICE_MSC_MAX_SEND_TRANSFER_LENGTH) ?
1365 USB_DEVICE_MSC_MAX_SEND_TRANSFER_LENGTH :
1366 mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].bulkInBufferSize;
1367 lba.size =
1368 (mscHandle->transferRemaining > lba.size) ? lba.size : mscHandle->transferRemaining; /* which one is smaller */
1369
1370 lba.buffer = NULL;
1371 lba.lun = mscHandle->mscCbw->logicalUnitNumber;
1372 /*classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
1373 it is from the second parameter of classInit*/
1374 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1375 if (kStatus_USB_Success !=
1376 mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventReadRequest, &lba))
1377 {
1378 return kStatus_USB_Error;
1379 }
1380 #else
1381 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventReadRequest,
1382 &lba);
1383 #endif
1384
1385 if (mscHandle->currentOffset <
1386 mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].totalLbaNumberSupports)
1387 {
1388 status = USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, lba.buffer, lba.size);
1389 }
1390 else
1391 {
1392 mscHandle->needInStallFlag = 0U;
1393 mscHandle->inEndpointStallFlag = 1U;
1394 mscHandle->dataInFlag = 0U;
1395 mscHandle->stallStatus = (uint8_t)USB_DEVICE_MSC_STALL_IN_DATA;
1396 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1397 if (kStatus_USB_Success != USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkInEndpoint))
1398 {
1399 return kStatus_USB_Error;
1400 }
1401 #else
1402 (void)USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkInEndpoint);
1403 #endif
1404 }
1405 return status;
1406 }
1407
1408 /*!
1409 * @brief Receive data through a specified endpoint.
1410 *
1411 * The function is used to receive data through a specified endpoint.
1412 * The function calls USB_DeviceRecvRequest internally.
1413 *
1414 * @param handle The msc class handle got from usb_device_class_config_struct_t::classHandle.
1415 *
1416 * @return A USB error code or kStatus_USB_Success.
1417 *
1418 * @note The return value just means if the receiving request is successful or not; the transfer done is notified by
1419 * USB_DeviceMscBulkOut.
1420 * Currently, only one transfer request can be supported for one specific endpoint.
1421 * If there is a specific requirement to support multiple transfer requests for one specific endpoint, the application
1422 * should implement a queue in the application level.
1423 * The subsequent transfer could begin only when the previous transfer is done (get notification through the endpoint
1424 * callback).
1425 */
USB_DeviceMscRecv(usb_device_msc_struct_t * mscHandle)1426 usb_status_t USB_DeviceMscRecv(usb_device_msc_struct_t *mscHandle)
1427 {
1428 usb_status_t status = kStatus_USB_Success;
1429 usb_device_lba_app_struct_t lba;
1430
1431 lba.offset = mscHandle->currentOffset;
1432 /*bulkOutBufferSize is the application buffer size, USB_DEVICE_MSC_MAX_RECV_TRANSFER_LENGTH is the max transfer
1433 length by the hardware,
1434 lba.size is the data pending for transfer ,select the minimum size to transfer ,the remaining will be transfer
1435 next time*/
1436 lba.size = (mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].bulkOutBufferSize >
1437 USB_DEVICE_MSC_MAX_RECV_TRANSFER_LENGTH) ?
1438 USB_DEVICE_MSC_MAX_RECV_TRANSFER_LENGTH :
1439 mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].bulkOutBufferSize;
1440 lba.size =
1441 (mscHandle->transferRemaining > lba.size) ? lba.size : mscHandle->transferRemaining; /* whichever is smaller */
1442
1443 lba.buffer = NULL;
1444 lba.lun = mscHandle->mscCbw->logicalUnitNumber;
1445 /*classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
1446 it is from the second parameter of classInit*/
1447 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1448 if (kStatus_USB_Success !=
1449 mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventWriteRequest, &lba))
1450 {
1451 return kStatus_USB_Error;
1452 }
1453 #else
1454 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventWriteRequest,
1455 &lba);
1456 #endif
1457
1458 if (mscHandle->currentOffset <
1459 mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].totalLbaNumberSupports)
1460 {
1461 status = USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, lba.buffer, lba.size);
1462 }
1463 else
1464 {
1465 mscHandle->needOutStallFlag = 0U;
1466 mscHandle->outEndpointStallFlag = 1U;
1467 mscHandle->dataOutFlag = 0U;
1468 mscHandle->stallStatus = (uint8_t)USB_DEVICE_MSC_STALL_IN_DATA;
1469 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1470 if (kStatus_USB_Success != USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkOutEndpoint))
1471 {
1472 return kStatus_USB_Error;
1473 }
1474 #else
1475 (void)USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkOutEndpoint);
1476 #endif
1477 }
1478 return status;
1479 }
1480
1481 /*!
1482 * @brief Recv Send data through a specified endpoint.
1483 *
1484 * The function is used when ufi process read/write command .
1485 * The function calls USB_DeviceMscRecv or usb_device_send_recv as the direction internally.
1486 *
1487 * @param handle The msc class handle got from usb_device_class_config_struct_t::classHandle.
1488 * @param direction Data direction: 0 = Data-Out from host to the device, 1 = Data-In from the device to the host.
1489 * @param buffer The memory address to hold the data need to be sent.
1490 * @return A USB error code or kStatus_USB_Success.
1491 *
1492 * @note The return value just means if the sending or receiving request is successful or not.
1493 */
USB_DeviceMscLbaTransfer(usb_device_msc_struct_t * mscHandle,uint8_t direction,usb_lba_transfer_information_struct_t * lba_info_ptr)1494 usb_status_t USB_DeviceMscLbaTransfer(usb_device_msc_struct_t *mscHandle,
1495 uint8_t direction,
1496 usb_lba_transfer_information_struct_t *lba_info_ptr)
1497 {
1498 usb_status_t error = kStatus_USB_Success;
1499
1500 mscHandle->transferRemaining =
1501 lba_info_ptr->transferNumber * mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].lengthOfEachLba;
1502 mscHandle->currentOffset = lba_info_ptr->startingLogicalBlockAddress;
1503
1504 if (direction == USB_IN)
1505 {
1506 error = USB_DeviceMscSend(mscHandle);
1507 }
1508 else
1509 {
1510 error = USB_DeviceMscRecv(mscHandle);
1511 }
1512 return error;
1513 }
1514 #endif
1515