diff -r 000000000000 -r a41df078684a kernel/eka/drivers/pbus/pbusmedia.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/drivers/pbus/pbusmedia.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,247 @@ +// Copyright (c) 1998-2009 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" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32\drivers\pbus\pbusmedia.cpp +// +// + +#include + +void mediaCallBack(TAny* aPtr, TInt aReason, TAny* a1, TAny* a2) + { + DPBusPrimaryMedia* pM=(DPBusPrimaryMedia*)aPtr; + __KTRACE_OPT(KLOCDRV,Kern::Printf("mediaCallBack media %d, reason %d, a1=0x%x, a2=0x%x",pM->iMediaId,aReason,a1,a2)); + switch (aReason) + { + case TPBusCallBack::EPBusStateChange: + pM->PBusStateChange((TInt)a1,(TInt)a2); + break; + } + } + +/** + Constructor for DPBusPrimaryMedia. Initializes the iSocket with aSocket. + @param aSocket Pointer to DPBusSocket object + @see DPBusPrimaryMedia::iSocket + */ + +DPBusPrimaryMedia::DPBusPrimaryMedia(DPBusSocket* aSocket) + : iSocket(aSocket) + { + } +/** + This function install a media call back for a removable media device. + @param aDevice Local media ID. + @param aMediaId Media Id (unique for a media subsystem) + @param aLastMediaId This indicates number of used media ids+ number of DMedia objects to be associated with the media driver + @return KErrNone if successful, + otherwise one of the other system wide error codes. + @see DPrimaryMediaBase::Create() + */ +TInt DPBusPrimaryMedia::Create(TMediaDevice aDevice, TInt aMediaId, TInt aLastMediaId) + { + // Permanently install a media call back if for a removable media device + TInt r=KErrArgument; + iPBusState=EPBusCardAbsent; + if (__IS_REMOVABLE(aDevice)) + { + iBusCallBack.iFunction=mediaCallBack; + iBusCallBack.iPtr=this; + iBusCallBack.SetSocket(iSocket->iSocketNumber); + iDfcQ=&iSocket->iDfcQ; + r=DPrimaryMediaBase::Create(aDevice,aMediaId,aLastMediaId); + if (r==KErrNone) + { + iBusCallBack.Add(); + iPBusState=iSocket->State(); + iMsgQ.Receive(); + } + } + return r; + } + +/** + Checks the PBUS state. + @return KErrNone if successful, + KErrNotReady if card is absent. + @see TPBusState + */ +TInt DPBusPrimaryMedia::QuickCheckStatus() + { + TInt r=KErrNone; + if (iSocket && iSocket->State()==EPBusCardAbsent) + r=KErrNotReady; + __KTRACE_OPT(KLOCDRV,Kern::Printf("DPBusPrimaryMedia::QuickCheckStatus media %d returns %d",iMediaId,r)); + return r; + } + +/** + This function is called by the local media device driver to force a remount of the media device. + @param aFlags Corresponds to force media change. + @return KErrNone if successful, + otherwise one of the other system wide error codes. + @see TForceMediaChangeFlags + */ +TInt DPBusPrimaryMedia::ForceMediaChange(TInt aFlags) + { + if ((aFlags != KMediaRemountForceMediaChange) || (iPBusState == EPBusCardAbsent)) + { + TInt pbusState = iPBusState; + + // This should ensure NotifyMediaChange() is called for ALL primary media attached to this socket + iSocket->ChangeState(EPBusCardAbsent, KErrNotReady); + + // If a request was cancelled it's possible that the socket controller has been left in an + // unusable state which might cause the next request to fail, so power down the socket to be safe + iSocket->ResetSocket(EFalse); + + iSocket->ChangeState(pbusState == EPBusCardAbsent ? EPBusCardAbsent : EPBusOff, KErrNotReady); + + return KErrCompletion; + } + + iSocket->ForceMediaChange(); + return KErrNone; + } + +/** + Called by clients to power up the PBUS. + @return KErrNone if successful, + otherwise one of the other system wide error codes. + @see DPBusSocket::PowerUp() + */ +TInt DPBusPrimaryMedia::InitiatePowerUp() + { + return iSocket->PowerUp(); + } + +/** + Flags the media driver as entering a critical part of its processing. + @return KErrNone if successful, + otherwise one of the other system wide error codes. + @see DPBusSocket::InCritical() + */ +TInt DPBusPrimaryMedia::DoInCritical() + { + return iSocket->InCritical(); + } + +/** + Flags the media driver as leaving a critical part of its processing. + @return KErrNone if successful, + otherwise one of the other system wide error codes. + @see DPBusSocket::EndInCritical() + */ +void DPBusPrimaryMedia::DoEndInCritical() + { + iSocket->EndInCritical(); + } + +/** + Sets the incremental value of current consumption to aCurrent. + @param aCurrent Delta Current in Milliamps. + @see DPBusSocket::DeltaCurrentConsumption() + */ +void DPBusPrimaryMedia::DeltaCurrentConsumption(TInt aCurrent) + { + iSocket->DeltaCurrentConsumption(aCurrent); + } + +/** + Gets the default drive capability/attributes. + @param aCaps A reference to a client-supplied TLocalDriveCapsV2 class to be filled by this function. + @see TLocalDriveCapsV2 + @see TMediaType + */ +void DPBusPrimaryMedia::DefaultDriveCaps(TLocalDriveCapsV2& aCaps) + { + // aCaps is zeroed beforehand + aCaps.iType = EMediaNotPresent; + aCaps.iDriveAtt = KDriveAttLocal|KDriveAttRemovable; + } + +/** + Checks whether it is a removable media device or not. + @param aSocketNum This will be updated with socket number + @return ETrue if Removable Device, EFalse if the device is Non-Removable. + */ +TBool DPBusPrimaryMedia::IsRemovableDevice(TInt& aSocketNum) + { + aSocketNum=iSocket->iSocketNumber; + return(ETrue); + } + +void DPBusPrimaryMedia::PBusStateChange(TInt aState, TInt anError) + { + // receive power down and media change notifications + __KTRACE_OPT(KLOCDRV,Kern::Printf("DPBusPrimaryMedia(%d)::PBusStateChange state %d, err %d",iMediaId,aState,anError)); + if (aState!=iPBusState) + { + TInt oldState = iPBusState; + iPBusState=aState; + switch (aState) + { + case EPBusCardAbsent: + NotifyMediaChange(); + break; + case EPBusOff: + switch (anError) + { + case KErrNone: + // machine power down + NotifyPowerDown(); + break; + case KErrTimedOut: + // machine power down + NotifyPowerDown(); + if(oldState == EPBusCardAbsent) + { + // powering down after power up with no card present. + // ...to prevent the bus powering up again, maintain + // the card state as absent. A media change will + // update the status to allow the bus to power up. + iPBusState = EPBusCardAbsent; + } + break; + case KErrNotReady: + // card detected following door close + NotifyMediaPresent(); + break; + case KErrAbort: + NotifyEmergencyPowerDown(); + break; + default: + if (iState==EPoweringUp1 || iState==EPoweringUp2) + PowerUpComplete(anError); + break; + } + case EPBusPoweringUp: + // no action required + break; + case EPBusOn: + // bus is now powered up + if (iState==EPoweringUp1 || iState==EPoweringUp2) + PowerUpComplete(anError); + break; + case EPBusPsuFault: + NotifyPsuFault(anError); + break; + case EPBusPowerUpPending: + // no action required + break; + default: + break; + } + } + } +