kernel/eka/drivers/sdapc/d_sdapc.cpp
changeset 148 31ea0f8e3c99
equal deleted inserted replaced
135:5e441a173c63 148:31ea0f8e3c99
       
     1 // Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL " http://www.eclipse.org/legal/epl-v10.html ".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 
       
    15 
       
    16 #include <kernel/kernel.h>
       
    17 #include <drivers/mmc.h>
       
    18 #include <drivers/sdcard.h>
       
    19 #include <drivers/sdio/sdio.h>
       
    20 #include <drivers/d_sdapc.h>
       
    21 
       
    22 #include "OstTraceDefinitions.h"
       
    23 #ifdef OST_TRACE_COMPILER_IN_USE
       
    24 #include "locmedia_ost.h"
       
    25 #ifdef __VC32__
       
    26 #pragma warning(disable: 4127) // disabling warning "conditional expression is constant"
       
    27 #endif
       
    28 #include "d_sdapcTraces.h"
       
    29 #endif
       
    30 
       
    31 _LIT(KLddName,"D_SDAPC");
       
    32 
       
    33 const TInt KMajorVersionNumber=1;
       
    34 const TInt KMinorVersionNumber=0;
       
    35 const TInt KBuildVersionNumber=1;
       
    36 
       
    37 const TInt KSocketNumber = 0;
       
    38 const TInt KStackNumber  = 0;
       
    39 const TInt KCardNumber   = 0;
       
    40 
       
    41 // global Dfc Que
       
    42 TDynamicDfcQue* gDfcQ;
       
    43 
       
    44 class DSDAuxiliaryPowerControlFactory : public DLogicalDevice
       
    45 //
       
    46 // LDD factory
       
    47 //
       
    48 	{
       
    49 public:
       
    50 	DSDAuxiliaryPowerControlFactory();
       
    51 	~DSDAuxiliaryPowerControlFactory();
       
    52 	virtual TInt Install(); 					//overriding pure virtual
       
    53 	virtual void GetCaps(TDes8& aDes) const;	//overriding pure virtual
       
    54 	virtual TInt Create(DLogicalChannelBase*& aChannel); 	//overriding pure virtual
       
    55 	};
       
    56 
       
    57 
       
    58 class DSDAuxiliaryPowerControl : public DLogicalChannel
       
    59 //
       
    60 // Logical channel
       
    61 //
       
    62 	{
       
    63 public:
       
    64 	DSDAuxiliaryPowerControl();
       
    65 	virtual ~DSDAuxiliaryPowerControl();
       
    66 
       
    67 protected:
       
    68 	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
       
    69 	virtual void HandleMsg(class TMessageBase *);
       
    70 
       
    71 private:
       
    72 	static void BusCallBack(TAny* aPtr, TInt aReason, TAny* a1, TAny* a2);
       
    73 	TInt PowerUpStack();
       
    74 
       
    75 private:
       
    76 	DMMCSocket* iSocketP;
       
    77 	DMMCStack*  iStackP;
       
    78 	TSDCard*  iCardP;
       
    79     
       
    80 	DThread* iClient;
       
    81 	
       
    82 	TPBusCallBack iBusCallBack;		
       
    83 	DSemaphore* iPowerUpSemaphore;
       
    84 	TBool iInitialised;
       
    85 	};
       
    86 
       
    87 
       
    88 DECLARE_STANDARD_LDD()
       
    89 	{
       
    90 	return new DSDAuxiliaryPowerControlFactory;
       
    91 	}
       
    92 
       
    93 DSDAuxiliaryPowerControlFactory::DSDAuxiliaryPowerControlFactory()
       
    94 //
       
    95 // Constructor
       
    96 //
       
    97 	{
       
    98     OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROLFACTORY_DSDAUXILIARYPOWERCONTROLFACTORY, "DSDAuxiliaryPowerControlFactory::DSDAuxiliaryPowerControlFactory");
       
    99 	__KTRACE_OPT(KPBUS1, Kern::Printf(">DSDAuxiliaryPowerControlFactory::DSDAuxiliaryPowerControlFactory"));
       
   100     iParseMask=KDeviceAllowUnit;
       
   101 	iUnitsMask=0xffffffff;
       
   102 	iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
       
   103 	}
       
   104 
       
   105 TInt DSDAuxiliaryPowerControlFactory::Create(DLogicalChannelBase*& aChannel)
       
   106 //
       
   107 // Create a new DSDAuxiliaryPowerControl on this logical device
       
   108 //
       
   109 	{
       
   110     OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROLFACTORY_CREATE, "DSDAuxiliaryPowerControlFactory::Create");
       
   111 	__KTRACE_OPT(KPBUS1, Kern::Printf(">DSDAuxiliaryPowerControlFactory::Create"));
       
   112 	aChannel=new DSDAuxiliaryPowerControl;
       
   113 	return aChannel ? KErrNone : KErrNoMemory;
       
   114 	}
       
   115 
       
   116 const TInt KDSDAuxiliaryPowerControlApiThreadPriority = 27;
       
   117 _LIT(KDSDAuxiliaryPowerControlApiThread,"DSDAuxiliaryPowerControlApiThread");
       
   118 
       
   119 TInt DSDAuxiliaryPowerControlFactory::Install()
       
   120 //
       
   121 // Install the LDD - overriding pure virtual
       
   122 //
       
   123 	{
       
   124 	// Allocate a kernel thread to run the DFC 
       
   125 	TInt r = Kern::DynamicDfcQCreate(gDfcQ, KDSDAuxiliaryPowerControlApiThreadPriority, KDSDAuxiliaryPowerControlApiThread);
       
   126 
       
   127 	if (r != KErrNone)
       
   128 		return r; 	
       
   129 
       
   130 	return SetName(&KLddName);
       
   131 	}
       
   132 
       
   133 void DSDAuxiliaryPowerControlFactory::GetCaps(TDes8& aDes) const
       
   134 //
       
   135 // Get capabilities - overriding pure virtual
       
   136 //
       
   137 	{
       
   138 	TCapsTestV01 b;
       
   139 	b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
       
   140     Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
       
   141 	}
       
   142 
       
   143 /**
       
   144   Destructor
       
   145 */
       
   146 DSDAuxiliaryPowerControlFactory::~DSDAuxiliaryPowerControlFactory()
       
   147 	{
       
   148     OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROLFACTORY_DSDAUXILIARYPOWERCONTROLFACTORY_DTOR, "DSDAuxiliaryPowerControlFactory::~DSDAuxiliaryPowerControlFactory");
       
   149 	__KTRACE_OPT(KPBUS1, Kern::Printf(">DSDAuxiliaryPowerControlFactory::~DSDAuxiliaryPowerControlFactory"));
       
   150 	if (gDfcQ)
       
   151 		gDfcQ->Destroy();
       
   152 	}
       
   153 
       
   154 void DSDAuxiliaryPowerControl::BusCallBack(TAny* aPtr, TInt aReason, TAny* a1, TAny* a2)
       
   155 	{
       
   156 	DSDAuxiliaryPowerControl* pTest = (DSDAuxiliaryPowerControl*)aPtr;
       
   157 	TPBusState busState = (TPBusState) (TInt) a1;
       
   158 	switch (aReason)
       
   159 		{
       
   160 		case TPBusCallBack::EPBusStateChange:
       
   161 			if (busState != EPBusPoweringUp)
       
   162 				Kern::SemaphoreSignal(*(pTest->iPowerUpSemaphore));
       
   163 			break;
       
   164 		}
       
   165 	}
       
   166 
       
   167 TInt DSDAuxiliaryPowerControl::PowerUpStack()
       
   168 	{
       
   169 	iBusCallBack.iFunction = BusCallBack;
       
   170 	iBusCallBack.iPtr=this;
       
   171 	iBusCallBack.SetSocket(iSocketP->iSocketNumber);
       
   172 	iBusCallBack.Add();
       
   173 	TInt r = Kern::SemaphoreCreate(iPowerUpSemaphore, _L("SDPowerUpSem"), 0);
       
   174 	if (r == KErrNone)
       
   175 		{
       
   176 		r = iSocketP->PowerUp();
       
   177 		if (r == KErrNone)
       
   178 			Kern::SemaphoreWait(*iPowerUpSemaphore);
       
   179 		}
       
   180 	return r;
       
   181 	}
       
   182 
       
   183 TInt DSDAuxiliaryPowerControl::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer)
       
   184 //
       
   185 // Create channel
       
   186 //
       
   187 	{
       
   188     OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_1, "DSDAuxiliaryPowerControl::DoCreate()");
       
   189 	__KTRACE_OPT(KPBUS1, Kern::Printf(">DSDAuxiliaryPowerControl::DoCreate()"));
       
   190 
       
   191 	if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
       
   192 		return KErrNotSupported;
       
   193 
       
   194 	//
       
   195 	// Obtain the appropriate card from the socket/stack
       
   196 	//
       
   197 	iSocketP = static_cast<DMMCSocket*>(DPBusSocket::SocketFromId(KSocketNumber));
       
   198 	if(iSocketP == NULL)
       
   199 		{
       
   200         OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_2, "DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain socket");
       
   201 		__KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain socket"));
       
   202 		return KErrNoMemory;
       
   203 		}
       
   204 
       
   205 	iStackP = static_cast<DSDStack*>(iSocketP->Stack(KStackNumber));
       
   206 	if(iStackP == NULL)
       
   207 		{
       
   208         OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_3, "DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain stack");
       
   209 		__KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain stack"));
       
   210 		return KErrNoMemory;
       
   211 		}
       
   212 
       
   213 	iCardP = static_cast<TSDCard*>(iStackP->CardP(KCardNumber));
       
   214 	if(iCardP == NULL)
       
   215 		{
       
   216         OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_4, "DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain card");
       
   217 		__KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain card"));
       
   218 		return KErrNoMemory;
       
   219 		}
       
   220 
       
   221 	SetDfcQ(gDfcQ);
       
   222 	iMsgQ.Receive();
       
   223 
       
   224 	// Make sure stack is powered up
       
   225 	TInt r = PowerUpStack();
       
   226 	if (r != KErrNone && r != KErrCompletion)
       
   227 		{
       
   228         OstTrace1( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_5, "DSDAuxiliaryPowerControl::DoCreate() : Failed To Power up stack, r = %d", r);
       
   229 		__KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : Failed To Power up stack, r = %d", r));
       
   230 		return r;
       
   231 		}
       
   232 		
       
   233 	if(!iCardP->IsReady())
       
   234 		{
       
   235         OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_6, "DSDAuxiliaryPowerControl::DoCreate() : Card not ready");
       
   236 		__KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : Card not ready"));
       
   237 		return KErrNotReady;
       
   238 		}
       
   239     	
       
   240 	if(!iCardP->ClientsRegistered())
       
   241 		{		
       
   242 		iCardP->RegisterClient();
       
   243 		((DSDIOPsu*)(iSocketP->iVcc))->Lock();
       
   244 		TBool locked = ((DSDIOPsu*)(iSocketP->iVcc))->IsLocked();
       
   245 		OstTrace1( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_7, "DSDAuxiliaryPowerControl::DoCreate() : PSU IsLocked(), locked = %d", locked);
       
   246 		__KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : PSU IsLocked(), locked = %d", locked));
       
   247 		if(!locked)
       
   248 			return KErrNotReady;
       
   249 		}
       
   250 		
       
   251 	return KErrNone;
       
   252 	}
       
   253 
       
   254 DSDAuxiliaryPowerControl::DSDAuxiliaryPowerControl()
       
   255 //
       
   256 // Constructor
       
   257 //
       
   258 	{
       
   259 	iClient=&Kern::CurrentThread();
       
   260 	((DObject*)iClient)->Open();
       
   261 	}
       
   262 
       
   263 
       
   264 DSDAuxiliaryPowerControl::~DSDAuxiliaryPowerControl()
       
   265 //
       
   266 // Destructor
       
   267 //
       
   268 	{
       
   269     OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DSDAUXILIARYPOWERCONTROL_DTOR, "DSDAuxiliaryPowerControl::~DSDAuxiliaryPowerControl");
       
   270 	__KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::~DSDAuxiliaryPowerControl"));
       
   271 	iBusCallBack.Remove();
       
   272 
       
   273 	if (iSocketP)
       
   274 		iSocketP->ControlIO(DPBusSocket::EControlMediaState, (TAny*)DPBusSocket::EPeriphBusMediaNormal, NULL);
       
   275 
       
   276 	
       
   277 	if(iCardP->ClientsRegistered())
       
   278 		{		
       
   279 		iCardP->DeregisterClient();
       
   280 		((DSDIOPsu*)(iSocketP->iVcc))->Unlock();
       
   281 		}
       
   282 
       
   283 	iPowerUpSemaphore->Close(NULL);
       
   284 
       
   285 	Kern::SafeClose((DObject*&)iClient,NULL);
       
   286 	}
       
   287 
       
   288 void DSDAuxiliaryPowerControl::HandleMsg(TMessageBase* aMsg)
       
   289     {
       
   290     TThreadMessage& m=*(TThreadMessage*)aMsg;
       
   291     TInt id=m.iValue;
       
   292     
       
   293 	if (id==(TInt)ECloseMsg)
       
   294 		{
       
   295 		if (iSocketP)
       
   296 			iSocketP->ControlIO(DPBusSocket::EControlMediaState, (TAny*)DPBusSocket::EPeriphBusMediaNormal, NULL);
       
   297 
       
   298 		m.Complete(KErrNone, EFalse);
       
   299 		return;
       
   300 		}
       
   301     else if (id==KMaxTInt)
       
   302 		{
       
   303 		// DoCancel
       
   304 		m.Complete(KErrNone,ETrue);
       
   305 		return;
       
   306 		}
       
   307 	}