xref: /utopia/UTPA2-700.0.x/modules/usb/drv/usbhost/source/usb_host_p1/drvScsi.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ////////////////////////////////////////////////////////////////////////////////
79 //
80 // Copyright (c) 2006-2008 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // (��MStar Confidential Information��) by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94 #if defined(MSOS_TYPE_NOS)
95 #include "../USBHostConfig.h"
96 #include <stdlib.h>
97 #ifndef ATV_SERISE_USE
98 #include <stdio.h>
99 #endif
100 #include <string.h>
101 #ifndef ATV_SERISE_USE
102 #include "../../include/datatype.h"
103 #else
104 #include "UsbHostDataDef.h"
105 #endif
106 #include "../drvHostLib.h"
107 #include "../drvHost200.h"
108 #include "../drvscsi.h"
109 #include "../drvMassStorage.h"
110 #ifdef ATV_SERISE_USE
111 #include "Board.h"
112 #include "common.h"
113 #include "uart.h"
114 #endif
115 #include "../drvUsbMain.h"
116 #include "../../include/_drvUSB.h"
117 #include "MsCommon.h"
118 #include "MsIRQ.h"
119 #include "MsOS.h"
120 
121 extern void msAPI_Timer_ResetWDT(void);
122 
123 #define DRV_SCSI_DBG(x) // x;
124 
125 //struct us_data xdata *Mass_stor_us;
126 #define MAX_LUN_SUPPORT    5
127 
128 struct us_data  Mass_stor_us1;
129 #if 1
130 struct LUN_Device  Mass_stor_device[MAX_LUN_SUPPORT]; //support 4 LUN
131 #else
132 struct LUN_Device  Mass_stor_device_1; //support 4 LUN
133 struct LUN_Device  Mass_stor_device_2;
134 struct LUN_Device  Mass_stor_device_3;
135 struct LUN_Device  Mass_stor_device_4;
136 struct LUN_Device  Mass_stor_device_5;
137 #endif
138 
139 extern UINT8  pUsbData[1024];
140 Scsi_Cmnd  srb_data;
141 
142 UINT8 u8Drive = 0;
143 extern U8 gUsbStatus;
144 extern U8 gSpeed;
145 
146 struct stForceModeSense1A
147 {
148     U16     VID;
149     U16     PID;
150 } stForceModeSense1A;
151 
152 struct stForceModeSense1A gForceModeSense1A[] =
153 {
154         {0x0DD8, 0x1448},
155         {0x1AA6, 0x0201},
156         {0x0DD8, 0x1414},
157         {0x0DD8, 0x1400},
158         {0x0DD8, 0xE203},
159         {0x8644, 0x800a},           //alan.yu add on 2010.08.13 (�Ϲ� ����)
160         {0x0DD8, 0xD202},           //alan.yu add on 2010.08.16 (�ʿ�Netac)
161         {0x18A5,0x302},             //alan.yu add on 2011.08.01
162         {0, 0}
163 };
164 
165 extern void MDrv_USBGetVIDPID(U16 *pVID, U16 *pPID);
166 
167 //BOOLEAN gDeviceFatalError=FALSE;
Init_Mass_Storage_Structure(void)168 void Init_Mass_Storage_Structure(void)
169 {
170   U16   uVID, uPID;
171   //Mass_stor_us=&Mass_stor_us1;
172   memset(&Mass_stor_device[0], 0, sizeof(Mass_stor_device[0]));
173   Mass_stor_us1.Mass_stor_device=&Mass_stor_device[0];
174 #ifdef   ENABLE_CBI_HOST
175   if ( (sAttachDevice.saCD[0].sInterface[0].bInterfaceProtocol==0x00)||
176        (sAttachDevice.saCD[0].sInterface[0].bInterfaceProtocol==0x01) )
177     Mass_stor_us1.max_lun=0;
178   else
179 #endif
180   {
181     MDrv_USBGetVIDPID(&uVID, &uPID);
182     //printf("MAXLUN VID: %x, PID: %x\n", uVID, uPID);
183     if ( ((uVID == 0x8564) && (uPID == 0x1000)) ||
184          ((uVID == 0xFCA) && (uPID == 0x8004)) ) //20130301, for blackberry phone
185         Mass_stor_us1.max_lun = 0;
186     else
187         Mass_stor_us1.max_lun=   Host20_MSCD_GetMaxLUN();
188   }
189 
190     if (Mass_stor_us1.max_lun > (MAX_LUN_SUPPORT-1) )
191         Mass_stor_us1.max_lun = MAX_LUN_SUPPORT-1;
192 
193   //printf("Max Lun:%02bx\n",Mass_stor_us1.max_lun);
194 }
195 //***************************************************************************************
196 // Function Name: vSCSICmd_READ_10
197 // Description:
198 // Input:
199 // Output:
200 // Status:S
201 //***************************************************************************************
vSCSICmd_READ_WRITE_10(BOOLEAN DoWrite,struct us_data * us,Scsi_Cmnd * srb,INT8U u8LunNum,INT32U u32BlockAddr,INT16U u16BlockNum,U32 u8Buffer)202 void vSCSICmd_READ_WRITE_10(BOOLEAN DoWrite,struct us_data *us, Scsi_Cmnd *srb, INT8U u8LunNum,
203 							  INT32U u32BlockAddr, INT16U u16BlockNum, U32 u8Buffer)
204 {
205 
206 
207   /* set the command and the LUN */
208   #if 0
209   memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
210   srb->cmnd[0] = READ_10;
211 
212   srb->cmnd[2] = (INT8U)(u32BlockAddr >> 24);
213   srb->cmnd[3] = (INT8U)(u32BlockAddr >> 16);
214   srb->cmnd[4] = (INT8U)(u32BlockAddr >> 8);
215   srb->cmnd[5] = (INT8U)(u32BlockAddr);
216 
217   srb->cmnd[7] = (INT8U)(u16BlockNum >> 8);
218   srb->cmnd[8] = (INT8U)(u16BlockNum );
219   #endif
220   if (DoWrite)
221     OTGH_PT_BLK.sCBW.u8CB[0]=WRITE_10;
222   else
223     OTGH_PT_BLK.sCBW.u8CB[0]=READ_10;
224   OTGH_PT_BLK.sCBW.u8CB[1]=0;
225 
226   OTGH_PT_BLK.sCBW.u8CB[2]= (INT8U)(u32BlockAddr >> 24);
227   OTGH_PT_BLK.sCBW.u8CB[3]= (INT8U)(u32BlockAddr >> 16);
228   OTGH_PT_BLK.sCBW.u8CB[4]= (INT8U)(u32BlockAddr >> 8);
229   OTGH_PT_BLK.sCBW.u8CB[5]= (INT8U)(u32BlockAddr);
230 
231   OTGH_PT_BLK.sCBW.u8CB[7] = (INT8U)(u16BlockNum >> 8);
232   OTGH_PT_BLK.sCBW.u8CB[8] = (INT8U)(u16BlockNum );
233 
234 
235   /* FIXME: we must do the protocol translation here */
236   /*
237   if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
238     srb->cmd_len = 6;
239   else
240 	srb->cmd_len = 12;
241   */
242   srb->cmd_len = 10;
243 
244   /* set the transfer direction */
245   if (DoWrite)
246   	srb->sc_data_direction = SCSI_DATA_WRITE;
247   else
248 	srb->sc_data_direction = SCSI_DATA_READ;
249 
250   /* use the new buffer we have */
251   srb->request_buffer= u8Buffer;
252 
253   /* set the buffer length for transfer */
254   srb->request_bufflen = (us->Mass_stor_device[u8LunNum].u32BlockSize)*u16BlockNum;
255 
256   /* set up for no scatter-gather use */
257   //srb->use_sg = 0;
258 
259   /* change the serial number -- toggle the high bit*/
260   //srb->serial_number ^= 0x80000000;
261 
262   /* set Lun number*/
263   srb->lun= u8LunNum;
264 
265   //srb->scsi_done = vScsi_SendCmd_Done;
266 
267 
268 
269 }
270 #if 0
271 //***************************************************************************************
272 // Function Name:
273 // Description:
274 // Input:
275 // Output:
276 // Status:S
277 //***************************************************************************************
278 void vSCSICmd_WRITE_10(struct us_data *us, Scsi_Cmnd *srb,  INT8U u8LunNum,
279 							  INT32U u32BlockAddr, INT16U u16BlockNum, U32 u8Buffer)
280 {
281 
282 
283   /* set the command and the LUN */
284   #if 0
285   memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
286   srb->cmnd[0] = WRITE_10;
287 
288   srb->cmnd[2] = (INT8U)(u32BlockAddr >> 24);
289   srb->cmnd[3] = (INT8U)(u32BlockAddr >> 16);
290   srb->cmnd[4] = (INT8U)(u32BlockAddr >> 8);
291   srb->cmnd[5] = (INT8U)(u32BlockAddr);
292 
293   srb->cmnd[7] = (INT8U)(u16BlockNum >> 8);
294   srb->cmnd[8] = (INT8U)(u16BlockNum );
295   #endif
296   OTGH_PT_BLK.sCBW.u8CB[0]=WRITE_10;
297   OTGH_PT_BLK.sCBW.u8CB[1]=0;
298 
299   OTGH_PT_BLK.sCBW.u8CB[2]= (INT8U)(u32BlockAddr >> 24);
300   OTGH_PT_BLK.sCBW.u8CB[3]= (INT8U)(u32BlockAddr >> 16);
301   OTGH_PT_BLK.sCBW.u8CB[4]= (INT8U)(u32BlockAddr >> 8);
302   OTGH_PT_BLK.sCBW.u8CB[5]= (INT8U)(u32BlockAddr);
303 
304   OTGH_PT_BLK.sCBW.u8CB[7] = (INT8U)(u16BlockNum >> 8);
305   OTGH_PT_BLK.sCBW.u8CB[8] = (INT8U)(u16BlockNum );
306 
307   /* FIXME: we must do the protocol translation here */
308   /*
309   if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
310     srb->cmd_len = 6;
311   else
312 	srb->cmd_len = 12;
313   */
314   srb->cmd_len = CB_LENGTH_WRITE_10;
315 
316   /* set the transfer direction */
317   srb->sc_data_direction = SCSI_DATA_WRITE;
318 
319   /* use the new buffer we have */
320   srb->phy_buf_adr=u8Buffer;
321   srb->buffer_type=BUFFER_PHY;
322 
323   /* set the buffer length for transfer */
324   srb->request_bufflen = us->Mass_stor_device[u8LunNum].u32BlockSize*u16BlockNum;
325 
326   /* set up for no scatter-gather use */
327   //srb->use_sg = 0;
328 
329   /* change the serial number -- toggle the high bit*/
330   //srb->serial_number ^= 0x80000000;
331 
332   /* set Lun number*/
333   srb->lun= u8LunNum;
334 
335   //srb->scsi_done = vScsi_SendCmd_Done;
336 
337 
338 }
339 #endif
340 //***************************************************************************************
341 // Function Name:
342 // Description:
343 // Input:
344 // Output:
345 // Status:S
346 //***************************************************************************************
vSCSICmd_INQUIRY(Scsi_Cmnd * srb,INT8U * u8Buffer)347 void vSCSICmd_INQUIRY( Scsi_Cmnd *srb, INT8U *u8Buffer)
348 {
349 
350 
351   /* set the command and the LUN */
352   //memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
353   //srb->cmnd[0] = INQUIRY;
354   //srb->cmnd[4] = DATA_LENGTH_INQUIRY;
355   memset(&OTGH_PT_BLK.sCBW.u8CB[0], 0, 16);
356   OTGH_PT_BLK.sCBW.u8CB[0]= INQUIRY;
357   OTGH_PT_BLK.sCBW.u8CB[4]= DATA_LENGTH_INQUIRY;
358 
359   /* FIXME: we must do the protocol translation here */
360   /*
361   if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
362     srb->cmd_len = 6;
363   else
364 	srb->cmd_len = 12;
365   */
366   srb->cmd_len = CB_LENGTH_INQUIRY;
367 
368   /* set the transfer direction */
369   srb->sc_data_direction = SCSI_DATA_READ;
370 
371   /* use the new buffer we have */
372     srb->request_buffer = (U32)u8Buffer;
373 
374   /* set the buffer length for transfer */
375   srb->request_bufflen = DATA_LENGTH_INQUIRY;
376 
377   /* set up for no scatter-gather use */
378   //srb->use_sg = 0;
379 
380   /* change the serial number -- toggle the high bit*/
381   //srb->serial_number ^= 0x80000000;
382 
383   /* set Lun number*/
384   //srb->lun= u8Drive;//0;
385 
386   //srb->scsi_done = vScsi_SendCmd_Done;
387 
388 
389 }
390 //***************************************************************************************
391 // Function Name:
392 // Description:
393 // Input:
394 // Output:
395 // Status:S
396 //***************************************************************************************
vSCSICmd_READ_CAPACITY(Scsi_Cmnd * srb,INT8U * u8Buffer)397 void vSCSICmd_READ_CAPACITY( Scsi_Cmnd *srb, INT8U *u8Buffer)
398 {
399 
400   /* set the command and the LUN */
401   //memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
402   //srb->cmnd[0] = READ_CAPACITY;
403   memset(&OTGH_PT_BLK.sCBW.u8CB[0], 0, 16);
404   OTGH_PT_BLK.sCBW.u8CB[0]= READ_CAPACITY;
405 
406   /* FIXME: we must do the protocol translation here */
407   /*
408   if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
409     srb->cmd_len = 6;
410   else
411 	srb->cmd_len = 12;
412   */
413   srb->cmd_len = CB_LENGTH_READ_CAPACITY;
414 
415   /* set the transfer direction */
416   srb->sc_data_direction = SCSI_DATA_READ;
417 
418   /* use the new buffer we have */
419     srb->request_buffer = (U32)u8Buffer;
420 
421   /* set the buffer length for transfer */
422   srb->request_bufflen = DATA_LENGTH_READ_CAPACITY;
423 
424   /* set up for no scatter-gather use */
425   //srb->use_sg = 0;
426 
427   /* change the serial number -- toggle the high bit*/
428   //srb->serial_number ^= 0x80000000;
429 
430   /* set Lun number*/
431   //srb->lun= u8Drive;
432 
433   //srb->scsi_done = vScsi_SendCmd_Done;
434 
435 
436 }
437 
vSCSICmd_READ_FORMAT_CAPACITY(Scsi_Cmnd * srb,INT8U * u8Buffer)438 void vSCSICmd_READ_FORMAT_CAPACITY( Scsi_Cmnd *srb, INT8U *u8Buffer)
439 {
440 
441   /* set the command and the LUN */
442   //memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
443   //srb->cmnd[0] = READ_CAPACITY;
444   memset(&OTGH_PT_BLK.sCBW.u8CB[0], 0, 16);
445   OTGH_PT_BLK.sCBW.u8CB[0]= READ_FORMAT_CAPACITY;
446   OTGH_PT_BLK.sCBW.u8CB[8]= 12; //Length
447 
448   /* FIXME: we must do the protocol translation here */
449   /*
450   if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
451     srb->cmd_len = 6;
452   else
453 	srb->cmd_len = 12;
454   */
455   srb->cmd_len = CB_LENGTH_READ_CAPACITY;
456 
457   /* set the transfer direction */
458   srb->sc_data_direction = SCSI_DATA_READ;
459 
460   /* use the new buffer we have */
461   srb->request_buffer = (U32)u8Buffer;
462 
463   /* set the buffer length for transfer */
464   srb->request_bufflen = 12;
465 
466   /* set up for no scatter-gather use */
467   //srb->use_sg = 0;
468 
469   /* change the serial number -- toggle the high bit*/
470   //srb->serial_number ^= 0x80000000;
471 
472   /* set Lun number*/
473   //srb->lun= u8Drive;
474 
475   //srb->scsi_done = vScsi_SendCmd_Done;
476 
477 
478 }
479 
480 //***************************************************************************************
481 // Function Name:vSCSICmd_MODE_SENSE
482 // Description:
483 // Input:
484 // Output:
485 // Status:
486 //***************************************************************************************
vSCSICmd_MODE_SENSE(Scsi_Cmnd * srb,INT8U u8PageCode,INT8U * u8Buffer)487 void vSCSICmd_MODE_SENSE( Scsi_Cmnd *srb,INT8U u8PageCode,INT8U *u8Buffer)
488 {
489 
490   /* set the command and the LUN */
491   //memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
492   //srb->cmnd[0] = MODE_SENSE;
493   //srb->cmnd[2] = u8PageCode;
494   //srb->cmnd[4] = DATA_LENGTH_MODE_SENSE;
495   memset(&OTGH_PT_BLK.sCBW.u8CB[0], 0, 16);
496   OTGH_PT_BLK.sCBW.u8CB[0]= MODE_SENSE;
497   OTGH_PT_BLK.sCBW.u8CB[2]= u8PageCode;
498   OTGH_PT_BLK.sCBW.u8CB[4]= DATA_LENGTH_MODE_SENSE;
499 
500   /* FIXME: we must do the protocol translation here */
501   /*
502   if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
503     srb->cmd_len = 6;
504   else
505     srb->cmd_len = 12;
506   */
507   srb->cmd_len = CB_LENGTH_MODE_SENSE;
508 
509   /* set the transfer direction */
510   srb->sc_data_direction = SCSI_DATA_READ;
511 
512   /* use the new buffer we have */
513     srb->request_buffer = (U32)u8Buffer;
514   /* set the buffer length for transfer */
515   srb->request_bufflen = DATA_LENGTH_MODE_SENSE;
516 
517   /* set up for no scatter-gather use */
518   //srb->use_sg = 0;
519 
520   /* change the serial number -- toggle the high bit*/
521   //srb->serial_number ^= 0x80000000;
522 
523   /* set Lun number*/
524   //srb->lun= u8Drive;
525 
526   //srb->scsi_done = vScsi_SendCmd_Done;
527 
528 
529 }
530 
531 //***************************************************************************************
532 // Function Name:vSCSICmd_MODE_SENSE_OperCode5A
533 // Description:
534 // Input:
535 // Output:
536 // Status:
537 //***************************************************************************************
vSCSICmd_MODE_SENSE_OperCode5A(Scsi_Cmnd * srb,INT8U u8PageCode,INT8U * u8Buffer)538 void vSCSICmd_MODE_SENSE_OperCode5A( Scsi_Cmnd *srb,INT8U u8PageCode,INT8U *u8Buffer)
539 {
540 
541   /* set the command and the LUN */
542   //memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
543   //srb->cmnd[0] = MODE_SENSE;
544   //srb->cmnd[2] = u8PageCode;
545   //srb->cmnd[4] = DATA_LENGTH_MODE_SENSE;
546   memset(&OTGH_PT_BLK.sCBW.u8CB[0], 0, 16);
547   OTGH_PT_BLK.sCBW.u8CB[0]= MODE_SENSE_5A;
548   OTGH_PT_BLK.sCBW.u8CB[2]= u8PageCode;
549 #if 0
550   OTGH_PT_BLK.sCBW.u8CB[4]= DATA_LENGTH_MODE_SENSE_OperCode5A;		//RCC?
551 #else
552   OTGH_PT_BLK.sCBW.u8CB[7] = (INT8U)(DATA_LENGTH_MODE_SENSE_OperCode5A >> 8);
553   OTGH_PT_BLK.sCBW.u8CB[8] = (INT8U)(DATA_LENGTH_MODE_SENSE_OperCode5A );
554 #endif
555   /* FIXME: we must do the protocol translation here */
556   /*
557   if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
558     srb->cmd_len = 6;
559   else
560     srb->cmd_len = 12;
561   */
562   srb->cmd_len = CB_LENGTH_MODE_SENSE_OperCode5A;
563 
564   /* set the transfer direction */
565   srb->sc_data_direction = SCSI_DATA_READ;
566 
567   /* use the new buffer we have */
568     srb->request_buffer = (U32)u8Buffer;
569   /* set the buffer length for transfer */
570   srb->request_bufflen = DATA_LENGTH_MODE_SENSE_OperCode5A;
571 
572   /* set up for no scatter-gather use */
573   //srb->use_sg = 0;
574 
575   /* change the serial number -- toggle the high bit*/
576   //srb->serial_number ^= 0x80000000;
577 
578   /* set Lun number*/
579   //srb->lun= u8Drive;
580 
581   //srb->scsi_done = vScsi_SendCmd_Done;
582 
583 
584 }
585 
586 //***************************************************************************************
587 // Function Name:vSCSICmd_REQUEST_SENSE
588 // Description:
589 // Input:
590 // Output:
591 // Status:
592 //***************************************************************************************
vSCSICmd_REQUEST_SENSE(Scsi_Cmnd * srb,INT8U * u8Buffer)593 void vSCSICmd_REQUEST_SENSE(  Scsi_Cmnd *srb, INT8U *u8Buffer)
594 {
595 
596 
597   /* set the command and the LUN */
598   //memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
599   //srb->cmnd[0] = REQUEST_SENSE;
600   //srb->cmnd[4] = 18;
601   memset(&OTGH_PT_BLK.sCBW.u8CB[0], 0, 16);
602   OTGH_PT_BLK.sCBW.u8CB[0]= REQUEST_SENSE;
603   OTGH_PT_BLK.sCBW.u8CB[4]= 18;
604 
605   /* FIXME: we must do the protocol translation here */
606   /*
607   if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
608     srb->cmd_len = 6;
609   else
610 	srb->cmd_len = 12;
611   */
612   srb->cmd_len = CB_LENGTH_REQUEST_SENSE;
613 
614   /* set the transfer direction */
615   srb->sc_data_direction = SCSI_DATA_READ;
616 
617   /* use the new buffer we have */
618     srb->request_buffer = (U32)u8Buffer;
619   /* set the buffer length for transfer */
620   srb->request_bufflen = 18;
621 
622   /* set up for no scatter-gather use */
623   //srb->use_sg = 0;
624 
625   /* change the serial number -- toggle the high bit*/
626   //srb->serial_number ^= 0x80000000;
627 
628   /* set Lun number*/
629   //srb->lun= u8Drive;
630 
631   //srb->scsi_done = vScsi_SendCmd_Done;
632 
633 
634 }
635 #if 0
636 //***************************************************************************************
637 // Function Name:vSCSICmd_TEST_UNIT_READY
638 // Description:
639 // Input:
640 // Output:
641 // Status:S
642 //***************************************************************************************
643 void vSCSICmd_TEST_UNIT_READY( Scsi_Cmnd *srb)
644 {
645 
646   memset(&OTGH_PT_BLK.sCBW.u8CB[0], 0, 16);
647   OTGH_PT_BLK.sCBW.u8CB[0]= TEST_UNIT_READY;
648 
649   srb->cmd_len = CB_LENGTH_TEST_UNIT_READY;
650 
651 
652   /* set the transfer direction */
653   srb->sc_data_direction = SCSI_DATA_READ;
654 
655   /* set the buffer length for transfer */
656   srb->request_bufflen = 0;
657 
658 }
659 #endif
660 
vSCSICmd_Prepare(Scsi_Cmnd * srb,U8 cmd)661 void vSCSICmd_Prepare(Scsi_Cmnd *srb, U8 cmd)
662 {
663   memset(&OTGH_PT_BLK.sCBW.u8CB[0], 0, 16);
664   OTGH_PT_BLK.sCBW.u8CB[0]= cmd;
665 
666   srb->cmd_len = 6;
667   /* set the transfer direction */
668   srb->sc_data_direction = SCSI_DATA_READ;
669   /* set the buffer length for transfer */
670   srb->request_bufflen = 0;
671 }
672 
673 
674 
675 
vSCSI_EJECT_DEVICE(U8 lun)676 BOOLEAN  vSCSI_EJECT_DEVICE(U8 lun)
677 {
678   BOOLEAN result;
679 
680   Mass_stor_us1.srb =&srb_data;
681   memset(Mass_stor_us1.srb, 0, sizeof(struct scsi_cmnd ));
682 
683   vSCSICmd_Prepare(Mass_stor_us1.srb,START_STOP);
684   Mass_stor_us1.srb->lun=lun;
685   OTGH_PT_BLK.sCBW.u8CB[4]= 2;                         //stop the device
686 
687   //result=Host20_MSCD_usb_stor_control_thread(&Mass_stor_us1);
688   //if (result==FALSE) return result;
689   //OTGH_PT_BLK.sCBW.u8CB[0]= START_STOP;
690   //OTGH_PT_BLK.sCBW.u8CB[4]= 2;                         //stop the device
691   //printf("lun:%02bx\n",lun);
692   result=Host20_MSCD_usb_stor_control_thread(&Mass_stor_us1);
693   return result;
694 }
695 
696 
697 
698 
699 
700 //=======================================================================================
701 //=======================================================================================
702 //=======================================================================================
703 //=======================================================================================
704 //***************************************************************************************
705 // Function Name:vSCSI_REQUEST_SENSE
706 // Description: Reserved.
707 //              If Device do not support the command-A
708 //              ,Host should issue command "vSCSI_REQUEST_SENSE" to ask "why not support".
709 // Input:
710 // Output:
711 // Status:P-OK
712 //***************************************************************************************
vSCSI_REQUEST_SENSE(U8 lun)713 BOOLEAN vSCSI_REQUEST_SENSE(U8 lun)
714 {
715   INT8U *u8RequestSenseData;
716   //Scsi_Cmnd  srb_data;
717   BOOLEAN result;
718 
719   u8RequestSenseData=pUsbData;
720   Mass_stor_us1.srb = &srb_data;
721   memset(Mass_stor_us1.srb, 0, sizeof(struct scsi_cmnd ));
722 
723   // Build SCSI command.
724   vSCSICmd_REQUEST_SENSE( Mass_stor_us1.srb,u8RequestSenseData);
725 
726   Mass_stor_us1.srb->lun=lun;
727 
728   //call mass storage function to send CBW
729   //and get REQUEST_SENSE Data. Return CSW to check status.
730   result=Host20_MSCD_usb_stor_control_thread(&Mass_stor_us1);
731   return result;
732 
733 
734 
735 }
736 
737 //***************************************************************************************
738 // Function Name:bSCSI_INQUIRY
739 // Description:To ask the device u8DeviceType/u8ProductID/u8ProductVer... information
740 // Input:
741 // Output:
742 // Status:P-OK
743 //***************************************************************************************
744 ///////////////////////////////////////////////////////////////////////////////
745 //		bSCSI_INQUIRY()
746 //		Description:
747 //			1. scsi inquiry command.
748 //		input: none
749 //		output: TRUE or FALSE (BOOLEAN)
750 ///////////////////////////////////////////////////////////////////////////////
751 //INT8U xdata u8InquiryData[DATA_LENGTH_INQUIRY] _at_ Host20_TEMP_DATA;
bSCSI_INQUIRY(U8 lun)752 BOOLEAN bSCSI_INQUIRY(U8 lun)
753 {
754   INT8U u8i, u8j;
755   //Scsi_Cmnd  srb_data;
756   U8 *u8InquiryData;
757   BOOLEAN result;
758 
759   u8InquiryData=pUsbData;
760   //printf("INQUIRY\n");
761   for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++)
762   {
763 
764     Mass_stor_us1.srb =&srb_data;
765 	memset(Mass_stor_us1.srb, 0, sizeof(struct scsi_cmnd ));
766 
767 	//Build SCSI command.
768 	vSCSICmd_INQUIRY( Mass_stor_us1.srb, u8InquiryData);
769     Mass_stor_us1.srb->lun=lun;
770 
771 	//call mass storage function to send CBW
772 	//and get INQUIRY Data. Return CSW to check status.
773 	result=Host20_MSCD_usb_stor_control_thread(&Mass_stor_us1);
774 	if (result==FALSE) continue;
775 
776 	if(Mass_stor_us1.srb->result == SAM_STAT_GOOD)
777 	{
778       //save all INQUIRY data
779 	  Mass_stor_us1.device.u8DeviceType = (u8InquiryData[0] & 0x1F);
780 
781         Mass_stor_us1.Mass_stor_device[lun].bRMB = (u8InquiryData[1] & 0x80) >> 7;
782         //printf("Removable: %d\n", Mass_stor_us1.Mass_stor_device[lun].bRMB);
783 
784 	  for(u8i =0; u8i <8; u8i++)
785 	    Mass_stor_us1.Mass_stor_device[lun].u8VendorID[u8i] = u8InquiryData[u8i+8];
786 	  for(u8i =0; u8i <16; u8i++)
787 		Mass_stor_us1.Mass_stor_device[lun].u8ProductID[u8i] = u8InquiryData[u8i+16];
788 	  for(u8i =0; u8i <4; u8i++)
789 	    Mass_stor_us1.Mass_stor_device[lun].u8ProductVer[u8i] = u8InquiryData[u8i+32];
790 
791 	  if(Mass_stor_us1.device.u8DeviceType != TYPE_DISK)
792 	  {
793 	    DRV_SCSI_DBG(printf("Device type unsuport, it's not a scsi disk%s","\n"));
794 
795 		return FALSE;
796 	  }
797 	  else
798 	  {
799 
800 	    DRV_SCSI_DBG(SCSI_DbgPrint("SCSI INQUIRY : SCSI Device ID <%s>\n",&Mass_stor_us1.Mass_stor_device[lun].u8VendorID));
801 		//SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ID <%s>\n",&Mass_stor_us1.device.u8ProductID);
802 		//SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ver <%s>\n",&Mass_stor_us1.device.u8ProductVer);
803         return TRUE;
804 	  }
805 
806 
807 	}
808 
809   }
810 	return FALSE;
811 }
812 //***************************************************************************************
813 // Function Name:bSCSI_MODE_SENSE
814 // Description:To know the mode of device <1>.Write Protect => Y/N
815 // Input:
816 // Output:
817 // Status:P-OK
818 //***************************************************************************************
819 ///////////////////////////////////////////////////////////////////////////////
820 //		bSCSI_MODE_SENSE()
821 //		Description:
822 //			1. scsi mode sense command.
823 //		input: none
824 //		output: TRUE or FALSE (BOOLEAN)
825 ///////////////////////////////////////////////////////////////////////////////
bSCSI_MODE_SENSE(U8 lun)826 BOOLEAN bSCSI_MODE_SENSE(U8 lun)
827 {
828   INT8U  u8j;
829   INT8U *u8ModeSenseData;
830   BOOLEAN result;
831   //Scsi_Cmnd  srb_data;
832 
833   u8ModeSenseData=pUsbData;
834 
835   Mass_stor_us1.srb = &srb_data;
836 
837   for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++)
838   {
839     memset(Mass_stor_us1.srb, 0, sizeof(struct scsi_cmnd ));
840     //Build SCSI command.
841 	vSCSICmd_MODE_SENSE( Mass_stor_us1.srb,0x3F, u8ModeSenseData);
842     Mass_stor_us1.srb->lun=lun;
843 
844 	//call mass storage function to send CBW
845 	//and get Mode Sense Data. Return CSW to check status.
846 	result=Host20_MSCD_usb_stor_control_thread(&Mass_stor_us1);
847 	if (result==FALSE) return FALSE;
848 
849 	if(Mass_stor_us1.srb->result == SAM_STAT_GOOD)
850 	{
851       //save all Mode Sense(page code=0x3F) data
852 	  //Now we only use u8ModeSenseData[2], this byte save device
853 	  //write protection information
854 	  Mass_stor_us1.Mass_stor_device[lun].bWriteProtect = (u8ModeSenseData[2]==0x80)?
855 												TRUE:FALSE;
856 
857 
858 	  return TRUE;
859 	}
860   }
861   Mass_stor_us1.Mass_stor_device[lun].bWriteProtect=FALSE;      //not support this command
862   return FALSE;
863 }
864 
865 //***************************************************************************************
866 // Function Name:bSCSI_MODE_SENSE_OperCode5A
867 // Description:To know the mode of device <1>.Write Protect => Y/N
868 // Input:
869 // Output:
870 // Status:P-OK
871 //***************************************************************************************
872 ///////////////////////////////////////////////////////////////////////////////
873 //		bSCSI_MODE_SENSE_OperCode5A()
874 //		Description:
875 //			1. scsi mode sense command.
876 //		input: none
877 //		output: TRUE or FALSE (BOOLEAN)
878 ///////////////////////////////////////////////////////////////////////////////
bSCSI_MODE_SENSE_OperCode5A(U8 lun)879 BOOLEAN bSCSI_MODE_SENSE_OperCode5A(U8 lun)
880 {
881   INT8U  u8j;
882   INT8U *u8ModeSenseData;
883   BOOLEAN result;
884   //Scsi_Cmnd  srb_data;
885 
886   u8ModeSenseData=pUsbData;
887 
888   Mass_stor_us1.srb = &srb_data;
889 
890   for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++)
891   {
892     memset(Mass_stor_us1.srb, 0, sizeof(struct scsi_cmnd ));
893     //Build SCSI command.
894 		vSCSICmd_MODE_SENSE_OperCode5A( Mass_stor_us1.srb,0x3F, u8ModeSenseData);
895     Mass_stor_us1.srb->lun=lun;
896 
897 	//call mass storage function to send CBW
898 	//and get Mode Sense Data. Return CSW to check status.
899 	result=Host20_MSCD_usb_stor_control_thread(&Mass_stor_us1);
900 	if (result==FALSE) return FALSE;
901 
902 	if(Mass_stor_us1.srb->result == SAM_STAT_GOOD)
903 	{
904     //save all Mode Sense(page code=0x3F) data
905 	  //Now we only use u8ModeSenseData[2], this byte save device
906 	  //write protection information
907 	  Mass_stor_us1.Mass_stor_device[lun].bWriteProtect = (u8ModeSenseData[3]==0x80)?		//RCC?
908 												TRUE:FALSE;
909 	  return TRUE;
910 	}
911   }
912   Mass_stor_us1.Mass_stor_device[lun].bWriteProtect=FALSE;      //not support this command
913   return FALSE;
914 }
915 
916 //***************************************************************************************
917 // Function Name:bSCSI_READ_CAPACITY
918 // Description:To get the CAPACITY
919 // Input:
920 // Output:
921 // Status:S
922 //***************************************************************************************
923 ///////////////////////////////////////////////////////////////////////////////
924 //		bSCSI_READ_CAPACITY()
925 //		Description:
926 //			1. scsi READ_CAPACITY command.
927 //		input: none
928 //		output: TRUE or FALSE (BOOLEAN)
929 ///////////////////////////////////////////////////////////////////////////////
bSCSI_READ_CAPACITY(U8 lun)930 BOOLEAN bSCSI_READ_CAPACITY(U8 lun)
931 {
932   //INT8U u8j;
933   INT8U *u8ReadCapacityData;
934   BOOLEAN result;
935   //Scsi_Cmnd  srb_data;
936 
937   u8ReadCapacityData=pUsbData;
938   //for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++)
939   {
940     Mass_stor_us1.srb = &srb_data;
941 	memset(Mass_stor_us1.srb, 0, sizeof(struct scsi_cmnd ));
942 
943 	//Build SCSI command.
944 	vSCSICmd_READ_CAPACITY(Mass_stor_us1.srb, u8ReadCapacityData);
945     Mass_stor_us1.srb->lun=lun;
946 
947     //call mass storage function to send CBW
948 	//and get CAPACITY Data. Return CSW to check status.
949 	result=Host20_MSCD_usb_stor_control_thread(&Mass_stor_us1);
950 	if (result==FALSE) return result;
951 
952 	if(Mass_stor_us1.srb->result == SAM_STAT_GOOD)
953 	{
954 	  //save all CAPACITY data
955 	  Mass_stor_us1.Mass_stor_device[lun].u32BlockTotalNum = ((INT32U)u8ReadCapacityData[0] << 24) |
956 										   ((INT32U)u8ReadCapacityData[1] << 16) |
957 										   ((INT32U)u8ReadCapacityData[2] << 8) |
958 										   ((INT32U)u8ReadCapacityData[3] ) ;
959 
960 	  Mass_stor_us1.Mass_stor_device[lun].u32BlockSize = ((INT32U)u8ReadCapacityData[4] << 24) |
961 									   ((INT32U)u8ReadCapacityData[5] << 16) |
962 									   ((INT32U)u8ReadCapacityData[6] << 8) |
963 									   ((INT32U)u8ReadCapacityData[7] ) ;
964      //if ( Mass_stor_us1.Mass_stor_device[lun].u32BlockSize > 1024)
965      //{
966      //  printf("Block size over 1024, is %X\n",Mass_stor_us1.Mass_stor_device[lun].u32BlockSize);
967      //  while(1);
968      //}
969 
970 	 DRV_SCSI_DBG(SCSI_DbgPrint("SCSI CAPACITY : SCSI Device total block <0x%x%x>\n",
971 	                           (INT16U)(Mass_stor_us1.Mass_stor_device[lun].u32BlockTotalNum >> 16),
972 					           (INT16U)Mass_stor_us1.Mass_stor_device[lun].u32BlockTotalNum));
973 	 DRV_SCSI_DBG(SCSI_DbgPrint("SCSI CAPACITY : SCSI Product block size <0x%x bytes>\n",(INT16U)Mass_stor_us1.Mass_stor_device[lun].u32BlockSize));
974 
975 	 return TRUE;
976    }
977      else
978      {
979         vSCSI_REQUEST_SENSE(lun);
980 #if 0
981         printf("ReqSense: ");
982         for (ii=0; ii<18; ii++)
983         {
984             printf(" %bx", pUsbData[ii]);
985         }
986         printf("\n");
987 #endif
988         return FALSE;
989      }
990  }
991  return FALSE;
992 
993 }
994 
bSCSI_READ_FORMAT_CAPACITY(U8 lun)995 BOOLEAN bSCSI_READ_FORMAT_CAPACITY(U8 lun)
996 {
997   INT8U u8j;
998   INT8U *u8ReadCapacityData;
999   BOOLEAN result;
1000   //Scsi_Cmnd  srb_data;
1001 
1002   u8ReadCapacityData=pUsbData;
1003   for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++)
1004   {
1005     Mass_stor_us1.srb = &srb_data;
1006 	memset(Mass_stor_us1.srb, 0, sizeof(struct scsi_cmnd ));
1007 
1008 	//Build SCSI command.
1009 	vSCSICmd_READ_FORMAT_CAPACITY(Mass_stor_us1.srb, u8ReadCapacityData);
1010     Mass_stor_us1.srb->lun=lun;
1011 
1012     //call mass storage function to send CBW
1013 	//and get CAPACITY Data. Return CSW to check status.
1014 	result=Host20_MSCD_usb_stor_control_thread(&Mass_stor_us1);
1015 	if (result==FALSE) return result;
1016 
1017 	if(Mass_stor_us1.srb->result == SAM_STAT_GOOD)
1018 	{
1019 	  //save all CAPACITY data
1020 	  Mass_stor_us1.Mass_stor_device[lun].u32BlockTotalNum = ((INT32U)u8ReadCapacityData[4] << 24) |
1021 										   ((INT32U)u8ReadCapacityData[5] << 16) |
1022 										   ((INT32U)u8ReadCapacityData[6] << 8) |
1023 										   ((INT32U)u8ReadCapacityData[7] ) ;
1024 
1025 	  Mass_stor_us1.Mass_stor_device[lun].u32BlockSize = ((INT32U)u8ReadCapacityData[9] << 16) |
1026 									   ((INT32U)u8ReadCapacityData[10] << 8) |
1027 									   ((INT32U)u8ReadCapacityData[11] ) ;
1028      //if ( Mass_stor_us1.Mass_stor_device[lun].u32BlockSize > 1024)
1029      //{
1030      //  printf("Block size over 1024, is %X\n",Mass_stor_us1.Mass_stor_device[lun].u32BlockSize);
1031      //  while(1);
1032      //}
1033 
1034 	 DRV_SCSI_DBG(SCSI_DbgPrint("SCSI CAPACITY : SCSI Device total block <0x%x%x>\n",
1035 	                           (INT16U)(Mass_stor_us1.Mass_stor_device[lun].u32BlockTotalNum >> 16),
1036 					           (INT16U)Mass_stor_us1.Mass_stor_device[lun].u32BlockTotalNum));
1037 	 DRV_SCSI_DBG(SCSI_DbgPrint("SCSI CAPACITY : SCSI Product block size <0x%x bytes>\n",(INT16U)Mass_stor_us1.Mass_stor_device[lun].u32BlockSize));
1038 
1039 	 return TRUE;
1040    }
1041  }
1042  return FALSE;
1043 
1044 }
1045 
1046 extern void OTGH_PT_Bulk_Init(void);
1047 //***************************************************************************************
1048 // Function Name:bSCSI_TEST_UNIT_READY
1049 // Description: To know that "device is ready ?"
1050 // Input:
1051 // Output:
1052 // Status:
1053 //***************************************************************************************
1054 ///////////////////////////////////////////////////////////////////////////////
1055 //		bSCSI_TEST_UNIT_READY()
1056 //		Description:
1057 //			1. scsi TEST_UNIT_READY command.
1058 //		input: none
1059 //		output: TRUE or FALSE (BOOLEAN)
1060 ///////////////////////////////////////////////////////////////////////////////
bSCSI_TEST_UNIT_READY(U8 lun)1061 BOOLEAN bSCSI_TEST_UNIT_READY(U8 lun)
1062 {
1063   INT8U u8j;
1064   BOOLEAN result;
1065   #ifdef ATV_SERISE_USE
1066   U32 i;
1067   #endif
1068   //Scsi_Cmnd  srb_data;
1069   //printf("TUR\n");
1070 
1071   for(u8j =0; u8j< TestUnitReady_Fail_Retry ;u8j++)
1072   {
1073     //printf("connect status:%02bx\n",mwHost20_PORTSC_ConnectStatus_Rd());
1074 	if (mwHost20_PORTSC_ConnectStatus_Rd()==0)
1075       return FALSE;               //device is not connected
1076 
1077 	Mass_stor_us1.srb = &srb_data;
1078 	memset((U8 xdata *)Mass_stor_us1.srb, 0, sizeof(struct scsi_cmnd ));
1079 
1080 	// Build SCSI command.
1081 	vSCSICmd_Prepare(Mass_stor_us1.srb,TEST_UNIT_READY);
1082 	//vSCSICmd_TEST_UNIT_READY(Mass_stor_us1.srb);
1083     Mass_stor_us1.srb->lun=lun;
1084     //printf("Mass_stor_us1.srb:%02bx\n",Mass_stor_us1.srb->request_bufflen);
1085 	//call mass storage function to send CBW
1086 	//and get CAPACITY Data. Return CSW to check status.
1087 
1088 	result=Host20_MSCD_usb_stor_control_thread(&Mass_stor_us1);
1089     //printf("result:%02bx\n",result);
1090 #if 1
1091         if (result == FALSE)
1092         {
1093             if (gUsbStatus == USB_TIMEOUT)
1094             {
1095                 DRV_SCSI_DBG(printf("resend TUR\n"));
1096                 if ( MDrv_UsbHost_Init() && (flib_Host20_Enumerate(1,3)!=0) )
1097                 {
1098                     OTGH_PT_Bulk_Init();
1099                     continue;
1100                 }
1101             }
1102             else
1103                 return result;
1104         }
1105 #else
1106         if (result==FALSE)
1107         {
1108             return result;
1109         }
1110 #endif
1111 	if(Mass_stor_us1.srb->result == SAM_STAT_GOOD)
1112 	{
1113 	  Mass_stor_us1.Mass_stor_device[lun].bDeviceReady = TRUE;
1114       //SCSI_DbgPrint("SCSI TEST UNIT READY : Succeed\n",u8Drive);
1115 
1116 	  return TRUE;
1117 	}
1118 	else
1119 	{
1120        #ifndef ATV_SERISE_USE
1121          MsOS_DelayTask(10);
1122        #else
1123          for(i=0;i<(0x100);i++);
1124        #endif
1125 
1126 	  result=vSCSI_REQUEST_SENSE(lun);
1127       if ((pUsbData[12]==0x3a)&&(pUsbData[13]==0)) return FALSE;  //no media
1128 	  if (result==FALSE) return result;
1129 	}
1130     #ifndef ATV_SERISE_USE
1131 	MsOS_DelayTask(10);
1132 	#else
1133 	for(i=0;i<0x100;i++);
1134 	#endif
1135   }
1136 	//SCSI_DbgPrint("SCSI TEST UNIT READY : Failed%s","\n");
1137   return FALSE;
1138 }
1139 extern BOOLEAN  MDrv_Usb_Device_Enum(void);
1140 #ifdef ATV_SERISE_USE
1141 extern void EnableINT(void);
1142 #endif
1143 
bSCSI_TEST_UNIT_READY2(U8 lun)1144 BOOLEAN bSCSI_TEST_UNIT_READY2(U8 lun)
1145 {
1146   INT8U u8j;
1147   BOOLEAN result;
1148   U8  RetryCnt=0;
1149 
1150   #ifdef ATV_SERISE_USE
1151   U32 i;
1152   #endif
1153   //Scsi_Cmnd  srb_data;
1154   //printf("TUR\n");
1155 
1156   for(u8j =0; u8j< TestUnitReady_Fail_Retry ;u8j++)
1157   {
1158     //printf("connect status:%02bx\n",mwHost20_PORTSC_ConnectStatus_Rd());
1159 	if (mwHost20_PORTSC_ConnectStatus_Rd()==0)
1160       return FALSE;               //device is not connected
1161 
1162 	Mass_stor_us1.srb = &srb_data;
1163 	memset((U8 xdata *)Mass_stor_us1.srb, 0, sizeof(struct scsi_cmnd ));
1164 
1165 	// Build SCSI command.
1166 	vSCSICmd_Prepare(Mass_stor_us1.srb,TEST_UNIT_READY);
1167 	//vSCSICmd_TEST_UNIT_READY(Mass_stor_us1.srb);
1168     Mass_stor_us1.srb->lun=lun;
1169     //printf("Mass_stor_us1.srb:%02bx\n",Mass_stor_us1.srb->request_bufflen);
1170 	//call mass storage function to send CBW
1171 	//and get CAPACITY Data. Return CSW to check status.
1172 
1173 	result=Host20_MSCD_usb_stor_control_thread(&Mass_stor_us1);
1174     //printf("result:%02bx\n",result);
1175 
1176     if (result==FALSE)
1177     {
1178       RetryCnt++;
1179       if (gUsbStatus==USB_TIMEOUT)
1180       {
1181         if (RetryCnt > 3) return FALSE;
1182         if ((RetryCnt==2)&&(mwOTG20_Control_HOST_SPD_TYP_Rd()==2) )           //make sure it is hi speed
1183         {
1184           DRV_SCSI_DBG( printf("Force FS\n"));
1185           UHC_ORXBYTE(0x40,0x80);//force enter FSmode
1186         }
1187         #ifndef ATV_SERISE_USE
1188         msAPI_Timer_ResetWDT();
1189         #else
1190           #ifdef Enable_Close_INT
1191           //XBYTE[0x2B00]&=0xFD;
1192           EnableINT();
1193           #endif
1194         #endif
1195         #ifdef Enable_Low_Temperature_Patch
1196 	    if(gSpeed==0)
1197 	    {
1198 	      //printf("\r\n CDR toggle!!",0);
1199               UTMI_SETXBYTE(0x0a,UTMI_READXBYTE(0x0a)^0x10);    //invert CDR_CLOCK
1200               UTMI_ORXBYTE(0x06,0x03);  //reset UTMI
1201               UTMI_ANDXBYTE(0x06,0xfc);
1202 
1203 	    }
1204 		#endif
1205        // MDrv_Usb_Device_Enum();
1206         if (MDrv_Usb_Device_Enum()==FALSE) return FALSE;
1207 
1208         continue;
1209       }
1210       else
1211         return FALSE;
1212     }
1213 
1214 	if(Mass_stor_us1.srb->result == SAM_STAT_GOOD)
1215 	{
1216 	  Mass_stor_us1.Mass_stor_device[lun].bDeviceReady = TRUE;
1217       //SCSI_DbgPrint("SCSI TEST UNIT READY : Succeed\n",u8Drive);
1218 
1219 	  return TRUE;
1220 	}
1221 	else
1222 	{
1223 	#ifndef ATV_SERISE_USE
1224          MsOS_DelayTask(10);
1225 	#else
1226          for(i=0;i<(0x100);i++);
1227        #endif
1228 
1229 	  result=vSCSI_REQUEST_SENSE(lun);
1230       if ((pUsbData[12]==0x3a)&&(pUsbData[13]==0)) return FALSE;  //no media
1231       if ((pUsbData[12]==0x28)&&(pUsbData[13]==0)) return FALSE;  //media change
1232 	  if (result==FALSE) return result;
1233 	}
1234     #ifndef ATV_SERISE_USE
1235 	MsOS_DelayTask(10);
1236 	#else
1237 	for(i=0;i<0x100;i++);
1238 	#endif
1239   }
1240 	//SCSI_DbgPrint("SCSI TEST UNIT READY : Failed%s","\n");
1241   return FALSE;
1242 }
1243 //***************************************************************************************
1244 // Function Name:bSCSI_Initial
1245 // Description:
1246 // Input:
1247 // Output:
1248 // Status:P-OK
1249 //***************************************************************************************
1250 U8 ValidLunNum;
bSCSI_Initial(void)1251 BOOLEAN bSCSI_Initial(void)
1252 {
1253   //INT8U i=0;
1254   //iCardSuddenlyRemove = FALSE;
1255   //iCardReplace = FALSE;
1256   BOOLEAN		bFoundValidDev = FALSE;
1257   struct LUN_Device* LunDevice = Mass_stor_us1.Mass_stor_device;
1258   U8		LunIdx;
1259 
1260  ValidLunNum=0;
1261  for (	LunIdx=0; LunIdx<=Mass_stor_us1.max_lun; LunIdx++)
1262   {
1263     LunDevice[LunIdx].bDeviceValid=FALSE;
1264 	if (bSCSI_INQUIRY(LunIdx))
1265        {
1266             LunDevice[LunIdx].bDeviceValid=TRUE;
1267             ValidLunNum++;
1268        }
1269 	//break;
1270   }
1271  DRV_SCSI_DBG(printf("ValidLunNum:%02bx\n",ValidLunNum));
1272     // For some usb harddrive without enough power, may meet following case.
1273     if (!ValidLunNum)
1274     {
1275     	  if (mwHost20_PORTSC_ConnectChange_Rd()==0)
1276             MDrv_SetUsbDeviceStatus(BAD_DEVICE);
1277         return bFoundValidDev;
1278     }
1279 
1280   // Sometime device is failed to initial at first time, but success at last.
1281   // It set the device status as BAD_DEVICE at first time when it failed.
1282   // We need to set correct value to device status when successed.
1283   if (gSpeed==2)
1284   {
1285       MDrv_SetUsbDeviceStatus(USB20_DEVICE);
1286   }
1287   else
1288   {
1289       MDrv_SetUsbDeviceStatus(USB11_DEVICE);
1290   }
1291   #ifdef ATV_SERISE_USE
1292     #ifdef Enable_Close_INT
1293   EA=0;
1294   #endif
1295   #endif
1296   for (	LunIdx=0; LunIdx<=Mass_stor_us1.max_lun; LunIdx++)
1297   {
1298     LunDevice[LunIdx].bDeviceReady = FALSE;
1299 	if (!bInit_USB_LUN(LunIdx))
1300 	  continue;
1301 	LunDevice[LunIdx].bDeviceReady = TRUE;
1302     bFoundValidDev = TRUE;
1303 
1304   }
1305   #ifdef ATV_SERISE_USE
1306     #ifdef Enable_Close_INT
1307   EA=1;
1308   #endif
1309   #endif
1310   return bFoundValidDev;
1311 
1312 }
GetValidLun(void)1313 void GetValidLun(void)
1314 {
1315   U8 LunIdx;
1316   struct LUN_Device* LunDevice = Mass_stor_us1.Mass_stor_device;
1317 
1318   if (LunDevice == NULL)
1319   {
1320       DRV_SCSI_DBG(printf(" LUN structure not initialized!!\n"));
1321       return;
1322   }
1323 
1324   if ( (Mass_stor_us1.max_lun == 0) && (!LunDevice[0].bRMB) && LunDevice[0].bDeviceReady)
1325   {
1326         //20120817, Don't do TUR on this special USB HDD.
1327         //It returns NOT READY after 30 minutes idle.
1328               return;
1329           }
1330 
1331   for (LunIdx=0; LunIdx<=Mass_stor_us1.max_lun; LunIdx++)
1332   {
1333     if (LunDevice[LunIdx].bDeviceValid)
1334     {
1335       if(!bSCSI_TEST_UNIT_READY2(LunIdx))
1336       {
1337             LunDevice[LunIdx].bDeviceReady=FALSE;
1338             LunDevice[LunIdx].u32BlockSize = 0; // 20111110: resolve lun capacity zero if not the first lun
1339             LunDevice[LunIdx].u32BlockTotalNum = 0;
1340       }
1341       else
1342       {
1343               LunDevice[LunIdx].bDeviceReady = TRUE;
1344               if (LunDevice[LunIdx].u32BlockSize == 0) // 20111110: resolve lun capacity zero if not the first lun
1345               {
1346                   if(!bSCSI_READ_CAPACITY(LunIdx))
1347                   {
1348                     if (!bSCSI_READ_FORMAT_CAPACITY(LunIdx))
1349                     {
1350                         DRV_SCSI_DBG(SCSI_DbgPrint("Read CAPACITY failed.%s","\n"));
1351                     }
1352                   }
1353               }
1354         }
1355     }
1356     else
1357       LunDevice[LunIdx].bDeviceReady=FALSE;                   //not a valid device, so always not ready
1358   }
1359 }
bInit_USB_LUN(U8 Lun)1360 BOOLEAN bInit_USB_LUN(U8 Lun)
1361 {
1362   U16   uVID, uPID;
1363   U8     ii;
1364   BOOLEAN bIsForceMS1A = FALSE;
1365 
1366   MDrv_USBGetVIDPID(&uVID, &uPID);
1367   if ( (uVID == 0xFCA) && (uPID == 0x8004) ) //20130301, for blackberry phone
1368   {
1369       if (!bSCSI_INQUIRY(Lun))
1370       {
1371         DRV_SCSI_DBG(SCSI_DbgPrint("Scsi inquiry failed (Lun=%d).\n",u8Drive));
1372     	return FALSE;
1373       }
1374   }
1375 
1376   if(!bSCSI_TEST_UNIT_READY(Lun))
1377   {
1378     DRV_SCSI_DBG(SCSI_DbgPrint("Scsi Device not ready (Lun=%d).\n",Lun));
1379 	return FALSE;
1380   }
1381   //bSCSI_INQUIRY();
1382   if (!bSCSI_INQUIRY(Lun))
1383   {
1384     DRV_SCSI_DBG(SCSI_DbgPrint("Scsi inquiry failed (Lun=%d).\n",u8Drive));
1385 	return FALSE;
1386   }
1387   if(!bSCSI_READ_CAPACITY(Lun))
1388   {
1389     if (!bSCSI_READ_FORMAT_CAPACITY(Lun))
1390     {
1391         DRV_SCSI_DBG(SCSI_DbgPrint("Read CAPACITY failed.%s","\n"));
1392         return FALSE;
1393     }
1394   }
1395 
1396 #ifdef ENABLE_CBI_HOST
1397     if ((sAttachDevice.saCD[0].sInterface[0].bInterfaceProtocol==0x00)||(sAttachDevice.saCD[0].sInterface[0].bInterfaceProtocol==0x01))
1398     {
1399         //do nothing
1400     }
1401     else
1402 #endif
1403     {
1404     MDrv_USBGetVIDPID(&uVID, &uPID);
1405     DRV_SCSI_DBG(printf("VID: %x, PID: %x\n", uVID, uPID));
1406     ii = 0;
1407     while ( (gForceModeSense1A[ii].VID != 0) && (gForceModeSense1A[ii].PID != 0) )
1408     {
1409         if ( (uVID == gForceModeSense1A[ii].VID) && (uPID == gForceModeSense1A[ii].PID) )
1410         {
1411             DRV_SCSI_DBG(printf("Find a Force Mode Sense 1A device\n"));
1412             bIsForceMS1A = TRUE;
1413         }
1414 
1415         ii++;
1416         if (ii >= (sizeof(gForceModeSense1A) / sizeof(struct stForceModeSense1A)))
1417           break;
1418     }
1419 
1420     if (bIsForceMS1A)
1421         bSCSI_MODE_SENSE(Lun);
1422     else
1423         bSCSI_MODE_SENSE_OperCode5A(Lun);
1424 
1425     }
1426 
1427   //if (!bSCSI_MODE_SENSE(Lun))
1428   //{
1429   //  SCSI_DbgPrint("Mode sense failed!\n");
1430   //  return FALSE;
1431   //}
1432 
1433   if(!bSCSI_TEST_UNIT_READY(Lun))
1434   {
1435     DRV_SCSI_DBG(SCSI_DbgPrint("Scsi Device not ready (Lun=%d).\n",u8Drive));
1436 	return FALSE;
1437   }
1438   return TRUE;
1439 
1440 }
1441 
1442 
1443 //***************************************************************************************
1444 // Function Name:
1445 // Description:
1446 // Input:
1447 // Output:
1448 // Status:
1449 //***************************************************************************************
1450 
1451 
1452 
bSCSI_Read_Write10(BOOLEAN DoWrite,U8 lun,INT32U u32BlockAddr,INT32U u32BlockNum,U32 u8Buffer)1453 BOOLEAN bSCSI_Read_Write10(BOOLEAN DoWrite, U8 lun,  INT32U u32BlockAddr, INT32U u32BlockNum,U32 u8Buffer)
1454 {
1455 
1456   //Scsi_Cmnd  srb_data;
1457   BOOLEAN result;
1458   Mass_stor_us1.srb = &srb_data;
1459   //memset(Mass_stor_us1.srb, 0, sizeof(struct scsi_cmnd ));
1460   //printf("read sector:%lx, sz:%lx\n",u32BlockAddr,u32BlockNum);
1461 
1462   if (DoWrite)
1463   {
1464     if(Mass_stor_us1.Mass_stor_device[lun].bWriteProtect)
1465     {
1466 	  DRV_SCSI_DBG(printf("This device is write protect now\n"));
1467 	  return FALSE;
1468 	}
1469   }
1470 
1471   //Build SCSI command.
1472   vSCSICmd_READ_WRITE_10(DoWrite,&Mass_stor_us1, Mass_stor_us1.srb, lun,
1473 								u32BlockAddr, (INT16U)u32BlockNum, u8Buffer);
1474 
1475 
1476   //call mass storage function to send scsi command
1477   result=Host20_MSCD_usb_stor_control_thread(&Mass_stor_us1);
1478   if (result==FALSE) return result;
1479 
1480   if(Mass_stor_us1.srb->result != SAM_STAT_GOOD)
1481   {
1482     DRV_SCSI_DBG(SCSI_DbgPrint("Scsi ReadWrite_10 command failed.%s","\n"));
1483 
1484 	return FALSE;
1485   }
1486 
1487 
1488   //printf("#");
1489   return TRUE;
1490 
1491 
1492 
1493 }
1494 
1495 #endif //#if defined(MSOS_TYPE_NOS)
1496 
1497 
1498 
1499