1 /* 2 * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. 3 * Copyright 2016 - 2023 NXP 4 * All rights reserved. 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 */ 8 9 #ifndef __USB_DEVICE_MSC_H__ 10 #define __USB_DEVICE_MSC_H__ 11 12 #include "usb_device_msc_ufi.h" 13 /*! 14 * @addtogroup usb_msc 15 * @{ 16 */ 17 /*! @brief prevent media removal flag */ 18 #define USB_DEVICE_CONFIG_MSC_SUPPORT_DISK_LOCKING_MECHANISM (0U) 19 #define USB_DEVICE_CONFIG_MSC_IMPLEMENTING_DISK_DRIVE (0U) 20 /*! @brief The class code of the MSC class */ 21 #define USB_DEVICE_CONFIG_MSC_CLASS_CODE (0x08U) 22 23 /*! @brief Bulk-Only Mass Storage Reset (class-specific request) */ 24 #define USB_DEVICE_MSC_BULK_ONLY_MASS_STORAGE_RESET (0xFFU) 25 /*! @brief Get Maximum LUN (class-specific request) */ 26 #define USB_DEVICE_MSC_GET_MAX_LUN (0xFEU) 27 28 /*! @brief CBW dCBWSignature*/ 29 #define USB_DEVICE_MSC_DCBWSIGNATURE USB_LONG_TO_BIG_ENDIAN(0x55534243UL) 30 /*! @brief CSW dCSSWSignature*/ 31 #define USB_DEVICE_MSC_DCSWSIGNATURE USB_LONG_TO_BIG_ENDIAN(0x55534253UL) 32 /*! @brief CSW bmCBWFlags bit7 */ 33 #define USB_DEVICE_MSC_CBW_DIRECTION_BIT (0x80U) 34 #define USB_DEVICE_MSC_CBW_DIRECTION_SHIFT (7U) 35 /*! @brief CBW command length*/ 36 #define USB_DEVICE_MSC_CBW_LENGTH (31U) 37 /*! @brief CSW command length*/ 38 #define USB_DEVICE_MSC_CSW_LENGTH (13U) 39 /*! @brief Command Block Status Values*/ 40 #define USB_DEVICE_MSC_COMMAND_PASSED (0x00U) 41 #define USB_DEVICE_MSC_COMMAND_FAILED (0x01U) 42 #define USB_DEVICE_MSC_PHASE_ERROR (0x02U) 43 /*! @brief UFI Commands code*/ 44 #define USB_DEVICE_MSC_INQUIRY_COMMAND (0x12U) 45 #define USB_DEVICE_MSC_READ_10_COMMAND (0x28U) 46 #define USB_DEVICE_MSC_READ_12_COMMAND (0xA8U) 47 #define USB_DEVICE_MSC_REQUEST_SENSE_COMMAND (0x03U) 48 #define USB_DEVICE_MSC_TEST_UNIT_READY_COMMAND (0x00U) 49 #define USB_DEVICE_MSC_WRITE_10_COMMAND (0x2AU) 50 #define USB_DEVICE_MSC_WRITE_12_COMMAND (0xAAU) 51 #define USB_DEVICE_MSC_PREVENT_ALLOW_MEDIUM_REM_COMMAND (0x1EU) 52 #define USB_DEVICE_MSC_FORMAT_UNIT_COMMAND (0x04U) 53 #define USB_DEVICE_MSC_READ_CAPACITY_10_COMMAND (0x25U) 54 #define USB_DEVICE_MSC_READ_CAPACITY_16_COMMAND (0x9EU) 55 #define USB_DEVICE_MSC_READ_FORMAT_CAPACITIES_COMMAND (0x23U) 56 #define USB_DEVICE_MSC_MODE_SENSE_10_COMMAND (0x5AU) 57 #define USB_DEVICE_MSC_MODE_SENSE_6_COMMAND (0x1AU) 58 #define USB_DEVICE_MSC_MODE_SELECT_10_COMMAND (0x55U) 59 #define USB_DEVICE_MSC_MODE_SELECT_6_COMMAND (0x15U) 60 #define USB_DEVICE_MSC_SEND_DIAGNOSTIC_COMMAND (0x1DU) 61 #define USB_DEVICE_MSC_VERIFY_COMMAND (0x2FU) 62 #define USB_DEVICE_MSC_START_STOP_UNIT_COMMAND (0x1BU) 63 64 /*Max transfer length */ 65 #define USB_DEVICE_MSC_MAX_RECV_TRANSFER_LENGTH (65536U) 66 #define USB_DEVICE_MSC_MAX_SEND_TRANSFER_LENGTH (65536U) 67 68 #define USB_DEVICE_MSC_MAX_LUN (3U) 69 70 /*! @brief Command Block Wrapper(CBW) */ 71 typedef struct _usb_device_msc_cbw 72 { 73 uint32_t signature; /*!< Byte 0-3 dCBWSignature*/ 74 uint32_t tag; /*!< Byte 4-7 dCBWTag*/ 75 uint32_t dataTransferLength; /*!< Byte 8-11 dCBWDataTransferLength*/ 76 uint8_t flags; /*!< Byte 12 bmCBWFlags*/ 77 uint8_t logicalUnitNumber; /*!< Byte 13 bCBWLUN*/ 78 uint8_t cbLength; /*!< Byte 14 bCBWCBLength*/ 79 uint8_t cbwcb[16]; /*!< Byte 15-30 CBWCB, CBWCB is used to store UFI command*/ 80 } usb_device_msc_cbw_t; 81 /*! @brief Command Status Wrapper(CSW) */ 82 typedef struct _usb_device_msc_csw 83 { 84 uint32_t signature; /*!< Byte 0-3 dCSWSignature*/ 85 uint32_t tag; /*!< Byte 4-7 dCSWTag*/ 86 uint32_t dataResidue; /*!< Byte 8-11 dCSWDataResidue*/ 87 uint8_t cswStatus; /*!< Byte 12 bCSWStatus*/ 88 } usb_device_msc_csw_t; 89 /*! @brief Read/write information */ 90 typedef struct _usb_lba_transfer_information_struct 91 { 92 uint32_t startingLogicalBlockAddress; /*!< The logical block at which the read/write operation shall begin*/ 93 uint32_t transferNumber; /*!< The number of contiguous logical blocks of data that shall be transferred*/ 94 } usb_lba_transfer_information_struct_t; 95 /*! @brief device information */ 96 typedef struct _usb_device_logical_unit_information_struct 97 { 98 uint32_t totalLbaNumberSupports; /*!< Total blocks number supported*/ 99 uint32_t lengthOfEachLba; /*!< Length of each block*/ 100 uint32_t bulkInBufferSize; /*!< Bulk in buffer size*/ 101 uint32_t bulkOutBufferSize; /*!< Bulk out buffer size*/ 102 } usb_device_logical_unit_information_struct_t; 103 /*! @brief device information */ 104 typedef struct _usb_device_lba_information_struct 105 { 106 uint32_t logicalUnitNumberSupported; /*!< Number of LUN*/ 107 usb_device_logical_unit_information_struct_t logicalUnitInformations[USB_DEVICE_MSC_MAX_LUN]; 108 } usb_device_lba_information_struct_t; 109 typedef struct _usb_device_capacity_information_struct 110 { 111 uint32_t totalLbaNumberSupports; /*!< Total blocks number supported*/ 112 uint32_t lengthOfEachLba; /*!< Length of each block*/ 113 uint8_t logicalUnitNumber; /*!< Logical Unit Number*/ 114 } usb_device_capacity_information_struct_t; 115 116 /*! @brief Data transfer information */ 117 typedef struct _usb_device_lba_app_struct 118 { 119 uint32_t offset; /*!< Offset of the block need to access*/ 120 uint32_t size; /*!< Size of the transferred data*/ 121 uint8_t *buffer; /*!< Buffer address of the transferred data*/ 122 uint8_t lun; 123 } usb_device_lba_app_struct_t; 124 /*! @brief command and Data transfer information for UFI command*/ 125 typedef struct _usb_device_ufi_app_struct 126 { 127 uint8_t *cbwcb; /*!< current ufi command block strored in the CBW*/ 128 uint32_t size; /*!< Size of the transferred data if commmand has data flow*/ 129 uint8_t *buffer; /*!< Buffer address of the transferred data if commmand has data flow*/ 130 usb_device_request_sense_data_struct_t *requestSense; /*!< sense data for the current command*/ 131 uint8_t logicalUnitNumber; /*!< Logical Unit Number*/ 132 } usb_device_ufi_app_struct_t; 133 /*! @brief The thirteen possible use cases of host expectations and device intent in the absence of 134 overriding error conditions. */ 135 typedef struct _usb_device_msc_thirteen_case_struct 136 { 137 uint32_t hostExpectedDataLength; /*!< The number of bytes of data that the host expects to transfer */ 138 uint32_t deviceExpectedDataLength; /*!< The number of bytes of data that the device expects to transfer */ 139 uint8_t *buffer; /*!< Data buffer*/ 140 usb_lba_transfer_information_struct_t lbaInformation; /*!< Read/write information*/ 141 uint8_t lbaSendRecvSelect; /*!< Whether the command is read or write command*/ 142 uint8_t hostExpectedDirection; /*!< Host expected data direction*/ 143 uint8_t deviceExpectedDirection; /*!< Device expected data direction*/ 144 } usb_device_msc_thirteen_case_struct_t; 145 /*! @brief stall flag */ 146 typedef enum 147 { 148 USB_DEVICE_MSC_STALL_IN_CBW = 1U, /*!< Stall in CBW*/ 149 USB_DEVICE_MSC_STALL_IN_DATA, /*!< Stall in data transfer*/ 150 USB_DEVICE_MSC_STALL_IN_CSW, /*!< Stall in CSW*/ 151 } usb_device_msc_stall_type; 152 /*! @brief Available common EVENT types in MSC class callback */ 153 typedef enum 154 { 155 kUSB_DeviceMscEventReadResponse = 156 0x01U, /*!< host has already read the whole data from device or device send is cancelled etc*/ 157 kUSB_DeviceMscEventWriteResponse, /*!< devcie has already received the data from host or device receive is cancelled 158 etc. */ 159 kUSB_DeviceMscEventWriteRequest, /*!< Host want to write data to device through write command, devcie need prepare 160 one buffer to store the data from host*/ 161 kUSB_DeviceMscEventReadRequest, /*!< Host want to read data from device through read command, device need prepare 162 one buffer containing data pending for transfer*/ 163 kUSB_DeviceMscEventGetLbaInformation, /*!< Get device information */ 164 kUSB_DeviceMscEventFormatComplete, /*!< Format complete */ 165 kUSB_DeviceMscEventTestUnitReady, /*!< Test Unit Ready command*/ 166 kUSB_DeviceMscEventInquiry, /*!< Inquiry Command command*/ 167 kUSB_DeviceMscEventModeSense, /*!< mode sense command*/ 168 kUSB_DeviceMscEventModeSelect, /*!< mode select command, prepare data buffer and buffer length to store data for 169 mode select*/ 170 kUSB_DeviceMscEventModeSelectResponse, /*!< got data of mode select command*/ 171 kUSB_DeviceMscEventRemovalRequest, /*!< Prevent_allow_medium_command */ 172 kUSB_DeviceMscEventSendDiagnostic, /*!< Send Diagnostic command */ 173 kUSB_DeviceMscEventStopEjectMedia, /*!< Start_stop_unit_command */ 174 kUSB_DeviceMscEventRequestSense, /*!< Request Sense command */ 175 kUSB_DeviceMscEventReadCapacity, /*!< ReadCapacity command */ 176 kUSB_DeviceMscEventReadFormatCapacity, /*!< Read Format Capacity command */ 177 } USB_DeviceMscEvent_t; 178 /*! @brief The MSC device UFI command status structure */ 179 typedef struct _usb_device_msc_ufi_struct 180 { 181 usb_device_request_sense_data_struct_t *requestSense; /*!< Request Sense Standard Data*/ 182 usb_device_msc_thirteen_case_struct_t thirteenCase; /*!< Thirteen possible cases*/ 183 usb_device_read_capacity_struct_t *readCapacity; /*!< READ CAPACITY Data*/ 184 usb_device_read_capacity16_data_struct_t *readCapacity16; /*!< READ CAPACITY Data*/ 185 usb_device_mode_parameters_header_struct_t ModeParametersHeader; /*!< Mode Parameter Header*/ 186 uint8_t formattedDisk; /*!< *Formatted or unformatted media*/ 187 uint8_t *formatCapacityData; 188 /*!< Capacity List*/ 189 } usb_device_msc_ufi_struct_t; 190 /*! @brief The MSC device structure */ 191 typedef struct _usb_device_msc_struct 192 { 193 usb_device_handle handle; /*!< The device handle */ 194 usb_device_class_config_struct_t *configurationStruct; /*!< The configuration of the class*/ 195 usb_device_interface_struct_t *interfaceHandle; /*!< Current interface handle */ 196 uint32_t transferRemaining; /*!< Transfer remaining data */ 197 uint32_t currentOffset; /*!< Current address offset */ 198 uint32_t implementingDiskDrive; /*!< Disk drive*/ 199 200 usb_device_msc_cbw_t *mscCbw; /*!< CBW structure */ 201 usb_device_msc_csw_t *mscCsw; /*!< CSW structure */ 202 203 usb_device_msc_ufi_struct_t mscUfi; /*!< UFI command information structure*/ 204 205 usb_device_logical_unit_information_struct_t luInformations[USB_DEVICE_MSC_MAX_LUN]; 206 207 uint8_t dataOutFlag; /*!< CBW indicating bulk out transfer, clear this flag when data transfer done*/ 208 uint8_t dataInFlag; /*!< CBW indicating bulk in transfer, clear this flag when data transfer done*/ 209 uint8_t inEndpointStallFlag; /*!< In endpoint stall flag*/ 210 uint8_t outEndpointStallFlag; /*!< Out endpoint stall flag*/ 211 uint8_t cbwValidFlag; /*!< The CBW was received after the device had sent a CSW or after a reset ,or else it is 212 invalid*/ 213 uint8_t performResetRecover; /*!< Device need reset command from host*/ 214 uint8_t performResetDoneFlag; /*!< Device has perform reset command */ 215 uint8_t needInStallFlag; /*!< In endpoint should be stalled*/ 216 uint8_t needOutStallFlag; /*!< Out endpoint should be stalled*/ 217 uint8_t cbwPrimeFlag; /*!< CBW prime flag, prime means device MSC has been ready to receive CBW, the bulk out 218 endpoint has got the prepared buffer*/ 219 uint8_t cswPrimeFlag; /*!< CSW prime flag, prime means device MSC has been ready to receive CSW, the bulk in 220 endpoint has got the prepared buffer*/ 221 uint8_t stallStatus; /*!< Stall status*/ 222 223 uint8_t logicalUnitNumber; /*!< Supported logical units number of device. See bulk only specification 3.2 Get 224 Maximum LUN 225 (class-specific request)*/ 226 uint8_t bulkInEndpoint; /*!< Bulk in endpoint number*/ 227 uint8_t bulkOutEndpoint; /*!< Bulk out endpoint number*/ 228 uint8_t alternate; /*!< Current alternate setting of the interface */ 229 uint8_t configuration; /*!< Current configuration */ 230 uint8_t interfaceNumber; /*!< The interface number of the class */ 231 uint8_t inEndpointCswCancelFlag; /*!< the state when calcel function happens, and need send the csw after cancel*/ 232 } usb_device_msc_struct_t; 233 #ifdef __cplusplus 234 extern "C" { 235 #endif 236 237 /*! 238 * @name USB device MSC class APIs 239 * @{ 240 */ 241 /*! 242 * @brief Initializes the MSC class. 243 * 244 * This function is used to initialize the MSC class. 245 * 246 * @param controllerId The controller ID of the USB IP. See the enumeration usb_controller_index_t. 247 * @param config The class configuration information. 248 * @param handle A parameter used to return pointer of the MSC class handle to the caller. 249 * 250 * @return A USB error code or kStatus_USB_Success. 251 */ 252 extern usb_status_t USB_DeviceMscInit(uint8_t controllerId, 253 usb_device_class_config_struct_t *config, 254 class_handle_t *handle); 255 /*! 256 * @brief Deinitializes the device MSC class. 257 * 258 * The function deinitializes the device MSC class. 259 * 260 * @param handle The MSC class handle received from usb_device_class_config_struct_t::classHandle. 261 * 262 * @return A USB error code or kStatus_USB_Success. 263 */ 264 extern usb_status_t USB_DeviceMscDeinit(class_handle_t handle); 265 266 /*! @}*/ 267 268 extern usb_status_t USB_DeviceMscEvent(void *handle, uint32_t event, void *param); 269 extern usb_status_t USB_DeviceMscLbaTransfer(usb_device_msc_struct_t *mscHandle, 270 uint8_t direction, 271 usb_lba_transfer_information_struct_t *lba_info_ptr); 272 273 #ifdef __cplusplus 274 } 275 #endif 276 277 /*! @}*/ 278 279 #endif 280