1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
1 // Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). |
2 // All rights reserved. |
2 // All rights reserved. |
3 // This component and the accompanying materials are made available |
3 // This component and the accompanying materials are made available |
4 // under the terms of the License "Eclipse Public License v1.0" |
4 // under the terms of the License "Eclipse Public License v1.0" |
5 // which accompanies this distribution, and is available |
5 // which accompanies this distribution, and is available |
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
24 #include "msdebug.h" |
24 #include "msdebug.h" |
25 #include "msctypes.h" |
25 #include "msctypes.h" |
26 #include "shared.h" |
26 #include "shared.h" |
27 #include "msgservice.h" |
27 #include "msgservice.h" |
28 |
28 |
29 #include "mscutils.h" |
|
30 |
|
31 #include "mtransport.h" |
29 #include "mtransport.h" |
32 #include "mprotocol.h" |
30 #include "mprotocol.h" |
33 #include "tscsiclientreq.h" |
31 #include "tscsiclientreq.h" |
34 #include "tscsiprimarycmds.h" |
32 #include "tscsiprimarycmds.h" |
35 #include "tscsiblockcmds.h" |
33 #include "tscsiblockcmds.h" |
43 #include "cscsiprotocol.h" |
41 #include "cscsiprotocol.h" |
44 |
42 |
45 #include "usbmshostpanic.h" |
43 #include "usbmshostpanic.h" |
46 |
44 |
47 |
45 |
48 |
|
49 /** |
46 /** |
50 Create the CScsiProtocol object. |
47 Create the CScsiProtocol object. |
51 |
48 |
52 @param aLun The LUN for the device represented by this object |
49 @param aLun The LUN for the device represented by this object |
53 @param aTransport The transport interface |
50 @param aTransport The transport interface |
66 } |
63 } |
67 |
64 |
68 void CScsiProtocol::ConstructL(TLun aLun) |
65 void CScsiProtocol::ConstructL(TLun aLun) |
69 { |
66 { |
70 __MSFNLOG |
67 __MSFNLOG |
|
68 // iState = EEntry; |
71 iFsm = CMassStorageFsm::NewL(*this); |
69 iFsm = CMassStorageFsm::NewL(*this); |
72 iState = EDisconnected; |
|
73 |
70 |
74 const TInt blockLength = 0x200; |
71 const TInt blockLength = 0x200; |
75 |
72 |
76 iHeadbuf.CreateL(blockLength); |
73 iHeadbuf.CreateL(blockLength); |
77 iTailbuf.CreateL(blockLength); |
74 iTailbuf.CreateL(blockLength); |
97 |
94 |
98 |
95 |
99 void CScsiProtocol::InitialiseUnitL() |
96 void CScsiProtocol::InitialiseUnitL() |
100 { |
97 { |
101 __MSFNLOG |
98 __MSFNLOG |
|
99 iState = EDisconnected; |
102 |
100 |
103 // A device may take time to mount the media. If the device fails attempt to |
101 // A device may take time to mount the media. If the device fails attempt to |
104 // retry the connection for a number of seconds |
102 // retry the connection for a number of seconds |
105 TInt retryCounter = 20; |
103 TInt retryCounter = 20; |
106 do |
104 do |
107 { |
105 { |
108 retryCounter--; |
106 retryCounter--; |
109 iFsm->ConnectLogicalUnitL(); |
107 iFsm->ConnectLogicalUnitL(); |
110 iState = iFsm->IsConnected() ? EConnected: EDisconnected; |
108 if (iFsm->IsConnected()) |
111 |
|
112 if (iState == EConnected) |
|
113 { |
109 { |
|
110 iState = EConnected; |
114 break; |
111 break; |
115 } |
112 } |
116 User::After(1000 * 200); // 200 mS |
113 User::After(1000 * 200); // 200 mS |
117 } |
114 } |
118 while (retryCounter); |
115 while (retryCounter); |
266 do |
259 do |
267 { |
260 { |
268 err = iSbcInterface->ReadCapacity10L(lastLba, blockLength); |
261 err = iSbcInterface->ReadCapacity10L(lastLba, blockLength); |
269 } while (err == KErrCommandStalled && stallCounter-- > 0); |
262 } while (err == KErrCommandStalled && stallCounter-- > 0); |
270 |
263 |
271 |
264 if (err) |
|
265 { |
|
266 // DoCheckConditionL clears sense error |
|
267 // Media not present will return KErrNotReady so leave here |
|
268 User::LeaveIfError(DoCheckConditionL()); |
|
269 } |
|
270 |
|
271 // update iWriteProtect |
|
272 err = MsModeSense10L(); |
272 if (err) |
273 if (err) |
273 { |
274 { |
274 if (err == KErrCommandFailed) |
275 if (err == KErrCommandFailed) |
275 { |
276 { |
276 // Clear sense error |
277 // Clear sense error |
277 DoCheckConditionL(); |
278 err = DoCheckConditionL(); |
278 } |
279 // ignore error if unsupported |
279 User::LeaveIfError(KErrAbort); |
280 if (err != KErrUnknown) |
280 } |
281 { |
281 |
282 User::LeaveIfError(err); |
282 // update iWriteProtect |
283 } |
283 err = MsModeSense10L(); |
|
284 if (err) |
|
285 { |
|
286 if (err == KErrCommandFailed) |
|
287 { |
|
288 // Clear sense error |
|
289 DoCheckConditionL(); |
|
290 } |
284 } |
291 |
285 |
292 err = MsModeSense6L(); |
286 err = MsModeSense6L(); |
293 if (err == KErrCommandFailed) |
287 if (err == KErrCommandFailed) |
294 { |
288 { |
295 // Clear sense error |
289 // Clear sense error |
296 DoCheckConditionL(); |
290 err = DoCheckConditionL(); |
|
291 // ignore error if unsupported |
|
292 if (err != KErrUnknown) |
|
293 { |
|
294 User::LeaveIfError(err); |
|
295 } |
297 } |
296 } |
298 } |
297 } |
299 |
298 |
300 aCapsInfo.iNumberOfBlocks = lastLba + 1; |
299 aCapsInfo.iNumberOfBlocks = lastLba + 1; |
301 aCapsInfo.iBlockLength = blockLength; |
300 aCapsInfo.iBlockLength = blockLength; |
479 __MSFNLOG |
478 __MSFNLOG |
480 return iSpcInterface.PreventAllowMediumRemovalL(aPrevent); |
479 return iSpcInterface.PreventAllowMediumRemovalL(aPrevent); |
481 } |
480 } |
482 |
481 |
483 |
482 |
484 void CScsiProtocol::DoCheckConditionL() |
483 TInt CScsiProtocol::DoCheckConditionL() |
485 { |
484 { |
486 __MSFNLOG |
485 __MSFNLOG |
487 User::LeaveIfError(MsRequestSenseL()); |
486 User::LeaveIfError(MsRequestSenseL()); |
|
487 |
|
488 TInt err; |
488 |
489 |
489 // Check if init is needed |
490 // Check if init is needed |
490 if (iSenseInfo.iSenseCode == TSenseInfo::ENotReady && |
491 if (iSenseInfo.iSenseCode == TSenseInfo::ENotReady && |
491 iSenseInfo.iAdditional == TSenseInfo::EAscLogicalUnitNotReady && |
492 iSenseInfo.iAdditional == TSenseInfo::EAscLogicalUnitNotReady && |
492 iSenseInfo.iQualifier == TSenseInfo::EAscqInitializingCommandRequired) |
493 iSenseInfo.iQualifier == TSenseInfo::EAscqInitializingCommandRequired) |
493 { |
494 { |
494 // start unit |
495 // start unit |
495 TInt err = iSbcInterface->StartStopUnitL(ETrue); |
496 err = iSbcInterface->StartStopUnitL(ETrue); |
496 |
|
497 if (err) |
497 if (err) |
498 { |
498 { |
499 User::LeaveIfError(MsRequestSenseL()); |
499 User::LeaveIfError(MsRequestSenseL()); |
500 } |
500 } |
501 |
501 } |
502 } |
502 |
503 |
503 err = GetSystemWideSenseError(iSenseInfo); |
504 TInt r = GetSystemWideSenseError(iSenseInfo); |
504 |
505 |
505 TScsiState nextState = iState; |
506 if (((r == KErrNotReady) && (iState == EConnected)) || |
506 if (err == KErrDisconnected) |
507 r == KErrDisconnected) |
507 { |
508 { |
508 nextState = EDisconnected; |
509 CompleteNotifyChangeL(); |
509 } |
510 } |
510 else if (err == KErrNotReady) |
|
511 { |
|
512 nextState = EMediaNotPresent; |
|
513 } |
|
514 else |
|
515 { |
|
516 // no state change; |
|
517 } |
|
518 |
|
519 if (nextState != iState) |
|
520 { |
|
521 iMediaChangeNotifier.DoNotifyL(); |
|
522 iState = nextState; |
|
523 } |
|
524 |
|
525 return err; |
511 } |
526 } |
512 |
527 |
513 |
528 |
514 /** |
529 /** |
515 Map SCSI sense error to a system wide error code |
530 Map SCSI sense error to a system wide error code |
728 void CScsiProtocol::DoScsiReadyCheckEventL() |
743 void CScsiProtocol::DoScsiReadyCheckEventL() |
729 { |
744 { |
730 __MSFNLOG |
745 __MSFNLOG |
731 TInt err = KErrNone; |
746 TInt err = KErrNone; |
732 |
747 |
733 if(iFsm->IsRemovableMedia() || iState == EDisconnected) |
748 if(iFsm->IsRemovableMedia() || iState != EConnected) |
734 { |
749 { |
735 iFsm->SetStatusCheck(); |
750 iFsm->SetStatusCheck(); |
736 TRAP(err, iFsm->ConnectLogicalUnitL()); |
751 TRAP(err, iFsm->ConnectLogicalUnitL()); |
737 iFsm->ClearStatusCheck(); |
752 iFsm->ClearStatusCheck(); |
738 |
753 |
758 iMediaChangeNotifier.DoNotifyL(); |
773 iMediaChangeNotifier.DoNotifyL(); |
759 } |
774 } |
760 } |
775 } |
761 } |
776 } |
762 |
777 |
763 void CScsiProtocol::CompleteNotifyChangeL() |
|
764 { |
|
765 __MSFNLOG |
|
766 if (!iFsm->IsStatusCheck()) |
|
767 { |
|
768 if (iState == EConnected) |
|
769 { |
|
770 iState = EDisconnected; |
|
771 iMediaChangeNotifier.DoNotifyL(); |
|
772 } |
|
773 } |
|
774 } |
|
775 |
778 |
776 RMediaChangeNotifier::RMediaChangeNotifier() |
779 RMediaChangeNotifier::RMediaChangeNotifier() |
777 : iRegistered(EFalse) |
780 : iRegistered(EFalse) |
778 { |
781 { |
779 __MSFNSLOG |
782 __MSFNSLOG |