os/kernelhwsrv/kernel/eka/drivers/resmanus/d_resmanus.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1995-2009 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 // e32\drivers\resmanus\d_resmanus.cpp
    15 // 
    16 //
    17 
    18 // LDD for Resource Manager user side API
    19 #include "resmanus.h"
    20 #include <kernel/kern_priv.h>
    21 #include <kernel/kernel.h>
    22 #include <e32hal.h>
    23 #include <e32uid.h>
    24 #include <e32cmn.h>
    25 #include <e32cmn_private.h>
    26 #include <e32def_private.h>
    27 #include <drivers/resource_extend.h>
    28 
    29 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
    30 #include "rescontrol_psl.h"
    31 #endif
    32 
    33 #ifdef PRM_US_INSTRUMENTATION_MACRO
    34 #include <drivers/resmanus_trace.h>
    35 #endif
    36 
    37 #ifdef PRM_ENABLE_EXTENDED_VERSION2
    38 _LIT(KResManUsThreadName,"ResManUsExtendedCoreLddThread");
    39 #elif defined (PRM_ENABLE_EXTENDED_VERSION)
    40 _LIT(KResManUsThreadName,"ResManUsExtendedLddThread");
    41 #else
    42 _LIT(KResManUsThreadName,"ResManUsLddThread");
    43 #endif
    44 
    45 #define RESMANUS_FAULT()	Kern::Fault("RESMANUS",__LINE__)
    46 
    47 const TInt KResManUsThreadPriority = 24;
    48 const TInt KResManUsRegistrationPriority = 5; // Arbitrary! Can be 0-7, 7 is highest
    49 const TInt KResManCallBackPriority = 5; // Arbitrary! Can be 0-7, 7 is highest
    50 
    51 //Macro to return appropriate request type.
    52 #define GET_USER_REQUEST(request, buffer, type)						\
    53 	{																\
    54 	if(type == EGetState)											\
    55 		request = ((TTrackGetStateBuf*)buffer)->iRequest;			\
    56 	else if(type == ESetState)										\
    57 		request = ((TTrackSetStateBuf*)buffer)->iRequest;			\
    58 	else															\
    59 		request = ((TTrackNotifyBuf*)buffer)->iRequest;				\
    60 	}
    61 
    62 /***************************************************************************************
    63 	class TTrackGetStateBuf
    64  ***************************************************************************************/
    65 TTrackGetStateBuf::TTrackGetStateBuf(TPowerResourceCbFn aFn, TAny* aPtr,
    66 						       TDfcQue* aQue, TInt aPriority)
    67 							   :	iCtrlBlock(aFn, aPtr, aQue, aPriority)
    68 	{
    69 	iRequest = NULL;
    70 	}
    71 
    72 /***************************************************************************************
    73 	class TTrackSetStateBuf
    74  ***************************************************************************************/
    75 TTrackSetStateBuf::TTrackSetStateBuf(TPowerResourceCbFn aFn, TAny* aPtr,
    76 						       TDfcQue* aQue, TInt aPriority)
    77 							   :	iCtrlBlock(aFn, aPtr, aQue, aPriority)
    78 	{
    79 	iRequest = NULL;
    80 	}
    81 
    82 /***************************************************************************************
    83 	class TTrackNotifyBuf
    84  ***************************************************************************************/
    85 TTrackNotifyBuf::TTrackNotifyBuf(TPowerResourceCbFn aFn, TAny* aPtr,
    86 								 TDfcQue* aQue, TInt aPriority)
    87 							   :	iNotifyBlock(aFn, aPtr, aQue, aPriority)
    88 	{
    89 	iRequest = NULL;
    90 	}
    91 
    92 TTrackNotifyBuf::~TTrackNotifyBuf()
    93 	{
    94 	if(iRequest)
    95 		Kern::DestroyClientRequest(iRequest);
    96 	}
    97 
    98 TTrackSetStateBuf::~TTrackSetStateBuf()
    99 	{
   100 	if(iRequest)
   101 		Kern::DestroyClientRequest(iRequest);
   102 	}
   103 
   104 TTrackGetStateBuf::~TTrackGetStateBuf()
   105 	{
   106 	if(iRequest)
   107 		Kern::DestroyClientRequest(iRequest);
   108 	}
   109 	
   110 /***************************************************************************************
   111 	class DDeviceResManUs
   112  ***************************************************************************************/
   113 DDeviceResManUs::DDeviceResManUs()
   114 // Constructor
   115     {
   116     __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::DDeviceResManUs()"));
   117     iParseMask=KDeviceAllowAll&~KDeviceAllowUnit; // Allow info and pdd, but not units
   118     iUnitsMask=0;
   119     iVersion=TVersion(KResManUsMajorVersionNumber,
   120 		      KResManUsMinorVersionNumber,
   121 		      KResManUsBuildVersionNumber);
   122     }
   123 
   124 DDeviceResManUs::~DDeviceResManUs()
   125 // Destructor
   126     {
   127     __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::~DDeviceResManUs()"));
   128 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
   129 	iSharedDfcQue->Destroy();
   130 #else
   131 	delete iSharedDfcQue;
   132 #endif
   133 	}
   134 
   135 TInt DDeviceResManUs::Install()
   136 // Install the device driver.
   137     {
   138     __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::Install()"));
   139 	// Create the message queue and initialise the DFC queue pointer
   140 #ifndef RESOURCE_MANAGER_SIMULATED_PSL
   141 	TInt r=Kern::DfcQInit(iSharedDfcQue,KResManUsThreadPriority,&KResManUsThreadName);
   142 #else
   143 	TInt r = Kern::DynamicDfcQCreate(iSharedDfcQue,KResManUsThreadPriority,KResManUsThreadName);
   144 #endif
   145     __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DfcQCreate r  = %d", r));
   146 	if(r!=KErrNone)
   147 		return r;
   148 
   149 #ifdef CPU_AFFINITY_ANY
   150         NKern::ThreadSetCpuAffinity((NThread*)(iSharedDfcQue->iThread), KCpuAffinityAny);
   151 #endif
   152 	r = SetName(&KLddRootName);
   153     __KTRACE_OPT(KRESMANAGER, Kern::Printf("> SetName, r  = %d", r));
   154 	return r;
   155     }
   156 
   157 
   158 void DDeviceResManUs::GetCaps(TDes8& aDes) const
   159 // Return the ResManUs capabilities.
   160     {
   161     __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::GetCaps(TDes8& aDes) const"));
   162     TPckgBuf<TCapsDevResManUs> b;
   163     b().version=TVersion(KResManUsMajorVersionNumber,
   164 			 KResManUsMinorVersionNumber,
   165 			 KResManUsBuildVersionNumber);
   166     Kern::InfoCopy(aDes,b);
   167     }
   168 
   169 
   170 TInt DDeviceResManUs::Create(DLogicalChannelBase*& aChannel)
   171 // Create a channel on the device.
   172     {
   173     __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::Create(DLogicalChannelBase*& aChannel)"));
   174 	if(iOpenChannels>=KMaxNumChannels)
   175 		return KErrOverflow;
   176     aChannel=new DChannelResManUs;
   177     return aChannel?KErrNone:KErrNoMemory;
   178     }
   179 
   180 
   181 /***************************************************************************************
   182 	class DChannelResManUs
   183  ***************************************************************************************/
   184 DChannelResManUs::DChannelResManUs() 
   185 // Constructor
   186     {
   187     __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DChannelResManUs()"));
   188     iClient=&Kern::CurrentThread();
   189 	// Increase the DThread's ref count so that it does not close without us
   190 	iClient->Open();
   191     }
   192 
   193 
   194 DChannelResManUs::~DChannelResManUs()
   195 // Destructor
   196     {
   197     __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::~DChannelResManUs()"));
   198 
   199 	// Cancel any outstanding requests
   200 	//
   201 	// For each tracker (Get, Set and notify)
   202 	// 
   203 	if(iGetStateTracker != NULL)
   204 		{
   205 		CancelTrackerRequests(iGetStateTracker,EFalse,0,NULL); // EFalse,0, to ignore resource IDs
   206 		RemoveTrackingControl(iGetStateTracker);
   207 		}
   208 	if(iSetStateTracker != NULL)
   209 		{
   210 		CancelTrackerRequests(iSetStateTracker,EFalse,0,NULL); // EFalse,0, to ignore resource IDs
   211 		RemoveTrackingControl(iSetStateTracker);
   212 		}
   213 	if(iListenableTracker != NULL)
   214 		{
   215 		CancelTrackerRequests(iListenableTracker,EFalse,0,NULL); // EFalse,0, to ignore resource IDs
   216 		RemoveTrackingControl(iListenableTracker);
   217 		}
   218 
   219 	delete iUserNameUsed;
   220 	delete iResourceDependencyIds;
   221 	delete iClientNamesResCtrl;
   222 	delete iResourceInfoResCtrl;
   223 
   224 	// decrement the DThread's reference count
   225 	Kern::SafeClose((DObject*&)iClient, NULL);
   226     }
   227 
   228 
   229 static void AsyncCallBackFn(TUint aClient, TUint aResourceId, TInt aLevel, TInt aLevelOwnerId, TInt aResult, TAny* aTrackingBuffer)
   230 	{
   231 // Callback function for asynchronous requests
   232     __KTRACE_OPT(KRESMANAGER, Kern::Printf("> AsyncCallBackFn aClient=0x%x aResourceId=0x%x, aLevel=0x%x, aResult=0x%x, aTrackingBuffer=0x%x\n",aClient, aResourceId, aLevel, aResult, aTrackingBuffer));
   233 	TTrackingBuffer* buffer = ((TTrackingBuffer*)aTrackingBuffer);
   234 	TTrackingControl* tracker = buffer->GetTrackingControl();
   235 	__ASSERT_ALWAYS((tracker!=NULL),RESMANUS_FAULT());
   236 	DChannelResManUs* channel = tracker->iOwningChannel;
   237 
   238 #ifdef PRM_US_INSTRUMENTATION_MACRO
   239 	if(tracker->iType==EGetState)
   240 		{
   241 		PRM_US_GET_RESOURCE_STATE_END_TRACE;
   242 		}
   243 	else if(tracker->iType==ESetState)
   244 		{
   245 		PRM_US_SET_RESOURCE_STATE_END_TRACE;
   246 		}
   247 #endif
   248 	if(tracker->iType == EGetState)
   249 		{
   250 		TTrackGetStateBuf* stateBuf = (TTrackGetStateBuf*)aTrackingBuffer;
   251 		if(aResult==KErrNone)
   252 			{
   253 			// Write the state value to the user-supplied variable
   254 			stateBuf->iRequest->Data1() = aLevel;
   255 			stateBuf->iRequest->Data2() = aLevelOwnerId;
   256 			}
   257 		Kern::QueueRequestComplete(channel->iClient, ((TTrackGetStateBuf*)buffer)->iRequest, aResult);
   258 		}
   259 	else if(tracker->iType == ESetState)
   260 		{
   261 		Kern::QueueRequestComplete(channel->iClient, ((TTrackSetStateBuf*)buffer)->iRequest, aResult);
   262 		}
   263 	// Once notified of a change in a resource state, must cancel the notification
   264 	// request in the Resource Controller to give the client the appearance of a 
   265 	// 'one'shot' type of operation.
   266 	else if(tracker->iType==ENotify)
   267 		{
   268 #ifdef PRM_ENABLE_EXTENDED_VERSION
   269 		if(((TInt)aClient==KDynamicResourceDeRegistering)&&(aResourceId&KIdMaskDynamic))  
   270 			{
   271 			// Resource has de-registered from Resource Controller, so can't expect any more notifications
   272 			// of this type. Cancellation of notifications (i.e. invoke Resource Controller) and transfer of
   273 			// buffers to free queue (for both conditional and unconditional notifications) is already done.
   274 			// To distinguish removal of a dynamic resource, hijack aResult (the value used when completing
   275 			// the user-side TRequestStatus object) and set it to KErrDisconnected.
   276 			aResult = KErrDisconnected;
   277 			}
   278 
   279 #endif
   280 		TInt r = (channel->iPddPtr)->CancelNotification(channel->ClientHandle(),aResourceId,
   281 										((TTrackNotifyBuf*)buffer)->iNotifyBlock);
   282 		__ASSERT_ALWAYS((r == KErrCancel),RESMANUS_FAULT());
   283 		Kern::QueueRequestComplete(channel->iClient, ((TTrackNotifyBuf*)buffer)->iRequest, aResult);
   284 		}
   285 
   286 	// Return the tracking buffer to the free queue
   287 	channel->FreeTrackingBuffer(buffer);
   288 	}
   289 
   290 TInt DChannelResManUs::GetValidName(const TDesC8* aInfo)
   291 	{
   292 // Extract a usable name from that supplied by the client
   293 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::GetValidName"));
   294 	TInt err=KErrNone;
   295 	if(aInfo)
   296 		{
   297 		DThread* thread = &Kern::CurrentThread();
   298 		TInt nameLen = Kern::ThreadGetDesLength(thread, aInfo);
   299 		if(nameLen<0)
   300 			return nameLen; // return error code
   301 		iNameProvidedLength = nameLen;
   302 		if(nameLen > MAX_CLIENT_NAME_LENGTH)
   303 			err=KErrBadName;
   304 		else
   305 			{
   306 			nameLen = (nameLen<=MAX_NAME_LENGTH_IN_RESMAN) ? nameLen : MAX_NAME_LENGTH_IN_RESMAN;
   307 			if((iUserNameUsed = HBuf8::New(nameLen))==NULL)
   308 				return KErrNoMemory;
   309 			err = Kern::ThreadDesRead(thread,aInfo,*iUserNameUsed,0);
   310 			if(err!=KErrNone)
   311 				return err;
   312 			}
   313 		}
   314 	else
   315 		err=KErrBadName;
   316 	return err;
   317 	}
   318 
   319 TInt DChannelResManUs::RequestUserHandle(DThread* aThread, TOwnerType aType)
   320 // Called when a user thread requests a handle to this channel
   321     {
   322     // Make sure that only our client can get a handle
   323 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::RequestUserHandle"));
   324     if (aType!=EOwnerThread || aThread!=iClient)
   325         return KErrAccessDenied;
   326     return KErrNone;
   327     }
   328 
   329 void DChannelResManUs::RegistrationDfcFunc(TAny* aChannel)
   330 	{
   331 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::RegistrationDfcFunc"));
   332 	// DFC function invoked for registration with Resource Controller
   333 	DChannelResManUs* channel = (DChannelResManUs*)aChannel;
   334 	// RegisterProxyClient(TUint& aProxyId, const TDesC& aName);
   335 	TUint uintVal=0;
   336 	TInt r = KErrNone;
   337 	__ASSERT_ALWAYS((r==KErrNone),RESMANUS_FAULT());
   338 
   339 	r=(channel->iPddPtr)->RegisterProxyClient(uintVal,*((TDesC8*)(channel->iUserNameUsed)));
   340 	if(r!=KErrNone)
   341 		{
   342 		// Registration failed
   343 		// Ensure that the client-side flag is cleared in uintVal
   344 		// so the failure can be detected in DoCreate
   345 		uintVal &= ~USER_SIDE_CLIENT_BIT_MASK; // Copied from rescontrol_export
   346 		}
   347 	channel->SetClientHandle((TInt)uintVal);
   348 	NKern::FSSignal(channel->iFastSem);
   349 	}
   350 
   351 
   352 TInt DChannelResManUs::RegisterWithResCtrlr()
   353 	{
   354 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::RegisterWithResCtrlr"));
   355 	TInt r = KErrNone;
   356 	// Initialise the channel's fast semaphore
   357 	iFastSem = new NFastSemaphore();
   358 	if(iFastSem == NULL)
   359 		r = KErrNoMemory;
   360 	else
   361 		{
   362 		iFastSem->iOwningThread = (NThreadBase*)NKern::CurrentThread();
   363 
   364 		// Attempt to perform registration with the Resource Controller on behalf of the client.
   365 		SetDfcQ(((DDeviceResManUs*)(iDevice))->iSharedDfcQue);
   366 		TDfc tempDfc(RegistrationDfcFunc, this, iDfcQ, KResManUsRegistrationPriority);
   367 
   368 		// Block this thread until the DFC has executed
   369 		tempDfc.Enque();
   370 		NKern::FSWait(iFastSem);
   371 		// Have finished with iFastSem
   372 		delete iFastSem;
   373 
   374 		// Registration complete - check success
   375 		if(!(USER_SIDE_CLIENT_BIT_MASK & ClientHandle()))
   376 			{
   377 			// Registration failed
   378 			r = KErrCouldNotConnect;	
   379 			}
   380 		// Start receiving messages ...
   381 		iMsgQ.Receive();
   382 		}
   383 	return r;
   384 	}
   385 
   386 TInt DChannelResManUs::DoCreate(TInt /*aUnit*/,
   387                                 const TDesC8* aInfo, 
   388                                 const TVersion &aVer)
   389 // Create the channel from the passed info.
   390     {
   391     __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer)"));
   392 
   393 	TInt r = KErrNone;
   394 	iPddPtr = ((DUserSideProxyInterface*)iPdd)->iController;
   395 	// Check client has appropriate capabilities
   396 	if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by DDevicePowerRsrc::Create")))
   397 		return KErrPermissionDenied;
   398 
   399 	// Check software version
   400 	if (!Kern::QueryVersionSupported(TVersion(KResManUsMajorVersionNumber,
   401 			 KResManUsMinorVersionNumber,
   402 			 KResManUsBuildVersionNumber),
   403 				     aVer))
   404 		return KErrNotSupported;
   405 
   406 	// Implementation note: if this method fails, the destructor will be invoked
   407 	// as part of which all successfully-allocated memory will be freed. Therefore,
   408 	// no memory will be explicitly freed in the event of failure in the code which follows.
   409 	
   410 	// Allocate the arrays used for acquiring client, resource and dependency information
   411 	if((iClientNamesResCtrl = HBuf8::New(KNumClientNamesResCtrl * sizeof(TPowerClientInfoV01)))==NULL)
   412 		return KErrNoMemory;
   413 	if((iResourceInfoResCtrl = HBuf8::New(KNumResourceInfoResCtrl * sizeof(TPowerResourceInfoV01)))==NULL)
   414 		return KErrNoMemory;
   415 	if((iResourceDependencyIds = HBuf8::New(KNumResourceDependencies * sizeof(SResourceDependencyInfo)))==NULL)
   416 		return KErrNoMemory;
   417 	// Obtain the channel name to use
   418 	if((r=GetValidName(aInfo))!=KErrNone)
   419 		return r;
   420 #ifdef PRM_ENABLE_EXTENDED_VERSION
   421 	iResDepsValid = 0;
   422 #endif
   423 
   424 #ifdef PRM_US_INSTRUMENTATION_MACRO
   425 	PRM_US_OPEN_CHANNEL_START_TRACE;	 
   426 #endif
   427 
   428 	// Set up the request tracking support
   429 	iGetStateTracker = new TTrackingControl();
   430 	iSetStateTracker = new TTrackingControl();;
   431 	iListenableTracker = new TTrackingControl();
   432 	if((iGetStateTracker==NULL) || (iSetStateTracker==NULL) || (iListenableTracker==NULL))
   433 		return KErrNoMemory;
   434 
   435 	// Register with the Resource Controller
   436 	r = RegisterWithResCtrlr();
   437 
   438 #ifdef PRM_US_INSTRUMENTATION_MACRO
   439 	PRM_US_OPEN_CHANNEL_END_TRACE;
   440 #endif
   441 
   442     return r;
   443     }
   444 
   445 //Override sendMsg to allow data copy in the context of client thread for WDP.
   446 TInt DChannelResManUs::SendMsg(TMessageBase* aMsg)
   447 	{
   448 	TThreadMessage& m = *(TThreadMessage*)aMsg;
   449 	TInt id = m.iValue;
   450 	TInt r = KErrNone;
   451 	if (id != (TInt)ECloseMsg && id != KMaxTInt)
   452 		{
   453 		if (id<0)
   454 			{
   455 			TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
   456 			r = SendRequest(aMsg);
   457 			if (r != KErrNone)
   458 				Kern::RequestComplete(pS,r);
   459 			}
   460 		else
   461 			r = SendControl(aMsg);
   462 		}
   463 	else
   464 		r = DLogicalChannel::SendMsg(aMsg);
   465 	return r;
   466 	}
   467 
   468 TInt DChannelResManUs::SendRequest(TMessageBase* aMsg)
   469 	{
   470 	TThreadMessage& m = *(TThreadMessage*)aMsg;
   471 	TInt id = ~m.iValue;
   472 	TRequestStatus* pS = (TRequestStatus*)m.Ptr0();
   473 	TInt r = KErrNone;
   474 	TTrackingBuffer *trackBuf = NULL;
   475 	TUint parms[4];
   476 	TPowerResourceCb *callBack;
   477 	DPowerResourceNotification *prn;
   478 
   479 	switch(id)
   480 		{
   481 		case RBusDevResManUs::EChangeResourceState:
   482 			{
   483 			__ASSERT_ALWAYS(m.Ptr2() != NULL, RESMANUS_FAULT());
   484 #ifdef _DUMP_TRACKERS
   485 			if((r=DumpTracker(iSetStateTracker))!=KErrNone)
   486 				break;
   487 #endif
   488 			r = GetAndInitTrackingBuffer(iSetStateTracker, trackBuf, (TUint)m.Ptr1(), pS);
   489 			if( r != KErrNone)
   490 				return r;
   491 			callBack = &(((TTrackSetStateBuf*)trackBuf)->iCtrlBlock);
   492 			new (callBack) TPowerResourceCb(&AsyncCallBackFn, (TAny*)trackBuf, iDfcQ, KResManCallBackPriority);
   493 			parms[0] = (TUint)m.Ptr2();
   494 			parms[1] = (TUint)callBack;
   495 			m.iArg[2] = &(parms[0]);
   496 			break;
   497 			}
   498 		case RBusDevResManUs::EGetResourceState:
   499 			{
   500 			__ASSERT_ALWAYS(m.Ptr2() != NULL, RESMANUS_FAULT());
   501 			umemget32(&(parms[0]), m.Ptr2(), 3*sizeof(TInt));
   502 #ifdef _DUMP_TRACKERS
   503 			if((r=DumpTracker(iGetStateTracker))!=KErrNone)
   504 				break;
   505 #endif
   506 			r = GetStateBuffer(iGetStateTracker, trackBuf, (TUint)m.Ptr1(), (TInt*)parms[1], (TInt*)parms[2], callBack, pS);
   507 			if(r != KErrNone)
   508 				return r;
   509 			parms[3] = (TUint)callBack;
   510 			m.iArg[2] = &(parms[0]);
   511 			break;
   512 			}
   513 		case RBusDevResManUs::ERequestChangeNotification:
   514 			{
   515 			__ASSERT_ALWAYS(m.Ptr1() != NULL, RESMANUS_FAULT());
   516 			r = GetAndInitTrackingBuffer(iListenableTracker, trackBuf, (TUint)m.Ptr1(), pS);
   517 			if(r != KErrNone)
   518 				return r;
   519 			prn = &(((TTrackNotifyBuf*)trackBuf)->iNotifyBlock);
   520 			new (prn) DPowerResourceNotification(&AsyncCallBackFn, (TAny*)trackBuf, iDfcQ, KResManCallBackPriority);
   521 			m.iArg[2] = (TAny*)prn;
   522 			break;
   523 			}
   524 		case RBusDevResManUs::ERequestQualifiedChangeNotification:
   525 			{
   526 			__ASSERT_ALWAYS(m.Ptr1() != NULL, RESMANUS_FAULT());
   527 			__ASSERT_ALWAYS(m.Ptr2() != NULL, RESMANUS_FAULT());
   528 			umemget32(&(parms[0]), m.Ptr2(), 2*sizeof(TUint));
   529 			m.iArg[2] = &parms[0];
   530 			r = GetAndInitTrackingBuffer(iListenableTracker, trackBuf, (TUint)parms[0], pS);
   531 			if(r != KErrNone)
   532 				return r;
   533 			prn = &(((TTrackNotifyBuf*)trackBuf)->iNotifyBlock);
   534 			new (prn) DPowerResourceNotification(&AsyncCallBackFn, (TAny*)trackBuf, iDfcQ, KResManCallBackPriority);
   535 			parms[2] = (TUint)prn;
   536 			break;
   537 			}
   538 		default:
   539 			{
   540 			return KErrNotSupported;
   541 			}
   542 		}
   543 
   544 	if(r == KErrNone)
   545 		r = DLogicalChannel::SendMsg(aMsg);
   546 	if(r != KErrNone)
   547 		FreeTrackingBuffer(trackBuf);
   548 	return r;
   549 	}
   550 
   551 
   552 TInt DChannelResManUs::SendControl(TMessageBase* aMsg)
   553 	{
   554 	TThreadMessage& m = *(TThreadMessage*)aMsg;
   555 	TInt id = m.iValue;
   556 	TInt param1 = 0;
   557 	TUint parms[4];
   558 	TAny* a1 = m.Ptr0();
   559 	TAny* a2 = m.Ptr1();
   560 	TAny* ptr1 = NULL;
   561 	switch(id)
   562 		{
   563 		case RBusDevResManUs::EInitialise:
   564 			{
   565 			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
   566 			TUint8 stateRes[3];
   567 			umemget(&(stateRes[0]), a1, 3*sizeof(TUint8));
   568 			m.iArg[0] = &(stateRes[0]);
   569 			break;
   570 			}
   571 		case RBusDevResManUs::EGetNoOfResources:
   572 		case RBusDevResManUs::EGetResourceControllerVersion:
   573 			{
   574 			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
   575 			m.iArg[0] = &param1;
   576 			break;
   577 			}
   578 		case RBusDevResManUs::EGetNoOfClients:
   579 		case RBusDevResManUs::EGetNumClientsUsingResource:
   580 			{
   581 			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
   582 			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
   583 			umemget32(&(parms[0]), a2, 3*sizeof(TUint));
   584 			m.iArg[1]  = &(parms[0]);
   585 			m.iArg[0] = &param1;
   586 			break;
   587 			}
   588 		case RBusDevResManUs::EGetNumResourcesInUseByClient:
   589 			{
   590 			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
   591 			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
   592 			TBuf8 <MAX_NAME_LENGTH_IN_RESMAN> clientName;
   593 			Kern::KUDesGet(clientName, *(TDesC8*)m.Ptr0());
   594 			m.iArg[0] = (TAny*)&clientName;
   595 			umemget32(&(parms[0]), m.Ptr1(), 2*sizeof(TUint));
   596 			param1 = parms[1];
   597 			m.iArg[1] = &param1;
   598 			break;
   599 			}
   600 		case RBusDevResManUs::EGetResourceIdByName:
   601 			{
   602 			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
   603 			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
   604 			TBuf8 <MAX_NAME_LENGTH_IN_RESMAN> resourceName;
   605 			Kern::KUDesGet(resourceName, *(TDesC8*)m.Ptr0());
   606 			m.iArg[0] = (TAny*)&resourceName;
   607 			m.iArg[1] = &param1;
   608 			break;
   609 			}
   610 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
   611 		case RBusDevResManUs::EGetNumCandidateAsyncResources:
   612 		case RBusDevResManUs::EGetNumCandidateSharedResources:
   613 			{
   614 			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
   615 			m.iArg[0] = &param1;
   616 			break;
   617 			}
   618 		case RBusDevResManUs::EGetCandidateAsyncResourceId:
   619 		case RBusDevResManUs::EGetCandidateSharedResourceId:
   620 			{
   621 			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
   622 			m.iArg[1] = &param1;
   623 			break;
   624 			}
   625 #endif
   626 		case RBusDevResManUs::EGetNumDependentsForResource:
   627 			{
   628 			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
   629 			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
   630 			umemget32(&(parms[0]), m.Ptr1(), 2*sizeof(TUint));
   631 			m.iArg[1] = &(parms[0]);
   632 			m.iArg[0] = &param1;
   633 			break;
   634 			}
   635 		case RBusDevResManUs::EGetDependentsIdForResource:
   636 			{
   637 			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
   638 			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
   639 			umemget32(&(parms[0]), m.Ptr1(), 3*sizeof(TUint));
   640 			TInt len, maxLen;
   641 			ptr1 = (TAny*)parms[1];
   642 			Kern::KUDesInfo(*(const TDesC8*)parms[1], len, maxLen);
   643 			umemget32(&param1, m.Ptr0(), sizeof(TUint));
   644 			if((maxLen - len) < (TInt)(param1 * sizeof(SResourceDependencyInfo)))
   645 				{
   646 				return KErrArgument;
   647 				}
   648 			m.iArg[0] = &param1;
   649 			m.iArg[1] = &(parms[0]);
   650 			break;
   651 			}
   652 		case RBusDevResManUs::EGetResourceInfo:
   653 			{
   654 			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
   655 			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
   656 			TResourceInfoBuf buf;
   657 			m.iArg[1] = &buf;
   658 			break;
   659 			}
   660 		case RBusDevResManUs::EGetAllResourcesInfo:
   661 			{
   662 			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
   663 			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
   664 			umemget32(&(parms[0]), m.Ptr1(), 2*sizeof(TUint));
   665 			ptr1 = (TAny*)parms[0];
   666 			umemget32(&param1, (TAny*)parms[0], sizeof(TUint));
   667 			parms[0]  =(TUint)&param1;
   668 			RSimplePointerArray<TResourceInfoBuf> infoPtrs;
   669 			umemget(&infoPtrs, m.Ptr0(), sizeof(RSimplePointerArray<TResourceInfoBuf>));
   670 			if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
   671 				return KErrArgument;
   672 			m.iArg[1] = &(parms[0]);
   673 			break;
   674 			}
   675 		case RBusDevResManUs::EGetInfoOnClientsUsingResource:
   676 			{
   677 			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
   678 			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
   679 			umemget32(&parms[0], m.Ptr1(), 4*sizeof(TUint));
   680 			ptr1 = (TAny*)parms[0];
   681 			umemget32(&param1, (TAny*)parms[0], sizeof(TUint));
   682 			parms[0] = (TUint)&param1;
   683 			RSimplePointerArray<TClientInfoBuf>infoPtrs;
   684 			umemget(&infoPtrs, m.Ptr0(), sizeof(RSimplePointerArray<TClientInfoBuf>));
   685 			if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
   686 				return KErrArgument;
   687 			m.iArg[1] = &(parms[0]);
   688 			break;
   689 			}
   690 		case RBusDevResManUs::EGetNamesAllClients:
   691 			{
   692 			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
   693 			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
   694 			umemget32(&parms[0], m.Ptr1(), 4*sizeof(TUint));
   695 			ptr1 = (TAny*)parms[0];
   696 			umemget32(&param1, (TAny*)parms[0], sizeof(TUint));
   697 			parms[0] = (TUint)&param1;
   698 			RSimplePointerArray<TClientName> infoPtrs;
   699 			umemget(&infoPtrs, m.Ptr0(), sizeof(RSimplePointerArray<TClientName>));
   700 			if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
   701 				return KErrArgument;
   702 			m.iArg[1] = &(parms[0]);
   703 			break;
   704 			}
   705 		case RBusDevResManUs::EGetInfoOnResourcesInUseByClient:
   706 			{
   707 			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
   708 			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
   709 			TBuf8 <MAX_NAME_LENGTH_IN_RESMAN> clientName;
   710 			Kern::KUDesGet(clientName, *(TDesC8*)m.Ptr0());
   711 			m.iArg[0] = (TAny*)&clientName;
   712 			umemget32(&parms[0], m.Ptr1(), 3*sizeof(TUint));
   713 			ptr1 = (TAny*)parms[0];
   714 			umemget32(&param1, (TAny*)parms[0], sizeof(TUint));
   715 			parms[0] = (TUint)&param1;
   716 			RSimplePointerArray<TResourceInfoBuf> infoPtrs;
   717 			umemget(&infoPtrs, (TAny*)parms[1], sizeof(RSimplePointerArray<TResourceInfoBuf>));
   718 			if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
   719 				return KErrArgument;
   720 			m.iArg[1] = &(parms[0]);
   721 			break;
   722 			}
   723 		}
   724 
   725 	TInt r = DLogicalChannel::SendMsg(aMsg);
   726 	if(r != KErrNone)
   727 		return r;
   728 
   729 	switch(id)
   730 		{
   731 		case RBusDevResManUs::EGetNoOfResources:
   732 		case RBusDevResManUs::EGetNoOfClients:
   733 		case RBusDevResManUs::EGetNumClientsUsingResource:
   734 		case RBusDevResManUs::EGetResourceControllerVersion:
   735 		case RBusDevResManUs::EGetNumDependentsForResource:
   736 			{
   737 			umemput32(a1, (TAny*)&param1, sizeof(TUint));
   738 			break;
   739 			}
   740 		case RBusDevResManUs::EGetNumResourcesInUseByClient:
   741 			{
   742 			umemput32((TAny*)parms[0], (TAny*)&param1, sizeof(TUint));
   743 			break;
   744 			}
   745 		case RBusDevResManUs::EGetResourceIdByName:
   746 			{
   747 			umemput32(a2, (TAny*)&param1, sizeof(TUint));
   748 			break;
   749 			}
   750 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
   751 		case RBusDevResManUs::EGetNumCandidateAsyncResources:
   752 		case RBusDevResManUs::EGetNumCandidateSharedResources:
   753 			{
   754 			umemput32(a1, (TAny*)&param1, sizeof(TUint));
   755 			break;
   756 			}
   757 		case RBusDevResManUs::EGetCandidateAsyncResourceId:
   758 		case RBusDevResManUs::EGetCandidateSharedResourceId:
   759 			{
   760 			umemput32(a2, (TAny*)&param1, sizeof(TUint));
   761 			break;
   762 			}
   763 #endif
   764 		case RBusDevResManUs::EGetDependentsIdForResource:
   765 			{
   766 			r = Kern::ThreadDesWrite(iClient,(TAny*)ptr1, (const TDesC8&)*(SResourceDependencyInfo*)parms[1], 0);
   767 			if(r == KErrOverflow) //This is done to retain the error as per API spec
   768 				r = KErrArgument;
   769 			break;
   770 			}
   771 		case RBusDevResManUs::EGetResourceInfo:
   772 			{
   773 			Kern::KUDesPut(*(TDes8*)a2, (const TDesC8&)*(TResourceInfoBuf*)m.Ptr1());
   774 			break;
   775 			}
   776 		case RBusDevResManUs::EGetAllResourcesInfo:
   777 			{
   778 			TUint numToCopy;
   779 			RSimplePointerArray<TResourceInfoBuf> infoPtrs;
   780 			umemget(&infoPtrs, a1, sizeof(RSimplePointerArray<TResourceInfoBuf>));
   781 			numToCopy = (infoPtrs.Count() < param1) ? infoPtrs.Count() : param1;
   782 			umemput32(ptr1, (TAny*)&param1, sizeof(TUint));
   783 			TResourceInfoBuf** entriesAddr = infoPtrs.Entries();
   784 			TInt* entryPtr = (TInt*)entriesAddr;
   785 			TPowerResourceInfoV01 *currRes = (TPowerResourceInfoV01*)iResourceInfoResCtrl->Ptr();
   786 			TResourceInfoBuf* clientAddr;
   787 			TResourceInfoBuf tempInfo;
   788 			for(TUint index = 0; index < numToCopy; index++)
   789 				{
   790 				umemget32(&clientAddr, entryPtr, sizeof(TResourceInfoBuf*));
   791 				entryPtr++;
   792 				r = ExtractResourceInfo(currRes, tempInfo);
   793 				if(r != KErrNone)
   794 					return r;
   795 				umemput((TAny*)clientAddr, (TAny*)&(tempInfo), tempInfo.Length());
   796 				currRes++;
   797 				}
   798 			break;
   799 			}
   800 		case RBusDevResManUs::EGetInfoOnClientsUsingResource:
   801 			{
   802 			TUint numToCopy;
   803 			RSimplePointerArray<TClientInfoBuf> infoPtrs;
   804 			umemget(&infoPtrs, a1, sizeof(RSimplePointerArray<TClientName>));
   805 			numToCopy = infoPtrs.Count();
   806 			TClientInfoBuf** entriesAddr = infoPtrs.Entries();
   807 			TInt* entryPtr = (TInt*)entriesAddr;
   808 			TPowerClientInfoV01* rcDataPtr = (TPowerClientInfoV01*)iClientNamesResCtrl->Ptr();
   809 			TClientInfoBuf* clientAddr;
   810 			TUint userSideClients = 0;
   811 			TClientInfoBuf tempInfo;
   812 			for(TInt index = 0; index < param1; index++)
   813 				{
   814 				if((!parms[1]) && !(rcDataPtr->iClientId & USER_SIDE_CLIENT_BIT_MASK))
   815 					{
   816 					rcDataPtr++;
   817 					continue;
   818 					}
   819 				if(numToCopy == 0)
   820 					{
   821 					userSideClients++;
   822 					continue;
   823 					}
   824 				umemget32(&clientAddr, entryPtr, sizeof(TClientName*));
   825 				entryPtr++;
   826 				tempInfo().iId = rcDataPtr->iClientId;
   827 				tempInfo().iName = *rcDataPtr->iClientName;
   828 				Kern::InfoCopy(*clientAddr, tempInfo);
   829 				rcDataPtr++;
   830 				numToCopy--;
   831 				userSideClients++;
   832 				}
   833 			if(parms[1])
   834 				umemput32(ptr1, (TAny*)&param1, sizeof(TUint));
   835 			else
   836 				umemput32(ptr1, (TAny*)&userSideClients, sizeof(TUint));
   837 			break;
   838 			}
   839 		case RBusDevResManUs::EGetNamesAllClients:
   840 			{
   841 			TUint numToCopy;
   842 			RSimplePointerArray<TClientName> infoPtrs;
   843 			umemget(&infoPtrs, a1, sizeof(RSimplePointerArray<TClientName>));
   844 			numToCopy = infoPtrs.Count();
   845 			TClientName** entriesAddr = infoPtrs.Entries();
   846 			TInt* entryPtr = (TInt*)entriesAddr;
   847 			TPowerClientInfoV01* rcDataPtr = (TPowerClientInfoV01*)iClientNamesResCtrl->Ptr();
   848 			TClientName* clientAddr;
   849 			TUint userSideClients = 0;
   850 			for(TInt index = 0; index < param1; index++)
   851 				{
   852 				if((!parms[1]) && !(rcDataPtr->iClientId & USER_SIDE_CLIENT_BIT_MASK))
   853 					{
   854 					rcDataPtr++;
   855 					continue;
   856 					}
   857 				if(numToCopy == 0)
   858 					{
   859 					userSideClients++;
   860 					continue;
   861 					}
   862 				umemget32(&clientAddr, entryPtr, sizeof(TClientName*));
   863 				entryPtr++;
   864 				Kern::KUDesPut(*((TDes8*)clientAddr), *(const TDesC8*)rcDataPtr->iClientName);
   865 				rcDataPtr++;
   866 				numToCopy--;
   867 				userSideClients++;
   868 				}
   869 			if(parms[1])
   870 				umemput32(ptr1, (TAny*)&param1, sizeof(TUint));
   871 			else
   872 				umemput32(ptr1, (TAny*)&userSideClients, sizeof(TUint));
   873 			break;
   874 			}
   875 		case RBusDevResManUs::EGetInfoOnResourcesInUseByClient:
   876 			{
   877 			TUint numToCopy;
   878 			RSimplePointerArray<TResourceInfoBuf> infoPtrs;
   879 			umemget(&infoPtrs, (TAny*)parms[1], sizeof(RSimplePointerArray<TResourceInfoBuf>));
   880 			numToCopy = (infoPtrs.Count() < param1) ? infoPtrs.Count() : param1;
   881 			umemput32(ptr1, (TAny*)&param1, sizeof(TUint));
   882 			TResourceInfoBuf** entriesAddr = infoPtrs.Entries();
   883 			TInt* entryPtr = (TInt*)entriesAddr;
   884 			TPowerResourceInfoV01* currRes = (TPowerResourceInfoV01*)iResourceInfoResCtrl->Ptr();
   885 			TResourceInfoBuf* clientAddr;
   886 			TResourceInfoBuf tempInfo;
   887 			for(TUint index = 0; index < numToCopy; index++)
   888 				{
   889 				umemget32(&clientAddr, entryPtr, sizeof(TResourceInfoBuf*));
   890 				entryPtr++;
   891 				r = ExtractResourceInfo(currRes, tempInfo);
   892 				if(r != KErrNone)
   893 					return r;
   894 				umemput((TAny*)clientAddr, (TAny*)&(tempInfo), tempInfo.Length());
   895 				currRes++;
   896 				}
   897 			break;
   898 			}
   899 		}
   900 	return r;
   901 	}
   902 
   903 void DChannelResManUs::HandleMsg(TMessageBase* aMsg)
   904     {
   905     TThreadMessage& m=*(TThreadMessage*)aMsg;
   906     TInt id=m.iValue;
   907     
   908     __KTRACE_OPT(KRESMANAGER, Kern::Printf(" >ldd: DChannelResManUs::HandleMsg(TMessageBase* aMsg) id=%d\n", id));
   909 	
   910 	if (id==(TInt)ECloseMsg)
   911 		{
   912 		// Deregister here to ensure the correct thread ID is read
   913 		if(ClientHandle() != 0)
   914 			{
   915 			// Must de-register from Resource Controller before closing down
   916 			// Not checking return value - still need to delete allocated buffers
   917 #ifdef PRM_US_INSTRUMENTATION_MACRO
   918 	PRM_US_DEREGISTER_CLIENT_START_TRACE;
   919 #endif
   920 			((DPowerResourceController*)iPddPtr)->DeregisterProxyClient(ClientHandle());
   921 
   922 #ifdef PRM_US_INSTRUMENTATION_MACRO
   923 	PRM_US_DEREGISTER_CLIENT_END_TRACE;
   924 #endif
   925 			SetClientHandle(0);
   926 			}
   927 	    iMsgQ.iMessage->Complete(KErrNone,EFalse);
   928 		return;
   929 		}
   930     else if (id==KMaxTInt)
   931 		{
   932 		// DoCancel
   933 		DoCancel(m.Int0());
   934 		m.Complete(KErrNone,ETrue);
   935 		return;
   936 		}
   937 
   938     if (id<0)
   939 		{
   940 		// DoRequest
   941 		TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
   942 		TInt r=DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
   943 		m.Complete(r,ETrue);
   944 		}
   945     else
   946 		{
   947 		// DoControl
   948 		__KTRACE_OPT(KRESMANAGER, Kern::Printf(" >ldd: do control id=%d...\n", id));
   949 		TInt r=DoControl(id,m.Ptr0(),m.Ptr1());
   950 		m.Complete(r,ETrue);
   951 		}
   952 	}
   953 
   954 TInt DChannelResManUs::CancelTrackerRequests(TTrackingControl* aTracker, TBool aSingleRsrc, TUint aResourceId, TRequestStatus* aStatus)
   955 	{
   956 	// Cancel all outstanding requests from this client for a specified operation on 
   957 	// a specified resource
   958 
   959 	// Loop all entries in the iBusyQue of requests to locate a match for the 
   960 	// operation type and resource ID
   961 	//
   962 	// For each match, remove the buffer from the busy queue and return to the free queue
   963 	// If the request is already being processed, and so the callback function will be called
   964 	// later, then the callback will exit gracefully.
   965 	//
   966     __KTRACE_OPT(KRESMANAGER, Kern::Printf(" > DChannelResManUs::CancelTrackerRequests"));
   967 	TInt returnVal = KErrNone;
   968 	TBool statusMatched=EFalse;
   969 	TTrackingBuffer* firstLink = NULL;
   970 	TTrackingBuffer* lastLink = NULL;
   971 	TInt type = aTracker->iType;
   972 
   973 #ifdef PRM_US_INSTRUMENTATION_MACRO
   974 	if(type==EGetState)
   975 		{
   976 		PRM_US_CANCEL_GET_RESOURCE_STATE_START_TRACE;
   977 		}
   978 	else if(type==ESetState)
   979 		{
   980 		PRM_US_CANCEL_SET_RESOURCE_STATE_START_TRACE;
   981 		}
   982 #endif
   983 
   984 	if(aTracker->iBusyQue != NULL)
   985 		{
   986 		firstLink = (TTrackingBuffer*)(aTracker->iBusyQue->iA.iNext);
   987 		lastLink = (TTrackingBuffer*)(&(aTracker->iBusyQue->iA));
   988 		}
   989 	while(( firstLink!=lastLink )&&(!statusMatched))
   990 		{
   991 		TTrackingBuffer* buffer = firstLink;
   992 		TUint resourceId = buffer->GetResourceId();
   993 		if(aSingleRsrc)
   994 			if(resourceId != aResourceId)	// Required resource?
   995 				{
   996 				firstLink=(TTrackingBuffer*)(firstLink->iNext);
   997 				continue;
   998 				}
   999 		if(aStatus!=NULL)
  1000 			{
  1001 			TClientRequest *request;
  1002 			GET_USER_REQUEST(request, buffer, type)
  1003 			if(request->StatusPtr() == aStatus)
  1004 				{
  1005 				statusMatched = ETrue;
  1006 				}
  1007 			else
  1008 				{
  1009 				firstLink=(TTrackingBuffer*)(firstLink->iNext);
  1010 				continue;
  1011 				}
  1012 			}
  1013 		TInt r = KErrNone;
  1014 		if(type==EGetState)
  1015 			{
  1016 			TTrackGetStateBuf* stateBuf = (TTrackGetStateBuf*)firstLink;
  1017 			r=((DPowerResourceController*)iPddPtr)->CancelAsyncRequestCallBack(ClientHandle(),
  1018 															resourceId, (stateBuf->iCtrlBlock));
  1019 			}
  1020 		else if(type==ESetState)
  1021 			{
  1022 			TTrackSetStateBuf* stateBuf = (TTrackSetStateBuf*)firstLink;
  1023 			r = ((DPowerResourceController*)iPddPtr)->CancelAsyncRequestCallBack(ClientHandle(), 
  1024 															resourceId, (stateBuf->iCtrlBlock));
  1025 			}
  1026 		else if(type==ENotify)
  1027 			{
  1028 			TTrackNotifyBuf* notifyBuf = (TTrackNotifyBuf*)firstLink;
  1029 			r=((DPowerResourceController*)iPddPtr)->CancelNotification(ClientHandle(), resourceId,
  1030 															notifyBuf->iNotifyBlock);
  1031 			}
  1032 
  1033 		// Process the accumulated return value
  1034 		if((r==KErrCompletion)&&((returnVal==KErrNone)||(returnVal==KErrCancel)))
  1035 			{
  1036 			returnVal=KErrCompletion;	
  1037 			}
  1038 		else if((r==KErrInUse)&&
  1039 			((returnVal==KErrNone)||(returnVal==KErrCompletion)||(returnVal==KErrCancel)))
  1040 			{
  1041 			returnVal=KErrInUse;
  1042 			}
  1043 		else if(r!=KErrCancel)
  1044 			{
  1045 			returnVal=r;
  1046 			}
  1047 
  1048 		// Return the tracking buffer to the free queue
  1049 		TTrackingBuffer* tempLink = (TTrackingBuffer*)(firstLink->iNext);
  1050 		FreeTrackingBuffer(firstLink);
  1051 		firstLink = tempLink;
  1052 
  1053 #ifdef PRM_US_INSTRUMENTATION_MACRO
  1054 	if(type==EGetState)
  1055 		{
  1056 		PRM_US_CANCEL_GET_RESOURCE_STATE_END_TRACE;
  1057 		}
  1058 	else if(type==ESetState)
  1059 		{
  1060 		PRM_US_CANCEL_SET_RESOURCE_STATE_END_TRACE;
  1061 		}
  1062 #endif
  1063 		// Complete the TRequestStatus object
  1064 		if((r!=KErrCompletion)&&(r!=KErrInUse))
  1065 			{
  1066 			TClientRequest* request;
  1067 			GET_USER_REQUEST(request, buffer, type)
  1068 			Kern::QueueRequestComplete(iClient, request, r);
  1069 			}
  1070 
  1071 		} //  while
  1072 	return returnVal;
  1073 	}
  1074 
  1075 
  1076 TTrackingControl* DChannelResManUs::MapRequestToTracker(TInt aRequestType)
  1077 // Utility function to map identifiers for cancel commands to request types.
  1078 	{
  1079 	TTrackingControl *tracker=NULL;
  1080 	switch(aRequestType)
  1081 		{
  1082 		case RBusDevResManUs::ECancelChangeResourceStateRequests:
  1083 		case RBusDevResManUs::ECancelChangeResourceState:
  1084 			{
  1085 			tracker=iSetStateTracker;
  1086 			break;
  1087 			}
  1088 		case RBusDevResManUs::ECancelGetResourceStateRequests:
  1089 		case RBusDevResManUs::ECancelGetResourceState:
  1090 			{
  1091 			tracker=iGetStateTracker;
  1092 			break;
  1093 			}
  1094 		case RBusDevResManUs::ECancelChangeNotificationRequests:
  1095 		case RBusDevResManUs::ECancelRequestChangeNotification:
  1096 			{
  1097 			tracker=iListenableTracker;
  1098 			break;
  1099 			}
  1100 		default:
  1101 			{
  1102 			__ASSERT_ALWAYS(0,RESMANUS_FAULT());
  1103 			}
  1104 		}
  1105 	return tracker;
  1106 	}
  1107 
  1108 
  1109 TInt DChannelResManUs::CancelRequestsOfType(TInt aRequestType, TRequestStatus* aStatus)
  1110 // Cancel a particular request. This may be qualified by the type of operation
  1111     {
  1112 	__ASSERT_ALWAYS(((aRequestType==RBusDevResManUs::ECancelChangeResourceState)||
  1113 					(aRequestType==RBusDevResManUs::ECancelGetResourceState)||
  1114 					(aRequestType==RBusDevResManUs::ECancelRequestChangeNotification)||
  1115 					(KMaxTInt)),
  1116 					RESMANUS_FAULT());
  1117 	// For the KMaxTInt case, the type of the request is not known and so all trackers
  1118 	// must be considered before the request is found.
  1119 	// For all other cases, only the relevant tracker is searched.
  1120 	TInt r=KErrNone;
  1121 	if(aRequestType!=KMaxTInt)
  1122 		{
  1123 		TTrackingControl*tracker=MapRequestToTracker(aRequestType);
  1124 		r=CancelTrackerRequests(tracker, EFalse, 0, aStatus);
  1125 		}
  1126 	else
  1127 		{
  1128 		TTrackingControl* tracker[3] = {iGetStateTracker, iSetStateTracker, iListenableTracker};
  1129 		TUint8 index=0;
  1130 		while((index<3) && (r==KErrNone))
  1131 			{
  1132 			r=CancelTrackerRequests(tracker[index], EFalse, 0, aStatus);
  1133 			++index;
  1134 			}
  1135 		}
  1136 	if(r==KErrCancel) 
  1137 		r=KErrNone;	// All cancellations were successful
  1138 
  1139 	return r;
  1140 	}
  1141 
  1142 
  1143 void DChannelResManUs::DoCancel(TInt aMask)
  1144 // Cancel an outstanding request.
  1145     {
  1146 	TRequestStatus* status = (TRequestStatus*)aMask;
  1147 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoCancel, TRequestStatus addr = 0x%x",(TInt)status));
  1148 
  1149 	CancelRequestsOfType(KMaxTInt, status); // Ignore return value
  1150 	return;
  1151 	}
  1152 
  1153 TInt DChannelResManUs::DoRequest(TInt aReqNo, TRequestStatus* /*aStatus*/, TAny* a1, TAny* a2)
  1154 // Asynchronous requests.
  1155     {
  1156     __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)"));
  1157 
  1158     TInt r=KErrNone;
  1159     switch (aReqNo)
  1160 		{
  1161 		case RBusDevResManUs::EChangeResourceState:
  1162 			{
  1163 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case EChangeResourceState"));
  1164 			// a1 specifies the identifier of the required resource
  1165 			// a2 specifies the required state for the resource
  1166 			//
  1167 			TUint *param = (TUint*)a2;
  1168 			TUint resourceId = (TUint)a1;
  1169 			TInt newState = (TInt)param[0];
  1170 
  1171 #ifdef PRM_US_INSTRUMENTATION_MACRO
  1172 	PRM_US_SET_RESOURCE_STATE_START_TRACE;
  1173 #endif
  1174 				// Invoke the API
  1175 				r=((DPowerResourceController*)iPddPtr)->ChangeResourceState(ClientHandle(),
  1176 														resourceId, newState, (TPowerResourceCb*)param[1]);
  1177 			break;
  1178 			}
  1179 
  1180 		case RBusDevResManUs::EGetResourceState:
  1181 			{
  1182 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case EGetResourceState"));
  1183 			// a1 specifies the resource ID
  1184 			// a2 specifies the container stating if a cached value is required, the address of the variable
  1185 			// to be update with the state value and the address of the level owner ID
  1186 			//
  1187 			TUint resourceId = (TUint)a1;
  1188 			TUint *parms = (TUint*)a2;
  1189 			TBool cached = (TBool)(parms[0]);
  1190 
  1191 #ifdef PRM_US_INSTRUMENTATION_MACRO
  1192 	PRM_US_GET_RESOURCE_STATE_START_TRACE;
  1193 #endif
  1194 				// Always invoke the asynchronous version of the API
  1195 				r=((DPowerResourceController*)iPddPtr)->GetResourceState(ClientHandle(),
  1196 																		resourceId, cached, *((TPowerResourceCb*)parms[3]));
  1197 			break;
  1198 			}
  1199 
  1200 
  1201 		case RBusDevResManUs::ERequestChangeNotification:
  1202 			{
  1203 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case ERequestChangeNotification"));
  1204 			// a1 specifies the resource ID
  1205 			r=((DPowerResourceController*)iPddPtr)->RequestNotification(ClientHandle(),
  1206 														(TUint)a1, *((DPowerResourceNotification*)a2));
  1207 			break;
  1208 			}
  1209 
  1210 		case RBusDevResManUs::ERequestQualifiedChangeNotification:
  1211 			{
  1212 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case ERequestQualifiedChangeNotification"));
  1213 			// a1 specifies the threshold value that the state is to change by
  1214 			// a2 specifies the address of the container holding the resourceID and the required direction
  1215 			TInt threshold = (TInt)a1;
  1216 			TUint *parms = (TUint*)a2;
  1217 			TUint resourceId = parms[0];
  1218 			TBool direction = (TBool)(parms[1]);			
  1219 			r=((DPowerResourceController*)iPddPtr)->RequestNotification(ClientHandle(),
  1220 														resourceId, *((DPowerResourceNotification*)parms[2]), threshold, direction);
  1221 			break;
  1222 			}
  1223 
  1224 		default:
  1225 	    	return KErrNotSupported;
  1226 		}
  1227 	    return r;
  1228     }
  1229 
  1230 TInt DChannelResManUs::DoControl(TInt aFunction, TAny* a1, TAny* a2)
  1231 // Synchronous requests.
  1232     {
  1233     __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DoControl(TInt aFunction, TAny* a1, TAny* a2)") );
  1234 
  1235     TInt r=KErrNone;
  1236     switch (aFunction)
  1237 		{
  1238 		case RBusDevResManUs::EInitialise:
  1239 			{
  1240 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EInitialise"));
  1241 			// a1 specifies the array describing the number of 'gettable' and 'settable' state resources
  1242 			// and the number of 'listenable' resources
  1243 			//
  1244 			TUint8 *stateRes = (TUint8*)a1;
  1245 #ifdef PRM_US_INSTRUMENTATION_MACRO
  1246 	PRM_US_REGISTER_CLIENT_START_TRACE;
  1247 #endif
  1248 			// The call to the Resource Controller's AllocReserve method requires two parameters:
  1249 			// the number of client level objects and the number of request message objects
  1250 			// Each 'settable' state resource requires a client level object and a request message object
  1251 			// Each 'gettable' state resource requires a request message object, only.
  1252 			// Call Resource Control to make allocations
  1253 			r=((DPowerResourceController*)iPddPtr)->AllocReserve(ClientHandle(),
  1254 															stateRes[1],							// Number of settable
  1255 															(TUint8)(stateRes[1] + stateRes[0]));	// Number of (settable + gettable)
  1256 #ifdef PRM_US_INSTRUMENTATION_MACRO
  1257 	PRM_US_REGISTER_CLIENT_END_TRACE;
  1258 #endif
  1259 			if(r==KErrNone)
  1260 				{
  1261 				// Require 1 TPowerResourceCb object per gettable resource state
  1262 				// Require 1 TPowerResourceCb object per settable resource state
  1263 				// Require 1 DPowerResourceNotification object per listenable resource
  1264 				//
  1265 				if(stateRes[0]>0)
  1266 					r=InitTrackingControl(iGetStateTracker,EGetState,stateRes[0]);
  1267 				if((r==KErrNone) && (stateRes[1]>0))
  1268 					r=InitTrackingControl(iSetStateTracker,ESetState,stateRes[1]);
  1269 				if((r==KErrNone) && (stateRes[2]>0))
  1270 					r=InitTrackingControl(iListenableTracker,ENotify,stateRes[2]);
  1271 #ifdef _DUMP_TRACKERS
  1272 			if((r=DumpTracker(iGetStateTracker))!=KErrNone)
  1273 				break;
  1274 			if((r=DumpTracker(iSetStateTracker))!=KErrNone)
  1275 				break;
  1276 #endif
  1277 				}
  1278 			break;
  1279 			}
  1280 
  1281 		case RBusDevResManUs::EGetNoOfResources:
  1282 			{
  1283 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNoOfResources"));
  1284 			TUint numResources;
  1285 			r=((DPowerResourceController*)iPddPtr)->GetNumResourcesInUseByClient(ClientHandle(),0,numResources);
  1286 			iResInfoValid = 0;			// New numResources invalidates the iResInfoXXXX information
  1287 			iResInfoStoredClientId = 0;
  1288 			iResInfoStoredNum = 0;
  1289 			if(r!=KErrNone)
  1290 				return r;
  1291 			// a2 specifies whether the resource information should be loaded
  1292 			if((r==KErrNone)&&(a2!=NULL))
  1293 				{
  1294 				TUint prevNumRes = 0;
  1295 				while((numResources != prevNumRes)&&(r==KErrNone))
  1296 					{
  1297 					// if the number of resources is greater than can be accommodated by the array,
  1298 					// re-size it
  1299 					if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
  1300 						break;
  1301 					prevNumRes = numResources;
  1302 					// Get the resource info from the Resource Controller
  1303 					// Specify 'aTargetClientId' as zero to access all resources
  1304 					iResourceInfoResCtrl->SetLength(0);
  1305 					r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
  1306 															ClientHandle(),0,numResources,iResourceInfoResCtrl);
  1307 					}
  1308 				if(r==KErrNone)
  1309 					{
  1310 					iResInfoValid = 1;
  1311 					iResInfoStoredClientId = KAllResInfoStored;
  1312 					iResInfoStoredNum = numResources;
  1313 					}
  1314 				}
  1315 			if(r==KErrNone)
  1316 				*(TUint*)a1 = numResources;
  1317 			break;
  1318 			}
  1319 
  1320 		case RBusDevResManUs::EGetAllResourcesInfo:
  1321 			{
  1322 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetAllResourcesInfo"));
  1323 			// Parameters are passed in TUint* parms[2]
  1324 			// The address of the number of resources is at element 0
  1325 			// The flag to indicate if the resource info stored is to be refreshed is at element 1
  1326 			TUint* parms = (TUint*)a2;
  1327 			TUint numResources = *(TUint*)parms[0];
  1328 			TBool refresh=(TBool)(parms[1]);
  1329 			
  1330 			// The results are to be written to an RSimplePointerArray, the address is in a1
  1331 			// Check that the array has enough elements
  1332 			if(refresh)
  1333 				{
  1334 				// For the refresh option, invoke Resource Controller API once, only (do not recurse)
  1335 				// If the number of requested resources is greater than can be accommodated by the array,
  1336 				// re-size it
  1337 				if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
  1338 					break;
  1339 				// Get the resource info from the Resource Controller
  1340 				// Specify 'aTargetClientId' as zero to access all resources
  1341 				iResourceInfoResCtrl->SetLength(0);
  1342 				r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
  1343 														ClientHandle(),0,numResources,iResourceInfoResCtrl);
  1344 				if(numResources != iResInfoStoredNum)
  1345 					{
  1346 					iResInfoValid = 0;		// Assume cohesion is now lost 
  1347 					iResInfoStoredClientId = 0;
  1348 					iResInfoStoredNum = 0;
  1349 					}
  1350 				}
  1351 			else
  1352 				{
  1353 				// If the information stored is not valid or is not for all resources return KErrNotReady 
  1354 				if((iResInfoValid != 1)||(iResInfoStoredClientId != KAllResInfoStored))
  1355 					{
  1356 					r=KErrNotReady;
  1357 					break;
  1358 					}
  1359 				// The number of resources for which information is available in this case is iResInfoStoredNum
  1360 				numResources = iResInfoStoredNum;
  1361 				}
  1362 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
  1363 			TPowerResourceInfoV01* currRes = (TPowerResourceInfoV01*)iResourceInfoResCtrl->Ptr();
  1364 			for(TUint index = 0; index < numResources; index++)
  1365 				{
  1366 				CheckForCandidateAsyncResource(currRes);
  1367 				CheckForCandidateSharedResource(currRes);
  1368 				currRes++;
  1369 				}
  1370 #endif
  1371 			*(TUint*)(parms[0]) = numResources;
  1372 
  1373 			break;
  1374 			}
  1375 
  1376 		case RBusDevResManUs::EGetNoOfClients:
  1377 		case RBusDevResManUs::EGetNumClientsUsingResource:
  1378 			{
  1379 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNoOfClients"));
  1380 			// Parameters are passed in TUint parms[3]
  1381 			// The flag to indicate if kernel-side clients are to be included is at element 0
  1382 			// The ID of the resource of interest (0 is expected for EGetNoOfClients)
  1383 			// The flag to indicate if the client info is to be read now is at element 1
  1384 			TUint *parms = (TUint*)a2;
  1385 			TUint includeKern = parms[0];
  1386 			TUint resourceId = parms[1];
  1387 			TUint infoRead = parms[2];
  1388 			TUint requiredId = resourceId;
  1389 			if(aFunction == RBusDevResManUs::EGetNoOfClients)
  1390 				{
  1391 				__ASSERT_ALWAYS(resourceId==0,RESMANUS_FAULT());
  1392 				requiredId = KAllClientInfoStored;
  1393 				}
  1394 			TUint numClients = 0;
  1395 			if(includeKern==1)
  1396 				{
  1397 				// Client must exhibit PlatSec capability ReadDeviceData
  1398 				if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNoOfClients")))
  1399 					{
  1400 					r =  KErrPermissionDenied;
  1401 					break;
  1402 					}
  1403 				if(r==KErrNone)
  1404 					r=((DPowerResourceController*)iPddPtr)->GetNumClientsUsingResource(ClientHandle(),resourceId,numClients);
  1405 				}
  1406 			else
  1407 				numClients = (TUint)(iDevice->iOpenChannels);
  1408 
  1409 			// New numClients invalidates the iClientInfoXXXX information
  1410 			iClientInfoValid = 0;
  1411 			iClientInfoStoredResId = 0;
  1412 			iClientInfoStoredNum= 0;
  1413 
  1414 			if((r==KErrNone)&&(infoRead==1))
  1415 				{
  1416 				// Capability check already performed, so no need to repeat ...
  1417 				TUint prevNumClients = 0;
  1418 				while((numClients != prevNumClients)&&(r == KErrNone))
  1419 					{
  1420 					// Ensure buffer is large enough to store the information
  1421 					if((r=EnsureSizeIsSufficient(iClientNamesResCtrl, (TInt)(numClients*sizeof(TPowerClientInfoV01))))!=KErrNone)
  1422 						break;
  1423 					prevNumClients = numClients;
  1424 					// Invoke the API
  1425 					r=((DPowerResourceController*)iPddPtr)->GetInfoOnClientsUsingResource(ClientHandle(),
  1426 																					resourceId,numClients,iClientNamesResCtrl);
  1427 					};
  1428 
  1429 				if(r==KErrNone)
  1430 					{
  1431 					iClientInfoValid = 1;
  1432 					iClientInfoStoredResId = requiredId;
  1433 					iClientInfoStoredNum = numClients;
  1434 					if(includeKern!=1)
  1435 						{
  1436 						TUint numAllClients = numClients;
  1437 						numClients = 0;
  1438 						TPowerClientInfoV01* rcDataPtr = (TPowerClientInfoV01*)(iClientNamesResCtrl->Ptr());
  1439 						for(TUint i=0; i<numAllClients; i++)
  1440 							{
  1441 							if( rcDataPtr->iClientId & USER_SIDE_CLIENT_BIT_MASK)
  1442 								++numClients;
  1443 							++rcDataPtr;
  1444 							}
  1445 						}
  1446 					}
  1447 				}
  1448 			if(r==KErrNone)
  1449 				*(TUint*)a1 = numClients;
  1450 			break;
  1451 			}
  1452 
  1453 		case RBusDevResManUs::EGetNamesAllClients:
  1454 		case RBusDevResManUs::EGetInfoOnClientsUsingResource:
  1455 			{
  1456 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNamesAllClients-EGetInfoOnClientsUsingResource"));
  1457 			// Parameters are passed in TUint* parms[4]
  1458 			// The address of the number of clients is at element 0
  1459 			// The flag to indicate if kernel-side info is requested is at element 1
  1460 			// The resource ID is at element 2
  1461 			// The flag to indicate if the client information stored is to be refreshed is at element 3
  1462 			TUint* parms = (TUint*)a2;
  1463 			TUint numClients = *(TUint*)parms[0];
  1464 			TBool includeKern=(TBool)(parms[1]);
  1465 			TUint resourceId=(TUint)(parms[2]);
  1466 			TBool refresh=(TBool)(parms[3]);
  1467 		
  1468 			TUint numClientsAvailable = 0; 
  1469 			iClientNamesResCtrl->SetLength(0);
  1470 			
  1471 			if(includeKern)
  1472 				{
  1473 				// Client must exhibit PlatSec capability ReadDeviceData
  1474 				if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNamesAllClients-EGetInfoOnClientsUsingResource")))
  1475 					{
  1476 					r = KErrPermissionDenied;
  1477 					break;  // Early exit in event of error
  1478 					}
  1479 				TUint requiredId = (resourceId==0)?(TUint)KAllClientInfoStored:resourceId;
  1480 				if(refresh)
  1481 					{
  1482 					// For the refresh option, invoke Resource Controller API once, only (do not recurse)
  1483 					// If the number of clients is greater than can be accommodated by the array,
  1484 					// re-size it
  1485 					if((r=EnsureSizeIsSufficient(iClientNamesResCtrl, (TInt)(numClients*sizeof(TPowerClientInfoV01))))!=KErrNone)
  1486 						break;
  1487 					// Invoke the API
  1488 					numClientsAvailable = numClients; // Arbitrary initialisation (to silence compiler warning)
  1489 					r=((DPowerResourceController*)iPddPtr)->GetInfoOnClientsUsingResource(ClientHandle(),
  1490 																					resourceId,numClientsAvailable,iClientNamesResCtrl);
  1491 					if((r!=KErrNone)||(numClientsAvailable != iClientInfoStoredNum)||(iClientInfoStoredResId != requiredId))
  1492 						{
  1493 						iClientInfoValid = 0;	// Assume cohesion is now lost	
  1494 						iClientInfoStoredResId = 0;
  1495 						iClientInfoStoredNum = 0;
  1496 						}
  1497 					}
  1498 				else
  1499 					{
  1500 					// If the information stored is not valid, is not for the required resources return KErrNotReady 
  1501 					if((iClientInfoValid != 1)||(iClientInfoStoredResId != requiredId))
  1502 						r=KErrNotReady;
  1503 					// The number of clients for which information is available in this case is iClientInfoStoredNum
  1504 					numClientsAvailable = iClientInfoStoredNum;
  1505 					}
  1506 				}
  1507 			else
  1508 				{
  1509 				// Resource Controller will return information for the number of clients requested,
  1510 				// taken in order from its internal storage - but this will be regardless of whether
  1511 				// they are kernel-side or user-side; the USER_SIDE_CLIENT_BIT_MASK bit must be 
  1512 				// interrogated to determine this.
  1513 				//
  1514 				// Therefore, need to read all the clients - but to do this, must find out how many 
  1515 				// clients there are first.
  1516 				TUint numAllClients;
  1517 				r=((DPowerResourceController*)iPddPtr)->GetNumClientsUsingResource(ClientHandle(),resourceId,numAllClients);
  1518 				if(r!=KErrNone)
  1519 					break;  // Early exit in event of error
  1520 				if(numAllClients > 0)
  1521 					{
  1522 					if(refresh)
  1523 						{
  1524 						// For the refresh option, invoke Resource Controller API once, only (do not recurse)
  1525 						// If the number of clients is greater than can be accommodated by the array,
  1526 						// re-size it
  1527 						if((r=EnsureSizeIsSufficient(iClientNamesResCtrl, (TInt)(numAllClients*sizeof(TPowerClientInfoV01))))!=KErrNone)
  1528 							break;
  1529 						// Invoke the API
  1530 						r=((DPowerResourceController*)iPddPtr)->GetInfoOnClientsUsingResource(ClientHandle(),
  1531 																						resourceId,numAllClients,iClientNamesResCtrl);
  1532 						TUint requiredId = (resourceId==0)?(TUint)KAllClientInfoStored:resourceId;
  1533 						if((r!=KErrNone)||(numClientsAvailable != iClientInfoStoredNum)||(iClientInfoStoredResId != requiredId))
  1534 							{
  1535 							iClientInfoValid = 0;	// Assume cohesion is now lost	
  1536 							iClientInfoStoredResId = 0;
  1537 							iClientInfoStoredNum = 0;
  1538 							break;
  1539 							}
  1540 						else
  1541 							{
  1542 							iClientInfoValid = 1;
  1543 							iClientInfoStoredResId = requiredId;
  1544 							iClientInfoStoredNum = numAllClients;
  1545 							}
  1546 						}
  1547 					else
  1548 						{
  1549 						// If the information stored is not valid, is not for the required resources return KErrNotReady 
  1550 						TUint requiredId = (resourceId==0)?(TUint)KAllClientInfoStored:resourceId;
  1551 						if((iClientInfoValid != 1)||(iClientInfoStoredResId != requiredId))
  1552 							{
  1553 							r=KErrNotReady;
  1554 							break;
  1555 							}
  1556 						// The number of clients for which information is available in this case is iClientInfoStoredNum
  1557 						numAllClients = iClientInfoStoredNum;
  1558 						}
  1559 					numClientsAvailable = numAllClients;
  1560 					} // if(numAllClients > 0)
  1561 				}
  1562 			// Write the total number of user side cients available
  1563 			*(TUint*)parms[0] = numClientsAvailable;
  1564 			break;
  1565 			}
  1566 		case RBusDevResManUs::EGetNumResourcesInUseByClient:
  1567 			{
  1568 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumResourcesInUseByClient"));
  1569 			// a1 specifies the container holding the client name
  1570 			//
  1571 			
  1572 			// If client doesn't exist, return KErrNotFound
  1573 			// If client has appropriate capabilities, or if the client for which the information is sought
  1574 			// is user-side, invoke the Resource Controller API directly
  1575 			// Otherwise, return KErrPermissionDenied
  1576 			TUint clientId=0;
  1577 			r=((DPowerResourceController*)iPddPtr)->GetClientId(ClientHandle(),
  1578 															*(TDesC8*)a1,clientId);
  1579 			if(r!=KErrNone)
  1580 				return KErrNotFound;
  1581 			// Perform capability check
  1582 			if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNoOfClients")))
  1583 				{
  1584 				if(!(clientId & USER_SIDE_CLIENT_BIT_MASK))
  1585 					return KErrPermissionDenied;
  1586 				}
  1587 			TUint numResources=0;
  1588 			if(r==KErrNone)
  1589 				r=((DPowerResourceController*)iPddPtr)->GetNumResourcesInUseByClient(ClientHandle(),
  1590 																			clientId,numResources);
  1591 			// New numResources invalidates the iResXXXX information
  1592 			iResInfoValid = 0;
  1593 			iResInfoStoredClientId = 0;
  1594 			iResInfoStoredNum= 0;
  1595 
  1596 			// parms[1] specifies whether the resource information should be loaded
  1597 			if((r==KErrNone)&&(*(TUint*)a2 != NULL))
  1598 				{
  1599 				TUint prevNumRes = 0;
  1600 				while((numResources != prevNumRes)&&(r==KErrNone))
  1601 					{
  1602 					// if the number of resources is greater than can be accommodated by the array,
  1603 					// re-size it
  1604 					if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
  1605 						break;
  1606 					prevNumRes = numResources;
  1607 					// Get the resource info from the Resource Controller
  1608 					// Specify 'aTargetClientId' as zero to access all resources
  1609 					iResourceInfoResCtrl->SetLength(0);
  1610 					r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
  1611 															ClientHandle(),clientId,numResources,iResourceInfoResCtrl);
  1612 					}
  1613 				if(r==KErrNone)
  1614 					{
  1615 					iResInfoValid = 1;
  1616 					iResInfoStoredClientId = clientId;
  1617 					iResInfoStoredNum = numResources;
  1618 					}
  1619 				}
  1620 			if(r==KErrNone)
  1621 				*(TUint*)a2 = numResources;
  1622 			break;
  1623 			}
  1624 
  1625 		case RBusDevResManUs::EGetInfoOnResourcesInUseByClient:
  1626 			{
  1627 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetInfoOnResourcesInUseByClient"));
  1628 			// a1 specifies the container holding the client name
  1629 			// a2 specifies an array TUint* parms[3] which contains:
  1630 			//   - the address of the variable to write the number of reasources to
  1631 			//   - a pointer to the container to hold the resources' information
  1632 			//   - the flag to indicate whether the resource info should be (re-)read here
  1633 
  1634 			TUint clientId=0;
  1635 			TUint *parms = (TUint*)a2;
  1636 			TUint numResources = *(TUint*)parms[0];
  1637 			// The results are to be written to an RSimplePointerArray, the address is in parms[1]
  1638 			// Check that the array has enough elements
  1639 			// If client doesn't exist, return KErrNotFound
  1640 			// If client has appropriate capabilities, or if the client for which the information is sought
  1641 			// is user-side, invoke the Resource Controller API directly
  1642 			// Otherwise, return KErrPermissionDenied
  1643 			r=((DPowerResourceController*)iPddPtr)->GetClientId(ClientHandle(),
  1644 															*(TDesC8*)a1,clientId);
  1645 			if(r!=KErrNone)
  1646 				return KErrNotFound;
  1647 			// Perform capability check
  1648 			if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNoOfClients")))
  1649 				{
  1650 				if(!(clientId & USER_SIDE_CLIENT_BIT_MASK))
  1651 					return KErrPermissionDenied;
  1652 				}
  1653 
  1654 			TUint updatedNumResources = numResources;
  1655 			r=((DPowerResourceController*)iPddPtr)->GetNumResourcesInUseByClient(ClientHandle(),clientId,updatedNumResources);
  1656 			if(r!=KErrNone)
  1657 				break;
  1658 
  1659 			if(updatedNumResources>0)
  1660 				{
  1661 				if((TUint)(parms[2] != 0))
  1662 					{
  1663 					// For the refresh option, invoke Resource Controller API once, only (do not recurse)
  1664 					// If the number of requested resources is greater than can be accommodated by the array,
  1665 					// re-size it
  1666 					if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
  1667 						break;
  1668 					// Get the resource info from the Resource Controller
  1669 					// Specify 'aTargetClientId' as zero to access all resources
  1670 					iResourceInfoResCtrl->SetLength(0);
  1671 					r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
  1672 															ClientHandle(),clientId,numResources,iResourceInfoResCtrl);
  1673 					if((numResources != iResInfoStoredNum)||(iResInfoStoredClientId != clientId))
  1674 						{
  1675 						iResInfoValid = 0;		// Assume cohesion is now lost 
  1676 						iResInfoStoredClientId = 0;
  1677 						iResInfoStoredNum = 0;
  1678 						}
  1679 					}
  1680 				else
  1681 					{
  1682 					// If the information stored is not valid or is not for the required clientId return KErrNotReady 
  1683 					if((iResInfoValid != 1)||(iResInfoStoredClientId != clientId))
  1684 						r=KErrNotReady;
  1685 					// The number of resources for which information is available in this case is iResInfoStoredNum
  1686 					numResources = iResInfoStoredNum;
  1687 					}
  1688 				}
  1689 			if(r==KErrNone)
  1690 				*(TUint*)parms[0] = updatedNumResources;
  1691 
  1692 			break;
  1693 			}
  1694 
  1695 		case RBusDevResManUs::EGetResourceIdByName:
  1696 			{
  1697 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetResourceIdByName"));
  1698 			// a1 specifies the container holding the resource name
  1699 			// a2 specifies the variable to be update with the ID
  1700 			TUint resourceId;
  1701 			r=((DPowerResourceController*)iPddPtr)->GetResourceId(ClientHandle(), *(TDesC8*)a1, resourceId);
  1702 			if(r==KErrNone)
  1703 				*(TUint *)a2 = resourceId;
  1704 			break;
  1705 			}
  1706 
  1707 		case RBusDevResManUs::EGetResourceInfo:
  1708 			{
  1709 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetResourceInfo"));
  1710 			// a1 specifies the container holding the resource ID
  1711 			// a2 specifies the address of the container to be written to
  1712 
  1713 			TUint resourceId= (TUint)a1;
  1714 			TPowerResourceInfoBuf01 resCtrlInfo;
  1715 			resCtrlInfo.SetLength(0);
  1716 			TResourceInfoBuf tempInfo;
  1717 			r=((DPowerResourceController*)iPddPtr)->GetResourceInfo(ClientHandle(),resourceId,&resCtrlInfo);
  1718 			if(r==KErrNone)
  1719 				{
  1720 				// Copy the client buffer to tempInfo so that its size can be determined
  1721 				// by ExtractResourceInfo
  1722 				r=ExtractResourceInfo(&(resCtrlInfo()), tempInfo);
  1723 				}			
  1724 			if(r==KErrNone)
  1725 				{
  1726 				// Write the resources' info to the client thread
  1727 				*(TResourceInfoBuf*)a2 = tempInfo;
  1728 				}
  1729 			break;
  1730 			}
  1731 
  1732 
  1733 		case RBusDevResManUs::ECancelChangeResourceStateRequests:
  1734 		case RBusDevResManUs::ECancelGetResourceStateRequests:
  1735 		case RBusDevResManUs::ECancelChangeNotificationRequests:
  1736 			{
  1737 			TUint resourceId = (TUint)a1;
  1738 			TTrackingControl*tracker=MapRequestToTracker(aFunction);
  1739 			r=CancelTrackerRequests(tracker, ETrue, resourceId, NULL);
  1740 			if(r==KErrCancel)
  1741 				r=KErrNone;	// All cancellations were successful
  1742 			break;
  1743 			}
  1744 
  1745 		case RBusDevResManUs::ECancelChangeResourceState:
  1746 		case RBusDevResManUs::ECancelGetResourceState:
  1747 		case RBusDevResManUs::ECancelRequestChangeNotification:
  1748 			{
  1749 			TRequestStatus* status = (TRequestStatus*)a1;
  1750 			r=CancelRequestsOfType(aFunction, status);
  1751 			break;
  1752 			}
  1753 
  1754 
  1755 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
  1756 		case RBusDevResManUs::EGetNumCandidateAsyncResources:
  1757 			{
  1758 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumCandidateAsyncResources"));
  1759 			TUint numResources;
  1760 			GetNumCandidateAsyncResources(numResources);
  1761 			// Write the result to the client thread
  1762 			*(TUint*)a1 = numResources;
  1763 			break;
  1764 			}
  1765 		case RBusDevResManUs::EGetCandidateAsyncResourceId:
  1766 			{
  1767 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetCandidateAsyncResourceId"));
  1768 			// Get the index to use
  1769 			TUint index = (TUint)a1;
  1770 			TUint resourceId = 0;
  1771 			r=GetCandidateAsyncResourceId(index, resourceId);
  1772 			if(r==KErrNone)				// Write the result to the client thread
  1773 				*(TUint*)a2 = resourceId;
  1774 			break;
  1775 			}
  1776 
  1777 		case RBusDevResManUs::EGetNumCandidateSharedResources:
  1778 			{
  1779 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumCandidateSharedResources"));
  1780 			TUint numResources;
  1781 			GetNumCandidateSharedResources(numResources);
  1782 			// Write the result to the client thread
  1783 			*(TUint*)a1 = numResources;
  1784 			break;
  1785 			}
  1786 		case RBusDevResManUs::EGetCandidateSharedResourceId:
  1787 			{
  1788 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetCandidateSharedResourceId"));
  1789 			// Get the index to use
  1790 			TUint index = (TUint)a1;
  1791 			TUint resourceId = 0;
  1792 			r=GetCandidateSharedResourceId(index, resourceId);
  1793 			if(r==KErrNone)				// Write the result to the client thread
  1794 				*(TUint*)a2 = resourceId;
  1795 			break;
  1796 			}
  1797 #endif
  1798 
  1799 		case RBusDevResManUs::EGetResourceControllerVersion:
  1800 			{
  1801 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetResourceControllerVersion"));
  1802 			// a1 specifies the address of the TVersion variable to be written to
  1803 			// a2 is not used
  1804 			TUint version;
  1805 			if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(), 
  1806 																	KResManControlIoGetVersion, 
  1807 																	(TAny*)&version,
  1808 																	NULL, 
  1809 																	NULL))!=KErrNone)
  1810 				return r;
  1811 			// Write the required information
  1812 			*(TUint*)a1 = version;
  1813 			break;
  1814 			}
  1815 		
  1816 		case RBusDevResManUs::EGetNumDependentsForResource:
  1817 			{
  1818 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumDependentsForResource"));
  1819 			// a1 specifies a pointer to the variable to be written to
  1820 			// a2 specifies an array TUint parms[2] which contains:
  1821 			//   - the resource ID
  1822 			//   - flag to indicate if dependency information is to be loaded as part of this call
  1823 			TUint *parms = (TUint*)a2;
  1824 			TUint numDependents = 0;
  1825 			r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(), 
  1826 																	KResManControlIoGetNumDependents,
  1827 																	(TAny*)(parms[0]),	// Resource ID
  1828 																	&numDependents,
  1829 																	NULL);
  1830 			iResDepsValid=EFalse; // The number of dependents may differ from the dependency information stored
  1831 			if(r!=KErrNone)
  1832 				return r;
  1833 
  1834 			// Load the dependency information, if required.
  1835 			if(parms[1])
  1836 				{
  1837 				// The dependency information may be updated subsequent to the request for the number of dependents. In order
  1838 				// to provide a coherent number and array of dependents, the requests for dependency information will be
  1839 				// re-issued if the (new) number of dependents differs from that previously read.
  1840 				TUint prevNumDeps = 0;
  1841 				TUint newNumDeps = numDependents;
  1842 				while((newNumDeps != prevNumDeps)&&(r == KErrNone))
  1843 					{
  1844 					if((r=EnsureSizeIsSufficient(iResourceDependencyIds, (TInt)(newNumDeps*sizeof(SResourceDependencyInfo))))!=KErrNone)
  1845 						return r;
  1846 					prevNumDeps = newNumDeps;
  1847 					if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(), 
  1848 																			KResManControlIoGetDependentsId,
  1849 																			(TAny*)(parms[0]),	// Resource ID
  1850 																			(TAny*)(iResourceDependencyIds),
  1851 																			(TAny*)&newNumDeps))!=KErrNone)
  1852 						return r;
  1853 					};
  1854 				// Dependency information now in synch with number reported
  1855 				numDependents = newNumDeps;
  1856 				iNumResDepsStored = newNumDeps;
  1857 				iResDepsValid = ETrue;
  1858 				}
  1859 			// Write the number of dependents to the client thread
  1860 			*(TUint*)a1 = numDependents;
  1861 			break;
  1862 			}
  1863 
  1864 
  1865 		case RBusDevResManUs::EGetDependentsIdForResource:
  1866 			{
  1867 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetDependentsIdForResource"));
  1868 			// a1 specifies a pointer to the variable to hold the number of dependencies
  1869 			// a2 specifies an array TUint parms[4] which contains:
  1870 			//   - the resource ID
  1871 			//   - the address of the array to write the required IDs to
  1872 			//   - flag to indicate if dependency information is to be (re-)loaded as part of this call
  1873 			TUint *parms = (TUint*)a2;
  1874 			TUint numDependents = 0;
  1875 
  1876 			// (Re-)Load the dependency information, if required.
  1877 			if(parms[2])
  1878 				{
  1879 				if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(), 
  1880 															KResManControlIoGetNumDependents, 
  1881 															(TAny*)(parms[0]), 
  1882 															(TAny*)&numDependents, 
  1883 															NULL))!=KErrNone)
  1884 					return r;
  1885 
  1886 				iResDepsValid=EFalse; // The number of dependents may differ from the dependency information stored
  1887 				// In order to provide a coherent number and array of dependents, the requests for dependency information
  1888 				// will be re-issued if the (new) number of dependents differs from that previously read.
  1889 				TUint prevNumDeps = 0;
  1890 				TUint newNumDeps = numDependents;
  1891 				while(newNumDeps != prevNumDeps)
  1892 					{
  1893 					if((r=EnsureSizeIsSufficient(iResourceDependencyIds, (TInt)(newNumDeps*sizeof(SResourceDependencyInfo))))!=KErrNone)
  1894 						return r;
  1895 					prevNumDeps = newNumDeps;
  1896 					if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(), 
  1897 																			KResManControlIoGetDependentsId,
  1898 																			(TAny*)(parms[0]),	// Resource ID
  1899 																			(TAny*)(iResourceDependencyIds),
  1900 																			(TAny*)&newNumDeps))!=KErrNone)
  1901 						return r;
  1902 					};
  1903 
  1904 				// Dependency information now in synch with number reported
  1905 				numDependents = newNumDeps;
  1906 				iNumResDepsStored = newNumDeps;
  1907 				iResDepsValid = ETrue;
  1908 				}
  1909 
  1910 			// If iResDepsValid equals zero, the results are invalid - so return KErrNotReady.
  1911 			if(iResDepsValid==0)
  1912 				return KErrNotReady;
  1913 
  1914 			// Write the number of dependencies available to the client
  1915 			*(TUint*)a1 = iNumResDepsStored;
  1916 			// Write the dependencies to the client array if it is of sufficient size
  1917 			// Copy the required dependency information to the user-supplied container.
  1918 			parms[1] = (TUint)iResourceDependencyIds;
  1919 			break;
  1920 			}
  1921 		
  1922 		default:
  1923 			{
  1924 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl default 0x%x", aFunction));
  1925 			r=KErrNotSupported;
  1926 			}
  1927 		}
  1928 	    return(r);
  1929     }
  1930 
  1931 
  1932 TInt DChannelResManUs::EnsureSizeIsSufficient(HBuf*& aBuffer, TInt aMinSize)
  1933 	{
  1934 // Utility function to ensure a buffer is of at least the minimum required size
  1935 // If the buffer is to small, an attempt is made to increase its size.
  1936 // If the re-sizing fails, KErrNoMemory is returned; otherwise KErrNone.
  1937 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::EnsureSizeIsSufficient"));
  1938 
  1939 	if(aBuffer->MaxLength() < aMinSize)
  1940 		{
  1941 		aBuffer = aBuffer->ReAlloc(aMinSize);
  1942 		if(aBuffer->MaxLength() < aMinSize)
  1943 			return KErrNoMemory; // ReAlloc failed - aBuffer is unchanged
  1944 		}
  1945 	aBuffer->SetLength(0);
  1946 	return KErrNone;
  1947 	}
  1948 
  1949 void DChannelResManUs::FreeTrackingBuffer(TTrackingBuffer*& aBuffer)
  1950 	{
  1951 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::FreeTrackingBuffer"));
  1952 	// Function invoked for to free tracking buffers from the busy to free queue of a tracking control
  1953 	__ASSERT_ALWAYS((aBuffer!=NULL),RESMANUS_FAULT());
  1954 	NKern::FMWait(&iBufferFastMutex);
  1955 	TTrackingControl* tracker = aBuffer->GetTrackingControl();
  1956 	SDblQue* bufQue = aBuffer->GetQue();
  1957 
  1958 	__ASSERT_ALWAYS(((tracker!=NULL)&&(bufQue!=NULL)),RESMANUS_FAULT());
  1959 
  1960 	// Check that the buffer is still in the busy queue of the tracker - exit if not
  1961 	if(bufQue == tracker->iBusyQue)
  1962 		{
  1963 		aBuffer->Deque();
  1964 		tracker->iFreeQue->Add(aBuffer);
  1965 		aBuffer->SetQue(tracker->iFreeQue);
  1966 		}
  1967 	NKern::FMSignal(&iBufferFastMutex);	
  1968 	}
  1969 
  1970 
  1971 TInt DChannelResManUs::GetAndInitTrackingBuffer(TTrackingControl*& aTracker, TTrackingBuffer*& aBuffer, TUint aResourceId, TRequestStatus* aStatus)
  1972 	{
  1973 // Utility function - perform the necessary processing to get a buffer to support
  1974 // asynchronous requests to change the state of a resource
  1975 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetAndInitTrackingBuffer"));
  1976 	TInt r=KErrNone;
  1977 	NKern::FMWait(&iBufferFastMutex);
  1978 	if(aTracker->iFreeQue->IsEmpty())
  1979 		r = KErrUnderflow;
  1980 	else
  1981 		{
  1982 		// Need intermediate cast from SDblQueLink* to TAny* before TTrackingBuffer*
  1983 		TAny* ptr = (TAny*)(aTracker->iFreeQue->GetFirst());
  1984 		aBuffer = (TTrackingBuffer*)ptr;
  1985 		aTracker->iBusyQue->Add((SDblQueLink*)ptr);
  1986 		aBuffer->SetQue(aTracker->iBusyQue);
  1987 		aBuffer->SetResourceId(aResourceId);
  1988 		TClientRequest* request;
  1989 		TTrackingControl* tracker = aBuffer->GetTrackingControl();
  1990 		GET_USER_REQUEST(request, aBuffer, tracker->iType);
  1991 		request->Reset();
  1992 		request->SetStatus(aStatus);
  1993 		}
  1994 	NKern::FMSignal(&iBufferFastMutex);	
  1995 	return r;
  1996 	}
  1997 
  1998 TInt DChannelResManUs::GetStateBuffer(TTrackingControl*& aTracker, TTrackingBuffer*& aBuffer, TUint aResourceId, TInt* aState, TInt* aLevelOwnerPtr, TPowerResourceCb*& aCb, TRequestStatus* aStatus)
  1999 	{
  2000 // Utility function - perform the necessary processing to get a buffer and control block
  2001 // to support asynchronous requests to change the state of a resource
  2002 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetStateBuffer"));
  2003 
  2004 	TInt r=GetAndInitTrackingBuffer(aTracker, aBuffer, aResourceId, aStatus);
  2005 	if(r==KErrNone)
  2006 		{
  2007 		TTrackGetStateBuf* stateBuf = (TTrackGetStateBuf*)aBuffer;
  2008 		stateBuf->iRequest->SetDestPtr1(aState);
  2009 		stateBuf->iRequest->SetDestPtr2(aLevelOwnerPtr);
  2010 		// Use placement new to update the content of the TPowerResourceCb
  2011 		aCb = &(stateBuf->iCtrlBlock);
  2012 		new (aCb) TPowerResourceCb(&AsyncCallBackFn,(TAny*)aBuffer,iDfcQ,KResManCallBackPriority);
  2013 		}
  2014 	return r;
  2015 	}
  2016 
  2017 
  2018 #ifdef _DUMP_TRACKERS
  2019 TInt DChannelResManUs::DumpTracker(TTrackingControl* aTracker)
  2020 	{
  2021 	Kern::Printf("\nDChannelResManUs::DumpTracker");
  2022 	Kern::Printf("Tracker at 0x%x\n",aTracker);
  2023 	if(NULL==aTracker)
  2024 		return KErrGeneral;
  2025 	Kern::Printf("iType=%d",aTracker->iType);
  2026 	switch(aTracker->iType)
  2027 		{
  2028 		case 0:
  2029 			Kern::Printf("= GetState tracker\n");
  2030 		break;
  2031 		case 1:
  2032 			Kern::Printf("= SetState tracker\n");
  2033 		break;
  2034 		case 2:
  2035 			Kern::Printf("= Notify tracker\n");
  2036 		break;
  2037 		}
  2038 	Kern::Printf("iOwningChannel at 0x%x\n",aTracker->iOwningChannel);
  2039 	Kern::Printf("iFreeQue at 0x%x\n",aTracker->iFreeQue);
  2040 	SDblQueLink* buf;
  2041 	if(aTracker->iFreeQue!=NULL)
  2042 		{
  2043 		buf=aTracker->iFreeQue->First();
  2044 		while(buf!=aTracker->iFreeQue->Last())
  2045 			{
  2046 			Kern::Printf("iFreeQue buffer at 0x%x\n",buf);
  2047 			TAny* intermediatePtr = (TAny*)buf;
  2048 			if((aTracker->iType == EGetState)||(aTracker->iType == ESetState))
  2049 				{
  2050 				TTrackStateBuf* tempBuf =(TTrackStateBuf*)intermediatePtr;
  2051 				Kern::Printf("buffer control block at 0x%x\n",tempBuf->iCtrlBlock);
  2052 				}
  2053 			buf= buf->iNext;
  2054 			};
  2055 		}
  2056 	Kern::Printf("iBusyQue at 0x%x\n",aTracker->iBusyQue);
  2057 	if(aTracker->iBusyQue!=NULL)
  2058 		{
  2059 		buf=aTracker->iBusyQue->First();
  2060 		while(buf!=aTracker->iBusyQue->Last())
  2061 			{
  2062 			Kern::Printf("iBusyQue buffer at 0x%x\n",buf);
  2063 			TAny* intermediatePtr = (TAny*)buf;
  2064 			if((aTracker->iType == EGetState)||(aTracker->iType == ESetState))
  2065 				{
  2066 				TTrackStateBuf* tempBuf =(TTrackStateBuf*)intermediatePtr;
  2067 				Kern::Printf("buffer control block at 0x%x\n",tempBuf->iCtrlBlock);
  2068 				}
  2069 			buf= buf->iNext;
  2070 			};
  2071 		}
  2072 
  2073 	return KErrNone;
  2074 	}
  2075 #endif
  2076 
  2077 TInt DChannelResManUs::InitTrackingControl(TTrackingControl*& aTracker, TUint8 aType, TUint8 aNumBuffers)
  2078 	{
  2079 // Set the tracker type, create the tracking queues and required tracking buffers.
  2080 // Assign all the tracking buffers to the free queue.
  2081 //
  2082     __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::InitTrackingControl()"));
  2083 
  2084 	TInt r = KErrNone;
  2085 	aTracker->iType = (TAsyncOpType)aType;
  2086 	aTracker->iOwningChannel = this;
  2087 	aTracker->iFreeQue = new SDblQue();
  2088 	__ASSERT_DEBUG(aTracker->iFreeQue != NULL, RESMANUS_FAULT());
  2089 	if(aTracker->iFreeQue == NULL)
  2090 		r = KErrNoMemory;
  2091 	if(r==KErrNone)
  2092 		{
  2093 		aTracker->iBusyQue = new SDblQue();
  2094 		__ASSERT_DEBUG(aTracker->iBusyQue != NULL, RESMANUS_FAULT());
  2095 		if(aTracker->iBusyQue == NULL)
  2096 			{
  2097 			delete aTracker->iFreeQue;
  2098 			r = KErrNoMemory;
  2099 			}
  2100 		}
  2101 	if(r==KErrNone)
  2102 		{
  2103 		for(TUint8 i=0; (i<aNumBuffers) && (r==KErrNone) ;i++)
  2104 			{
  2105 			TAny* buf = NULL;
  2106 			TAny* ptr=NULL; // To be assigned to non-NULL value later
  2107 			switch(aTracker->iType)
  2108 				{
  2109 				case EGetState:
  2110 					{
  2111 					buf = (TAny*)(new TTrackGetStateBuf(&AsyncCallBackFn,ptr,iDfcQ,KResManCallBackPriority));
  2112 					r = Kern::CreateClientDataRequest2(((TTrackGetStateBuf*)buf)->iRequest);
  2113 					break;
  2114 					}
  2115 				case ESetState:
  2116 					{
  2117 					buf = (TAny*)(new TTrackSetStateBuf(&AsyncCallBackFn, ptr, iDfcQ, KResManCallBackPriority));
  2118 					r = Kern::CreateClientRequest(((TTrackSetStateBuf*)buf)->iRequest);
  2119 					break;
  2120 					}
  2121 				case ENotify:
  2122 					{
  2123 					buf = (TAny*)(new TTrackNotifyBuf(&AsyncCallBackFn,ptr,iDfcQ,KResManCallBackPriority));
  2124 					r = Kern::CreateClientRequest(((TTrackNotifyBuf*)buf)->iRequest);
  2125 					break;
  2126 					}
  2127 				default:
  2128 					__ASSERT_ALWAYS(0,RESMANUS_FAULT());
  2129 				}
  2130 			__ASSERT_DEBUG(buf!=NULL, RESMANUS_FAULT());
  2131 			if((buf == NULL) || (r == KErrNoMemory))
  2132 				{
  2133 				r = KErrNoMemory;
  2134 				break;
  2135 				}
  2136 			else
  2137 				{
  2138 				((TTrackingBuffer*)buf)->SetTrackingControl(aTracker);
  2139 				(aTracker->iFreeQue)->Add((SDblQueLink*)buf);
  2140 				((TTrackingBuffer*)buf)->SetQue(aTracker->iFreeQue);
  2141 				}
  2142 			}
  2143 		// If buffer allocation failed, need to remove all previously-allocated buffers and the queues
  2144 		if(r!=KErrNone)
  2145 			{
  2146 			SDblQueLink* ptr = (aTracker->iFreeQue)->First();
  2147 			do
  2148 				{
  2149 				SDblQueLink* next = NULL;
  2150 				if(ptr !=NULL)
  2151 					next = ptr->iNext;
  2152 				delete ptr;
  2153 				ptr = next;
  2154 				} while ((ptr!=NULL)&&(ptr!=(aTracker->iFreeQue)->Last()));
  2155 			delete aTracker->iFreeQue;
  2156 			delete aTracker->iBusyQue;
  2157 			}
  2158 		}
  2159 	return r;
  2160 	}
  2161 
  2162 
  2163 void DChannelResManUs::RemoveTrackingControl(TTrackingControl*& aTracker)
  2164     {
  2165     __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::RemoveTrackingControl()"));
  2166 
  2167 	// Free the resource-tracking links and their respective queues
  2168 	TAny* buf;
  2169 	if(aTracker->iFreeQue!=NULL)
  2170 		{
  2171 		while(!aTracker->iFreeQue->IsEmpty())
  2172 			{
  2173 			buf = (TAny*)(aTracker->iFreeQue->GetFirst()); // Dequeues the element
  2174 			delete buf;
  2175 			}
  2176 		delete aTracker->iFreeQue;
  2177 		}
  2178 
  2179 	if(aTracker->iBusyQue!=NULL)
  2180 		{
  2181 		while(!aTracker->iBusyQue->IsEmpty())
  2182 			{
  2183 			buf = (TAny*)(aTracker->iBusyQue->GetFirst()); // Dequeues the element
  2184 			delete buf;
  2185 			}
  2186 		delete aTracker->iBusyQue;
  2187 		}
  2188 	delete aTracker;
  2189     }
  2190 
  2191 
  2192 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
  2193 void DChannelResManUs::CheckForCandidateAsyncResource(TPowerResourceInfoV01* aResource)
  2194 	{
  2195 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::CheckForCandidateAsyncResource"));
  2196 	// Proceed only if we already have less that the maximum number of candidate resources
  2197 	if(iNoCandidateAsyncRes >= MAX_NUM_CANDIDATE_RESOURCES)
  2198 		return;
  2199 	// For the purposes of asynchronous testing, we need a long latency resource
  2200 	if(((TInt)(aResource->iLatencyGet)==(TInt)(EResLongLatency)) && 
  2201 		((TInt)(aResource->iLatencySet)==(TInt)(EResLongLatency)))
  2202 		{
  2203 		// An additional requirement is that the level of the resource can be 
  2204 		// updated a sufficient amount of times to support the required testing.
  2205 		if(((aResource->iMaxLevel - aResource->iMinLevel) > LEVEL_GAP_REQUIRED_FOR_ASYNC_TESTING) &&
  2206 			((TInt)(aResource->iSense) == (TInt)(EResPositive)) )
  2207 			{
  2208 			TInt r=((DPowerResourceController*)iPddPtr)->GetResourceId(ClientHandle(), *(aResource->iResourceName), iCandidateAsyncResIds[iNoCandidateAsyncRes]);
  2209 			if(r!=KErrNone)
  2210 				{
  2211 				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Failed to identify long latency resource\n"));
  2212 				}
  2213 			else
  2214 				{
  2215 				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Potential async resource ID = %d\n",iCandidateAsyncResIds[iNoCandidateAsyncRes]));
  2216 				iHaveLongLatencyResource = ETrue;
  2217 				++iNoCandidateAsyncRes;
  2218 				}
  2219 			}
  2220 		}
  2221 	}
  2222 
  2223 
  2224 void DChannelResManUs::GetNumCandidateAsyncResources(TUint& aNumResources)
  2225 	{
  2226 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetNumCandidateAsyncResources"));
  2227 
  2228 	aNumResources = iNoCandidateAsyncRes;
  2229 	}
  2230 
  2231 TInt DChannelResManUs::GetCandidateAsyncResourceId(TUint aIndex, TUint& aResourceId)
  2232 	{
  2233 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetCandidateAsyncResourceId"));
  2234 	TInt r = KErrNone;
  2235 	if(aIndex>=iNoCandidateAsyncRes)
  2236 		r = KErrNotFound;
  2237 	else
  2238 		aResourceId = iCandidateAsyncResIds[aIndex];
  2239 	return r;
  2240 	}
  2241 
  2242 void DChannelResManUs::CheckForCandidateSharedResource(TPowerResourceInfoV01* aResource)
  2243 	{
  2244 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::CheckForCandidateSharedResource"));
  2245 
  2246 	// Proceed only if we already have less that the maximum number of candidate resources
  2247 	if(iNoCandidateSharedRes >= MAX_NUM_CANDIDATE_RESOURCES)
  2248 		return;
  2249 
  2250 	// For the purposes of testing shared usgae of resources, we need a shareable resource
  2251 	if((TInt)(aResource->iUsage)==(TInt)(EResShared))
  2252 		{
  2253 		// An additional requirement is that the level of the resource can be 
  2254 		// updated a sufficient amount of times to support the required testing.
  2255 		if(((aResource->iMaxLevel - aResource->iMinLevel) > LEVEL_GAP_REQUIRED_FOR_SHARED_TESTING) &&
  2256 			((TInt)(aResource->iSense) == (TInt)(EResPositive)) )
  2257 			{
  2258 			TInt r=((DPowerResourceController*)iPddPtr)->GetResourceId(ClientHandle(), *(aResource->iResourceName), iCandidateSharedResIds[iNoCandidateSharedRes]);
  2259 			if(r!=KErrNone)
  2260 				{
  2261 				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Failed to identify shared resource\n"));
  2262 				}
  2263 			else
  2264 				{
  2265 				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Potential shared resource ID = %d\n",iCandidateSharedResIds[iNoCandidateAsyncRes]));
  2266 				iHaveLongLatencyResource = ETrue;
  2267 				++iNoCandidateSharedRes;
  2268 				}
  2269 			}
  2270 		}
  2271 	}
  2272 
  2273 void DChannelResManUs::GetNumCandidateSharedResources(TUint& aNumResources)
  2274 	{
  2275 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetNumCandidateSharedResources"));
  2276 
  2277 	aNumResources = iNoCandidateSharedRes;
  2278 	}
  2279 
  2280 TInt DChannelResManUs::GetCandidateSharedResourceId(TUint aIndex, TUint& aResourceId)
  2281 	{
  2282 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetCandidateSharedResourceId"));
  2283 	TInt r = KErrNone;
  2284 	if(aIndex>=iNoCandidateSharedRes)
  2285 		r = KErrNotFound;
  2286 	else
  2287 		aResourceId = iCandidateSharedResIds[aIndex];
  2288 	return r;
  2289 	}
  2290 
  2291 #endif
  2292 
  2293 TInt DChannelResManUs::ExtractResourceInfo(const TPowerResourceInfoV01* aPwrResInfo, TResourceInfoBuf& aInfo)
  2294 	{
  2295 // Extract data from a TPowerResourceInfoV01 object to a TResourceInfo instance
  2296 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::ExtractResourceInfo"));
  2297 
  2298 	TInt r=KErrNone;
  2299 	TInt copyLength=(((aInfo().iName).MaxLength())<((aPwrResInfo->iResourceName)->Length()))?
  2300 					(aInfo().iName).MaxLength():
  2301 					(aPwrResInfo->iResourceName)->Length();
  2302 	(aInfo().iName).Copy((aPwrResInfo->iResourceName)->Ptr(),copyLength);
  2303 	aInfo().iId = aPwrResInfo->iResourceId;
  2304 	aInfo().iClass	= (TResourceClass)aPwrResInfo->iClass;
  2305 	aInfo().iType	= (TResourceType)aPwrResInfo->iType;
  2306 	aInfo().iUsage	= (TResourceUsage)aPwrResInfo->iUsage;
  2307 	aInfo().iSense	= (TResourceSense)aPwrResInfo->iSense;
  2308 	aInfo().iMinLevel = aPwrResInfo->iMinLevel;
  2309 	aInfo().iMaxLevel = aPwrResInfo->iMaxLevel;
  2310 
  2311 #ifdef _DUMP_TRACKERS
  2312 	r=DumpResource(aPwrResInfo);
  2313 #endif
  2314 	return r;
  2315 	}
  2316 
  2317 #ifdef _DUMP_TRACKERS
  2318 TInt DChannelResManUs::DumpResource(const TPowerResourceInfoV01* aResource)
  2319 	{
  2320 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DumpResource"));
  2321 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("Resource name = %S \n",aResource->iResourceName));
  2322 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("Resource ID = 0x%d \n",aResource->iResourceId));
  2323 	switch(aResource->iClass)
  2324 		{
  2325 		case DStaticPowerResource::EPhysical:
  2326 			{
  2327 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("class = EPhysical\n"));
  2328 			break;
  2329 			}
  2330 		case DStaticPowerResource::ELogical:
  2331 			{
  2332 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("class = ELogical\n"));
  2333 			break;
  2334 			}
  2335 		default:
  2336 			{
  2337 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("class = % is UNKNOWN!\n"));
  2338 			return KErrGeneral;
  2339 			}
  2340 		}
  2341 	switch(aResource->iType)
  2342 		{
  2343 		case DStaticPowerResource::EBinary:
  2344 			{
  2345 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("type = EBinary\n"));
  2346 			break;
  2347 			}
  2348 		case DStaticPowerResource::EMultilevel:
  2349 			{
  2350 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("type = EMultilevel\n"));
  2351 			break;
  2352 			}
  2353 		case DStaticPowerResource::EMultiProperty:
  2354 			{
  2355 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("type = EMultiProperty\n"));
  2356 			break;
  2357 			}
  2358 		default:
  2359 			{
  2360 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("type = % is UNKNOWN!\n"));
  2361 			return KErrGeneral;
  2362 			}
  2363 		}
  2364 	switch(aResource->iUsage)
  2365 		{
  2366 		case DStaticPowerResource::ESingleUse:
  2367 			{
  2368 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("usage = ESingleUse\n"));
  2369 			break;
  2370 			}
  2371 		case DStaticPowerResource::EShared:
  2372 			{
  2373 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("usage = EShared\n"));
  2374 			break;
  2375 			}
  2376 		default:
  2377 			{
  2378 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("usage = % is UNKNOWN!\n"));
  2379 			return KErrGeneral;
  2380 			}
  2381 		}
  2382 	switch(aResource->iSense)
  2383 		{
  2384 		case DStaticPowerResource::EPositive:
  2385 			{
  2386 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = EPositive\n"));
  2387 			break;
  2388 			}
  2389 		case DStaticPowerResource::ENegative:
  2390 			{
  2391 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = ENegative\n"));
  2392 			break;
  2393 			}
  2394 		case DStaticPowerResource::ECustom:
  2395 			{
  2396 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = ECustom\n"));
  2397 			break;
  2398 			}
  2399 		default:
  2400 			{
  2401 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = % is UNKNOWN!\n"));
  2402 			return KErrGeneral;
  2403 			}
  2404 		}
  2405 	switch(aResource->iLatencyGet)
  2406 		{
  2407 		case DStaticPowerResource::EInstantaneous:
  2408 			{
  2409 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency get = EInstantaneous\n"));
  2410 			break;
  2411 			}
  2412 		case DStaticPowerResource::ENegative:
  2413 			{
  2414 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency get = ELongLatency\n"));
  2415 			break;
  2416 			}
  2417 		default:
  2418 			{
  2419 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency get = % is UNKNOWN!\n"));
  2420 			return KErrGeneral;
  2421 			}
  2422 		}
  2423 	switch(aResource->iLatencySet)
  2424 		{
  2425 		case DStaticPowerResource::EInstantaneous:
  2426 			{
  2427 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency set = EInstantaneous\n"));
  2428 			break;
  2429 			}
  2430 		case DStaticPowerResource::ENegative:
  2431 			{
  2432 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency set = ELongLatency\n"));
  2433 			break;
  2434 			}
  2435 		default:
  2436 			{
  2437 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency set = % is UNKNOWN!\n"));
  2438 			return KErrGeneral;
  2439 			}
  2440 		}
  2441 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("DefaultLevel = %d\n",aResource->iDefaultLevel));
  2442 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("MinLevel = %d\n",aResource->iMinLevel));
  2443 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("MaxLevel = %d\n",aResource->iMaxLevel));
  2444 
  2445 	return KErrNone;
  2446 	}
  2447 #endif
  2448 
  2449 #ifndef RESOURCE_MANAGER_SIMULATED_PSL
  2450 DECLARE_EXTENSION_LDD()
  2451 	{
  2452 	return new DDeviceResManUs;
  2453 	}
  2454 
  2455 
  2456 DECLARE_STANDARD_EXTENSION()
  2457 	{
  2458 	DDeviceResManUs* device = new DDeviceResManUs;
  2459 	__KTRACE_OPT(KBOOT, Kern::Printf("DECLARE_STANDARD_EXTENSION, device = 0x%x\n",device));
  2460 
  2461 	if(device == NULL)
  2462 		return KErrNoMemory;
  2463 	else
  2464 		{
  2465 		device->iSharedDfcQue = new TDfcQue();
  2466 		if(device->iSharedDfcQue==NULL)
  2467 			return KErrNoMemory;
  2468 
  2469 		return (Kern::InstallLogicalDevice(device));
  2470 		}
  2471 	}
  2472 #else
  2473 DECLARE_STANDARD_LDD()
  2474 	{
  2475 	TInt r = DSimulatedPowerResourceController::CompleteResourceControllerInitialisation();
  2476 	if(r != KErrNone)
  2477 		{
  2478 		// Unconditionally print message 
  2479 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("DECLARE_STANDARD_LDD: initialise Resource Controller failed with %d\n",r));
  2480 		return NULL;
  2481 		}
  2482 	DDeviceResManUs* device = new DDeviceResManUs;
  2483 	return device;
  2484 	}
  2485 #endif