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