📄 usbmass.lst
字号:
C51 COMPILER V6.12 USBMASS 03/13/2007 09:54:33 PAGE 1
C51 COMPILER V6.12, COMPILATION OF MODULE USBMASS
OBJECT MODULE PLACED IN .\usbmass.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE .\usbmass.c COMPACT DEBUG OBJECTEXTEND
stmt level source
1 #include "reg51.h"
2 #include "read_reg.h"
3 #include "usbmass.h"
4
5 #define TRY_WAIT 100 //100
6 #define ERROR_WAIT 500
7 #define READCAP_STALL_CNT_MAX 5
8
9 int gLunSet = 0; //"LUN" for USB_XXX routines
10 XD U8 gCBW[31]; //SCSI CBW 31byte or
11 XD U8 gMaxLun; //gMaxLun = ??á??· LUN
12
13
14 XD U8 gLunFlag; //bitmap for LUN presence
15 XD U8 gLunMask; //bit=0: allow, bit=1: disable(CD or ...)
16 XD U32 gLastSec; //last PHYSICAL sector
17
18 extern XD U8 gDevAddr;
19
20 U32 gUsbReadUnit;
21
22 extern XD U8 gEPOUT; //out-endpoint
23 extern XD U8 gEPIN; //in-endpoint
24 extern XD U8 volatile gEP;
25 extern XD U8 gIrqEn;
26 extern XD U8 gLun; //"LUN" for USB_XXX routines
27 extern XD U8 gMxPkSz; //maximum packet size (bulk)
28 extern XD U8 gIFSC; //interface sub-class
29 extern XD U8 gUsbVer; //USB Version
30
31
32 extern U8 gStallMark;
33
34 extern int gSecCnt;
35 extern int gSecAddr;
36 extern XD U16 gVID;
37 extern XD U16 gPID;
38
39 U32 gUsbTrgCnt; //1=when to get CSW,0=no active read
40
41 XD U32 gTotSecCnt; //total sector including all system area (for current partition)
42
43 /******************************************************************************
44 * RETURN:
45 * RES_ERR/RES_OK
46 * NOTE:
47 * gCBW俊 31 byte CBW data甫 固府 盲款 饶 妮!
48 ******************************************************************************/
49
50 U8 SCSI_SendCBW(void)
51 {
52 1 UH_SET_FIFO_SZ_EACH(0,31);
53 1 UH_FIFO_ROLLBACK_OUT();
54 1 UH_IRQ_EN(UH_IRQ_USB_PKT_DONE);
55 1 DEV_WriteRegMulti(RH_USB_HOST_BASE_ADDR, 31, (U8*)gCBW);
C51 COMPILER V6.12 USBMASS 03/13/2007 09:54:33 PAGE 2
56 1 UH_Trigger(gEPOUT);
57 1 //if(DEV_WaitForIrq(UH_IRQ_USB_PKT_DONE)==0) return RES_ERR_SCSI_CBW;
58 1 return RES_OK;
59 1 }
60
61
62 /******************************************************************************
63 * INPUT:
64 * - totBytCnt : total byte count of DATA-IN
65 * - buf : pointer to a data buffer
66 * NULL if you want to discard the data
67 * RETURN:
68 * RES_ERR: timeout or CSW error
69 * RES_ERR+1: CSW error --> require REQUEST_SENSE
70 * RES_OK: success
71 * RES_OK+1: incomplete DATA-IN
72 * RES_OK+UH_IRQ_FAKE_STALL: stalled --> require CSW-IN
73 *
74 ******************************************************************************/
75
76 U8 SCSI_GetDataIn(U16 totBytCnt, U8* buf)
77 {
78 1 U8 res;
79 1 U16 bytCnt;
80 1 res=RES_OK;
81 1
82 1 while(totBytCnt>0)
83 1 {
84 2 bytCnt = (totBytCnt>64)?64:totBytCnt;
85 2 res = DEV_SafeTriggerAndWaitForInPacket(gEPIN,bytCnt,2000);
86 2 if(UH_IRQ_FAKE_STALL==res) return (RES_OK+UH_IRQ_FAKE_STALL); // --> continue on CSW stage
87 2 if(0==res) return RES_ERR; //timeout
88 2 UH_FIFO_ROLLBACK_IN();
89 2 if(buf!=TxNULL){ DEV_ReadRegMulti(RH_USB_HOST_BASE_ADDR,bytCnt,buf); }
90 2 else{ DEV_ReadRegMultiAndDiscard(RH_USB_HOST_BASE_ADDR,bytCnt); }
91 2 if(!(UH_IRQ_READ_READY&res))//incomplete data-in
92 2 {
93 3 if((bytCnt<13)||(buf==TxNULL)) return RES_ERR; //we can't see CSW error flag
94 3 if(buf[0]==0&&buf[1]==0){ //ZERO packet arrived!
95 4 if(buf[2]==0x42&&buf[3]==0x43) return RES_OK+1; // only ZERO packet --> continue on CSW
96 4 if(buf[2]==0x55&&buf[3]==0x53){ //CSW followed ZERO packet
97 5 if(bytCnt>=15&&buf[4]==0x42&&buf[5]==0x53&&buf[14]==1) return RES_ERR+1;
98 5 return RES_ERR;
99 5 }
100 4 }
101 3 else if(buf[0]==0x55&&buf[1]==0x53&&buf[2]==0x42&&buf[3]==0x53){ //CSW arrived without DATA-IN
102 4 if(bytCnt>=13&&buf[12]==1) //SCSI_RequestSense(); //LIU TEST 11-29
103 4 return RES_ERR; //CSW
104 4 }
105 3 }
106 2 totBytCnt -=bytCnt;
107 2 if(buf!=TxNULL) buf += bytCnt;
108 2 }
109 1 return res;
110 1 }
111
112
113
114 U8 SCSI_RequestSense(void)
115 {
116 1 U8 res;
117 1
C51 COMPILER V6.12 USBMASS 03/13/2007 09:54:33 PAGE 3
118 1 MemFill(gCBW+8,0,31-8);
119 1 DEV_WriteReg(RH_USB_HOST_BASE_LEN,gMxPkSz);
120 1 gCBW[13]=gLun;
121 1 SET_CBW_BULKIN();
122 1 SET_CBW_CMD(SCSI_CMD_REQUESTSENSE);
123 1 gCBW[14]=0x0C;
124 1 gCBW[8]=gCBW[19]=18;
125 1 SCSI_SendCBW();
126 1 if(DEV_WaitForIrq(UH_IRQ_USB_PKT_DONE)==0) return RES_ERR_SCSI_CBW;
127 1
128 1 res = SCSI_GetDataIn(18,(U8*)TxNULL);
129 1 if(ISERR(res)) return RES_ERR; //timeout or earlier CSW (no measure for CSW-error)
130 1
131 1 res = SCSI_SafeCSW();
132 1 if(ISERR(res)) return RES_ERR; //timeout or earlier CSW (no measure for CSW-error)
133 1 return RES_OK;
134 1 }
135
136
137
138 /******************************************************************************
139 * INPUT:
140 *
141 * RETURN:
142 * RES_ERR: timeout or CSW error
143 * RES_ERR+1: CSW error --> require REQUEST_SENSE
144 * RES_OK: success
145 * RES_OK+UH_IRQ_FAKE_STALL: stalled --> no measure
146 *
147 ******************************************************************************/
148
149 U8 SCSI_SafeCSW(void)
150 {
151 1 U8 res;
152 1 res = DEV_SafeTriggerAndWaitForInPacket(gEPIN,13,2000);
153 1 if(res==0) return RES_ERR; //timeout --> no measure
154 1 if(UH_IRQ_FAKE_STALL==res) return UH_IRQ_FAKE_STALL;
155 1
156 1 UH_FIFO_ROLLBACK_IN();
157 1 res = DEV_ReadRegMultiAndDiscard(RH_USB_HOST_BASE_ADDR,13);
158 1 return (res==0)?RES_OK:RES_ERR+1;
159 1 }
160
161
162
163 /******************************************************************************
164 * IMPLICIT INPUT:
165 * - gLun : LUN number
166 *
167 * NOTE:
168 *
169 * Mode-Sense: subclass=6(SCSI-2) 捞搁 SCSI_CMD_MODESENSE6,
170 * 酒聪搁 SCSI_CMD_MODESENSE10
171 * * 林狼: 固府 buf[0] 俊 pageCode甫 持阑巴!!
172 *
173 * Prevent-Allow: buf=0(NULL) 捞搁 Allow,
174 * 弊寇绰 Prevent
175 *
176 * RETURN:
177 * RES_ERR_SCSI_CBW
178 * RES_ERR_SCSI_CMD_IGNORED
179 * RES_ERR_SCSI_DATA
C51 COMPILER V6.12 USBMASS 03/13/2007 09:54:33 PAGE 4
180 * RES_ERR
181 * RES_OK
182 ******************************************************************************/
183
184 U8 SCSI_CMD(IN U8 cmd, OUT U8* buf)
185 {
186 1 U8 res1,res2,bytCnt;
187 1 res1=res2=RES_OK;
188 1
189 1
190 1 bytCnt=0;
191 1 MemFill(gCBW+8,0,31-8);
192 1 gCBW[13]=gLun;
193 1 SET_CBW_CMD(cmd);
194 1 SET_CBW_BULKIN();
195 1 if(gIFSC==6) gCBW[14]=0x06; //CBW Length for subclass-6: non-fixed!!
196 1 else gCBW[14]=0x0C; //CBW Length for non-subclass-6: fixed to 0x0C
197 1
198 1 switch(cmd)
199 1 {
200 2 case SCSI_CMD_TESTUNITREADY: SET_CBW_BULKOUT();
201 2 break;
202 2
203 2 case SCSI_CMD_INQUIRY: bytCnt=0x24;
204 2 gCBW[8]=gCBW[19]=bytCnt;
205 2 break;
206 2
207 2 case SCSI_CMD_PREVENTALLOW: SET_CBW_BULKOUT();
208 2 gCBW[19]=(buf==NULL)?0:1; //1=prevent(disable removal)
209 2 break;
210 2
211 2
212 2 case SCSI_CMD_READFORMATCAP: bytCnt=12;
213 2 gCBW[8]=gCBW[23]=bytCnt;//0xFC;
214 2 if(gIFSC==6)gCBW[14]=0x0A;
215 2 break;
216 2
217 2 case SCSI_CMD_READCAPACITY: bytCnt=0x08;
218 2 gCBW[8]=bytCnt;
219 2 if(gIFSC==6)gCBW[14]=0x0A;
220 2 break;
221 2
222 2 case SCSI_CMD_TO_STALL_EPIN: bytCnt=1;
223 2 gCBW[8]=1;
224 2 break;
225 2 default:
226 2 return RES_ERR;
227 2 }
228 1
229 1 SCSI_SendCBW();
230 1 if(DEV_WaitForIrq(UH_IRQ_USB_PKT_DONE)==0) return RES_ERR_SCSI_CBW;
231 1
232 1
233 1 DEV_WaitMS(10);
234 1
235 1
236 1 res1 = SCSI_GetDataIn(bytCnt,buf);
237 1 if(res1==RES_ERR) return RES_ERR; //timeout
238 1 else if(res1==RES_ERR+1){ //earlier CSW(with error flag)
239 2 SCSI_RequestSense();
240 2 return RES_ERR;
241 2 }
C51 COMPILER V6.12 USBMASS 03/13/2007 09:54:33 PAGE 5
242 1
243 1
244 1 res2 = SCSI_SafeCSW();
245 1 if(res2==RES_ERR+1){ //earlier CSW(with error flag)
246 2 SCSI_RequestSense();
247 2 return RES_ERR;
248 2 }
249 1 if((res1|res2)&UH_IRQ_FAKE_STALL) return RES_ERR+1;
250 1 if(ISERR(res2)) return RES_ERR;
251 1 return RES_OK;
252 1 }
253
254
255 U8 UM_SetLun(U8 bLun, U8* tBUF)
256 {
257 1 if(gLunMask&(1<<bLun)) return RES_ERR; //skip non-generic storage
258 1 //#if (UMO_EXACT_SECTOR_READ==0)
259 1 // if(gSecCnt>0){ UBI9021_FlushSectorRead(); }
260 1 //#endif
261 1
262 1 if(bLun<=gMaxLun)
263 1 {
264 2 gLun = bLun;
265 2 if(ISERR(SCSI_ReadCapacity(tBUF))){
266 3 DEV_WaitMS(1);
267 3 gLastSec = nOK32-1; //unknown size
268 3 }else{
269 3 gLastSec = (((U32)tBUF[0])<<24)+(((U32)tBUF[1])<<16)+(((U32)tBUF[2])<<8)+((U32)tBUF[3]);
270 3 }
271 2 gTotSecCnt = gLastSec+1;
272 2 return RES_OK;
273 2 }
274 1 return RES_ERR;
275 1 }
276
277
278
279 /******************************************************************************
280 *
281 * get lun count and initialize each LUN
282 *
283 * INPUT:
284 * - tBUF: tiny buffer for SCSI data-in
285 *
286 * OUTPUT:
287 * - gLunFlag = bitmap for LUN presence (each bit indicate presence of each LUN)
288 * - gMaxLun
289 *
290 * RETURN:
291 * return max LUN
292 * return RES_ERR(=0x80)
293 *
294 ******************************************************************************/
295
296
297
298 U8 UM_InitMultiLun(U8* tBUF)
299 {
300 1 int i;
301 1 U8 res,rcscnt=0; //read-capacity stall count
302 1 U8 maxTryCnt=3;
303 1
C51 COMPILER V6.12 USBMASS 03/13/2007 09:54:33 PAGE 6
304 1 ///GET-MAX-LUN:
305 1 gMaxLun = 0;
306 1 gLunMask = 0;
307 1 if(ISOK(USB_ControlTransfer(USB_SETUP_GET_MAX_LUN,0,tBUF))){ gMaxLun = tBUF[0]; }
308 1 DEV_WriteReg(RH_USB_HOST_BASE_LEN,gMxPkSz);
309 1
310 1 if(gMaxLun>=16) gMaxLun=0;
311 1 if(gMaxLun>0) DEV_WaitMS(3000);//wait 3second for multi-card reader
312 1 else DEV_WaitMS(500);
313 1
314 1 for(gLun=0;gLun<=gMaxLun;gLun++)
315 1 {
316 2 DEV_WaitMS(TRY_WAIT); //100msec
317 2 if(ISERR(SCSI_Inquiry(tBUF))){
318 3 if(gDevAddr!=DEV_ReadReg(RH_DEV_ADDR)||0x5A!=DEV_ReadReg(RH_MASS_ADDR2)) return RES_ERR;
319 3 DEV_WaitMS(ERROR_WAIT);
320 3 continue;
321 3 }
322 2 else{
323 3 if(tBUF[0]!=0){ //check if generic Flash or HDD drive (0x05=CD)
324 4 gLunMask |= (1<<gLun);
325 4 continue;
326 4 }
327 3 }
328 2 // DEV_WaitMS(TRY_WAIT);
329 2 // if(ISERR(SCSI_ReadFormatCapacity(tBUF))){
330 2 // DEV_WaitMS(ERROR_WAIT);
331 2 // }
332 2 DEV_WaitMS(TRY_WAIT);
333 2 if(ISERR(SCSI_TestUnit())){
334 3 if(gDevAddr!=DEV_ReadReg(RH_DEV_ADDR)||0x5A!=DEV_ReadReg(RH_MASS_ADDR2)) return RES_ERR;
335 3 DEV_WaitMS(ERROR_WAIT);
336 3 }
337 2 }
338 1
339 1 IML_RETRY:
340 1 rcscnt=0;
341 1
342 1 for(gLun=0,gLunFlag=0;gLun<=gMaxLun;gLun++)
343 1 {
344 2 if(gLunMask&(1<<gLun))continue; //skip non-generic storage
345 2 DEV_WaitMS(TRY_WAIT);
346 2 if(rcscnt<READCAP_STALL_CNT_MAX){
347 3 res = SCSI_ReadCapacity(tBUF);
348 3 if(res==RES_ERR+1)rcscnt++;
349 3 if(ISERR(res)){
350 4 if(gDevAddr!=DEV_ReadReg(RH_DEV_ADDR)||0x5A!=DEV_ReadReg(RH_MASS_ADDR2)) return RES_ERR;
351 4 DEV_WaitMS(ERROR_WAIT);
352 4 }
353 3 }
354 2
355 2 //#if UMO_ENABLE_MODESENSE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -