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