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 USB_DEVICE_CONFIG_MSC
16 #include "usb_device_msc.h"
17 #include "usb_device_msc_ufi.h"
18
19 /*******************************************************************************
20 * Definitions
21 ******************************************************************************/
22
23 /*******************************************************************************
24 * Prototypes
25 ******************************************************************************/
26 /*******************************************************************************
27 * Variables
28 ******************************************************************************/
29 /*******************************************************************************
30 * Code
31 ******************************************************************************/
32
33 /*!
34 * @brief Thirteen possible case check.
35 *
36 * This function handle the thirteen possible cases of host expectations and device intent in the absence of
37 *overriding error conditions.
38 *
39 * @param handle The device msc class handle.
40 *
41 *@return A USB error code or kStatus_USB_Success. more information about return value ,refer to
42 *USB_DeviceMscLbaTransfer and USB_DeviceRecvRequest
43 */
44
USB_DeviceMscUfiThirteenCasesCheck(struct _usb_device_msc_struct * mscHandle)45 usb_status_t USB_DeviceMscUfiThirteenCasesCheck(struct _usb_device_msc_struct *mscHandle)
46 {
47 usb_status_t status = kStatus_USB_Success;
48 usb_device_msc_ufi_struct_t *ufi;
49 usb_device_msc_thirteen_case_struct_t *mscCheckEvent;
50
51 mscCheckEvent = (usb_device_msc_thirteen_case_struct_t *)&mscHandle->mscUfi.thirteenCase;
52 ufi = &mscHandle->mscUfi;
53 /* The following code describe the thirteen possible cases of host
54 expectations and device intent in absence of overriding error conditions ,refer to bulk-only spec chapter 6.7
55 The Thirteen Cases*/
56 if (mscCheckEvent->hostExpectedDataLength == 0U)
57 {
58 /*Host expects no data transfers*/
59 mscHandle->mscCsw->dataResidue = 0;
60 if (mscCheckEvent->deviceExpectedDataLength == 0U)
61 { /*case 1, Device intends to transfer no data*/
62 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED;
63 }
64 else
65 { /*case 2 ,Device intends to send data to the host; */
66 /*case 3, Device intends to receive data from the host*/
67 /*set csw status to 02h*/
68 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_PHASE_ERROR;
69 }
70 }
71 else if (0U != mscCheckEvent->hostExpectedDirection)
72 {
73 /*Host expects to receive data from the device*/
74 if (mscCheckEvent->deviceExpectedDataLength == 0U)
75 {
76 /*case 4, Device intends to transfer no data*/
77 mscHandle->mscCsw->dataResidue =
78 mscCheckEvent->hostExpectedDataLength - mscCheckEvent->deviceExpectedDataLength;
79 status = USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, mscCheckEvent->buffer,
80 mscCheckEvent->deviceExpectedDataLength);
81
82 if (kStatus_USB_Success == status)
83 {
84 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED;
85 }
86 else
87 {
88 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED;
89 ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_MEDIUM_ERROR;
90 ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_UNRECOVERED_READ_ERROR;
91 }
92 status = kStatus_USB_InvalidRequest;
93 }
94 else if (0U != mscCheckEvent->deviceExpectedDirection)
95 {
96 if (mscCheckEvent->hostExpectedDataLength > mscCheckEvent->deviceExpectedDataLength)
97 {
98 /*case 5, device intends to send less data than the host indicated*/
99 mscHandle->mscCsw->dataResidue =
100 mscCheckEvent->hostExpectedDataLength - mscCheckEvent->deviceExpectedDataLength;
101
102 if (ufi->thirteenCase.lbaSendRecvSelect == 1U)
103 {
104 status = USB_DeviceMscLbaTransfer(mscHandle, USB_IN, &mscCheckEvent->lbaInformation);
105 }
106 else
107 {
108 status = USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, mscCheckEvent->buffer,
109 mscCheckEvent->deviceExpectedDataLength);
110 }
111
112 if (kStatus_USB_Success == status)
113 {
114 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED;
115 }
116 else
117 {
118 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED;
119 ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_MEDIUM_ERROR;
120 ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_UNRECOVERED_READ_ERROR;
121 }
122 status = kStatus_USB_InvalidRequest;
123 }
124 else if (mscCheckEvent->hostExpectedDataLength == mscCheckEvent->deviceExpectedDataLength)
125 { /*case 6*,device intends to send dCBWDataTransferLength excepted by the host*/
126 mscHandle->mscCsw->dataResidue = 0;
127 if (ufi->thirteenCase.lbaSendRecvSelect == 1U)
128 {
129 status = USB_DeviceMscLbaTransfer(mscHandle, USB_IN, &mscCheckEvent->lbaInformation);
130 }
131 else
132 {
133 status = USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, mscCheckEvent->buffer,
134 mscCheckEvent->deviceExpectedDataLength);
135 }
136
137 if (kStatus_USB_Success == status)
138 {
139 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED;
140 }
141 else
142 {
143 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED;
144 ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_MEDIUM_ERROR;
145 ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_UNRECOVERED_READ_ERROR;
146 }
147 }
148 else
149 { /*case 7, device intends to send more data than the host indicated*/
150 mscHandle->mscCsw->dataResidue = 0U;
151
152 if (ufi->thirteenCase.lbaSendRecvSelect == 1U)
153 {
154 mscCheckEvent->lbaInformation.transferNumber =
155 mscCheckEvent->hostExpectedDataLength /
156 mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].lengthOfEachLba;
157 mscHandle->mscCsw->dataResidue =
158 mscCheckEvent->hostExpectedDataLength -
159 mscCheckEvent->lbaInformation.transferNumber *
160 mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].lengthOfEachLba;
161 status = USB_DeviceMscLbaTransfer(mscHandle, USB_IN, &mscCheckEvent->lbaInformation);
162 }
163 else
164 {
165 status = USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, mscCheckEvent->buffer,
166 mscCheckEvent->hostExpectedDataLength);
167 }
168
169 if (kStatus_USB_Success == status)
170 {
171 if (ufi->thirteenCase.lbaSendRecvSelect == 1U)
172 {
173 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_PHASE_ERROR;
174 }
175 else
176 {
177 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED;
178 }
179 }
180 else
181 {
182 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED;
183 ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_MEDIUM_ERROR;
184 ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_UNRECOVERED_READ_ERROR;
185 }
186 }
187 }
188 else
189 {
190 /*case 8, device intends to receive data from the host*/
191 mscHandle->mscCsw->dataResidue = mscCheckEvent->hostExpectedDataLength;
192 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
193 if (kStatus_USB_Success !=
194 USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, mscCheckEvent->buffer, 0))
195 {
196 return kStatus_USB_Error;
197 }
198 #else
199 (void)USB_DeviceSendRequest(mscHandle->handle, mscHandle->bulkInEndpoint, mscCheckEvent->buffer, 0);
200 #endif
201 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_PHASE_ERROR;
202 status = kStatus_USB_InvalidRequest;
203 }
204 }
205 else
206 {
207 /*Host expects to send data to the device*/
208 if (0U == mscCheckEvent->deviceExpectedDataLength)
209 { /*case 9,Device intends to transfer no data*/
210 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
211 if (kStatus_USB_Success != USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkOutEndpoint))
212 {
213 return kStatus_USB_Error;
214 }
215 #else
216 (void)USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkOutEndpoint);
217 #endif
218 mscHandle->mscCsw->dataResidue = mscCheckEvent->hostExpectedDataLength;
219 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED;
220 mscHandle->outEndpointStallFlag = 1;
221 status = kStatus_USB_InvalidRequest;
222 }
223 else if (0U != mscCheckEvent->deviceExpectedDirection)
224 { /*case 10,Device intends to send data to the host*/
225 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
226 if (kStatus_USB_Success != USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkOutEndpoint))
227 {
228 return kStatus_USB_Error;
229 }
230 #else
231 (void)USB_DeviceStallEndpoint(mscHandle->handle, mscHandle->bulkOutEndpoint);
232 #endif
233 mscHandle->mscCsw->dataResidue = mscCheckEvent->hostExpectedDataLength;
234 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_PHASE_ERROR;
235 mscHandle->outEndpointStallFlag = 1U;
236 status = kStatus_USB_InvalidRequest;
237 }
238 else
239 {
240 if (mscCheckEvent->hostExpectedDataLength > mscCheckEvent->deviceExpectedDataLength)
241 { /*case 11, device intends to process less than the amount of data that the host indicated*/
242 mscHandle->mscCsw->dataResidue =
243 mscCheckEvent->hostExpectedDataLength - mscCheckEvent->deviceExpectedDataLength;
244
245 if (ufi->thirteenCase.lbaSendRecvSelect == 1U)
246 {
247 status = USB_DeviceMscLbaTransfer(mscHandle, USB_OUT, &mscCheckEvent->lbaInformation);
248 }
249 else
250 {
251 status = USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, mscCheckEvent->buffer,
252 mscCheckEvent->deviceExpectedDataLength);
253 }
254
255 if (kStatus_USB_Success == status)
256 {
257 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED;
258 }
259 else
260 {
261 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED;
262 ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_MEDIUM_ERROR;
263 ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_WRITE_FAULT;
264 }
265 status = kStatus_USB_InvalidRequest;
266 }
267 else if (mscCheckEvent->hostExpectedDataLength == mscCheckEvent->deviceExpectedDataLength)
268 { /*case 12,device intends to process equal to the amount of data that the host indicated*/
269 mscHandle->mscCsw->dataResidue = 0;
270 if (ufi->thirteenCase.lbaSendRecvSelect == 1U)
271 {
272 status = USB_DeviceMscLbaTransfer(mscHandle, USB_OUT, &mscCheckEvent->lbaInformation);
273 }
274 else
275 {
276 status = USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, mscCheckEvent->buffer,
277 mscCheckEvent->deviceExpectedDataLength);
278 }
279 if (kStatus_USB_Success == status)
280 {
281 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED;
282 }
283 else
284 {
285 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED;
286 ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_MEDIUM_ERROR;
287 ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_WRITE_FAULT;
288 }
289 }
290 else
291 { /*case 13,device intends to process more data than the host indicated*/
292 mscHandle->mscCsw->dataResidue = 0;
293 if (ufi->thirteenCase.lbaSendRecvSelect == 1U)
294 {
295 mscCheckEvent->lbaInformation.transferNumber =
296 mscCheckEvent->hostExpectedDataLength /
297 mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].lengthOfEachLba;
298 mscHandle->mscCsw->dataResidue =
299 mscCheckEvent->hostExpectedDataLength -
300 mscCheckEvent->lbaInformation.transferNumber *
301 mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].lengthOfEachLba;
302 status = USB_DeviceMscLbaTransfer(mscHandle, USB_OUT, &mscCheckEvent->lbaInformation);
303 }
304 else
305 {
306 status = USB_DeviceRecvRequest(mscHandle->handle, mscHandle->bulkOutEndpoint, mscCheckEvent->buffer,
307 mscCheckEvent->hostExpectedDataLength);
308 }
309
310 if (kStatus_USB_Success == status)
311 {
312 if (ufi->thirteenCase.lbaSendRecvSelect == 1U)
313 {
314 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_PHASE_ERROR;
315 }
316 else
317 {
318 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED;
319 }
320 }
321 else
322 {
323 ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_MEDIUM_ERROR;
324 ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_WRITE_FAULT;
325 }
326 }
327 }
328 }
329 return status;
330 }
331
332 /*!
333 * @brief request sense command.
334 *
335 * The REQUEST SENSE command instructs the UFI device to transfer sense data to the host for the specified logical
336 *unit.
337 *
338 * @param handle The device msc class handle.
339 *
340 *@return A USB error code or kStatus_USB_Success.
341 */
USB_DeviceMscUfiRequestSenseCommand(struct _usb_device_msc_struct * mscHandle)342 usb_status_t USB_DeviceMscUfiRequestSenseCommand(struct _usb_device_msc_struct *mscHandle)
343 {
344 usb_device_msc_ufi_struct_t *ufi = NULL;
345 usb_status_t status;
346 usb_device_ufi_app_struct_t temp;
347
348 ufi = &mscHandle->mscUfi;
349 temp.requestSense = ufi->requestSense;
350 temp.cbwcb = &mscHandle->mscCbw->cbwcb[0];
351 temp.logicalUnitNumber = mscHandle->mscCbw->logicalUnitNumber;
352 if (mscHandle->configurationStruct->classCallback != NULL)
353 {
354 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
355 it is from the second parameter of classInit */
356 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
357 if (kStatus_USB_Success != mscHandle->configurationStruct->classCallback(
358 (class_handle_t)mscHandle, kUSB_DeviceMscEventRequestSense, (void *)&temp))
359 {
360 return kStatus_USB_Error;
361 }
362 #else
363 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventRequestSense,
364 (void *)&temp);
365 #endif
366 }
367
368 ufi->thirteenCase.deviceExpectedDataLength = USB_DEVICE_MSC_UFI_REQ_SENSE_DATA_LENGTH;
369 ufi->thirteenCase.deviceExpectedDirection = USB_IN;
370 ufi->thirteenCase.buffer = (uint8_t *)ufi->requestSense;
371 ufi->thirteenCase.lbaSendRecvSelect = 0;
372 status = USB_DeviceMscUfiThirteenCasesCheck(mscHandle);
373
374 return status;
375 }
376
377 /*!
378 * @brief inquiry command.
379 *
380 * The INQUIRY command requests that information regarding parameters of the UFI device itself be sent to the host.
381 *
382 * @param handle The device msc class handle.
383 *
384 *@return A USB error code or kStatus_USB_Success.
385 */
USB_DeviceMscUfiInquiryCommand(struct _usb_device_msc_struct * mscHandle)386 usb_status_t USB_DeviceMscUfiInquiryCommand(struct _usb_device_msc_struct *mscHandle)
387 {
388 usb_device_msc_ufi_struct_t *ufi = NULL;
389 usb_status_t status;
390 usb_device_ufi_app_struct_t temp;
391
392 ufi = &mscHandle->mscUfi;
393 temp.requestSense = ufi->requestSense;
394 temp.cbwcb = &mscHandle->mscCbw->cbwcb[0];
395 temp.size = 0U;
396 temp.buffer = NULL;
397 temp.logicalUnitNumber = mscHandle->mscCbw->logicalUnitNumber;
398
399 if (mscHandle->configurationStruct->classCallback != NULL)
400 {
401 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
402 it is from the second parameter of classInit */
403 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
404 if (kStatus_USB_Success != mscHandle->configurationStruct->classCallback(
405 (class_handle_t)mscHandle, kUSB_DeviceMscEventInquiry, (void *)&temp))
406 {
407 return kStatus_USB_Error;
408 }
409 #else
410 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventInquiry,
411 (void *)&temp);
412 #endif
413 }
414 ufi->thirteenCase.deviceExpectedDataLength = temp.size;
415 ufi->thirteenCase.deviceExpectedDirection = USB_IN;
416 ufi->thirteenCase.buffer = temp.buffer;
417 ufi->thirteenCase.lbaSendRecvSelect = 0;
418
419 status = USB_DeviceMscUfiThirteenCasesCheck(mscHandle);
420 return status;
421 }
422
423 /*!
424 * @brief read command.
425 *
426 * The READ(10),READ(12) command requests that the UFI device transfer data to the host.
427 *
428 * @param handle The device msc class handle.
429 *
430 *@return A USB error code or kStatus_USB_Success.
431 */
USB_DeviceMscUfiReadCommand(struct _usb_device_msc_struct * mscHandle)432 usb_status_t USB_DeviceMscUfiReadCommand(struct _usb_device_msc_struct *mscHandle)
433 {
434 usb_device_msc_ufi_struct_t *ufi = NULL;
435 usb_status_t status;
436 uint32_t logicalBlockAddress = 0;
437 uint32_t lbaTransferLength = 0;
438
439 ufi = &mscHandle->mscUfi;
440
441 logicalBlockAddress = ((uint32_t)mscHandle->mscCbw->cbwcb[2] << 24);
442 logicalBlockAddress |= ((uint32_t)mscHandle->mscCbw->cbwcb[3] << 16);
443 logicalBlockAddress |= ((uint32_t)mscHandle->mscCbw->cbwcb[4] << 8);
444 logicalBlockAddress |= ((uint32_t)mscHandle->mscCbw->cbwcb[5]);
445
446 if (mscHandle->mscCbw->cbwcb[0] == USB_DEVICE_MSC_READ_10_COMMAND)
447 {
448 lbaTransferLength = (uint16_t)((uint16_t)mscHandle->mscCbw->cbwcb[7] << 8);
449 lbaTransferLength |= (uint16_t)mscHandle->mscCbw->cbwcb[8];
450 }
451 else if (mscHandle->mscCbw->cbwcb[0] == USB_DEVICE_MSC_READ_12_COMMAND)
452 {
453 lbaTransferLength = ((uint32_t)mscHandle->mscCbw->cbwcb[6] << 24);
454 lbaTransferLength |= ((uint32_t)mscHandle->mscCbw->cbwcb[7] << 16);
455 lbaTransferLength |= ((uint32_t)mscHandle->mscCbw->cbwcb[8] << 8);
456 lbaTransferLength |= ((uint32_t)mscHandle->mscCbw->cbwcb[9]);
457 }
458 else
459 {
460 /*no action*/
461 }
462
463 ufi->thirteenCase.deviceExpectedDirection = USB_IN;
464 ufi->thirteenCase.deviceExpectedDataLength =
465 mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].lengthOfEachLba * lbaTransferLength;
466 ufi->thirteenCase.buffer = NULL;
467
468 ufi->thirteenCase.lbaSendRecvSelect = 1U;
469 ufi->thirteenCase.lbaInformation.startingLogicalBlockAddress = logicalBlockAddress;
470 ufi->thirteenCase.lbaInformation.transferNumber = lbaTransferLength;
471
472 status = USB_DeviceMscUfiThirteenCasesCheck(mscHandle);
473 return status;
474 }
475
476 /*!
477 * @brief write command.
478 *
479 * The WRITE(10),WRITE(12) command requests that the UFI device write the data transferred by the host to the medium.
480 *
481 * @param handle The device msc class handle.
482 *
483 *@return A USB error code or kStatus_USB_Success.
484 */
USB_DeviceMscUfiWriteCommand(struct _usb_device_msc_struct * mscHandle)485 usb_status_t USB_DeviceMscUfiWriteCommand(struct _usb_device_msc_struct *mscHandle)
486 {
487 usb_device_msc_ufi_struct_t *ufi = NULL;
488 usb_status_t status;
489 uint32_t logicalBlockAddress = 0;
490 uint32_t lbaTransferLength = 0;
491
492 ufi = &mscHandle->mscUfi;
493
494 logicalBlockAddress = ((uint32_t)mscHandle->mscCbw->cbwcb[2] << 24);
495 logicalBlockAddress |= ((uint32_t)mscHandle->mscCbw->cbwcb[3] << 16);
496 logicalBlockAddress |= ((uint32_t)mscHandle->mscCbw->cbwcb[4] << 8);
497 logicalBlockAddress |= ((uint32_t)mscHandle->mscCbw->cbwcb[5]);
498
499 if (mscHandle->mscCbw->cbwcb[0] == USB_DEVICE_MSC_WRITE_10_COMMAND)
500 {
501 lbaTransferLength = (uint16_t)((uint16_t)mscHandle->mscCbw->cbwcb[7] << 8);
502 lbaTransferLength |= (uint16_t)mscHandle->mscCbw->cbwcb[8];
503 }
504 else if (mscHandle->mscCbw->cbwcb[0] == USB_DEVICE_MSC_WRITE_12_COMMAND)
505 {
506 lbaTransferLength = ((uint32_t)mscHandle->mscCbw->cbwcb[6] << 24);
507 lbaTransferLength |= ((uint32_t)mscHandle->mscCbw->cbwcb[7] << 16);
508 lbaTransferLength |= ((uint32_t)mscHandle->mscCbw->cbwcb[8] << 8);
509 lbaTransferLength |= ((uint32_t)mscHandle->mscCbw->cbwcb[9]);
510 }
511 else
512 {
513 /*no action*/
514 }
515 ufi->thirteenCase.deviceExpectedDirection = USB_OUT;
516 ufi->thirteenCase.deviceExpectedDataLength =
517 mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].lengthOfEachLba * lbaTransferLength;
518 ufi->thirteenCase.buffer = NULL;
519
520 ufi->thirteenCase.lbaSendRecvSelect = 1U;
521 ufi->thirteenCase.lbaInformation.startingLogicalBlockAddress = logicalBlockAddress;
522 ufi->thirteenCase.lbaInformation.transferNumber = lbaTransferLength;
523
524 status = USB_DeviceMscUfiThirteenCasesCheck(mscHandle);
525 return status;
526 }
527
528 /*!
529 * @brief test unit ready command.
530 *
531 * The TEST UNIT READY command provides a means to check if the UFI device is ready.
532 *
533 * @param handle The device msc class handle.
534 *
535 *@return A USB error code or kStatus_USB_Success.
536 */
USB_DeviceMscUfiTestUnitReadyCommand(struct _usb_device_msc_struct * mscHandle)537 usb_status_t USB_DeviceMscUfiTestUnitReadyCommand(struct _usb_device_msc_struct *mscHandle)
538 {
539 usb_device_msc_ufi_struct_t *ufi = NULL;
540 usb_status_t status;
541 usb_device_ufi_app_struct_t temp;
542
543 ufi = &mscHandle->mscUfi;
544 temp.requestSense = ufi->requestSense;
545 temp.cbwcb = &mscHandle->mscCbw->cbwcb[0];
546 temp.logicalUnitNumber = mscHandle->mscCbw->logicalUnitNumber;
547 ufi->thirteenCase.deviceExpectedDataLength = 0U;
548 ufi->thirteenCase.deviceExpectedDirection = USB_IN;
549 ufi->thirteenCase.buffer = NULL;
550 ufi->thirteenCase.lbaSendRecvSelect = 0U;
551
552 status = USB_DeviceMscUfiThirteenCasesCheck(mscHandle);
553
554 if (mscHandle->configurationStruct->classCallback != NULL)
555 {
556 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
557 it is from the second parameter of classInit */
558 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
559 if (kStatus_USB_Success != mscHandle->configurationStruct->classCallback(
560 (class_handle_t)mscHandle, kUSB_DeviceMscEventTestUnitReady, (void *)&temp))
561 {
562 return kStatus_USB_Error;
563 }
564 #else
565 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventTestUnitReady,
566 (void *)&temp);
567 #endif
568 }
569 return status;
570 }
571
572 /*!
573 * @brief verify command.
574 *
575 * The VERIFY command requests that the UFI device verify the data on the medium.
576 *
577 * @param handle The device msc class handle.
578 *
579 *@return A USB error code or kStatus_USB_Success.
580 */
USB_DeviceMscUfiVerifyCommand(struct _usb_device_msc_struct * mscHandle)581 usb_status_t USB_DeviceMscUfiVerifyCommand(struct _usb_device_msc_struct *mscHandle)
582 {
583 usb_device_msc_ufi_struct_t *ufi = NULL;
584 usb_status_t status;
585
586 ufi = &mscHandle->mscUfi;
587
588 ufi->thirteenCase.deviceExpectedDataLength = 0;
589 ufi->thirteenCase.deviceExpectedDirection = USB_IN;
590 ufi->thirteenCase.buffer = NULL;
591 ufi->thirteenCase.lbaSendRecvSelect = 0U;
592
593 status = USB_DeviceMscUfiThirteenCasesCheck(mscHandle);
594 return status;
595 }
596
597 /*!
598 * @brief mode sense command.
599 *
600 * The MODE SENSE command allows the UFI device to report medium or device parameters to the host.
601 *
602 * @param handle The device msc class handle.
603 *
604 *@return A USB error code or kStatus_USB_Success.
605 */
USB_DeviceMscUfiModeSenseCommand(struct _usb_device_msc_struct * mscHandle)606 usb_status_t USB_DeviceMscUfiModeSenseCommand(struct _usb_device_msc_struct *mscHandle)
607 {
608 usb_device_msc_ufi_struct_t *ufi = NULL;
609 usb_status_t status;
610
611 usb_device_ufi_app_struct_t temp;
612
613 ufi = &mscHandle->mscUfi;
614 temp.requestSense = ufi->requestSense;
615 temp.cbwcb = &mscHandle->mscCbw->cbwcb[0];
616 temp.size = 0U;
617 temp.buffer = NULL;
618 temp.logicalUnitNumber = mscHandle->mscCbw->logicalUnitNumber;
619
620 if (mscHandle->configurationStruct->classCallback != NULL)
621 {
622 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
623 it is from the second parameter of classInit */
624 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
625 if (kStatus_USB_Success != mscHandle->configurationStruct->classCallback(
626 (class_handle_t)mscHandle, kUSB_DeviceMscEventModeSense, (void *)&temp))
627 {
628 return kStatus_USB_Error;
629 }
630 #else
631 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventModeSense,
632 (void *)&temp);
633 #endif
634 }
635 ufi->thirteenCase.deviceExpectedDataLength = temp.size;
636 ufi->thirteenCase.deviceExpectedDirection = USB_IN;
637 ufi->thirteenCase.buffer = temp.buffer;
638 ufi->thirteenCase.lbaSendRecvSelect = 0U;
639
640 status = USB_DeviceMscUfiThirteenCasesCheck(mscHandle);
641 return status;
642 }
643
644 /*!
645 * @brief mode select command.
646 *
647 * The MODE SELECT command allows the host to specify medium or device parameters to the UFI device.
648 *
649 * @param handle The device msc class handle.
650 *
651 *@return A USB error code or kStatus_USB_Success.
652 */
USB_DeviceMscUfiModeSelectCommand(struct _usb_device_msc_struct * mscHandle)653 usb_status_t USB_DeviceMscUfiModeSelectCommand(struct _usb_device_msc_struct *mscHandle)
654 {
655 usb_device_msc_ufi_struct_t *ufi = NULL;
656 usb_status_t status;
657
658 usb_device_ufi_app_struct_t temp;
659
660 ufi = &mscHandle->mscUfi;
661 temp.requestSense = ufi->requestSense;
662 temp.cbwcb = &mscHandle->mscCbw->cbwcb[0];
663 temp.buffer = NULL;
664 temp.size = 0U;
665 temp.logicalUnitNumber = mscHandle->mscCbw->logicalUnitNumber;
666
667 if (mscHandle->configurationStruct->classCallback != NULL)
668 {
669 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
670 it is from the second parameter of classInit */
671 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
672 if (kStatus_USB_Success != mscHandle->configurationStruct->classCallback(
673 (class_handle_t)mscHandle, kUSB_DeviceMscEventModeSelect, (void *)&temp))
674 {
675 return kStatus_USB_Error;
676 }
677 #else
678 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventModeSelect,
679 (void *)&temp);
680 #endif
681 }
682
683 ufi->thirteenCase.deviceExpectedDataLength = temp.size;
684 ufi->thirteenCase.deviceExpectedDirection = USB_OUT;
685 ufi->thirteenCase.buffer = temp.buffer;
686 ufi->thirteenCase.lbaSendRecvSelect = 0;
687
688 status = USB_DeviceMscUfiThirteenCasesCheck(mscHandle);
689
690 if (0U != (mscHandle->mscCbw->cbwcb[1] & 0x01U))
691 {
692 ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_ILLEGAL_REQUEST;
693 ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_INVALID_FIELD_IN_COMMAND_PKT;
694 }
695 return status;
696 }
697
698 /*!
699 * @brief read capacity command.
700 *
701 * The READ CAPACITIY command allows the host to request capacities of the currently installed medium.
702 *
703 * @param handle The device msc class handle.
704 *
705 *@return A USB error code or kStatus_USB_Success.
706 */
USB_DeviceMscUfiReadCapacityCommand(struct _usb_device_msc_struct * mscHandle)707 usb_status_t USB_DeviceMscUfiReadCapacityCommand(struct _usb_device_msc_struct *mscHandle)
708 {
709 usb_device_msc_ufi_struct_t *ufi = NULL;
710 usb_status_t status;
711 usb_device_capacity_information_struct_t diskInformation;
712 uint32_t deviceExpectedDataLength;
713 uint8_t logicalUnitNumber;
714
715 ufi = &mscHandle->mscUfi;
716 logicalUnitNumber = mscHandle->mscCbw->logicalUnitNumber;
717 diskInformation.logicalUnitNumber = logicalUnitNumber;
718 diskInformation.lengthOfEachLba = 0U;
719 diskInformation.totalLbaNumberSupports = 0U;
720 /* Get device information.*/
721 if (mscHandle->configurationStruct->classCallback != NULL)
722 {
723 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
724 it is from the second parameter of classInit */
725 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
726 if (kStatus_USB_Success != mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle,
727 kUSB_DeviceMscEventReadCapacity,
728 (void *)&diskInformation))
729 {
730 return kStatus_USB_Error;
731 }
732 #else
733 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle, kUSB_DeviceMscEventReadCapacity,
734 (void *)&diskInformation);
735 #endif
736 }
737
738 if (logicalUnitNumber > mscHandle->logicalUnitNumber)
739 {
740 ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_ILLEGAL_REQUEST;
741 logicalUnitNumber = 0;
742 }
743 if ((0U != diskInformation.lengthOfEachLba) && (0U != diskInformation.totalLbaNumberSupports))
744 {
745 mscHandle->luInformations[logicalUnitNumber].totalLbaNumberSupports = diskInformation.totalLbaNumberSupports;
746 mscHandle->luInformations[logicalUnitNumber].lengthOfEachLba = diskInformation.lengthOfEachLba;
747 deviceExpectedDataLength = USB_DEVICE_MSC_UFI_READ_CAPACITY_DATA_LENGTH;
748 }
749 else
750 {
751 deviceExpectedDataLength = 0U;
752 }
753 if (mscHandle->mscCbw->cbwcb[0] == USB_DEVICE_MSC_READ_CAPACITY_10_COMMAND)
754 {
755 ufi->thirteenCase.deviceExpectedDataLength = deviceExpectedDataLength;
756 ufi->readCapacity->lastLogicalBlockAddress = USB_LONG_TO_BIG_ENDIAN(
757 mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].totalLbaNumberSupports - 1U);
758 ufi->readCapacity->blockSize = USB_LONG_TO_BIG_ENDIAN(
759 (uint32_t)mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].lengthOfEachLba);
760 ufi->thirteenCase.buffer = (uint8_t *)(ufi->readCapacity);
761 }
762 else
763 {
764 if (0U != deviceExpectedDataLength)
765 {
766 deviceExpectedDataLength = USB_DEVICE_MSC_UFI_READ_CAPACITY16_DATA_LENGTH;
767 }
768 ufi->thirteenCase.deviceExpectedDataLength = deviceExpectedDataLength;
769 ufi->readCapacity16->lastLogicalBlockAddress1 = USB_LONG_TO_BIG_ENDIAN(
770 mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].totalLbaNumberSupports - 1U);
771 ufi->readCapacity16->blockSize = USB_LONG_TO_BIG_ENDIAN(
772 (uint32_t)mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].lengthOfEachLba);
773 ufi->thirteenCase.buffer = (uint8_t *)(ufi->readCapacity16);
774 }
775 ufi->thirteenCase.deviceExpectedDirection = USB_IN;
776 ufi->thirteenCase.lbaSendRecvSelect = 0;
777
778 status = USB_DeviceMscUfiThirteenCasesCheck(mscHandle);
779 return status;
780 }
781
782 /*!
783 * @brief read format capacity command.
784 *
785 * The READ FORMAT CAPACITIES command allows the host to request a list of the possible capacities that
786 * can be formatted on the currently installed medium.
787 *
788 * @param handle The device msc class handle.
789 *
790 *@return A USB error code or kStatus_USB_Success.
791 */
USB_DeviceMscUfiReadFormatCapacityCommand(struct _usb_device_msc_struct * mscHandle)792 usb_status_t USB_DeviceMscUfiReadFormatCapacityCommand(struct _usb_device_msc_struct *mscHandle)
793 {
794 usb_device_msc_ufi_struct_t *ufi = NULL;
795 usb_status_t status = kStatus_USB_TransferFailed;
796 usb_device_capacity_information_struct_t diskInformation;
797 usb_device_current_max_capacity_descriptor_struct_t current_max_head;
798 usb_device_formattable_capacity_descriptor_struct_t formattable_capacity_head;
799 usb_device_capacity_list_header_struct_t capacityListHead = {{0x00, 0x00, 0x00}, 0x00};
800 uint32_t response_size;
801 uint16_t allocation_length;
802 uint8_t num_formattable_cap_desc;
803 uint8_t descriptor_code;
804 uint8_t count = 0;
805 uint8_t i = 0;
806 uint8_t j = 0;
807 uint8_t logicalUnitNumber;
808 uint8_t *ptr;
809
810 ufi = &mscHandle->mscUfi;
811 logicalUnitNumber = mscHandle->mscCbw->logicalUnitNumber;
812 diskInformation.logicalUnitNumber = logicalUnitNumber;
813 diskInformation.lengthOfEachLba = 0U;
814 diskInformation.totalLbaNumberSupports = 0U;
815 /* Get device information. */
816 if (mscHandle->configurationStruct->classCallback != NULL)
817 {
818 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
819 it is from the second parameter of classInit */
820 status = mscHandle->configurationStruct->classCallback(
821 (class_handle_t)mscHandle, kUSB_DeviceMscEventReadFormatCapacity, (void *)&diskInformation);
822 if (kStatus_USB_Success != status)
823 {
824 return status;
825 }
826 }
827
828 if (logicalUnitNumber > mscHandle->logicalUnitNumber)
829 {
830 ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_ILLEGAL_REQUEST;
831 logicalUnitNumber = 0;
832 }
833 if ((0U != diskInformation.lengthOfEachLba) && (0U != diskInformation.totalLbaNumberSupports))
834 {
835 mscHandle->luInformations[logicalUnitNumber].totalLbaNumberSupports = diskInformation.totalLbaNumberSupports;
836 mscHandle->luInformations[logicalUnitNumber].lengthOfEachLba = diskInformation.lengthOfEachLba;
837 }
838
839 allocation_length = (uint16_t)((((uint16_t)mscHandle->mscCbw->cbwcb[7]) << 8) | mscHandle->mscCbw->cbwcb[8]);
840 /*reference ufi command spec table-33 Descriptor Code definition*/
841 num_formattable_cap_desc =
842 (uint8_t)((0U != ufi->formattedDisk) ? ((0U != mscHandle->implementingDiskDrive) ? 0x02U : 0x03U) : 0x00U);
843
844 formattable_capacity_head.blockNumber =
845 USB_LONG_TO_BIG_ENDIAN(mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].totalLbaNumberSupports);
846 formattable_capacity_head.blockLength =
847 USB_LONG_TO_BIG_ENDIAN(mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].lengthOfEachLba);
848
849 descriptor_code = (uint8_t)((0U != ufi->formattedDisk) ? USB_DEVICE_MSC_UFI_FORMATTED_MEDIA :
850 USB_DEVICE_MSC_UFI_UNFORMATTED_MEDIA);
851 capacityListHead.capacityListLength = num_formattable_cap_desc * 8U;
852 current_max_head.blockNumber =
853 USB_LONG_TO_BIG_ENDIAN(mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].totalLbaNumberSupports);
854 current_max_head.descriptorCodeBlockLength =
855 USB_LONG_TO_BIG_ENDIAN(((((uint32_t)descriptor_code) << 24) |
856 mscHandle->luInformations[mscHandle->mscCbw->logicalUnitNumber].lengthOfEachLba));
857
858 response_size = (uint32_t)sizeof(usb_device_capacity_list_header_struct_t) +
859 sizeof(usb_device_current_max_capacity_descriptor_struct_t) +
860 sizeof(usb_device_formattable_capacity_descriptor_struct_t) * ((uint32_t)num_formattable_cap_desc);
861
862 if (response_size > allocation_length)
863 {
864 response_size = allocation_length;
865 }
866
867 ptr = (uint8_t *)&capacityListHead;
868 for (count = 0U; count < sizeof(capacityListHead); count++)
869 {
870 ufi->formatCapacityData[count] = ptr[i++];
871 }
872 ptr = (uint8_t *)¤t_max_head;
873
874 for (i = 0U; i < sizeof(current_max_head); i++)
875 {
876 ufi->formatCapacityData[count] = ptr[i];
877 count++;
878 }
879
880 if (0U != ufi->formattedDisk)
881 {
882 for (i = 0U; i < num_formattable_cap_desc; i++)
883 {
884 ptr = (uint8_t *)&formattable_capacity_head;
885
886 for (; count < sizeof(formattable_capacity_head); count++)
887 {
888 ufi->formatCapacityData[count] = ptr[j++];
889 }
890 }
891 }
892
893 ufi->thirteenCase.deviceExpectedDataLength = response_size;
894 ufi->thirteenCase.deviceExpectedDirection = USB_IN;
895 ufi->thirteenCase.buffer = (uint8_t *)ufi->formatCapacityData;
896 ufi->thirteenCase.lbaSendRecvSelect = 0U;
897
898 status = USB_DeviceMscUfiThirteenCasesCheck(mscHandle);
899
900 return status;
901 }
902
903 /*!
904 * @brief format unit command.
905 *
906 * The Host sends the FORMAT UNIT command to physically format one track of a diskette according to the selected
907 *options.
908 *
909 * @param handle The device msc class handle.
910 *
911 *@return A USB error code or kStatus_USB_Success.
912 */
USB_DeviceMscUfiFormatUnitCommand(struct _usb_device_msc_struct * mscHandle)913 usb_status_t USB_DeviceMscUfiFormatUnitCommand(struct _usb_device_msc_struct *mscHandle)
914 {
915 usb_device_msc_ufi_struct_t *ufi = NULL;
916 usb_status_t status;
917
918 ufi = &mscHandle->mscUfi;
919
920 ufi->thirteenCase.deviceExpectedDataLength = 0U;
921 ufi->thirteenCase.deviceExpectedDirection = USB_IN;
922 ufi->thirteenCase.buffer = NULL;
923 ufi->thirteenCase.lbaSendRecvSelect = 0U;
924
925 status = USB_DeviceMscUfiThirteenCasesCheck(mscHandle);
926
927 if (mscHandle->mscCsw->cswStatus != USB_DEVICE_MSC_PHASE_ERROR)
928 {
929 if ((mscHandle->mscCbw->cbwcb[1] & 0x1fU) == 0x17U)
930 {
931 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_PASSED;
932 }
933 else
934 {
935 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED;
936 ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_ILLEGAL_REQUEST;
937 ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_INVALID_FIELD_IN_COMMAND_PKT;
938 }
939 }
940 return status;
941 }
942
943 /*!
944 * @brief prevent allow medium command.
945 *
946 * This command tells the UFI device to enable or disable the removal of the medium in the logical unit.
947 *
948 * @param handle The device msc class handle.
949 *
950 *@return A USB error code or kStatus_USB_Success.
951 */
USB_DeviceMscUfiPreventAllowMediumCommand(struct _usb_device_msc_struct * mscHandle)952 usb_status_t USB_DeviceMscUfiPreventAllowMediumCommand(struct _usb_device_msc_struct *mscHandle)
953 {
954 usb_device_msc_ufi_struct_t *ufi = NULL;
955 usb_status_t status;
956 usb_device_ufi_app_struct_t temp;
957
958 ufi = &mscHandle->mscUfi;
959 temp.requestSense = ufi->requestSense;
960 temp.cbwcb = &mscHandle->mscCbw->cbwcb[0];
961 temp.logicalUnitNumber = mscHandle->mscCbw->logicalUnitNumber;
962
963 ufi->thirteenCase.deviceExpectedDataLength = 0U;
964 ufi->thirteenCase.deviceExpectedDirection = USB_IN;
965 ufi->thirteenCase.buffer = NULL;
966 ufi->thirteenCase.lbaSendRecvSelect = 0U;
967
968 status = USB_DeviceMscUfiThirteenCasesCheck(mscHandle);
969
970 if (mscHandle->configurationStruct->classCallback != NULL)
971 {
972 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
973 it is from the second parameter of classInit */
974 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
975 if (kStatus_USB_Success != mscHandle->configurationStruct->classCallback(
976 (class_handle_t)mscHandle, kUSB_DeviceMscEventRemovalRequest, (void *)&temp))
977 {
978 return kStatus_USB_Error;
979 }
980 #else
981 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle,
982 kUSB_DeviceMscEventRemovalRequest, (void *)&temp);
983 #endif
984 }
985
986 return status;
987 }
988
989 /*!
990 * @brief send diagnostic command.
991 *
992 * The SEND DIAGNOSTIC command requests the UFI device to do a reset or perform a self-test.
993 *
994 * @param handle The device msc class handle.
995 *
996 *@return A USB error code or kStatus_USB_Success.
997 */
USB_DeviceMscUfiSendDiagnosticCommand(struct _usb_device_msc_struct * mscHandle)998 usb_status_t USB_DeviceMscUfiSendDiagnosticCommand(struct _usb_device_msc_struct *mscHandle)
999 {
1000 usb_device_msc_ufi_struct_t *ufi = NULL;
1001 usb_status_t status;
1002 usb_device_ufi_app_struct_t temp;
1003
1004 ufi = &mscHandle->mscUfi;
1005 temp.requestSense = ufi->requestSense;
1006 temp.cbwcb = &mscHandle->mscCbw->cbwcb[0];
1007 temp.logicalUnitNumber = mscHandle->mscCbw->logicalUnitNumber;
1008
1009 ufi->thirteenCase.deviceExpectedDataLength = 0;
1010 ufi->thirteenCase.deviceExpectedDirection = USB_IN;
1011 ufi->thirteenCase.buffer = NULL;
1012 ufi->thirteenCase.lbaSendRecvSelect = 0;
1013
1014 status = USB_DeviceMscUfiThirteenCasesCheck(mscHandle);
1015 if (mscHandle->configurationStruct->classCallback != NULL)
1016 {
1017 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
1018 it is from the second parameter of classInit */
1019 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1020 if (kStatus_USB_Success != mscHandle->configurationStruct->classCallback(
1021 (class_handle_t)mscHandle, kUSB_DeviceMscEventSendDiagnostic, (void *)&temp))
1022 {
1023 return kStatus_USB_Error;
1024 }
1025 #else
1026 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle,
1027 kUSB_DeviceMscEventSendDiagnostic, (void *)&temp);
1028 #endif
1029 }
1030 return status;
1031 }
1032
1033 /*!
1034 * @brief start stop unit command.
1035 *
1036 * The START-STOP UNIT command instructs the UFI device to enable or disable media access operations.
1037 *
1038 * @param handle The device msc class handle.
1039 *
1040 *@return A USB error code or kStatus_USB_Success.
1041 */
USB_DeviceMscUfiStartStopUnitCommand(struct _usb_device_msc_struct * mscHandle)1042 usb_status_t USB_DeviceMscUfiStartStopUnitCommand(struct _usb_device_msc_struct *mscHandle)
1043 {
1044 usb_device_msc_ufi_struct_t *ufi = NULL;
1045 usb_status_t status;
1046 usb_device_ufi_app_struct_t temp;
1047
1048 ufi = &mscHandle->mscUfi;
1049 temp.requestSense = ufi->requestSense;
1050 temp.cbwcb = &mscHandle->mscCbw->cbwcb[0];
1051 temp.logicalUnitNumber = mscHandle->mscCbw->logicalUnitNumber;
1052
1053 ufi->thirteenCase.deviceExpectedDataLength = 0U;
1054 ufi->thirteenCase.deviceExpectedDirection = USB_IN;
1055 ufi->thirteenCase.buffer = NULL;
1056 ufi->thirteenCase.lbaSendRecvSelect = 0U;
1057
1058 status = USB_DeviceMscUfiThirteenCasesCheck(mscHandle);
1059
1060 if (mscHandle->mscCsw->cswStatus != USB_DEVICE_MSC_PHASE_ERROR)
1061 {
1062 if (mscHandle->configurationStruct->classCallback != NULL)
1063 {
1064 /* classCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
1065 it is from the second parameter of classInit */
1066 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1067 if (kStatus_USB_Success != mscHandle->configurationStruct->classCallback(
1068 (class_handle_t)mscHandle, kUSB_DeviceMscEventStopEjectMedia, (void *)&temp))
1069 {
1070 return kStatus_USB_Error;
1071 }
1072 #else
1073 (void)mscHandle->configurationStruct->classCallback((class_handle_t)mscHandle,
1074 kUSB_DeviceMscEventStopEjectMedia, (void *)&temp);
1075 #endif
1076 }
1077 }
1078
1079 return status;
1080 }
1081
1082 /*!
1083 * @brief un-support command.
1084 *
1085 * Handle unsupported command .
1086 *
1087 * @param handle The device msc class handle.
1088 *
1089 *@return A USB error code or kStatus_USB_Success.
1090 */
USB_DeviceMscUfiUnsupportCommand(struct _usb_device_msc_struct * mscHandle)1091 usb_status_t USB_DeviceMscUfiUnsupportCommand(struct _usb_device_msc_struct *mscHandle)
1092 {
1093 usb_device_msc_ufi_struct_t *ufi = NULL;
1094 usb_status_t status;
1095 ufi = &mscHandle->mscUfi;
1096
1097 mscHandle->mscCsw->dataResidue = 0;
1098 mscHandle->mscCsw->cswStatus = USB_DEVICE_MSC_COMMAND_FAILED;
1099
1100 ufi->thirteenCase.deviceExpectedDataLength = 0;
1101 ufi->requestSense->senseKey = USB_DEVICE_MSC_UFI_ILLEGAL_REQUEST;
1102 ufi->requestSense->additionalSenseCode = USB_DEVICE_MSC_UFI_INVALID_COMMAND_OPCODE;
1103 ufi->requestSense->additionalSenseQualifer = USB_DEVICE_MSC_UFI_NO_SENSE;
1104
1105 status = USB_DeviceMscUfiThirteenCasesCheck(mscHandle);
1106
1107 return status;
1108 }
1109
1110 #endif
1111