xref: /utopia/UTPA2-700.0.x/modules/usb/drv/usb_ecos/newhost/drvMSC.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 //#include <MsCommon.h> // NUSED
80 //#include "drvMSC.h" // NUSED
81 //#include "include/drvKernel.h" // NUSED
82 #include "drvBulktran.h"
83 //#include "drvUsbd.h" // NUSED
84 #include "drvEHCI.h"
85 #include "drvUSBHwCtl.h"
86 /* applying drvUsbHostConfig.h (inside drvUSBHwCtl.h) */
87 
88 //#define SCSI_DEBUG
89 #ifdef SCSI_DEBUG
90 #define SCSI_DbgPrint(x,arg...) diag_printf(x,##arg)
91 #else
92 #define SCSI_DbgPrint(x,...)
93 #endif
94 
95 #define ScsiCmd_Fail_Retry      3
96 #define ScsiCmd_Fail_TUR_Retry      7
97 #define Scsi_Max_Transfer_Len   120*1024 //65536
98 
99 struct ms_usdata *Mass_stor_us[NUM_OF_ROOT_HUB*MAX_USTOR] = {NULL};
100 
101 static void ms_vScsi_SendCmd_Done(struct scMsc_cmd *srb);
102 extern VOID RemoveUSBDiskPort(U8 uPort, U8 uLunNum);
103 extern BOOL ConnectUSBDisk(U8 uPort, U8 uLunNum);
104 
ms_get_value_log2(U32 val)105 static U32 ms_get_value_log2(U32 val)
106 {
107     U32 i, log2;
108 
109     if(val == 0)
110         return 0;
111 
112     i    = val;
113     log2 = 0;
114 
115 
116     while (0 == (i & 1))
117     {
118         i >>= 1;
119         log2++;
120     }
121 
122     if (i != 1) return 0;
123     else        return log2;
124 }
125 
ms_vSCSICmd_READ_10(struct ms_usdata * us,U8 u8LunNum,U32 u32BlockAddr,U16 u16BlockNum,U8 * u8Buffer)126 static void ms_vSCSICmd_READ_10(struct ms_usdata *us, U8 u8LunNum,
127                             U32 u32BlockAddr, U16 u16BlockNum, U8 *u8Buffer)
128 {
129     stCmd_scsi *srb = &us->srb;
130 
131     /* set the command and the LUN */
132     //memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
133     srb->cmnd[0] = READ_10;
134     srb->cmnd[2] = (U8)(u32BlockAddr >> 24);
135     srb->cmnd[3] = (U8)(u32BlockAddr >> 16);
136     srb->cmnd[4] = (U8)(u32BlockAddr >> 8);
137     srb->cmnd[5] = (U8)(u32BlockAddr);
138     srb->cmnd[7] = (U8)(u16BlockNum >> 8);
139     srb->cmnd[8] = (U8)(u16BlockNum );
140 
141     srb->cmd_len = CB_LENGTH_READ_10;
142 
143     /* set the transfer direction */
144     srb->sc_data_direction = SCSI_DATA_READ;
145 
146     /* use the new buffer we have */
147     srb->req_buf = u8Buffer;
148 
149     /* set the buffer length for transfer */
150     srb->req_buf_len = u16BlockNum << (us->msc_device[u8LunNum].u32BlockSize_log2);
151 
152     /* change the serial number -- toggle the high bit*/
153     srb->serial_number ^= 0x80000000;
154 
155     /* set Lun number*/
156     srb->lun= u8LunNum;
157 
158     srb->scsi_done = ms_vScsi_SendCmd_Done;
159 }
160 
ms_vSCSICmd_WRITE_10(struct ms_usdata * us,U8 u8LunNum,U32 u32BlockAddr,U16 u16BlockNum,U8 * u8Buffer)161 static void ms_vSCSICmd_WRITE_10(struct ms_usdata *us, U8 u8LunNum,
162                             U32 u32BlockAddr, U16 u16BlockNum, U8 *u8Buffer)
163 {
164     stCmd_scsi *srb = &us->srb;
165 
166     /* set the command and the LUN */
167     //memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
168     srb->cmnd[0] = WRITE_10;
169     srb->cmnd[2] = (U8)(u32BlockAddr >> 24);
170     srb->cmnd[3] = (U8)(u32BlockAddr >> 16);
171     srb->cmnd[4] = (U8)(u32BlockAddr >> 8);
172     srb->cmnd[5] = (U8)(u32BlockAddr);
173     srb->cmnd[7] = (U8)(u16BlockNum >> 8);
174     srb->cmnd[8] = (U8)(u16BlockNum );
175 
176     srb->cmd_len = CB_LENGTH_WRITE_10;
177 
178     /* set the transfer direction */
179     srb->sc_data_direction = SCSI_DATA_WRITE;
180 
181     /* use the new buffer we have */
182     srb->req_buf = u8Buffer;
183 
184     /* set the buffer length for transfer */
185     srb->req_buf_len = u16BlockNum << us->msc_device[u8LunNum].u32BlockSize_log2;
186 
187     /* change the serial number -- toggle the high bit*/
188     srb->serial_number ^= 0x80000000;
189 
190     /* set Lun number*/
191     srb->lun= u8LunNum;
192 
193     srb->scsi_done = ms_vScsi_SendCmd_Done;
194 }
195 
196 
ms_vSCSICmd_INQUIRY(struct ms_usdata * us,U8 * u8Buffer,U8 u8LunNum)197 static void ms_vSCSICmd_INQUIRY(struct ms_usdata *us, U8 *u8Buffer,  U8 u8LunNum)
198 {
199     stCmd_scsi *srb = &us->srb;
200 
201     /* set the command and the LUN */
202     memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
203     srb->cmnd[0] = INQUIRY;
204     srb->cmnd[4] = DATA_LENGTH_INQUIRY;
205 
206     srb->cmd_len = CB_LENGTH_INQUIRY;
207 
208     /* set the transfer direction */
209     srb->sc_data_direction = SCSI_DATA_READ;
210 
211     /* use the new buffer we have */
212     srb->req_buf = u8Buffer;
213 
214     /* set the buffer length for transfer */
215     srb->req_buf_len = DATA_LENGTH_INQUIRY;
216 
217     /* change the serial number -- toggle the high bit*/
218     srb->serial_number ^= 0x80000000;
219 
220     /* set Lun number*/
221     srb->lun= u8LunNum;
222 
223     srb->scsi_done = ms_vScsi_SendCmd_Done;
224 }
225 
ms_vSCSICmd_READ_CAPACITY(struct ms_usdata * us,U8 * u8Buffer,U8 u8LunNum)226 static void ms_vSCSICmd_READ_CAPACITY(struct ms_usdata *us, U8 *u8Buffer,  U8 u8LunNum)
227 {
228     stCmd_scsi *srb = &us->srb;
229 
230     /* set the command and the LUN */
231     memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
232     srb->cmnd[0] = READ_CAPACITY;
233 
234     srb->cmd_len = CB_LENGTH_READ_CAPACITY;
235 
236     /* set the transfer direction */
237     srb->sc_data_direction = SCSI_DATA_READ;
238 
239     /* use the new buffer we have */
240     srb->req_buf = u8Buffer;
241 
242     /* set the buffer length for transfer */
243     srb->req_buf_len = DATA_LENGTH_READ_CAPACITY;
244 
245     /* change the serial number -- toggle the high bit*/
246     srb->serial_number ^= 0x80000000;
247 
248     /* set Lun number*/
249     srb->lun= u8LunNum;
250 
251     srb->scsi_done = ms_vScsi_SendCmd_Done;
252 }
253 
ms_vSCSICmd_MODE_SENSE(struct ms_usdata * us,U8 u8PageCode,U8 * u8Buffer,U8 u8LunNum,U16 uBufLen)254 static void ms_vSCSICmd_MODE_SENSE(
255     struct ms_usdata *us,
256     U8 u8PageCode,
257     U8 *u8Buffer,
258     U8 u8LunNum,
259     U16 uBufLen)
260 {
261     stCmd_scsi *srb = &us->srb;
262 
263     /* set the command and the LUN */
264     memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
265     srb->cmnd[0] = MODE_SENSE6;
266     srb->cmnd[2] = u8PageCode;
267     //srb->cmnd[7] = (U8)((uBufLen >> 8) & 0x00FF);
268     //srb->cmnd[8] = (U8)uBufLen;
269         srb->cmnd[4] = (U8)uBufLen;
270 
271     srb->cmd_len = CB_LENGTH_MODE_SENSE;
272 
273     /* set the transfer direction */
274     srb->sc_data_direction = SCSI_DATA_READ;
275 
276     /* use the new buffer we have */
277     srb->req_buf = u8Buffer;
278 
279     /* set the buffer length for transfer */
280     srb->req_buf_len = uBufLen;
281 
282     /* change the serial number -- toggle the high bit*/
283     srb->serial_number ^= 0x80000000;
284 
285     /* set Lun number*/
286     srb->lun= u8LunNum;
287 
288     srb->scsi_done = ms_vScsi_SendCmd_Done;
289 }
290 
291 #if 0 // NUSED now
292 static void ms_vSCSICmd_REQUEST_SENSE(struct ms_usdata *us, U8 u8LunNum)
293 {
294     stCmd_scsi *srb = &us->srb;
295 
296     /* set the command and the LUN */
297     memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
298     srb->cmnd[0] = REQUEST_SENSE;
299     srb->cmnd[4] = DATA_LENGTH_REQUEST_SENSE;
300 
301     srb->cmd_len = CB_LENGTH_REQUEST_SENSE;
302 
303     /* set the transfer direction */
304     srb->sc_data_direction = SCSI_DATA_READ;
305 
306     /* use the new buffer we have */
307     srb->req_buf = srb->sense_buffer;
308 
309     /* set the buffer length for transfer */
310     srb->req_buf_len = DATA_LENGTH_REQUEST_SENSE;
311 
312     /* change the serial number -- toggle the high bit*/
313     srb->serial_number ^= 0x80000000;
314 
315     /* set Lun number*/
316     srb->lun= u8LunNum;
317 
318     srb->scsi_done = ms_vScsi_SendCmd_Done;
319 }
320 #endif
321 
ms_vSCSICmd_TEST_UNIT_READY(struct ms_usdata * us,U8 u8LunNum)322 static void ms_vSCSICmd_TEST_UNIT_READY(struct ms_usdata *us, U8 u8LunNum)
323 {
324     stCmd_scsi *srb = &us->srb;
325 
326     /* set the command and the LUN */
327     memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
328     srb->cmnd[0] = TEST_UNIT_READY;
329 
330     srb->cmd_len = CB_LENGTH_TEST_UNIT_READY;
331 
332     /* set the transfer direction */
333     srb->sc_data_direction = SCSI_DATA_READ;
334 
335     /* set the buffer length for transfer */
336     srb->req_buf_len = 0;
337 
338     /* change the serial number -- toggle the high bit*/
339     srb->serial_number ^= 0x80000000;
340 
341     /* set Lun number*/
342     srb->lun= u8LunNum;
343 
344     srb->scsi_done = ms_vScsi_SendCmd_Done;
345 }
346 
347 #if 0 // NUSED now
348 BOOL ms_bSCSI_REQ_SENSE(U8 uPort, U8 uLunNum, U8 *pSenseBuf)
349 {
350     //BOOL	err;
351     BOOL      bRet=FALSE;
352     struct ms_usdata *pMass_stor;
353     U8      host_id;
354 
355 
356     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
357         return FALSE;
358     //err = MsOS_ObtainSemaphore(g_SCSISem,MSOS_WAIT_FOREVER);
359     //USB_ASSERT(err, "Wait SCSI sem fail\n");
360     //err=MsOS_ObtainMutex(_s32MutexUSB, MSOS_WAIT_FOREVER);
361     // if (err==FALSE) return FALSE;
362     //U32 u32OldIntr;
363 
364     // MsOS_DisableAllInterrupts(u32OldIntr);
365 
366     host_id = pMass_stor->host_id;
367     if(!ms_USBCriticalSectionIn_TimeOut(host_id, MS_MSC_WAIT_MUTEX_TIMEOUT))
368         return FALSE;
369 
370     memset(&pMass_stor->srb, 0, sizeof(struct scMsc_cmd ));
371 
372     ms_vSCSICmd_REQUEST_SENSE(pMass_stor, uLunNum);
373 
374     ms_usb_msc_control_thread(pMass_stor);
375 
376     if (pMass_stor->srb.result == MS_STAT_GOOD)
377     {
378         memcpy(pSenseBuf, pMass_stor->srb.sense_buffer, DATA_LENGTH_REQUEST_SENSE);
379         bRet=TRUE;
380     }
381     else
382         bRet=FALSE;
383 
384     ms_USBCriticalSectionOut(host_id);
385    return bRet;
386 }
387 #endif
388 
ms_bSCSI_INQUIRY(U8 uPort,U8 uLunNum,U8 * pIngBuf)389 static BOOL ms_bSCSI_INQUIRY(U8 uPort, U8 uLunNum, U8 *pIngBuf)
390 {
391     BOOL	bRet = FALSE;
392     int		i;
393     struct ms_usdata *pMass_stor;
394     U8      host_id;
395 
396     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
397         return FALSE;
398 
399     host_id = pMass_stor->host_id;
400     if(!ms_USBCriticalSectionIn_TimeOut(host_id, MS_MSC_WAIT_MUTEX_TIMEOUT))
401       return FALSE;
402 
403     for(i =0; i< ScsiCmd_Fail_Retry ;i++)
404     {
405         if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
406             break;
407 
408         memset(&pMass_stor->srb, 0, sizeof(struct scMsc_cmd ));
409         ms_vSCSICmd_INQUIRY(pMass_stor, pIngBuf, uLunNum);
410 
411         ms_usb_msc_control_thread(pMass_stor);
412 
413         if(pMass_stor->srb.result == MS_STAT_GOOD)
414         {
415             bRet = TRUE;
416             break;
417         }
418         else if (pMass_stor->srb.result == (DID_NO_CONNECT << 16))
419         {
420             diag_printf("INQUIRY break by NO_CONNECT\n");
421             break;
422         }
423     }
424     ms_USBCriticalSectionOut(host_id);
425     return bRet;
426 }
427 
428 // save all Mode Sense(page code=0x3F) data
429 // Now we only use u8ModeSenseData[2], this byte save device
430 // write protection information
ms_bSCSI_MODE_SENSE(U8 uPort,U8 uLunNum,U8 * pModSenBuf,U16 uBufLen)431 static BOOL ms_bSCSI_MODE_SENSE(U8 uPort, U8 uLunNum, U8 *pModSenBuf, U16 uBufLen)
432 {
433     int     i;
434     BOOL    bRet = FALSE;
435     struct ms_usdata *pMass_stor;
436     U8      host_id;
437 
438     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
439         return FALSE;
440 
441     host_id = pMass_stor->host_id;
442     if(!ms_USBCriticalSectionIn_TimeOut(host_id, MS_MSC_WAIT_MUTEX_TIMEOUT))
443         return FALSE;
444 
445     for(i =0; i< ScsiCmd_Fail_Retry ; i++)
446     {
447         if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
448             break;
449 
450         memset(&pMass_stor->srb, 0, sizeof(struct scMsc_cmd ));
451         ms_vSCSICmd_MODE_SENSE(pMass_stor, 0x3F, pModSenBuf, uLunNum, uBufLen);
452         ms_usb_msc_control_thread(pMass_stor);
453 
454         if(pMass_stor->srb.result == MS_STAT_GOOD)
455         {
456             bRet = TRUE;
457             break;
458         }
459         else if (pMass_stor->srb.result == (DID_NO_CONNECT << 16))
460         {
461             diag_printf("MODE_SENSE break by NO_CONNECT\n");
462             break;
463         }
464     }
465     ms_USBCriticalSectionOut(host_id);
466     return bRet;
467 }
468 
ms_bSCSI_READ_CAPACITY(U8 uPort,U8 uLunNum,U32 * pTotalBlks,U32 * pBlkSize)469 static BOOL ms_bSCSI_READ_CAPACITY(U8 uPort, U8 uLunNum, U32 *pTotalBlks, U32 *pBlkSize)
470 {
471     int     i;
472     BOOL    bRet = FALSE;
473     U8      CapBuf[DATA_LENGTH_READ_CAPACITY];
474     struct ms_usdata *pMass_stor;
475     U8      host_id;
476 
477     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
478         return bRet;
479     host_id = pMass_stor->host_id;
480     if(!ms_USBCriticalSectionIn_TimeOut(host_id, MS_MSC_WAIT_MUTEX_TIMEOUT))
481         return FALSE;
482 
483     for(i =0; i< ScsiCmd_Fail_Retry ; i++)
484     {
485         if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
486             break;
487 
488         memset(&pMass_stor->srb, 0, sizeof(struct scMsc_cmd ));
489 
490         ms_vSCSICmd_READ_CAPACITY(pMass_stor, CapBuf, uLunNum);
491 
492         ms_usb_msc_control_thread(pMass_stor);
493 
494         if(pMass_stor->srb.result == MS_STAT_GOOD)
495         {
496             U32 blk_idx;
497 
498             blk_idx = (((U32)CapBuf[0] << 24) |
499                 ((U32)CapBuf[1] << 16) |
500                 ((U32)CapBuf[2] << 8) |
501                 ((U32)CapBuf[3] ));
502             if (blk_idx == 0xffffffff)
503                 diag_printf("[MSC] maximum capacity exceed 2T!\n");
504             else
505                 blk_idx++;
506             *pTotalBlks = blk_idx;
507 
508             *pBlkSize = ((U32)CapBuf[4] << 24) |
509                 ((U32)CapBuf[5] << 16) |
510                 ((U32)CapBuf[6] << 8) |
511                 ((U32)CapBuf[7] ) ;
512 
513             SCSI_DbgPrint("SCSI CAPACITY : SCSI Device total block <0x%x%x>\n",
514                 (U16)(*pTotalBlks >> 16),
515                 (U16)*pTotalBlks);
516             SCSI_DbgPrint("SCSI CAPACITY : SCSI Product block size <0x%x bytes>\n",
517                 (U16)*pBlkSize);
518 
519             bRet = TRUE;
520             break;
521         }
522         else if (pMass_stor->srb.result == (DID_NO_CONNECT << 16))
523         {
524             diag_printf("READ_CAPACITY break by NO_CONNECT\n");
525             break;
526         }
527     }
528 
529     ms_USBCriticalSectionOut(host_id);
530     return bRet;
531 }
532 
533 // Some cameras with CBI subclass can't accept the TUR, but others need.
534 // Our solution is don't send real TUR to camera. If the command Get Capacity is failed,
535 // we send the real TUR.
ms_bSCSI_TEST_UNIT_READY(U8 uPort,U8 uLunNum,BOOL CheckCBI)536 static BOOL ms_bSCSI_TEST_UNIT_READY(U8 uPort, U8 uLunNum, BOOL CheckCBI)
537 {
538     int		i;
539     BOOL	bRet = FALSE;
540     struct ms_usdata *pMass_stor;
541     struct LUN_Device* LunDevice;
542     U8      host_id;
543 
544     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
545         return FALSE;
546 
547     if (CheckCBI)
548     {
549         if ( ( Mass_stor_us[uPort] != NULL) &&
550             (Mass_stor_us[uPort]->subclass == MS_SFF_SC) &&
551             (Mass_stor_us[uPort]->protocol == MS_CBI_PR) )
552         {
553             return TRUE;
554         }
555     }
556 
557     // fixed device test
558     LunDevice = pMass_stor->msc_device;
559     SCSI_DbgPrint("TUR:: [%d]u8DevType %x\n", uLunNum, LunDevice[uLunNum].u8DevType);
560     if ((LunDevice[uLunNum].u8DevType & 0x80) == 0)
561     {
562         return TRUE;
563     }
564 
565     host_id = pMass_stor->host_id;
566     if(!ms_USBCriticalSectionIn_TimeOut(host_id, MS_MSC_WAIT_MUTEX_TIMEOUT))
567         return FALSE;
568 
569     for(i =0; i< ScsiCmd_Fail_TUR_Retry ;i++)
570     {
571         if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
572             break;
573 
574         memset(&pMass_stor->srb, 0, sizeof(struct scMsc_cmd ));
575 
576         ms_vSCSICmd_TEST_UNIT_READY(pMass_stor, uLunNum);
577 
578         ms_usb_msc_control_thread(pMass_stor);
579 
580         if(pMass_stor->srb.result == MS_STAT_GOOD)
581         {
582             //diag_printf(" Succeed for lun %d\n",uLunNum);
583 
584             bRet = TRUE;
585             break;
586         }
587         else if (pMass_stor->srb.result == (DID_NO_CONNECT << 16))
588         {
589             diag_printf("TUR break by NO_CONNECT\n");
590             break;
591         }
592         else
593         {
594             if (i > ScsiCmd_Fail_Retry)
595                 SCSI_DbgPrint("TUR failed retry %d\n",i);
596         }
597     }
598 
599     ms_USBCriticalSectionOut(host_id);
600     return bRet;
601 }
602 
ms_bInit_USB_LUN(U8 uPort,U8 uLunIdx)603 static BOOL ms_bInit_USB_LUN(U8 uPort, U8 uLunIdx)
604 {
605     struct ms_usdata *pMass_stor;
606     struct LUN_Device* LunDevice;
607     U8      pIngBuf[DATA_LENGTH_INQUIRY];
608     U8      pModSenBuf[8];
609     U8 u8DevType;
610 
611     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
612         return FALSE;
613 
614     LunDevice = pMass_stor->msc_device;
615 
616     if(!quirk_bypass_stage(pMass_stor, QUIRK_IGNORE_TUR))
617     {
618         if(ms_bSCSI_TEST_UNIT_READY(uPort, uLunIdx, TRUE))
619         {
620             SCSI_DbgPrint("Scsi Device is ready (Lun=%d).\n", uLunIdx);
621         }
622         else
623             return FALSE;
624     }
625 
626     if (uLunIdx) {
627         if (ms_bSCSI_INQUIRY(uPort, uLunIdx, pIngBuf))
628         {
629             LunDevice[uLunIdx].u8DevType = (pIngBuf[1] & 0x80) | (pIngBuf[0] & 0x1F);
630             SCSI_DbgPrint("SCSI INQUIRY : SCSI Device ID <%s>\n",&pMass_stor->device.u8VendorID);
631             SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ID <%s>\n",&pMass_stor->device.u8ProductID);
632             SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ver <%s>\n",&pMass_stor->device.u8ProductVer);
633         }
634         else
635             return FALSE;
636     }
637     else
638         LunDevice[uLunIdx].u8DevType = pMass_stor->device.u8DeviceType;
639 
640     if(!quirk_bypass_stage(pMass_stor, QUIRK_IGNORE_CD_ROM))
641     {
642         u8DevType = LunDevice[uLunIdx].u8DevType & 0x1F;
643         if( (u8DevType == TYPE_ROM) ||  // FS does't support CD-ROM well
644             (u8DevType == TYPE_SES) )
645         {
646             return FALSE;
647         }
648     }
649 
650     if(quirk_bypass_stage(pMass_stor, QUIRK_IGNORE_RD_CAP))
651     {
652         /* fake capacity */
653         #define FAKE_CAPACITY_BLKNUM 0x10000
654         #define FAKE_CAPACITY_BLKSIZE 0x200
655         LunDevice[uLunIdx].u32BlockTotalNum = FAKE_CAPACITY_BLKNUM;
656         LunDevice[uLunIdx].u32BlockSize = FAKE_CAPACITY_BLKSIZE;
657     }
658     else
659     {
660         if(ms_bSCSI_READ_CAPACITY(uPort, uLunIdx, &LunDevice[uLunIdx].u32BlockTotalNum, &LunDevice[uLunIdx].u32BlockSize))
661         {
662             SCSI_DbgPrint("Read CAPACITY: TotalBlks %d, BlkSize %d\n",
663                                 LunDevice[uLunIdx].u32BlockTotalNum, LunDevice[uLunIdx].u32BlockSize);
664             LunDevice[uLunIdx].u32BlockSize_log2 = ms_get_value_log2(LunDevice[uLunIdx].u32BlockSize);
665         }
666         else
667         {
668             // Some cameras need real TUR command
669             // to start work. We send real TUR here for these special devices.
670             ms_bSCSI_TEST_UNIT_READY(uPort, uLunIdx, FALSE);
671             return FALSE;
672         }
673     }
674 
675     if(!quirk_bypass_stage(pMass_stor, QUIRK_IGNORE_MOD_SENSE))
676     {
677         LunDevice[uLunIdx].bWriteProtect = FALSE;
678         if (ms_bSCSI_MODE_SENSE(uPort, uLunIdx, pModSenBuf, 8))     // Just read the header of mode sense
679         {
680             LunDevice[uLunIdx].bWriteProtect = (pModSenBuf[2]==0x80) ? TRUE:FALSE;
681             if (LunDevice[uLunIdx].bWriteProtect )
682             {
683                 diag_printf("Usb Device WriteProtected! \n");
684             }
685         }
686     }
687 
688     return TRUE;
689 }
690 
ms_bSCSI_Initial(U8 uPort)691 static BOOL ms_bSCSI_Initial(U8 uPort)
692 {
693     BOOL        bFoundValidDev = FALSE;
694     struct ms_usdata *pMass_stor;
695     struct LUN_Device* LunDevice;
696     U8      pIngBuf[DATA_LENGTH_INQUIRY];
697     int     LunIdx;
698 
699     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
700         return FALSE;
701 
702     LunDevice = pMass_stor->msc_device;
703     // Firstly, we send a Inquiry to every LUN
704     // It is simulated from PC
705     for (LunIdx=0; LunIdx<=pMass_stor->max_lun; LunIdx++)
706     {
707         LunDevice[LunIdx].bDeviceReady = FALSE;
708         if (LunIdx == 0)
709         {
710             memset(pIngBuf, 0, DATA_LENGTH_INQUIRY);
711             if (ms_bSCSI_INQUIRY(uPort, 0, pIngBuf))
712             {
713                 // save device type
714                 pMass_stor->device.u8DeviceType = (pIngBuf[0] & 0x1F);
715                 // save vendor string, total 8 bytes
716                 memcpy(pMass_stor->device.u8VendorID, &pIngBuf[8], 8);
717                 // save product string, total 16 bytes
718                 memcpy(pMass_stor->device.u8ProductID, &pIngBuf[16], 16);
719                 // save revision information, total 4 bytes
720                 memcpy(pMass_stor->device.u8ProductVer, &pIngBuf[32], 4);
721                 SCSI_DbgPrint("SCSI INQUIRY : SCSI Device ID <%s>\n",&pMass_stor->device.u8VendorID);
722                 SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ID <%s>\n",&pMass_stor->device.u8ProductID);
723                 SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ver <%s>\n",&pMass_stor->device.u8ProductVer);
724             }
725             else
726                 goto Init_Done;
727         }
728         else
729         {
730             if (!ms_bSCSI_INQUIRY(uPort, LunIdx, pIngBuf))
731                 goto Init_Done;
732         }
733         LunDevice[LunIdx].u8DevType = (pIngBuf[0] & 0x1F) | (pIngBuf[1] & 0x80);
734     }
735 
736     // Start to init every LUN
737     for (LunIdx=0; LunIdx<=pMass_stor->max_lun; LunIdx++)
738     {
739         if (!ms_bInit_USB_LUN(uPort, LunIdx))
740             continue;
741 
742         LunDevice[LunIdx].bDeviceReady = TRUE;
743 
744         if (ConnectUSBDisk(uPort, LunIdx))
745             LunDevice[LunIdx].bFSInit = TRUE;
746 
747         bFoundValidDev = TRUE;
748     }
749 Init_Done:
750     SCSI_DbgPrint("Exit ms_bSCSI_Initial %d\n", bFoundValidDev);
751 
752     return bFoundValidDev;
753 }
754 
755 /* eCos USB host driver API, do not alter the function name!!!
756  * the function body not maintained, just complaint with the API interface
757 */
ChkUsbReady(void)758 BOOL ChkUsbReady(void)
759 {
760     return FALSE;
761 }
762 
763 /* eCos USB host driver API, do not alter the function name!!!
764  * the function body not maintained, just complaint with the API interface
765 */
ChkUsbReadyEx(MS_U8 uHostPort)766 MS_BOOL ChkUsbReadyEx(MS_U8 uHostPort)
767 {
768         return FALSE;
769 }
770 
ms_bInit_USB_Disk(U8 uPort)771 static BOOL ms_bInit_USB_Disk(U8 uPort)
772 {
773     struct ms_usdata *pMass_stor;
774     int     i;
775 
776     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
777         return FALSE;
778 
779     for (i=0; i<=pMass_stor->max_lun; i++)
780     {
781         //RemoveUSBDiskPort(uPort, i); // no need
782         pMass_stor->msc_device[i].u8LunNum = i;
783     }
784     return ms_bSCSI_Initial(uPort);
785 }
786 
ms_vChk_USB_LUNs(U8 uPort)787 static BOOL ms_vChk_USB_LUNs(U8 uPort)
788 {
789     int         LunIdx;
790     struct ms_usdata *pMass_stor;
791     struct LUN_Device* LunDevice;
792     BOOL        bLUNSts;
793     BOOL        retv = TRUE;
794     U8 u8DevType;
795 
796     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
797         return FALSE;
798 
799     LunDevice = pMass_stor->msc_device;
800 
801     for (LunIdx=0; LunIdx<=pMass_stor->max_lun; LunIdx++)
802     {
803         if ((bLUNSts = ms_bSCSI_TEST_UNIT_READY(uPort, LunIdx, TRUE)) != LunDevice[LunIdx].bDeviceReady) // Status of LUN changed
804         {
805             if (bLUNSts)	// No media card -> has media card
806             {
807                 if (ms_bInit_USB_LUN(uPort, LunIdx))
808                 {
809                     LunDevice[LunIdx].bDeviceReady = TRUE;
810                     RemoveUSBDiskPort(uPort, LunIdx);
811                     if (ConnectUSBDisk(uPort, LunIdx))
812                         LunDevice[LunIdx].bFSInit = TRUE;
813                 }
814                 u8DevType = LunDevice[LunIdx].u8DevType & 0x1F;
815                 if( (u8DevType == TYPE_ROM) ||
816                     (u8DevType == TYPE_SES) )
817                 {
818                     LunDevice[LunIdx].bDeviceReady = TRUE;
819                 }
820             }
821             else	// has media card -> no media card
822             {
823             #if 0
824                 /* let hub event to remove the disk, and speed up disconnection */
825                 diag_printf("TUR fail -> disconnect disk, us_id: %d\n", uPort);
826                 ms_set_bit(MS_IDX_DISCONNECTING, &pMass_stor->flags, unsigned long);
827                 break;
828             #else
829                 LunDevice[LunIdx].bDeviceReady = FALSE;
830                 LunDevice[LunIdx].bFSInit = FALSE;
831                 Set_Stor_Dev_Init(uPort, FALSE);
832                 diag_printf("TUR fail -> remove disk, us_id: %d\n", uPort);
833                 RemoveUSBDiskPort(uPort, LunIdx);
834 		/* card reader LUN remove, it should not clear store device info */
835                 //Clr_Stor_Dev_Info(uPort);
836             #endif
837                 retv = FALSE;
838             }
839         }
840     }
841     return retv;
842 }
843 
844 #if 0 // NUSED
845 void ms_vRemove_DISK_LUNs(U8 uPort)
846 {
847     int         LunIdx;
848     struct ms_usdata *pMass_stor;
849     struct LUN_Device* LunDevice;
850 
851     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
852         return;
853 
854     LunDevice = pMass_stor->msc_device;
855 
856     for (LunIdx=0; LunIdx<=pMass_stor->max_lun; LunIdx++)
857     {
858         LunDevice[LunIdx].bDeviceReady = FALSE;
859         LunDevice[LunIdx].bFSInit = FALSE;
860         RemoveUSBDiskPort(uPort, LunIdx);
861     }
862 }
863 
864 BOOL ms_bSCSI_ERASE(U8 uPort, U8 uLunNum, U32 u32BlockAddr, U32 u32BlockNum,
865                             U32 u32SectorSize)
866 {
867     if (uLunNum > Mass_stor_us[uPort]->max_lun)
868         return FALSE;
869     else
870         return TRUE;
871 }
872 
873 BOOL ms_bSCSI_Read_10_512(U8 uPort, U8 uLunNum, U32 u32BlockAddr, U32 u32BlockNum,
874                             U8 *u8Buffer)
875 {
876     struct ms_usdata *pMass_stor;
877     //U32 u32TransBlockTmp, u32TransSizeTmp,u32BlockOfSet = 0, u32TransOfSet = 0;
878     BOOL    bRet = TRUE;;
879     struct LUN_Device* LunDevice;
880     U32 u32BlkSize_log2;
881     U32 u32DataLeft;
882     U32 u32BlockSize;
883     U8  *lpu8TempBuf = NULL;
884 
885     U32 u32RealBlkAddr;
886     U32 u32RealBlkOffset;
887     U32 u32RealBlkLast;
888     U32 u32RealBlkLeft;
889     U32 u32CopyBytes;
890     U32 u32BlockNumAdj=0;
891 
892     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
893     {
894         bRet = FALSE;
895         goto Read10_done;
896     }
897 
898     LunDevice = pMass_stor->msc_device;
899     u32BlkSize_log2 = LunDevice[uLunNum].u32BlockSize_log2;
900     u32DataLeft = u32BlockNum << 9;
901     u32BlockSize = LunDevice[uLunNum].u32BlockSize;
902 
903     if(u32BlockSize != 512)
904     {
905         u32RealBlkAddr = (u32BlockAddr * 512) >> u32BlkSize_log2;
906         u32RealBlkOffset = u32BlockAddr * 512 - u32RealBlkAddr * u32BlockSize;
907 
908         u32RealBlkLast = ((u32BlockAddr + u32BlockNum) * 512) >> u32BlkSize_log2;
909         u32RealBlkLeft = ((u32BlockAddr + u32BlockNum) * 512) - u32RealBlkLast * u32BlockSize;
910 
911         u32BlockNumAdj = u32RealBlkLast - u32RealBlkAddr + 1;
912 
913 
914         if(u32RealBlkOffset > 0)
915         {
916             lpu8TempBuf = kmalloc(u32BlockSize, GFP_KERNEL);
917             bRet = ms_bSCSI_Read_10(uPort, uLunNum, u32RealBlkAddr, 1, lpu8TempBuf);
918             if(!bRet)
919                 goto Read10_done;
920             if(u32DataLeft > (u32BlockSize - u32RealBlkOffset))
921             {
922                 u32CopyBytes = u32BlockSize - u32RealBlkOffset;
923                 u32DataLeft -= u32CopyBytes;
924                 //u32ByteOffset = u32RealBlkOffset;
925             }
926             else
927             {
928                 u32DataLeft = 0;
929                 u32CopyBytes = u32DataLeft;
930             }
931 
932             memcpy(u8Buffer,
933                     lpu8TempBuf + u32RealBlkOffset ,
934                     (size_t)u32CopyBytes);
935             u32BlockNumAdj--;
936             u32RealBlkAddr++;
937             u8Buffer += u32CopyBytes;
938         }//Deal with beginning block
939 
940         if(u32BlockNumAdj > 1)  //Transfer mid blocks
941         {
942             if(u32RealBlkLeft != 0)
943                 u32BlockNumAdj--;
944 
945             bRet = ms_bSCSI_Read_10(uPort, uLunNum, u32RealBlkAddr, u32BlockNumAdj, u8Buffer);
946             if(!bRet)
947                 goto Read10_done;
948             u8Buffer += u32BlockNumAdj * u32BlockSize;
949             u32DataLeft -= u32BlockNumAdj * u32BlockSize;
950             if(u32DataLeft > 0)
951                 u32BlockNumAdj = 1;
952             else
953                 u32BlockNumAdj = 0;
954         }
955 
956         if(u32BlockNumAdj > 0) // Have last block
957         {
958             if(u32RealBlkLeft > 0)
959             {
960                 if(lpu8TempBuf == NULL)
961                     lpu8TempBuf = kmalloc(u32BlockSize, GFP_KERNEL);
962                 bRet = ms_bSCSI_Read_10(uPort, uLunNum, u32RealBlkLast, 1, lpu8TempBuf);
963                 if(!bRet)
964                     goto Read10_done;
965 
966                 memcpy(u8Buffer,
967                         lpu8TempBuf,
968                         (size_t)u32DataLeft);
969             }//Deal with ending block
970         }
971     }
972     else
973     {
974         bRet = ms_bSCSI_Read_10(uPort, uLunNum, u32BlockAddr, u32BlockNum, u8Buffer);
975     }
976 
977 Read10_done:
978     if(lpu8TempBuf != NULL)
979         kfree(lpu8TempBuf);
980     return bRet;
981 }
982 #endif
983 
ms_bSCSI_Read_10(U8 uPort,U8 uLunNum,U32 u32BlockAddr,U32 u32BlockNum,U8 * u8Buffer)984 BOOL ms_bSCSI_Read_10(U8 uPort, U8 uLunNum, U32 u32BlockAddr, U32 u32BlockNum,
985                             U8 *u8Buffer)
986 {
987     struct ms_usdata *pMass_stor;
988     U32 u32TransBlockTmp, u32TransSizeTmp,u32BlockOfSet = 0, u32TransOfSet = 0;
989     BOOL    bRet = TRUE, bConnSts;
990     struct LUN_Device* LunDevice;
991     U32 u32BlkSize_log2;
992     U32 u32DataLeft;
993     int     i;
994     U8      host_id;
995 
996     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
997         return FALSE;
998 #ifdef ENABLE_RW_DISCONNECTING
999     if (ms_test_bit(MS_IDX_DISCONNECTING, &pMass_stor->flags))
1000     {
1001             SCSI_DbgPrint("[ms_bSCSI_Read_10] OUT\n");
1002             return FALSE;
1003     }
1004 #endif
1005     host_id = pMass_stor->host_id;
1006     if(!ms_USBCriticalSectionIn_TimeOut(host_id, MS_MSC_WAIT_MUTEX_TIMEOUT))
1007     {
1008         SCSI_DbgPrint("[USB] R10 wait Mutex timeout\n");
1009         return FALSE;
1010     }
1011 
1012     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
1013     {
1014         bRet=FALSE;
1015         goto Func_Done;
1016     }
1017 
1018     LunDevice = pMass_stor->msc_device;
1019     u32BlkSize_log2 = LunDevice[uLunNum].u32BlockSize_log2;
1020     u32DataLeft = u32BlockNum << u32BlkSize_log2;
1021     if (uLunNum > pMass_stor->max_lun)
1022     {
1023         SCSI_DbgPrint("Invalid LUN Index %d\n",uLunNum);
1024         bRet = FALSE;
1025         goto Func_Done;
1026     }
1027     if (LunDevice[uLunNum].u32BlockTotalNum < u32BlockNum)
1028     {
1029         bRet=FALSE;
1030         goto Func_Done;
1031     }
1032     if (LunDevice[uLunNum].bDeviceReady == FALSE)
1033     {
1034         bRet = FALSE;
1035         goto Func_Done;
1036     }
1037 
1038     while(u32DataLeft > 0)
1039     {
1040         if(u32DataLeft > Scsi_Max_Transfer_Len)
1041         {
1042             u32TransBlockTmp = Scsi_Max_Transfer_Len >> u32BlkSize_log2;
1043             u32TransSizeTmp = u32TransBlockTmp << u32BlkSize_log2;
1044             u32DataLeft -= u32TransSizeTmp;
1045         }
1046         else
1047         {
1048             u32TransBlockTmp = u32DataLeft >> u32BlkSize_log2;
1049             u32TransSizeTmp = u32DataLeft;
1050             u32DataLeft = 0;
1051         }
1052 
1053         for(i =0; i< ScsiCmd_Fail_Retry+2 ;i++) // 20130221, WD HDD My Book 1140 should take 4 times to read the data at the begining
1054         {
1055             struct usb_hcd *hcd = pMass_stor->pusb_dev->bus->hcpriv;
1056 
1057             bConnSts = ms_RoothubPortConnected(hcd) & !(hcd->isRootHubPortReset);
1058 
1059             if (!bConnSts)
1060             {
1061                 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
1062                 diag_printf("Device is disconnect @ read 10 (retry %d)\n", i);
1063 #ifdef ENABLE_RW_DISCONNECTING
1064                 ms_set_bit(MS_IDX_DISCONNECTING, &pMass_stor->flags, unsigned long);
1065 #endif
1066 
1067                 if (hcd->isRootHubPortReset) // debug purpose
1068                     diag_printf("bSCSI_Read10:: ehci reset done = %x, isRootHubPortReset = %x\n", (unsigned int)ehci->u32ResetEnd[0], hcd->isRootHubPortReset);
1069 
1070                 bRet = FALSE;
1071                 goto Func_Done;
1072             }
1073 
1074             //if (pMass_stor==NULL)
1075             if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
1076             {
1077                 diag_printf("Mass_stor_us==NULL!\n");
1078                 bRet = FALSE;
1079                 goto Func_Done;
1080             }
1081 
1082             memset(&pMass_stor->srb, 0, sizeof(struct scMsc_cmd ));
1083 
1084             // Build SCSI command.
1085             ms_vSCSICmd_READ_10(pMass_stor, uLunNum,
1086                     u32BlockAddr + u32BlockOfSet, (U16)u32TransBlockTmp, u8Buffer + u32TransOfSet);
1087             // call mass storage function to send scsi command
1088             ms_usb_msc_control_thread(pMass_stor);
1089             if (pMass_stor->srb.result != MS_STAT_GOOD)
1090             {
1091                 if (pMass_stor->srb.result == MS_STAT_CHECK_CONDITION)
1092                 {
1093                     if(((pMass_stor->srb.sense_buffer[2] & 0xf) == 0x02) &&
1094                         (pMass_stor->srb.sense_buffer[12]  == 0x3A))
1095                     {
1096                         LunDevice[uLunNum].bDeviceReady = FALSE;
1097                     }
1098                     else if(((pMass_stor->srb.sense_buffer[2] & 0xf) == 0x06) &&
1099                         (pMass_stor->srb.sense_buffer[12]  == 0x28))
1100                     {
1101                         LunDevice[uLunNum].bDeviceReady = FALSE;
1102                     }
1103                 }
1104 
1105                 SCSI_DbgPrint("Scsi READ_10 command failed.\n");
1106                 bRet = FALSE;
1107 
1108                 if (pMass_stor->srb.result == (DID_NO_CONNECT << 16))
1109                     break;
1110             }
1111             else
1112             {
1113                 bRet = TRUE;
1114                 break;
1115             }
1116         }
1117 
1118         u32BlockOfSet += u32TransBlockTmp;
1119         u32TransOfSet += u32TransSizeTmp;
1120 
1121         if (bRet == FALSE)
1122             break;
1123     }
1124 
1125 Func_Done:
1126     ms_USBCriticalSectionOut(host_id);
1127 
1128     return bRet;
1129 }
1130 
1131 #if 0 // NUSED
1132 BOOL ms_bSCSI_Write_10_512(U8 uPort, U8 uLunNum, U32 u32BlockAddr, U32 u32BlockNum,
1133                             U8 *u8Buffer)
1134 {
1135     struct ms_usdata *pMass_stor;
1136     BOOL    bRet = TRUE;;
1137     struct LUN_Device* LunDevice;
1138     U32 u32BlkSize_log2;
1139     U32 u32DataLeft;
1140     U32 u32BlockSize;
1141     U8  *lpu8TempBuf = NULL;
1142 
1143     U32 u32RealBlkAddr;
1144     U32 u32RealBlkOffset;
1145     U32 u32RealBlkLast;
1146     U32 u32RealBlkLeft;
1147     U32 u32CopyBytes;
1148     U32 u32BlockNumAdj=0;
1149 
1150     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
1151     {
1152         bRet = FALSE;
1153         goto Write10_done;
1154     }
1155 
1156     LunDevice = pMass_stor->msc_device;
1157     u32BlkSize_log2 = LunDevice[uLunNum].u32BlockSize_log2;
1158     u32DataLeft = u32BlockNum << 9;
1159     u32BlockSize = LunDevice[uLunNum].u32BlockSize;
1160 
1161     if(u32BlockSize != 512)
1162     {
1163         u32RealBlkAddr = (u32BlockAddr * 512) >> u32BlkSize_log2;
1164         u32RealBlkOffset = u32BlockAddr * 512 - u32RealBlkAddr * u32BlockSize;
1165 
1166         u32RealBlkLast = ((u32BlockAddr + u32BlockNum) * 512) >> u32BlkSize_log2;
1167         u32RealBlkLeft = ((u32BlockAddr + u32BlockNum) * 512) - u32RealBlkLast * u32BlockSize;
1168 
1169         u32BlockNumAdj = u32RealBlkLast - u32RealBlkAddr + 1;
1170 
1171 
1172         if(u32RealBlkOffset > 0)
1173         {
1174             lpu8TempBuf = kmalloc(u32BlockSize, GFP_KERNEL);
1175             bRet = ms_bSCSI_Read_10(uPort, uLunNum, u32RealBlkAddr, 1, lpu8TempBuf);
1176             if(!bRet)
1177                 goto Write10_done;
1178             if(u32DataLeft > (u32BlockSize - u32RealBlkOffset))
1179             {
1180                 u32CopyBytes = u32BlockSize - u32RealBlkOffset;
1181                 u32DataLeft -= u32CopyBytes;
1182                 //u32ByteOffset = u32RealBlkOffset;
1183             }
1184             else
1185             {
1186                 u32DataLeft = 0;
1187                 u32CopyBytes = u32DataLeft;
1188             }
1189 
1190             memcpy(lpu8TempBuf + u32RealBlkOffset , u8Buffer, (size_t)u32CopyBytes);
1191             bRet = ms_bSCSI_Write_10(uPort, uLunNum, u32RealBlkAddr, 1, lpu8TempBuf);
1192             if(!bRet)
1193                 goto Write10_done;
1194             u32BlockNumAdj--;
1195             u32RealBlkAddr++;
1196             u8Buffer += u32CopyBytes;
1197         }//Deal with beginning block
1198 
1199         if(u32BlockNumAdj > 0)  //Transfer mid blocks
1200         {
1201             if(u32RealBlkLeft != 0)
1202                 u32BlockNumAdj--;
1203 
1204             bRet = ms_bSCSI_Write_10(uPort, uLunNum, u32RealBlkAddr, u32BlockNumAdj, u8Buffer);
1205             if(!bRet)
1206                 goto Write10_done;
1207             u8Buffer += u32BlockNumAdj * u32BlockSize;
1208             u32DataLeft -= u32BlockNumAdj * u32BlockSize;
1209             if(u32DataLeft > 0)
1210                 u32BlockNumAdj = 1;
1211             else
1212                 u32BlockNumAdj = 0;
1213         }
1214 
1215         if(u32BlockNumAdj > 0) // Have last block
1216         {
1217             if(u32RealBlkLeft > 0)
1218             {
1219                 if(lpu8TempBuf == NULL)
1220                     lpu8TempBuf = kmalloc(u32BlockSize, GFP_KERNEL);
1221                 bRet = ms_bSCSI_Read_10(uPort, uLunNum, u32RealBlkLast, 1, lpu8TempBuf);
1222                 if(!bRet)
1223                     goto Write10_done;
1224 
1225                 memcpy(lpu8TempBuf, u8Buffer, (size_t)u32DataLeft);
1226                 bRet = ms_bSCSI_Write_10(uPort, uLunNum, u32RealBlkLast, 1, lpu8TempBuf);
1227                 if(!bRet)
1228                     goto Write10_done;
1229             }//Deal with ending block
1230         }
1231     }
1232     else
1233     {
1234         bRet = ms_bSCSI_Write_10(uPort, uLunNum, u32BlockAddr, u32BlockNum, u8Buffer);
1235     }
1236 
1237 Write10_done:
1238     if(lpu8TempBuf != NULL)
1239         kfree(lpu8TempBuf);
1240     return bRet;
1241 }
1242 #endif
1243 
ms_bSCSI_Write_10(U8 uPort,U8 uLunNum,U32 u32BlockAddr,U32 u32BlockNum,U8 * u8Buffer)1244 BOOL ms_bSCSI_Write_10(U8 uPort, U8 uLunNum, U32 u32BlockAddr, U32 u32BlockNum, U8 *u8Buffer)
1245 {
1246     struct ms_usdata *pMass_stor;
1247     U32 u32TransBlockTmp, u32TransSizeTmp,u32BlockOfSet = 0, u32TransOfSet = 0;
1248     BOOL    bRet = TRUE, bConnSts;
1249     int     i;
1250     struct LUN_Device* LunDevice;
1251     U32 u32BlkSize_log2;
1252     U32 u32DataLeft;
1253     int     retrycount=0;
1254     U8      host_id;
1255 
1256     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
1257         return FALSE;
1258 #ifdef ENABLE_RW_DISCONNECTING
1259     if (ms_test_bit(MS_IDX_DISCONNECTING, &pMass_stor->flags))
1260     {
1261             SCSI_DbgPrint("[ms_bSCSI_Write_10] OUT\n");
1262             return FALSE;
1263     }
1264 #endif
1265     host_id = pMass_stor->host_id;
1266     if(!ms_USBCriticalSectionIn_TimeOut(host_id, MS_MSC_WAIT_MUTEX_TIMEOUT))
1267     {
1268         SCSI_DbgPrint("[USB] W10 wait Mutex timeout\n");
1269         return FALSE;
1270     }
1271 
1272     if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
1273     {
1274         bRet=FALSE;
1275         goto Func_Done;
1276     }
1277 
1278     LunDevice = pMass_stor->msc_device;
1279     u32BlkSize_log2 = LunDevice[uLunNum].u32BlockSize_log2;
1280     u32DataLeft = u32BlockNum << u32BlkSize_log2;
1281 
1282     if (uLunNum > pMass_stor->max_lun)
1283     {
1284         SCSI_DbgPrint("Invalid LUN Index %d\n",uLunNum);
1285         bRet = FALSE;
1286         goto Func_Done;
1287     }
1288     if (LunDevice[uLunNum].u32BlockTotalNum < u32BlockNum)
1289     {
1290         bRet=FALSE;
1291         goto Func_Done;
1292     }
1293     if (LunDevice[uLunNum].bDeviceReady == FALSE)
1294     {
1295         bRet = FALSE;
1296         goto Func_Done;
1297     }
1298     if(pMass_stor->msc_device[uLunNum].bWriteProtect)
1299     {
1300         SCSI_DbgPrint("Fail to write because write protection\n");
1301         bRet = FALSE;
1302         goto Func_Done;
1303     }
1304 
1305     while(u32DataLeft > 0)
1306     {
1307         if(u32DataLeft > Scsi_Max_Transfer_Len)
1308         {
1309             u32TransBlockTmp = Scsi_Max_Transfer_Len >> u32BlkSize_log2;
1310             u32TransSizeTmp = u32TransBlockTmp << u32BlkSize_log2;
1311             u32DataLeft -= u32TransSizeTmp;
1312         }
1313         else
1314         {
1315             u32TransBlockTmp = u32DataLeft >> u32BlkSize_log2;
1316             u32TransSizeTmp = u32DataLeft;
1317             u32DataLeft = 0;
1318         }
1319 
1320         for(i =0; i< ScsiCmd_Fail_Retry ;i++)
1321         {
1322             struct usb_hcd *hcd = pMass_stor->pusb_dev->bus->hcpriv;
1323 
1324             retrycount = 0;
1325             //When USB disk is disconnect or under reseting, FileSystem still writing data
1326             //and this may caused file system crush. So we block the writing operation for
1327             //20 secs, waiting for USB disk reseting or reconnect.
1328 retry:
1329             {
1330                 //struct usb_hcd *hcd = pMass_stor->current_urb->dev->bus->hcpriv;
1331                 struct usb_hcd *hcd = pMass_stor->pusb_dev->bus->hcpriv;
1332                 bConnSts = ms_RoothubPortConnected(hcd) & !(hcd->isRootHubPortReset);
1333             }
1334 
1335             if (!bConnSts)
1336             {
1337                 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
1338                 diag_printf("Device is disconnect @ write 10 (retry %d)\n", i);
1339 #ifdef ENABLE_RW_DISCONNECTING
1340                 ms_set_bit(MS_IDX_DISCONNECTING, &pMass_stor->flags, unsigned long);
1341 #endif
1342 
1343                 if (hcd->isRootHubPortReset) // debug purpose
1344                     diag_printf("bSCSI_Write10:: ehci reset done = %x, isRootHubPortReset = %x\n", (unsigned int)ehci->u32ResetEnd[0], hcd->isRootHubPortReset);
1345 
1346                 retrycount++;
1347 
1348                 if (0)  //Jonas
1349                 {
1350                     ms_USBCriticalSectionOut(host_id);
1351                     MsOS_DelayTask(2000);
1352                     if(!ms_USBCriticalSectionIn_TimeOut(host_id, MS_MSC_WAIT_MUTEX_TIMEOUT))
1353                         return FALSE;
1354                     goto retry;
1355                 }
1356                 else
1357                 {
1358                     bRet = FALSE;
1359                     goto Func_Done;
1360                 }
1361             }
1362             if ( (pMass_stor = Mass_stor_us[uPort]) == NULL)
1363             {
1364                 diag_printf("Mass_stor_us==NULL!\n");
1365                 retrycount++;
1366                 //if(retrycount <= 10)
1367                 if(0)  //Jonas
1368                 {
1369                     ms_USBCriticalSectionOut(host_id);
1370                     MsOS_DelayTask(2000);
1371                     if(!ms_USBCriticalSectionIn_TimeOut(host_id, MS_MSC_WAIT_MUTEX_TIMEOUT))
1372                         return FALSE;
1373                     goto retry;
1374                 }
1375                 else
1376                 {
1377                     bRet = FALSE;
1378                     goto Func_Done;
1379                 }
1380             }
1381 
1382             memset(&pMass_stor->srb, 0, sizeof(struct scMsc_cmd ));
1383 
1384             // Build SCSI command.
1385             ms_vSCSICmd_WRITE_10(pMass_stor, uLunNum,
1386                                 u32BlockAddr + u32BlockOfSet, (U16)u32TransBlockTmp, u8Buffer + u32TransOfSet);
1387 
1388             // call mass storage function to send scsi command
1389             ms_usb_msc_control_thread(pMass_stor);
1390 
1391             if(pMass_stor->srb.result != MS_STAT_GOOD)
1392             {
1393                 if (pMass_stor->srb.result == MS_STAT_CHECK_CONDITION)
1394                 {
1395                     if(((pMass_stor->srb.sense_buffer[2] & 0xf) == 0x02) &&
1396                         (pMass_stor->srb.sense_buffer[12]  == 0x3A))
1397                     {
1398                         LunDevice[uLunNum].bDeviceReady = FALSE;
1399                     }
1400                     else if(((pMass_stor->srb.sense_buffer[2] & 0xf) == 0x06) &&
1401                         (pMass_stor->srb.sense_buffer[12]  == 0x28))
1402                     {
1403                         LunDevice[uLunNum].bDeviceReady = FALSE;
1404                     }
1405                 }
1406 
1407                 SCSI_DbgPrint("Scsi WRITE_10 command failed.\n");
1408                 bRet = FALSE;
1409 
1410                 if (pMass_stor->srb.result == (DID_NO_CONNECT << 16))
1411                     break;
1412             }
1413             else
1414             {
1415                 bRet = TRUE;
1416                 break;
1417             }
1418         }
1419 
1420         u32BlockOfSet += u32TransBlockTmp;
1421         u32TransOfSet += u32TransSizeTmp;
1422 
1423         if (bRet == FALSE)
1424             break;
1425     }
1426 
1427 Func_Done:
1428     ms_USBCriticalSectionOut(host_id);
1429 
1430     return bRet;
1431 }
1432 
ms_vScsi_SendCmd_Done(struct scMsc_cmd * srb)1433 static void ms_vScsi_SendCmd_Done(struct scMsc_cmd *srb)
1434 {
1435     SCSI_DbgPrint("SCSI command (0x%x) Done, result = 0x%x\n", srb->cmnd[0], srb->result);
1436 }
1437 
ms_bIsDevValid(U8 uPort,U8 LunNum)1438 BOOL ms_bIsDevValid(U8 uPort, U8 LunNum)
1439 {
1440     struct LUN_Device* LunDevice = Mass_stor_us[uPort]->msc_device;
1441 
1442     if (LunNum <= Mass_stor_us[uPort]->max_lun)
1443         return (LunDevice[LunNum].bFSInit);
1444     else
1445         return FALSE;
1446 }
1447 #if 0 // NUSED
1448 U8 ms_u8GetDevType(U8 uPort, U8 LunNum)
1449 {
1450     struct LUN_Device* LunDevice = Mass_stor_us[uPort]->msc_device;
1451 
1452     if (LunNum <= Mass_stor_us[uPort]->max_lun)
1453         return LunDevice[LunNum].u8DevType;
1454     else
1455         return  0;
1456 }
1457 #endif
1458 /*-------------------------------------------------------------------------*/
1459 /* Mass storage class API */
MDrv_GetUsbBlockSize(MS_U8 lun)1460 MS_U32 MDrv_GetUsbBlockSize(MS_U8 lun)
1461 {
1462     MS_U32 uBlkSize = 0;
1463 
1464     if ( (Mass_stor_us[0] != NULL) && (lun <= Mass_stor_us[0]->max_lun) )
1465     {
1466         uBlkSize = Mass_stor_us[0]->msc_device[lun].u32BlockSize;
1467     }
1468 
1469     return uBlkSize;
1470 }
1471 
MDrv_GetUsbBlockSizeEx(MS_U8 uPort,MS_U8 lun)1472 MS_U32 MDrv_GetUsbBlockSizeEx(MS_U8 uPort, MS_U8 lun)
1473 {
1474     MS_U32 uBlkSize = 0;
1475 
1476     if ( (Mass_stor_us[uPort] != NULL) && (lun <= Mass_stor_us[uPort]->max_lun) )
1477     {
1478         uBlkSize = Mass_stor_us[uPort]->msc_device[lun].u32BlockSize;
1479     }
1480 
1481     return uBlkSize;
1482 }
1483 
MDrv_GetUsbBlockNum(MS_U8 lun)1484 MS_U32 MDrv_GetUsbBlockNum(MS_U8 lun)
1485 {
1486     MS_U32 uTotalBlks = 0;
1487 
1488     if ( (Mass_stor_us[0] != NULL) && (lun <= Mass_stor_us[0]->max_lun) )
1489     {
1490         uTotalBlks = Mass_stor_us[0]->msc_device[lun].u32BlockTotalNum;
1491     }
1492 
1493     return uTotalBlks;
1494 }
1495 
MDrv_GetUsbBlockNumEx(MS_U8 uPort,MS_U8 lun)1496 MS_U32 MDrv_GetUsbBlockNumEx(MS_U8 uPort, MS_U8 lun)
1497 {
1498     MS_U32 uTotalBlks = 0;
1499 
1500     if ( (Mass_stor_us[uPort] != NULL) && (lun <= Mass_stor_us[uPort]->max_lun) )
1501     {
1502         uTotalBlks = Mass_stor_us[uPort]->msc_device[lun].u32BlockTotalNum;
1503     }
1504 
1505     return uTotalBlks;
1506 }
1507 
MDrv_UsbGetMaxLUNCount(void)1508 MS_U8 MDrv_UsbGetMaxLUNCount(void)
1509 {
1510     if (Mass_stor_us[0] != NULL)
1511         return Mass_stor_us[0]->max_lun + 1;
1512     else
1513         return 0;
1514 }
1515 
MDrv_UsbGetMaxLUNCountEx(MS_U8 uPort)1516 MS_U8 MDrv_UsbGetMaxLUNCountEx(MS_U8 uPort)
1517 {
1518     if (Mass_stor_us[uPort] != NULL)
1519         return Mass_stor_us[uPort]->max_lun + 1;
1520     else
1521         return 0;
1522 }
1523 
MDrv_UsbBlockReadToMIU(MS_U8 lun,MS_U32 u32BlockAddr,MS_U32 u32BlockNum,MS_U32 u32MIUAddr)1524 MS_BOOL MDrv_UsbBlockReadToMIU(
1525     MS_U8 lun,
1526     MS_U32 u32BlockAddr,
1527     MS_U32 u32BlockNum,
1528     MS_U32 u32MIUAddr)
1529 {
1530     return ms_bSCSI_Read_10(0, lun, u32BlockAddr, u32BlockNum, (U8*) u32MIUAddr);
1531 }
1532 
MDrv_UsbBlockReadToMIUEx(MS_U8 uPort,MS_U8 lun,MS_U32 u32BlockAddr,MS_U32 u32BlockNum,MS_U32 u32MIUAddr)1533 MS_BOOL MDrv_UsbBlockReadToMIUEx(
1534     MS_U8 uPort,
1535     MS_U8 lun,
1536     MS_U32 u32BlockAddr,
1537     MS_U32 u32BlockNum,
1538     MS_U32 u32MIUAddr)
1539 {
1540     return ms_bSCSI_Read_10(uPort, lun, u32BlockAddr, u32BlockNum, (U8*) u32MIUAddr);
1541 }
1542 
MDrv_UsbBlockWriteFromMIU(MS_U8 lun,MS_U32 u32BlockAddr,MS_U32 u32BlockNum,MS_U32 u32MIUAddr)1543 MS_BOOL MDrv_UsbBlockWriteFromMIU(
1544     MS_U8 lun,
1545     MS_U32 u32BlockAddr,
1546     MS_U32 u32BlockNum,
1547     MS_U32 u32MIUAddr)
1548 {
1549     return ms_bSCSI_Write_10(0, lun, u32BlockAddr, u32BlockNum, (U8*) u32MIUAddr);
1550 }
1551 
MDrv_UsbBlockWriteFromMIUEx(MS_U8 uPort,MS_U8 lun,MS_U32 u32BlockAddr,MS_U32 u32BlockNum,MS_U32 u32MIUAddr)1552 MS_BOOL MDrv_UsbBlockWriteFromMIUEx(
1553     MS_U8 uPort,
1554     MS_U8 lun,
1555     MS_U32 u32BlockAddr,
1556     MS_U32 u32BlockNum,
1557     MS_U32 u32MIUAddr)
1558 {
1559     return ms_bSCSI_Write_10(uPort, lun, u32BlockAddr, u32BlockNum, (U8*) u32MIUAddr);
1560 }
1561 
MDrv_UsbIsLunConnected(MS_U8 uPort,MS_U8 lun)1562 MS_BOOL MDrv_UsbIsLunConnected(MS_U8 uPort, MS_U8 lun)
1563 {
1564     struct LUN_Device* LunDevice;
1565 
1566     if (Mass_stor_us[uPort] == NULL)
1567         return FALSE;
1568 
1569     LunDevice = Mass_stor_us[uPort]->msc_device;
1570 
1571     if (lun <= Mass_stor_us[uPort]->max_lun)
1572         return (LunDevice[lun].bFSInit);
1573     else
1574         return FALSE;
1575 
1576 }
1577 
ms_MSC_fast_device_disconnect(MS_U8 uDevS,MS_U8 uDevE)1578 void ms_MSC_fast_device_disconnect(MS_U8 uDevS, MS_U8 uDevE)
1579 {
1580     MS_U8       us_id; // for MSC
1581 
1582     for (us_id=uDevS; us_id<uDevE; us_id++)
1583     {
1584         if (Is_Stor_Dev_Info_Valid(us_id))   // Check if we found a Mass Stoarge device.
1585         {
1586             struct ms_usdata *pMass_stor = Mass_stor_us[us_id];
1587             ms_set_bit(MS_IDX_DISCONNECTING, &pMass_stor->flags, unsigned long);
1588         }
1589     }
1590 }
1591 
ms_readyChk_USB_LUNs(int * gated)1592 MS_BOOL ms_readyChk_USB_LUNs(int *gated)
1593 {
1594     static MS_U32 usbTURStartTime = 0;
1595 
1596     if (*gated)
1597         return TRUE;
1598 
1599     if (MsOS_GetSystemTime()-usbTURStartTime > 1000 )
1600     {
1601         usbTURStartTime = MsOS_GetSystemTime();
1602         *gated = 1;
1603         return TRUE;
1604     }
1605     return FALSE;
1606 }
1607 
ms_MSC_device_inquiry(MS_U8 uDevS,MS_U8 uDevE)1608 void ms_MSC_device_inquiry(MS_U8 uDevS, MS_U8 uDevE)
1609 {
1610     MS_U8       ii, us_id; // for MSC
1611     int all_luns_check_gated = 0;
1612 
1613     for (us_id=uDevS; us_id<uDevE; us_id++)
1614     {
1615         if (Is_Stor_Dev_Info_Valid(us_id))   // Check if we found a Mass Stoarge device.
1616         {
1617 #ifdef ENABLE_DISCONNECT_FAST_RESPONSE
1618             struct ms_usdata *pMass_stor = Mass_stor_us[us_id];
1619 
1620             if (ms_test_bit(MS_IDX_DISCONNECTING, &pMass_stor->flags))
1621                 continue;
1622 #endif
1623             if (!Is_Stor_Dev_Init(us_id))    // First time after connected
1624             {
1625                 if (ms_bInit_USB_Disk(us_id))
1626                 {
1627                     SCSI_DbgPrint("found a Mass Storage device @ port %d, try to init it\n", Mass_stor_us[us_id]->host_id);
1628                     for (ii=0; ii<=Get_Stor_Max_Lun(us_id); ii++)
1629                     {
1630                         if (ms_bIsDevValid(us_id, ii))
1631                         {
1632                             struct ms_usdata *pMass_stor = Mass_stor_us[us_id];
1633                             struct LUN_Device* LunDevice = pMass_stor->msc_device;
1634 
1635                             diag_printf("LUN %d is init ok\n", ii);
1636                             if (LunDevice[ii].u8DevType & 0x80)
1637                                 diag_printf("Removable MSC Lun %d\n", ii);
1638                         }
1639                     }
1640                     Set_Stor_Dev_Init(us_id, TRUE);
1641                     diag_printf("MSC plug in\n");
1642                 }
1643             }
1644             else if (ms_readyChk_USB_LUNs(&all_luns_check_gated))
1645             {
1646                 ms_vChk_USB_LUNs(us_id);
1647                 //if (ms_vChk_USB_LUNs(us_id)) // all LUN ready
1648                 //{
1649                 //    for (ii=0; ii<=Get_Stor_Max_Lun(us_id); ii++)
1650                 //    {
1651                 //        if (ms_bIsDevValid(us_id, ii))
1652                 //        {
1653                 //            SCSI_DbgPrint("Chk LUN %d is init ok\n", ii);
1654                 //        }
1655                 //    }
1656                 //}
1657             }
1658         }
1659     }
1660 }
1661 
1662