sl@0: // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Class implementation of CDriveManager and CMassStorageDrive. sl@0: // sl@0: // sl@0: sl@0: sl@0: sl@0: /** sl@0: @file sl@0: @internalTechnology sl@0: */ sl@0: sl@0: #include sl@0: #include sl@0: sl@0: sl@0: #include "usbmsshared.h" sl@0: #include "msctypes.h" sl@0: sl@0: #include "drivepublisher.h" sl@0: #include "drivemanager.h" sl@0: #include "debug.h" sl@0: #include "msdebug.h" sl@0: sl@0: sl@0: void TMediaParams::Init(TLocalDriveCapsV4& aCaps) sl@0: { sl@0: iSize = aCaps.MediaSizeInBytes(); sl@0: TInt64 driveBlocks = iSize / MAKE_TINT64(0, KDefaultBlockSize); sl@0: iNumBlocks = I64LOW(driveBlocks); sl@0: iMediaAtt = aCaps.iMediaAtt; sl@0: } sl@0: sl@0: sl@0: void TLocalDriveRef::SetDriveState(TDriveState aState) sl@0: { sl@0: if (iDriveState != aState) sl@0: { sl@0: CMountCB* mount = iProxyDrive.Mount(); sl@0: __ASSERT_DEBUG(mount != NULL, User::Invariant()); sl@0: if (mount) sl@0: { sl@0: if (!IsActive(iDriveState) && IsActive(aState)) sl@0: { sl@0: mount->IncLock(); sl@0: } sl@0: else if (IsActive(iDriveState) && !IsActive(aState)) sl@0: { sl@0: mount->DecLock(); sl@0: } sl@0: __PRINT1(_L("SetDriveState: LockStatus=%d\n"), mount->LockStatus()); sl@0: } sl@0: sl@0: iDriveState = aState; sl@0: iDriveStateChangedPublisher.DriveStateChanged(); sl@0: } sl@0: } sl@0: sl@0: sl@0: TInt TLocalDriveRef::Read(const TInt64& aPos, TInt aLength, TDes8& aBuf, TBool aWholeMedia) sl@0: { sl@0: __MSFNLOG sl@0: sl@0: TInt err = KErrUnknown; // never return this sl@0: sl@0: if(aWholeMedia) sl@0: { sl@0: err = iProxyDrive.Read(aPos, aLength, &aBuf, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia); sl@0: } sl@0: else sl@0: { sl@0: err = iProxyDrive.Read(aPos, aLength, aBuf); sl@0: } sl@0: sl@0: if (err == KErrLocked) sl@0: { sl@0: SetDriveState(TLocalDriveRef::ELocked); sl@0: } sl@0: sl@0: return err; sl@0: } sl@0: sl@0: sl@0: TInt TLocalDriveRef::Write(const TInt64& aPos, TDesC8& aBuf, TBool aWholeMedia) sl@0: { sl@0: TInt err = KErrNone; sl@0: sl@0: TDriveState oldState = iDriveState; sl@0: if (oldState != EActive) sl@0: { sl@0: // SCSI hasn't called SetCritical sl@0: SetDriveState(EActive); sl@0: } sl@0: sl@0: if (aWholeMedia) sl@0: { sl@0: err = iProxyDrive.Write(aPos, aBuf.Length(), &aBuf, KLocalMessageHandle, 0, RLocalDrive::ELocDrvWholeMedia); sl@0: } sl@0: else sl@0: { sl@0: err = iProxyDrive.Write(aPos,aBuf); sl@0: } sl@0: sl@0: if (err == KErrLocked) sl@0: { sl@0: SetDriveState(ELocked); sl@0: } sl@0: else if (oldState != EActive) sl@0: { sl@0: SetDriveState(oldState); sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Checks the Media Changed flag, and optionally resets it. sl@0: @return The state of the Media Changed flag. sl@0: @param aReset If true, the Media Changed flag is reset to EFalse. sl@0: */ sl@0: TBool TLocalDriveRef::IsMediaChanged(TBool aReset) sl@0: { sl@0: __MSFNLOG sl@0: TBool mediaChanged = iMediaChanged; sl@0: if (aReset) sl@0: { sl@0: iMediaChanged = EFalse; sl@0: } sl@0: return mediaChanged; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Set the Drive State to Active or Idle. sl@0: @return KErrNone on success, KErrNotReady if media not present, KErrDisMounted if not mounted sl@0: @param aCritical ETrue for Active, EFalse for Idle sl@0: */ sl@0: TInt TLocalDriveRef::SetCritical(TBool aCritical) sl@0: { sl@0: __MSFNLOG sl@0: TInt err = KErrNone; sl@0: if (iDriveState == EMediaNotPresent) sl@0: { sl@0: err = KErrNotReady; sl@0: } sl@0: else sl@0: { sl@0: SetDriveState(aCritical ? EActive : EIdle); sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Provides an interface to CProxyDrive::Caps that hides the sl@0: package buffer. sl@0: @return KErrNone on success, otherwise system wide error code sl@0: @param aInfo sl@0: */ sl@0: TInt TLocalDriveRef::Caps(TLocalDriveCapsV4& aInfo) sl@0: { sl@0: __MSFNLOG sl@0: TLocalDriveCapsV4Buf buf; sl@0: buf.FillZ(); sl@0: sl@0: __PRINT(_L("CMassStorageDrive::DoCaps calling Caps\n")); sl@0: TInt err = iProxyDrive.Caps(buf); sl@0: __PRINT1(_L("CMassStorageDrive::DoCaps: Caps returned %d\n"), err); sl@0: sl@0: if (err == KErrNone) sl@0: { sl@0: // Invoke function call operator to cast to TLocalDriveCapsV4& sl@0: aInfo = buf(); sl@0: } sl@0: sl@0: return err; sl@0: } sl@0: sl@0: sl@0: /////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: /** sl@0: @param aCritSec A Critical Section object shared by all drives. sl@0: @param aDrives Reference to the list of CMassStorageDrive objects. sl@0: @param aDriveMap Reference to array mapping lun to drive number for supported sl@0: mass storage drives. sl@0: @post Object is fully constructed sl@0: */ sl@0: CMassStorageDrive* CMassStorageDrive::NewL(RCriticalSection& aCritSec, sl@0: RDriveStateChangedPublisher& aDriveStateChangedPublisher) sl@0: { sl@0: __MSFNSLOG sl@0: CMassStorageDrive* self = new (ELeave) CMassStorageDrive(aCritSec, aDriveStateChangedPublisher); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: sl@0: CMassStorageDrive::CMassStorageDrive(RCriticalSection& aCritSec, sl@0: RDriveStateChangedPublisher& aDriveStateChangedPublisher) sl@0: : iCritSec(aCritSec), sl@0: iMountState(EDisconnected), sl@0: iDriveStateChangedPublisher(aDriveStateChangedPublisher) sl@0: { sl@0: __MSFNLOG sl@0: } sl@0: sl@0: sl@0: void CMassStorageDrive::ConstructL() sl@0: { sl@0: __MSFNLOG sl@0: iDriveMediaErrorPublisher = new (ELeave) RDriveMediaErrorPublisher(); sl@0: } sl@0: sl@0: sl@0: CMassStorageDrive::~CMassStorageDrive() sl@0: { sl@0: __MSFNLOG sl@0: delete iDriveMediaErrorPublisher; sl@0: delete iLocalDrive; sl@0: } sl@0: sl@0: /** sl@0: Read from the target drive unit. sl@0: @return KErrNone on success, otherwise system wide error code sl@0: */ sl@0: TInt CMassStorageDrive::Read(const TInt64& aPos, TInt aLength, TDes8& aBuf, TBool aWholeMedia) sl@0: { sl@0: __MSFNLOG sl@0: sl@0: TInt err = KErrUnknown; // never return this sl@0: iCritSec.Wait(); sl@0: sl@0: if(iMountState != EConnected) sl@0: { sl@0: err = KErrDisconnected; sl@0: } sl@0: else sl@0: { sl@0: err = iLocalDrive->Read(aPos, aLength, aBuf, aWholeMedia); sl@0: } sl@0: sl@0: iCritSec.Signal(); sl@0: return err; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Write to the target drive unit. sl@0: @return KErrNone on success, otherwise system wide error code sl@0: */ sl@0: TInt CMassStorageDrive::Write(const TInt64& aPos, TDesC8& aBuf, TBool aWholeMedia) sl@0: { sl@0: __MSFNLOG sl@0: sl@0: TInt err = KErrNone; sl@0: iCritSec.Wait(); sl@0: sl@0: if (iMountState != EConnected) sl@0: { sl@0: err = KErrDisconnected; sl@0: } sl@0: else sl@0: { sl@0: __ASSERT_DEBUG(iLocalDrive, User::Invariant()); sl@0: err = iLocalDrive->Write(aPos, aBuf, aWholeMedia); sl@0: } sl@0: sl@0: iCritSec.Signal(); sl@0: return err; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Provides an interface to CProxyDrive::Caps that hides the sl@0: package buffer. sl@0: @return KErrNone on success, otherwise system wide error code sl@0: @param aInfo sl@0: */ sl@0: TInt CMassStorageDrive::DoCaps(TLocalDriveCapsV4& aInfo) sl@0: { sl@0: __MSFNLOG sl@0: TInt err = KErrDisMounted; sl@0: sl@0: if (iLocalDrive) sl@0: { sl@0: err = iLocalDrive->Caps(aInfo); sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Publish media error, user should reinsert the memory card. sl@0: Similar to FAT32's TDriver::HandleCriticalError. sl@0: Note: User notification is not implemented, instead we abort and dismount. sl@0: */ sl@0: TInt CMassStorageDrive::HandleCriticalError() sl@0: { sl@0: __MSFNLOG sl@0: TRAPD(err, iDriveMediaErrorPublisher->PublishErrorL(ETrue)); sl@0: // ignore leave sl@0: err = err; sl@0: return KErrAbort; sl@0: } sl@0: sl@0: sl@0: TInt CMassStorageDrive::ClearCriticalError() sl@0: { sl@0: __MSFNLOG sl@0: TRAPD(err, iDriveMediaErrorPublisher->PublishErrorL(EFalse)); sl@0: // ignore leave sl@0: err = err; sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Checks the Media Changed flag, and optionally resets it. sl@0: @return The state of the Media Changed flag. sl@0: @param aReset If true, the Media Changed flag is reset to EFalse. sl@0: */ sl@0: TBool CMassStorageDrive::IsMediaChanged(TBool aReset) sl@0: { sl@0: __MSFNLOG sl@0: sl@0: iCritSec.Wait(); sl@0: sl@0: TBool mediaChanged = EFalse; sl@0: if (iLocalDrive) sl@0: { sl@0: mediaChanged = iLocalDrive->IsMediaChanged(aReset); sl@0: } sl@0: sl@0: iCritSec.Signal(); sl@0: sl@0: __PRINT1(_L("CMassStorageDrive::IsMediaChanged: returning %d\n"), mediaChanged); sl@0: return mediaChanged; sl@0: } sl@0: sl@0: /** sl@0: Set the Drive State to Active or Idle. sl@0: @return KErrNone on success, KErrNotReady if media not present, KErrDisMounted if not mounted sl@0: @param aCritical ETrue for Active, EFalse for Idle sl@0: */ sl@0: TInt CMassStorageDrive::SetCritical(TBool aCritical) sl@0: { sl@0: __MSFNLOG sl@0: sl@0: TInt err = KErrDisMounted; sl@0: iCritSec.Wait(); sl@0: if (iLocalDrive) sl@0: { sl@0: err = iLocalDrive->SetCritical(aCritical); sl@0: } sl@0: sl@0: iCritSec.Signal(); sl@0: return err; sl@0: } sl@0: sl@0: /** sl@0: Set the mount state sl@0: */ sl@0: void CMassStorageDrive::SetMountConnectedL(CProxyDrive& aProxyDrive, sl@0: TBool& aMediaChanged, sl@0: RDriveStateChangedPublisher& aDriveStateChangedPublisher) sl@0: { sl@0: __MSFNLOG sl@0: TLocalDriveRef* localDrive = NULL; sl@0: sl@0: __PRINT(_L("SetMountConnectedL entering critical section\n")); sl@0: iCritSec.Wait(); // note: signalled in SetMountState sl@0: sl@0: TRAPD(err, localDrive = new (ELeave) TLocalDriveRef(aProxyDrive, sl@0: aMediaChanged, sl@0: aDriveStateChangedPublisher)); sl@0: if (err) sl@0: { sl@0: iCritSec.Signal(); sl@0: User::Leave(err); sl@0: } sl@0: iLocalDrive = localDrive; sl@0: SetMountState(EConnected, ETrue); sl@0: } sl@0: sl@0: /** sl@0: @return KErrNone sl@0: @param aNewState sl@0: @param aLocalDrive Only provide this if aNewState is EConnected. sl@0: */ sl@0: void CMassStorageDrive::SetMountState(TMountState aNewState, TBool aCriticalSection/*=EFalse*/) sl@0: { sl@0: __MSFNLOG sl@0: if(iMountState == aNewState) sl@0: { sl@0: __PRINT(_L("SetMountState: No change\n")); sl@0: } sl@0: else sl@0: { sl@0: // If called from SetMountConnected, already in critical section, sl@0: // otherwise, must enter it here. sl@0: if (!aCriticalSection) sl@0: { sl@0: iCritSec.Wait(); sl@0: } sl@0: sl@0: switch(aNewState) sl@0: { sl@0: case EDisconnected: sl@0: delete iLocalDrive; sl@0: iLocalDrive = NULL; sl@0: break; sl@0: sl@0: case EConnected: sl@0: case EDisconnecting: sl@0: case EConnecting: sl@0: // Do not change iLocalDrive for these state changes sl@0: break; sl@0: } sl@0: sl@0: iMountState = aNewState; sl@0: __PRINT1(_L("SetMountState: state=%d\n"), iMountState); sl@0: sl@0: iDriveStateChangedPublisher.DriveStateChanged(); sl@0: iCritSec.Signal(); sl@0: __PRINT(_L("SetMountState has left the critical section\n")); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: @return Current drive media state sl@0: */ sl@0: TLocalDriveRef::TDriveState CMassStorageDrive::DriveState() const sl@0: { sl@0: __MSFNSLOG sl@0: return iLocalDrive ? iLocalDrive->DriveState() : TLocalDriveRef::EErrDisMounted; sl@0: } sl@0: sl@0: /** sl@0: Check for media not present, and return the drive state. sl@0: @return Current drive media state sl@0: */ sl@0: TLocalDriveRef::TDriveState CMassStorageDrive::CheckDriveState() sl@0: { sl@0: __MSFNLOG sl@0: TLocalDriveRef::TDriveState state = TLocalDriveRef::EErrDisMounted; sl@0: iCritSec.Wait(); sl@0: sl@0: if (iLocalDrive) sl@0: { sl@0: TInt err = KErrGeneral; sl@0: TLocalDriveCapsV4 caps; sl@0: sl@0: FOREVER sl@0: { sl@0: // Initialise in case Caps() fails sl@0: caps.iType = ::EMediaNotPresent; sl@0: err = DoCaps(caps); sl@0: sl@0: __PRINTERR(_L("CheckDriveState: DoCaps err=%d\n"), err); sl@0: if (err == KErrNotReady || (err == KErrNone && caps.iType == ::EMediaNotPresent)) sl@0: { sl@0: __PRINT(_L("CheckDriveState: detected MediaNotPresent\n")); sl@0: sl@0: SetDriveState(TLocalDriveRef::EMediaNotPresent); sl@0: sl@0: if (HandleCriticalError() == KErrAbort) sl@0: break; sl@0: } sl@0: else sl@0: { sl@0: ClearCriticalError(); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: if (err == KErrNone && caps.iType != ::EMediaNotPresent) sl@0: { sl@0: iMediaParams.Init(caps); sl@0: TLocalDriveRef::TDriveState driveState = TLocalDriveRef::EIdle; sl@0: sl@0: if (iLocalDrive->DriveState() == TLocalDriveRef::EMediaNotPresent) sl@0: { sl@0: __PRINT(_L("CheckDriveState: detected media inserted\n")); sl@0: } sl@0: else if (iLocalDrive->DriveState() == TLocalDriveRef::ELocked && sl@0: !(caps.iMediaAtt & KMediaAttLocked)) sl@0: { sl@0: __PRINT(_L("CheckDriveState: detected media unlocked\n")); sl@0: } sl@0: else if (caps.iMediaAtt & KMediaAttLocked) sl@0: { sl@0: __PRINT(_L("CheckDriveState: detected media locked\n")); sl@0: driveState = TLocalDriveRef::ELocked; sl@0: } sl@0: SetDriveState(driveState); sl@0: } sl@0: sl@0: // Get the current state sl@0: state = iLocalDrive->DriveState(); sl@0: } sl@0: sl@0: iCritSec.Signal(); sl@0: sl@0: return state; sl@0: } sl@0: sl@0: sl@0: /** sl@0: @param aNewState sl@0: */ sl@0: void CMassStorageDrive::SetDriveState(TLocalDriveRef::TDriveState aNewState) sl@0: { sl@0: __MSFNLOG sl@0: __ASSERT_DEBUG(aNewState == TLocalDriveRef::EIdle || sl@0: (iMountState == EConnected && NULL != iLocalDrive) || sl@0: (iMountState == EDisconnecting && NULL != iLocalDrive), sl@0: User::Invariant()); sl@0: sl@0: if (!iLocalDrive) sl@0: { sl@0: __PRINT(_L("SetDriveState: Drive not mounted.\n")); sl@0: } sl@0: else sl@0: { sl@0: iLocalDrive->SetDriveState(aNewState); sl@0: __PRINT2(_L("SetDriveState: %d->%d\n"), iLocalDrive->iDriveState, aNewState); sl@0: } sl@0: } sl@0: sl@0: sl@0: ///////////////////////////////////////////////////////////////// sl@0: sl@0: /** sl@0: Construct a CDriveManager object. sl@0: @param aDriveMap Reference to array mapping lun to drive number for supported sl@0: mass storage drives. sl@0: */ sl@0: CDriveManager* CDriveManager::NewL(const TLunToDriveMap& aDriveMap) sl@0: { sl@0: __MSFNSLOG sl@0: __PRINT1(_L("CDriveManager::NewL - %d drives\n"), aDriveMap.Count()); sl@0: sl@0: CDriveManager* self = new (ELeave) CDriveManager(aDriveMap.Count() -1); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aDriveMap); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: CDriveManager::CDriveManager(TLun aMaxLun) sl@0: : iMaxLun(aMaxLun) sl@0: { sl@0: __MSFNLOG sl@0: } sl@0: sl@0: /** sl@0: Construct a CDriveManager object. sl@0: */ sl@0: void CDriveManager::ConstructL(const TLunToDriveMap& aDriveMap) sl@0: { sl@0: __MSFNLOG sl@0: User::LeaveIfError(iDriveCritSec.CreateLocal()); sl@0: sl@0: iDriveStateChangedPublisher = new (ELeave) RDriveStateChangedPublisher(iDrives, aDriveMap); sl@0: sl@0: iDrives.Reserve(iMaxLun + 1); sl@0: sl@0: for (TLun lun = 0; lun < iMaxLun + 1; lun++) sl@0: { sl@0: iDrives.Append(CMassStorageDrive::NewL(iDriveCritSec, sl@0: *iDriveStateChangedPublisher)); sl@0: } sl@0: sl@0: // Publish initial drive state sl@0: if (iDrives.Count() > 0) sl@0: { sl@0: iDriveStateChangedPublisher->DriveStateChanged(); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Destructor sl@0: */ sl@0: CDriveManager::~CDriveManager() sl@0: { sl@0: __MSFNLOG sl@0: iDrives.ResetAndDestroy(); sl@0: delete iDriveStateChangedPublisher; sl@0: iDriveCritSec.Close(); sl@0: } sl@0: sl@0: /** sl@0: Set the mount state to Connected and specify the Proxy Drive. sl@0: @return KErrNone on success, otherwise system wide error code sl@0: @param aDrive The mounted Proxy Drive sl@0: @param aLun The Logical Drive Unit identifier (0..numDrives-1) sl@0: @pre If the Mount State is Connected, then aDrive must be the sl@0: same as it was the last time this function was called. sl@0: @post The Mount State will be Connected. sl@0: */ sl@0: void CDriveManager::RegisterDriveL(CProxyDrive& aProxyDrive, TBool& aMediaChanged, TLun aLun) sl@0: { sl@0: __MSFNLOG sl@0: __PRINT1(_L("Lun=%d \n"),aLun); sl@0: CMassStorageDrive* drive = Drive(aLun); sl@0: drive->SetMountConnectedL(aProxyDrive, aMediaChanged, *iDriveStateChangedPublisher); sl@0: } sl@0: sl@0: /** sl@0: Set the mount state to Disconnected. sl@0: @return KErrNone on success, otherwise system wide error code sl@0: @param aLun The Logical Drive Unit identifier (0..numDrives-1) sl@0: @post The Mount State will be Disconnected. sl@0: */ sl@0: void CDriveManager::DeregisterDrive(TLun aLun) sl@0: { sl@0: __MSFNLOG sl@0: CMassStorageDrive* drive = Drive(aLun); sl@0: drive->SetMountDisconnected(); sl@0: } sl@0: sl@0: /** sl@0: Return a pointer to the drive specified aLun, or NULL if aLun is invalid. sl@0: sl@0: @return Pointer to the specified drive, or NULL. sl@0: @param aLun The Logical Drive Unit identifier (0..numDrives-1) sl@0: @param aError KErrNone on success, KErrArgument if NULL is returned. sl@0: */ sl@0: CMassStorageDrive* CDriveManager::Drive(TLun aLun) const sl@0: { sl@0: __MSFNSLOG sl@0: __ASSERT_DEBUG(aLun < iDrives.Count(), User::Invariant()); sl@0: return iDrives[aLun]; sl@0: } sl@0: sl@0: /** sl@0: Checks the Media Changed flag, and optionally resets it. sl@0: @return The state of the Media Changed flag. sl@0: @param aLun The Logical Drive Unit identifier (0..numDrives-1) sl@0: @param aReset If true, the Media Changed flag is reset to EFalse. sl@0: */ sl@0: TBool CDriveManager::IsMediaChanged(TLun aLun, TBool aReset) sl@0: { sl@0: __MSFNLOG sl@0: CMassStorageDrive* drive = Drive(aLun); sl@0: return drive->IsMediaChanged(aReset); sl@0: } sl@0: sl@0: /** sl@0: Set the Drive State to Active or Idle. sl@0: Ref: 3.6.3.2 - PREVENT_MEDIUM_REMOVAL sl@0: @return KErrNone on success, otherwise system wide error code sl@0: @param aLun The Logical Drive Unit identifier (0..numDrives-1) sl@0: @param aCritical ETrue for Active, EFalse for Idle sl@0: */ sl@0: TInt CDriveManager::SetCritical(TLun aLun, TBool aCritical) sl@0: { sl@0: __MSFNLOG sl@0: TInt err = KErrUnknown; // never return this sl@0: sl@0: TLun i = aLun; sl@0: TLun cnt = aLun + 1; sl@0: sl@0: if (aLun == KAllLuns) sl@0: { sl@0: i = 0; sl@0: cnt = iMaxLun + 1; sl@0: } sl@0: sl@0: for(; i < cnt; i++) sl@0: { sl@0: CMassStorageDrive* drive = Drive(i); sl@0: err = drive->SetCritical(aCritical); sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: void CDriveManager::Connect() sl@0: { sl@0: __FNLOG("CDriveManager::Connect"); sl@0: TLun lun = iMaxLun; sl@0: do sl@0: { sl@0: Connect(lun); sl@0: } sl@0: while(--lun >= 0); sl@0: } sl@0: sl@0: /** sl@0: Inititiate transition to Connected. sl@0: @return KErrNone on success, otherwise system wide error code sl@0: @param aLun The Logical Drive Unit identifier (0..numDrives-1) sl@0: @post The Mount State will be Connected or Connecting. sl@0: */ sl@0: void CDriveManager::Connect(TLun aLun) sl@0: { sl@0: __MSFNLOG sl@0: CMassStorageDrive* drive = Drive(aLun); sl@0: sl@0: __PRINT2(_L("CDriveManager::Connect lun=%d, mountState=%d\n"), aLun, drive->MountState()); sl@0: sl@0: switch(drive->MountState()) sl@0: { sl@0: case CMassStorageDrive::EDisconnected: sl@0: drive->SetMountConnecting(); sl@0: break; sl@0: case CMassStorageDrive::EDisconnecting: sl@0: drive->SetMountConnected(); sl@0: break; sl@0: case CMassStorageDrive::EConnected: sl@0: case CMassStorageDrive::EConnecting: sl@0: default: sl@0: // do nothing sl@0: break; sl@0: } sl@0: } sl@0: sl@0: void CDriveManager::Disconnect() sl@0: { sl@0: __FNLOG("CDriveManager::Disconnect"); sl@0: TLun lun = iMaxLun; sl@0: do sl@0: { sl@0: Disconnect(lun); sl@0: } sl@0: while(--lun >= 0); sl@0: } sl@0: sl@0: /** sl@0: Inititiate transition to Disconnected. sl@0: @return KErrNone on success, otherwise system wide error code sl@0: @param aLun The Logical Drive Unit identifier (0..numDrives-1) sl@0: @post The Mount State will be Disconnected or Disconnecting. sl@0: */ sl@0: void CDriveManager::Disconnect(TLun aLun) sl@0: { sl@0: __MSFNLOG sl@0: CMassStorageDrive* drive = Drive(aLun); sl@0: switch (drive->MountState()) sl@0: { sl@0: case CMassStorageDrive::EConnected: sl@0: drive->SetMountDisconnecting(); sl@0: break; sl@0: case CMassStorageDrive::EConnecting: sl@0: drive->SetMountDisconnected(); sl@0: break; sl@0: case CMassStorageDrive::EDisconnected: sl@0: case CMassStorageDrive::EDisconnecting: sl@0: // do nothing sl@0: break; sl@0: } sl@0: }