userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp
changeset 124 5802e2ce68ed
parent 90 947f0dc9f7a8
child 127 e408fc570bb5
--- a/userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp	Fri Apr 23 22:20:31 2010 +0100
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp	Fri Apr 23 22:26:35 2010 +0100
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of the License "Eclipse Public License v1.0"
@@ -26,8 +26,6 @@
 #include "shared.h"
 #include "msgservice.h"
 
-#include "mscutils.h"
-
 #include "mtransport.h"
 #include "mprotocol.h"
 #include "tscsiclientreq.h"
@@ -45,7 +43,6 @@
 #include "usbmshostpanic.h"
 
 
-
 /**
 Create the CScsiProtocol object.
 
@@ -68,8 +65,8 @@
 void CScsiProtocol::ConstructL(TLun aLun)
     {
 	__MSFNLOG
+	// iState = EEntry;
     iFsm = CMassStorageFsm::NewL(*this);
-	iState = EDisconnected;
 
     const TInt blockLength = 0x200;
 
@@ -99,6 +96,7 @@
 void CScsiProtocol::InitialiseUnitL()
     {
 	__MSFNLOG
+    iState = EDisconnected;
 
 	// A device may take time to mount the media. If the device fails attempt to
 	// retry the connection for a number of seconds
@@ -106,13 +104,16 @@
     do
         {
         retryCounter--;
-        iFsm->ConnectLogicalUnitL();
-        iState = iFsm->IsConnected() ? EConnected: EDisconnected;
-
-        if (iState == EConnected)
+        TInt err = iFsm->ConnectLogicalUnitL();
+        if (err == KErrNotSupported)
             {
             break;
             }
+        if (iFsm->IsConnected())
+            {
+            iState = EConnected;
+            break;
+            }
         User::After(1000 * 200);    // 200 mS
         }
     while (retryCounter);
@@ -136,6 +137,10 @@
                           TInt aLength)
     {
 	__MSFNLOG
+
+    if (!iSbcInterface)
+        User::Leave(KErrNotSupported);
+
     if(!IsConnected())
 		User::Leave(KErrNotReady);
     iSbcInterface->iBlockTransfer.ReadL(*this, aPos, aLength, aBuf);
@@ -145,6 +150,9 @@
 void CScsiProtocol::BlockReadL(TPos aPos, TDes8& aCopybuf, TInt aLen)
     {
 	__MSFNLOG
+    if (!iSbcInterface)
+        User::Leave(KErrNotSupported);
+
 	__ASSERT_DEBUG(aPos % iSbcInterface->iBlockTransfer.BlockLength() == 0,
                    User::Panic(KUsbMsHostPanicCat, EBlockDevice));
 
@@ -162,8 +170,7 @@
     if (err)
         {
         __SCSIPRINT1(_L("READ(10) Err=%d"), err);
-        DoCheckConditionL();
-        User::LeaveIfError(KErrAbort);
+        User::LeaveIfError(DoCheckConditionL());
         }
 
     // handle residue
@@ -189,8 +196,7 @@
         TInt err = iSbcInterface->Read10L(aPos/blockLen, aCopybuf, len);
         if (err)
             {
-            DoCheckConditionL();
-            User::LeaveIfError(KErrAbort);
+            User::LeaveIfError(DoCheckConditionL());
             }
         }
     }
@@ -201,6 +207,9 @@
                            TInt aLength)
     {
 	__MSFNLOG
+    if (!iSbcInterface)
+        User::Leave(KErrNotSupported);
+
     if(!IsConnected())
 		User::Leave(KErrNotReady);
     iSbcInterface->iBlockTransfer.WriteL(*this, aPosition, aLength, aBuf);
@@ -210,6 +219,9 @@
 void CScsiProtocol::BlockWriteL(TPos aPos, TDesC8& aCopybuf, TUint aOffset, TInt aLen)
     {
 	__MSFNLOG
+    if (!iSbcInterface)
+        User::Leave(KErrNotSupported);
+
 	__ASSERT_DEBUG(aPos % iSbcInterface->iBlockTransfer.BlockLength() == 0,
                    User::Panic(KUsbMsHostPanicCat, EBlockDevice));
     const TInt blockLen = iSbcInterface->iBlockTransfer.BlockLength();
@@ -217,8 +229,7 @@
 	TInt err = iSbcInterface->Write10L(aPos/blockLen, aCopybuf, aOffset, len);
     if (err)
         {
-        DoCheckConditionL();
-        User::LeaveIfError(KErrAbort);
+        User::LeaveIfError(DoCheckConditionL());
         }
 
     while (len != aLen)
@@ -242,8 +253,7 @@
         TInt err = iSbcInterface->Write10L(aPos/blockLen, buf, aOffset, len);
         if (err)
             {
-            DoCheckConditionL();
-            User::LeaveIfError(KErrAbort);
+            User::LeaveIfError(DoCheckConditionL());
             }
         }
     }
@@ -257,6 +267,17 @@
         DoScsiReadyCheckEventL();
         }
 
+    if (!iSbcInterface)
+        {
+        aCapsInfo.iMediaType = EMediaCdRom;
+        aCapsInfo.iNumberOfBlocks = 0;
+        aCapsInfo.iBlockLength = 0;
+        aCapsInfo.iWriteProtect = ETrue;
+        return;
+        }
+
+    aCapsInfo.iMediaType = EMediaHardDisk;
+
 	TLba lastLba;
 	TUint32 blockLength;
 
@@ -268,15 +289,11 @@
         err = iSbcInterface->ReadCapacity10L(lastLba, blockLength);
         } while (err == KErrCommandStalled && stallCounter-- > 0);
 
-
     if (err)
         {
-        if (err == KErrCommandFailed)
-            {
-            // Clear sense error
-            DoCheckConditionL();
-            }
-        User::LeaveIfError(KErrAbort);
+        // DoCheckConditionL clears sense error
+        // Media not present will return KErrNotReady so leave here
+        User::LeaveIfError(DoCheckConditionL());
         }
 
     // update iWriteProtect
@@ -286,14 +303,24 @@
         if (err == KErrCommandFailed)
             {
             // Clear sense error
-            DoCheckConditionL();
+            err = DoCheckConditionL();
+            // ignore error if unsupported
+            if (err != KErrUnknown)
+                {
+                User::LeaveIfError(err);
+                }
             }
 
         err = MsModeSense6L();
         if (err == KErrCommandFailed)
             {
             // Clear sense error
-            DoCheckConditionL();
+            err = DoCheckConditionL();
+            // ignore error if unsupported
+            if (err != KErrUnknown)
+                {
+                User::LeaveIfError(err);
+                }
             }           
         }
 
@@ -352,23 +379,38 @@
 
     if (info.iPeripheralQualifier != 0 && info.iPeripheralQualifier != 1)
         {
-        __HOSTPRINT(_L("Peripheral Qualifier[Unknown device type]\n"))
-        return KErrUnknown;
+        __HOSTPRINT(_L("Peripheral Qualifier[Unknown device type]"))
+        err = KErrUnknown;
+        }
+    else if (info.iPeripheralDeviceType == 0)
+        {
+        // SCSI SBC Direct access device
+        iRemovableMedia = info.iRemovable;
+    
+        // SCSI Block device
+        iSbcInterface = new (ELeave) TSbcClientInterface(iSpcInterface.Transport());
+        iSbcInterface->InitBuffers(&iHeadbuf, &iTailbuf);
+        err = KErrNone;
+        }
+    else if (info.iPeripheralDeviceType == 5)
+        {
+        // SCSI MMC-2 CD-ROM device
+        __HOSTPRINT(_L("Peripheral Device Type[CD-ROM]"))
+        iRemovableMedia = info.iRemovable;
+
+        // MMC-2 is not supported. A SCSI interface call will return 
+        // KErrNotSupported. If SCSI support is extended in future then
+        // TSbcInterface class should be replaced with a proper interface class.
+        iSbcInterface = NULL;
+        err = KErrNone;
+        }
+    else
+        {
+        __HOSTPRINT(_L("Peripheral Device Type[Unsupported device type]"))
+        err = KErrUnknown;    
         }
 
-    if (info.iPeripheralDeviceType != 0)
-        {
-        __HOSTPRINT(_L("Peripheral Device Type[Unsupported device type]\n"))
-        return KErrUnknown;
-        }
-
-    iRemovableMedia = info.iRemovable;
-
-    // SCSI Block device
-    iSbcInterface = new (ELeave) TSbcClientInterface(iSpcInterface.Transport());
-    iSbcInterface->InitBuffers(&iHeadbuf, &iTailbuf);
-
-    return KErrNone;
+    return err;
     }
 
 
@@ -401,6 +443,11 @@
 TInt CScsiProtocol::MsReadCapacityL()
     {
 	__MSFNLOG
+    if (!iSbcInterface)
+        {
+        User::Leave(KErrNotSupported);
+        }
+
     // READ CAPACITY
     TUint32 blockSize;
     TUint32 lastLba;
@@ -421,6 +468,9 @@
 TInt CScsiProtocol::MsModeSense10L()
     {
 	__MSFNLOG
+    if (!iSbcInterface)
+        User::Leave(KErrNotSupported);
+
     TBool writeProtected;
     TInt err = iSbcInterface->ModeSense10L(TSbcClientInterface::EReturnAllModePages, writeProtected);
 
@@ -442,6 +492,9 @@
 TInt CScsiProtocol::MsModeSense6L()
     {
 	__MSFNLOG
+    if (!iSbcInterface)
+        User::Leave(KErrNotSupported);
+
     TBool writeProtected;
     TInt err = iSbcInterface->ModeSense6L(TSbcClientInterface::EReturnAllModePages, writeProtected);
 
@@ -463,6 +516,9 @@
 TInt CScsiProtocol::MsStartStopUnitL(TBool aStart)
     {
 	__MSFNLOG
+    if (!iSbcInterface)
+        User::Leave(KErrNotSupported);
+
     return iSbcInterface->StartStopUnitL(aStart);
     }
 
@@ -481,33 +537,52 @@
     }
 
 
-void CScsiProtocol::DoCheckConditionL()
+TInt CScsiProtocol::DoCheckConditionL()
     {
 	__MSFNLOG
     User::LeaveIfError(MsRequestSenseL());
 
+    TInt err;
+
     // Check if init is needed
     if (iSenseInfo.iSenseCode == TSenseInfo::ENotReady &&
         iSenseInfo.iAdditional == TSenseInfo::EAscLogicalUnitNotReady &&
         iSenseInfo.iQualifier == TSenseInfo::EAscqInitializingCommandRequired)
         {
-        // start unit
-        TInt err = iSbcInterface->StartStopUnitL(ETrue);
-
-        if (err)
-            {
-            User::LeaveIfError(MsRequestSenseL());
-            }
-
+		if (iSbcInterface)
+			{
+	        // start unit
+			err = iSbcInterface->StartStopUnitL(ETrue);
+	        if (err)
+		        {
+			    User::LeaveIfError(MsRequestSenseL());
+				}			
+			}
         }
 
-    TInt r = GetSystemWideSenseError(iSenseInfo);
+    err = GetSystemWideSenseError(iSenseInfo);
 
-    if (((r == KErrNotReady) && (iState == EConnected)) ||
-        r == KErrDisconnected)
-	    {
-        CompleteNotifyChangeL();
+    TScsiState nextState = iState;
+    if (err == KErrDisconnected)
+        {
+        nextState = EDisconnected;
+        }
+    else if (err == KErrNotReady)
+        {
+        nextState = EMediaNotPresent;
         }
+    else
+        {
+        // no state change;
+        }
+
+    if (nextState != iState)
+        {
+        iMediaChangeNotifier.DoNotifyL();
+        iState = nextState;
+        }
+           
+    return err;
     }
 
 
@@ -730,7 +805,7 @@
     __MSFNLOG
 	TInt err = KErrNone;
 
-	if(iFsm->IsRemovableMedia() || iState == EDisconnected)
+	if(iRemovableMedia || iState != EConnected)
         {
 		iFsm->SetStatusCheck();
 		TRAP(err, iFsm->ConnectLogicalUnitL());
@@ -760,18 +835,6 @@
         }
 	}
 
-void CScsiProtocol::CompleteNotifyChangeL()
-	{
-    __MSFNLOG
-    if (!iFsm->IsStatusCheck())
-		{
-		if (iState == EConnected)
-			{
-			iState = EDisconnected;
-            iMediaChangeNotifier.DoNotifyL();
-			}
-		}
-	}
 
 RMediaChangeNotifier::RMediaChangeNotifier()
 :   iRegistered(EFalse)