xref: /utopia/UTPA2-700.0.x/modules/usb/drv/usb_ecos/usbhost/drvSCSI.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 
79 
80 #include "MsCommon.h"
81 #include "drvSCSI.h"
82 #include "drvProtocol.h"
83 #include "include/drvKernel.h"
84 #include "drvTransport.h"
85 #include "drvHCD.h"
86 #include "drvEHCI.h"
87 
88 #ifdef SCSI_DEBUG
89 #define SCSI_DbgPrint(x,...) printk(x,__VA_ARGS__)
90 #else
91 #define SCSI_DbgPrint(x,...)
92 #endif
93 
94 #define ScsiCmd_Fail_Retry		3
95 #define ScsiCmd_Fail_TUR_Retry		7
96 #define Scsi_Max_Transfer_Len	120*1024 //65536
97 
98 struct us_data *Mass_stor_us[NUM_OF_ROOT_HUB*MAX_USTOR] = {NULL};
99 //extern S32		g_SCSISem;
100 //extern S32 _s32MutexUSB;
101 
102 extern void USBCriticalSectionIn(MS_U8 Port);
103 extern void USBCriticalSectionOut(MS_U8 Port);
104 extern struct usb_hcd *msc_get_hcd(U8 host_id);
105 
106 extern MS_BOOL MDrv_UsbDeviceConnect_EX(struct usb_hcd *hcd);
107 
108 static void vScsi_SendCmd_Done(struct scsi_cmnd *srb);
109 BOOL bSCSI_Initial(U8 uPort);
110 BOOL bInit_USB_Disk(U8 uPort);
111 BOOL bSCSI_ERASE(U8 uPort, U8 uLunNum, U32 u32BlockAddr, U32 u32BlockNum,
112 							U32 u32SectorSize);
113 BOOL bSCSI_Read_10(U8 uPort, U8 uLunNum, U32 u32BlockAddr, U32 u32BlockNum,
114 							U8 *u8Buffer);
115 BOOL bSCSI_Write_10(U8 uPort, U8 uLunNum, U32 u32BlockAddr, U32 u32BlockNum,
116 							U8 *u8Buffer);
117 BOOL bSCSI_Read_10_512(U8 uPort, U8 uLunNum, U32 u32BlockAddr, U32 u32BlockNum,
118 							U8 *u8Buffer);
119 BOOL bSCSI_Write_10_512(U8 uPort, U8 uLunNum, U32 u32BlockAddr, U32 u32BlockNum,
120 							U8 *u8Buffer);
121 VOID RemoveUSBDiskPort(U8 uPort, U8 uLunNum);
122 BOOL ConnectUSBDisk(U8 uPort, U8 uLunNum);
123 
124 static U32
get_value_log2(U32 val)125 get_value_log2(U32 val)
126 {
127     U32 i, log2;
128 
129     if(val == 0)
130         return 0;
131 
132     i    = val;
133     log2 = 0;
134 
135 
136     while (0 == (i & 1))
137     {
138         i >>= 1;
139         log2++;
140     }
141 
142     if (i != 1) return 0;
143     else        return log2;
144 }
145 
vSCSICmd_READ_10(struct us_data * us,U8 u8LunNum,U32 u32BlockAddr,U16 u16BlockNum,U8 * u8Buffer)146 void vSCSICmd_READ_10(struct us_data *us, U8 u8LunNum,
147 							  U32 u32BlockAddr, U16 u16BlockNum, U8 *u8Buffer)
148 {
149 	Scsi_Cmnd *srb = &us->srb;
150 
151 	/* set the command and the LUN */
152 	//memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
153 	srb->cmnd[0] = READ_10;
154 	srb->cmnd[2] = (U8)(u32BlockAddr >> 24);
155 	srb->cmnd[3] = (U8)(u32BlockAddr >> 16);
156 	srb->cmnd[4] = (U8)(u32BlockAddr >> 8);
157 	srb->cmnd[5] = (U8)(u32BlockAddr);
158 	srb->cmnd[7] = (U8)(u16BlockNum >> 8);
159 	srb->cmnd[8] = (U8)(u16BlockNum );
160 
161 	srb->cmd_len = CB_LENGTH_READ_10;
162 
163 	/* set the transfer direction */
164 	srb->sc_data_direction = SCSI_DATA_READ;
165 
166 	/* use the new buffer we have */
167 	srb->request_buffer = u8Buffer;
168 
169 	/* set the buffer length for transfer */
170 	srb->request_bufflen = u16BlockNum << (us->Mass_stor_device[u8LunNum].u32BlockSize_log2);
171 
172 	/* set up for no scatter-gather use */
173 	srb->use_sg = 0;
174 
175 	/* change the serial number -- toggle the high bit*/
176 	srb->serial_number ^= 0x80000000;
177 
178 	/* set Lun number*/
179 	srb->lun= u8LunNum;
180 
181 	srb->scsi_done = vScsi_SendCmd_Done;
182 }
183 
vSCSICmd_WRITE_10(struct us_data * us,U8 u8LunNum,U32 u32BlockAddr,U16 u16BlockNum,U8 * u8Buffer)184 void vSCSICmd_WRITE_10(struct us_data *us, U8 u8LunNum,
185 							  U32 u32BlockAddr, U16 u16BlockNum, U8 *u8Buffer)
186 {
187 	Scsi_Cmnd *srb = &us->srb;
188 
189 	/* set the command and the LUN */
190 	//memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
191 	srb->cmnd[0] = WRITE_10;
192 	srb->cmnd[2] = (U8)(u32BlockAddr >> 24);
193 	srb->cmnd[3] = (U8)(u32BlockAddr >> 16);
194 	srb->cmnd[4] = (U8)(u32BlockAddr >> 8);
195 	srb->cmnd[5] = (U8)(u32BlockAddr);
196 	srb->cmnd[7] = (U8)(u16BlockNum >> 8);
197 	srb->cmnd[8] = (U8)(u16BlockNum );
198 
199 	srb->cmd_len = CB_LENGTH_WRITE_10;
200 
201 	/* set the transfer direction */
202 	srb->sc_data_direction = SCSI_DATA_WRITE;
203 
204 	/* use the new buffer we have */
205 	srb->request_buffer = u8Buffer;
206 
207 	/* set the buffer length for transfer */
208 	srb->request_bufflen = u16BlockNum << us->Mass_stor_device[u8LunNum].u32BlockSize_log2;
209 
210 	/* set up for no scatter-gather use */
211 	srb->use_sg = 0;
212 
213 	/* change the serial number -- toggle the high bit*/
214 	srb->serial_number ^= 0x80000000;
215 
216 	/* set Lun number*/
217 	srb->lun= u8LunNum;
218 
219 	srb->scsi_done = vScsi_SendCmd_Done;
220 }
221 
222 
vSCSICmd_INQUIRY(struct us_data * us,U8 * u8Buffer,U8 u8LunNum)223 void vSCSICmd_INQUIRY(struct us_data *us, U8 *u8Buffer,  U8 u8LunNum)
224 {
225 	Scsi_Cmnd *srb = &us->srb;
226 
227 	/* set the command and the LUN */
228 	memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
229 	srb->cmnd[0] = INQUIRY;
230 	srb->cmnd[4] = DATA_LENGTH_INQUIRY;
231 
232 	srb->cmd_len = CB_LENGTH_INQUIRY;
233 
234 	/* set the transfer direction */
235 	srb->sc_data_direction = SCSI_DATA_READ;
236 
237 	/* use the new buffer we have */
238 	srb->request_buffer = u8Buffer;
239 
240 	/* set the buffer length for transfer */
241 	srb->request_bufflen = DATA_LENGTH_INQUIRY;
242 
243 	/* set up for no scatter-gather use */
244 	srb->use_sg = 0;
245 
246 	/* change the serial number -- toggle the high bit*/
247 	srb->serial_number ^= 0x80000000;
248 
249 	/* set Lun number*/
250 	srb->lun= u8LunNum;
251 
252 	srb->scsi_done = vScsi_SendCmd_Done;
253 }
254 
vSCSICmd_READ_CAPACITY(struct us_data * us,U8 * u8Buffer,U8 u8LunNum)255 void vSCSICmd_READ_CAPACITY(struct us_data *us, U8 *u8Buffer,  U8 u8LunNum)
256 {
257 	Scsi_Cmnd *srb = &us->srb;
258 
259 	/* set the command and the LUN */
260 	memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
261 	srb->cmnd[0] = READ_CAPACITY;
262 
263 	srb->cmd_len = CB_LENGTH_READ_CAPACITY;
264 
265 	/* set the transfer direction */
266 	srb->sc_data_direction = SCSI_DATA_READ;
267 
268 	/* use the new buffer we have */
269 	srb->request_buffer = u8Buffer;
270 
271 	/* set the buffer length for transfer */
272 	srb->request_bufflen = DATA_LENGTH_READ_CAPACITY;
273 
274 	/* set up for no scatter-gather use */
275 	srb->use_sg = 0;
276 
277 	/* change the serial number -- toggle the high bit*/
278 	srb->serial_number ^= 0x80000000;
279 
280 	/* set Lun number*/
281 	srb->lun= u8LunNum;
282 
283 	srb->scsi_done = vScsi_SendCmd_Done;
284 }
285 
vSCSICmd_MODE_SENSE(struct us_data * us,U8 u8PageCode,U8 * u8Buffer,U8 u8LunNum,U16 uBufLen)286 void vSCSICmd_MODE_SENSE(
287 	struct us_data *us,
288 	U8 u8PageCode,
289 	U8 *u8Buffer,
290 	U8 u8LunNum,
291 	U16 uBufLen)
292 {
293 	Scsi_Cmnd *srb = &us->srb;
294 
295 	/* set the command and the LUN */
296 	memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
297 	srb->cmnd[0] = MODE_SENSE6;
298 	srb->cmnd[2] = u8PageCode;
299 	//srb->cmnd[7] = (U8)((uBufLen >> 8) & 0x00FF);
300 	//srb->cmnd[8] = (U8)uBufLen;
301         srb->cmnd[4] = (U8)uBufLen;
302 
303 	srb->cmd_len = CB_LENGTH_MODE_SENSE;
304 
305 	/* set the transfer direction */
306 	srb->sc_data_direction = SCSI_DATA_READ;
307 
308 	/* use the new buffer we have */
309 	srb->request_buffer = u8Buffer;
310 
311 	/* set the buffer length for transfer */
312 	srb->request_bufflen = uBufLen;
313 
314 	/* set up for no scatter-gather use */
315 	srb->use_sg = 0;
316 
317 	/* change the serial number -- toggle the high bit*/
318 	srb->serial_number ^= 0x80000000;
319 
320 	/* set Lun number*/
321 	srb->lun= u8LunNum;
322 
323 	srb->scsi_done = vScsi_SendCmd_Done;
324 }
325 
vSCSICmd_REQUEST_SENSE(struct us_data * us,U8 u8LunNum)326 void vSCSICmd_REQUEST_SENSE(struct us_data *us, U8 u8LunNum)
327 {
328 	Scsi_Cmnd *srb = &us->srb;
329 
330 	/* set the command and the LUN */
331 	memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
332 	srb->cmnd[0] = REQUEST_SENSE;
333 	srb->cmnd[4] = DATA_LENGTH_REQUEST_SENSE;
334 
335 	srb->cmd_len = CB_LENGTH_REQUEST_SENSE;
336 
337 	/* set the transfer direction */
338 	srb->sc_data_direction = SCSI_DATA_READ;
339 
340 	/* use the new buffer we have */
341 	srb->request_buffer = srb->sense_buffer;
342 
343 	/* set the buffer length for transfer */
344 	srb->request_bufflen = DATA_LENGTH_REQUEST_SENSE;
345 
346 	/* set up for no scatter-gather use */
347 	srb->use_sg = 0;
348 
349 	/* change the serial number -- toggle the high bit*/
350 	srb->serial_number ^= 0x80000000;
351 
352 	/* set Lun number*/
353 	srb->lun= u8LunNum;
354 
355 	srb->scsi_done = vScsi_SendCmd_Done;
356 }
357 
vSCSICmd_TEST_UNIT_READY(struct us_data * us,U8 u8LunNum)358 void vSCSICmd_TEST_UNIT_READY(struct us_data *us, U8 u8LunNum)
359 {
360 	Scsi_Cmnd *srb = &us->srb;
361 
362 	/* set the command and the LUN */
363 	memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
364 	srb->cmnd[0] = TEST_UNIT_READY;
365 
366 	srb->cmd_len = CB_LENGTH_TEST_UNIT_READY;
367 
368 	/* set the transfer direction */
369 	srb->sc_data_direction = SCSI_DATA_READ;
370 
371 	/* use the new buffer we have */
372 //	srb->request_buffer = srb->sense_buffer;
373 
374 	/* set the buffer length for transfer */
375 	srb->request_bufflen = 0;
376 
377 	/* set up for no scatter-gather use */
378 	srb->use_sg = 0;
379 
380 	/* change the serial number -- toggle the high bit*/
381 	srb->serial_number ^= 0x80000000;
382 
383 	/* set Lun number*/
384 	srb->lun= u8LunNum;
385 
386 	srb->scsi_done = vScsi_SendCmd_Done;
387 }
388 
389 
bSCSI_REQ_SENSE(U8 uPort,U8 uLunNum,U8 * pSenseBuf)390 BOOL bSCSI_REQ_SENSE(U8 uPort, U8 uLunNum, U8 *pSenseBuf)
391 {
392     //BOOL	err;
393     BOOL      bRet=FALSE;
394     struct us_data *pMass_stor;
395     U8      host_id;
396 
397 
398     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
399         return FALSE;
400     //err = MsOS_ObtainSemaphore(g_SCSISem,MSOS_WAIT_FOREVER);
401     //USB_ASSERT(err, "Wait SCSI sem fail\n");
402     //err=MsOS_ObtainMutex(_s32MutexUSB, MSOS_WAIT_FOREVER);
403     // if (err==FALSE) return FALSE;
404     //U32 u32OldIntr;
405 
406     // MsOS_DisableAllInterrupts(u32OldIntr);
407 
408     //lock_usb_core();
409     host_id = pMass_stor->host_id;
410     USBCriticalSectionIn(host_id);
411 
412     memset(&pMass_stor->srb, 0, sizeof(struct scsi_cmnd ));
413 
414     vSCSICmd_REQUEST_SENSE(pMass_stor, uLunNum);
415 
416     usb_stor_control_thread(pMass_stor);
417 
418     if (pMass_stor->srb.result == SAM_STAT_GOOD)
419     {
420         memcpy(pSenseBuf, pMass_stor->srb.sense_buffer, DATA_LENGTH_REQUEST_SENSE);
421         bRet=TRUE;
422     }
423     else
424         bRet=FALSE;
425 
426     //unlock_usb_core();
427     USBCriticalSectionOut(host_id);
428 
429    //MsOS_ReleaseMutex(_s32MutexUSB);
430   // MsOS_RestoreAllInterrupts(u32OldIntr);
431    return bRet;
432 }
433 
434 
bSCSI_INQUIRY(U8 uPort,U8 uLunNum,U8 * pIngBuf)435 BOOL bSCSI_INQUIRY(U8 uPort, U8 uLunNum, U8 *pIngBuf)
436 {
437     BOOL	bRet = FALSE;
438     int		i;
439     struct us_data *pMass_stor;
440     U8      host_id;
441 	//BOOL	err;
442 
443 	//err = MsOS_ObtainSemaphore(g_SCSISem,MSOS_WAIT_FOREVER);
444 	//USB_ASSERT(err, "Wait SCSI sem fail\n");
445       //err=MsOS_ObtainMutex(_s32MutexUSB, MSOS_WAIT_FOREVER);
446        //if (err==FALSE) return FALSE;
447  //   U32 u32OldIntr;
448 
449   //  MsOS_DisableAllInterrupts(u32OldIntr);
450 
451 	//lock_usb_core();
452     //USBCriticalSectionIn(uPort);
453     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
454         return FALSE;
455 
456     host_id = pMass_stor->host_id;
457     USBCriticalSectionIn(host_id);
458     for(i =0; i< ScsiCmd_Fail_Retry ;i++)
459     {
460         if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
461             break;
462 
463         memset(&pMass_stor->srb, 0, sizeof(struct scsi_cmnd ));
464         vSCSICmd_INQUIRY(pMass_stor, pIngBuf, uLunNum);
465 
466         usb_stor_control_thread(pMass_stor);
467 
468         if(pMass_stor->srb.result == SAM_STAT_GOOD)
469         {
470             bRet = TRUE;
471             break;
472         }
473     }
474     //unlock_usb_core();
475     USBCriticalSectionOut(host_id);
476 
477 	//err = MsOS_ReleaseSemaphore(g_SCSISem);
478 	//USB_ASSERT(err, "Signal SCSI sem fail\n");
479      //MsOS_ReleaseMutex(_s32MutexUSB);
480  //  MsOS_RestoreAllInterrupts(u32OldIntr);
481 
482     return bRet;
483 }
484 
485 // save all Mode Sense(page code=0x3F) data
486 // Now we only use u8ModeSenseData[2], this byte save device
487 // write protection information
bSCSI_MODE_SENSE(U8 uPort,U8 uLunNum,U8 * pModSenBuf,U16 uBufLen)488 BOOL bSCSI_MODE_SENSE(U8 uPort, U8 uLunNum, U8 *pModSenBuf, U16 uBufLen)
489 {
490     int		i;
491     BOOL	bRet = FALSE;
492     struct us_data *pMass_stor;
493     U8      host_id;
494 	//BOOL			err;
495 
496 	//err = MsOS_ObtainSemaphore(g_SCSISem,MSOS_WAIT_FOREVER);
497 	//USB_ASSERT(err, "Wait SCSI sem fail\n");
498 	//err=MsOS_ObtainMutex(_s32MutexUSB, MSOS_WAIT_FOREVER);
499        //if (err==FALSE) return FALSE;
500     //U32 u32OldIntr;
501 
502    // MsOS_DisableAllInterrupts(u32OldIntr);
503 
504 	//lock_usb_core();
505     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
506         return FALSE;
507 
508     host_id = pMass_stor->host_id;
509     USBCriticalSectionIn(host_id);
510     for(i =0; i< ScsiCmd_Fail_Retry ; i++)
511     {
512         if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
513             break;
514 
515         memset(&pMass_stor->srb, 0, sizeof(struct scsi_cmnd ));
516 
517         vSCSICmd_MODE_SENSE(pMass_stor, 0x3F, pModSenBuf, uLunNum, uBufLen);
518 
519         usb_stor_control_thread(pMass_stor);
520 
521         if(pMass_stor->srb.result == SAM_STAT_GOOD)
522         {
523             bRet = TRUE;
524             break;
525         }
526 
527     }
528     //unlock_usb_core();
529     USBCriticalSectionOut(host_id);
530 
531 //	err = MsOS_ReleaseSemaphore(g_SCSISem);
532 //	USB_ASSERT(err, "Signal SCSI sem fail\n");
533    //MsOS_ReleaseMutex(_s32MutexUSB);
534   // MsOS_RestoreAllInterrupts(u32OldIntr);
535 
536     return bRet;
537 }
538 
bSCSI_READ_CAPACITY(U8 uPort,U8 uLunNum,U32 * pTotalBlks,U32 * pBlkSize)539 BOOL bSCSI_READ_CAPACITY(U8 uPort, U8 uLunNum, U32 *pTotalBlks, U32 *pBlkSize)
540 {
541     int		i;
542     BOOL	bRet = FALSE;
543     U8	CapBuf[DATA_LENGTH_READ_CAPACITY];
544     struct us_data *pMass_stor;
545     U8      host_id;
546 	//BOOL			err;
547 
548 	//err = MsOS_ObtainSemaphore(g_SCSISem,MSOS_WAIT_FOREVER);
549 	//USB_ASSERT(err, "Wait SCSI sem fail\n");
550        //err=MsOS_ObtainMutex(_s32MutexUSB, MSOS_WAIT_FOREVER);
551       //if (err==FALSE) return FALSE;
552  //   U32 u32OldIntr;
553 
554   //  MsOS_DisableAllInterrupts(u32OldIntr);
555 
556 
557 	//lock_usb_core();
558     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
559         return bRet;
560     host_id = pMass_stor->host_id;
561     USBCriticalSectionIn(host_id);
562     for(i =0; i< ScsiCmd_Fail_Retry ; i++)
563     {
564         if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
565             break;
566 
567         memset(&pMass_stor->srb, 0, sizeof(struct scsi_cmnd ));
568 
569         vSCSICmd_READ_CAPACITY(pMass_stor, CapBuf, uLunNum);
570 
571         usb_stor_control_thread(pMass_stor);
572 
573         if(pMass_stor->srb.result == SAM_STAT_GOOD)
574         {
575             *pTotalBlks = (((U32)CapBuf[0] << 24) |
576             ((U32)CapBuf[1] << 16) |
577             ((U32)CapBuf[2] << 8) |
578             ((U32)CapBuf[3] )) + 1 ;
579 
580             *pBlkSize = ((U32)CapBuf[4] << 24) |
581             ((U32)CapBuf[5] << 16) |
582             ((U32)CapBuf[6] << 8) |
583             ((U32)CapBuf[7] ) ;
584 
585             SCSI_DbgPrint("SCSI CAPACITY : SCSI Device total block <0x%x%x>\n",
586             (U16)(*pTotalBlks >> 16),
587             (U16)*pTotalBlks);
588             SCSI_DbgPrint("SCSI CAPACITY : SCSI Product block size <0x%x bytes>\n",
589             (U16)*pBlkSize);
590 
591             bRet = TRUE;
592             break;
593         }
594     }
595     //unlock_usb_core();
596     USBCriticalSectionOut(host_id);
597 #if 0                     //Disable it, for testing new feature which to support different block size
598     if(*pBlkSize != 512)  //File system only support BlkSize=512
599 		bRet = FALSE;
600 #endif
601 	//err = MsOS_ReleaseSemaphore(g_SCSISem);
602 	//USB_ASSERT(err, "Signal SCSI sem fail\n");
603     //MsOS_ReleaseMutex(_s32MutexUSB);
604    //MsOS_RestoreAllInterrupts(u32OldIntr);
605 
606     return bRet;
607 }
608 
609 // GGYY
610 // Some cameras with CBI subclass can't accept the TUR, but others need.
611 // Our solution is don't send real TUR to camera. If the command Get Capacity is failed,
612 // we send the real TUR.
bSCSI_TEST_UNIT_READY(U8 uPort,U8 uLunNum,BOOL CheckCBI)613 BOOL bSCSI_TEST_UNIT_READY(U8 uPort, U8 uLunNum, BOOL CheckCBI)
614 {
615     int		i;
616     BOOL	bRet = FALSE;
617     struct us_data *pMass_stor;
618     U8      host_id;
619 	//BOOL			err;
620 
621 	//err = MsOS_ObtainSemaphore(g_SCSISem,MSOS_WAIT_FOREVER);
622 	//USB_ASSERT(err, "Wait SCSI sem fail\n");
623        //err=MsOS_ObtainMutex(_s32MutexUSB, MSOS_WAIT_FOREVER);
624        //if (err==FALSE) return FALSE;
625   //  U32 u32OldIntr;
626 
627    // MsOS_DisableAllInterrupts(u32OldIntr);
628       // diag_printf("SCSI TEST UNIT READY--");
629 	//lock_usb_core();
630     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
631         return FALSE;
632     host_id = pMass_stor->host_id;
633     USBCriticalSectionIn(host_id);
634 
635     if (CheckCBI)
636     {
637         if ( ( Mass_stor_us[uPort] != NULL) &&
638             (Mass_stor_us[uPort]->subclass == US_SC_8070) &&
639             (Mass_stor_us[uPort]->protocol == US_PR_CBI) )
640         {
641             bRet = TRUE;
642             goto Fun_Exit;
643         }
644     }
645 
646     for(i =0; i< ScsiCmd_Fail_TUR_Retry ;i++)
647     {
648         if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
649         break;
650 
651         memset(&pMass_stor->srb, 0, sizeof(struct scsi_cmnd ));
652 
653         vSCSICmd_TEST_UNIT_READY(pMass_stor, uLunNum);
654 
655         usb_stor_control_thread(pMass_stor);
656 
657         if(pMass_stor->srb.result == SAM_STAT_GOOD)
658         {
659             //diag_printf(" Succeed for lun %d\n",uLunNum);
660 
661             bRet = TRUE;
662             break;
663         }
664         else
665         {
666             if (i > ScsiCmd_Fail_Retry)
667                 diag_printf("TUR failed retry %d\n",i);
668         }
669     }
670 
671 Fun_Exit: //GGYY
672 	//unlock_usb_core();
673     USBCriticalSectionOut(host_id);
674 
675 	//err = MsOS_ReleaseSemaphore(g_SCSISem);
676 	//USB_ASSERT(err, "Signal SCSI sem fail\n");
677    //MsOS_ReleaseMutex(_s32MutexUSB);
678 //   MsOS_RestoreAllInterrupts(u32OldIntr);
679 
680     return bRet;
681 }
bInit_USB_LUN(U8 uPort,U8 uLunIdx)682 
683 BOOL bInit_USB_LUN(U8 uPort, U8 uLunIdx)
684 {
685     struct us_data *pMass_stor;
686     struct LUN_Device* LunDevice;
687     U8		pIngBuf[DATA_LENGTH_INQUIRY];
688     U8		pModSenBuf[8];
689     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
690         return FALSE;
691 
692     LunDevice = pMass_stor->Mass_stor_device;
693 
694     if(bSCSI_TEST_UNIT_READY(uPort, uLunIdx, TRUE))	// GGYY
695     {
696         SCSI_DbgPrint("Scsi Device is ready (Lun=%d).\n", uLunIdx);
697     }
698     else
699         return FALSE;
700 
701     if (bSCSI_INQUIRY(uPort, uLunIdx, pIngBuf))
702     {
703         LunDevice[uLunIdx].u8DevType = (pIngBuf[1] & 0x80) | (pIngBuf[0] & 0x1F);
704         SCSI_DbgPrint("SCSI INQUIRY : SCSI Device ID <%s>\n",&pMass_stor->device.u8VendorID);
705         SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ID <%s>\n",&pMass_stor->device.u8ProductID);
706         SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ver <%s>\n",&pMass_stor->device.u8ProductVer);
707     }
708     else
709         return FALSE;
710 
711     if( (LunDevice[uLunIdx].u8DevType & 0x1F) == TYPE_ROM) // FS does't support CD-ROM well
712     {
713         return FALSE;
714     }
715 
716     if(bSCSI_READ_CAPACITY(uPort, uLunIdx, &LunDevice[uLunIdx].u32BlockTotalNum, &LunDevice[uLunIdx].u32BlockSize))
717     {
718         SCSI_DbgPrint("Read CAPACITY: TotalBlks %d, BlkSize %d",
719                                 LunDevice[uLunIdx].u32BlockTotalNum, LunDevice[uLunIdx].u32BlockSize);
720         LunDevice[uLunIdx].u32BlockSize_log2 = get_value_log2(LunDevice[uLunIdx].u32BlockSize);
721     }
722     else
723     {
724         // GGYY
725         // Some cameras need real TUR command
726         // to start work. We send real TUR here for these special devices.
727         bSCSI_TEST_UNIT_READY(uPort, uLunIdx, FALSE);
728         return FALSE;
729     }
730 
731     LunDevice[uLunIdx].bWriteProtect = FALSE;
732     if (bSCSI_MODE_SENSE(uPort, uLunIdx, pModSenBuf, 8))		// Just read the header of mode sense
733     {
734         LunDevice[uLunIdx].bWriteProtect = (pModSenBuf[2]==0x80) ? TRUE:FALSE;
735         if (LunDevice[uLunIdx].bWriteProtect )
736         {
737             diag_printf("Usb Device WriteProtected! \n");
738         }
739     }
740 
741     return TRUE;
742 }
743 extern MS_BOOL UsbReady;
bSCSI_Initial(U8 uPort)744 extern MS_BOOL UsbReady_Port2;
745 BOOL bSCSI_Initial(U8 uPort)
746 {
747     BOOL		bFoundValidDev = FALSE;
748     struct us_data *pMass_stor;
749     struct LUN_Device* LunDevice;
750     U8		pIngBuf[DATA_LENGTH_INQUIRY];
751     int			LunIdx;
752 
753     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
754         return FALSE;
755 
756     LunDevice = pMass_stor->Mass_stor_device;
757     // Firstly, we send a Inquiry to every LUN
758     // It is simulated from PC
759     for (	LunIdx=0; LunIdx<=pMass_stor->max_lun; LunIdx++)
760     {
761         LunDevice[LunIdx].bDeviceReady = FALSE;
762         if (LunIdx == 0)
763         {
764             memset(pIngBuf, 0, DATA_LENGTH_INQUIRY);
765             if (bSCSI_INQUIRY(uPort, 0, pIngBuf))
766             {
767                 // save device type
768                 pMass_stor->device.u8DeviceType = (pIngBuf[0] & 0x1F);
769                 // save vendor string, total 8 bytes
770                 memcpy(pMass_stor->device.u8VendorID, &pIngBuf[8], 8);
771                 // save product string, total 16 bytes
772                 memcpy(pMass_stor->device.u8ProductID, &pIngBuf[16], 16);
773                 // save revision information, total 4 bytes
774                 memcpy(pMass_stor->device.u8ProductVer, &pIngBuf[32], 4);
775                 SCSI_DbgPrint("SCSI INQUIRY : SCSI Device ID <%s>\n",&pMass_stor->device.u8VendorID);
776                 SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ID <%s>\n",&pMass_stor->device.u8ProductID);
777                 SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ver <%s>\n",&pMass_stor->device.u8ProductVer);
778             }
779             else
780                 goto Init_Done;
781         }
782         else
783         {
784             if (!bSCSI_INQUIRY(uPort, LunIdx, pIngBuf))
785                 goto Init_Done;
786         }
787     }
788 
789     // Start to init every LUN
790     for (	LunIdx=0; LunIdx<=pMass_stor->max_lun; LunIdx++)
791     {
792         if (!bInit_USB_LUN(uPort, LunIdx))
793             continue;
794 
795         LunDevice[LunIdx].bDeviceReady = TRUE;
796 
797         if (ConnectUSBDisk(uPort, LunIdx))
798             LunDevice[LunIdx].bFSInit = TRUE;
799 
800         bFoundValidDev = TRUE;
801     }
802 Init_Done:
803     SCSI_DbgPrint("Exit bSCSI_Initial %d\n", bFoundValidDev);
804 
805     if (bFoundValidDev)
806     {
807         if (uPort < MAX_USTOR)
808             UsbReady=TRUE;
809         else if (uPort < MAX_USTOR*2)
810             UsbReady_Port2=TRUE;
811     }
812     return bFoundValidDev;
813 }
ChkUsbReady(void)814 
815 BOOL ChkUsbReady(void)
816 {
817     return UsbReady;
818 }
ChkUsbReadyEx(MS_U8 uHostPort)819 
820 MS_BOOL ChkUsbReadyEx(MS_U8 uHostPort)
821 {
822     if (uHostPort == 0)
823             return UsbReady;
824     else if (uHostPort == 1)
825             return UsbReady_Port2;
826     else
827     {
828         diag_printf("Invalid port number for ChkUsbReadyEx\n");
829         return FALSE;
830     }
831 }
bInit_USB_Disk(U8 uPort)832 
833 BOOL bInit_USB_Disk(U8 uPort)
834 {
835     struct us_data *pMass_stor;
836     int		i;
837 
838     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
839         return FALSE;
840 
841     for (i=0; i<=pMass_stor->max_lun; i++)
842     {
843         RemoveUSBDiskPort(uPort, i);
844         pMass_stor->Mass_stor_device[i].u8LunNum = i;
845     }
846     return bSCSI_Initial(uPort);
847 }
848 #if 1
vChk_USB_LUNs(U8 uPort)849 
850 void vChk_USB_LUNs(U8 uPort)
851 {
852     int			LunIdx;
853     struct us_data *pMass_stor;
854     struct LUN_Device* LunDevice;
855     BOOL		bLUNSts;
856 
857     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
858         return;
859 
860     LunDevice = pMass_stor->Mass_stor_device;
861 
862     for (LunIdx=0; LunIdx<=pMass_stor->max_lun; LunIdx++)
863     {	// GGYY
864         if ((bLUNSts = bSCSI_TEST_UNIT_READY(uPort, LunIdx, TRUE)) != LunDevice[LunIdx].bDeviceReady) // Status of LUN changed
865         {
866             if (bLUNSts)	// No media card -> has media card
867             {
868                 if (bInit_USB_LUN(uPort, LunIdx))
869                 {
870                     LunDevice[LunIdx].bDeviceReady = TRUE;
871                     RemoveUSBDiskPort(uPort, LunIdx);
872                     if (ConnectUSBDisk(uPort, LunIdx))
873                         LunDevice[LunIdx].bFSInit = TRUE;
874                 }
875             }
876             else	// has media card -> no media card
877             {
878                 LunDevice[LunIdx].bDeviceReady = FALSE;
879                 LunDevice[LunIdx].bFSInit = FALSE;
880                 diag_printf("F->R\n");
881                 RemoveUSBDiskPort(uPort, LunIdx);
882 
883             }
884         }
885     }
886 }
887 #endif
vRemove_DISK_LUNs(U8 uPort)888 
889 
890 void vRemove_DISK_LUNs(U8 uPort)
891 {
892     int			LunIdx;
893     struct us_data *pMass_stor;
894     struct LUN_Device* LunDevice;
895 
896     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
897         return;
898 
899     LunDevice = pMass_stor->Mass_stor_device;
900 
901     for (LunIdx=0; LunIdx<=pMass_stor->max_lun; LunIdx++)
902     {
903         LunDevice[LunIdx].bDeviceReady = FALSE;
904         LunDevice[LunIdx].bFSInit = FALSE;
905         RemoveUSBDiskPort(uPort, LunIdx);
906     }
907 }
908 
909 
910 BOOL bSCSI_ERASE(U8 uPort, U8 uLunNum, U32 u32BlockAddr, U32 u32BlockNum,
911 							U32 u32SectorSize)
912 {
913 	if (uLunNum > Mass_stor_us[uPort]->max_lun)
914 		return FALSE;
915 	else
bSCSI_Read_10_512(U8 uPort,U8 uLunNum,U32 u32BlockAddr,U32 u32BlockNum,U8 * u8Buffer)916 		return TRUE;
917 }
918 
919 BOOL bSCSI_Read_10_512(U8 uPort, U8 uLunNum, U32 u32BlockAddr, U32 u32BlockNum,
920 							U8 *u8Buffer)
921 {
922 	struct us_data *pMass_stor; //USB_2
923 	//U32 u32TransBlockTmp, u32TransSizeTmp,u32BlockOfSet = 0, u32TransOfSet = 0;
924 	BOOL	bRet = TRUE;;
925 
926 	if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
927 	{
928 		bRet = FALSE;
929 		goto Write10_done;
930 	}
931 
932 	struct LUN_Device* LunDevice = pMass_stor->Mass_stor_device;
933 	U32 u32BlkSize_log2 = LunDevice[uLunNum].u32BlockSize_log2;
934 	U32 u32DataLeft = u32BlockNum << 9;
935 	U32 u32BlockSize = LunDevice[uLunNum].u32BlockSize;
936 	U8  *lpu8TempBuf = NULL;
937 
938 	U32 u32RealBlkAddr;
939 	U32 u32RealBlkOffset;
940 	U32 u32RealBlkLast;
941 	U32 u32RealBlkLeft;
942 	U32 u32CopyBytes;
943 	U32 u32BlockNumAdj=0;
944 
945 	if(u32BlockSize != 512)
946 	{
947 	    u32RealBlkAddr = (u32BlockAddr * 512) >> u32BlkSize_log2;
948 		u32RealBlkOffset = u32BlockAddr * 512 - u32RealBlkAddr * u32BlockSize;
949 
950 		u32RealBlkLast = ((u32BlockAddr + u32BlockNum) * 512) >> u32BlkSize_log2;
951 		u32RealBlkLeft = ((u32BlockAddr + u32BlockNum) * 512) - u32RealBlkLast * u32BlockSize;
952 
953 		u32BlockNumAdj = u32RealBlkLast - u32RealBlkAddr + 1;
954 
955 
956 		if(u32RealBlkOffset > 0)
957 		{
958 		    lpu8TempBuf = kmalloc(u32BlockSize, GFP_KERNEL);
959 		    bRet = bSCSI_Read_10(uPort, uLunNum, u32RealBlkAddr, 1, lpu8TempBuf);
960 			if(!bRet)
961 				goto Write10_done;
962 			if(u32DataLeft > (u32BlockSize - u32RealBlkOffset))
963 			{
964 				u32CopyBytes = u32BlockSize - u32RealBlkOffset;
965 			    u32DataLeft -= u32CopyBytes;
966 				//u32ByteOffset = u32RealBlkOffset;
967 			}
968 			else
969 			{
970 			    u32DataLeft = 0;
971 				u32CopyBytes = u32DataLeft;
972 			}
973 
974 			memcpy(u8Buffer,
975 				   lpu8TempBuf + u32RealBlkOffset ,
976 				   (size_t)u32CopyBytes);
977 			u32BlockNumAdj--;
978 			u32RealBlkAddr++;
979 			u8Buffer += u32CopyBytes;
980 		}//Deal with beginning block
981 
982 		if(u32BlockNumAdj > 1)  //Transfer mid blocks
983 		{
984       	    if(u32RealBlkLeft != 0)
985 				u32BlockNumAdj--;
986 
987 			bRet = bSCSI_Read_10(uPort, uLunNum, u32RealBlkAddr, u32BlockNumAdj, u8Buffer);
988 			if(!bRet)
989 				goto Write10_done;
990 			u8Buffer += u32BlockNumAdj * u32BlockSize;
991 			u32DataLeft -= u32BlockNumAdj * u32BlockSize;
992 		    if(u32DataLeft > 0)
993 				u32BlockNumAdj = 1;
994 			else
995 				u32BlockNumAdj = 0;
996 		}
997 
998 		if(u32BlockNumAdj > 0) // Have last block
999 		{
1000 			if(u32RealBlkLeft > 0)
1001 			{
1002 			    if(lpu8TempBuf == NULL)
1003 			        lpu8TempBuf = kmalloc(u32BlockSize, GFP_KERNEL);
1004 			    bRet = bSCSI_Read_10(uPort, uLunNum, u32RealBlkLast, 1, lpu8TempBuf);
1005 				if(!bRet)
1006 					goto Write10_done;
1007 
1008 				memcpy(u8Buffer,
1009 					   lpu8TempBuf,
1010 					   (size_t)u32DataLeft);
1011 			}//Deal with ending block
1012 		}
1013 	}
1014 	else
1015 	{
1016 	    bRet = bSCSI_Read_10(uPort, uLunNum, u32BlockAddr, u32BlockNum, u8Buffer);
1017 	}
1018 
1019 Write10_done:
1020 	if(lpu8TempBuf != NULL)
1021 		kfree(lpu8TempBuf);
1022 	return bRet;
1023 }
bSCSI_Read_10(U8 uPort,U8 uLunNum,U32 u32BlockAddr,U32 u32BlockNum,U8 * u8Buffer)1024 
1025 
1026 
1027 BOOL bSCSI_Read_10(U8 uPort, U8 uLunNum, U32 u32BlockAddr, U32 u32BlockNum,
1028 							U8 *u8Buffer)
1029 {
1030 	//BOOL			err;
1031 
1032        //err=MsOS_ObtainMutex(_s32MutexUSB, MSOS_WAIT_FOREVER);
1033        //if (err==FALSE) return FALSE;
1034 
1035 	struct us_data *pMass_stor; //USB_2
1036 	U32 u32TransBlockTmp, u32TransSizeTmp,u32BlockOfSet = 0, u32TransOfSet = 0;
1037 	BOOL	bRet = TRUE, bConnSts;
1038 	int		i;
1039     U8      host_id;
1040 
1041 //    U32 u32OldIntr;
1042 
1043     //MsOS_DisableAllInterrupts(u32OldIntr);
1044 
1045 	//lock_usb_core();
1046 
1047     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
1048         return FALSE;
1049     host_id = pMass_stor->host_id;
1050     USBCriticalSectionIn(host_id);
1051     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
1052     {
1053         bRet=FALSE;
1054         goto Func_Done;
1055     }
1056 
1057 	struct LUN_Device* LunDevice = pMass_stor->Mass_stor_device;
1058 	U32 u32BlkSize_log2 = LunDevice[uLunNum].u32BlockSize_log2;
1059 	U32 u32DataLeft = u32BlockNum << u32BlkSize_log2;
1060 	if (uLunNum > pMass_stor->max_lun)
1061 	{
1062 		SCSI_DbgPrint("Invalid LUN Index%s","");
1063 		bRet = FALSE;
1064 		goto Func_Done;
1065 	}
1066 	if (LunDevice[uLunNum].u32BlockTotalNum < u32BlockNum)
1067 	{
1068 	       bRet=FALSE;
1069 		goto Func_Done;
1070 	}
1071 	if (LunDevice[uLunNum].bDeviceReady == FALSE)
1072 	{
1073 		bRet = FALSE;
1074 		goto Func_Done;
1075 	}
1076 
1077 	while(u32DataLeft > 0)
1078 	{
1079 		if(u32DataLeft > Scsi_Max_Transfer_Len)
1080 		{
1081 			u32TransBlockTmp = Scsi_Max_Transfer_Len >> u32BlkSize_log2;
1082 			u32TransSizeTmp = u32TransBlockTmp << u32BlkSize_log2;
1083 			u32DataLeft -= u32TransSizeTmp;
1084 		}
1085 		else
1086 		{
1087 			u32TransBlockTmp = u32DataLeft >> u32BlkSize_log2;
1088 			u32TransSizeTmp = u32DataLeft;
1089 			u32DataLeft = 0;
1090 		}
1091 	//	err = MsOS_ObtainSemaphore(g_SCSISem,MSOS_WAIT_FOREVER);
1092 		//USB_ASSERT(err, "Wait SCSI sem fail\n");
1093 
1094 		for(i =0; i< ScsiCmd_Fail_Retry ;i++)
1095 		{
1096                         //struct usb_hcd *hcd = pMass_stor->pusb_dev->bus->hcpriv;
1097                         struct usb_hcd *hcd;
1098 
1099                         hcd = msc_get_hcd(host_id);
1100                         bConnSts = MDrv_UsbDeviceConnect_EX(hcd) & !(hcd->isRootHubPortReset);
1101 
1102                         if (!bConnSts)
1103                         {
1104                             struct ehci_hcd *ehci = hcd_to_ehci(hcd);
1105                             diag_printf("Device is disconnect @ read 10\n");
1106                             if (hcd->isRootHubPortReset) // debug purpose
1107                                 diag_printf("bSCSI_Read10:: ehci reset done = %x, isRootHubPortReset = %x\n", ehci->reset_done[0], hcd->isRootHubPortReset);
1108 
1109                             bRet = FALSE;
1110                             goto Func_Done;
1111                         }
1112 
1113                         //if (pMass_stor==NULL)
1114                         if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
1115                         {
1116                             diag_printf("Mass_stor_us==NULL!\n");
1117                             bRet = FALSE;
1118                             goto Func_Done;
1119                         }
1120 
1121             			memset(&pMass_stor->srb, 0, sizeof(struct scsi_cmnd ));
1122 
1123             			// Build SCSI command.
1124             			vSCSICmd_READ_10(pMass_stor, uLunNum,
1125             								u32BlockAddr + u32BlockOfSet, (U16)u32TransBlockTmp, u8Buffer + u32TransOfSet);
1126             			// call mass storage function to send scsi command
1127             			usb_stor_control_thread(pMass_stor);
1128             			if (pMass_stor->srb.result != SAM_STAT_GOOD)
1129             			{
1130             				if (pMass_stor->srb.result == SAM_STAT_CHECK_CONDITION)
1131             				{
1132             					if(((pMass_stor->srb.sense_buffer[2] & 0xf) == 0x02) &&
1133             						(pMass_stor->srb.sense_buffer[12]  == 0x3A))
1134             					{
1135             						LunDevice[uLunNum].bDeviceReady = FALSE;
1136             					}
1137             					else if(((pMass_stor->srb.sense_buffer[2] & 0xf) == 0x06) &&
1138             						(pMass_stor->srb.sense_buffer[12]  == 0x28))
1139             					{
1140             						LunDevice[uLunNum].bDeviceReady = FALSE;
1141             					}
1142             				}
1143 
1144             				SCSI_DbgPrint("Scsi READ_10 command failed.%s","\n");
1145             				bRet = FALSE;
1146             			}
1147             			else
1148             			{
1149             				bRet = TRUE;
1150             				break;
1151             			}
1152 
1153 		}
1154 
1155 		//err = MsOS_ReleaseSemaphore(g_SCSISem);
1156 		//USB_ASSERT(err, "Signal SCSI sem fail\n");
1157 
1158 		u32BlockOfSet += u32TransBlockTmp;
1159 		u32TransOfSet += u32TransSizeTmp;
1160 
1161 		if (bRet == FALSE)
1162 			break;
1163 	}
1164 
1165 Func_Done:
1166     //unlock_usb_core();
1167     //MsOS_ReleaseMutex(_s32MutexUSB);
1168     USBCriticalSectionOut(host_id);
1169     //   MsOS_RestoreAllInterrupts(u32OldIntr);
1170 
1171     return bRet;
1172 }
1173 
1174 BOOL bSCSI_Write_10_512(U8 uPort, U8 uLunNum, U32 u32BlockAddr, U32 u32BlockNum,
1175 							U8 *u8Buffer)
1176 {
1177 	struct us_data *pMass_stor; //USB_2
1178 	//U32 u32TransBlockTmp, u32TransSizeTmp,u32BlockOfSet = 0, u32TransOfSet = 0;
1179 	BOOL	bRet = TRUE;;
1180 
1181 	if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
1182 	{
1183 		bRet = FALSE;
1184 		goto Write10_done;
1185 	}
1186 
1187 	struct LUN_Device* LunDevice = pMass_stor->Mass_stor_device;
1188 	U32 u32BlkSize_log2 = LunDevice[uLunNum].u32BlockSize_log2;
1189 	U32 u32DataLeft = u32BlockNum << 9;
1190 	U32 u32BlockSize = LunDevice[uLunNum].u32BlockSize;
1191 	U8  *lpu8TempBuf = NULL;
1192 
1193 	U32 u32RealBlkAddr;
1194 	U32 u32RealBlkOffset;
1195 	U32 u32RealBlkLast;
1196 	U32 u32RealBlkLeft;
1197 	U32 u32CopyBytes;
1198 	U32 u32BlockNumAdj=0;
1199 
1200 	if(u32BlockSize != 512)
1201 	{
1202 	    u32RealBlkAddr = (u32BlockAddr * 512) >> u32BlkSize_log2;
1203 		u32RealBlkOffset = u32BlockAddr * 512 - u32RealBlkAddr * u32BlockSize;
1204 
1205 		u32RealBlkLast = ((u32BlockAddr + u32BlockNum) * 512) >> u32BlkSize_log2;
1206 		u32RealBlkLeft = ((u32BlockAddr + u32BlockNum) * 512) - u32RealBlkLast * u32BlockSize;
1207 
1208 		u32BlockNumAdj = u32RealBlkLast - u32RealBlkAddr + 1;
1209 
1210 
1211 		if(u32RealBlkOffset > 0)
1212 		{
1213 		    lpu8TempBuf = kmalloc(u32BlockSize, GFP_KERNEL);
1214 		    bRet = bSCSI_Read_10(uPort, uLunNum, u32RealBlkAddr, 1, lpu8TempBuf);
1215 			if(!bRet)
1216 				goto Write10_done;
1217 			if(u32DataLeft > (u32BlockSize - u32RealBlkOffset))
1218 			{
1219 				u32CopyBytes = u32BlockSize - u32RealBlkOffset;
1220 			    u32DataLeft -= u32CopyBytes;
1221 				//u32ByteOffset = u32RealBlkOffset;
1222 			}
1223 			else
1224 			{
1225 			    u32DataLeft = 0;
1226 				u32CopyBytes = u32DataLeft;
1227 			}
1228 
1229 			memcpy(lpu8TempBuf + u32RealBlkOffset ,
1230 				   u8Buffer,
1231 				   (size_t)u32CopyBytes);
1232 			bRet = bSCSI_Write_10(uPort, uLunNum, u32RealBlkAddr, 1, lpu8TempBuf);
1233 			if(!bRet)
1234 				goto Write10_done;
1235 			u32BlockNumAdj--;
1236 			u32RealBlkAddr++;
1237 			u8Buffer += u32CopyBytes;
1238 		}//Deal with beginning block
1239 
1240 		if(u32BlockNumAdj > 0)  //Transfer mid blocks
1241 		{
1242 		    if(u32RealBlkLeft != 0)
1243 				u32BlockNumAdj--;
1244 
1245 			bRet = bSCSI_Write_10(uPort, uLunNum, u32RealBlkAddr, u32BlockNumAdj, u8Buffer);
1246 			if(!bRet)
1247 				goto Write10_done;
1248 			u8Buffer += u32BlockNumAdj * u32BlockSize;
1249 			u32DataLeft -= u32BlockNumAdj * u32BlockSize;
1250 		    if(u32DataLeft > 0)
1251 				u32BlockNumAdj = 1;
1252 			else
1253 				u32BlockNumAdj = 0;
1254 		}
1255 
1256 		if(u32BlockNumAdj > 0) // Have last block
1257 		{
1258 			if(u32RealBlkLeft > 0)
1259 			{
1260 			    if(lpu8TempBuf == NULL)
1261 			        lpu8TempBuf = kmalloc(u32BlockSize, GFP_KERNEL);
1262 			    bRet = bSCSI_Read_10(uPort, uLunNum, u32RealBlkLast, 1, lpu8TempBuf);
1263 				if(!bRet)
1264 					goto Write10_done;
1265 
1266 				memcpy(lpu8TempBuf,
1267 					   u8Buffer,
1268 					   (size_t)u32DataLeft);
1269 				bRet = bSCSI_Write_10(uPort, uLunNum, u32RealBlkLast, 1, lpu8TempBuf);
1270 				if(!bRet)
1271 					goto Write10_done;
1272 			}//Deal with ending block
1273 		}
1274 
1275 
1276 	}
1277 	else
1278 	{
1279 	    bRet = bSCSI_Write_10(uPort, uLunNum, u32BlockAddr, u32BlockNum, u8Buffer);
1280 	}
1281 
1282 Write10_done:
1283 	if(lpu8TempBuf != NULL)
1284 		kfree(lpu8TempBuf);
1285 	return bRet;
1286 }
bSCSI_Write_10(U8 uPort,U8 uLunNum,U32 u32BlockAddr,U32 u32BlockNum,U8 * u8Buffer)1287 
1288 
1289 
1290 BOOL bSCSI_Write_10(U8 uPort, U8 uLunNum, U32 u32BlockAddr, U32 u32BlockNum,
1291 							U8 *u8Buffer)
1292 {
1293 	//BOOL			err;
1294 
1295        //err=MsOS_ObtainMutex(_s32MutexUSB, MSOS_WAIT_FOREVER);
1296        //if (err==FALSE) return FALSE;
1297 
1298 	struct us_data *pMass_stor; //USB_2
1299 	U32 u32TransBlockTmp, u32TransSizeTmp,u32BlockOfSet = 0, u32TransOfSet = 0;
1300 	BOOL	bRet = TRUE, bConnSts;
1301 	int		i;
1302 	int     retrycount=0;
1303     U8      host_id;
1304 //    U32 u32OldIntr;
1305 
1306     //MsOS_DisableAllInterrupts(u32OldIntr);
1307 
1308 	//lock_usb_core();
1309 	if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
1310         return FALSE;
1311 
1312     host_id = pMass_stor->host_id;
1313 	USBCriticalSectionIn(host_id);
1314         if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
1315         {
1316             bRet=FALSE;
1317             goto Func_Done;
1318         }
1319 
1320 	struct LUN_Device* LunDevice = pMass_stor->Mass_stor_device;
1321 	U32 u32BlkSize_log2 = LunDevice[uLunNum].u32BlockSize_log2;
1322 	U32 u32DataLeft = u32BlockNum << u32BlkSize_log2;
1323 
1324 	if (uLunNum > pMass_stor->max_lun)
1325 	{
1326 		SCSI_DbgPrint("Invalid LUN Index%s","");
1327 		bRet = FALSE;
1328 		goto Func_Done;
1329 	}
1330 	if (LunDevice[uLunNum].u32BlockTotalNum < u32BlockNum)
1331 	{
1332 	       bRet=FALSE;
1333 		goto Func_Done;
1334 	}
1335 
1336 	if (LunDevice[uLunNum].bDeviceReady == FALSE)
1337 	{
1338 		bRet = FALSE;
1339 		goto Func_Done;
1340 	}
1341 
1342 	if(pMass_stor->Mass_stor_device[uLunNum].bWriteProtect)
1343 	{
1344 		SCSI_DbgPrint("Fail to write because write protection%s","");
1345 		bRet = FALSE;
1346 		goto Func_Done;
1347 	}
1348 
1349 	while(u32DataLeft > 0)
1350 	{
1351 		if(u32DataLeft > Scsi_Max_Transfer_Len)
1352 		{
1353 			u32TransBlockTmp = Scsi_Max_Transfer_Len >> u32BlkSize_log2;
1354 			u32TransSizeTmp = u32TransBlockTmp << u32BlkSize_log2;
1355 			u32DataLeft -= u32TransSizeTmp;
1356 		}
1357 		else
1358 		{
1359 			u32TransBlockTmp = u32DataLeft >> u32BlkSize_log2;
1360 			u32TransSizeTmp = u32DataLeft;
1361 			u32DataLeft = 0;
1362 		}
1363 
1364 
1365 		//err = MsOS_ObtainSemaphore(g_SCSISem,MSOS_WAIT_FOREVER);
1366 		//USB_ASSERT(err, "Wait SCSI sem fail\n");
1367 
1368 		for(i =0; i< ScsiCmd_Fail_Retry ;i++)
1369 		{
1370 		    retrycount = 0;
1371 			//When USB disk is disconnect or under reseting, FileSystem still writing data
1372 			//and this may caused file system crush. So we block the writing operation for
1373 			//20 secs, waiting for USB disk reseting or reconnect.
1374 retry:
1375 
1376                     {
1377                         //struct usb_hcd *hcd = pMass_stor->current_urb->dev->bus->hcpriv;
1378                         struct usb_hcd *hcd;
1379                         hcd = msc_get_hcd(host_id);
1380                         bConnSts = MDrv_UsbDeviceConnect_EX(hcd) & !(hcd->isRootHubPortReset);
1381                     }
1382 
1383             if (!bConnSts)
1384             {
1385                 diag_printf("Device is disconnect @ write 10\n");
1386 				retrycount++;
1387 				//if(retrycount <= 10)
1388 				if (0)  //Jonas
1389 				{
1390 					USBCriticalSectionOut(host_id);
1391 	                MsOS_DelayTask(2000);
1392 					USBCriticalSectionIn(host_id);
1393                     goto retry;
1394 				}
1395 				else
1396 				{
1397 				    bRet = FALSE;
1398 					goto Func_Done;
1399             	}
1400 			}
1401 
1402             //if (pMass_stor==NULL)
1403             if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
1404             {
1405                 diag_printf("Mass_stor_us==NULL!\n");
1406 				retrycount++;
1407 				//if(retrycount <= 10)
1408 				if(0)  //Jonas
1409 				{
1410 					USBCriticalSectionOut(host_id);
1411 	                MsOS_DelayTask(2000);
1412 					USBCriticalSectionIn(host_id);
1413                     goto retry;
1414 				}
1415 				else
1416 				{
1417 				    bRet = FALSE;
1418 					goto Func_Done;
1419             	}
1420             }
1421 
1422 			memset(&pMass_stor->srb, 0, sizeof(struct scsi_cmnd ));
1423 
1424 			// Build SCSI command.
1425 			vSCSICmd_WRITE_10(pMass_stor, uLunNum,
1426 								u32BlockAddr + u32BlockOfSet, (U16)u32TransBlockTmp, u8Buffer + u32TransOfSet);
1427 
1428 			// call mass storage function to send scsi command
1429 			usb_stor_control_thread(pMass_stor);
1430 
1431 			if(pMass_stor->srb.result != SAM_STAT_GOOD)
1432 			{
1433 				if (pMass_stor->srb.result == SAM_STAT_CHECK_CONDITION)
1434 				{
1435 					if(((pMass_stor->srb.sense_buffer[2] & 0xf) == 0x02) &&
1436 						(pMass_stor->srb.sense_buffer[12]  == 0x3A))
1437 					{
1438 						LunDevice[uLunNum].bDeviceReady = FALSE;
1439 					}
1440 					else if(((pMass_stor->srb.sense_buffer[2] & 0xf) == 0x06) &&
1441 						(pMass_stor->srb.sense_buffer[12]  == 0x28))
1442 					{
1443 						LunDevice[uLunNum].bDeviceReady = FALSE;
1444 					}
1445 				}
1446 
1447 				SCSI_DbgPrint("Scsi WRITE_10 command failed.%s","\n");
1448 				bRet = FALSE;
1449 			}
1450 			else
1451 			{
1452 				bRet = TRUE;
1453 				break;
1454 			}
1455 		}
1456 
1457 		//err = MsOS_ReleaseSemaphore(g_SCSISem);
1458 		//USB_ASSERT(err, "Signal SCSI sem fail\n");
1459 
1460 		u32BlockOfSet += u32TransBlockTmp;
1461 		u32TransOfSet += u32TransSizeTmp;
1462 
1463 		if (bRet == FALSE)
1464 			break;
1465 	}
1466 
1467 Func_Done:
1468 	//unlock_usb_core();
1469    //MsOS_ReleaseMutex(_s32MutexUSB);
1470    USBCriticalSectionOut(host_id);
1471    //MsOS_RestoreAllInterrupts(u32OldIntr);
1472 
1473     return bRet;
1474 }
1475 
1476 static void vScsi_SendCmd_Done(struct scsi_cmnd *srb)
1477 {
1478 
bIsDevValid(U8 uPort,U8 LunNum)1479 	SCSI_DbgPrint("SCSI command (0x%x) Done, result = 0x%x\n", srb->cmnd[0], srb->result);
1480 }
1481 
1482 BOOL bIsDevValid(U8 uPort, U8 LunNum)
1483 {
1484 //	U8	i;
1485 	struct LUN_Device* LunDevice = Mass_stor_us[uPort]->Mass_stor_device;
1486 
1487 	if (LunNum <= Mass_stor_us[uPort]->max_lun)
1488 		return (LunDevice[LunNum].bFSInit);
1489 	else
1490 		return FALSE;
1491 
1492 //	for (i=0; i<=Mass_stor_us->max_lun; i++)
u8GetDevType(U8 uPort,U8 LunNum)1493 //		pLunSts[i] = LunDevice[i].bFSInit;
1494 }
1495 
1496 U8 u8GetDevType(U8 uPort, U8 LunNum)
1497 {
1498 	struct LUN_Device* LunDevice = Mass_stor_us[uPort]->Mass_stor_device;
1499 
1500 	if (LunNum <= Mass_stor_us[uPort]->max_lun)
1501 		return LunDevice[LunNum].u8DevType;
1502 	else
1503 		return  0;
1504 }
1505 
1506