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