1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "usb_host_config.h"
10 #if ((defined USB_HOST_CONFIG_MSD) && (USB_HOST_CONFIG_MSD))
11 #include "usb_host.h"
12 #include "usb_host_msd.h"
13
14 /*******************************************************************************
15 * Definitions
16 ******************************************************************************/
17
18 /* UFI command code */
19 #define UFI_FORMAT_UNIT (0x04U)
20 #define UFI_INQUIRY (0x12U)
21 #define UFI_START_STOP (0x1BU)
22 #define UFI_MODE_SELECT (0x55U)
23 #define UFI_MODE_SENSE (0x5AU)
24 #define UFI_MEDIUM_REMOVAL (0x1EU)
25 #define UFI_READ10 (0x28U)
26 #define UFI_READ12 (0xA8U)
27 #define UFI_READ_CAPACITY (0x25U)
28 #define UFI_READ_FORMAT_CAPACITY (0x23U)
29 #define UFI_REQUEST_SENSE (0x03U)
30 #define UFI_REZERO_UINT (0x01U)
31 #define UFI_SEEK (0x2BU)
32 #define UFI_SEND_DIAGNOSTIC (0x1DU)
33 #define UFI_TEST_UNIT_READY (0x00U)
34 #define UFI_VERIFY (0x2FU)
35 #define UFI_WRITE10 (0x2AU)
36 #define UFI_WRITE12 (0xAAU)
37 #define UFI_WRITE_VERIFY (0x2EU)
38
39 #define GET_BYTE_FROM_LE_LONG(b, n) \
40 ((uint8_t)((USB_LONG_TO_LITTLE_ENDIAN(b)) >> ((n)*8))) /* get the byte from the long value */
41
42 /*******************************************************************************
43 * Prototypes
44 ******************************************************************************/
45
46 /*******************************************************************************
47 * Variables
48 ******************************************************************************/
49
50 /*******************************************************************************
51 * Code
52 ******************************************************************************/
53
USB_HostMsdRead10(usb_host_class_handle classHandle,uint8_t logicalUnit,uint32_t blockAddress,uint8_t * buffer,uint32_t bufferLength,uint32_t blockNumber,transfer_callback_t callbackFn,void * callbackParam)54 usb_status_t USB_HostMsdRead10(usb_host_class_handle classHandle,
55 uint8_t logicalUnit,
56 uint32_t blockAddress,
57 uint8_t *buffer,
58 uint32_t bufferLength,
59 uint32_t blockNumber,
60 transfer_callback_t callbackFn,
61 void *callbackParam)
62 {
63 uint8_t ufiBytes[] = {UFI_READ10,
64 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
65 GET_BYTE_FROM_LE_LONG(blockAddress, 3),
66 GET_BYTE_FROM_LE_LONG(blockAddress, 2),
67 GET_BYTE_FROM_LE_LONG(blockAddress, 1),
68 GET_BYTE_FROM_LE_LONG(blockAddress, 0),
69 0x00,
70 GET_BYTE_FROM_LE_LONG(blockNumber, 1),
71 GET_BYTE_FROM_LE_LONG(blockNumber, 0),
72 0x00};
73 return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
74 USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
75 }
76
USB_HostMsdRead12(usb_host_class_handle classHandle,uint8_t logicalUnit,uint32_t blockAddress,uint8_t * buffer,uint32_t bufferLength,uint32_t blockNumber,transfer_callback_t callbackFn,void * callbackParam)77 usb_status_t USB_HostMsdRead12(usb_host_class_handle classHandle,
78 uint8_t logicalUnit,
79 uint32_t blockAddress,
80 uint8_t *buffer,
81 uint32_t bufferLength,
82 uint32_t blockNumber,
83 transfer_callback_t callbackFn,
84 void *callbackParam)
85 {
86 uint8_t ufiBytes[] = {UFI_READ12,
87 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
88 GET_BYTE_FROM_LE_LONG(blockAddress, 3),
89 GET_BYTE_FROM_LE_LONG(blockAddress, 2),
90 GET_BYTE_FROM_LE_LONG(blockAddress, 1),
91 GET_BYTE_FROM_LE_LONG(blockAddress, 0),
92 GET_BYTE_FROM_LE_LONG(blockNumber, 3),
93 GET_BYTE_FROM_LE_LONG(blockNumber, 2),
94 GET_BYTE_FROM_LE_LONG(blockNumber, 1),
95 GET_BYTE_FROM_LE_LONG(blockNumber, 0)};
96 return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
97 USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
98 }
99
USB_HostMsdWrite10(usb_host_class_handle classHandle,uint8_t logicalUnit,uint32_t blockAddress,uint8_t * buffer,uint32_t bufferLength,uint32_t blockNumber,transfer_callback_t callbackFn,void * callbackParam)100 usb_status_t USB_HostMsdWrite10(usb_host_class_handle classHandle,
101 uint8_t logicalUnit,
102 uint32_t blockAddress,
103 uint8_t *buffer,
104 uint32_t bufferLength,
105 uint32_t blockNumber,
106 transfer_callback_t callbackFn,
107 void *callbackParam)
108 {
109 uint8_t ufiBytes[] = {UFI_WRITE10,
110 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
111 GET_BYTE_FROM_LE_LONG(blockAddress, 3),
112 GET_BYTE_FROM_LE_LONG(blockAddress, 2),
113 GET_BYTE_FROM_LE_LONG(blockAddress, 1),
114 GET_BYTE_FROM_LE_LONG(blockAddress, 0),
115 0x00,
116 GET_BYTE_FROM_LE_LONG(blockNumber, 1),
117 GET_BYTE_FROM_LE_LONG(blockNumber, 0),
118 0x00};
119 return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
120 USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
121 }
122
USB_HostMsdWrite12(usb_host_class_handle classHandle,uint8_t logicalUnit,uint32_t blockAddress,uint8_t * buffer,uint32_t bufferLength,uint32_t blockNumber,transfer_callback_t callbackFn,void * callbackParam)123 usb_status_t USB_HostMsdWrite12(usb_host_class_handle classHandle,
124 uint8_t logicalUnit,
125 uint32_t blockAddress,
126 uint8_t *buffer,
127 uint32_t bufferLength,
128 uint32_t blockNumber,
129 transfer_callback_t callbackFn,
130 void *callbackParam)
131 {
132 uint8_t ufiBytes[] = {UFI_WRITE12,
133 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
134 GET_BYTE_FROM_LE_LONG(blockAddress, 3),
135 GET_BYTE_FROM_LE_LONG(blockAddress, 2),
136 GET_BYTE_FROM_LE_LONG(blockAddress, 1),
137 GET_BYTE_FROM_LE_LONG(blockAddress, 0),
138 GET_BYTE_FROM_LE_LONG(blockNumber, 3),
139 GET_BYTE_FROM_LE_LONG(blockNumber, 2),
140 GET_BYTE_FROM_LE_LONG(blockNumber, 1),
141 GET_BYTE_FROM_LE_LONG(blockNumber, 0)};
142 return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
143 USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
144 }
145
USB_HostMsdReadCapacity(usb_host_class_handle classHandle,uint8_t logicalUnit,uint8_t * buffer,uint32_t bufferLength,transfer_callback_t callbackFn,void * callbackParam)146 usb_status_t USB_HostMsdReadCapacity(usb_host_class_handle classHandle,
147 uint8_t logicalUnit,
148 uint8_t *buffer,
149 uint32_t bufferLength,
150 transfer_callback_t callbackFn,
151 void *callbackParam)
152 {
153 uint8_t ufiBytes[] = {UFI_READ_CAPACITY,
154 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
155 0x00,
156 0x00,
157 0x00,
158 0x00,
159 0x00,
160 0x00,
161 0x00,
162 0x00};
163 return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
164 USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
165 }
166
USB_HostMsdTestUnitReady(usb_host_class_handle classHandle,uint8_t logicalUnit,transfer_callback_t callbackFn,void * callbackParam)167 usb_status_t USB_HostMsdTestUnitReady(usb_host_class_handle classHandle,
168 uint8_t logicalUnit,
169 transfer_callback_t callbackFn,
170 void *callbackParam)
171 {
172 uint8_t ufiBytes[] = {UFI_TEST_UNIT_READY,
173 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
174 0x00,
175 0x00,
176 0x00,
177 0x00,
178 0x00,
179 0x00,
180 0x00,
181 0x00};
182 return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
183 ufiBytes);
184 }
185
USB_HostMsdRequestSense(usb_host_class_handle classHandle,uint8_t logicalUnit,uint8_t * buffer,uint32_t bufferLength,transfer_callback_t callbackFn,void * callbackParam)186 usb_status_t USB_HostMsdRequestSense(usb_host_class_handle classHandle,
187 uint8_t logicalUnit,
188 uint8_t *buffer,
189 uint32_t bufferLength,
190 transfer_callback_t callbackFn,
191 void *callbackParam)
192 {
193 uint8_t ufiBytes[] = {UFI_REQUEST_SENSE,
194 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
195 0x00,
196 0x00,
197 (uint8_t)bufferLength,
198 0x00,
199 0x00,
200 0x00,
201 0x00,
202 0x00};
203 return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
204 USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
205 }
206
USB_HostMsdModeSelect(usb_host_class_handle classHandle,uint8_t logicalUnit,uint8_t * buffer,uint32_t bufferLength,transfer_callback_t callbackFn,void * callbackParam)207 usb_status_t USB_HostMsdModeSelect(usb_host_class_handle classHandle,
208 uint8_t logicalUnit,
209 uint8_t *buffer,
210 uint32_t bufferLength,
211 transfer_callback_t callbackFn,
212 void *callbackParam)
213 {
214 uint8_t ufiBytes[] = {UFI_MODE_SELECT,
215 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
216 0x00,
217 0x00,
218 0x00,
219 0x00,
220 0x00,
221 GET_BYTE_FROM_LE_LONG(bufferLength, 1),
222 GET_BYTE_FROM_LE_LONG(bufferLength, 0),
223 0x00};
224 return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
225 USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
226 }
227
USB_HostMsdModeSense(usb_host_class_handle classHandle,uint8_t logicalUnit,uint8_t pageControl,uint8_t pageCode,uint8_t * buffer,uint32_t bufferLength,transfer_callback_t callbackFn,void * callbackParam)228 usb_status_t USB_HostMsdModeSense(usb_host_class_handle classHandle,
229 uint8_t logicalUnit,
230 uint8_t pageControl,
231 uint8_t pageCode,
232 uint8_t *buffer,
233 uint32_t bufferLength,
234 transfer_callback_t callbackFn,
235 void *callbackParam)
236 {
237 uint8_t ufiBytes[] = {UFI_MODE_SENSE,
238 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
239 (uint8_t)(((uint32_t)pageCode << USB_HOST_UFI_MODE_SENSE_PAGE_CONTROL_SHIFT) |
240 ((uint32_t)pageCode << USB_HOST_UFI_MODE_SENSE_PAGE_CODE_SHIFT)),
241 0x00,
242 0x00,
243 0x00,
244 0x00,
245 GET_BYTE_FROM_LE_LONG(bufferLength, 1),
246 GET_BYTE_FROM_LE_LONG(bufferLength, 0),
247 0x00};
248 return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
249 USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
250 }
251
USB_HostMsdInquiry(usb_host_class_handle classHandle,uint8_t logicalUnit,uint8_t * buffer,uint32_t bufferLength,transfer_callback_t callbackFn,void * callbackParam)252 usb_status_t USB_HostMsdInquiry(usb_host_class_handle classHandle,
253 uint8_t logicalUnit,
254 uint8_t *buffer,
255 uint32_t bufferLength,
256 transfer_callback_t callbackFn,
257 void *callbackParam)
258 {
259 uint8_t ufiBytes[] = {UFI_INQUIRY,
260 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
261 0x00,
262 0x00,
263 (uint8_t)bufferLength,
264 0x00,
265 0x00,
266 0x00,
267 0x00,
268 0x00};
269 return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
270 USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
271 }
272
USB_HostMsdReadFormatCapacities(usb_host_class_handle classHandle,uint8_t logicalUnit,uint8_t * buffer,uint32_t bufferLength,transfer_callback_t callbackFn,void * callbackParam)273 usb_status_t USB_HostMsdReadFormatCapacities(usb_host_class_handle classHandle,
274 uint8_t logicalUnit,
275 uint8_t *buffer,
276 uint32_t bufferLength,
277 transfer_callback_t callbackFn,
278 void *callbackParam)
279 {
280 uint8_t ufiBytes[] = {UFI_READ_FORMAT_CAPACITY,
281 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
282 0x00,
283 0x00,
284 0x00,
285 0x00,
286 0x00,
287 GET_BYTE_FROM_LE_LONG(bufferLength, 1),
288 GET_BYTE_FROM_LE_LONG(bufferLength, 0),
289 0x00};
290 return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
291 USB_HOST_MSD_CBW_FLAGS_DIRECTION_IN, ufiBytes);
292 }
293
USB_HostMsdFormatUnit(usb_host_class_handle classHandle,uint8_t logicalUnit,uint8_t trackNumber,uint16_t interLeave,uint8_t * buffer,uint32_t bufferLength,transfer_callback_t callbackFn,void * callbackParam)294 usb_status_t USB_HostMsdFormatUnit(usb_host_class_handle classHandle,
295 uint8_t logicalUnit,
296 uint8_t trackNumber,
297 uint16_t interLeave,
298 uint8_t *buffer,
299 uint32_t bufferLength,
300 transfer_callback_t callbackFn,
301 void *callbackParam)
302 {
303 uint8_t ufiBytes[] = {UFI_FORMAT_UNIT,
304 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
305 trackNumber,
306 GET_BYTE_FROM_LE_LONG(interLeave, 1),
307 GET_BYTE_FROM_LE_LONG(interLeave, 0),
308 0x00,
309 0x00,
310 GET_BYTE_FROM_LE_LONG(bufferLength, 1),
311 GET_BYTE_FROM_LE_LONG(bufferLength, 0),
312 0x00};
313 return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
314 USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
315 }
316
USB_HostMsdPreventAllowRemoval(usb_host_class_handle classHandle,uint8_t logicalUnit,uint8_t prevent,transfer_callback_t callbackFn,void * callbackParam)317 usb_status_t USB_HostMsdPreventAllowRemoval(usb_host_class_handle classHandle,
318 uint8_t logicalUnit,
319 uint8_t prevent,
320 transfer_callback_t callbackFn,
321 void *callbackParam)
322 {
323 uint8_t ufiBytes[] = {UFI_MEDIUM_REMOVAL,
324 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
325 0x00,
326 0x00,
327 prevent,
328 0x00,
329 0x00,
330 0x00,
331 0x00,
332 0x00};
333 return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
334 ufiBytes);
335 }
336
USB_HostMsdWriteAndVerify(usb_host_class_handle classHandle,uint8_t logicalUnit,uint32_t blockAddress,uint8_t * buffer,uint32_t bufferLength,uint32_t blockNumber,transfer_callback_t callbackFn,void * callbackParam)337 usb_status_t USB_HostMsdWriteAndVerify(usb_host_class_handle classHandle,
338 uint8_t logicalUnit,
339 uint32_t blockAddress,
340 uint8_t *buffer,
341 uint32_t bufferLength,
342 uint32_t blockNumber,
343 transfer_callback_t callbackFn,
344 void *callbackParam)
345 {
346 uint8_t ufiBytes[] = {UFI_WRITE_VERIFY,
347 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
348 GET_BYTE_FROM_LE_LONG(blockAddress, 3),
349 GET_BYTE_FROM_LE_LONG(blockAddress, 2),
350 GET_BYTE_FROM_LE_LONG(blockAddress, 1),
351 GET_BYTE_FROM_LE_LONG(blockAddress, 0),
352 0x00,
353 GET_BYTE_FROM_LE_LONG(blockNumber, 1),
354 GET_BYTE_FROM_LE_LONG(blockNumber, 0),
355 0x00};
356 return USB_HostMsdCommand(classHandle, buffer, bufferLength, callbackFn, callbackParam,
357 USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT, ufiBytes);
358 }
359
USB_HostMsdStartStopUnit(usb_host_class_handle classHandle,uint8_t logicalUnit,uint8_t loadEject,uint8_t start,transfer_callback_t callbackFn,void * callbackParam)360 usb_status_t USB_HostMsdStartStopUnit(usb_host_class_handle classHandle,
361 uint8_t logicalUnit,
362 uint8_t loadEject,
363 uint8_t start,
364 transfer_callback_t callbackFn,
365 void *callbackParam)
366 {
367 uint8_t ufiBytes[] = {UFI_START_STOP,
368 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
369 0x00,
370 0x00,
371 (uint8_t)(((uint32_t)loadEject << USB_HOST_UFI_START_STOP_UNIT_LOEJ_SHIFT) |
372 ((uint32_t)start << USB_HOST_UFI_START_STOP_UNIT_START_SHIFT)),
373 0x00,
374 0x00,
375 0x00,
376 0x00,
377 0x00};
378 return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
379 ufiBytes);
380 }
381
USB_HostMsdVerify(usb_host_class_handle classHandle,uint8_t logicalUnit,uint32_t blockAddress,uint16_t verificationLength,transfer_callback_t callbackFn,void * callbackParam)382 usb_status_t USB_HostMsdVerify(usb_host_class_handle classHandle,
383 uint8_t logicalUnit,
384 uint32_t blockAddress,
385 uint16_t verificationLength,
386 transfer_callback_t callbackFn,
387 void *callbackParam)
388 {
389 uint8_t ufiBytes[] = {UFI_VERIFY,
390 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
391 GET_BYTE_FROM_LE_LONG(blockAddress, 3),
392 GET_BYTE_FROM_LE_LONG(blockAddress, 2),
393 GET_BYTE_FROM_LE_LONG(blockAddress, 1),
394 GET_BYTE_FROM_LE_LONG(blockAddress, 0),
395 0x00,
396 GET_BYTE_FROM_LE_LONG(verificationLength, 1),
397 GET_BYTE_FROM_LE_LONG(verificationLength, 0),
398 0x00};
399 return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
400 ufiBytes);
401 }
402
USB_HostMsdRezeroUnit(usb_host_class_handle classHandle,uint8_t logicalUnit,transfer_callback_t callbackFn,void * callbackParam)403 usb_status_t USB_HostMsdRezeroUnit(usb_host_class_handle classHandle,
404 uint8_t logicalUnit,
405 transfer_callback_t callbackFn,
406 void *callbackParam)
407 {
408 uint8_t ufiBytes[] = {UFI_REZERO_UINT,
409 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
410 0x00,
411 0x00,
412 0x00,
413 0x00,
414 0x00,
415 0x00,
416 0x00,
417 0x00};
418 return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
419 ufiBytes);
420 }
421
USB_HostMsdSeek10(usb_host_class_handle classHandle,uint8_t logicalUnit,uint32_t blockAddress,transfer_callback_t callbackFn,void * callbackParam)422 usb_status_t USB_HostMsdSeek10(usb_host_class_handle classHandle,
423 uint8_t logicalUnit,
424 uint32_t blockAddress,
425 transfer_callback_t callbackFn,
426 void *callbackParam)
427 {
428 uint8_t ufiBytes[] = {UFI_SEEK,
429 (uint8_t)(logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION),
430 GET_BYTE_FROM_LE_LONG(blockAddress, 3),
431 GET_BYTE_FROM_LE_LONG(blockAddress, 2),
432 GET_BYTE_FROM_LE_LONG(blockAddress, 1),
433 GET_BYTE_FROM_LE_LONG(blockAddress, 0),
434 0x00,
435 0x00,
436 0x00,
437 0x00};
438 return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
439 ufiBytes);
440 }
441
USB_HostMsdSendDiagnostic(usb_host_class_handle classHandle,uint8_t logicalUnit,uint8_t selfTest,transfer_callback_t callbackFn,void * callbackParam)442 usb_status_t USB_HostMsdSendDiagnostic(usb_host_class_handle classHandle,
443 uint8_t logicalUnit,
444 uint8_t selfTest,
445 transfer_callback_t callbackFn,
446 void *callbackParam)
447 {
448 uint8_t ufiBytes[] = {UFI_REZERO_UINT,
449 (uint8_t)(((uint32_t)logicalUnit << USB_HOST_UFI_LOGICAL_UNIT_POSITION) |
450 ((uint32_t)selfTest << USB_HOST_UFI_SEND_DIAGNOSTIC_SELF_TEST_SHIFT)),
451 0x00,
452 0x00,
453 0x00,
454 0x00,
455 0x00,
456 0x00,
457 0x00,
458 0x00};
459 return USB_HostMsdCommand(classHandle, NULL, 0, callbackFn, callbackParam, USB_HOST_MSD_CBW_FLAGS_DIRECTION_OUT,
460 ufiBytes);
461 }
462
463 #endif /* USB_HOST_CONFIG_MSD */
464