1 /*
2 ********************************************************************************************************************
3 *                                              usb host driver
4 *
5 *                              (c) Copyright 2007-2010, javen.China
6 *                                       All Rights Reserved
7 *
8 * File Name     : usb_msc_i.h
9 *
10 * Author        : javen
11 *
12 * Version       : 2.0
13 *
14 * Date          : 2010.03.02
15 *
16 * Description   :
17 *
18 * History       :
19 *
20 ********************************************************************************************************************
21 */
22 #ifndef  __USB_MSC_I_H__
23 #define  __USB_MSC_I_H_
24 
25 #include "usb_host_common.h"
26 
27 /* Sub Classes */
28 #define USBMSC_SUBCLASS_RBC             0x01        /* Typically, flash devices */
29 #define USBMSC_SUBCLASS_8020            0x02        /* CD-ROM                   */
30 #define USBMSC_SUBCLASS_QIC             0x03        /* QIC-157 Tapes            */
31 #define USBMSC_SUBCLASS_UFI             0x04        /* Floppy                   */
32 #define USBMSC_SUBCLASS_8070            0x05        /* Removable media          */
33 #define USBMSC_SUBCLASS_SCSI            0x06        /* Transparent              */
34 #define USBMSC_SUBCLASS_ISD200          0x07        /* ISD200 ATA               */
35 
36 #define USBMSC_SUBCLASS_MIN             USBMSC_SUBCLASS_RBC
37 #define USBMSC_SUBCLASS_MAX             USBMSC_SUBCLASS_ISD200
38 
39 /* Protocol */
40 #define USBMSC_INTERFACE_PROTOCOL_CBIT  0x00    /* Control/Bulk/Interrupt       */
41 #define USBMSC_INTERFACE_PROTOCOL_CBT   0x01    /* Control/Bulk w/o interrupt   */
42 #define USBMSC_INTERFACE_PROTOCOL_BOT   0x50    /* bulk only                    */
43 
44 /* 预定义 */
45 struct __mscDev;
46 struct __ScsiCmnd;
47 struct __mscLun;
48 
49 
50 #define  MSC_MAX_LUN            15      /* msc协议规定最大支持15个Lun       */
51 #define  SCSI_INQUERY_LEN       36      /* 标准inquery命令返回的都是36字节  */
52 #define  SCSI_MAX_INQUERY_LEN   44      /* 标准inquery命令返回的都是36字节  */
53 #define  MSC_IOBUF_SIZE         64
54 
55 
56 /* mscDev状态 */
57 typedef enum __mscDev_state
58 {
59     MSC_DEV_OFFLINE = 0,        /* mscDev已经拔出       */
60     MSC_DEV_ONLINE,             /* mscDev已经添加       */
61     MSC_DEV_DIED,               /* mscDev不可用         */
62     MSC_DEV_RESET               /* mscDev正在被reset    */
63 } mscDev_state_t;
64 
65 typedef int(* msc_ResetRecovery)(struct __mscDev *mscDev);
66 typedef int(* msc_Transport)(struct __mscDev *mscDev, struct __ScsiCmnd *ScsiCmnd);
67 typedef int(* msc_StopTransport)(struct __mscDev *mscDev);
68 typedef int(* msc_ProtocolHandler)(struct __mscDev *mscDev, struct __ScsiCmnd *ScsiCmnd);
69 
70 
71 /* mscDev的抽象, 描述了一个mscDev拥有的资源 */
72 typedef struct __mscDev
73 {
74     struct usb_host_virt_dev *pusb_dev; /* mscDev 对应的Public USB Device   */
75     struct usb_interface    *pusb_intf; /* Public usb interface             */
76 
77     /* device information */
78     unsigned char InterfaceNo;           /* 接口号                               */
79     unsigned char *transport_name;       /* 传输协议的名称                       */
80     unsigned char *Protocol_name;        /* 命令集版本                           */
81     unsigned char SubClass;              /* 子类                                 */
82     unsigned char Protocol;              /* 传输协议                             */
83     unsigned char MaxLun;                /* 最大Lun个数                          */
84     unsigned int mscDevNo;             /* mscDev的编号                         */
85     unsigned int lun_num;              /* mscDev拥有的lun的个数                */
86 
87     /* device manager */
88     struct __mscLun *Lun[MSC_MAX_LUN];      /* 存放所有的Lun                */
89     struct usb_list_head cmd_list;              /* 命令队列                     */
90     hal_sem_t scan_lock;         /* 用来实现scan 和remove的互斥  */
91     hal_sem_t DevLock;           /* 同一时间只允许一个人访问mscDev*/
92     hal_sem_t ThreadSemi;        /* 线程信号量                   */
93     hal_sem_t notify_complete;   /* 同步thread创建/删除          */
94     mscDev_state_t state;                   /* mscDev当前所处的连接状态     */
95 
96     struct rt_thread *MainThreadId;                     /* 主线程ID                     */
97     struct rt_thread *MediaChangeId;                        /* media change处理线程ID       */
98 
99     unsigned int SuspendTime;                      /* Suspend设备所需的时间        */
100 
101     /* command transport */
102     unsigned int BulkIn;                           /* bulk in  pipe                */
103     unsigned int BulkOut;                          /* bulk out pipe                */
104     unsigned int CtrlIn;                           /* ctrl in  pipe                */
105     unsigned int CtrlOut;                          /* ctrl out pipe                */
106     unsigned int IntIn;                            /* interrupt in pipe            */
107     unsigned char  EpInterval;                       /* int 传输主机查询设备的周期,Bulk传输忽略此值 */
108 
109     unsigned int Tag;                              /* SCSI-II queued command tag   */
110     unsigned int busy;                             /* 主机是否正在处理命令         */
111     struct __ScsiCmnd *ScsiCmnd;            /* current srb                  */
112     struct urb *CurrentUrb;                 /* USB requests                 */
113     hal_sem_t UrbWait;           /* wait for Urb done            */
114     struct usb_ctrlrequest *CtrlReq;        /* control requests             */
115     unsigned char *iobuf;                            /* mscDev缓冲区, CBW和CSW都用得到*/
116 
117     osal_timer_t TimerHdle;    /* timer 句柄                   */
118 
119     msc_ResetRecovery   ResetRecovery;      /* USB Controller reset         */
120     msc_Transport       Transport;          /* msc设备支持的传输方式        */
121     msc_StopTransport   StopTransport;      /* 中止msc传输                  */
122     msc_ProtocolHandler ProtocolHandler;    /* msc传输                      */
123 } __mscDev_t;
124 
125 typedef struct __disk_info_t
126 {
127     unsigned int capacity;             /* 设备的容量,以扇区为单位         */
128     unsigned int sector_size;          /* 扇区的大小                       */
129 } disk_info_t;
130 
131 typedef enum __mscLun_state
132 {
133     MSC_LUN_DEL = 0,        /* mscDev不可用     */
134     MSC_LUN_ADD,            /* mscDev已经添加   */
135     MSC_LUN_CANCEL          /* mscDev已经拔出   */
136 } mscLun_state_t;
137 
138 
139 typedef int(* LunProbe)(struct __mscLun *);       /* lun识别  */
140 typedef int(* LunRemove)(struct __mscLun *);      /* lun卸载  */
141 typedef void (* LunMediaChange)(struct __mscLun *); /* media change后的处理 */
142 
143 
144 /* Lun的抽象, 描述了一个Lun拥有的资源 */
145 typedef struct __mscLun
146 {
147     __mscDev_t *mscDev;             /* Lun所属的mscDev                      */
148     unsigned int LunNo;                    /* lun的编号                            */
149 
150     /* device information */
151     unsigned int DeviceType;               /* 设备的类型                           */
152     unsigned int MediumType;               /* 介质类型,CD_ROM枚举时有用           */
153     unsigned char  DiskSubClass;             /* 命令类型                             */
154     unsigned int ScsiLevel;                /* scsi命令集版本                       */
155     unsigned char Inquiry[SCSI_MAX_INQUERY_LEN]; /* 存放inquire命令获得的设备信息        */
156     unsigned char *Vendor;                   /* 供应商                               */
157     unsigned char *Product;                  /* 产品信息                             */
158     unsigned char *Revision;                 /* 产品序列号                           */
159 
160     /* Lun管理 */
161     disk_info_t disk_info;          /* 磁盘信息                             */
162 
163     unsigned int WriteProtect: 1;          /* 是否是可写设备                       */
164     unsigned int RemoveAble: 1;            /* 是否是可移动设备                     */
165     unsigned int Changed: 1;               /* 设备是否改变过                       */
166     unsigned int MediaPresent: 1;          /* 设备介质是否存在                     */
167     unsigned int WCE: 1;                   /* cache写允许                          */
168     unsigned int RCD: 1;                   /* cache读允许                          */
169     unsigned int use_10_for_rw: 1;         /* first try 10-byte read / write       */
170     unsigned int use_10_for_ms: 1;         /* first try 10-byte mode sense/select  */
171     unsigned int skip_ms_page_8: 1;        /* do not use MODE SENSE page 0x08      */
172     unsigned int skip_ms_page_3f: 1;       /* do not use MODE SENSE page 0x3f      */
173     unsigned int use_192_bytes_for_3f: 1;  /* ask for 192 bytes from page 0x3f     */
174 
175     hal_sem_t Lock;      /* 信号量,每次值保证一个用在读或写 */
176 
177     LunProbe        Probe;
178     LunRemove       Remove;
179     LunMediaChange  MediaChange;
180 
181     void *sdev_data;                /* 指向top level的scsi disk等数据结构   */
182 } __mscLun_t;
183 
184 /* 命令数据的方向 */
185 typedef enum scsi_data_direction
186 {
187     DATA_NONE = 0,          /* No Data                  */
188     DATA_TO_DEVICE,         /* Data Out. host->device   */
189     DATA_FROM_DEVICE,       /* Data in. device->host    */
190 } scsi_data_direction_t;
191 
192 /* command block的抽象 */
193 typedef struct __scsi_transport_cmd
194 {
195     scsi_data_direction_t data_direction;   /* IN - DATA_IN or DATA_OUT         */
196     unsigned int Tag;                      /* SCSI-II queued command tag               */
197     unsigned int Timeout;                  /* IN - Timeout for this command Block      */
198     unsigned int dwLun;                    /* IN - Logical Number for Logic Device.    */
199     unsigned int CBLen;                    /* The length of command block              */
200     void *CommandBlock;             /* IN - Pointer to the command block buffer.*/
201 } __scsi_transport_cmd_t;
202 
203 typedef void (*LunDone)(struct __ScsiCmnd *);   /* mscDev调用,Lun cmd处理完毕  */
204 
205 /* ScsiCmnd的抽象, 描述了一个ScsiCmnd拥有的资源 */
206 typedef struct __ScsiCmnd
207 {
208     __mscLun_t *sc_lun;                     /* 命令所属的设备                       */
209     //  struct list_head list;                  /* 此命令在device的cmd_list中的位置     */
210 
211     __scsi_transport_cmd_t cmnd;            /* Command Block                */
212     unsigned int retries;                          /* 当前retry的次数              */
213     unsigned int allowed;                          /* 允许retry的次数              */
214 
215     void *buffer;                           /* Data buffer                  */
216     unsigned int DataTransferLength;               /* Size of data buffer          */
217     unsigned int ActualLength;                     /* actual transport length      */
218 
219     hal_sem_t complete;          /* 等待Lun cmd处理完毕          */
220     LunDone Done;
221 
222     unsigned int Result;                           /* 命令的执行结果               */
223 } __ScsiCmnd_t;
224 
225 //-------------------------------------------------------------------
226 //
227 //-------------------------------------------------------------------
228 #define  USB_STOR_TRANSPORT_GOOD        0   /* 没有错误                 */
229 #define  USB_STOR_TRANSPORT_FAILED      1   /* 传输成功,命令执行失败   */
230 #define  USB_STOR_TRANSPORT_ERROR       2   /* 传输失败                 */
231 
232 
233 //-------------------------------------------------------------------
234 //
235 //-------------------------------------------------------------------
236 int mscDevQueueCmnd(__mscLun_t *mscLun, __ScsiCmnd_t *ScsiCmnd);
237 unsigned int mscDevOnline(__mscDev_t *mscDev);
238 
239 #endif   //__USB_MSC_I_H__
240 
241 
242 
243 
244