1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** USBX Component                                                        */
17 /**                                                                       */
18 /**   Storage Class                                                       */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 
24 /**************************************************************************/
25 /*                                                                        */
26 /*  COMPONENT DEFINITION                                   RELEASE        */
27 /*                                                                        */
28 /*    ux_host_class_storage.h                             PORTABLE C      */
29 /*                                                           6.1.10       */
30 /*  AUTHOR                                                                */
31 /*                                                                        */
32 /*    Chaoqiong Xiao, Microsoft Corporation                               */
33 /*                                                                        */
34 /*  DESCRIPTION                                                           */
35 /*                                                                        */
36 /*    This file contains all the header and extern functions used by the  */
37 /*    USBX storage class.                                                 */
38 /*                                                                        */
39 /*  RELEASE HISTORY                                                       */
40 /*                                                                        */
41 /*    DATE              NAME                      DESCRIPTION             */
42 /*                                                                        */
43 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
44 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
45 /*                                            added option to disable FX  */
46 /*                                            media integration, used UX_ */
47 /*                                            things instead of FX_       */
48 /*                                            things directly, used host  */
49 /*                                            class extension pointer for */
50 /*                                            class specific structured   */
51 /*                                            data, used UX prefix to     */
52 /*                                            refer to TX symbols instead */
53 /*                                            of using them directly,     */
54 /*                                            resulting in version 6.1    */
55 /*  11-09-2020     Chaoqiong Xiao           Modified comment(s),          */
56 /*                                            added exFAT type define,    */
57 /*                                            resulting in version 6.1.2  */
58 /*  12-31-2020     Chaoqiong Xiao           Modified comment(s),          */
59 /*                                            resulting in version 6.1.3  */
60 /*  08-02-2021     Chaoqiong Xiao           Modified comment(s),          */
61 /*                                            added extern "C" keyword    */
62 /*                                            for compatibility with C++, */
63 /*                                            resulting in version 6.1.8  */
64 /*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
65 /*                                            added standalone support,   */
66 /*                                            resulting in version 6.1.10 */
67 /*                                                                        */
68 /**************************************************************************/
69 
70 #ifndef UX_HOST_CLASS_STORAGE_H
71 #define UX_HOST_CLASS_STORAGE_H
72 
73 /* Determine if a C++ compiler is being used.  If so, ensure that standard
74    C is used to process the API information.  */
75 
76 #ifdef   __cplusplus
77 
78 /* Yes, C++ compiler is present.  Use standard C.  */
79 extern   "C" {
80 
81 #endif
82 
83 
84 #if !defined(UX_HOST_CLASS_STORAGE_NO_FILEX) && !defined(UX_HOST_STANDALONE)
85 /* Include the FileX API.  */
86 #include "fx_api.h"
87 
88 /* Refine media stubs.  */
89 
90 #ifndef UX_MEDIA
91 #define UX_MEDIA                                            FX_MEDIA
92 #endif
93 
94 #ifndef ux_media_id_get
95 #define ux_media_id_get(m)                                  ((m)->fx_media_id)
96 #endif
97 
98 #ifndef ux_media_id_set
99 #define ux_media_id_set(m,id)                               ((m)->fx_media_id=(id))
100 #endif
101 
102 #ifndef ux_media_driver_info_get
103 #define ux_media_driver_info_get(m)                         ((m)->fx_media_driver_info)
104 #endif
105 
106 #ifndef ux_media_driver_info_set
107 #define ux_media_driver_info_set(m,i)                       ((m)->fx_media_driver_info=(VOID*)(i))
108 #endif
109 
110 #ifndef ux_media_reserved_for_user_get
111 #define ux_media_reserved_for_user_get(m)                   ((m)->fx_media_reserved_for_user)
112 #endif
113 
114 #ifndef ux_media_reserved_for_user_set
115 #define ux_media_reserved_for_user_set(m,u)                 ((m)->fx_media_reserved_for_user=(ALIGN_TYPE)(u))
116 #endif
117 
118 #ifndef ux_media_open
119 #define ux_media_open                                       fx_media_open
120 #endif
121 
122 #ifndef ux_media_close
123 #define ux_media_close                                      fx_media_close
124 #endif
125 #endif
126 
127 /* Define User configurable Storage Class constants.  */
128 
129 #ifndef UX_MAX_HOST_LUN
130 #define UX_MAX_HOST_LUN                                     1
131 #endif
132 
133 #ifndef UX_HOST_CLASS_STORAGE_MAX_MEDIA
134 #define UX_HOST_CLASS_STORAGE_MAX_MEDIA                     1
135 #endif
136 
137 #ifndef UX_HOST_CLASS_STORAGE_MEMORY_BUFFER_SIZE
138 #define UX_HOST_CLASS_STORAGE_MEMORY_BUFFER_SIZE            (1024)
139 #endif
140 
141 #ifndef UX_HOST_CLASS_STORAGE_MAX_TRANSFER_SIZE
142 #define UX_HOST_CLASS_STORAGE_MAX_TRANSFER_SIZE             (1024)
143 #endif
144 
145 #ifndef UX_HOST_CLASS_STORAGE_THREAD_STACK_SIZE
146 #define UX_HOST_CLASS_STORAGE_THREAD_STACK_SIZE             UX_THREAD_STACK_SIZE
147 #endif
148 
149 #if defined(UX_HOST_STANDALONE) && !defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
150 #define UX_HOST_CLASS_STORAGE_NO_FILEX
151 #endif
152 
153 
154 /* Define Storage Class constants.  */
155 
156 #define UX_HOST_CLASS_STORAGE_DEVICE_INIT_DELAY             (200)
157 #define UX_HOST_CLASS_STORAGE_THREAD_SLEEP_TIME             (2000)
158 #define UX_HOST_CLASS_STORAGE_INSTANCE_SHUTDOWN_TIMER       (10)
159 #define UX_HOST_CLASS_STORAGE_THREAD_PRIORITY_CLASS         20
160 #define UX_HOST_CLASS_STORAGE_TRANSFER_TIMEOUT              10000
161 #define UX_HOST_CLASS_STORAGE_CBI_STATUS_TIMEOUT            3000
162 #define UX_HOST_CLASS_STORAGE_CLASS                         8
163 #define UX_HOST_CLASS_STORAGE_SUBCLASS_RBC                  1
164 #define UX_HOST_CLASS_STORAGE_SUBCLASS_SFF8020              2
165 #define UX_HOST_CLASS_STORAGE_SUBCLASS_UFI                  4
166 #define UX_HOST_CLASS_STORAGE_SUBCLASS_SFF8070              5
167 #define UX_HOST_CLASS_STORAGE_SUBCLASS_SCSI                 6
168 
169 #define UX_HOST_CLASS_STORAGE_CBW_SIZE                      64
170 
171 #define UX_HOST_CLASS_STORAGE_PROTOCOL_CBI                  0
172 #define UX_HOST_CLASS_STORAGE_PROTOCOL_CB                   1
173 #define UX_HOST_CLASS_STORAGE_PROTOCOL_BO                   0x50
174 
175 #define UX_HOST_CLASS_STORAGE_DATA_OUT                      0
176 #define UX_HOST_CLASS_STORAGE_DATA_IN                       0x80
177 
178 #define UX_HOST_CLASS_STORAGE_CSW_PASSED                    0
179 #define UX_HOST_CLASS_STORAGE_CSW_FAILED                    1
180 #define UX_HOST_CLASS_STORAGE_CSW_PHASE_ERROR               2
181 
182 #define UX_HOST_CLASS_STORAGE_CBW_SIGNATURE_MASK            0x43425355
183 #define UX_HOST_CLASS_STORAGE_CBW_TAG_MASK                  0x55534243
184 
185 #define UX_HOST_CLASS_STORAGE_MEDIA_NAME                    "usb disk"
186 
187 #define UX_HOST_CLASS_STORAGE_MEDIA_REMOVABLE               0x80
188 #define UX_HOST_CLASS_STORAGE_MEDIA_UNKNOWN                 0
189 #define UX_HOST_CLASS_STORAGE_MEDIA_KNOWN                   1
190 
191 #define UX_HOST_CLASS_STORAGE_MEDIA_FAT_DISK                0
192 #define UX_HOST_CLASS_STORAGE_MEDIA_CDROM                   5
193 #define UX_HOST_CLASS_STORAGE_MEDIA_OPTICAL_DISK            7
194 #define UX_HOST_CLASS_STORAGE_MEDIA_IOMEGA_CLICK            0x55
195 
196 #define UX_HOST_CLASS_STORAGE_RESET                         0xff
197 #define UX_HOST_CLASS_STORAGE_GET_MAX_LUN                   0xfe
198 
199 #define UX_HOST_CLASS_STORAGE_TRANSPORT_ERROR               1
200 #define UX_HOST_CLASS_STORAGE_COMMAND_ERROR                 2
201 #define UX_HOST_CLASS_STORAGE_SENSE_ERROR                   3
202 
203 #define UX_HOST_CLASS_STORAGE_SECTOR_SIZE_FAT               512
204 #define UX_HOST_CLASS_STORAGE_SECTOR_SIZE_OTHER             2048
205 
206 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RETRY           10
207 
208 #define UX_HOST_CLASS_STORAGE_START_MEDIA                   1
209 #define UX_HOST_CLASS_STORAGE_STOP_MEDIA                    0
210 
211 
212 #define UX_HOST_CLASS_STORAGE_MEDIA_UNMOUNTED               0
213 #define UX_HOST_CLASS_STORAGE_MEDIA_MOUNTED                 1
214 
215 /* Define Storage Class SCSI command constants.  */
216 
217 #define UX_HOST_CLASS_STORAGE_SCSI_TEST_READY               0x00
218 #define UX_HOST_CLASS_STORAGE_SCSI_REQUEST_SENSE            0x03
219 #define UX_HOST_CLASS_STORAGE_SCSI_FORMAT                   0x04
220 #define UX_HOST_CLASS_STORAGE_SCSI_INQUIRY                  0x12
221 #define UX_HOST_CLASS_STORAGE_SCSI_MODE_SENSE_SHORT         0x1a
222 #define UX_HOST_CLASS_STORAGE_SCSI_START_STOP               0x1b
223 #define UX_HOST_CLASS_STORAGE_SCSI_READ_FORMAT_CAPACITY     0x23
224 #define UX_HOST_CLASS_STORAGE_SCSI_READ_CAPACITY            0x25
225 #define UX_HOST_CLASS_STORAGE_SCSI_READ16                   0x28
226 #define UX_HOST_CLASS_STORAGE_SCSI_WRITE16                  0x2a
227 #define UX_HOST_CLASS_STORAGE_SCSI_VERIFY                   0x2f
228 #define UX_HOST_CLASS_STORAGE_SCSI_MODE_SELECT              0x55
229 #define UX_HOST_CLASS_STORAGE_SCSI_MODE_SENSE               0x5a
230 #define UX_HOST_CLASS_STORAGE_SCSI_READ32                   0xa8
231 #define UX_HOST_CLASS_STORAGE_SCSI_WRITE32                  0xaa
232 
233 
234 /* Define Storage Class SCSI command block wrapper constants.  */
235 
236 #define UX_HOST_CLASS_STORAGE_CBW_SIGNATURE                 0
237 #define UX_HOST_CLASS_STORAGE_CBW_TAG                       4
238 #define UX_HOST_CLASS_STORAGE_CBW_DATA_LENGTH               8
239 #define UX_HOST_CLASS_STORAGE_CBW_FLAGS                     12
240 #define UX_HOST_CLASS_STORAGE_CBW_LUN                       13
241 #define UX_HOST_CLASS_STORAGE_CBW_CB_LENGTH                 14
242 #define UX_HOST_CLASS_STORAGE_CBW_CB                        15
243 
244 
245 /* Define Storage Class SCSI response status wrapper constants.  */
246 
247 #define UX_HOST_CLASS_STORAGE_CSW_SIGNATURE                 0
248 #define UX_HOST_CLASS_STORAGE_CSW_TAG                       4
249 #define UX_HOST_CLASS_STORAGE_CSW_DATA_RESIDUE              8
250 #define UX_HOST_CLASS_STORAGE_CSW_STATUS                    12
251 #define UX_HOST_CLASS_STORAGE_CSW_LENGTH                    13
252 
253 
254 /* Define Storage Class SCSI inquiry command constants.  */
255 
256 #define UX_HOST_CLASS_STORAGE_INQUIRY_OPERATION             0
257 #define UX_HOST_CLASS_STORAGE_INQUIRY_LUN                   1
258 #define UX_HOST_CLASS_STORAGE_INQUIRY_PAGE_CODE             2
259 #define UX_HOST_CLASS_STORAGE_INQUIRY_ALLOCATION_LENGTH     4
260 #define UX_HOST_CLASS_STORAGE_INQUIRY_COMMAND_LENGTH_UFI    12
261 #define UX_HOST_CLASS_STORAGE_INQUIRY_COMMAND_LENGTH_SBC    06
262 
263 
264 /* Define Storage Class SCSI inquiry response constants.  */
265 
266 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_PERIPHERAL_TYPE          0
267 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_REMOVABLE_MEDIA          1
268 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_DATA_FORMAT              3
269 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_ADDITIONAL_LENGTH        4
270 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_VENDOR_INFORMATION       8
271 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_PRODUCT_ID               16
272 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_PRODUCT_REVISION         32
273 #define UX_HOST_CLASS_STORAGE_INQUIRY_RESPONSE_LENGTH                   36
274 
275 
276 /* Define Storage Class SCSI start/stop command constants.  */
277 
278 #define UX_HOST_CLASS_STORAGE_START_STOP_OPERATION                      0
279 #define UX_HOST_CLASS_STORAGE_START_STOP_LBUFLAGS                       1
280 #define UX_HOST_CLASS_STORAGE_START_STOP_START_BIT                      4
281 #define UX_HOST_CLASS_STORAGE_START_STOP_COMMAND_LENGTH_UFI             12
282 #define UX_HOST_CLASS_STORAGE_START_STOP_COMMAND_LENGTH_SBC             12
283 
284 
285 /* Define Storage Class SCSI mode sense command constants.  */
286 
287 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_OPERATION                      0
288 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_LUN                            1
289 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_PC_PAGE_CODE                   2
290 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_PARAMETER_LIST_LENGTH          7
291 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_COMMAND_LENGTH_UFI             12
292 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_COMMAND_LENGTH_SBC             12
293 
294 /* Define Storage Class SCSI mode sense command constants.  */
295 
296 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RESPONSE_MODE_DATA_LENGTH      0
297 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RESPONSE_MEDIUM_TYPE_CODE      2
298 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RESPONSE_ATTRIBUTES_SHORT      2
299 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RESPONSE_ATTRIBUTES            3
300 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RESPONSE_ATTRIBUTES_WP         0x80
301 
302 /* Define Storage Class SCSI request sense command constants.  */
303 
304 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_OPERATION                   0
305 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_LUN                         1
306 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_ALLOCATION_LENGTH           4
307 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_COMMAND_LENGTH_UFI          12
308 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_COMMAND_LENGTH_SBC          12
309 
310 
311 /* Define Storage Class request sense response constants.  */
312 
313 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_ERROR_CODE         0
314 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_SENSE_KEY          2
315 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_INFORMATION        3
316 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_ADD_LENGTH         7
317 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_CODE               12
318 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_CODE_QUALIFIER     13
319 #define UX_HOST_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_LENGTH             18
320 
321 
322 /* Define Storage Class read format  command constants.  */
323 
324 #define UX_HOST_CLASS_STORAGE_READ_FORMAT_OPERATION                     0
325 #define UX_HOST_CLASS_STORAGE_READ_FORMAT_LUN                           1
326 #define UX_HOST_CLASS_STORAGE_READ_FORMAT_LBA                           2
327 #define UX_HOST_CLASS_STORAGE_READ_FORMAT_PARAMETER_LIST_LENGTH         7
328 #define UX_HOST_CLASS_STORAGE_READ_FORMAT_COMMAND_LENGTH_UFI            12
329 #define UX_HOST_CLASS_STORAGE_READ_FORMAT_COMMAND_LENGTH_SBC            10
330 #define UX_HOST_CLASS_STORAGE_READ_FORMAT_RESPONSE_LENGTH               0xFC
331 
332 /* Define Storage Class read capacity command constants.  */
333 
334 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_OPERATION                   0
335 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_LUN                         1
336 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_LBA                         2
337 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_COMMAND_LENGTH_UFI          12
338 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_COMMAND_LENGTH_SBC          10
339 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_RESPONSE_LENGTH             8
340 
341 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_DATA_LBA                    0
342 #define UX_HOST_CLASS_STORAGE_READ_CAPACITY_DATA_SECTOR_SIZE            4
343 
344 
345 /* Define Storage Class test unit read command constants.  */
346 
347 #define UX_HOST_CLASS_STORAGE_TEST_READY_OPERATION                      0
348 #define UX_HOST_CLASS_STORAGE_TEST_READY_LUN                            1
349 #define UX_HOST_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_UFI             12
350 #define UX_HOST_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_SBC             6
351 
352 /* Define Storage Class SCSI read command constants.  */
353 
354 #define UX_HOST_CLASS_STORAGE_READ_OPERATION                            0
355 #define UX_HOST_CLASS_STORAGE_READ_LUN                                  1
356 #define UX_HOST_CLASS_STORAGE_READ_LBA                                  2
357 #define UX_HOST_CLASS_STORAGE_READ_TRANSFER_LENGTH                      7
358 #define UX_HOST_CLASS_STORAGE_READ_COMMAND_LENGTH_UFI                   12
359 #define UX_HOST_CLASS_STORAGE_READ_COMMAND_LENGTH_SBC                   10
360 
361 
362 /* Define Storage Class SCSI write command constants.  */
363 
364 #define UX_HOST_CLASS_STORAGE_WRITE_OPERATION                           0
365 #define UX_HOST_CLASS_STORAGE_WRITE_LUN                                 1
366 #define UX_HOST_CLASS_STORAGE_WRITE_LBA                                 2
367 #define UX_HOST_CLASS_STORAGE_WRITE_TRANSFER_LENGTH                     7
368 #define UX_HOST_CLASS_STORAGE_WRITE_COMMAND_LENGTH_UFI                  12
369 #define UX_HOST_CLASS_STORAGE_WRITE_COMMAND_LENGTH_SBC                  10
370 
371 
372 /* Define Storage Class SCSI sense key definition constants.  */
373 
374 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_NO_SENSE                        0x0
375 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_RECOVERED_ERROR                 0x1
376 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_NOT_READY                       0x2
377 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_MEDIUM_ERROR                    0x3
378 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_HARDWARE_ERROR                  0x4
379 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_ILLEGAL_REQUEST                 0x5
380 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_UNIT_ATTENTION                  0x6
381 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_DATA_PROTECT                    0x7
382 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_BLANK_CHECK                     0x8
383 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_ABORTED_COMMAND                 0x0b
384 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_VOLUME_OVERFLOW                 0x0d
385 #define UX_HOST_CLASS_STORAGE_SENSE_KEY_MISCOMPARE                      0x0e
386 
387 #define UX_HOST_CLASS_STORAGE_SENSE_CODE_NOT_READY                      0x04
388 #define UX_HOST_CLASS_STORAGE_SENSE_CODE_WRITE_PROTECTED                0x27
389 #define UX_HOST_CLASS_STORAGE_SENSE_CODE_NOT_READY_TO_READY             0x28
390 #define UX_HOST_CLASS_STORAGE_SENSE_CODE_NOT_PRESENT                    0x3A
391 
392 /* Convertion between sense status and sense key, ASC, ASCQ.  */
393 
394 #define UX_HOST_CLASS_STORAGE_SENSE_STATUS(key,ascode,ascqualifier)     (((key) << 16) | ((ascode) << 8) | (ascqualifier))
395 #define UX_HOST_CLASS_STORAGE_SENSE_QUALIFIER(status)                   ((status) & 0xFF)
396 #define UX_HOST_CLASS_STORAGE_SENSE_CODE(status)                        (((status) >> 8) & 0xFF)
397 #define UX_HOST_CLASS_STORAGE_SENSE_KEY(status)                         (((status) >> 16) & 0xFF)
398 #define UX_HOST_CLASS_STORAGE_SENSE_ASCQ(status)                        UX_HOST_CLASS_STORAGE_SENSE_QUALIFIER(status)
399 #define UX_HOST_CLASS_STORAGE_SENSE_ASC(status)                         UX_HOST_CLASS_STORAGE_SENSE_CODE(status)
400 
401 
402 /* Define Mode Sense page codes. */
403 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RWER_PAGE                      0x01
404 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_FD_PAGE                        0x05
405 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RBAC_PAGE                      0x1B
406 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_TP_PAGE                        0x1C
407 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_ALL_PAGE                       0x3F
408 
409 /* Define Mode Sense page codes response length . */
410 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_HEADER_PAGE_LENGTH             0x08
411 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RWER_PAGE_LENGTH               0x0c
412 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_FD_PAGE_LENGTH                 0x20
413 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_RBAC_PAGE_LENGTH               0x0c
414 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_TP_PAGE_LENGTH                 0x08
415 #define UX_HOST_CLASS_STORAGE_MODE_SENSE_ALL_PAGE_LENGTH                0xC0
416 
417 /* Define Storage Class useful error sense key/code constant.  */
418 
419 #define UX_HOST_CLASS_STORAGE_ERROR_MEDIA_NOT_READ                      0x023A00
420 
421 
422 /* Define Storage Class MS-DOS partition entry constants.  */
423 
424 #define UX_HOST_CLASS_STORAGE_PARTITION_SIGNATURE                       0xaa55
425 #define UX_HOST_CLASS_STORAGE_PARTITION_TABLE_START                     446
426 
427 #define UX_HOST_CLASS_STORAGE_PARTITION_BOOT_FLAG                       0
428 #define UX_HOST_CLASS_STORAGE_PARTITION_START_HEAD                      1
429 #define UX_HOST_CLASS_STORAGE_PARTITION_START_SECTOR                    2
430 #define UX_HOST_CLASS_STORAGE_PARTITION_START_TRACK                     3
431 #define UX_HOST_CLASS_STORAGE_PARTITION_TYPE                            4
432 #define UX_HOST_CLASS_STORAGE_PARTITION_END_HEAD                        5
433 #define UX_HOST_CLASS_STORAGE_PARTITION_END_SECTOR                      6
434 #define UX_HOST_CLASS_STORAGE_PARTITION_END_TRACK                       7
435 #define UX_HOST_CLASS_STORAGE_PARTITION_SECTORS_BEFORE                  8
436 #define UX_HOST_CLASS_STORAGE_PARTITION_NUMBER_SECTORS                  12
437 #define UX_HOST_CLASS_STORAGE_PARTITION_TABLE_SIZE                      16
438 
439 #define UX_HOST_CLASS_STORAGE_PARTITION_FAT_12                          1
440 #define UX_HOST_CLASS_STORAGE_PARTITION_FAT_16                          4
441 #define UX_HOST_CLASS_STORAGE_PARTITION_EXTENDED                        5
442 #define UX_HOST_CLASS_STORAGE_PARTITION_FAT_16L                         6
443 #define UX_HOST_CLASS_STORAGE_PARTITION_EXFAT                           7
444 #define UX_HOST_CLASS_STORAGE_PARTITION_FAT_32_1                        0x0b
445 #define UX_HOST_CLASS_STORAGE_PARTITION_FAT_32_2                        0x0c
446 #define UX_HOST_CLASS_STORAGE_PARTITION_FAT_16_LBA_MAPPED               0x0e
447 #define UX_HOST_CLASS_STORAGE_PARTITION_EXTENDED_LBA_MAPPED             0x0f
448 
449 /* Define Storage Class instance structure.  */
450 
451 #define UX_HOST_CLASS_STORAGE_CBW_LENGTH                        31
452 #define UX_HOST_CLASS_STORAGE_CSW_LENGTH                        13
453 #define UX_HOST_CLASS_STORAGE_CBW_LENGTH_ALIGNED                32
454 #define UX_HOST_CLASS_STORAGE_CSW_LENGTH_ALIGNED                16
455 
456 
457 typedef struct UX_HOST_CLASS_STORAGE_STRUCT
458 {
459 
460     struct UX_HOST_CLASS_STORAGE_STRUCT
461                     *ux_host_class_storage_next_instance;
462     UX_HOST_CLASS   *ux_host_class_storage_class;
463     UX_DEVICE       *ux_host_class_storage_device;
464     UX_INTERFACE    *ux_host_class_storage_interface;
465     UX_ENDPOINT     *ux_host_class_storage_bulk_out_endpoint;
466     UX_ENDPOINT     *ux_host_class_storage_bulk_in_endpoint;
467     UX_ENDPOINT     *ux_host_class_storage_interrupt_endpoint;
468     UCHAR           ux_host_class_storage_cbw[UX_HOST_CLASS_STORAGE_CBW_LENGTH_ALIGNED];
469     UCHAR           ux_host_class_storage_saved_cbw[UX_HOST_CLASS_STORAGE_CBW_LENGTH_ALIGNED];
470     UCHAR           ux_host_class_storage_csw[UX_HOST_CLASS_STORAGE_CSW_LENGTH_ALIGNED];
471     UINT            ux_host_class_storage_state;
472     UINT            ux_host_class_storage_media_type;
473     UINT            ux_host_class_storage_lun_removable_media_flags[UX_MAX_HOST_LUN];
474     UINT            ux_host_class_storage_write_protected_media;
475     UINT            ux_host_class_storage_max_lun;
476     UINT            ux_host_class_storage_lun;
477     UINT            ux_host_class_storage_lun_types[UX_MAX_HOST_LUN];
478 #if defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
479     ULONG           ux_host_class_storage_last_sector_number;
480 #endif
481     ULONG           ux_host_class_storage_sector_size;
482     ULONG           ux_host_class_storage_data_phase_length;
483     ULONG           ux_host_class_storage_sense_code;
484     UCHAR           *ux_host_class_storage_memory;
485 #if !defined(UX_HOST_STANDALONE)
486     UINT            (*ux_host_class_storage_transport) (struct UX_HOST_CLASS_STORAGE_STRUCT *storage, UCHAR * data_pointer);
487     UX_SEMAPHORE    ux_host_class_storage_semaphore;
488 #else
489     ULONG           ux_host_class_storage_flags;
490     UINT            ux_host_class_storage_status;
491     UCHAR           *ux_host_class_storage_sense_memory;
492 
493     /* State info for transport state machine.  */
494     UX_TRANSFER     *ux_host_class_storage_trans;
495     UCHAR           *ux_host_class_storage_trans_data;
496     UCHAR           *ux_host_class_storage_trans_data_bak;
497     UCHAR           ux_host_class_storage_trans_state;
498     UCHAR           ux_host_class_storage_trans_stage;
499     UCHAR           ux_host_class_storage_trans_retry;
500     UCHAR           ux_host_class_storage_trans_status;
501 
502     /* State info for media main state machine.  */
503     ULONG           ux_host_class_storage_delay_start;
504     ULONG           ux_host_class_storage_delay_ms;
505     UCHAR           ux_host_class_storage_state_state;
506     UCHAR           ux_host_class_storage_state_next;
507     UCHAR           ux_host_class_storage_check_lun;
508     UCHAR           ux_host_class_storage_op_state;
509     UCHAR           ux_host_class_storage_dbg_state;
510     UCHAR           ux_host_class_storage_dbg_rw_state;
511     UCHAR           ux_host_class_storage_dbg_trans_state;
512     UCHAR           ux_host_class_storage_dbg_trans_stage;
513     ULONG           ux_host_class_storage_dbg_state_count;
514     ULONG           ux_host_class_storage_dbg_rw_state_count;
515     ULONG           ux_host_class_storage_dbg_trans_state_count;
516 
517 #endif
518 } UX_HOST_CLASS_STORAGE;
519 
520 #define UX_HOST_CLASS_STORAGE_FLAG_PROTECT              (1ul << 0)
521 #define UX_HOST_CLASS_STORAGE_FLAG_LOCK                 (1ul << 1)
522 #define UX_HOST_CLASS_STORAGE_FLAG_CHECK_CURRENT        (1ul << 2)
523 
524 /* Read/write states.  */
525 
526 #define UX_HOST_CLASS_STORAGE_RW_STATE_RESET(s)         ((s) -> ux_host_class_storage_op_state = UX_STATE_RESET)
527 #define UX_HOST_CLASS_STORAGE_RW_STATE_IS_IDLE(s)       ((s) -> ux_host_class_storage_op_state == UX_STATE_IDLE)
528 #define UX_HOST_CLASS_STORAGE_RW_STATE_IS_RESET(s)      ((s) -> ux_host_class_storage_op_state == UX_STATE_RESET)
529 #define UX_HOST_CLASS_STORAGE_RW_IS_IDLE(s)             (UX_HOST_CLASS_STORAGE_RW_STATE_IS_IDLE(s) || UX_HOST_CLASS_STORAGE_RW_STATE_IS_RESET(s))
530 
531 /* Main states.  */
532 
533 #define UX_HOST_CLASS_STORAGE_STATE_MAX_LUN_GET         (UX_STATE_CLASS_STEP + 0)
534 #define UX_HOST_CLASS_STORAGE_STATE_MAX_LUN_SAVE        (UX_STATE_CLASS_STEP + 1)
535 #define UX_HOST_CLASS_STORAGE_STATE_CHECK_START         (UX_STATE_CLASS_STEP + 2)
536 #define UX_HOST_CLASS_STORAGE_STATE_LOCK_WAIT           (UX_STATE_CLASS_STEP + 3)
537 #define UX_HOST_CLASS_STORAGE_STATE_TEST_READY          (UX_STATE_CLASS_STEP + 4)
538 #define UX_HOST_CLASS_STORAGE_STATE_TEST_CHECK          (UX_STATE_CLASS_STEP + 5)
539 #define UX_HOST_CLASS_STORAGE_STATE_INQUIRY             (UX_STATE_CLASS_STEP + 6)
540 #define UX_HOST_CLASS_STORAGE_STATE_INQUIRY_SAVE        (UX_STATE_CLASS_STEP + 7)
541 #define UX_HOST_CLASS_STORAGE_STATE_FORMAT_CAP_GET      (UX_STATE_CLASS_STEP + 8)
542 #define UX_HOST_CLASS_STORAGE_STATE_FORMAT_CAP_SAVE     (UX_STATE_CLASS_STEP + 9)
543 #define UX_HOST_CLASS_STORAGE_STATE_CAP_GET             (UX_STATE_CLASS_STEP + 10)
544 #define UX_HOST_CLASS_STORAGE_STATE_CAP_SAVE            (UX_STATE_CLASS_STEP + 11)
545 #define UX_HOST_CLASS_STORAGE_STATE_NEXT_LUN            (UX_STATE_CLASS_STEP + 12)
546 #define UX_HOST_CLASS_STORAGE_STATE_DELAY_WAIT          (UX_STATE_CLASS_STEP + 13)
547 #define UX_HOST_CLASS_STORAGE_STATE_TRANSPORT           (UX_STATE_CLASS_STEP + 14)
548 #define UX_HOST_CLASS_STORAGE_STATE_TRANSFER            (UX_STATE_CLASS_STEP + 15)
549 #define UX_HOST_CLASS_STORAGE_STATE_CHECK_DONE          (UX_STATE_CLASS_STEP + 16)
550 
551 /* Transport states.  */
552 
553 #define UX_HOST_CLASS_STORAGE_TRANS_STATE_RESET(s)      do {                    \
554         (s) -> ux_host_class_storage_trans_state = UX_STATE_RESET;              \
555         (s) -> ux_host_class_storage_trans_data = UX_NULL;                      \
556     } while(0)                                                                  \
557 
558 #define UX_HOST_CLASS_STORAGE_TRANS_CBW                 (UX_STATE_CLASS_STEP + 0)
559 #define UX_HOST_CLASS_STORAGE_TRANS_IN_NEXT             (UX_STATE_CLASS_STEP + 1)
560 #define UX_HOST_CLASS_STORAGE_TRANS_OUT_NEXT            (UX_STATE_CLASS_STEP + 2)
561 #define UX_HOST_CLASS_STORAGE_TRANS_CSW                 (UX_STATE_CLASS_STEP + 3)
562 #define UX_HOST_CLASS_STORAGE_TRANS_REQ_SENSE           (UX_STATE_CLASS_STEP + 4)
563 #define UX_HOST_CLASS_STORAGE_TRANS_WAIT                (UX_STATE_CLASS_STEP + 5)
564 #define UX_HOST_CLASS_STORAGE_TRANS_STATUS              (UX_STATE_CLASS_STEP + 6)
565 #define UX_HOST_CLASS_STORAGE_TRANS_MS_RESET            (UX_STATE_CLASS_STEP + 7)
566 #define UX_HOST_CLASS_STORAGE_TRANS_EP_RESET            (UX_STATE_CLASS_STEP + 8)
567 #define UX_HOST_CLASS_STORAGE_TRANS_RESET_NEXT          (UX_STATE_CLASS_STEP + 9)
568 
569 #define UX_HOST_CLASS_STORAGE_STAGE_CBW                 (0x00u)
570 #define UX_HOST_CLASS_STORAGE_STAGE_DATA                (0x01u)
571 #define UX_HOST_CLASS_STORAGE_STAGE_CSW                 (0x02u)
572 #define UX_HOST_CLASS_STORAGE_STAGE_MS_RESET            (0x04u)
573 #define UX_HOST_CLASS_STORAGE_STAGE_EP_RESET            (0x08u)
574 
575 typedef struct UX_HOST_CLASS_STORAGE_EXT_STRUCT
576 {
577 #if !defined(UX_HOST_STANDALONE)
578     UX_THREAD       ux_host_class_thread;
579     CHAR            ux_host_class_thread_stack[UX_HOST_CLASS_STORAGE_THREAD_STACK_SIZE];
580 #else
581     ALIGN_TYPE      reserved;
582 #endif
583 } UX_HOST_CLASS_STORAGE_EXT;
584 
585 
586 /* Define Host Storage Class Media structure.  */
587 
588 typedef struct UX_HOST_CLASS_STORAGE_MEDIA_STRUCT
589 {
590 
591 #if !defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
592     UX_MEDIA        ux_host_class_storage_media;
593     ULONG           ux_host_class_storage_media_partition_start;
594     VOID            *ux_host_class_storage_media_memory;
595     ULONG           ux_host_class_storage_media_status;
596     ULONG           ux_host_class_storage_media_lun;
597     ULONG           ux_host_class_storage_media_sector_size;
598 #else
599     struct UX_HOST_CLASS_STORAGE_STRUCT
600                     *ux_host_class_storage_media_storage;
601     ULONG           ux_host_class_storage_media_number_sectors;
602     USHORT          ux_host_class_storage_media_sector_size;
603     UCHAR           ux_host_class_storage_media_lun;
604     UCHAR           ux_host_class_storage_media_status;
605 #endif
606 
607 } UX_HOST_CLASS_STORAGE_MEDIA;
608 
609 
610 /* Define Storage Class function prototypes.  */
611 
612 UINT    _ux_host_class_storage_activate(UX_HOST_CLASS_COMMAND *command);
613 VOID    _ux_host_class_storage_cbw_initialize(UX_HOST_CLASS_STORAGE *storage, UINT flags,
614                                        ULONG data_transfer_length, UINT command_length);
615 UINT    _ux_host_class_storage_configure(UX_HOST_CLASS_STORAGE *storage);
616 UINT    _ux_host_class_storage_deactivate(UX_HOST_CLASS_COMMAND *command);
617 UINT    _ux_host_class_storage_device_initialize(UX_HOST_CLASS_STORAGE *storage);
618 UINT    _ux_host_class_storage_device_reset(UX_HOST_CLASS_STORAGE *storage);
619 UINT    _ux_host_class_storage_device_support_check(UX_HOST_CLASS_STORAGE *storage);
620 
621 #if !defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
622 VOID    _ux_host_class_storage_driver_entry(UX_MEDIA *media);
623 #endif
624 
625 UINT    _ux_host_class_storage_endpoints_get(UX_HOST_CLASS_STORAGE *storage);
626 UINT    _ux_host_class_storage_entry(UX_HOST_CLASS_COMMAND *command);
627 UINT    _ux_host_class_storage_max_lun_get(UX_HOST_CLASS_STORAGE *storage);
628 UINT    _ux_host_class_storage_media_capacity_get(UX_HOST_CLASS_STORAGE *storage);
629 UINT    _ux_host_class_storage_media_characteristics_get(UX_HOST_CLASS_STORAGE *storage);
630 UINT    _ux_host_class_storage_media_format_capacity_get(UX_HOST_CLASS_STORAGE *storage);
631 UINT    _ux_host_class_storage_media_mount(UX_HOST_CLASS_STORAGE *storage, ULONG sector);
632 UINT    _ux_host_class_storage_media_open(UX_HOST_CLASS_STORAGE *storage, ULONG hidden_sectors);
633 UINT    _ux_host_class_storage_media_protection_check(UX_HOST_CLASS_STORAGE *storage);
634 UINT    _ux_host_class_storage_media_read(UX_HOST_CLASS_STORAGE *storage, ULONG sector_start,
635                                         ULONG sector_count, UCHAR *data_pointer);
636 UINT    _ux_host_class_storage_media_recovery_sense_get(UX_HOST_CLASS_STORAGE *storage);
637 UINT    _ux_host_class_storage_media_write(UX_HOST_CLASS_STORAGE *storage, ULONG sector_start,
638                                         ULONG sector_count, UCHAR *data_pointer);
639 UINT    _ux_host_class_storage_partition_read(UX_HOST_CLASS_STORAGE *storage, UCHAR *sector_memory, ULONG sector);
640 UINT    _ux_host_class_storage_request_sense(UX_HOST_CLASS_STORAGE *storage);
641 UINT    _ux_host_class_storage_sense_code_translate(UX_HOST_CLASS_STORAGE *storage, UINT status);
642 UINT    _ux_host_class_storage_start_stop(UX_HOST_CLASS_STORAGE *storage,
643                                             ULONG start_stop_signal);
644 VOID    _ux_host_class_storage_thread_entry(ULONG class_address);
645 UINT    _ux_host_class_storage_transport(UX_HOST_CLASS_STORAGE *storage, UCHAR *data_pointer);
646 UINT    _ux_host_class_storage_transport_bo(UX_HOST_CLASS_STORAGE *storage, UCHAR *data_pointer);
647 UINT    _ux_host_class_storage_transport_cb(UX_HOST_CLASS_STORAGE *storage, UCHAR *data_pointer);
648 UINT    _ux_host_class_storage_transport_cbi(UX_HOST_CLASS_STORAGE *storage, UCHAR *data_pointer);
649 UINT    _ux_host_class_storage_unit_ready_test(UX_HOST_CLASS_STORAGE *storage);
650 
651 UINT    _ux_host_class_storage_media_get(UX_HOST_CLASS_STORAGE *storage, ULONG media_lun, UX_HOST_CLASS_STORAGE_MEDIA **storage_media);
652 UINT    _ux_host_class_storage_media_lock(UX_HOST_CLASS_STORAGE_MEDIA *storage_media, ULONG wait);
653 
654 #if defined(UX_HOST_STANDALONE)
655 UINT    _ux_host_class_storage_lock(UX_HOST_CLASS_STORAGE *storage, ULONG wait);
656 #define _ux_host_class_storage_unlock(s) do { (s) -> ux_host_class_storage_flags &= ~UX_HOST_CLASS_STORAGE_FLAG_LOCK; } while(0)
657 #define _ux_host_class_storage_media_unlock(m) _ux_host_class_storage_unlock((m) -> ux_host_class_storage_media_storage)
658 #else
659 #define _ux_host_class_storage_lock(s,w) _ux_host_semaphore_get(&(s) -> ux_host_class_storage_semaphore, (w))
660 #define _ux_host_class_storage_unlock(s) _ux_host_semaphore_put(&(s) -> ux_host_class_storage_semaphore)
661 #define _ux_host_class_storage_media_unlock(m) _ux_host_class_storage_unlock((m) -> ux_host_class_storage_media_storage)
662 #endif
663 #define _ux_host_class_storage_max_lun(s)           ((s) -> ux_host_class_storage_max_lun)
664 #define _ux_host_class_storage_lun(s)               ((s) -> ux_host_class_storage_lun)
665 #define _ux_host_class_storage_lun_select(s,l)      do { (s) -> ux_host_class_storage_lun = (l); } while(0)
666 #define _ux_host_class_storage_sense_status(s)      ((s) -> ux_host_class_storage_sense_code)
667 
668 UINT    _ux_host_class_storage_media_check(UX_HOST_CLASS_STORAGE *storage);
669 
670 UINT    _ux_host_class_storage_tasks_run(UX_HOST_CLASS *storage_class);
671 UINT    _ux_host_class_storage_transport_run(UX_HOST_CLASS_STORAGE *storage);
672 UINT    _ux_host_class_storage_check_run(UX_HOST_CLASS_STORAGE *storage);
673 UINT    _ux_host_class_storage_read_write_run(UX_HOST_CLASS_STORAGE *storage,
674                     ULONG read_write, ULONG sector_start, ULONG sector_count, UCHAR *data_pointer);
675 
676 /* Define Storage Class API prototypes.  */
677 
678 #define  ux_host_class_storage_entry                           _ux_host_class_storage_entry
679 
680 #define  ux_host_class_storage_lock                            _ux_host_class_storage_lock
681 #define  ux_host_class_storage_unlock                          _ux_host_class_storage_unlock
682 #define  ux_host_class_storage_lun_select                      _ux_host_class_storage_lun_select
683 
684 #define  ux_host_class_storage_media_read                      _ux_host_class_storage_media_read
685 #define  ux_host_class_storage_media_write                     _ux_host_class_storage_media_write
686 
687 #define  ux_host_class_storage_media_get                       _ux_host_class_storage_media_get
688 #define  ux_host_class_storage_media_lock                      _ux_host_class_storage_media_lock
689 #define  ux_host_class_storage_media_unlock                    _ux_host_class_storage_media_unlock
690 
691 #define  ux_host_class_storage_media_check                     _ux_host_class_storage_media_check
692 
693 #define  ux_host_class_storage_sense_status                    _ux_host_class_storage_sense_status
694 
695 /* Determine if a C++ compiler is being used.  If so, complete the standard
696    C conditional started above.  */
697 #ifdef __cplusplus
698 }
699 #endif
700 
701 #endif
702