1 /* ---------------------------------------------------------------------------- 2 * Copyright (c) Huawei Technologies Co., Ltd. 2015-2019. All rights reserved. 3 * Description: LiteOS USB Driver Mass Storage Protocol HeadFile 4 * Author: huangjieliang 5 * Create: 2015-07-30 6 * Redistribution and use in source and binary forms, with or without modification, 7 * are permitted provided that the following conditions are met: 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 * of conditions and the following disclaimer in the documentation and/or other materials 12 * provided with the distribution. 13 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 14 * to endorse or promote products derived from this software without specific prior written 15 * permission. 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * --------------------------------------------------------------------------- */ 28 /* ---------------------------------------------------------------------------- 29 * Notice of Export Control Law 30 * =============================================== 31 * Huawei LiteOS may be subject to applicable export control laws and regulations, which might 32 * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. 33 * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such 34 * applicable export control laws and regulations. 35 * --------------------------------------------------------------------------- */ 36 37 #ifndef _F_MASS_STORAGE_H 38 #define _F_MASS_STORAGE_H 39 40 #include <fs/fs.h> 41 #include <disk.h> 42 #include "gadget/composite.h" 43 #include "implementation/freebsd_sys.h" 44 45 #ifdef __cplusplus 46 #if __cplusplus 47 extern "C" { 48 #endif /* __cplusplus */ 49 #endif /* __cplusplus */ 50 51 /* Command Block Wrapper */ 52 53 typedef struct bulk_cbw 54 { 55 uint32_t dCBWSignature; /* Command Block Wrapper Signature */ 56 uint32_t dCBWTag; /* Command Block Tag */ 57 uint32_t dCBWDataTransferLength; /* Data Transfer Length */ 58 uint8_t bmCBWFlags; 59 uint8_t bCBWLUN; /* Logical Unit Number */ 60 uint8_t bCBWLEN; /* Command Block Length */ 61 uint8_t CDB[16]; 62 } bulk_cbw_t; 63 64 /* Command Status Wrapper */ 65 66 typedef struct bulk_csw 67 { 68 uint32_t dCSWSignature; /* Command Status Wrapper Signature */ 69 uint32_t dCSWTag; /* Command Status Tag */ 70 uint32_t dCSWResidue; 71 uint8_t bCSWStatus; 72 } bulk_csw_t; 73 74 #define BULK_CBW_WRAP_LEN 31 75 #define BULK_CBW_SIGN 0x43425355 76 #define BULK_CBW_FLAG_IN (1 << 7) 77 #define BULK_CBW_FLAG_OUT 0 78 79 #define BULK_CSW_WRAP_LEN 13 80 #define BULK_CSW_SIGN 0x53425355 81 #define BULK_CSW_STAT_OK 0 82 #define BULK_CSW_STAT_FAIL 1 83 #define BULK_CSW_STAT_PHASE 2 84 85 /* Bulk-only class specific requests */ 86 87 #define USB_BULK_RESET_REQUEST 0xff 88 #define USB_BULK_GET_MAX_LUN 0xfe 89 90 #define SCSI_TEST_UNIT_READY 0x00 91 #define SCSI_REQUEST_SENSE 0x03 92 #define SCSI_FORMAT_UNIT 0x04 93 #define SCSI_INQUIRY 0x12 94 #define SCSI_MODE_SELECT_6 0x15 95 #define SCSI_MODE_SELECT_10 0x55 96 #define SCSI_MODE_SENSE_6 0x1a 97 #define SCSI_MODE_SENSE_10 0x5a 98 #define SCSI_ALLOW_MEDIUM_REMOVAL 0x1e 99 #define SCSI_READ_FORMAT_CAPACITIES 0x23 100 #define SCSI_READ_CAPACITY 0x25 101 #define SCSI_READ_6 0x08 102 #define SCSI_READ_10 0x28 103 #define SCSI_READ_12 0xa8 104 #define SCSI_WRITE_6 0x0a 105 #define SCSI_WRITE_10 0x2a 106 #define SCSI_WRITE_12 0xaa 107 #define START_STOP 0x1b 108 109 /* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */ 110 111 #define SCSI_NO_SENSE 0 112 #define SCSI_COMMUNICATION_FAILURE 0x040800 113 #define SCSI_INVALID_COMMAND 0x052000 114 #define SCSI_INVALID_FIELD_IN_CDB 0x052400 115 #define SCSI_INVALID_COM 0x052600 116 #define SCSI_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100 117 #define SCSI_LOGICAL_UNIT_NOT_SUPPORTED 0x052500 118 #define SCSI_MEDIUM_NOT_PRESENT 0x023a00 119 #define SCSI_MEDIUM_REMOVAL_PREVENTED 0x055302 120 #define SCSI_UNIT_ATTENTION 0x060000 121 #define SCSI_NOT_READY_TO_READY_TRANSITION 0x062800 122 #define SCSI_RESET_OCCURRED 0x062900 123 #define SCSI_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900 124 #define SCSI_UNRECOVERED_READ_ERROR 0x031100 125 #define SCSI_WRITE_ERROR 0x030c02 126 #define SCSI_WRITE_PROTECTED 0x072700 127 128 #define SK(x) ((uint8_t) ((x) >> 16)) /* Sense Key byte, etc. */ 129 #define ASC(x) ((uint8_t) ((x) >> 8)) 130 #define ASCQ(x) ((uint8_t) (x)) 131 132 #define FMASS_MAX_LUNS 8 133 134 typedef enum data_direct_t 135 { 136 DATA_DIRECT_UNKNOWN = 0, 137 DATA_DIRECT_FROM_HOST, 138 DATA_DIRECT_TO_HOST, 139 DATA_DIRECT_NONE 140 } data_direct; 141 142 typedef enum fmass_task_state_t 143 { 144 FMASS_TASK_IDLE = 0x0, 145 FMASS_TASK_DISCONNECT = 0x01, 146 FMASS_TASK_CONFIG_CHANGE = 0x02, 147 FMASS_TASK_REQ_COMMAND_PHASE = 0x04, 148 FMASS_TASK_DONE_COMMAND_PHASE = 0x08, 149 FMASS_TASK_REQ_DATA_PHASE = 0x10, 150 FMASS_TASK_DONE_DATA_PHASE = 0x20, 151 FMASS_TASK_REQ_STATUS_PHASE = 0x40, 152 FMASS_TASK_DONE_STATUS_PHASE = 0x80, 153 FMASS_TASK_REPORT_USB_STATUS = 0x100 154 } fmass_task_state; 155 156 /* Length of a SCSI Command Data Block */ 157 158 #define MAX_COMMAND_SIZE 16 159 160 #define MAX_BLOCK_RW_SECTORS 256 161 #define MAX_DATA_BUFFER_NUM 2 162 #define MAX_FILE_STORAGE_LUNS 32 163 #define MAX_NOFIFY_NUM 10 164 typedef void (*fmass_notify_cb)(void *context, int status); 165 166 struct fmass_notify 167 { 168 fmass_notify_cb notifycb; 169 void *notifydata; 170 int is_used; 171 }; 172 173 enum fmass_data_buf_state 174 { 175 DBUF_STATE_EMPTY = 0, 176 DBUF_STATE_FULL, 177 DBUF_STATE_BUSY 178 }; 179 180 struct fmass_data_buf_t 181 { 182 void *buf; 183 uint32_t filledbit; 184 struct fmass_data_buf_t *next; 185 enum fmass_data_buf_state state; 186 }; 187 188 struct fmass_capacity 189 { 190 size_t nsectors; /* Number of sectors on the device */ 191 size_t sectorsize; /* Size of one sector */ 192 int read_only; 193 }; 194 195 struct mass_dev_s 196 { 197 data_direct data_dir; 198 uint32_t data_size; 199 uint32_t data_size_from_cmd; 200 uint32_t tag; 201 uint32_t residue; 202 uint32_t usb_amount_left; 203 204 205 int cmd_size; 206 uint8_t cmd[MAX_COMMAND_SIZE]; 207 208 uint32_t sense_data; 209 uint32_t sense_data_info; 210 uint32_t unit_attention_data; 211 uint32_t info_valid; 212 213 uint8_t bulk_in_enabled; 214 uint8_t bulk_out_enabled; 215 216 struct bulk_csw csw; 217 218 /* 219 * Vendor (8 chars), product (16 chars), release (4 220 * hexadecimal digits) and NULL byte 221 */ 222 223 char inquiry_str[8 + 16 + 4 + 1]; 224 225 uint32_t nluns; 226 uint32_t lun; 227 228 #define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */ 229 #define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */ 230 231 los_part *parts[MAX_FILE_STORAGE_LUNS]; 232 FAR struct inode *fileNode[MAX_FILE_STORAGE_LUNS]; 233 struct fmass_capacity caps[MAX_FILE_STORAGE_LUNS]; 234 struct fmass_data_buf_t *databuf_fill; 235 struct fmass_data_buf_t databuf[MAX_DATA_BUFFER_NUM]; 236 uint32_t fmass_db_bitmap; 237 238 #define FMASS_DATA_PROC 0x01 239 #define FMASS_NEED_EXIT 0x02 240 #define FMASS_THREAD_EXITED 0x04 241 EVENT_CB_S task_event; 242 243 struct mtx task_mtx; 244 wait_queue_head_t xfer_wait; 245 uint32_t task_state; 246 spinlock_t lock; 247 248 struct fmass_notify *notify; 249 int dev_status; /* 0: usb device disconnect , 1 : usb device connectted */ 250 #define DEV_ST_DISCONNECT 0 251 #define DEV_ST_CONNECTTED 1 252 253 struct usbdev_req_s ctrlreq; 254 struct usbdev_req_s bulkreq; 255 struct usbdev_ep_s *bulkout; 256 struct usbdev_ep_s *bulkin; 257 }; 258 259 struct mass_driver_s 260 { 261 struct usbdevclass_driver_s drvr; 262 struct mass_dev_s *dev; 263 }; 264 265 struct mass_softc 266 { 267 struct mass_dev_s dev; 268 struct mass_driver_s drvr; 269 }; 270 271 #ifdef __cplusplus 272 #if __cplusplus 273 } 274 #endif /* __cplusplus */ 275 #endif /* __cplusplus */ 276 277 #endif