kernel/eka/drivers/resmanus/d_resmanus.cpp
changeset 0 a41df078684a
child 109 b3a1d9898418
child 256 c1f20ce4abcf
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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