kernel/eka/drivers/sdapc/d_sdapc.cpp
branchRCL_3
changeset 42 a179b74831c9
child 43 c1f20ce4abcf
equal deleted inserted replaced
41:0ffb4e86fcc9 42:a179b74831c9
       
     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 // Stub - overriding pure virtual
       
   136 //
       
   137 	{
       
   138 	}
       
   139 
       
   140 /**
       
   141   Destructor
       
   142 */
       
   143 DSDAuxiliaryPowerControlFactory::~DSDAuxiliaryPowerControlFactory()
       
   144 	{
       
   145     OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROLFACTORY_DSDAUXILIARYPOWERCONTROLFACTORY_DTOR, "DSDAuxiliaryPowerControlFactory::~DSDAuxiliaryPowerControlFactory");
       
   146 	__KTRACE_OPT(KPBUS1, Kern::Printf(">DSDAuxiliaryPowerControlFactory::~DSDAuxiliaryPowerControlFactory"));
       
   147 	if (gDfcQ)
       
   148 		gDfcQ->Destroy();
       
   149 	}
       
   150 
       
   151 void DSDAuxiliaryPowerControl::BusCallBack(TAny* aPtr, TInt aReason, TAny* a1, TAny* a2)
       
   152 	{
       
   153 	DSDAuxiliaryPowerControl* pTest = (DSDAuxiliaryPowerControl*)aPtr;
       
   154 	TPBusState busState = (TPBusState) (TInt) a1;
       
   155 	switch (aReason)
       
   156 		{
       
   157 		case TPBusCallBack::EPBusStateChange:
       
   158 			if (busState != EPBusPoweringUp)
       
   159 				Kern::SemaphoreSignal(*(pTest->iPowerUpSemaphore));
       
   160 			break;
       
   161 		}
       
   162 	}
       
   163 
       
   164 TInt DSDAuxiliaryPowerControl::PowerUpStack()
       
   165 	{
       
   166 	iBusCallBack.iFunction = BusCallBack;
       
   167 	iBusCallBack.iPtr=this;
       
   168 	iBusCallBack.SetSocket(iSocketP->iSocketNumber);
       
   169 	iBusCallBack.Add();
       
   170 	TInt r = Kern::SemaphoreCreate(iPowerUpSemaphore, _L("SDPowerUpSem"), 0);
       
   171 	if (r == KErrNone)
       
   172 		{
       
   173 		r = iSocketP->PowerUp();
       
   174 		if (r == KErrNone)
       
   175 			Kern::SemaphoreWait(*iPowerUpSemaphore);
       
   176 		}
       
   177 	return r;
       
   178 	}
       
   179 
       
   180 TInt DSDAuxiliaryPowerControl::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer)
       
   181 //
       
   182 // Create channel
       
   183 //
       
   184 	{
       
   185     OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_1, "DSDAuxiliaryPowerControl::DoCreate()");
       
   186 	__KTRACE_OPT(KPBUS1, Kern::Printf(">DSDAuxiliaryPowerControl::DoCreate()"));
       
   187 
       
   188 	if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
       
   189 		return KErrNotSupported;
       
   190 
       
   191 	//
       
   192 	// Obtain the appropriate card from the socket/stack
       
   193 	//
       
   194 	iSocketP = static_cast<DMMCSocket*>(DPBusSocket::SocketFromId(KSocketNumber));
       
   195 	if(iSocketP == NULL)
       
   196 		{
       
   197         OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_2, "DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain socket");
       
   198 		__KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain socket"));
       
   199 		return KErrNoMemory;
       
   200 		}
       
   201 
       
   202 	iStackP = static_cast<DSDStack*>(iSocketP->Stack(KStackNumber));
       
   203 	if(iStackP == NULL)
       
   204 		{
       
   205         OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_3, "DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain stack");
       
   206 		__KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain stack"));
       
   207 		return KErrNoMemory;
       
   208 		}
       
   209 
       
   210 	iCardP = static_cast<TSDCard*>(iStackP->CardP(KCardNumber));
       
   211 	if(iCardP == NULL)
       
   212 		{
       
   213         OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_4, "DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain card");
       
   214 		__KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : Didn't obtain card"));
       
   215 		return KErrNoMemory;
       
   216 		}
       
   217 
       
   218 	SetDfcQ(gDfcQ);
       
   219 	iMsgQ.Receive();
       
   220 
       
   221 	// Make sure stack is powered up
       
   222 	TInt r = PowerUpStack();
       
   223 	if (r != KErrNone && r != KErrCompletion)
       
   224 		{
       
   225         OstTrace1( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_5, "DSDAuxiliaryPowerControl::DoCreate() : Failed To Power up stack, r = %d", r);
       
   226 		__KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : Failed To Power up stack, r = %d", r));
       
   227 		return r;
       
   228 		}
       
   229 		
       
   230 	if(!iCardP->IsReady())
       
   231 		{
       
   232         OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_6, "DSDAuxiliaryPowerControl::DoCreate() : Card not ready");
       
   233 		__KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : Card not ready"));
       
   234 		return KErrNotReady;
       
   235 		}
       
   236     	
       
   237 	if(!iCardP->ClientsRegistered())
       
   238 		{		
       
   239 		iCardP->RegisterClient();
       
   240 		((DSDIOPsu*)(iSocketP->iVcc))->Lock();
       
   241 		TBool locked = ((DSDIOPsu*)(iSocketP->iVcc))->IsLocked();
       
   242 		OstTrace1( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DOCREATE_7, "DSDAuxiliaryPowerControl::DoCreate() : PSU IsLocked(), locked = %d", locked);
       
   243 		__KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::DoCreate() : PSU IsLocked(), locked = %d", locked));
       
   244 		if(!locked)
       
   245 			return KErrNotReady;
       
   246 		}
       
   247 		
       
   248 	return KErrNone;
       
   249 	}
       
   250 
       
   251 DSDAuxiliaryPowerControl::DSDAuxiliaryPowerControl()
       
   252 //
       
   253 // Constructor
       
   254 //
       
   255 	{
       
   256 	iClient=&Kern::CurrentThread();
       
   257 	((DObject*)iClient)->Open();
       
   258 	}
       
   259 
       
   260 
       
   261 DSDAuxiliaryPowerControl::~DSDAuxiliaryPowerControl()
       
   262 //
       
   263 // Destructor
       
   264 //
       
   265 	{
       
   266     OstTrace0( TRACE_FLOW, DSDAUXILIARYPOWERCONTROL_DSDAUXILIARYPOWERCONTROL_DTOR, "DSDAuxiliaryPowerControl::~DSDAuxiliaryPowerControl");
       
   267 	__KTRACE_OPT(KPBUS1, Kern::Printf("DSDAuxiliaryPowerControl::~DSDAuxiliaryPowerControl"));
       
   268 	iBusCallBack.Remove();
       
   269 
       
   270 	if (iSocketP)
       
   271 		iSocketP->ControlIO(DPBusSocket::EControlMediaState, (TAny*)DPBusSocket::EPeriphBusMediaNormal, NULL);
       
   272 
       
   273 	
       
   274 	if(iCardP->ClientsRegistered())
       
   275 		{		
       
   276 		iCardP->DeregisterClient();
       
   277 		((DSDIOPsu*)(iSocketP->iVcc))->Unlock();
       
   278 		}
       
   279 
       
   280 	iPowerUpSemaphore->Close(NULL);
       
   281 
       
   282 	Kern::SafeClose((DObject*&)iClient,NULL);
       
   283 	}
       
   284 
       
   285 void DSDAuxiliaryPowerControl::HandleMsg(TMessageBase* aMsg)
       
   286     {
       
   287     TThreadMessage& m=*(TThreadMessage*)aMsg;
       
   288     TInt id=m.iValue;
       
   289     
       
   290 	if (id==(TInt)ECloseMsg)
       
   291 		{
       
   292 		if (iSocketP)
       
   293 			iSocketP->ControlIO(DPBusSocket::EControlMediaState, (TAny*)DPBusSocket::EPeriphBusMediaNormal, NULL);
       
   294 
       
   295 		m.Complete(KErrNone, EFalse);
       
   296 		return;
       
   297 		}
       
   298     else if (id==KMaxTInt)
       
   299 		{
       
   300 		// DoCancel
       
   301 		m.Complete(KErrNone,ETrue);
       
   302 		return;
       
   303 		}
       
   304 	}