1 /*
2  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef _USB_MSC_UFI_H
10 #define _USB_MSC_UFI_H 1
11 
12 struct _usb_device_msc_struct;
13 /*!
14  * @addtogroup msc_ufi
15  * @{
16  */
17 /*Sense Key of REQUEST SENSE command, refer to UFI specification chapter 5*/
18 /*! @brief Indicates that there is no specific sense key information to be reported*/
19 #define USB_DEVICE_MSC_UFI_NO_SENSE 0x00U
20 /*! @brief Indicates that the last command completed successfully with some recovery action performed by the UFI
21  * device*/
22 #define USB_DEVICE_MSC_UFI_RECOVERED_ERROR 0x01U
23 /*! @brief Indicates that the UFI device cannot be accessed*/
24 #define USB_DEVICE_MSC_UFI_NOT_READY 0x02U
25 /*! @brief Indicates that the command terminated with a non-recovered
26 error condition that was probably caused by a flaw in the medium or an error in the
27 recorded data*/
28 #define USB_DEVICE_MSC_UFI_MEDIUM_ERROR 0x03U
29 /*! @brief Indicates that the UFI device detected a non-recoverable hardware failure while performing the command or
30  * during a self test*/
31 #define USB_DEVICE_MSC_UFI_HARDWARE_ERROR 0x04U
32 /*! @brief Indicates that there was an illegal parameter in the Command
33 Packet or in the additional parameters supplied as data for some commands*/
34 #define USB_DEVICE_MSC_UFI_ILLEGAL_REQUEST 0x05U
35 /*! @brief Indicates that the removable medium may have been changed or the UFI device has been reset*/
36 #define USB_DEVICE_MSC_UFI_UNIT_ATTENTION 0x06U
37 /*! @brief Indicates that a command that writes the medium was attempted on a block that is protected from this
38  * operation*/
39 #define USB_DEVICE_MSC_UFI_DATA_PROTECT 0x07U
40 /*! @brief Indicates that a write-once device or a sequential-access device
41 encountered blank medium or format-defined end-of-data indication while reading or
42 a write-once device encountered a non-blank medium while writing*/
43 #define USB_DEVICE_MSC_UFI_BLANK_CHECK 0x08U
44 /*! @brief This sense key is available for reporting vendor-specific conditions*/
45 #define USB_DEVICE_MSC_UFI_VENDOR_SPECIFIC_ERROR 0x09U
46 /*! @brief Indicates that the UFI device has aborted the command
47 The host may be able to recover by trying the command again*/
48 #define USB_DEVICE_MSC_UFI_ABORTED_COMMAND 0x0BU
49 /*! @brief Indicates that a buffered peripheral device has reached the
50 end-of-partition and data may remain in the buffer that has not been written to the medium*/
51 #define USB_DEVICE_MSC_UFI_VOLUME_OVERFLOW 0x0DU
52 /*! @brief Indicates that the source data did not match the data read from the medium*/
53 #define USB_DEVICE_MSC_UFI_MISCOMPARE 0x0EU
54 /*! @brief additional sense code*/
55 /*! @brief additional sense code medium not present*/
56 #define USB_DEVICE_MSC_UFI_ASC_MEDIUM_NOT_PRESENT 0x3AU
57 /*! @brief additional sense code not ready to ready transition- media change*/
58 #define USB_DEVICE_MSC_UFI_ASC_MEDIUM_CHANGE 0x28U
59 
60 /*! @brief Invalid command operation code*/
61 #define USB_DEVICE_MSC_UFI_INVALID_COMMAND_OPCODE 0x20U
62 /*! @brief Write fault*/
63 #define USB_DEVICE_MSC_UFI_WRITE_FAULT 0x03U
64 /*! @brief Not recovered read error*/
65 #define USB_DEVICE_MSC_UFI_UNRECOVERED_READ_ERROR 0x11U
66 /*! @brief Unknown error*/
67 #define USB_DEVICE_MSC_UFI_UNKNOWN_ERROR 0xFFU
68 /*! @brief Invalid field in command packet*/
69 #define USB_DEVICE_MSC_UFI_INVALID_FIELD_IN_COMMAND_PKT 0x24U
70 /*! @brief Invalid logical block address out of range*/
71 #define USB_DEVICE_MSC_UFI_LBA_OUT_OF_RANGE 0x21U
72 
73 /*! @brief Valid error code, 70h indicate current errors*/
74 #define USB_DEVICE_MSC_UFI_REQ_SENSE_VALID_ERROR_CODE 0x70U
75 /*! @brief The UFI device sets the value of this field to ten, to indicate that ten more bytes of sense data follow this
76  * field*/
77 #define USB_DEVICE_MSC_UFI_REQ_SENSE_ADDITIONAL_SENSE_LEN 0x0AU
78 
79 /*! @brief Prevent media removal flag*/
80 #define USB_DEVICE_MSC_UFI_PREVENT_ALLOW_REMOVAL_MASK 0x01U
81 /*! @brief LoEj Start flag */
82 #define USB_DEVICE_MSC_UFI_LOAD_EJECT_START_MASK 0x03U
83 
84 /*! @brief Formatted Media - Current media capacity */
85 #define USB_DEVICE_MSC_UFI_FORMATTED_MEDIA 0x02U
86 /*! @brief Unformatted Media - Maximum formatting capacity for this cartridge*/
87 #define USB_DEVICE_MSC_UFI_UNFORMATTED_MEDIA 0x01U
88 /*! @brief No Cartridge in Drive - Maximum formating capacity for any cartridge*/
89 #define USB_DEVICE_MSC_UFI_NO_CARTRIDGE_IN_DRIVE 0x03U
90 
91 /*! @brief INQUIRY Data length of INQUIRY Command*/
92 #define USB_DEVICE_MSC_UFI_INQUIRY_ALLOCATION_LENGTH 0x24U
93 /*! @brief Request Sense Data length of REQUEST SENSE Command*/
94 #define USB_DEVICE_MSC_UFI_REQ_SENSE_DATA_LENGTH 18U
95 /*! @brief READ CAPACITY Data length of READ CAPACITY Command*/
96 #define USB_DEVICE_MSC_UFI_READ_CAPACITY_DATA_LENGTH 0x08U
97 /*! @brief READ CAPACITY Data length of READ CAPACITY Command*/
98 #define USB_DEVICE_MSC_UFI_READ_CAPACITY16_DATA_LENGTH 0x0CU
99 
100 /*! @brief Reserved*/
101 #define USB_DEVICE_MSC_UFI_PERIPHERAL_QUALIFIER 0U
102 /*! @brief Peripheral Device Type shift*/
103 #define USB_DEVICE_MSC_UFI_PERIPHERAL_QUALIFIER_SHIFT 5U
104 /*! @brief Version value*/
105 #define USB_DEVICE_MSC_UFI_VERSIONS 4U
106 /*! @brief Peripheral Device Type value of INQUIRY Data*/
107 #define USB_DEVICE_MSC_UFI_PERIPHERAL_DEVICE_TYPE 0x00U
108 /*! @brief Removable Media Bit value, this shall be set to one to indicate removable media*/
109 #define USB_DEVICE_MSC_UFI_REMOVABLE_MEDIUM_BIT 1U
110 /*! @brief  Removable Media Bit shift*/
111 #define USB_DEVICE_MSC_UFI_REMOVABLE_MEDIUM_BIT_SHIFT 7U
112 /*! @brief  Additional Length*/
113 #define USB_DEVICE_MSC_UFI_ADDITIONAL_LENGTH 0x20U
114 
115 /*! @brief  UFI inquiry command structure*/
116 typedef struct _usb_device_inquiry_command_struct
117 {
118     uint8_t operationCode;     /*!< Operation Code*/
119     uint8_t logicalUnitNumber; /*!< Specifies the logical unit (0~7) for which Inquiry data should be returned*/
120     uint8_t pageCode;          /*!< Page Code*/
121     uint8_t reserved;          /*!< Reserved*/
122     uint8_t allocationLength;  /*!< Specifies the maximum number of bytes of inquiry data to be returned*/
123     uint8_t reserved1[7];      /*!< Reserved*/
124 } usb_device_inquiry_command_struct_t;
125 
126 /*! @brief  UFI request sense command structure*/
127 typedef struct _usb_device_request_sense_command_struct
128 {
129     uint8_t operationCode;     /*!< Operation Code*/
130     uint8_t logicalUnitNumber; /*!< Logical Unit Number*/
131     uint8_t reserved[2];       /*!< reserved*/
132     uint8_t allocationLength;  /*!< Allocation Length*/
133     uint8_t reserved1[7];      /*!< reserved*/
134 } usb_device_request_sense_command_struct_t;
135 
136 /*! @brief  UFI read format capacities command structure*/
137 typedef struct _usb_device_read_format_capacities_command_struct
138 {
139     uint8_t operationCode;     /*!< Operation Code*/
140     uint8_t logicalUnitNumber; /*!< Logical Unit Number*/
141     uint8_t reserved[5];       /*!< reserved*/
142     uint16_t allocationLength; /*!< Allocation Length*/
143     uint8_t reserved1[3];      /*!< reserved*/
144 } usb_device_read_format_capacities_command_struct_t;
145 
146 /*! @brief  UFI read capacities command structure*/
147 typedef struct _usb_device_read_capacities_command_struct
148 {
149     uint8_t operationCode;     /*!< Operation Code*/
150     uint8_t logicalUnitNumber; /*!< Logical Unit Number*/
151     uint32_t lba;              /*!< Logical Block Address*/
152     uint8_t reserved[2];       /*!< Reserved*/
153     uint8_t pmi;               /*!< This bit should be set to zero for UFI*/
154     uint8_t reserved1[3];      /*!< Reserved*/
155 } usb_device_read_capacities_command_struct_t;
156 
157 /*! @brief  UFI read write 10 structure*/
158 typedef struct _usb_device_read_write_10_command_struct
159 {
160     uint8_t operationCode;     /*!< Operation Code*/
161     uint8_t lunDpoFuaReladr;   /*!< Logical Unit Number DPO FUA RelAdr*/
162     uint32_t lba;              /*!< Logical Block Address*/
163     uint8_t reserved;          /*!< Reserved*/
164     uint8_t transferLengthMsb; /*!< Transfer Length (MSB)*/
165     uint8_t transferLengthLsb; /*!< Transfer Length (LSB)*/
166     uint8_t reserved1[3];      /*!< Reserved*/
167 } usb_device_read_write_10_command_struct_t;
168 /*! @brief  UFI Test Unit Ready structure*/
169 typedef struct _usb_device_test_unit_ready
170 {
171     uint8_t operationCode;     /*!< Operation Code*/
172     uint8_t logicalUnitNumber; /*!< Logical Unit Number*/
173     uint8_t reserved1[10];     /*!< Reserved*/
174 } usb_device_test_unit_ready_struct_t;
175 
176 /*! @brief  UFI inquiry data format structure*/
177 typedef struct _usb_device_inquiry_data_fromat_struct
178 {
179     uint8_t peripheralDeviceType; /*!< Peripheral Device Type*/
180     uint8_t rmb;                  /*!< Removable Media Bit*/
181     uint8_t versions;             /*!< ISO Version, ECMA Version, ANSI Version*/
182     uint8_t responseDataFormat;   /*!< Response Data Format*/
183     uint8_t additionalLength;     /*!< The Additional Length field shall specify the length in bytes of the parameters*/
184     uint8_t reserved[3];          /*!< reserved*/
185     uint8_t vendorInformatin[8];  /*!< Vendor Identification*/
186     uint8_t productId[16];        /*!< Product Identification*/
187     uint8_t productVersionLevel[4]; /*!< Product Revision Level*/
188 } usb_device_inquiry_data_fromat_struct_t;
189 
190 /*! @brief  UFI request sense data structure*/
191 typedef struct _usb_device_request_sense_data_struct
192 {
193     uint8_t validErrorCode;          /*!< Error Code*/
194     uint8_t reserved;                /*!< reserved*/
195     uint8_t senseKey;                /*!< Sense Key*/
196     uint8_t information[4];          /*!< Information*/
197     uint8_t additionalSenseLength;   /*!< Additional Sense Length*/
198     uint8_t reserved1[4];            /*!< reserved*/
199     uint8_t additionalSenseCode;     /*!< Additional Sense Code*/
200     uint8_t additionalSenseQualifer; /*!< Additional Sense Code Qualifier*/
201     uint8_t reserved2[4];            /*!< reserved*/
202 } usb_device_request_sense_data_struct_t;
203 
204 /*! @brief  UFI read capacity data structure*/
205 typedef struct _usb_device_read_capacity_struct
206 {
207     uint32_t lastLogicalBlockAddress; /*!< Last Logical Block Address*/
208     uint32_t blockSize;               /*!< Block Length In Bytes*/
209 } usb_device_read_capacity_struct_t;
210 
211 /*! @brief  UFI read capacity data structure*/
212 typedef struct _usb_device_read_capacity16_data_struct
213 {
214     uint32_t lastLogicalBlockAddress0; /*!<  Last Logical Block Address*/
215     uint32_t lastLogicalBlockAddress1; /*!<  Last Logical Block Address*/
216     uint32_t blockSize;                /*!< Block Length In Bytes*/
217 } usb_device_read_capacity16_data_struct_t;
218 
219 /*! @brief  UFI capacity list header structure*/
220 typedef struct _usb_device_capacity_list_header_struct
221 {
222     uint8_t reserverd[3];       /*!< reserved*/
223     uint8_t capacityListLength; /*!< Capacity List Length*/
224 } usb_device_capacity_list_header_struct_t;
225 
226 /*! @brief  UFI current maximum capacity structure*/
227 typedef struct _usb_device_current_max_capacity_descriptor_struct
228 {
229     uint32_t blockNumber;               /*!< Number of Blocks*/
230     uint32_t descriptorCodeBlockLength; /*!< Byte 4 Descriptor Code , byte 5-7 Block Length*/
231 } usb_device_current_max_capacity_descriptor_struct_t;
232 
233 /*! @brief  UFI formatting capacity structure*/
234 typedef struct _usb_device_formattable_capacity_descriptor_struct
235 {
236     uint32_t blockNumber; /*!< Number of Blocks*/
237     uint32_t blockLength; /*!< Block Length*/
238 } usb_device_formattable_capacity_descriptor_struct_t;
239 
240 /*! @brief  UFI mode parameters header structure*/
241 typedef struct _usb_device_mode_parameters_header_struct
242 {
243     uint16_t modeDataLength; /*!< Mode Data Length*/
244     uint8_t mediumTypeCode;  /*!< The Medium Type Code field specifies the inserted medium type*/
245     uint8_t wpDpfua;         /*!< WP and DPOFUA bit*/
246     uint8_t reserved[4];     /*!< Reserved*/
247 } usb_device_mode_parameters_header_struct_t;
248 
249 /*! @brief  UFI Capacity List structure*/
250 typedef struct _usb_device_format_capacity_response_data_struct
251 {
252     uint8_t capacityListHead[sizeof(usb_device_capacity_list_header_struct_t)]; /*!<Capacity List Header*/
253     uint8_t currentMaxCapacityDesccriptor[sizeof(
254         usb_device_current_max_capacity_descriptor_struct_t)]; /*!<Current/Maximum Capacity Header*/
255     uint8_t formattableCapacityDesccriptor[sizeof(usb_device_formattable_capacity_descriptor_struct_t) *
256                                            3]; /*!<Formatting Capacity Descriptor*/
257 } usb_device_format_capacity_response_data_struct_t;
258 
259 extern usb_status_t USB_DeviceMscUfiThirteenCasesCheck(struct _usb_device_msc_struct *mscHandle);
260 
261 extern usb_status_t USB_DeviceMscUfiRequestSenseCommand(struct _usb_device_msc_struct *mscHandle);
262 extern usb_status_t USB_DeviceMscUfiInquiryCommand(struct _usb_device_msc_struct *mscHandle);
263 extern usb_status_t USB_DeviceMscUfiReadCommand(struct _usb_device_msc_struct *mscHandle);
264 extern usb_status_t USB_DeviceMscUfiWriteCommand(struct _usb_device_msc_struct *mscHandle);
265 extern usb_status_t USB_DeviceMscUfiTestUnitReadyCommand(struct _usb_device_msc_struct *mscHandle);
266 extern usb_status_t USB_DeviceMscUfiVerifyCommand(struct _usb_device_msc_struct *mscHandle);
267 extern usb_status_t USB_DeviceMscUfiModeSenseCommand(struct _usb_device_msc_struct *mscHandle);
268 extern usb_status_t USB_DeviceMscUfiModeSelectCommand(struct _usb_device_msc_struct *mscHandle);
269 extern usb_status_t USB_DeviceMscUfiReadCapacityCommand(struct _usb_device_msc_struct *mscHandle);
270 extern usb_status_t USB_DeviceMscUfiReadFormatCapacityCommand(struct _usb_device_msc_struct *mscHandle);
271 extern usb_status_t USB_DeviceMscUfiFormatUnitCommand(struct _usb_device_msc_struct *mscHandle);
272 extern usb_status_t USB_DeviceMscUfiPreventAllowMediumCommand(struct _usb_device_msc_struct *mscHandle);
273 extern usb_status_t USB_DeviceMscUfiSendDiagnosticCommand(struct _usb_device_msc_struct *mscHandle);
274 extern usb_status_t USB_DeviceMscUfiStartStopUnitCommand(struct _usb_device_msc_struct *mscHandle);
275 extern usb_status_t USB_DeviceMscUfiUnsupportCommand(struct _usb_device_msc_struct *mscHandle);
276 
277 /*! @}*/
278 
279 #endif
280