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