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