diff -r 0ffb4e86fcc9 -r a179b74831c9 kernel/eka/drivers/sdapc/d_sdapc.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/drivers/sdapc/d_sdapc.cpp Thu Aug 19 11:14:22 2010 +0300 @@ -0,0 +1,304 @@ +// Copyright (c) 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" +// 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: + + +#include +#include +#include +#include +#include + +#include "OstTraceDefinitions.h" +#ifdef OST_TRACE_COMPILER_IN_USE +#include "locmedia_ost.h" +#ifdef __VC32__ +#pragma warning(disable: 4127) // disabling warning "conditional expression is constant" +#endif +#include "d_sdapcTraces.h" +#endif + +_LIT(KLddName,"D_SDAPC"); + +const TInt KMajorVersionNumber=1; +const TInt KMinorVersionNumber=0; +const TInt KBuildVersionNumber=1; + +const TInt KSocketNumber = 0; +const TInt KStackNumber = 0; +const TInt KCardNumber = 0; + +// global Dfc Que +TDynamicDfcQue* gDfcQ; + +class DSDAuxiliaryPowerControlFactory : public DLogicalDevice +// +// LDD factory +// + { +public: + DSDAuxiliaryPowerControlFactory(); + ~DSDAuxiliaryPowerControlFactory(); + virtual TInt Install(); //overriding pure virtual + virtual void GetCaps(TDes8& aDes) const; //overriding pure virtual + virtual TInt Create(DLogicalChannelBase*& aChannel); //overriding pure virtual + }; + + +class DSDAuxiliaryPowerControl : public DLogicalChannel +// +// Logical channel +// + { +public: + DSDAuxiliaryPowerControl(); + virtual ~DSDAuxiliaryPowerControl(); + +protected: + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); + virtual void HandleMsg(class TMessageBase *); + +private: + static void BusCallBack(TAny* aPtr, TInt aReason, TAny* a1, TAny* a2); + TInt PowerUpStack(); + +private: + DMMCSocket* iSocketP; + DMMCStack* iStackP; + TSDCard* iCardP; + + DThread* iClient; + + TPBusCallBack iBusCallBack; + DSemaphore* iPowerUpSemaphore; + TBool iInitialised; + }; + + +DECLARE_STANDARD_LDD() + { + return new DSDAuxiliaryPowerControlFactory; + } + +DSDAuxiliaryPowerControlFactory::DSDAuxiliaryPowerControlFactory() +// +// Constructor +// + { + OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROLFACTORY_DSDAUXILIARYPOWERCONTROLFACTORY, "DSDAuxiliaryPowerControlFactory::DSDAuxiliaryPowerControlFactory"); + __KTRACE_OPT(KPBUS1, Kern::Printf(">DSDAuxiliaryPowerControlFactory::DSDAuxiliaryPowerControlFactory")); + iParseMask=KDeviceAllowUnit; + iUnitsMask=0xffffffff; + iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); + } + +TInt DSDAuxiliaryPowerControlFactory::Create(DLogicalChannelBase*& aChannel) +// +// Create a new DSDAuxiliaryPowerControl on this logical device +// + { + OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROLFACTORY_CREATE, "DSDAuxiliaryPowerControlFactory::Create"); + __KTRACE_OPT(KPBUS1, Kern::Printf(">DSDAuxiliaryPowerControlFactory::Create")); + aChannel=new DSDAuxiliaryPowerControl; + return aChannel ? KErrNone : KErrNoMemory; + } + +const TInt KDSDAuxiliaryPowerControlApiThreadPriority = 27; +_LIT(KDSDAuxiliaryPowerControlApiThread,"DSDAuxiliaryPowerControlApiThread"); + +TInt DSDAuxiliaryPowerControlFactory::Install() +// +// Install the LDD - overriding pure virtual +// + { + // Allocate a kernel thread to run the DFC + TInt r = Kern::DynamicDfcQCreate(gDfcQ, KDSDAuxiliaryPowerControlApiThreadPriority, KDSDAuxiliaryPowerControlApiThread); + + if (r != KErrNone) + return r; + + return SetName(&KLddName); + } + +void DSDAuxiliaryPowerControlFactory::GetCaps(TDes8& aDes) const +// +// Stub - overriding pure virtual +// + { + } + +/** + Destructor +*/ +DSDAuxiliaryPowerControlFactory::~DSDAuxiliaryPowerControlFactory() + { + OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROLFACTORY_DSDAUXILIARYPOWERCONTROLFACTORY_DTOR, "DSDAuxiliaryPowerControlFactory::~DSDAuxiliaryPowerControlFactory"); + __KTRACE_OPT(KPBUS1, Kern::Printf(">DSDAuxiliaryPowerControlFactory::~DSDAuxiliaryPowerControlFactory")); + if (gDfcQ) + gDfcQ->Destroy(); + } + +void DSDAuxiliaryPowerControl::BusCallBack(TAny* aPtr, TInt aReason, TAny* a1, TAny* a2) + { + DSDAuxiliaryPowerControl* pTest = (DSDAuxiliaryPowerControl*)aPtr; + TPBusState busState = (TPBusState) (TInt) a1; + switch (aReason) + { + case TPBusCallBack::EPBusStateChange: + if (busState != EPBusPoweringUp) + Kern::SemaphoreSignal(*(pTest->iPowerUpSemaphore)); + break; + } + } + +TInt DSDAuxiliaryPowerControl::PowerUpStack() + { + iBusCallBack.iFunction = BusCallBack; + iBusCallBack.iPtr=this; + iBusCallBack.SetSocket(iSocketP->iSocketNumber); + iBusCallBack.Add(); + TInt r = Kern::SemaphoreCreate(iPowerUpSemaphore, _L("SDPowerUpSem"), 0); + if (r == KErrNone) + { + r = iSocketP->PowerUp(); + if (r == KErrNone) + Kern::SemaphoreWait(*iPowerUpSemaphore); + } + return r; + } + +TInt DSDAuxiliaryPowerControl::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer) +// +// Create channel +// + { + OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_1, "DSDAuxiliaryPowerControl::DoCreate()"); + __KTRACE_OPT(KPBUS1, Kern::Printf(">DSDAuxiliaryPowerControl::DoCreate()")); + + if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer)) + return KErrNotSupported; + + // + // Obtain the appropriate card from the socket/stack + // + iSocketP = static_cast(DPBusSocket::SocketFromId(KSocketNumber)); + if(iSocketP == NULL) + { + OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_2, "DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain socket"); + __KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain socket")); + return KErrNoMemory; + } + + iStackP = static_cast(iSocketP->Stack(KStackNumber)); + if(iStackP == NULL) + { + OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_3, "DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain stack"); + __KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain stack")); + return KErrNoMemory; + } + + iCardP = static_cast(iStackP->CardP(KCardNumber)); + if(iCardP == NULL) + { + OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_4, "DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain card"); + __KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain card")); + return KErrNoMemory; + } + + SetDfcQ(gDfcQ); + iMsgQ.Receive(); + + // Make sure stack is powered up + TInt r = PowerUpStack(); + if (r != KErrNone && r != KErrCompletion) + { + OstTrace1( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_5, "DSDAuxiliaryPowerControl::DoCreate() : Failed To Power up stack, r = %d", r); + __KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : Failed To Power up stack, r = %d", r)); + return r; + } + + if(!iCardP->IsReady()) + { + OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_6, "DSDAuxiliaryPowerControl::DoCreate() : Card not ready"); + __KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : Card not ready")); + return KErrNotReady; + } + + if(!iCardP->ClientsRegistered()) + { + iCardP->RegisterClient(); + ((DSDIOPsu*)(iSocketP->iVcc))->Lock(); + TBool locked = ((DSDIOPsu*)(iSocketP->iVcc))->IsLocked(); + OstTrace1( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_7, "DSDAuxiliaryPowerControl::DoCreate() : PSU IsLocked(), locked = %d", locked); + __KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : PSU IsLocked(), locked = %d", locked)); + if(!locked) + return KErrNotReady; + } + + return KErrNone; + } + +DSDAuxiliaryPowerControl::DSDAuxiliaryPowerControl() +// +// Constructor +// + { + iClient=&Kern::CurrentThread(); + ((DObject*)iClient)->Open(); + } + + +DSDAuxiliaryPowerControl::~DSDAuxiliaryPowerControl() +// +// Destructor +// + { + OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DSDAUXILIARYPOWERCONTROL_DTOR, "DSDAuxiliaryPowerControl::~DSDAuxiliaryPowerControl"); + __KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::~DSDAuxiliaryPowerControl")); + iBusCallBack.Remove(); + + if (iSocketP) + iSocketP->ControlIO(DPBusSocket::EControlMediaState, (TAny*)DPBusSocket::EPeriphBusMediaNormal, NULL); + + + if(iCardP->ClientsRegistered()) + { + iCardP->DeregisterClient(); + ((DSDIOPsu*)(iSocketP->iVcc))->Unlock(); + } + + iPowerUpSemaphore->Close(NULL); + + Kern::SafeClose((DObject*&)iClient,NULL); + } + +void DSDAuxiliaryPowerControl::HandleMsg(TMessageBase* aMsg) + { + TThreadMessage& m=*(TThreadMessage*)aMsg; + TInt id=m.iValue; + + if (id==(TInt)ECloseMsg) + { + if (iSocketP) + iSocketP->ControlIO(DPBusSocket::EControlMediaState, (TAny*)DPBusSocket::EPeriphBusMediaNormal, NULL); + + m.Complete(KErrNone, EFalse); + return; + } + else if (id==KMaxTInt) + { + // DoCancel + m.Complete(KErrNone,ETrue); + return; + } + }