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_4.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_4.h"
107 #include "../drvHost200_4.h"
108 #include "../drvscsi_4.h"
109 #include "../drvMassStorage_4.h"
110 #ifdef ATV_SERISE_USE
111 #include "Board.h"
112 #include "common.h"
113 #include "uart.h"
114 #endif
115 #include "../drvUsbMain_4.h"
116 #include "../../include/_drvUSB.h"
117
118 #include "MsCommon.h"
119 #include "MsIRQ.h"
120 #include "MsOS.h"
121
122 extern void msAPI_Timer_ResetWDT(void);
123
124 #define DRV_SCSI_DBG(x) // x;
125
126 //struct us_data xdata *Mass_stor_us;
127 #define MAX_LUN_SUPPORT 5
128
129 struct us_data Mass_stor_us1_port4;
130 #if 1
131 struct LUN_Device Mass_stor_device_port4[MAX_LUN_SUPPORT];
132 #else
133 struct LUN_Device Mass_stor_device_1_port4; //support 4 LUN
134 struct LUN_Device Mass_stor_device_2_port4;
135 struct LUN_Device Mass_stor_device_3_port4;
136 struct LUN_Device Mass_stor_device_4_port4;
137 struct LUN_Device Mass_stor_device_5_port4;
138 #endif
139
140 extern UINT8 pUsbData_Port4[1024];
141 Scsi_Cmnd srb_data_port4;
142
143 UINT8 u8Drive_port4 = 0;
144 extern U8 gUsbStatus_Port4;
145 extern U8 gSpeed_Port4;
146
147 struct stForceModeSense1A
148 {
149 U16 VID;
150 U16 PID;
151 } stForceModeSense1A;
152
153 struct stForceModeSense1A gForceModeSense1A_Port4[] =
154 {
155 {0x0DD8, 0x1448},
156 {0x1AA6, 0x0201},
157 {0x0DD8, 0x1414},
158 {0x0DD8, 0x1400},
159 {0x0DD8, 0xE203},
160 {0x8644, 0x800a}, //alan.yu add on 2010.08.13 (�Ϲ� ����)
161 {0x0DD8, 0xD202}, //alan.yu add on 2010.08.16 (�ʿ�Netac)
162 {0x18A5,0x302}, //alan.yu add on 2011.08.01
163 {0, 0}
164 };
165
166 extern void MDrv_USBGetVIDPID_Port4(U16 *pVID, U16 *pPID);
167
168 //BOOLEAN gDeviceFatalError=FALSE;
Init_Mass_Storage_Structure_Port4(void)169 void Init_Mass_Storage_Structure_Port4(void)
170 {
171 U16 uVID, uPID;
172
173 //Mass_stor_us=&Mass_stor_us1;
174 Mass_stor_us1_port4.Mass_stor_device=&Mass_stor_device_port4[0];
175 #ifdef ENABLE_CBI_HOST
176 if ( (psAttachDevice_Port4->saCD[0].sInterface[0].bInterfaceProtocol==0x00)||
177 (psAttachDevice_Port4->saCD[0].sInterface[0].bInterfaceProtocol==0x01) )
178 Mass_stor_us1_port4.max_lun=0;
179 else
180 #endif
181 {
182 MDrv_USBGetVIDPID_Port4(&uVID, &uPID);
183 //printf("MAXLUN VID: %x, PID: %x\n", uVID, uPID);
184 if ( ((uVID == 0x8564) && (uPID == 0x1000)) ||
185 ((uVID == 0xFCA) && (uPID == 0x8004)) ) //20130301, for blackberry phone
186 Mass_stor_us1_port4.max_lun = 0;
187 else
188 Mass_stor_us1_port4.max_lun= Host20_MSCD_GetMaxLUN_Port4();
189 }
190 //printf("Max Lun:%02bx\n",Mass_stor_us1.max_lun);
191 if (Mass_stor_us1_port4.max_lun > (MAX_LUN_SUPPORT-1) )
192 Mass_stor_us1_port4.max_lun = MAX_LUN_SUPPORT-1;
193 }
194 //***************************************************************************************
195 // Function Name: vSCSICmd_READ_10
196 // Description:
197 // Input:
198 // Output:
199 // Status:S
200 //***************************************************************************************
vSCSICmd_READ_WRITE_10_Port4(BOOLEAN DoWrite,struct us_data * us,Scsi_Cmnd * srb,INT8U u8LunNum,INT32U u32BlockAddr,INT16U u16BlockNum,U32 u8Buffer)201 void vSCSICmd_READ_WRITE_10_Port4(BOOLEAN DoWrite,struct us_data *us, Scsi_Cmnd *srb, INT8U u8LunNum,
202 INT32U u32BlockAddr, INT16U u16BlockNum, U32 u8Buffer)
203 {
204
205
206 /* set the command and the LUN */
207 #if 0
208 memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
209 srb->cmnd[0] = READ_10;
210
211 srb->cmnd[2] = (INT8U)(u32BlockAddr >> 24);
212 srb->cmnd[3] = (INT8U)(u32BlockAddr >> 16);
213 srb->cmnd[4] = (INT8U)(u32BlockAddr >> 8);
214 srb->cmnd[5] = (INT8U)(u32BlockAddr);
215
216 srb->cmnd[7] = (INT8U)(u16BlockNum >> 8);
217 srb->cmnd[8] = (INT8U)(u16BlockNum );
218 #endif
219 if (DoWrite)
220 pOTGH_PT_BLK_Port4->sCBW.u8CB[0]=WRITE_10;
221 else
222 pOTGH_PT_BLK_Port4->sCBW.u8CB[0]=READ_10;
223 pOTGH_PT_BLK_Port4->sCBW.u8CB[1]=0;
224
225 pOTGH_PT_BLK_Port4->sCBW.u8CB[2]= (INT8U)(u32BlockAddr >> 24);
226 pOTGH_PT_BLK_Port4->sCBW.u8CB[3]= (INT8U)(u32BlockAddr >> 16);
227 pOTGH_PT_BLK_Port4->sCBW.u8CB[4]= (INT8U)(u32BlockAddr >> 8);
228 pOTGH_PT_BLK_Port4->sCBW.u8CB[5]= (INT8U)(u32BlockAddr);
229
230 pOTGH_PT_BLK_Port4->sCBW.u8CB[7] = (INT8U)(u16BlockNum >> 8);
231 pOTGH_PT_BLK_Port4->sCBW.u8CB[8] = (INT8U)(u16BlockNum );
232
233
234 /* FIXME: we must do the protocol translation here */
235 /*
236 if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
237 srb->cmd_len = 6;
238 else
239 srb->cmd_len = 12;
240 */
241 srb->cmd_len = 10;
242
243 /* set the transfer direction */
244 if (DoWrite)
245 srb->sc_data_direction = SCSI_DATA_WRITE;
246 else
247 srb->sc_data_direction = SCSI_DATA_READ;
248
249 /* use the new buffer we have */
250 srb->request_buffer= u8Buffer;
251
252 /* set the buffer length for transfer */
253 srb->request_bufflen = (us->Mass_stor_device[u8LunNum].u32BlockSize)*u16BlockNum;
254
255 /* set up for no scatter-gather use */
256 //srb->use_sg = 0;
257
258 /* change the serial number -- toggle the high bit*/
259 //srb->serial_number ^= 0x80000000;
260
261 /* set Lun number*/
262 srb->lun= u8LunNum;
263
264 //srb->scsi_done = vScsi_SendCmd_Done;
265
266
267
268 }
269 #if 0
270 //***************************************************************************************
271 // Function Name:
272 // Description:
273 // Input:
274 // Output:
275 // Status:S
276 //***************************************************************************************
277 void vSCSICmd_WRITE_10(struct us_data *us, Scsi_Cmnd *srb, INT8U u8LunNum,
278 INT32U u32BlockAddr, INT16U u16BlockNum, U32 u8Buffer)
279 {
280
281
282 /* set the command and the LUN */
283 #if 0
284 memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
285 srb->cmnd[0] = WRITE_10;
286
287 srb->cmnd[2] = (INT8U)(u32BlockAddr >> 24);
288 srb->cmnd[3] = (INT8U)(u32BlockAddr >> 16);
289 srb->cmnd[4] = (INT8U)(u32BlockAddr >> 8);
290 srb->cmnd[5] = (INT8U)(u32BlockAddr);
291
292 srb->cmnd[7] = (INT8U)(u16BlockNum >> 8);
293 srb->cmnd[8] = (INT8U)(u16BlockNum );
294 #endif
295 pOTGH_PT_BLK_Port4->sCBW.u8CB[0]=WRITE_10;
296 pOTGH_PT_BLK_Port4->sCBW.u8CB[1]=0;
297
298 pOTGH_PT_BLK_Port4->sCBW.u8CB[2]= (INT8U)(u32BlockAddr >> 24);
299 pOTGH_PT_BLK_Port4->sCBW.u8CB[3]= (INT8U)(u32BlockAddr >> 16);
300 pOTGH_PT_BLK_Port4->sCBW.u8CB[4]= (INT8U)(u32BlockAddr >> 8);
301 pOTGH_PT_BLK_Port4->sCBW.u8CB[5]= (INT8U)(u32BlockAddr);
302
303 pOTGH_PT_BLK_Port4->sCBW.u8CB[7] = (INT8U)(u16BlockNum >> 8);
304 pOTGH_PT_BLK_Port4->sCBW.u8CB[8] = (INT8U)(u16BlockNum );
305
306 /* FIXME: we must do the protocol translation here */
307 /*
308 if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
309 srb->cmd_len = 6;
310 else
311 srb->cmd_len = 12;
312 */
313 srb->cmd_len = CB_LENGTH_WRITE_10;
314
315 /* set the transfer direction */
316 srb->sc_data_direction = SCSI_DATA_WRITE;
317
318 /* use the new buffer we have */
319 srb->phy_buf_adr=u8Buffer;
320 srb->buffer_type=BUFFER_PHY;
321
322 /* set the buffer length for transfer */
323 srb->request_bufflen = us->Mass_stor_device[u8LunNum].u32BlockSize*u16BlockNum;
324
325 /* set up for no scatter-gather use */
326 //srb->use_sg = 0;
327
328 /* change the serial number -- toggle the high bit*/
329 //srb->serial_number ^= 0x80000000;
330
331 /* set Lun number*/
332 srb->lun= u8LunNum;
333
334 //srb->scsi_done = vScsi_SendCmd_Done;
335
336
337 }
338 #endif
339 //***************************************************************************************
340 // Function Name:
341 // Description:
342 // Input:
343 // Output:
344 // Status:S
345 //***************************************************************************************
vSCSICmd_INQUIRY_Port4(Scsi_Cmnd * srb,INT8U * u8Buffer)346 void vSCSICmd_INQUIRY_Port4( Scsi_Cmnd *srb, INT8U *u8Buffer)
347 {
348
349
350 /* set the command and the LUN */
351 //memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
352 //srb->cmnd[0] = INQUIRY;
353 //srb->cmnd[4] = DATA_LENGTH_INQUIRY;
354 memset(&pOTGH_PT_BLK_Port4->sCBW.u8CB[0], 0, 16);
355 pOTGH_PT_BLK_Port4->sCBW.u8CB[0]= INQUIRY;
356 pOTGH_PT_BLK_Port4->sCBW.u8CB[4]= DATA_LENGTH_INQUIRY;
357
358 /* FIXME: we must do the protocol translation here */
359 /*
360 if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
361 srb->cmd_len = 6;
362 else
363 srb->cmd_len = 12;
364 */
365 srb->cmd_len = CB_LENGTH_INQUIRY;
366
367 /* set the transfer direction */
368 srb->sc_data_direction = SCSI_DATA_READ;
369
370 /* use the new buffer we have */
371 srb->request_buffer = (U32)u8Buffer;
372
373 /* set the buffer length for transfer */
374 srb->request_bufflen = DATA_LENGTH_INQUIRY;
375
376 /* set up for no scatter-gather use */
377 //srb->use_sg = 0;
378
379 /* change the serial number -- toggle the high bit*/
380 //srb->serial_number ^= 0x80000000;
381
382 /* set Lun number*/
383 //srb->lun= u8Drive;//0;
384
385 //srb->scsi_done = vScsi_SendCmd_Done;
386
387
388 }
389 //***************************************************************************************
390 // Function Name:
391 // Description:
392 // Input:
393 // Output:
394 // Status:S
395 //***************************************************************************************
vSCSICmd_READ_CAPACITY_Port4(Scsi_Cmnd * srb,INT8U * u8Buffer)396 void vSCSICmd_READ_CAPACITY_Port4( Scsi_Cmnd *srb, INT8U *u8Buffer)
397 {
398
399 /* set the command and the LUN */
400 //memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
401 //srb->cmnd[0] = READ_CAPACITY;
402 memset(&pOTGH_PT_BLK_Port4->sCBW.u8CB[0], 0, 16);
403 pOTGH_PT_BLK_Port4->sCBW.u8CB[0]= READ_CAPACITY;
404
405 /* FIXME: we must do the protocol translation here */
406 /*
407 if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
408 srb->cmd_len = 6;
409 else
410 srb->cmd_len = 12;
411 */
412 srb->cmd_len = CB_LENGTH_READ_CAPACITY;
413
414 /* set the transfer direction */
415 srb->sc_data_direction = SCSI_DATA_READ;
416
417 /* use the new buffer we have */
418 srb->request_buffer = (U32)u8Buffer;
419
420 /* set the buffer length for transfer */
421 srb->request_bufflen = DATA_LENGTH_READ_CAPACITY;
422
423 /* set up for no scatter-gather use */
424 //srb->use_sg = 0;
425
426 /* change the serial number -- toggle the high bit*/
427 //srb->serial_number ^= 0x80000000;
428
429 /* set Lun number*/
430 //srb->lun= u8Drive;
431
432 //srb->scsi_done = vScsi_SendCmd_Done;
433
434
435 }
436
vSCSICmd_READ_FORMAT_CAPACITY_Port4(Scsi_Cmnd * srb,INT8U * u8Buffer)437 void vSCSICmd_READ_FORMAT_CAPACITY_Port4( Scsi_Cmnd *srb, INT8U *u8Buffer)
438 {
439
440 /* set the command and the LUN */
441 //memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
442 //srb->cmnd[0] = READ_CAPACITY;
443 memset(&pOTGH_PT_BLK_Port4->sCBW.u8CB[0], 0, 16);
444 pOTGH_PT_BLK_Port4->sCBW.u8CB[0]= READ_FORMAT_CAPACITY;
445 pOTGH_PT_BLK_Port4->sCBW.u8CB[8]= 12; //Length
446
447 /* FIXME: we must do the protocol translation here */
448 /*
449 if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
450 srb->cmd_len = 6;
451 else
452 srb->cmd_len = 12;
453 */
454 srb->cmd_len = CB_LENGTH_READ_CAPACITY;
455
456 /* set the transfer direction */
457 srb->sc_data_direction = SCSI_DATA_READ;
458
459 /* use the new buffer we have */
460 srb->request_buffer = (U32)u8Buffer;
461
462 /* set the buffer length for transfer */
463 srb->request_bufflen = 12;
464
465 /* set up for no scatter-gather use */
466 //srb->use_sg = 0;
467
468 /* change the serial number -- toggle the high bit*/
469 //srb->serial_number ^= 0x80000000;
470
471 /* set Lun number*/
472 //srb->lun= u8Drive;
473
474 //srb->scsi_done = vScsi_SendCmd_Done;
475
476
477 }
478
479 //***************************************************************************************
480 // Function Name:vSCSICmd_MODE_SENSE_Port4
481 // Description:
482 // Input:
483 // Output:
484 // Status:
485 //***************************************************************************************
vSCSICmd_MODE_SENSE_Port4(Scsi_Cmnd * srb,INT8U u8PageCode,INT8U * u8Buffer)486 void vSCSICmd_MODE_SENSE_Port4( Scsi_Cmnd *srb,INT8U u8PageCode,INT8U *u8Buffer)
487 {
488
489 /* set the command and the LUN */
490 //memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
491 //srb->cmnd[0] = MODE_SENSE;
492 //srb->cmnd[2] = u8PageCode;
493 //srb->cmnd[4] = DATA_LENGTH_MODE_SENSE;
494 memset(&pOTGH_PT_BLK_Port4->sCBW.u8CB[0], 0, 16);
495 pOTGH_PT_BLK_Port4->sCBW.u8CB[0]= MODE_SENSE;
496 pOTGH_PT_BLK_Port4->sCBW.u8CB[2]= u8PageCode;
497 pOTGH_PT_BLK_Port4->sCBW.u8CB[4]= DATA_LENGTH_MODE_SENSE;
498
499 /* FIXME: we must do the protocol translation here */
500 /*
501 if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
502 srb->cmd_len = 6;
503 else
504 srb->cmd_len = 12;
505 */
506 srb->cmd_len = CB_LENGTH_MODE_SENSE;
507
508 /* set the transfer direction */
509 srb->sc_data_direction = SCSI_DATA_READ;
510
511 /* use the new buffer we have */
512 srb->request_buffer = (U32)u8Buffer;
513 /* set the buffer length for transfer */
514 srb->request_bufflen = DATA_LENGTH_MODE_SENSE;
515
516 /* set up for no scatter-gather use */
517 //srb->use_sg = 0;
518
519 /* change the serial number -- toggle the high bit*/
520 //srb->serial_number ^= 0x80000000;
521
522 /* set Lun number*/
523 //srb->lun= u8Drive;
524
525 //srb->scsi_done = vScsi_SendCmd_Done;
526
527
528 }
529
530 //***************************************************************************************
531 // Function Name:vSCSICmd_MODE_SENSE_OperCode5A_Port4
532 // Description:
533 // Input:
534 // Output:
535 // Status:
536 //***************************************************************************************
vSCSICmd_MODE_SENSE_OperCode5A_Port4(Scsi_Cmnd * srb,INT8U u8PageCode,INT8U * u8Buffer)537 void vSCSICmd_MODE_SENSE_OperCode5A_Port4( Scsi_Cmnd *srb,INT8U u8PageCode,INT8U *u8Buffer)
538 {
539
540 /* set the command and the LUN */
541 //memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
542 //srb->cmnd[0] = MODE_SENSE;
543 //srb->cmnd[2] = u8PageCode;
544 //srb->cmnd[4] = DATA_LENGTH_MODE_SENSE;
545 memset(&pOTGH_PT_BLK_Port4->sCBW.u8CB[0], 0, 16);
546 pOTGH_PT_BLK_Port4->sCBW.u8CB[0]= MODE_SENSE_5A;
547 pOTGH_PT_BLK_Port4->sCBW.u8CB[2]= u8PageCode;
548
549 #if 0
550 pOTGH_PT_BLK_Port4->sCBW.u8CB[4]= DATA_LENGTH_MODE_SENSE_OperCode5A; //RCC?
551 #else
552 pOTGH_PT_BLK_Port4->sCBW.u8CB[7] = (INT8U)(DATA_LENGTH_MODE_SENSE_OperCode5A >> 8);
553 pOTGH_PT_BLK_Port4->sCBW.u8CB[8] = (INT8U)(DATA_LENGTH_MODE_SENSE_OperCode5A );
554 #endif
555
556 /* FIXME: we must do the protocol translation here */
557 /*
558 if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
559 srb->cmd_len = 6;
560 else
561 srb->cmd_len = 12;
562 */
563 srb->cmd_len = CB_LENGTH_MODE_SENSE_5A;
564
565 /* set the transfer direction */
566 srb->sc_data_direction = SCSI_DATA_READ;
567
568 /* use the new buffer we have */
569 srb->request_buffer = (U32)u8Buffer;
570 /* set the buffer length for transfer */
571 srb->request_bufflen = DATA_LENGTH_MODE_SENSE_OperCode5A;
572
573 /* set up for no scatter-gather use */
574 //srb->use_sg = 0;
575
576 /* change the serial number -- toggle the high bit*/
577 //srb->serial_number ^= 0x80000000;
578
579 /* set Lun number*/
580 //srb->lun= u8Drive;
581
582 //srb->scsi_done = vScsi_SendCmd_Done;
583
584
585 }
586
587 //***************************************************************************************
588 // Function Name:vSCSICmd_REQUEST_SENSE_Port4
589 // Description:
590 // Input:
591 // Output:
592 // Status:
593 //***************************************************************************************
vSCSICmd_REQUEST_SENSE_Port4(Scsi_Cmnd * srb,INT8U * u8Buffer)594 void vSCSICmd_REQUEST_SENSE_Port4( Scsi_Cmnd *srb, INT8U *u8Buffer)
595 {
596
597
598 /* set the command and the LUN */
599 //memset(srb->cmnd, 0, MAX_COMMAND_SIZE);
600 //srb->cmnd[0] = REQUEST_SENSE;
601 //srb->cmnd[4] = 18;
602 memset(&pOTGH_PT_BLK_Port4->sCBW.u8CB[0], 0, 16);
603 pOTGH_PT_BLK_Port4->sCBW.u8CB[0]= REQUEST_SENSE;
604 pOTGH_PT_BLK_Port4->sCBW.u8CB[4]= 18;
605
606 /* FIXME: we must do the protocol translation here */
607 /*
608 if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI)
609 srb->cmd_len = 6;
610 else
611 srb->cmd_len = 12;
612 */
613 srb->cmd_len = CB_LENGTH_REQUEST_SENSE;
614
615 /* set the transfer direction */
616 srb->sc_data_direction = SCSI_DATA_READ;
617
618 /* use the new buffer we have */
619 srb->request_buffer = (U32)u8Buffer;
620 /* set the buffer length for transfer */
621 srb->request_bufflen = 18;
622
623 /* set up for no scatter-gather use */
624 //srb->use_sg = 0;
625
626 /* change the serial number -- toggle the high bit*/
627 //srb->serial_number ^= 0x80000000;
628
629 /* set Lun number*/
630 //srb->lun= u8Drive;
631
632 //srb->scsi_done = vScsi_SendCmd_Done;
633
634
635 }
636 #if 0
637 //***************************************************************************************
638 // Function Name:vSCSICmd_TEST_UNIT_READY
639 // Description:
640 // Input:
641 // Output:
642 // Status:S
643 //***************************************************************************************
644 void vSCSICmd_TEST_UNIT_READY( Scsi_Cmnd *srb)
645 {
646
647 memset(&pOTGH_PT_BLK_Port4->sCBW.u8CB[0], 0, 16);
648 pOTGH_PT_BLK_Port4->sCBW.u8CB[0]= TEST_UNIT_READY;
649
650 srb->cmd_len = CB_LENGTH_TEST_UNIT_READY;
651
652
653 /* set the transfer direction */
654 srb->sc_data_direction = SCSI_DATA_READ;
655
656 /* set the buffer length for transfer */
657 srb->request_bufflen = 0;
658
659 }
660 #endif
661
vSCSICmd_Prepare_Port4(Scsi_Cmnd * srb,U8 cmd)662 void vSCSICmd_Prepare_Port4(Scsi_Cmnd *srb, U8 cmd)
663 {
664 memset(&pOTGH_PT_BLK_Port4->sCBW.u8CB[0], 0, 16);
665 pOTGH_PT_BLK_Port4->sCBW.u8CB[0]= cmd;
666
667 srb->cmd_len = 6;
668 /* set the transfer direction */
669 srb->sc_data_direction = SCSI_DATA_READ;
670 /* set the buffer length for transfer */
671 srb->request_bufflen = 0;
672 }
673
674
675
676
vSCSI_EJECT_DEVICE_Port4(U8 lun)677 BOOLEAN vSCSI_EJECT_DEVICE_Port4(U8 lun)
678 {
679 BOOLEAN result;
680
681 Mass_stor_us1_port4.srb =&srb_data_port4;
682 memset(Mass_stor_us1_port4.srb, 0, sizeof(struct scsi_cmnd ));
683
684 vSCSICmd_Prepare_Port4(Mass_stor_us1_port4.srb,START_STOP);
685 Mass_stor_us1_port4.srb->lun=lun;
686 pOTGH_PT_BLK_Port4->sCBW.u8CB[4]= 2; //stop the device
687
688 //result=Host20_MSCD_usb_stor_control_thread_Port4(&Mass_stor_us1);
689 //if (result==FALSE) return result;
690 //pOTGH_PT_BLK_Port4->sCBW.u8CB[0]= START_STOP;
691 //pOTGH_PT_BLK_Port4->sCBW.u8CB[4]= 2; //stop the device
692 //printf("lun:%02bx\n",lun);
693 result=Host20_MSCD_usb_stor_control_thread_Port4(&Mass_stor_us1_port4);
694 return result;
695 }
696
697
698
699
700
701 //=======================================================================================
702 //=======================================================================================
703 //=======================================================================================
704 //=======================================================================================
705 //***************************************************************************************
706 // Function Name:vSCSI_REQUEST_SENSE_Port4
707 // Description: Reserved.
708 // If Device do not support the command-A
709 // ,Host should issue command "vSCSI_REQUEST_SENSE" to ask "why not support".
710 // Input:
711 // Output:
712 // Status:P-OK
713 //***************************************************************************************
vSCSI_REQUEST_SENSE_Port4(U8 lun)714 BOOLEAN vSCSI_REQUEST_SENSE_Port4(U8 lun)
715 {
716 INT8U *u8RequestSenseData;
717 //Scsi_Cmnd srb_data;
718 BOOLEAN result;
719
720 u8RequestSenseData=pUsbData_Port4;
721 Mass_stor_us1_port4.srb = &srb_data_port4;
722 memset(Mass_stor_us1_port4.srb, 0, sizeof(struct scsi_cmnd ));
723
724 // Build SCSI command.
725 vSCSICmd_REQUEST_SENSE_Port4( Mass_stor_us1_port4.srb,u8RequestSenseData);
726
727 Mass_stor_us1_port4.srb->lun=lun;
728
729 //call mass storage function to send CBW
730 //and get REQUEST_SENSE Data. Return CSW to check status.
731 result=Host20_MSCD_usb_stor_control_thread_Port4(&Mass_stor_us1_port4);
732 return result;
733
734
735
736 }
737
738 //***************************************************************************************
739 // Function Name:bSCSI_INQUIRY_Port4
740 // Description:To ask the device u8DeviceType/u8ProductID/u8ProductVer... information
741 // Input:
742 // Output:
743 // Status:P-OK
744 //***************************************************************************************
745 ///////////////////////////////////////////////////////////////////////////////
746 // bSCSI_INQUIRY_Port4()
747 // Description:
748 // 1. scsi inquiry command.
749 // input: none
750 // output: TRUE or FALSE (BOOLEAN)
751 ///////////////////////////////////////////////////////////////////////////////
752 //INT8U xdata u8InquiryData[DATA_LENGTH_INQUIRY] _at_ Host20_TEMP_DATA;
bSCSI_INQUIRY_Port4(U8 lun)753 BOOLEAN bSCSI_INQUIRY_Port4(U8 lun)
754 {
755 INT8U u8i, u8j;
756 //Scsi_Cmnd srb_data;
757 U8 *u8InquiryData;
758 BOOLEAN result;
759
760 u8InquiryData=pUsbData_Port4;
761 //printf("INQUIRY\n");
762 for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++)
763 {
764
765 Mass_stor_us1_port4.srb =&srb_data_port4;
766 memset(Mass_stor_us1_port4.srb, 0, sizeof(struct scsi_cmnd ));
767
768 //Build SCSI command.
769 vSCSICmd_INQUIRY_Port4( Mass_stor_us1_port4.srb, u8InquiryData);
770 Mass_stor_us1_port4.srb->lun=lun;
771
772 //call mass storage function to send CBW
773 //and get INQUIRY Data. Return CSW to check status.
774 result=Host20_MSCD_usb_stor_control_thread_Port4(&Mass_stor_us1_port4);
775 if (result==FALSE) continue;
776
777 if(Mass_stor_us1_port4.srb->result == SAM_STAT_GOOD)
778 {
779 //save all INQUIRY data
780 Mass_stor_us1_port4.device.u8DeviceType = (u8InquiryData[0] & 0x1F);
781
782 Mass_stor_us1_port4.Mass_stor_device[lun].bRMB = (u8InquiryData[1] & 0x80) >> 7;
783 //printf("Removable: %d\n", Mass_stor_us1_port4.Mass_stor_device[lun].bRMB);
784
785 for(u8i =0; u8i <8; u8i++)
786 Mass_stor_us1_port4.Mass_stor_device[lun].u8VendorID[u8i] = u8InquiryData[u8i+8];
787 for(u8i =0; u8i <16; u8i++)
788 Mass_stor_us1_port4.Mass_stor_device[lun].u8ProductID[u8i] = u8InquiryData[u8i+16];
789 for(u8i =0; u8i <4; u8i++)
790 Mass_stor_us1_port4.Mass_stor_device[lun].u8ProductVer[u8i] = u8InquiryData[u8i+32];
791
792 if(Mass_stor_us1_port4.device.u8DeviceType != TYPE_DISK)
793 {
794 DRV_SCSI_DBG(printf("Device type unsuport, it's not a scsi disk%s","\n"));
795
796 return FALSE;
797 }
798 else
799 {
800
801 DRV_SCSI_DBG(SCSI_DbgPrint("SCSI INQUIRY : SCSI Device ID <%s>\n",&Mass_stor_us1_port4.Mass_stor_device[lun].u8VendorID));
802 //SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ID <%s>\n",&Mass_stor_us1.device.u8ProductID);
803 //SCSI_DbgPrint("SCSI INQUIRY : SCSI Product ver <%s>\n",&Mass_stor_us1.device.u8ProductVer);
804 return TRUE;
805 }
806
807
808 }
809
810 }
811 return FALSE;
812 }
813 //***************************************************************************************
814 // Function Name:bSCSI_MODE_SENSE_Port4
815 // Description:To know the mode of device <1>.Write Protect => Y/N
816 // Input:
817 // Output:
818 // Status:P-OK
819 //***************************************************************************************
820 ///////////////////////////////////////////////////////////////////////////////
821 // bSCSI_MODE_SENSE()
822 // Description:
823 // 1. scsi mode sense command.
824 // input: none
825 // output: TRUE or FALSE (BOOLEAN)
826 ///////////////////////////////////////////////////////////////////////////////
bSCSI_MODE_SENSE_Port4(U8 lun)827 BOOLEAN bSCSI_MODE_SENSE_Port4(U8 lun)
828 {
829 INT8U u8j;
830 INT8U *u8ModeSenseData;
831 BOOLEAN result;
832 //Scsi_Cmnd srb_data;
833
834 u8ModeSenseData=pUsbData_Port4;
835
836 Mass_stor_us1_port4.srb = &srb_data_port4;
837
838 for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++)
839 {
840 memset(Mass_stor_us1_port4.srb, 0, sizeof(struct scsi_cmnd ));
841 //Build SCSI command.
842 vSCSICmd_MODE_SENSE_Port4( Mass_stor_us1_port4.srb,0x3F, u8ModeSenseData);
843 Mass_stor_us1_port4.srb->lun=lun;
844
845 //call mass storage function to send CBW
846 //and get Mode Sense Data. Return CSW to check status.
847 result=Host20_MSCD_usb_stor_control_thread_Port4(&Mass_stor_us1_port4);
848 if (result==FALSE) return FALSE;
849
850 if(Mass_stor_us1_port4.srb->result == SAM_STAT_GOOD)
851 {
852 //save all Mode Sense(page code=0x3F) data
853 //Now we only use u8ModeSenseData[2], this byte save device
854 //write protection information
855 Mass_stor_us1_port4.Mass_stor_device[lun].bWriteProtect = (u8ModeSenseData[2]==0x80)?
856 TRUE:FALSE;
857
858
859 return TRUE;
860 }
861 }
862 Mass_stor_us1_port4.Mass_stor_device[lun].bWriteProtect=FALSE; //not support this command
863 return FALSE;
864 }
865
866
867 //***************************************************************************************
868 // Function Name:bSCSI_MODE_SENSE_OperCode5A_Port4
869 // Description:To know the mode of device <1>.Write Protect => Y/N
870 // Input:
871 // Output:
872 // Status:P-OK
873 //***************************************************************************************
874 ///////////////////////////////////////////////////////////////////////////////
875 // bSCSI_MODE_SENSE_OperCode5A_Port4()
876 // Description:
877 // 1. scsi mode sense command.
878 // input: none
879 // output: TRUE or FALSE (BOOLEAN)
880 ///////////////////////////////////////////////////////////////////////////////
bSCSI_MODE_SENSE_OperCode5A_Port4(U8 lun)881 BOOLEAN bSCSI_MODE_SENSE_OperCode5A_Port4(U8 lun)
882 {
883 INT8U u8j;
884 INT8U *u8ModeSenseData;
885 BOOLEAN result;
886 //Scsi_Cmnd srb_data;
887
888 u8ModeSenseData=pUsbData_Port4;
889
890 Mass_stor_us1_port4.srb = &srb_data_port4;
891
892 for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++)
893 {
894 memset(Mass_stor_us1_port4.srb, 0, sizeof(struct scsi_cmnd ));
895 //Build SCSI command.
896 vSCSICmd_MODE_SENSE_OperCode5A_Port4( Mass_stor_us1_port4.srb,0x3F, u8ModeSenseData);
897 Mass_stor_us1_port4.srb->lun=lun;
898
899 //call mass storage function to send CBW
900 //and get Mode Sense Data. Return CSW to check status.
901 result=Host20_MSCD_usb_stor_control_thread_Port4(&Mass_stor_us1_port4);
902 if (result==FALSE) return FALSE;
903
904 if(Mass_stor_us1_port4.srb->result == SAM_STAT_GOOD)
905 {
906 //save all Mode Sense(page code=0x3F) data
907 //Now we only use u8ModeSenseData[2], this byte save device
908 //write protection information
909 Mass_stor_us1_port4.Mass_stor_device[lun].bWriteProtect = (u8ModeSenseData[3]==0x80)?
910 TRUE:FALSE;
911 return TRUE;
912 }
913 }
914 Mass_stor_us1_port4.Mass_stor_device[lun].bWriteProtect=FALSE; //not support this command
915 return FALSE;
916 }
917
918
919 //***************************************************************************************
920 // Function Name:bSCSI_READ_CAPACITY_Port4
921 // Description:To get the CAPACITY
922 // Input:
923 // Output:
924 // Status:S
925 //***************************************************************************************
926 ///////////////////////////////////////////////////////////////////////////////
927 // bSCSI_READ_CAPACITY_Port4()
928 // Description:
929 // 1. scsi READ_CAPACITY command.
930 // input: none
931 // output: TRUE or FALSE (BOOLEAN)
932 ///////////////////////////////////////////////////////////////////////////////
bSCSI_READ_CAPACITY_Port4(U8 lun)933 BOOLEAN bSCSI_READ_CAPACITY_Port4(U8 lun)
934 {
935 //INT8U u8j;
936 INT8U *u8ReadCapacityData;
937 BOOLEAN result;
938 //Scsi_Cmnd srb_data;
939
940 u8ReadCapacityData=pUsbData_Port4;
941 //for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++)
942 {
943 Mass_stor_us1_port4.srb = &srb_data_port4;
944 memset(Mass_stor_us1_port4.srb, 0, sizeof(struct scsi_cmnd ));
945
946 //Build SCSI command.
947 vSCSICmd_READ_CAPACITY_Port4(Mass_stor_us1_port4.srb, u8ReadCapacityData);
948 Mass_stor_us1_port4.srb->lun=lun;
949
950 //call mass storage function to send CBW
951 //and get CAPACITY Data. Return CSW to check status.
952 result=Host20_MSCD_usb_stor_control_thread_Port4(&Mass_stor_us1_port4);
953 if (result==FALSE) return result;
954
955 if(Mass_stor_us1_port4.srb->result == SAM_STAT_GOOD)
956 {
957 //save all CAPACITY data
958 Mass_stor_us1_port4.Mass_stor_device[lun].u32BlockTotalNum = ((INT32U)u8ReadCapacityData[0] << 24) |
959 ((INT32U)u8ReadCapacityData[1] << 16) |
960 ((INT32U)u8ReadCapacityData[2] << 8) |
961 ((INT32U)u8ReadCapacityData[3] ) ;
962
963 Mass_stor_us1_port4.Mass_stor_device[lun].u32BlockSize = ((INT32U)u8ReadCapacityData[4] << 24) |
964 ((INT32U)u8ReadCapacityData[5] << 16) |
965 ((INT32U)u8ReadCapacityData[6] << 8) |
966 ((INT32U)u8ReadCapacityData[7] ) ;
967 //if ( Mass_stor_us1.Mass_stor_device[lun].u32BlockSize > 1024)
968 //{
969 // printf("Block size over 1024, is %X\n",Mass_stor_us1.Mass_stor_device[lun].u32BlockSize);
970 // while(1);
971 //}
972
973 DRV_SCSI_DBG(SCSI_DbgPrint("SCSI CAPACITY : SCSI Device total block <0x%x%x>\n",
974 (INT16U)(Mass_stor_us1_port4.Mass_stor_device[lun].u32BlockTotalNum >> 16),
975 (INT16U)Mass_stor_us1_port4.Mass_stor_device[lun].u32BlockTotalNum));
976 DRV_SCSI_DBG(SCSI_DbgPrint("SCSI CAPACITY : SCSI Product block size <0x%x bytes>\n",(INT16U)Mass_stor_us1_port4.Mass_stor_device[lun].u32BlockSize));
977
978 return TRUE;
979 }
980 else
981 {
982 vSCSI_REQUEST_SENSE_Port4(lun);
983 return FALSE;
984 }
985 }
986 return FALSE;
987
988 }
989
bSCSI_READ_FORMAT_CAPACITY_Port4(U8 lun)990 BOOLEAN bSCSI_READ_FORMAT_CAPACITY_Port4(U8 lun)
991 {
992 INT8U u8j;
993 INT8U *u8ReadCapacityData;
994 BOOLEAN result;
995 //Scsi_Cmnd srb_data;
996
997 u8ReadCapacityData=pUsbData_Port4;
998 for(u8j =0; u8j< ScsiCmd_Fail_Retry ;u8j++)
999 {
1000 Mass_stor_us1_port4.srb = &srb_data_port4;
1001 memset(Mass_stor_us1_port4.srb, 0, sizeof(struct scsi_cmnd ));
1002
1003 //Build SCSI command.
1004 vSCSICmd_READ_FORMAT_CAPACITY_Port4(Mass_stor_us1_port4.srb, u8ReadCapacityData);
1005 Mass_stor_us1_port4.srb->lun=lun;
1006
1007 //call mass storage function to send CBW
1008 //and get CAPACITY Data. Return CSW to check status.
1009 result=Host20_MSCD_usb_stor_control_thread_Port4(&Mass_stor_us1_port4);
1010 if (result==FALSE) return result;
1011
1012 if(Mass_stor_us1_port4.srb->result == SAM_STAT_GOOD)
1013 {
1014 //save all CAPACITY data
1015 Mass_stor_us1_port4.Mass_stor_device[lun].u32BlockTotalNum = ((INT32U)u8ReadCapacityData[4] << 24) |
1016 ((INT32U)u8ReadCapacityData[5] << 16) |
1017 ((INT32U)u8ReadCapacityData[6] << 8) |
1018 ((INT32U)u8ReadCapacityData[7] ) ;
1019
1020 Mass_stor_us1_port4.Mass_stor_device[lun].u32BlockSize = ((INT32U)u8ReadCapacityData[9] << 16) |
1021 ((INT32U)u8ReadCapacityData[10] << 8) |
1022 ((INT32U)u8ReadCapacityData[11] ) ;
1023 //if ( Mass_stor_us1.Mass_stor_device[lun].u32BlockSize > 1024)
1024 //{
1025 // printf("Block size over 1024, is %X\n",Mass_stor_us1.Mass_stor_device[lun].u32BlockSize);
1026 // while(1);
1027 //}
1028
1029 DRV_SCSI_DBG(SCSI_DbgPrint("SCSI CAPACITY : SCSI Device total block <0x%x%x>\n",
1030 (INT16U)(Mass_stor_us1_port4.Mass_stor_device[lun].u32BlockTotalNum >> 16),
1031 (INT16U)Mass_stor_us1_port4.Mass_stor_device[lun].u32BlockTotalNum));
1032 DRV_SCSI_DBG(SCSI_DbgPrint("SCSI CAPACITY : SCSI Product block size <0x%x bytes>\n",(INT16U)Mass_stor_us1_port4.Mass_stor_device[lun].u32BlockSize));
1033
1034 return TRUE;
1035 }
1036 }
1037 return FALSE;
1038
1039 }
1040
1041
1042 extern void OTGH_PT_Bulk_Init_Port4(void);
1043 extern BOOLEAN MDrv_UsbHost_Init_Port4(void);
1044 //***************************************************************************************
1045 // Function Name:bSCSI_TEST_UNIT_READY_Port4
1046 // Description: To know that "device is ready ?"
1047 // Input:
1048 // Output:
1049 // Status:
1050 //***************************************************************************************
1051 ///////////////////////////////////////////////////////////////////////////////
1052 // bSCSI_TEST_UNIT_READY_Port4()
1053 // Description:
1054 // 1. scsi TEST_UNIT_READY command.
1055 // input: none
1056 // output: TRUE or FALSE (BOOLEAN)
1057 ///////////////////////////////////////////////////////////////////////////////
bSCSI_TEST_UNIT_READY_Port4(U8 lun)1058 BOOLEAN bSCSI_TEST_UNIT_READY_Port4(U8 lun)
1059 {
1060 INT8U u8j;
1061 BOOLEAN result;
1062 #ifdef ATV_SERISE_USE
1063 U32 i;
1064 #endif
1065 //Scsi_Cmnd srb_data;
1066 //printf("TUR\n");
1067
1068 for(u8j =0; u8j< TestUnitReady_Fail_Retry ;u8j++)
1069 {
1070 //printf("connect status:%02bx\n",mwHost20_PORTSC_ConnectStatus_Rd());
1071 if (mwHost20_PORTSC_ConnectStatus_Rd()==0)
1072 return FALSE; //device is not connected
1073
1074 Mass_stor_us1_port4.srb = &srb_data_port4;
1075 memset((U8 xdata *)Mass_stor_us1_port4.srb, 0, sizeof(struct scsi_cmnd ));
1076
1077 // Build SCSI command.
1078 vSCSICmd_Prepare_Port4(Mass_stor_us1_port4.srb,TEST_UNIT_READY);
1079 //vSCSICmd_TEST_UNIT_READY(Mass_stor_us1.srb);
1080 Mass_stor_us1_port4.srb->lun=lun;
1081 //printf("Mass_stor_us1.srb:%02bx\n",Mass_stor_us1.srb->request_bufflen);
1082 //call mass storage function to send CBW
1083 //and get CAPACITY Data. Return CSW to check status.
1084
1085 result=Host20_MSCD_usb_stor_control_thread_Port4(&Mass_stor_us1_port4);
1086 //printf("result:%02bx\n",result);
1087 #if 1
1088 if (result == FALSE)
1089 {
1090 if (gUsbStatus_Port4== USB_TIMEOUT)
1091 {
1092 DRV_SCSI_DBG(printf("resend TUR\n"));
1093 if ( MDrv_UsbHost_Init_Port4() && (flib_Host20_Enumerate_Port4(1,3)!=0) )
1094 {
1095 OTGH_PT_Bulk_Init_Port4();
1096 continue;
1097 }
1098 }
1099 else
1100 return result;
1101 }
1102 #else
1103 if (result==FALSE)
1104 {
1105 return result;
1106 }
1107 #endif
1108
1109 if(Mass_stor_us1_port4.srb->result == SAM_STAT_GOOD)
1110 {
1111 Mass_stor_us1_port4.Mass_stor_device[lun].bDeviceReady = TRUE;
1112 //SCSI_DbgPrint("SCSI TEST UNIT READY : Succeed\n",u8Drive);
1113
1114 return TRUE;
1115 }
1116 else
1117 {
1118 #ifndef ATV_SERISE_USE
1119 MsOS_DelayTask(10);
1120 #else
1121 for(i=0;i<(0x100);i++);
1122 #endif
1123
1124
1125 result=vSCSI_REQUEST_SENSE_Port4(lun);
1126 if ((pUsbData_Port4[12]==0x3a)&&(pUsbData_Port4[13]==0)) return FALSE; //no media
1127 if (result==FALSE) return result;
1128 }
1129 #ifndef ATV_SERISE_USE
1130 MsOS_DelayTask(10);
1131 #else
1132 for(i=0;i<0x100;i++);
1133 #endif
1134 }
1135 //SCSI_DbgPrint("SCSI TEST UNIT READY : Failed%s","\n");
1136 return FALSE;
1137 }
1138 extern BOOLEAN MDrv_Usb_Device_Enum_Port4(void);
1139 #ifdef ATV_SERISE_USE
1140 extern void EnableINT(void);
1141 #endif
1142
bSCSI_TEST_UNIT_READY2_Port4(U8 lun)1143 BOOLEAN bSCSI_TEST_UNIT_READY2_Port4(U8 lun)
1144 {
1145 INT8U u8j;
1146 BOOLEAN result;
1147 U8 RetryCnt=0;
1148
1149 #ifdef ATV_SERISE_USE
1150 U32 i;
1151 #endif
1152 //Scsi_Cmnd srb_data;
1153 //printf("TUR\n");
1154
1155 for(u8j =0; u8j< TestUnitReady_Fail_Retry ;u8j++)
1156 {
1157 //printf("connect status:%02bx\n",mwHost20_PORTSC_ConnectStatus_Rd());
1158 if (mwHost20_PORTSC_ConnectStatus_Rd()==0)
1159 return FALSE; //device is not connected
1160
1161 Mass_stor_us1_port4.srb = &srb_data_port4;
1162 memset((U8 xdata *)Mass_stor_us1_port4.srb, 0, sizeof(struct scsi_cmnd ));
1163
1164 // Build SCSI command.
1165 vSCSICmd_Prepare_Port4(Mass_stor_us1_port4.srb,TEST_UNIT_READY);
1166 //vSCSICmd_TEST_UNIT_READY(Mass_stor_us1.srb);
1167 Mass_stor_us1_port4.srb->lun=lun;
1168 //printf("Mass_stor_us1.srb:%02bx\n",Mass_stor_us1.srb->request_bufflen);
1169 //call mass storage function to send CBW
1170 //and get CAPACITY Data. Return CSW to check status.
1171
1172 result=Host20_MSCD_usb_stor_control_thread_Port4(&Mass_stor_us1_port4);
1173 //printf("result:%02bx\n",result);
1174
1175 if (result==FALSE)
1176 {
1177 RetryCnt++;
1178 if (gUsbStatus_Port4==USB_TIMEOUT)
1179 {
1180 if (RetryCnt > 3) return FALSE;
1181 if ((RetryCnt==2)&&(mwOTG20_Control_HOST_SPD_TYP_Rd()==2) ) //make sure it is hi speed
1182 {
1183 DRV_SCSI_DBG( printf("Force FS\n"));
1184 UHC4_ORXBYTE(0x40,0x80);//force enter FSmode
1185 }
1186 #ifndef ATV_SERISE_USE
1187 msAPI_Timer_ResetWDT();
1188 #else
1189 #ifdef Enable_Close_INT
1190 //XBYTE[0x2B00]&=0xFD;
1191 EnableINT();
1192 #endif
1193 #endif
1194 #ifdef Enable_Low_Temperature_Patch
1195 if(gSpeed_Port4==0)
1196 {
1197 //printf("\r\n CDR toggle!!",0);
1198 UTMI4_SETXBYTE(0x0a,UTMI4_READXBYTE(0x0a)^0x10); //invert CDR_CLOCK
1199 UTMI4_ORXBYTE(0x06,0x03); //reset UTMI
1200 UTMI4_ANDXBYTE(0x06,0xfc);
1201 }
1202 #endif
1203 // MDrv_Usb_Device_Enum();
1204 if (MDrv_Usb_Device_Enum_Port4()==FALSE) return FALSE;
1205
1206 continue;
1207 }
1208 else
1209 return FALSE;
1210 }
1211
1212 if(Mass_stor_us1_port4.srb->result == SAM_STAT_GOOD)
1213 {
1214 Mass_stor_us1_port4.Mass_stor_device[lun].bDeviceReady = TRUE;
1215 //SCSI_DbgPrint("SCSI TEST UNIT READY : Succeed\n",u8Drive);
1216
1217 return TRUE;
1218 }
1219 else
1220 {
1221 #ifndef ATV_SERISE_USE
1222 MsOS_DelayTask(10);
1223 #else
1224 for(i=0;i<(0x100);i++);
1225 #endif
1226
1227
1228 result=vSCSI_REQUEST_SENSE_Port4(lun);
1229 if ((pUsbData_Port4[12]==0x3a)&&(pUsbData_Port4[13]==0)) return FALSE; //no media
1230 if ((pUsbData_Port4[12]==0x28)&&(pUsbData_Port4[13]==0)) return FALSE; //media change
1231 if (result==FALSE) return result;
1232 }
1233 #ifndef ATV_SERISE_USE
1234 MsOS_DelayTask(10);
1235 #else
1236 for(i=0;i<0x100;i++);
1237 #endif
1238 }
1239 //SCSI_DbgPrint("SCSI TEST UNIT READY : Failed%s","\n");
1240 return FALSE;
1241 }
1242 //***************************************************************************************
1243 // Function Name:bSCSI_Initial_Port4
1244 // Description:
1245 // Input:
1246 // Output:
1247 // Status:P-OK
1248 //***************************************************************************************
1249 U8 ValidLunNum_Port4;
bSCSI_Initial_Port4(void)1250 BOOLEAN bSCSI_Initial_Port4(void)
1251 {
1252 //INT8U i=0;
1253 //iCardSuddenlyRemove = FALSE;
1254 //iCardReplace = FALSE;
1255 BOOLEAN bFoundValidDev = FALSE;
1256 struct LUN_Device* LunDevice = Mass_stor_us1_port4.Mass_stor_device;
1257 U8 LunIdx;
1258
1259 ValidLunNum_Port4=0;
1260 for ( LunIdx=0; LunIdx<=Mass_stor_us1_port4.max_lun; LunIdx++)
1261 {
1262 LunDevice[LunIdx].bDeviceValid=FALSE;
1263 if (bSCSI_INQUIRY_Port4(LunIdx))
1264 {
1265 LunDevice[LunIdx].bDeviceValid=TRUE;
1266 ValidLunNum_Port4++;
1267 }
1268 //break;
1269 }
1270 DRV_SCSI_DBG(printf("ValidLunNum_Port4:%02bx\n",ValidLunNum_Port4));
1271 // For some usb harddrive without enough power, may meet following case.
1272 if (!ValidLunNum_Port4)
1273 {
1274 if (mwHost20_PORTSC_ConnectChange_Rd()==0)
1275 MDrv_SetUsbDeviceStatus_Port4(BAD_DEVICE);
1276 return bFoundValidDev;
1277 }
1278
1279 // Sometime device is failed to initial at first time, but success at last.
1280 // It set the device status as BAD_DEVICE at first time when it failed.
1281 // We need to set correct value to device status when successed.
1282 if (gSpeed_Port4==2)
1283 {
1284 MDrv_SetUsbDeviceStatus_Port4(USB20_DEVICE);
1285 }
1286 else
1287 {
1288 MDrv_SetUsbDeviceStatus_Port4(USB11_DEVICE);
1289 }
1290 #ifdef ATV_SERISE_USE
1291 #ifdef Enable_Close_INT
1292 EA=0;
1293 #endif
1294 #endif
1295 for ( LunIdx=0; LunIdx<=Mass_stor_us1_port4.max_lun; LunIdx++)
1296 {
1297 LunDevice[LunIdx].bDeviceReady = FALSE;
1298 if (!bInit_USB_LUN_Port4(LunIdx))
1299 continue;
1300 LunDevice[LunIdx].bDeviceReady = TRUE;
1301 bFoundValidDev = TRUE;
1302
1303 }
1304 #ifdef ATV_SERISE_USE
1305 #ifdef Enable_Close_INT
1306 EA=1;
1307 #endif
1308 #endif
1309 return bFoundValidDev;
1310
1311 }
GetValidLun_Port4(void)1312 void GetValidLun_Port4(void)
1313 {
1314 U8 LunIdx;
1315 struct LUN_Device* LunDevice = Mass_stor_us1_port4.Mass_stor_device;
1316
1317 if (LunDevice == NULL)
1318 {
1319 DRV_SCSI_DBG(printf(" LUN structure not initialized!!\n"));
1320 return;
1321 }
1322
1323 if ( (Mass_stor_us1_port4.max_lun == 0) && (!LunDevice[0].bRMB) && LunDevice[0].bDeviceReady)
1324 {
1325 //20120817, Don't do TUR on this special USB HDD.
1326 //It returns NOT READY after 30 minutes idle.
1327 return;
1328 }
1329
1330 for (LunIdx=0; LunIdx<=Mass_stor_us1_port4.max_lun; LunIdx++)
1331 {
1332 if (LunDevice[LunIdx].bDeviceValid)
1333 {
1334 if(!bSCSI_TEST_UNIT_READY2_Port4(LunIdx))
1335 {
1336 LunDevice[LunIdx].bDeviceReady=FALSE;
1337 LunDevice[LunIdx].u32BlockSize = 0; // 20111110: resolve lun capacity zero if not the first lun
1338 LunDevice[LunIdx].u32BlockTotalNum = 0;
1339 }
1340 else
1341 {
1342 LunDevice[LunIdx].bDeviceReady = TRUE;
1343 if (LunDevice[LunIdx].u32BlockSize == 0) // 20111110: resolve lun capacity zero if not the first lun
1344 {
1345 if(!bSCSI_READ_CAPACITY_Port4(LunIdx))
1346 {
1347 if (!bSCSI_READ_FORMAT_CAPACITY_Port4(LunIdx))
1348 {
1349 DRV_SCSI_DBG(SCSI_DbgPrint("Read CAPACITY failed.%s","\n"));
1350 }
1351 }
1352 }
1353 }
1354 }
1355 else
1356 LunDevice[LunIdx].bDeviceReady=FALSE; //not a valid device, so always not ready
1357 }
1358 }
bInit_USB_LUN_Port4(U8 Lun)1359 BOOLEAN bInit_USB_LUN_Port4(U8 Lun)
1360 {
1361 U16 uVID, uPID;
1362 U8 ii;
1363 BOOLEAN bIsForceMS1A = FALSE;
1364
1365 MDrv_USBGetVIDPID_Port4(&uVID, &uPID);
1366 if ( (uVID == 0xFCA) && (uPID == 0x8004) ) //20130301, for blackberry phone
1367 {
1368 if (!bSCSI_INQUIRY_Port4(Lun))
1369 {
1370 DRV_SCSI_DBG(SCSI_DbgPrint("Scsi inquiry failed (Lun=%d).\n",u8Drive_port4));
1371 return FALSE;
1372 }
1373 }
1374
1375 if(!bSCSI_TEST_UNIT_READY_Port4(Lun))
1376 {
1377 DRV_SCSI_DBG(SCSI_DbgPrint("Scsi Device not ready (Lun=%d).\n",Lun));
1378 return FALSE;
1379 }
1380 //bSCSI_INQUIRY();
1381 if (!bSCSI_INQUIRY_Port4(Lun))
1382 {
1383 DRV_SCSI_DBG(SCSI_DbgPrint("Scsi inquiry failed (Lun=%d).\n",u8Drive_port4));
1384 return FALSE;
1385 }
1386 if(!bSCSI_READ_CAPACITY_Port4(Lun))
1387 {
1388 if (!bSCSI_READ_FORMAT_CAPACITY_Port4(Lun))
1389 {
1390 DRV_SCSI_DBG(SCSI_DbgPrint("Read CAPACITY failed.%s","\n"));
1391 return FALSE;
1392 }
1393 }
1394
1395 #ifdef ENABLE_CBI_HOST
1396 if ((psAttachDevice_Port4->saCD[0].sInterface[0].bInterfaceProtocol==0x00)||(psAttachDevice_Port4->saCD[0].sInterface[0].bInterfaceProtocol==0x01))
1397 {
1398 //do nothing
1399 }
1400 else
1401 #endif
1402 {
1403 MDrv_USBGetVIDPID_Port4(&uVID, &uPID);
1404 DRV_SCSI_DBG(printf("VID: %x, PID: %x\n", uVID, uPID));
1405 ii = 0;
1406 while ( (gForceModeSense1A_Port4[ii].VID != 0) && (gForceModeSense1A_Port4[ii].PID != 0) )
1407 {
1408 if ( (uVID == gForceModeSense1A_Port4[ii].VID) && (uPID == gForceModeSense1A_Port4[ii].PID) )
1409 {
1410 DRV_SCSI_DBG(printf("Find a Force Mode Sense 1A device\n"));
1411 bIsForceMS1A = TRUE;
1412 }
1413
1414 ii++;
1415 if (ii >= (sizeof(gForceModeSense1A_Port4) / sizeof(struct stForceModeSense1A)))
1416 break;
1417 }
1418
1419 if (bIsForceMS1A)
1420 bSCSI_MODE_SENSE_Port4(Lun);
1421 else
1422 bSCSI_MODE_SENSE_OperCode5A_Port4(Lun);
1423
1424 }
1425 //if (!bSCSI_MODE_SENSE(Lun))
1426 //{
1427 // SCSI_DbgPrint("Mode sense failed!\n");
1428 // return FALSE;
1429 //}
1430
1431 if(!bSCSI_TEST_UNIT_READY_Port4(Lun))
1432 {
1433 DRV_SCSI_DBG(SCSI_DbgPrint("Scsi Device not ready (Lun=%d).\n",u8Drive_port4));
1434 return FALSE;
1435 }
1436 return TRUE;
1437
1438 }
1439
1440
1441 //***************************************************************************************
1442 // Function Name:
1443 // Description:
1444 // Input:
1445 // Output:
1446 // Status:
1447 //***************************************************************************************
1448
1449
1450
bSCSI_Read_Write10_Port4(BOOLEAN DoWrite,U8 lun,INT32U u32BlockAddr,INT32U u32BlockNum,U32 u8Buffer)1451 BOOLEAN bSCSI_Read_Write10_Port4(BOOLEAN DoWrite, U8 lun, INT32U u32BlockAddr, INT32U u32BlockNum,U32 u8Buffer)
1452 {
1453
1454 //Scsi_Cmnd srb_data;
1455 BOOLEAN result;
1456 Mass_stor_us1_port4.srb = &srb_data_port4;
1457 //memset(Mass_stor_us1.srb, 0, sizeof(struct scsi_cmnd ));
1458 //printf("read sector:%lx, sz:%lx\n",u32BlockAddr,u32BlockNum);
1459
1460 if (DoWrite)
1461 {
1462 if(Mass_stor_us1_port4.Mass_stor_device[lun].bWriteProtect)
1463 {
1464 DRV_SCSI_DBG(printf("This device is write protect now\n"));
1465 return FALSE;
1466 }
1467 }
1468
1469 //Build SCSI command.
1470 vSCSICmd_READ_WRITE_10_Port4(DoWrite,&Mass_stor_us1_port4, Mass_stor_us1_port4.srb, lun,
1471 u32BlockAddr, (INT16U)u32BlockNum, u8Buffer);
1472
1473
1474 //call mass storage function to send scsi command
1475 result=Host20_MSCD_usb_stor_control_thread_Port4(&Mass_stor_us1_port4);
1476 if (result==FALSE) return result;
1477
1478 if(Mass_stor_us1_port4.srb->result != SAM_STAT_GOOD)
1479 {
1480 DRV_SCSI_DBG(SCSI_DbgPrint("Scsi ReadWrite_10 command failed.%s","\n"));
1481
1482 return FALSE;
1483 }
1484
1485
1486 //printf("#");
1487 return TRUE;
1488
1489
1490
1491 }
1492 #endif //#if defined(MSOS_TYPE_NOS)
1493
1494
1495