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
47extern "C" {
48#endif /* __cplusplus */
49#endif /* __cplusplus */
50
51/* Command Block Wrapper */
52
53typedef 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
66typedef 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
134typedef 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
142typedef 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
164typedef void (*fmass_notify_cb)(void *context, int status);
165
166struct fmass_notify
167{
168  fmass_notify_cb notifycb;
169  void *notifydata;
170  int is_used;
171};
172
173enum fmass_data_buf_state
174{
175  DBUF_STATE_EMPTY = 0,
176  DBUF_STATE_FULL,
177  DBUF_STATE_BUSY
178};
179
180struct 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
188struct 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
195struct 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
259struct mass_driver_s
260{
261  struct usbdevclass_driver_s drvr;
262  struct mass_dev_s *dev;
263};
264
265struct 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