diff -r fc55edbf3919 -r 5802e2ce68ed userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp --- 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)