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 /**   Device Storage Class                                                */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 
24 /**************************************************************************/
25 /*                                                                        */
26 /*  COMPONENT DEFINITION                                   RELEASE        */
27 /*                                                                        */
28 /*    ux_device_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 device 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 /*                                            optimized command logic,    */
46 /*                                            resulting in version 6.1    */
47 /*  12-31-2020     Chaoqiong Xiao           Modified comment(s),          */
48 /*                                            fixed USB CV test issues,   */
49 /*                                            resulting in version 6.1.3  */
50 /*  08-02-2021     Chaoqiong Xiao           Modified comment(s),          */
51 /*                                            added extern "C" keyword    */
52 /*                                            for compatibility with C++, */
53 /*                                            resulting in version 6.1.8  */
54 /*  10-15-2021     Chaoqiong Xiao           Modified comment(s),          */
55 /*                                            improved TAG management,    */
56 /*                                            resulting in version 6.1.9  */
57 /*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
58 /*                                            added standalone support,   */
59 /*                                            resulting in version 6.1.10 */
60 /*                                                                        */
61 /**************************************************************************/
62 
63 #ifndef UX_DEVICE_CLASS_STORAGE_H
64 #define UX_DEVICE_CLASS_STORAGE_H
65 
66 /* Determine if a C++ compiler is being used.  If so, ensure that standard
67    C is used to process the API information.  */
68 
69 #ifdef   __cplusplus
70 
71 /* Yes, C++ compiler is present.  Use standard C.  */
72 extern   "C" {
73 
74 #endif
75 
76 /* Define User configurable Storage Class constants.  */
77 
78 #ifndef UX_MAX_SLAVE_LUN
79 #define UX_MAX_SLAVE_LUN                                            2
80 #endif
81 
82 
83 /* Define Storage Class USB Class constants.  */
84 
85 #define UX_SLAVE_CLASS_STORAGE_CLASS                                8
86 #define UX_SLAVE_CLASS_STORAGE_SUBCLASS_RBC                         1
87 #define UX_SLAVE_CLASS_STORAGE_SUBCLASS_SFF8020                     2
88 #define UX_SLAVE_CLASS_STORAGE_SUBCLASS_UFI                         4
89 #define UX_SLAVE_CLASS_STORAGE_SUBCLASS_SFF8070                     5
90 #define UX_SLAVE_CLASS_STORAGE_SUBCLASS_SCSI                        6
91 #define UX_SLAVE_CLASS_STORAGE_PROTOCOL_CBI                         0
92 #define UX_SLAVE_CLASS_STORAGE_PROTOCOL_CB                          1
93 #define UX_SLAVE_CLASS_STORAGE_PROTOCOL_BO                          0x50
94 
95 /* Define Storage Class USB MEDIA types.  */
96 #define UX_SLAVE_CLASS_STORAGE_MEDIA_FAT_DISK                       0
97 #define UX_SLAVE_CLASS_STORAGE_MEDIA_CDROM                          5
98 #define UX_SLAVE_CLASS_STORAGE_MEDIA_OPTICAL_DISK                   7
99 #define UX_SLAVE_CLASS_STORAGE_MEDIA_IOMEGA_CLICK                   0x55
100 
101 
102 
103 /* Define Storage Class SCSI command constants.  */
104 
105 #define UX_SLAVE_CLASS_STORAGE_SCSI_TEST_READY                      0x00
106 #define UX_SLAVE_CLASS_STORAGE_SCSI_REQUEST_SENSE                   0x03
107 #define UX_SLAVE_CLASS_STORAGE_SCSI_FORMAT                          0x04
108 #define UX_SLAVE_CLASS_STORAGE_SCSI_INQUIRY                         0x12
109 #define UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE_SHORT                0x1a
110 #define UX_SLAVE_CLASS_STORAGE_SCSI_START_STOP                      0x1b
111 #define UX_SLAVE_CLASS_STORAGE_SCSI_PREVENT_ALLOW_MEDIA_REMOVAL     0x1e
112 #define UX_SLAVE_CLASS_STORAGE_SCSI_READ_FORMAT_CAPACITY            0x23
113 #define UX_SLAVE_CLASS_STORAGE_SCSI_READ_CAPACITY                   0x25
114 #define UX_SLAVE_CLASS_STORAGE_SCSI_READ16                          0x28
115 #define UX_SLAVE_CLASS_STORAGE_SCSI_WRITE16                         0x2a
116 #define UX_SLAVE_CLASS_STORAGE_SCSI_VERIFY                          0x2f
117 #define UX_SLAVE_CLASS_STORAGE_SCSI_SYNCHRONIZE_CACHE               0x35
118 #define UX_SLAVE_CLASS_STORAGE_SCSI_READ_TOC                        0x43
119 #define UX_SLAVE_CLASS_STORAGE_SCSI_GET_CONFIGURATION               0x46
120 #define UX_SLAVE_CLASS_STORAGE_SCSI_GET_STATUS_NOTIFICATION         0x4A
121 #define UX_SLAVE_CLASS_STORAGE_SCSI_READ_DISK_INFORMATION           0x51
122 #define UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SELECT                     0x55
123 #define UX_SLAVE_CLASS_STORAGE_SCSI_MODE_SENSE                      0x5a
124 #define UX_SLAVE_CLASS_STORAGE_SCSI_READ32                          0xa8
125 #define UX_SLAVE_CLASS_STORAGE_SCSI_REPORT_KEY                      0xa4
126 #define UX_SLAVE_CLASS_STORAGE_SCSI_WRITE32                         0xaa
127 #define UX_SLAVE_CLASS_STORAGE_SCSI_GET_PERFORMANCE                 0xac
128 #define UX_SLAVE_CLASS_STORAGE_SCSI_READ_DVD_STRUCTURE              0xad
129 
130 /* Define Storage Class SCSI command block wrapper constants.  */
131 
132 #define UX_SLAVE_CLASS_STORAGE_CBW_SIGNATURE_MASK                   0x43425355
133 #define UX_SLAVE_CLASS_STORAGE_CBW_SIGNATURE                        0
134 #define UX_SLAVE_CLASS_STORAGE_CBW_TAG                              4
135 #define UX_SLAVE_CLASS_STORAGE_CBW_DATA_LENGTH                      8
136 #define UX_SLAVE_CLASS_STORAGE_CBW_FLAGS                            12
137 #define UX_SLAVE_CLASS_STORAGE_CBW_LUN                              13
138 #define UX_SLAVE_CLASS_STORAGE_CBW_CB_LENGTH                        14
139 #define UX_SLAVE_CLASS_STORAGE_CBW_CB                               15
140 #define UX_SLAVE_CLASS_STORAGE_CBW_LENGTH                           31
141 
142 #define UX_DEVICE_CLASS_STORAGE_CBW_FLAG_DIR                        (1u<<7)
143 #define UX_DEVICE_CLASS_STORAGE_CBW_FLAG_IN                         (1u<<7)
144 #define UX_DEVICE_CLASS_STORAGE_CBW_FLAG_D2H                        (1u<<7)
145 #define UX_DEVICE_CLASS_STORAGE_CBW_FLAG_OUT                        (0u)
146 #define UX_DEVICE_CLASS_STORAGE_CBW_FLAG_H2D                        (0u)
147 
148 
149 /* Define Storage Class SCSI response status wrapper constants.  */
150 
151 #define UX_SLAVE_CLASS_STORAGE_CSW_SIGNATURE_MASK                   0x53425355
152 #define UX_SLAVE_CLASS_STORAGE_CSW_SIGNATURE                        0
153 #define UX_SLAVE_CLASS_STORAGE_CSW_TAG                              4
154 #define UX_SLAVE_CLASS_STORAGE_CSW_DATA_RESIDUE                     8
155 #define UX_SLAVE_CLASS_STORAGE_CSW_STATUS                           12
156 #define UX_SLAVE_CLASS_STORAGE_CSW_LENGTH                           13
157 
158 
159 /* Define Storage Class SCSI inquiry command constants.  */
160 
161 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_OPERATION                    0
162 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_LUN                          1
163 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_PAGE_CODE                    2
164 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_ALLOCATION_LENGTH            4
165 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_COMMAND_LENGTH_UFI           12
166 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_COMMAND_LENGTH_SBC           06
167 
168 
169 /* Define Storage Class SCSI inquiry response constants.  */
170 
171 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_PERIPHERAL_TYPE     0
172 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_REMOVABLE_MEDIA     1
173 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_DATA_FORMAT         3
174 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_ADDITIONAL_LENGTH   4
175 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_VENDOR_INFORMATION  8
176 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_PRODUCT_ID          16
177 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_PRODUCT_REVISION    32
178 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_LENGTH              36
179 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_RESPONSE_LENGTH_CD_ROM       0x5b
180 
181 
182 /* Define Storage Class SCSI start/stop command constants.  */
183 
184 #define UX_SLAVE_CLASS_STORAGE_START_STOP_OPERATION                 0
185 #define UX_SLAVE_CLASS_STORAGE_START_STOP_LBUFLAGS                  1
186 #define UX_SLAVE_CLASS_STORAGE_START_STOP_START_BIT                 4
187 #define UX_SLAVE_CLASS_STORAGE_START_STOP_COMMAND_LENGTH_UFI        12
188 #define UX_SLAVE_CLASS_STORAGE_START_STOP_COMMAND_LENGTH_SBC        6
189 
190 
191 /* Define Storage Class SCSI mode sense command constants.  */
192 
193 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_OPERATION                  0
194 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_LUN                        1
195 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PC_PAGE_CODE               2
196 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_LIST_LENGTH_6    4
197 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_LIST_LENGTH_10   7
198 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_ALLOCATION_LENGTH_6        4
199 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_ALLOCATION_LENGTH_10       7
200 
201 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_MEDIUM_TYPE_6    1
202 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_MEDIUM_TYPE_10   2
203 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_FLAGS_6          2
204 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_FLAGS_10         3
205 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_FLAG_WP          0x80
206 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_HEADER_LENGTH_6  4
207 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_PARAMETER_HEADER_LENGTH_10 8
208 
209 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_COMMAND_LENGTH_UFI         12
210 #define UX_SLAVE_CLASS_STORAGE_MODE_SENSE_COMMAND_LENGTH_SBC         12
211 
212 #define UX_SLAVE_CLASS_STORAGE_IEC_MODE_PAGE_PAGE_LENGTH             0x0A
213 
214 #define UX_SLAVE_CLASS_STORAGE_CACHING_MODE_PAGE_PAGE_LENGTH         0x12
215 #define UX_SLAVE_CLASS_STORAGE_CACHING_MODE_PAGE_CODE                0
216 #define UX_SLAVE_CLASS_STORAGE_CACHING_MODE_PAGE_LENGTH              1
217 #define UX_SLAVE_CLASS_STORAGE_CACHING_MODE_PAGE_FLAGS               2
218 #define UX_SLAVE_CLASS_STORAGE_CACHING_MODE_PAGE_FLAG_WCE            (1u<<2)
219 
220 
221 /* Define Storage Class SCSI request sense command constants.  */
222 
223 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_OPERATION              0
224 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_LUN                    1
225 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_ALLOCATION_LENGTH      4
226 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_COMMAND_LENGTH_UFI     12
227 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_COMMAND_LENGTH_SBC     12
228 
229 
230 /* Define Storage Class request sense response constants.  */
231 
232 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_ERROR_CODE     0
233 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_SENSE_KEY      2
234 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_INFORMATION    3
235 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_ADD_LENGTH     7
236 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_CODE           12
237 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_CODE_QUALIFIER 13
238 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_LENGTH         18
239 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_HEADER_LENGTH  8
240 
241 
242 /* Define Storage Class read capacity command constants.  */
243 
244 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_OPERATION              0
245 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_LUN                    1
246 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_LBA                    2
247 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_COMMAND_LENGTH_UFI     12
248 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_COMMAND_LENGTH_SBC     10
249 
250 
251 /* Define Storage Class read capacity response constants.  */
252 
253 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_RESPONSE_LAST_LBA      0
254 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_RESPONSE_BLOCK_SIZE    4
255 #define UX_SLAVE_CLASS_STORAGE_READ_CAPACITY_RESPONSE_LENGTH        8
256 
257 /* Define Storage Class read capacity response constants.  */
258 
259 #define UX_SLAVE_CLASS_STORAGE_READ_FORMAT_CAPACITY_RESPONSE_SIZE           0
260 #define UX_SLAVE_CLASS_STORAGE_READ_FORMAT_CAPACITY_RESPONSE_LAST_LBA       4
261 #define UX_SLAVE_CLASS_STORAGE_READ_FORMAT_CAPACITY_RESPONSE_DESC_CODE      8
262 #define UX_SLAVE_CLASS_STORAGE_READ_FORMAT_CAPACITY_RESPONSE_BLOCK_SIZE     8
263 #define UX_SLAVE_CLASS_STORAGE_READ_FORMAT_CAPACITY_RESPONSE_LENGTH         12
264 
265 /* Define Storage Class test unit read command constants.  */
266 
267 #define UX_SLAVE_CLASS_STORAGE_TEST_READY_OPERATION                 0
268 #define UX_SLAVE_CLASS_STORAGE_TEST_READY_LUN                       1
269 #define UX_SLAVE_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_UFI        12
270 #define UX_SLAVE_CLASS_STORAGE_TEST_READY_COMMAND_LENGTH_SBC        6
271 
272 
273 /* Define Storage Class SCSI read command constants.  */
274 
275 #define UX_SLAVE_CLASS_STORAGE_READ_OPERATION                       0
276 #define UX_SLAVE_CLASS_STORAGE_READ_LUN                             1
277 #define UX_SLAVE_CLASS_STORAGE_READ_LBA                             2
278 #define UX_SLAVE_CLASS_STORAGE_READ_TRANSFER_LENGTH_32              6
279 #define UX_SLAVE_CLASS_STORAGE_READ_TRANSFER_LENGTH_16              7
280 #define UX_SLAVE_CLASS_STORAGE_READ_COMMAND_LENGTH_UFI              12
281 #define UX_SLAVE_CLASS_STORAGE_READ_COMMAND_LENGTH_SBC              10
282 
283 
284 /* Define Storage Class SCSI write command constants.  */
285 
286 #define UX_SLAVE_CLASS_STORAGE_WRITE_OPERATION                      0
287 #define UX_SLAVE_CLASS_STORAGE_WRITE_LUN                            1
288 #define UX_SLAVE_CLASS_STORAGE_WRITE_LBA                            2
289 #define UX_SLAVE_CLASS_STORAGE_WRITE_TRANSFER_LENGTH_32             6
290 #define UX_SLAVE_CLASS_STORAGE_WRITE_TRANSFER_LENGTH_16             7
291 #define UX_SLAVE_CLASS_STORAGE_WRITE_COMMAND_LENGTH_UFI             12
292 #define UX_SLAVE_CLASS_STORAGE_WRITE_COMMAND_LENGTH_SBC             10
293 
294 
295 /* Define Storage Class SCSI sense key definition constants.  */
296 
297 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_NO_SENSE                   0x0
298 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_RECOVERED_ERROR            0x1
299 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_NOT_READY                  0x2
300 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_MEDIUM_ERROR               0x3
301 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_HARDWARE_ERROR             0x4
302 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_ILLEGAL_REQUEST            0x5
303 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_UNIT_ATTENTION             0x6
304 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_DATA_PROTECT               0x7
305 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_BLANK_CHECK                0x8
306 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_ABORTED_COMMAND            0x0b
307 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_VOLUME_OVERFLOW            0x0d
308 #define UX_SLAVE_CLASS_STORAGE_SENSE_KEY_MISCOMPARE                 0x0e
309 
310 
311 /* Define Storage Class SCSI sense key definition constants.  */
312 
313 #define UX_SLAVE_CLASS_STORAGE_REQUEST_CODE_MEDIA_PROTECTED         0x27
314 
315 /* Define Storage Class SCSI GET CONFIGURATION command constants.  */
316 
317 #define UX_SLAVE_CLASS_STORAGE_GET_CONFIGURATION_OPERATION              0
318 #define UX_SLAVE_CLASS_STORAGE_GET_CONFIGURATION_RT                     1
319 #define UX_SLAVE_CLASS_STORAGE_GET_CONFIGURATION_STARTING_FEATURE       2
320 #define UX_SLAVE_CLASS_STORAGE_GET_CONFIGURATION_ALLOCATION_LENGTH      7
321 #define UX_SLAVE_CLASS_STORAGE_GET_CONFIGURATION_COMMAND_LENGTH_SBC     9
322 
323 /* Define Storage Class SCSI ASC return codes.  */
324 #define UX_SLAVE_CLASS_STORAGE_ASC_KEY_INVALID_COMMAND              0x20
325 
326 /* Define Storage Class CSW status.  */
327 
328 #define UX_SLAVE_CLASS_STORAGE_CSW_PASSED                           0
329 #define UX_SLAVE_CLASS_STORAGE_CSW_FAILED                           1
330 #define UX_SLAVE_CLASS_STORAGE_CSW_PHASE_ERROR                      2
331 
332 /* Define generic SCSI values.  */
333 
334 #define UX_SLAVE_CLASS_STORAGE_REQUEST_SENSE_RESPONSE_ERROR_CODE_VALUE  0x70
335 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_PAGE_CODE_STANDARD               0x00
336 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_PAGE_CODE_SERIAL                 0x80
337 #define UX_SLAVE_CLASS_STORAGE_INQUIRY_PERIPHERAL_TYPE                  0x00
338 #define UX_SLAVE_CLASS_STORAGE_RESET                                    0xff
339 #define UX_SLAVE_CLASS_STORAGE_GET_MAX_LUN                              0xfe
340 #define UX_SLAVE_CLASS_STORAGE_MAX_LUN                                  0
341 #define UX_SLAVE_CLASS_STORAGE_RESPONSE_LENGTH                          64
342 
343 /* Define Storage Class SCSI read disk information command constants.  */
344 
345 #define UX_SLAVE_CLASS_STORAGE_READ_DISK_INFORMATION_OPERATION          0
346 #define UX_SLAVE_CLASS_STORAGE_READ_DISK_INFORMATION_STATUS             2
347 #define UX_SLAVE_CLASS_STORAGE_READ_DISK_INFORMATION_ALLOCATION_LENGTH  7
348 #define UX_SLAVE_CLASS_STORAGE_READ_DISK_INFORMATION_LENGTH             10
349 
350 /* Define Storage Class Feature Descriptor generic format.  */
351 
352 #define USBX_DEVICE_CLASS_STORAGE_FEATURE_DESCRIPTOR_FEATURE_CODE       0
353 #define USBX_DEVICE_CLASS_STORAGE_FEATURE_DESCRIPTOR_FEATURE_PARAMETER  2
354 #define USBX_DEVICE_CLASS_STORAGE_FEATURE_DESCRIPTOR_FEATURE_ADD_LENGTH 3
355 #define USBX_DEVICE_CLASS_STORAGE_FEATURE_DESCRIPTOR_FEATURE_LENGTH     4
356 
357 
358 /* Define Storage Class SCSI REPORT_KEY command constants.  */
359 
360 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_OPERATION                    0
361 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_ALLOCATION_LENGTH            8
362 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_FORMAT                       10
363 
364 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_ANSWER_LENGTH                8
365 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_ANSWER_PAYLOAD               6
366 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_ANSWER_RESET_FIELD           4
367 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_ANSWER_REGION_MASK           5
368 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_ANSWER_RPC_SCHEME            6
369 
370 
371 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_FORMAT_AGID                  0
372 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_FORMAT_CHALLENGE             1
373 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_FORMAT_KEY2                  2
374 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_FORMAT_TITLE                 4
375 #define UX_SLAVE_CLASS_STORAGE_REPORT_KEY_FORMAT_RPC                   8
376 
377 /* Define Storage Class SCSI get event status notification command constants.  */
378 
379 #define UX_SLAVE_CLASS_STORAGE_EVENT_NOTIFICATION_OPCODE                0
380 #define UX_SLAVE_CLASS_STORAGE_EVENT_NOTIFICATION_IMMEDIATE             1
381 #define UX_SLAVE_CLASS_STORAGE_EVENT_NOTIFICATION_CLASS_REQUEST         4
382 #define UX_SLAVE_CLASS_STORAGE_EVENT_NOTIFICATION_ALLOCATION_LENGTH     7
383 #define UX_SLAVE_CLASS_STORAGE_EVENT_NOTIFICATION_LENGTH                10
384 
385 /* Define Storage Class SCSI read toc command constants.  */
386 
387 #define UX_SLAVE_CLASS_STORAGE_READ_TOC_OPCODE                          0
388 #define UX_SLAVE_CLASS_STORAGE_READ_TOC_FORMAT                          2
389 #define UX_SLAVE_CLASS_STORAGE_READ_TOC_TRACK_NUMBER                    6
390 #define UX_SLAVE_CLASS_STORAGE_READ_TOC_ALLOCATION_LENGTH               7
391 
392 /* Define Storage Class SCSI read DVD structure command constants.  */
393 
394 #define UX_SLAVE_CLASS_STORAGE_READ_DVD_STRUCTURE_OPCODE                0
395 #define UX_SLAVE_CLASS_STORAGE_READ_DVD_STRUCTURE_ADDRESS               2
396 #define UX_SLAVE_CLASS_STORAGE_READ_DVD_STRUCTURE_FORMAT                7
397 #define UX_SLAVE_CLASS_STORAGE_READ_DVD_STRUCTURE_ALLOCATION_LENGTH     8
398 
399 #define UX_SLAVE_CLASS_STORAGE_READ_DVD_STRUCTURE_RESP_LENGTH           0
400 #define UX_SLAVE_CLASS_STORAGE_READ_DVD_STRUCTURE_BOOK_TYPE             4
401 #define UX_SLAVE_CLASS_STORAGE_READ_DVD_STRUCTURE_DS_MR                 5
402 
403 
404 /* Define Storage Class SCSI get performance command constants.  */
405 
406 #define UX_SLAVE_CLASS_STORAGE_GET_PERFORMANCE_PAGE                     1
407 #define UX_SLAVE_CLASS_STORAGE_GET_PERFORMANCE_PAGE_14                  0x14
408 #define UX_SLAVE_CLASS_STORAGE_GET_PERFORMANCE_PAGE_0                   0x00
409 #define UX_SLAVE_CLASS_STORAGE_GET_PERFORMANCE_PAYLOAD_LENGTH           4
410 #define UX_SLAVE_CLASS_STORAGE_GET_PERFORMANCE_RESPONSE_LENGTH          8
411 #define UX_SLAVE_CLASS_STORAGE_GET_PERFORMANCE_PAYLOAD                  0x20000000
412 
413 /* Define buffer length for IN/OUT pipes.  This should match the size of the endpoint maximum buffer size. */
414 
415 #define UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE                              UX_SLAVE_REQUEST_DATA_MAX_LENGTH
416 
417 
418 /* Define MMC2 CD-ROM / DVD-ROM bit fields */
419 
420 #define UX_SLAVE_CLASS_STORAGE_MMC2_DISK_STATUS_EMPTY                   0
421 #define UX_SLAVE_CLASS_STORAGE_MMC2_DISK_STATUS_INCOMPLETE              1
422 #define UX_SLAVE_CLASS_STORAGE_MMC2_DISK_STATUS_COMPLETE                2
423 #define UX_SLAVE_CLASS_STORAGE_MMC2_DISK_STATUS_OTHERS                  3
424 
425 #define UX_SLAVE_CLASS_STORAGE_MMC2_LAT_SESSION_EMPTY                   0
426 #define UX_SLAVE_CLASS_STORAGE_MMC2_LAT_SESSION_INCOMPLETE              1
427 #define UX_SLAVE_CLASS_STORAGE_MMC2_LAT_SESSION_COMPLETE                3
428 
429 
430 /* Define Storage Class SCSI synchronize cache constants.  */
431 
432 #define UX_SLAVE_CLASS_STORAGE_SYNCHRONIZE_CACHE_FLAGS                  1
433 #define UX_SLAVE_CLASS_STORAGE_SYNCHRONIZE_CACHE_LBA                    2
434 #define UX_SLAVE_CLASS_STORAGE_SYNCHRONIZE_CACHE_NUMBER_OF_BLOCKS       7
435 
436 #define UX_SLAVE_CLASS_STORAGE_SYNCHRONIZE_CACHE_FLAGS_IMMED            0x02
437 
438 
439 /* Define MODE SENSE Page Codes.  */
440 #define UX_SLAVE_CLASS_STORAGE_MMC2_PAGE_CODE_CDROM                     0x2a
441 
442 #define UX_SLAVE_CLASS_STORAGE_PAGE_CODE_CACHE                          0x08
443 #define UX_SLAVE_CLASS_STORAGE_PAGE_CODE_IEC                            0x1C
444 #define UX_SLAVE_CLASS_STORAGE_PAGE_CODE_ALL                            0x3F
445 
446 #if defined(UX_DEVICE_STANDALONE)
447 
448 /* Define Device Storage Class states.  */
449 
450 #define UX_DEVICE_CLASS_STORAGE_STATE_IDLE              (UX_STATE_STEP + 0)
451 #define UX_DEVICE_CLASS_STORAGE_STATE_RESET             (UX_STATE_STEP + 1)
452 #define UX_DEVICE_CLASS_STORAGE_STATE_RESET_WAIT        (UX_STATE_STEP + 2)
453 #define UX_DEVICE_CLASS_STORAGE_STATE_TRANS_START       (UX_STATE_STEP + 3)
454 #define UX_DEVICE_CLASS_STORAGE_STATE_TRANS_WAIT        (UX_STATE_STEP + 4)
455 #define UX_DEVICE_CLASS_STORAGE_STATE_TRANS_NEXT        (UX_STATE_STEP + 5)
456 #define UX_DEVICE_CLASS_STORAGE_STATE_DISK_WAIT         (UX_STATE_STEP + 6)
457 #define UX_DEVICE_CLASS_STORAGE_STATE_DISK_ERROR        (UX_STATE_STEP + 7)
458 
459 #define UX_DEVICE_CLASS_STORAGE_DISK_IDLE               (0)
460 #define UX_DEVICE_CLASS_STORAGE_DISK_OP_START           (1)
461 #define UX_DEVICE_CLASS_STORAGE_DISK_OP_WAIT            (2)
462 #define UX_DEVICE_CLASS_STORAGE_DISK_OP_NEXT            (3)
463 #define UX_DEVICE_CLASS_STORAGE_DISK_USB_WAIT           (4)
464 #define UX_DEVICE_CLASS_STORAGE_DISK_USB_ERROR          (5)
465 
466 #define UX_DEVICE_CLASS_STORAGE_BUFFER_IDLE             (0)
467 #define UX_DEVICE_CLASS_STORAGE_BUFFER_EMPTY            (1)
468 #define UX_DEVICE_CLASS_STORAGE_BUFFER_FULL             (2)
469 
470 #define UX_DEVICE_CLASS_STORAGE_CMD_IDLE                (0)
471 #define UX_DEVICE_CLASS_STORAGE_CMD_CBW                 (1)
472 #define UX_DEVICE_CLASS_STORAGE_CMD_ERR                 (2)
473 #define UX_DEVICE_CLASS_STORAGE_CMD_CSW                 (3)
474 #define UX_DEVICE_CLASS_STORAGE_CMD_WRITE               (4)
475 #define UX_DEVICE_CLASS_STORAGE_CMD_READ                (5)
476 #define UX_DEVICE_CLASS_STORAGE_CMD_DISK_OP             (6)
477 
478 #endif
479 
480 /* Define Slave Storage Class LUN structure.  */
481 
482 typedef struct UX_SLAVE_CLASS_STORAGE_LUN_STRUCT
483 {
484     ULONG           ux_slave_class_storage_media_last_lba;
485     ULONG           ux_slave_class_storage_media_block_length;
486     ULONG           ux_slave_class_storage_media_type;
487     ULONG           ux_slave_class_storage_media_removable_flag;
488     ULONG           ux_slave_class_storage_media_read_only_flag;
489     ULONG           ux_slave_class_storage_media_id;
490     ULONG           ux_slave_class_storage_request_sense_status;
491     ULONG           ux_slave_class_storage_disk_status;
492     ULONG           ux_slave_class_storage_last_session_state;
493 
494     UINT            (*ux_slave_class_storage_media_read)(VOID *storage, ULONG lun, UCHAR *data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status);
495     UINT            (*ux_slave_class_storage_media_write)(VOID *storage, ULONG lun, UCHAR *data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status);
496     UINT            (*ux_slave_class_storage_media_flush)(VOID *storage, ULONG lun, ULONG number_blocks, ULONG lba, ULONG *media_status);
497     UINT            (*ux_slave_class_storage_media_status)(VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status);
498     UINT            (*ux_slave_class_storage_media_notification)(VOID *storage, ULONG lun, ULONG media_id, ULONG notification_class, UCHAR **media_notification, ULONG *media_notification_length);
499 } UX_SLAVE_CLASS_STORAGE_LUN;
500 
501 /* Sense status value (key at bit0-7, code at bit8-15 and qualifier at bit16-23).  */
502 
503 #define UX_DEVICE_CLASS_STORAGE_SENSE_STATUS(key,code,qualifier)        (((key) & 0xFF)|(((code) & 0xFF) << 8)|(((qualifier) & 0xFF) << 16))
504 #define UX_DEVICE_CLASS_STORAGE_SENSE_KEY(status)                       ((status) & 0xFF)
505 #define UX_DEVICE_CLASS_STORAGE_SENSE_CODE(status)                      (((status) >> 8) & 0xFF)
506 #define UX_DEVICE_CLASS_STORAGE_SENSE_QUALIFIER(status)                 (((status) >> 16) & 0xFF)
507 
508 
509 /* Define Slave Storage Class structure.  */
510 
511 typedef struct UX_SLAVE_CLASS_STORAGE_STRUCT
512 {
513     UX_SLAVE_INTERFACE          *ux_slave_class_storage_interface;
514     ULONG                       ux_slave_class_storage_number_lun;
515     UX_SLAVE_CLASS_STORAGE_LUN  ux_slave_class_storage_lun[UX_MAX_SLAVE_LUN];
516     ULONG                       ux_slave_class_storage_host_length;
517     UCHAR                       ux_slave_class_storage_cbw_flags;
518     UCHAR                       ux_slave_class_storage_cbw_lun;
519     UCHAR                       ux_slave_class_storage_reserved[2];
520     ULONG                       ux_slave_class_storage_scsi_tag;
521     ULONG                       ux_slave_class_storage_csw_residue;
522     ULONG                       ux_slave_class_storage_csw_status;
523     VOID                        (*ux_slave_class_storage_instance_activate)(VOID *);
524     VOID                        (*ux_slave_class_storage_instance_deactivate)(VOID *);
525     UCHAR                       *ux_slave_class_storage_vendor_id;
526     UCHAR                       *ux_slave_class_storage_product_id;
527     UCHAR                       *ux_slave_class_storage_product_rev;
528     UCHAR                       *ux_slave_class_storage_product_serial;
529 
530 #if defined(UX_DEVICE_STANDALONE)
531     UCHAR                       *ux_device_class_storage_buffer[2];
532     UCHAR                       ux_device_class_storage_buffer_state[2];
533     UCHAR                       ux_device_class_storage_buffer_usb;
534     UCHAR                       ux_device_class_storage_buffer_disk;
535 
536     UCHAR                       ux_device_class_storage_cmd;
537     UCHAR                       ux_device_class_storage_cmd_state;
538     UCHAR                       ux_device_class_storage_disk_state;
539     UCHAR                       ux_device_class_storage_state;
540 
541     UX_SLAVE_ENDPOINT           *ux_device_class_storage_ep_out;
542     UX_SLAVE_ENDPOINT           *ux_device_class_storage_ep_in;
543     UX_SLAVE_TRANSFER           *ux_device_class_storage_transfer;
544 
545     ULONG                       ux_device_class_storage_device_length;
546     UCHAR                       *ux_device_class_storage_data_buffer;
547     ULONG                       ux_device_class_storage_data_length;
548     ULONG                       ux_device_class_storage_data_count;
549     ULONG                       ux_device_class_storage_trans_host_length;
550     ULONG                       ux_device_class_storage_trans_device_length;
551 
552     ULONG                       ux_device_class_storage_cmd_lba;
553     ULONG                       ux_device_class_storage_cmd_n_lb;
554     ULONG                       ux_device_class_storage_disk_n_lb;
555     ULONG                       ux_device_class_storage_media_status;
556 #endif
557 
558 } UX_SLAVE_CLASS_STORAGE;
559 
560 #define UX_DEVICE_CLASS_STORAGE_CSW_STATUS(p)               (((UCHAR*)(p))[0])
561 #define UX_DEVICE_CLASS_STORAGE_CSW_SKIP(p)                 (((UCHAR*)(p))[3])
562 
563 /* Define Slave Storage Class Calling Parameter structure */
564 
565 typedef struct UX_SLAVE_CLASS_STORAGE_PARAMETER_STRUCT
566 {
567     VOID                        (*ux_slave_class_storage_instance_activate)(VOID *);
568     VOID                        (*ux_slave_class_storage_instance_deactivate)(VOID *);
569     ULONG                       ux_slave_class_storage_parameter_number_lun;
570     UX_SLAVE_CLASS_STORAGE_LUN  ux_slave_class_storage_parameter_lun[UX_MAX_SLAVE_LUN];
571     UCHAR                       *ux_slave_class_storage_parameter_vendor_id;
572     UCHAR                       *ux_slave_class_storage_parameter_product_id;
573     UCHAR                       *ux_slave_class_storage_parameter_product_rev;
574     UCHAR                       *ux_slave_class_storage_parameter_product_serial;
575 
576 } UX_SLAVE_CLASS_STORAGE_PARAMETER;
577 
578 /* Define Device Storage Class prototypes.  */
579 
580 UINT    _ux_device_class_storage_initialize(UX_SLAVE_CLASS_COMMAND *command);
581 UINT    _ux_device_class_storage_uninitialize(UX_SLAVE_CLASS_COMMAND *command);
582 UINT    _ux_device_class_storage_activate(UX_SLAVE_CLASS_COMMAND *command);
583 UINT    _ux_device_class_storage_control_request(UX_SLAVE_CLASS_COMMAND *command);
584 UINT    _ux_device_class_storage_csw_send(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in, UCHAR csw_status);
585 UINT    _ux_device_class_storage_deactivate(UX_SLAVE_CLASS_COMMAND *command);
586 UINT    _ux_device_class_storage_entry(UX_SLAVE_CLASS_COMMAND *command);
587 UINT    _ux_device_class_storage_format(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in,
588                     UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb);
589 UINT    _ux_device_class_storage_inquiry(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in,
590                     UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb);
591 UINT    _ux_device_class_storage_mode_select(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in,
592                     UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb);
593 UINT    _ux_device_class_storage_mode_sense(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in,
594                     UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb);
595 UINT    _ux_device_class_storage_prevent_allow_media_removal(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun,
596                     UX_SLAVE_ENDPOINT *endpoint_in, UX_SLAVE_ENDPOINT *endpoint_out, UCHAR * cbwcb);
597 UINT    _ux_device_class_storage_read(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in,
598                     UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb, UCHAR scsi_command);
599 UINT    _ux_device_class_storage_read_capacity(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in,
600                     UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb);
601 UINT    _ux_device_class_storage_read_format_capacity(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in,
602                     UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb);
603 UINT    _ux_device_class_storage_read_toc(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in,
604                                             UX_SLAVE_ENDPOINT *endpoint_out, UCHAR * cbwcb);
605 UINT    _ux_device_class_storage_request_sense(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in,
606                     UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb);
607 UINT    _ux_device_class_storage_start_stop(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in,
608                     UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb);
609 UINT    _ux_device_class_storage_test_ready(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in,
610                     UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb);
611 VOID    _ux_device_class_storage_thread(ULONG storage_instance);
612 UINT    _ux_device_class_storage_verify(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in,
613                     UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb);
614 UINT    _ux_device_class_storage_write(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in,
615                     UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb, UCHAR scsi_command);
616 UINT    _ux_device_class_storage_synchronize_cache(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun, UX_SLAVE_ENDPOINT *endpoint_in,
617                     UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb, UCHAR scsi_command);
618 UINT    _ux_device_class_storage_read_disk_information(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun,
619                                             UX_SLAVE_ENDPOINT *endpoint_in,
620                                             UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb);
621 
622 UINT    _ux_device_class_storage_get_configuration(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun,
623                                             UX_SLAVE_ENDPOINT *endpoint_in,
624                                             UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb);
625 UINT    _ux_device_class_storage_get_status_notification(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun,
626                                             UX_SLAVE_ENDPOINT *endpoint_in,
627                                             UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb);
628 UINT    _ux_device_class_storage_report_key(UX_SLAVE_CLASS_STORAGE *storage,
629                                             ULONG               lun,
630                                             UX_SLAVE_ENDPOINT   *endpoint_in,
631                                             UX_SLAVE_ENDPOINT   *endpoint_out,
632                                             UCHAR               *cbwcb);
633 
634 UINT    _ux_device_class_storage_get_performance(UX_SLAVE_CLASS_STORAGE *storage,
635                                             ULONG               lun,
636                                             UX_SLAVE_ENDPOINT   *endpoint_in,
637                                             UX_SLAVE_ENDPOINT   *endpoint_out,
638                                             UCHAR               *cbwcb);
639 UINT    _ux_device_class_storage_read_dvd_structure(UX_SLAVE_CLASS_STORAGE *storage, ULONG lun,
640                                             UX_SLAVE_ENDPOINT *endpoint_in,
641                                             UX_SLAVE_ENDPOINT *endpoint_out, UCHAR *cbwcb);
642 
643 UINT    _ux_device_class_storage_tasks_run(VOID *instance);
644 
645 /* Define Device Storage Class API prototypes.  */
646 
647 #define ux_device_class_storage_entry        _ux_device_class_storage_entry
648 
649 /* Determine if a C++ compiler is being used.  If so, complete the standard
650    C conditional started above.  */
651 #ifdef __cplusplus
652 }
653 #endif
654 
655 #endif
656