kernel/eka/drivers/resourceman/resourcecontrol.cpp
branchRCL_3
changeset 43 c1f20ce4abcf
parent 4 56f325a607ea
child 44 3e88ff8f41d5
equal deleted inserted replaced
42:a179b74831c9 43:c1f20ce4abcf
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    10 //
    10 //
    11 // Contributors:
    11 // Contributors:
    12 //
    12 //
    13 // Description:
    13 // Description:
    14 // e32\drivers\resourceman\resourcecontrol.cpp
    14 // e32\drivers\resourceman\resourcecontrol.cpp
    15 // 
    15 //
    16 //
    16 //
    17 
    17 
    18 #include <drivers/resourcecontrol.h>
    18 #include <drivers/resourcecontrol.h>
    19 #include <drivers/resourcecontrol_trace.h>
    19 #include <drivers/resourcecontrol_trace.h>
    20 #ifdef DEBUG_VERSION
    20 #ifdef DEBUG_VERSION
   311     {
   311     {
   312     __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::ControlIO"));
   312     __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::ControlIO"));
   313     return PowerResourceController->GetInterface(aClientId, aFunction, aParam1, aParam2, aParam3);
   313     return PowerResourceController->GetInterface(aClientId, aFunction, aParam1, aParam2, aParam3);
   314     }
   314     }
   315 
   315 
   316 /** Resouce controller panic */
   316 /** Resource controller panic */
   317 void DPowerResourceController::Panic(TUint8 aPanic)
   317 void DPowerResourceController::Panic(TUint8 aPanic)
   318 	{
   318 	{
   319 	Kern::Fault("Power Resource Controller", aPanic);
   319 	Kern::Fault("Power Resource Controller", aPanic);
   320 	}
   320 	}
   321 
   321 
   322 /** Constructor for power controller. Creates message queue and generates ID for power controller to use. */
   322 /** Constructor for power controller. Creates message queue and generates ID for power controller to use. */
       
   323 extern RPointerArray <DStaticPowerResource> *StaticResourceArrayPtr;
       
   324 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   325 extern RPointerArray <DStaticPowerResourceD> *StaticResourceDependencyArrayPtr;
       
   326 #endif
   323 DPowerResourceController::DPowerResourceController()
   327 DPowerResourceController::DPowerResourceController()
   324 	{
   328 	{
   325     __KTRACE_OPT(KRESMANAGER, Kern::Printf("DPowerResourceController::DPowerResouceController()"));
   329 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("DPowerResourceController::DPowerResouceController()"));
   326 	//Constructor is expected to invoke multiple times (during creation, variant init 0 and extension init 1)
   330 	// Constructor is expected to invoke multiple times, i.e.: 
   327 	if(PowerResourceController) 
   331 	// during creation: variant init 0(KModuleEntryReasonVariantInit0) and later extension init 1 (KModuleEntryReasonExtensionInit1)
       
   332 	if(PowerResourceController)
       
   333 		{
       
   334 		// If InitController() was called in the Init3() static resource arrays were populated already and invocation of this 
       
   335 		// constructor has zeroed the dynamic pointer arrays (calling their default constructors). In such case we need to 
       
   336 		// restore these arrays from their temporary shadow copies (i.e. copies of RPointerArray objects, not their content)
       
   337 		// (See comments in RegisterStaticResources())
       
   338 		if(StaticResourceArrayPtr)
       
   339 			{
       
   340 			// by making a (binary) copy of RPointerArray object (compiler's auto-generated code)
       
   341 			// we are taking the ownership of content (pointers stored/owned by that array) of this temporary array
       
   342 			iStaticResourceArray = *StaticResourceArrayPtr;
       
   343 			}
       
   344 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   345 		// the same applies to static resources with dependencies for extended version.
       
   346 		// Temporary object are de-allocated in InitResources()
       
   347 		if(StaticResourceDependencyArrayPtr)
       
   348 			{
       
   349 			iStaticResDependencyArray = *StaticResourceDependencyArrayPtr;
       
   350 			}
       
   351 #endif
   328 		return;
   352 		return;
       
   353 		}
   329     PowerResourceController = this;
   354     PowerResourceController = this;
   330 	iClientList.Initialise(0);
   355 	iClientList.Initialise(0);
   331 	iUserSideClientList.Initialise(0);
   356 	iUserSideClientList.Initialise(0);
   332 	iInitialised = EResConCreated;
   357 	iInitialised = EResConCreated;
   333 #ifdef PRM_ENABLE_EXTENDED_VERSION
   358 #ifdef PRM_ENABLE_EXTENDED_VERSION
   334 	iDynamicResourceList.Initialise(0);
   359 	iDynamicResourceList.Initialise(0);
   335 	iDynamicResDependencyList.Initialise(0);
   360 	iDynamicResDependencyList.Initialise(0);
   336 #endif
   361 #endif
   337 	}
       
   338 
       
   339 /** Destructor for power controller. Frees the memory allocated in kernel heap. */
       
   340 DPowerResourceController::~DPowerResourceController()
       
   341 	{
       
   342 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("DPowerResourceController::~DPowerResourceController()"));
       
   343 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
       
   344 	iCleanList.ResetAndDestroy();
       
   345 #endif
       
   346 	iClientList.Delete();
       
   347 	iUserSideClientList.Delete();
       
   348 
       
   349 
       
   350 		
       
   351 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   352 	iDynamicResourceList.Delete();
       
   353 	iDynamicResDependencyList.Delete();
       
   354 #endif
       
   355 
       
   356 	SPowerResourceClientLevel *pCL = iClientLevelPool;
       
   357 	while(iClientLevelPool) //Find the starting position of array to delete
       
   358 		{
       
   359 		if(iClientLevelPool < pCL)
       
   360 			pCL = iClientLevelPool;
       
   361 		iClientLevelPool = iClientLevelPool->iNextInList;
       
   362 		}
       
   363 	//delete pCL;
       
   364 	delete []pCL;
       
   365 	SPowerRequest *pReq = iRequestPool;
       
   366 	while(iRequestPool) //Find the starting position of array to delete
       
   367 		{
       
   368 		if(iRequestPool < pReq)
       
   369 			pReq = iRequestPool;
       
   370 		iRequestPool = iRequestPool->iNext;
       
   371 		}
       
   372 	//delete pR
       
   373 	delete []pReq;
       
   374 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   375 	pCL = iResourceLevelPool;
       
   376 	while(iResourceLevelPool)
       
   377 		{
       
   378 		if(iResourceLevelPool < pCL)
       
   379 			pCL = iResourceLevelPool;
       
   380 		iResourceLevelPool = iResourceLevelPool->iNextInList;
       
   381 		}
       
   382 	//delete resource pool
       
   383 	delete []pCL;
       
   384 	//delete Message Queue dependency
       
   385 	delete iMsgQDependency;
       
   386 #endif
       
   387 	//delete Message Queue
       
   388 	delete iMsgQ;
       
   389 	}
   362 	}
   390 
   363 
   391 /** Send notificatins to clients registered for it for the specified resource. */
   364 /** Send notificatins to clients registered for it for the specified resource. */
   392 void DPowerResourceController::CompleteNotifications(TInt aClientId, DStaticPowerResource* aResource, TInt aState, 
   365 void DPowerResourceController::CompleteNotifications(TInt aClientId, DStaticPowerResource* aResource, TInt aState, 
   393 													      TInt aReturnCode, TInt aLevelOwnerId, TBool aLock)
   366 													      TInt aReturnCode, TInt aLevelOwnerId, TBool aLock)
   401         pN = _LOFF(pNL, DPowerResourceNotification, iNotificationLink);
   374         pN = _LOFF(pNL, DPowerResourceNotification, iNotificationLink);
   402 #ifdef PRM_ENABLE_EXTENDED_VERSION
   375 #ifdef PRM_ENABLE_EXTENDED_VERSION
   403 		//If dyanmic resource is deregistering, send notification to all clients requested for it
   376 		//If dyanmic resource is deregistering, send notification to all clients requested for it
   404 		if((pN->iCallback.iResourceId & KIdMaskDynamic) && (aClientId == KDynamicResourceDeRegistering))
   377 		if((pN->iCallback.iResourceId & KIdMaskDynamic) && (aClientId == KDynamicResourceDeRegistering))
   405 			{
   378 			{
       
   379 			pN->iCallback.iResult=aReturnCode;			
       
   380 			pN->iCallback.iMutex = iResourceMutex;
       
   381 			pN->iCallback.iPendingRequestCount++;
   406 			pN->iCallback.iResult = aReturnCode;
   382 			pN->iCallback.iResult = aReturnCode;
   407 			pN->iCallback.iLevel = aState;
   383 			pN->iCallback.iLevel = aState;
   408 			pN->iCallback.iClientId = aClientId;
   384 			pN->iCallback.iClientId = aClientId;
   409 			pN->iCallback.iLevelOwnerId = aLevelOwnerId;
   385 			pN->iCallback.iLevelOwnerId = aLevelOwnerId;
   410 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Notification ClientId = 0x%x, ResourceId = %d, state = %d, Result = %d", 
   386 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Notification ClientId = 0x%x, ResourceId = %d, state = %d, Result = %d", 
   416 #endif
   392 #endif
   417 		if((pN->iType==DPowerResourceNotification::EUnconditional) || 
   393 		if((pN->iType==DPowerResourceNotification::EUnconditional) || 
   418 				(pN->iDirection && ((pN->iPreviousLevel < pN->iThreshold) && (aState >= pN->iThreshold))) ||
   394 				(pN->iDirection && ((pN->iPreviousLevel < pN->iThreshold) && (aState >= pN->iThreshold))) ||
   419 				(!pN->iDirection && ((pN->iPreviousLevel > pN->iThreshold) && (aState <= pN->iThreshold))))
   395 				(!pN->iDirection && ((pN->iPreviousLevel > pN->iThreshold) && (aState <= pN->iThreshold))))
   420 			{
   396 			{
   421             pN->iCallback.iResult=aReturnCode;
   397 			pN->iCallback.iResult=aReturnCode;
   422             pN->iCallback.iLevel=aState;
   398 			pN->iCallback.iMutex = iResourceMutex;
   423             pN->iCallback.iClientId = aClientId;
   399             pN->iCallback.iPendingRequestCount++;			
       
   400 			pN->iCallback.iLevel=aState;
       
   401 			pN->iCallback.iClientId = aClientId;
   424 			pN->iCallback.iLevelOwnerId = aLevelOwnerId;
   402 			pN->iCallback.iLevelOwnerId = aLevelOwnerId;
       
   403 			
   425 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Notifications ClientId = 0x%x, ResourceId = %d, State = %d, Result = %d",
   404 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Notifications ClientId = 0x%x, ResourceId = %d, State = %d, Result = %d",
   426 										pN->iCallback.iClientId, pN->iCallback.iResourceId, aState, aReturnCode));
   405 										pN->iCallback.iClientId, pN->iCallback.iResourceId, aState, aReturnCode));
   427 			PRM_POSTNOTIFICATION_SENT_TRACE
   406 			PRM_POSTNOTIFICATION_SENT_TRACE
   428             pN->iCallback.Enque();
   407 
       
   408 			pN->iCallback.Enque();
       
   409 
   429 			}
   410 			}
   430 		pN->iPreviousLevel = aState; //Update the state
   411 		pN->iPreviousLevel = aState; //Update the state
   431 		}
   412 		}
   432 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::CompleteNotifications"));
   413 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::CompleteNotifications"));
   433 	if(aLock)
   414 	if(aLock)
   702 		{
   683 		{
   703 		TInt aNewState = aReq->Level();
   684 		TInt aNewState = aReq->Level();
   704 		PRM_CLIENT_CHANGE_STATE_END_TRACE
   685 		PRM_CLIENT_CHANGE_STATE_END_TRACE
   705 		}
   686 		}
   706 #endif
   687 #endif
   707 	//Check whether callback is cancelled and if not queue the DFC.
   688 	//Check whether callback is canceled and if not queue the DFC.
   708     TPowerResourceCb* pCb = aReq->ResourceCb();
   689     TPowerResourceCb* pCb = aReq->ResourceCb();
   709     if(pCb)
   690     if(pCb)
   710 		{
   691 		{
       
   692         pCb->iMutex = pRC->iResourceMutex;
       
   693         pCb->iPendingRequestCount++;    
   711         pCb->iResult=aReq->ReturnCode();
   694         pCb->iResult=aReq->ReturnCode();
   712         pCb->iLevel=aReq->Level();
   695         pCb->iLevel=aReq->Level();
   713         pCb->iResourceId=aReq->ResourceId();
   696         pCb->iResourceId=aReq->ResourceId();
   714         pCb->iClientId=aReq->ClientId();
   697         pCb->iClientId=aReq->ClientId();
   715 		pCb->iLevelOwnerId = pR->iLevelOwnerId;
   698 		pCb->iLevelOwnerId = pR->iLevelOwnerId;
   746 		{
   729 		{
   747 		pC = &tRes;
   730 		pC = &tRes;
   748 		pC->iClientId = aReq->ClientId();
   731 		pC->iClientId = aReq->ClientId();
   749 		DDynamicPowerResourceD* pDRes;
   732 		DDynamicPowerResourceD* pDRes;
   750 		if(aReq->ClientId() & KIdMaskDynamic)
   733 		if(aReq->ClientId() & KIdMaskDynamic)
   751 			pDRes = pRC->iDynamicResDependencyList[(TUint16)(aReq->ClientId() & ID_INDEX_BIT_MASK)];	
   734 			pDRes = pRC->iDynamicResDependencyList[(aReq->ClientId() & ID_INDEX_BIT_MASK)];	
   752 		else
   735 		else
   753 			pDRes = (DDynamicPowerResourceD*)pRC->iStaticResDependencyArray[(aReq->ClientId() & ID_INDEX_BIT_MASK) - 1];
   736 			pDRes = (DDynamicPowerResourceD*)pRC->iStaticResDependencyArray[(aReq->ClientId() & ID_INDEX_BIT_MASK) - 1];
   754 		pC->iName = pDRes->iName;
   737 		
       
   738 		if (pDRes != NULL)
       
   739 		    {
       
   740             pC->iName = pDRes->iName;
       
   741 		    }
       
   742 		else
       
   743 		    {
       
   744             pC->iName = &KNullDesC;
       
   745 		    }
   755 		}
   746 		}
   756 	else if((aReq->ClientId() == -1) || (aReq->ClientId() == KDynamicResourceDeRegistering))
   747 	else if((aReq->ClientId() == -1) || (aReq->ClientId() == KDynamicResourceDeRegistering))
   757 		{
   748 		{
   758         pC = &tRes;
   749         pC = &tRes;
   759         pC->iClientId = (TUint)-1;
   750         pC->iClientId = (TUint)-1;
   775 		{
   766 		{
   776 		TInt aNewState = aReq->Level();
   767 		TInt aNewState = aReq->Level();
   777 		PRM_CLIENT_CHANGE_STATE_END_TRACE
   768 		PRM_CLIENT_CHANGE_STATE_END_TRACE
   778 		}
   769 		}
   779 #endif
   770 #endif
   780 	//Check whether callback is cancelled and if not queue the DFC.
   771 	//Check whether callback is canceled and if not queue the DFC.
   781     TPowerResourceCb* pCb = aReq->ResourceCb();
   772     TPowerResourceCb* pCb = aReq->ResourceCb();
   782     if(pCb)
   773     if(pCb)
   783 		{
   774 		{
       
   775         pCb->iMutex = pRC->iResourceMutex;
       
   776         pCb->iPendingRequestCount++;       
   784         pCb->iResult=aReq->ReturnCode();
   777         pCb->iResult=aReq->ReturnCode();
   785         pCb->iLevel=aReq->Level();
   778         pCb->iLevel=aReq->Level();
   786         pCb->iResourceId=aReq->ResourceId();
   779         pCb->iResourceId=aReq->ResourceId();
   787         pCb->iClientId=aReq->ClientId();
   780         pCb->iClientId=aReq->ClientId();
   788 		pCb->iLevelOwnerId = pR->iLevelOwnerId;
   781 		pCb->iLevelOwnerId = pR->iLevelOwnerId;
   842    Finally mark resource controller as fully initialised (ready to accept state change and get request)
   835    Finally mark resource controller as fully initialised (ready to accept state change and get request)
   843    and start the message queue if exists. */
   836    and start the message queue if exists. */
   844 TInt DPowerResourceController::InitResources()
   837 TInt DPowerResourceController::InitResources()
   845 	{
   838 	{
   846     __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::InitResources()"));
   839     __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::InitResources()"));
   847 	TUint16 count;
   840 	TInt count;
   848 	//Create a Kernel client object for Power Controller
   841 	//Create a Kernel client object for Power Controller
   849 	Lock();
   842 	Lock();
   850 	SPowerResourceClient * pC = NULL;
   843 	SPowerResourceClient * pC = NULL;
   851 	// By now client pool should be created
   844 	// By now client pool should be created
   852 	LIST_POP(iClientPool, pC, iNextInList);
   845 	LIST_POP(iClientPool, pC, iNextInList);
   853 	TUint16 growBy = iClientList.GrowBy();
   846 	TInt growBy = iClientList.GrowBy();
   854 	if(!pC)
   847 	if(!pC)
   855 		{
   848 		{
   856 		UnLock();
   849 		UnLock();
   857 		// coverity[alloc_fn]
   850 		// coverity[alloc_fn]
   858 		SPowerResourceClient *pCL = new SPowerResourceClient[growBy];
   851 		SPowerResourceClient *pCL = new SPowerResourceClient[growBy];
   886 	iClientList.Add(pC, iPowerControllerId);
   879 	iClientList.Add(pC, iPowerControllerId);
   887 	pC->iClientId = iPowerControllerId | CLIENT_POWER_CONTROLLER_BIT_MASK;
   880 	pC->iClientId = iPowerControllerId | CLIENT_POWER_CONTROLLER_BIT_MASK;
   888 	iPowerControllerId = pC->iClientId;
   881 	iPowerControllerId = pC->iClientId;
   889     iClientCount++;
   882     iClientCount++;
   890     if(TPowerController::PowerController())
   883     if(TPowerController::PowerController())
   891        TPowerController::PowerController()->RegisterResourceController(this, iPowerControllerId);
   884 		{
       
   885 		if(TPowerController::PowerController()->RegisterResourceController(this, iPowerControllerId))
       
   886 			{
       
   887 #ifndef RESOURCE_MANAGER_SIMULATED_PSL
       
   888 			Panic(EControllerAlreadyExists);	//	Panic with this error for any error returned by RegisterResourceController
       
   889 #endif
       
   890 			}
       
   891 		}
       
   892 
   892 	iInitialised =EResConStartupCompleted;
   893 	iInitialised =EResConStartupCompleted;
   893 	UnLock();
   894 	UnLock();
   894 	//Check the resource for postboot level and send notifications to clients registered for it.
   895 	//Check the resource for postboot level and send notifications to clients registered for it.
   895 	DStaticPowerResource *pR = NULL;
   896 	DStaticPowerResource *pR = NULL;
   896 	TInt r;
   897 	TInt r;
   897 	TPowerRequest req = TPowerRequest::Get();
   898 	TPowerRequest req = TPowerRequest::Get();
   898 	//For Static resource with no dependencies
   899 	//For Static resource with no dependencies
   899     for(count = 0; count< iStaticResourceArrayEntries; count++)
   900     for(count = 0; count < iStaticResourceArray.Count(); count++)
   900 		{
   901 		{
   901 		pR = iStaticResourceArray[count];
   902 		pR = iStaticResourceArray[count];
   902 		if(pR && (pR->iFlags & SET_VALID_POST_BOOT_LEVEL))
   903 		if(pR && (pR->iFlags & SET_VALID_POST_BOOT_LEVEL))
   903 			{
   904 			{
   904             //Form the request message
   905             //Form the request message
   917 				}
   918 				}
   918 			}
   919 			}
   919 		}
   920 		}
   920 #ifdef PRM_ENABLE_EXTENDED_VERSION
   921 #ifdef PRM_ENABLE_EXTENDED_VERSION
   921 	//For Static resource with dependencies 
   922 	//For Static resource with dependencies 
   922 	for(count = 0; count < iStaticResDependencyCount; count++)
   923 	for(count = 0; count < iStaticResDependencyArray.Count(); count++)
   923 		{
   924 		{
   924 		pR = iStaticResDependencyArray[count];
   925 		pR = iStaticResDependencyArray[count];
   925 		if(pR->iFlags & SET_VALID_POST_BOOT_LEVEL)
   926 		if(pR->iFlags & SET_VALID_POST_BOOT_LEVEL)
   926 			{
   927 			{
   927 			req.ReqType() = TPowerRequest::EChange;
   928 			req.ReqType() = TPowerRequest::EChange;
   932 			req.ResourceCb() = NULL;
   933 			req.ResourceCb() = NULL;
   933 			req.RequiresChange() = ETrue;
   934 			req.RequiresChange() = ETrue;
   934 			//Form the request message
   935 			//Form the request message
   935 			((DStaticPowerResourceD*)pR)->HandleChangePropagation(req, EChangeStart, req.ClientId(), KNoClient);
   936 			((DStaticPowerResourceD*)pR)->HandleChangePropagation(req, EChangeStart, req.ClientId(), KNoClient);
   936 			}
   937 			}
       
   938 		}
       
   939 #endif
       
   940 	
       
   941 	// delete the temporary copy of static resource array used during initialization.
       
   942 	if(StaticResourceArrayPtr)
       
   943 		{
       
   944 		delete StaticResourceArrayPtr;
       
   945 		StaticResourceArrayPtr = NULL;
       
   946 		}
       
   947 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   948 	// the same applies to dependency resources array for extended version.
       
   949 	if(StaticResourceDependencyArrayPtr)
       
   950 		{
       
   951 		delete StaticResourceDependencyArrayPtr;
       
   952 		StaticResourceDependencyArrayPtr = NULL;
   937 		}
   953 		}
   938 #endif
   954 #endif
   939 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::InitResources()"));
   955 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::InitResources()"));
   940     return KErrNone;
   956     return KErrNone;
   941 	}
   957 	}
  1247         iClientList.Delete();
  1263         iClientList.Delete();
  1248 		return KErrNoMemory;
  1264 		return KErrNoMemory;
  1249 		}
  1265 		}
  1250 #ifdef PRM_ENABLE_EXTENDED_VERSION
  1266 #ifdef PRM_ENABLE_EXTENDED_VERSION
  1251 	SPowerResourceClientLevel* pRL = NULL;
  1267 	SPowerResourceClientLevel* pRL = NULL;
  1252 	if(iStaticResDependencyCount)
  1268 	if(iStaticResDependencyArray.Count())
  1253 		{
  1269 		{
  1254 		pRL = new SPowerResourceClientLevel[iStaticResDependencyCount];
  1270 		pRL = new SPowerResourceClientLevel[iStaticResDependencyArray.Count()];
  1255 		if(!pRL)
  1271 		if(!pRL)
  1256 			{
  1272 			{
  1257 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Resource level Pool Allocation Failed"));
  1273 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Resource level Pool Allocation Failed"));
  1258 			delete []pC;
  1274 			delete []pC;
  1259 			delete []pCL;
  1275 			delete []pCL;
  1265 		}
  1281 		}
  1266 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
  1282 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
  1267 	iCleanList.Append(pC);
  1283 	iCleanList.Append(pC);
  1268 #endif
  1284 #endif
  1269 	Lock();
  1285 	Lock();
  1270 	TUint16 c;
  1286 	TInt c;
  1271 	for(c = 0; c < iStaticResDependencyCount; c++)
  1287 	for(c = 0; c < iStaticResDependencyArray.Count(); c++)
  1272 		{
  1288 		{
  1273 		LIST_PUSH(iResourceLevelPool, &pRL[c], iNextInList);
  1289 		LIST_PUSH(iResourceLevelPool, &pRL[c], iNextInList);
  1274 		}
  1290 		}
  1275 	iResourceLevelPoolCount = iStaticResDependencyCount;
  1291 	iResourceLevelPoolCount = (TUint16)iStaticResDependencyArray.Count();
  1276 #else
  1292 #else
  1277 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
  1293 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
  1278     iCleanList.Append(pC);
  1294     iCleanList.Append(pC);
  1279 #endif
  1295 #endif
  1280     Lock();
  1296     Lock();
  1281     TUint16 c;
  1297     TUint16 c;
  1282 #endif
  1298 #endif
  1283     // Create Client pool list
  1299     // Create Client pool list
  1284     for(c = 0; c< (aKClients + aUClients); c++)
  1300     for(c = 0; c < TUint16(aKClients + aUClients); c++)
  1285 		{
  1301 		{
  1286         LIST_PUSH(iClientPool, &pC[c], iNextInList);
  1302         LIST_PUSH(iClientPool, &pC[c], iNextInList);
  1287 		}
  1303 		}
  1288     // Create client level pool list
  1304     // Create client level pool list
  1289     for(c = 0; c < aNClientLevels; c++)
  1305     for(c = 0; c < aNClientLevels; c++)
  1365 	req->ReqType() = TPowerRequest::ERegisterKernelClient;
  1381 	req->ReqType() = TPowerRequest::ERegisterKernelClient;
  1366 	UnLock();
  1382 	UnLock();
  1367 	req->SendReceive(iMsgQ);
  1383 	req->SendReceive(iMsgQ);
  1368 	if(req->ReturnCode() == KErrNone)
  1384 	if(req->ReturnCode() == KErrNone)
  1369 		{
  1385 		{
  1370 		pC = iClientList[(TUint16)(req->ClientId() & ID_INDEX_BIT_MASK)];
  1386 		pC = iClientList[(req->ClientId() & ID_INDEX_BIT_MASK)];
  1371 		if(aType == EOwnerThread)
  1387 		if(aType == EOwnerThread)
  1372 			{
  1388 			{
  1373 			pC->iClientId |= CLIENT_THREAD_RELATIVE_BIT_MASK; //Set 31st bit;
  1389 			pC->iClientId |= CLIENT_THREAD_RELATIVE_BIT_MASK; //Set 31st bit;
  1374 			//Store the current thread Id;
  1390 			//Store the current thread Id;
  1375 			pC->iThreadId = thread.iId;
  1391 			pC->iThreadId = thread.iId;
  1376 			}
  1392 			}
  1377 		pC->iName = &aName;
  1393 		pC->iName = &aName;
  1378 		aClientId = pC->iClientId;
  1394 		aClientId = pC->iClientId;
  1379 		}
  1395 	    PRM_CLIENT_REGISTER_TRACE
  1380     PRM_CLIENT_REGISTER_TRACE
  1396 	    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterClient, clientId = 0x%x", aClientId));
  1381 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterClient, clientId = 0x%x", aClientId));
  1397 		}
  1382 	return(req->ReturnCode());
  1398 	return(req->ReturnCode());
  1383 	}
  1399 	}
  1384 
  1400 
  1385 #ifdef PRM_ENABLE_EXTENDED_VERSION
  1401 #ifdef PRM_ENABLE_EXTENDED_VERSION
  1386 TInt DPowerResourceController::HandleResourceRegistration(TPowerRequest& aReq)
  1402 TInt DPowerResourceController::HandleResourceRegistration(TPowerRequest& aReq)
  1414 	if(aRequest.ReqType() == TPowerRequest::ERegisterKernelClient)
  1430 	if(aRequest.ReqType() == TPowerRequest::ERegisterKernelClient)
  1415 		{
  1431 		{
  1416 		//Get Next client from FreePool
  1432 		//Get Next client from FreePool
  1417 		LIST_POP(iClientPool, pC, iNextInList);
  1433 		LIST_POP(iClientPool, pC, iNextInList);
  1418 
  1434 
  1419 		TUint16 growBy = iClientList.GrowBy();
  1435 		TInt growBy = iClientList.GrowBy();
  1420 		if(!pC)
  1436 		if(!pC)
  1421 			{
  1437 			{
  1422 			//Free Pool is empty, so try to grow the pool.
  1438 			//Free Pool is empty, so try to grow the pool.
  1423 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client pool exhausted so growing client Pool by %d", growBy));
  1439 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client pool exhausted so growing client Pool by %d", growBy));
  1424 			// coverity[alloc_fn]
  1440 			// coverity[alloc_fn]
  1459 		}
  1475 		}
  1460 	else // Request is registration of user side client
  1476 	else // Request is registration of user side client
  1461 		{
  1477 		{
  1462 		//Get Next client from FreePool
  1478 		//Get Next client from FreePool
  1463 		LIST_POP(iClientPool, pC, iNextInList);
  1479 		LIST_POP(iClientPool, pC, iNextInList);
  1464 		TUint16 growBy = iUserSideClientList.GrowBy();
  1480 		TInt growBy = iUserSideClientList.GrowBy();
  1465 		if(!pC)
  1481 		if(!pC)
  1466 			{
  1482 			{
  1467 			//Free Pool is empty, so try to grow the pool.
  1483 			//Free Pool is empty, so try to grow the pool.
  1468 			SPowerResourceClient *pCL = (SPowerResourceClient*)Kern::Alloc(sizeof(SPowerResourceClient) * growBy);
  1484 			SPowerResourceClient *pCL = (SPowerResourceClient*)Kern::Alloc(sizeof(SPowerResourceClient) * growBy);
  1469 			if(!pCL)
  1485 			if(!pCL)
  1472 				}
  1488 				}
  1473 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
  1489 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
  1474 			iCleanList.Append(pCL);
  1490 			iCleanList.Append(pCL);
  1475 #endif
  1491 #endif
  1476 			Lock();
  1492 			Lock();
  1477 			TUint16 count;
  1493 			TInt count;
  1478 			for(count = 0; count < growBy - 1; count++)
  1494 			for(count = 0; count < growBy - 1; count++)
  1479 				LIST_PUSH(iClientPool, &pCL[count], iNextInList);
  1495 				LIST_PUSH(iClientPool, &pCL[count], iNextInList);
  1480 			UnLock();
  1496 			UnLock();
  1481 #ifdef PRM_INSTRUMENTATION_MACRO
  1497 #ifdef PRM_INSTRUMENTATION_MACRO
  1482 		TUint size = growBy * sizeof(SPowerResourceClient);
  1498 		TUint size = growBy * sizeof(SPowerResourceClient);
  1538     SPowerResourceClientLevel* pCLL = NULL;
  1554     SPowerResourceClientLevel* pCLL = NULL;
  1539 	while(pCL != NULL)
  1555 	while(pCL != NULL)
  1540 		{
  1556 		{
  1541         __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client 0x%x has requirement on resource %d", pCL->iClientId, pCL->iResourceId));
  1557         __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client 0x%x has requirement on resource %d", pCL->iClientId, pCL->iResourceId));
  1542 #ifdef PRM_ENABLE_EXTENDED_VERSION
  1558 #ifdef PRM_ENABLE_EXTENDED_VERSION
  1543 		switch((pCL->iResourceId >>RESOURCE_BIT_IN_ID_CHECK) & 0x3)													
  1559 		switch((pCL->iResourceId >>RESOURCE_BIT_IN_ID_CHECK) & 0x3)
  1544 		{																		
  1560 			{
  1545 		case PRM_STATIC_RESOURCE:												
  1561 			case PRM_STATIC_RESOURCE:
  1546 			pR = iStaticResourceArray[pCL->iResourceId - 1];								
  1562 			pR = iStaticResourceArray[pCL->iResourceId - 1];
  1547 			break;																
  1563 				break;
  1548 		case PRM_DYNAMIC_RESOURCE:												
  1564 			case PRM_DYNAMIC_RESOURCE:
  1549 			pR = (iDynamicResourceList[(TUint16)(pCL->iResourceId & ID_INDEX_BIT_MASK)]);			
  1565 			pR = (iDynamicResourceList[(pCL->iResourceId & ID_INDEX_BIT_MASK)]);
  1550 			break;																
  1566 				break;
  1551 		case PRM_STATIC_DEPENDENCY_RESOURCE:									
  1567 			case PRM_STATIC_DEPENDENCY_RESOURCE:
  1552 			pR = (iStaticResDependencyArray[(TUint16)(pCL->iResourceId & ID_INDEX_BIT_MASK) - 1]);						
  1568 			pR = (iStaticResDependencyArray[(pCL->iResourceId & ID_INDEX_BIT_MASK) - 1]);
  1553 			break;																
  1569 				break;
  1554 		case PRM_DYNAMIC_DEPENDENCY_RESOURCE:									
  1570 			case PRM_DYNAMIC_DEPENDENCY_RESOURCE:
  1555 			pR = (iDynamicResDependencyList[(TUint16)(pCL->iResourceId & ID_INDEX_BIT_MASK)]);		
  1571 			pR = (iDynamicResDependencyList[(pCL->iResourceId & ID_INDEX_BIT_MASK)]);
  1556 			break;																
  1572 				break;
  1557 		}
  1573 			}
  1558 #else
  1574 #else
  1559 		pR = iStaticResourceArray[pCL->iResourceId -1];
  1575 		pR = iStaticResourceArray[pCL->iResourceId - 1];
  1560 #endif
  1576 #endif
  1561 #ifdef PRM_ENABLE_EXTENDED_VERSION
  1577 #ifdef PRM_ENABLE_EXTENDED_VERSION
  1562 		if(((pR->Sense() == DStaticPowerResource::ECustom) || ((TInt)pCL->iClientId == pR->iLevelOwnerId)) && (!(pCL->iResourceId & KIdMaskDynamic) ||
  1578 		if(pR  &&  (((pR->Sense() == DStaticPowerResource::ECustom) || ((TInt)pCL->iClientId == pR->iLevelOwnerId)) && (!(pCL->iResourceId & KIdMaskDynamic) ||
  1563 			         ((pCL->iResourceId & KIdMaskDynamic) && (((DDynamicPowerResource*)pR)->LockCount() != 0))))
  1579 			         ((pCL->iResourceId & KIdMaskDynamic) && (((DDynamicPowerResource*)pR)->LockCount() != 0)))))
  1564 #else
  1580 #else
  1565 		if((pR->Sense() == DStaticPowerResource::ECustom) || ((TInt)pCL->iClientId == pR->iLevelOwnerId)) 
  1581 		if(pR  &&  ((pR->Sense() == DStaticPowerResource::ECustom) || ((TInt)pCL->iClientId == pR->iLevelOwnerId))) 
  1566 #endif
  1582 #endif
  1567 		    {
  1583 		    {
  1568             pReq->ReqType() = TPowerRequest::ESetDefaultLevel;
  1584             pReq->ReqType() = TPowerRequest::ESetDefaultLevel;
  1569             pReq->ResourceId() = pCL->iResourceId;
  1585             pReq->ResourceId() = pCL->iResourceId;
  1570             pReq->ClientId() = pCL->iClientId;
  1586             pReq->ClientId() = pCL->iClientId;
  1679 	CHECK_CONTEXT(thread)
  1695 	CHECK_CONTEXT(thread)
  1680 	if((aClientId & USER_SIDE_CLIENT_BIT_MASK) || (aClientId == iPowerControllerId))
  1696 	if((aClientId & USER_SIDE_CLIENT_BIT_MASK) || (aClientId == iPowerControllerId))
  1681 		return KErrArgument;
  1697 		return KErrArgument;
  1682 	//Get the index from client ID
  1698 	//Get the index from client ID
  1683 	Lock();
  1699 	Lock();
  1684 	SPowerResourceClient* pC = iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];
  1700 	SPowerResourceClient* pC = iClientList[(aClientId & ID_INDEX_BIT_MASK)];
  1685     if(!pC)
  1701     if(!pC)
  1686 	    {
  1702 	    {
  1687         __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found"));
  1703         __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found"));
  1688         UNLOCK_RETURN(KErrNotFound);
  1704         UNLOCK_RETURN(KErrNotFound);
  1689 		}
  1705 		}
  1723 	ResourceStateChangeOfClientLevels(pC);
  1739 	ResourceStateChangeOfClientLevels(pC);
  1724 	// Add reserved request to pool
  1740 	// Add reserved request to pool
  1725 	iRequestPoolCount = (TUint16)(iRequestPoolCount + (TUint16)pC->iReservedRm);
  1741 	iRequestPoolCount = (TUint16)(iRequestPoolCount + (TUint16)pC->iReservedRm);
  1726 	PRM_CLIENT_DEREGISTER_TRACE
  1742 	PRM_CLIENT_DEREGISTER_TRACE
  1727 	//Increment the free pool count for client level and request level.
  1743 	//Increment the free pool count for client level and request level.
  1728 	iClientList.Remove(pC, (TUint16)(pC->iClientId & ID_INDEX_BIT_MASK));
  1744 	iClientList.Remove(pC, (pC->iClientId & ID_INDEX_BIT_MASK));
  1729 	pC->iName = NULL;
  1745 	pC->iName = NULL;
  1730 	iClientCount--; //Decrement client count
  1746 	iClientCount--; //Decrement client count
  1731 	LIST_PUSH(iClientPool, pC, iNextInList);
  1747 	LIST_PUSH(iClientPool, pC, iNextInList);
  1732 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::DeRegisterClient"));
  1748 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::DeRegisterClient"));
  1733 	UNLOCK_RETURN(KErrNone);
  1749 	UNLOCK_RETURN(KErrNone);
  1860 	SPowerResourceClient* pC;
  1876 	SPowerResourceClient* pC;
  1861 	if(aResourceName.Length() > KMaxResourceNameLength)
  1877 	if(aResourceName.Length() > KMaxResourceNameLength)
  1862 		return KErrTooBig;
  1878 		return KErrTooBig;
  1863 	Lock();
  1879 	Lock();
  1864 	VALIDATE_CLIENT(thread);
  1880 	VALIDATE_CLIENT(thread);
  1865 	TUint count = 0;
  1881 	TInt count = 0;
  1866 	//Search in static resource with no dependencies array for specified resource name.
  1882 	//Search in static resource with no dependencies array for specified resource name.
  1867 	for(count = 0; count < iStaticResourceArrayEntries; count++)
  1883 	for(count = 0; count < iStaticResourceArray.Count(); count++)
  1868 		{
  1884 		{
  1869 		if((iStaticResourceArray[count]) && (!(aResourceName.Compare(*(const TDesC8*)iStaticResourceArray[count]->iName))))
  1885 		if((iStaticResourceArray[count]) && (!(aResourceName.Compare(*(const TDesC8*)iStaticResourceArray[count]->iName))))
  1870 			{
  1886 			{
  1871 			aResourceId = ++count;
  1887 			aResourceId = ++count;
  1872 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetResourceId, ResourceId = 0x%x", aResourceId));
  1888 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetResourceId, ResourceId = 0x%x", aResourceId));
  1882 		aResourceId = pDR->iResourceId;
  1898 		aResourceId = pDR->iResourceId;
  1883 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetResourceId, ResourceId = 0x%x", aResourceId));
  1899 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetResourceId, ResourceId = 0x%x", aResourceId));
  1884 		UNLOCK_RETURN(KErrNone);
  1900 		UNLOCK_RETURN(KErrNone);
  1885 		}
  1901 		}
  1886 	//Search in static resource with dependencies (if exists) for specified resource name
  1902 	//Search in static resource with dependencies (if exists) for specified resource name
  1887 	for(count = 0; count < iStaticResDependencyCount; count++)
  1903 	for(count = 0; count < iStaticResDependencyArray.Count(); count++)
  1888 		{
  1904 		{
  1889 		if(!(aResourceName.Compare(*(const TDesC8*)iStaticResDependencyArray[count]->iName)))
  1905 		if(!(aResourceName.Compare(*(const TDesC8*)iStaticResDependencyArray[count]->iName)))
  1890 			{
  1906 			{
  1891 			aResourceId = iStaticResDependencyArray[count]->iResourceId;
  1907 			aResourceId = iStaticResDependencyArray[count]->iResourceId;
  1892 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetResourceId, ResourceId = 0x%x", aResourceId));
  1908 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetResourceId, ResourceId = 0x%x", aResourceId));
  1951 	//Validate buffer size
  1967 	//Validate buffer size
  1952 	if((TUint)(buf->MaxLength() - buf->Length()) < sizeof(TPowerResourceInfoV01))
  1968 	if((TUint)(buf->MaxLength() - buf->Length()) < sizeof(TPowerResourceInfoV01))
  1953 	   UNLOCK_RETURN(KErrArgument);
  1969 	   UNLOCK_RETURN(KErrArgument);
  1954 
  1970 
  1955 #ifndef PRM_ENABLE_EXTENDED_VERSION
  1971 #ifndef PRM_ENABLE_EXTENDED_VERSION
  1956 	if((!aResourceId) || (aResourceId > iStaticResourceArrayEntries))
  1972 	if((!aResourceId) || (aResourceId > (TUint)iStaticResourceArray.Count()))
  1957 		UNLOCK_RETURN(KErrNotFound);
  1973 		UNLOCK_RETURN(KErrNotFound);
  1958 	//Get resource from static resource array. 0(1) operation.
  1974 	//Get resource from static resource array. 0(1) operation.
  1959 	pR = iStaticResourceArray[aResourceId-1];
  1975 	pR = iStaticResourceArray[aResourceId-1];
  1960 	if(!pR)
  1976 	if(!pR)
  1961 		{
  1977 		{
  2022 	VALIDATE_CLIENT(thread);
  2038 	VALIDATE_CLIENT(thread);
  2023 	//Special case, return number of resources registered resource controller.
  2039 	//Special case, return number of resources registered resource controller.
  2024 	if(!aTargetClientId)
  2040 	if(!aTargetClientId)
  2025 		{
  2041 		{
  2026 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2042 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2027 		aNumResource = iStaticResourceCount + iDynamicResourceCount + iStaticResDependencyCount + 
  2043 		aNumResource = iStaticResourceCount + iDynamicResourceCount + iStaticResDependencyArray.Count() + 
  2028 			                                                          iDynamicResDependencyCount; 
  2044 			                                                          iDynamicResDependencyCount; 
  2029 #else
  2045 #else
  2030 		aNumResource = iStaticResourceCount;
  2046 		aNumResource = iStaticResourceCount;
  2031 #endif
  2047 #endif
  2032 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetNumResourcesInUseByClient, numResources = %d", aNumResource));
  2048 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetNumResourcesInUseByClient, numResources = %d", aNumResource));
  2101     TDes8 *pInfo = (TDes8*)anInfo;
  2117     TDes8 *pInfo = (TDes8*)anInfo;
  2102     if((TUint)(pInfo->MaxLength() - pInfo->Length()) < (sizeof(TPowerResourceInfoV01) * aNumResources))
  2118     if((TUint)(pInfo->MaxLength() - pInfo->Length()) < (sizeof(TPowerResourceInfoV01) * aNumResources))
  2103          UNLOCK_RETURN(KErrArgument);
  2119          UNLOCK_RETURN(KErrArgument);
  2104     TPowerResourceInfoBuf01 buf;
  2120     TPowerResourceInfoBuf01 buf;
  2105 
  2121 
  2106 	TUint16 count = 0;
  2122 	TInt count = 0;
  2107 	TInt r = KErrNone;
  2123 	TInt r = KErrNone;
  2108 	//Special case, if aTargetClientId is 0 fill with all the resource
  2124 	//Special case, if aTargetClientId is 0 fill with all the resource
  2109 	if(!aTargetClientId)
  2125 	if(!aTargetClientId)
  2110 		{
  2126 		{
  2111 		TUint numResources = aNumResources;
  2127 		TInt numResources = aNumResources;
  2112 #ifndef PRM_ENABLE_EXTENDED_VERSION
  2128 #ifndef PRM_ENABLE_EXTENDED_VERSION
  2113 		aNumResources = iStaticResourceCount;
  2129 		aNumResources = iStaticResourceCount;
  2114 #else
  2130 #else
  2115 		aNumResources = iStaticResourceCount + iDynamicResourceCount + iStaticResDependencyCount + 
  2131 		aNumResources = iStaticResourceCount + iDynamicResourceCount + iStaticResDependencyArray.Count() + 
  2116 			                                                           iDynamicResDependencyCount;
  2132 			                                                           iDynamicResDependencyCount;
  2117 #endif
  2133 #endif
  2118 		UnLock();
  2134 		UnLock();
  2119 		while(count < iStaticResourceArrayEntries)
  2135 		while(count < iStaticResourceArray.Count())
  2120 			{
  2136 			{
  2121 			if(numResources <=0)
  2137 			if(numResources == 0)
  2122 				return KErrNone;
  2138 				return KErrNone;
  2123 			pR = iStaticResourceArray[count++];
  2139 			pR = iStaticResourceArray[count++];
  2124 			if(!pR)
  2140 			if(!pR)
  2125 				continue;
  2141 				continue;
  2126             r = pR->GetInfo((TDes8*)buf.Ptr());
  2142             r = pR->GetInfo((TDes8*)buf.Ptr());
  2131 			pInfo->Append(buf);
  2147 			pInfo->Append(buf);
  2132 			numResources--;
  2148 			numResources--;
  2133 			}	
  2149 			}	
  2134 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2150 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2135 		count = 0;
  2151 		count = 0;
  2136 		while(count < iStaticResDependencyCount)
  2152 		while(count < iStaticResDependencyArray.Count())
  2137 			{
  2153 			{
  2138 			if(count >= numResources)
  2154 			if(count >= numResources)
  2139 				return KErrNone;
  2155 				return KErrNone;
  2140 			pR = iStaticResDependencyArray[count++];
  2156 			pR = iStaticResDependencyArray[count++];
  2141 			r = pR->GetInfo((TDes8*)buf.Ptr());
  2157 			r = pR->GetInfo((TDes8*)buf.Ptr());
  2143 			((TPowerResourceInfoV01*)buf.Ptr())->iResourceId = ((DStaticPowerResourceD*)pR)->iResourceId;
  2159 			((TPowerResourceInfoV01*)buf.Ptr())->iResourceId = ((DStaticPowerResourceD*)pR)->iResourceId;
  2144 			if(r != KErrNone)
  2160 			if(r != KErrNone)
  2145 				return r;
  2161 				return r;
  2146 			pInfo->Append(buf);
  2162 			pInfo->Append(buf);
  2147 			}
  2163 			}
  2148 		numResources -= iStaticResDependencyCount;
  2164 		numResources -= iStaticResDependencyArray.Count();
  2149 		if((!numResources) || (!iDynamicResourceCount && !iDynamicResDependencyCount))
  2165 		if((!numResources) || (!iDynamicResourceCount && !iDynamicResDependencyCount))
  2150 			return r;
  2166 			return r;
  2151 		Lock();
  2167 		Lock();
  2152 		TUint resCount = 0;
  2168 		TInt resCount = 0;
  2153 		for(count = 0; count < iDynamicResourceList.Allocd(); count++)
  2169 		for(count = 0; count < iDynamicResourceList.Allocd(); count++)
  2154 			{
  2170 			{
  2155 			pR = iDynamicResourceList[count];
  2171 			pR = iDynamicResourceList[count];
  2156 			if(!pR)
  2172 			if(!pR)
  2157 				continue;
  2173 				continue;
  2164 			pInfo->Append(buf);
  2180 			pInfo->Append(buf);
  2165 			resCount++;
  2181 			resCount++;
  2166 			}
  2182 			}
  2167 		numResources -= resCount;
  2183 		numResources -= resCount;
  2168 		resCount = 0;
  2184 		resCount = 0;
  2169 		for(count = 0; count < iDynamicResDependencyList.Allocd(); count++) 
  2185 		for(count = 0; count < (TInt)iDynamicResDependencyList.Allocd(); count++) 
  2170 			{
  2186 			{
  2171 			pR = iDynamicResDependencyList[count];
  2187 			pR = iDynamicResDependencyList[count];
  2172 			if(!pR)
  2188 			if(!pR)
  2173 				continue;
  2189 				continue;
  2174 			if((resCount >= iDynamicResDependencyCount) || (resCount >= numResources))
  2190 			if((resCount >= iDynamicResDependencyCount) || (resCount >= numResources))
  2186 		}
  2202 		}
  2187 	GET_TARGET_CLIENT();
  2203 	GET_TARGET_CLIENT();
  2188 	SPowerResourceClientLevel* pCL = pC->iLevelList;
  2204 	SPowerResourceClientLevel* pCL = pC->iLevelList;
  2189 	for (count= 0; pCL; count++, pCL = pCL->iNextInList)
  2205 	for (count= 0; pCL; count++, pCL = pCL->iNextInList)
  2190 		{
  2206 		{
  2191 		if(count >= aNumResources)
  2207 		if(count >= (TInt)aNumResources)
  2192 			continue;
  2208 			continue;
  2193 #ifndef PRM_ENABLE_EXTENDED_VERSION
  2209 #ifndef PRM_ENABLE_EXTENDED_VERSION
  2194 		pR = iStaticResourceArray[pCL->iResourceId-1];
  2210 		pR = iStaticResourceArray[pCL->iResourceId-1];
  2195 #else
  2211 #else
  2196 		GET_RESOURCE_FROM_LIST(pCL->iResourceId, pR);
  2212 		GET_RESOURCE_FROM_LIST(pCL->iResourceId, pR);
  2253 		}
  2269 		}
  2254 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2270 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2255 	DStaticPowerResource* pR = NULL;
  2271 	DStaticPowerResource* pR = NULL;
  2256 	GET_RESOURCE_FROM_LIST(aResourceId, pR) 
  2272 	GET_RESOURCE_FROM_LIST(aResourceId, pR) 
  2257 #else
  2273 #else
  2258 	if(aResourceId > iStaticResourceArrayEntries)
  2274 	if(aResourceId > (TUint)iStaticResourceArray.Count())
  2259 		UNLOCK_RETURN(KErrNotFound);
  2275 		UNLOCK_RETURN(KErrNotFound);
  2260 	DStaticPowerResource* pR = iStaticResourceArray[aResourceId-1];
  2276 	DStaticPowerResource* pR = iStaticResourceArray[aResourceId-1];
  2261 	if(!pR)
  2277 	if(!pR)
  2262 		UNLOCK_RETURN(KErrNotFound);
  2278 		UNLOCK_RETURN(KErrNotFound);
  2263 #endif
  2279 #endif
  2357 		}
  2373 		}
  2358 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2374 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2359 	DStaticPowerResource* pR = NULL;
  2375 	DStaticPowerResource* pR = NULL;
  2360 	GET_RESOURCE_FROM_LIST(aResourceId, pR) 
  2376 	GET_RESOURCE_FROM_LIST(aResourceId, pR) 
  2361 #else
  2377 #else
  2362 	if(aResourceId > iStaticResourceArrayEntries)
  2378 	if(aResourceId > (TUint)iStaticResourceArray.Count())
  2363 		UNLOCK_RETURN(KErrNotFound);
  2379 		UNLOCK_RETURN(KErrNotFound);
  2364 	DStaticPowerResource* pR = iStaticResourceArray[aResourceId-1];
  2380 	DStaticPowerResource* pR = iStaticResourceArray[aResourceId-1];
  2365 	if(!pR)
  2381 	if(!pR)
  2366 		UNLOCK_RETURN(KErrNotFound);
  2382 		UNLOCK_RETURN(KErrNotFound);
  2367 #endif
  2383 #endif
  2371 		{
  2387 		{
  2372 		if(c >= aNumClients)
  2388 		if(c >= aNumClients)
  2373 			continue;
  2389 			continue;
  2374 		pCL = (SPowerResourceClientLevel*)pRC;
  2390 		pCL = (SPowerResourceClientLevel*)pRC;
  2375 		if(pCL->iClientId & USER_SIDE_CLIENT_BIT_MASK)
  2391 		if(pCL->iClientId & USER_SIDE_CLIENT_BIT_MASK)
  2376 			pC = iUserSideClientList[(TUint16)(pCL->iClientId & ID_INDEX_BIT_MASK)];
  2392 			pC = iUserSideClientList[(pCL->iClientId & ID_INDEX_BIT_MASK)];
  2377 		else
  2393 		else
  2378 			pC = iClientList[(TUint16)(pCL->iClientId & ID_INDEX_BIT_MASK)];
  2394 			pC = iClientList[(pCL->iClientId & ID_INDEX_BIT_MASK)];
  2379 		info.iClientId = pC->iClientId;
  2395 		info.iClientId = pC->iClientId;
  2380 		info.iClientName =  (TDesC8*)pC->iName;
  2396 		info.iClientName =  (TDesC8*)pC->iName;
  2381         pInfo->Append(TPckgC<TPowerClientInfoV01>(info));
  2397         pInfo->Append(TPckgC<TPowerClientInfoV01>(info));
  2382 		}
  2398 		}
  2383 	aNumClients = c;
  2399 	aNumClients = c;
  2391 
  2407 
  2392 Request changing the state of a resource
  2408 Request changing the state of a resource
  2393 NOTE: If a resource callback is specified for instantaneous resource, then callback
  2409 NOTE: If a resource callback is specified for instantaneous resource, then callback
  2394       will be called after resource change and will be executed in the context of the
  2410       will be called after resource change and will be executed in the context of the
  2395       client thread.
  2411       client thread.
  2396       If a resource callback is specified for long latency reosurces, then it will be
  2412       If a resource callback is specified for long latency resources, then it will be
  2397       executed asynchronously.When the request is accepted the API returns immediately
  2413       executed asynchronously.When the request is accepted the API returns immediately
  2398 	  and the calling thread is unblocked: the callback (called in the client's context) 
  2414 	  and the calling thread is unblocked: the callback (called in the client's context) 
  2399 	  will be invoked when the resource change finally takes place.
  2415 	  will be invoked when the resource change finally takes place.
  2400       If aCb is not specified (NULL by default) the API executes synchronously and will
  2416       If aCb is not specified (NULL by default) the API executes synchronously and will
  2401       only return when the resource change has taken place for long latency resource.
  2417       only return when the resource change has taken place for long latency resource.
  2410                    binary resource, an integer level for a multilevel resource or some
  2426                    binary resource, an integer level for a multilevel resource or some
  2411                    platform specific token for a multi-property resource.
  2427                    platform specific token for a multi-property resource.
  2412 @param aCb         For Long latency resource
  2428 @param aCb         For Long latency resource
  2413                        A pointer to a resource callback object which encapsulates a
  2429                        A pointer to a resource callback object which encapsulates a
  2414                        callback function to be called whenever the resource state change
  2430                        callback function to be called whenever the resource state change
  2415                        happens (if left NULL the API will execute synchrounously).
  2431                        happens (if left NULL the API will execute synchronously).
  2416                    For Instantaneous resource
  2432                    For Instantaneous resource
  2417                        A pointer to a resource callback object which encapsulates a callback
  2433                        A pointer to a resource callback object which encapsulates a callback
  2418                        function to be called after resource change. This executes in the
  2434                        function to be called after resource change. This executes in the
  2419                        context of the client thread.
  2435                        context of the client thread.
  2420 
  2436 
  2465 	VALIDATE_CLIENT(thread);
  2481 	VALIDATE_CLIENT(thread);
  2466 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2482 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2467 	DStaticPowerResource *pR = NULL;
  2483 	DStaticPowerResource *pR = NULL;
  2468 	GET_RESOURCE_FROM_LIST(aResourceId, pR) 
  2484 	GET_RESOURCE_FROM_LIST(aResourceId, pR) 
  2469 #else
  2485 #else
  2470 	if(aResourceId > iStaticResourceArrayEntries)
  2486 	if(aResourceId > (TUint)iStaticResourceArray.Count())
  2471 		UNLOCK_RETURN(KErrNotFound);
  2487 		UNLOCK_RETURN(KErrNotFound);
  2472 	DStaticPowerResource* pR = iStaticResourceArray[aResourceId-1];
  2488 	DStaticPowerResource* pR = iStaticResourceArray[aResourceId-1];
  2473 	if(!pR)
  2489 	if(!pR)
  2474 		UNLOCK_RETURN(KErrNotFound);
  2490 		UNLOCK_RETURN(KErrNotFound);
  2475 #endif
  2491 #endif
  2476 	//Return if the resource is already in that state and client is also the same.
  2492 	//Return if the resource is already in that state and client is also the same.
  2477 	if((aNewState == pR->iCachedLevel) && ((TInt)aClientId == pR->iLevelOwnerId))
  2493 	if((aNewState == pR->iCachedLevel) && ((TInt)aClientId == pR->iLevelOwnerId))
  2478 		UNLOCK_RETURN(KErrNone);
  2494 		{
  2479 
  2495 		if(aCb)
       
  2496 			{
       
  2497 			//Invoke callback function
       
  2498             TUint ClientId = aClientId;
       
  2499             TUint ResourceId = aResourceId;
       
  2500             TInt Level = aNewState;
       
  2501             TInt LevelOwnerId = pR->iLevelOwnerId;
       
  2502             TInt Result = KErrNone;
       
  2503             TAny* Param = aCb->iParam;
       
  2504             aCb->iPendingRequestCount++;
       
  2505             UnLock();
       
  2506             // Call the client specified callback function
       
  2507             aCb->iCallback(ClientId, ResourceId, Level, LevelOwnerId, Result, Param);   
       
  2508             Lock();
       
  2509             aCb->iPendingRequestCount--;
       
  2510             if(aCb->iPendingRequestCount == 0)
       
  2511                 {
       
  2512                 aCb->iResult = KErrCompletion;
       
  2513                 }
       
  2514 			}
       
  2515         UNLOCK_RETURN(KErrNone);
       
  2516 		}
  2480 	
  2517 	
  2481 	PRM_CLIENT_CHANGE_STATE_START_TRACE
  2518 	PRM_CLIENT_CHANGE_STATE_START_TRACE
  2482 	//If long latency resource requested synchronously from DFC thread 0 Panic
  2519 	//If long latency resource requested synchronously from DFC thread 0 Panic
  2483 
  2520 
  2484     const TDesC8* pDfc0 = &KDfcThread0Name;
  2521     const TDesC8* pDfc0 = &KDfcThread0Name;
  2528 
  2565 
  2529 	TPowerRequest* req;
  2566 	TPowerRequest* req;
  2530 	SPowerRequest* pS=NULL;
  2567 	SPowerRequest* pS=NULL;
  2531 	if(pR->LatencySet() && aCb)
  2568 	if(pR->LatencySet() && aCb)
  2532 		{
  2569 		{
  2533 		// Get request object from free pool, as it is long latency reosurce as client
  2570 		// Get request object from free pool, as it is long latency resource as client
  2534 		// will be unblocked once message is sent to controller, so cant use thread message.
  2571 		// will be unblocked once message is sent to controller, so can't use thread message.
  2535 		if(pC->iReservedRm ==0 && !iRequestPoolCount)
  2572 		if(pC->iReservedRm ==0 && !iRequestPoolCount)
  2536 			{
  2573 			{
  2537             r = KErrUnderflow;
  2574             r = KErrUnderflow;
  2538             PRM_CLIENT_CHANGE_STATE_END_TRACE
  2575             PRM_CLIENT_CHANGE_STATE_END_TRACE
  2539 			UNLOCK_RETURN(r);
  2576 			UNLOCK_RETURN(r);
  2582 				return KErrNone;
  2619 				return KErrNone;
  2583 				}
  2620 				}
  2584 			else
  2621 			else
  2585 #endif
  2622 #endif
  2586 				{
  2623 				{
  2587 				req->Send(iMsgQ); // Send the request to Resource Controler thread.
  2624 				req->Send(iMsgQ); // Send the request to Resource Controller thread.
  2588 				return KErrNone;
  2625 				return KErrNone;
  2589 				}
  2626 				}
  2590 			}
  2627 			}
  2591 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2628 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2592 		if(aResourceId & KIdMaskResourceWithDependencies) //Dependency resource
  2629 		if(aResourceId & KIdMaskResourceWithDependencies) //Dependency resource
  2614 			req->Level() = pR->iCachedLevel;
  2651 			req->Level() = pR->iCachedLevel;
  2615 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2652 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2616 		    if(aResourceId & KIdMaskDynamic)
  2653 		    if(aResourceId & KIdMaskDynamic)
  2617 				((DDynamicPowerResource*)pR)->UnLock();
  2654 				((DDynamicPowerResource*)pR)->UnLock();
  2618 #endif
  2655 #endif
  2619 			UnLock();
       
  2620 			if(aCb)
  2656 			if(aCb)
  2621 				{
  2657 				{
  2622 				//Invoke callback function
  2658                 //Invoke callback function
  2623 				aCb->iCallback(req->ClientId(), aResourceId, req->Level(), pR->iLevelOwnerId, r, aCb->iParam);
  2659                 TUint ClientId = req->ClientId();
  2624 				//Mark the callback object to act properly during cancellation of this request.
  2660                 TUint ResourceId = aResourceId;
  2625 				aCb->iResult = KErrCompletion; 
  2661                 TInt Level = req->Level();
  2626 				}
  2662                 TInt LevelOwnerId = pR->iLevelOwnerId;
       
  2663                 TInt Result = r;
       
  2664                 TAny* Param = aCb->iParam;
       
  2665                 aCb->iPendingRequestCount++;
       
  2666                 UnLock();
       
  2667                 // Call the client specified callback function
       
  2668                 aCb->iCallback(ClientId, ResourceId, Level, LevelOwnerId, Result, Param);   
       
  2669                 Lock();
       
  2670                 aCb->iPendingRequestCount--;
       
  2671                 if(aCb->iPendingRequestCount == 0)
       
  2672                     {
       
  2673                     aCb->iResult = KErrCompletion;
       
  2674                     }
       
  2675                 }
       
  2676 
  2627 			PRM_CLIENT_CHANGE_STATE_END_TRACE
  2677 			PRM_CLIENT_CHANGE_STATE_END_TRACE
  2628 			return(r);
  2678 			UNLOCK_RETURN(r);
  2629 			}
  2679 			}
  2630 		}
  2680 		}
  2631 	else if(pR->iLevelOwnerId == -1)
  2681 	else if(pR->iLevelOwnerId == -1)
  2632 		{
  2682 		{
  2633 		/* Add client Level */
  2683 		/* Add client Level */
  2682 		}
  2732 		}
  2683 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2733 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2684 	if(aResourceId & KIdMaskDynamic)
  2734 	if(aResourceId & KIdMaskDynamic)
  2685 		((DDynamicPowerResource*)pR)->UnLock();
  2735 		((DDynamicPowerResource*)pR)->UnLock();
  2686 #endif
  2736 #endif
  2687 	UnLock();
       
  2688 	if(aCb)
  2737 	if(aCb)
  2689 		{
  2738 		{
  2690 		//Invoke callback function
  2739         //Invoke callback function
  2691 		aCb->iCallback(req->ClientId(), aResourceId, req->Level(), pR->iLevelOwnerId, r, aCb->iParam);
  2740         TUint ClientId = req->ClientId();
  2692 		aCb->iResult = KErrCompletion; //Mark the callback object to act properly during cancellation of this request.
  2741         TUint ResourceId = aResourceId;
       
  2742         TInt Level = req->Level();
       
  2743         TInt LevelOwnerId = pR->iLevelOwnerId;
       
  2744         TInt Result = r;
       
  2745         TAny* Param = aCb->iParam;
       
  2746         aCb->iPendingRequestCount++;
       
  2747         UnLock();
       
  2748         // Call the client specified callback function
       
  2749         aCb->iCallback(ClientId, ResourceId, Level, LevelOwnerId, Result, Param);   
       
  2750         Lock();
       
  2751         aCb->iPendingRequestCount--;
       
  2752         if(aCb->iPendingRequestCount == 0)
       
  2753             {
       
  2754             aCb->iResult = KErrCompletion;
       
  2755             }
  2693 		}
  2756 		}
  2694 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::ChangeResourceState, Level = %d", req->Level()));
  2757 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::ChangeResourceState, Level = %d", req->Level()));
  2695     PRM_CLIENT_CHANGE_STATE_END_TRACE
  2758     PRM_CLIENT_CHANGE_STATE_END_TRACE
  2696     return r;
  2759     UNLOCK_RETURN(r);
  2697 	}
  2760 	}
  2698 
  2761 
  2699 /**
  2762 /**
  2700 @publishedPartner
  2763 @publishedPartner
  2701 @prototype 9.5
  2764 @prototype 9.5
  2707 @param aCached     If ETrue, cached value will be updated in aState.
  2770 @param aCached     If ETrue, cached value will be updated in aState.
  2708                    If EFalse, aState will be updated after the resource
  2771                    If EFalse, aState will be updated after the resource
  2709                    state is read from resource.
  2772                    state is read from resource.
  2710 @param aState      Returns the resource state if operation was successful. This
  2773 @param aState      Returns the resource state if operation was successful. This
  2711                    could be a binary value for a binary resource, an integer level
  2774                    could be a binary value for a binary resource, an integer level
  2712                    for a multilevel resource or some platform specific tolen for a
  2775                    for a multilevel resource or some platform specific token for a
  2713                    multi-property resource.
  2776                    multi-property resource.
  2714 @param aLevelOwnerId Returns the Id of the client that is currently holding the resource.
  2777 @param aLevelOwnerId Returns the Id of the client that is currently holding the resource.
  2715 					 -1	is returned when no client is holding the resource.
  2778 					 -1	is returned when no client is holding the resource.
  2716 
  2779 
  2717 @return KErrNone   if operation was successful
  2780 @return KErrNone   if operation was successful
  2754 		{
  2817 		{
  2755 		if(((DDynamicPowerResource*)pR)->LockCount() == 0)
  2818 		if(((DDynamicPowerResource*)pR)->LockCount() == 0)
  2756 			UNLOCK_RETURN(KErrNotFound);
  2819 			UNLOCK_RETURN(KErrNotFound);
  2757 		}
  2820 		}
  2758 #else
  2821 #else
  2759 	if(aResourceId > iStaticResourceArrayEntries)
  2822 	if(aResourceId > (TUint)iStaticResourceArray.Count())
  2760 		UNLOCK_RETURN(KErrNotFound);
  2823 		UNLOCK_RETURN(KErrNotFound);
  2761 	DStaticPowerResource *pR = iStaticResourceArray[aResourceId-1];
  2824 	DStaticPowerResource *pR = iStaticResourceArray[aResourceId-1];
  2762 	if(!pR)
  2825 	if(!pR)
  2763 		UNLOCK_RETURN(KErrNotFound);
  2826 		UNLOCK_RETURN(KErrNotFound);
  2764 #endif
  2827 #endif
  2838 
  2901 
  2839 /**   
  2902 /**   
  2840 @publishedPartner
  2903 @publishedPartner
  2841 @prototype 9.5
  2904 @prototype 9.5
  2842 
  2905 
  2843 Request the state of the resource asynchrounously for long latency resource and
  2906 Request the state of the resource asynchronously for long latency resource and
  2844 synchronously for instantaneous resource
  2907 synchronously for instantaneous resource
  2845 
  2908 
  2846 @param aClientId  ID of the client which is requesting the resource state.
  2909 @param aClientId  ID of the client which is requesting the resource state.
  2847 @param aResourceId ID of the resource whose state is being requested.
  2910 @param aResourceId ID of the resource whose state is being requested.
  2848 @param aCached If ETrue, cached value will be updated in aState
  2911 @param aCached If ETrue, cached value will be updated in aState
  2900 		//Dynamic resource in process of deregistration
  2963 		//Dynamic resource in process of deregistration
  2901 		if(((DDynamicPowerResource*)pR)->LockCount() == 0)
  2964 		if(((DDynamicPowerResource*)pR)->LockCount() == 0)
  2902 			UNLOCK_RETURN(KErrNotFound);
  2965 			UNLOCK_RETURN(KErrNotFound);
  2903 		}
  2966 		}
  2904 #else
  2967 #else
  2905 	if(aResourceId > iStaticResourceArrayEntries)
  2968 	if(aResourceId > (TUint)iStaticResourceArray.Count())
  2906 		UNLOCK_RETURN(KErrNotFound);
  2969 		UNLOCK_RETURN(KErrNotFound);
  2907 	DStaticPowerResource *pR = iStaticResourceArray[aResourceId-1];
  2970 	DStaticPowerResource *pR = iStaticResourceArray[aResourceId-1];
  2908 	if(!pR)
  2971 	if(!pR)
  2909 		UNLOCK_RETURN(KErrNotFound);
  2972 		UNLOCK_RETURN(KErrNotFound);
  2910 #endif
  2973 #endif
  2913 	aCb.iClientId = aClientId;
  2976 	aCb.iClientId = aClientId;
  2914 
  2977 
  2915 	PRM_RESOURCE_GET_STATE_START_TRACE
  2978 	PRM_RESOURCE_GET_STATE_START_TRACE
  2916 	if(aCached) //Call the callback directly
  2979 	if(aCached) //Call the callback directly
  2917 		{
  2980 		{
  2918 		UnLock();
  2981         //Invoke callback function
  2919 		aCb.iCallback(aClientId, aResourceId, pR->iCachedLevel, pR->iLevelOwnerId, KErrNone, aCb.iParam);
  2982         TUint ClientId = aClientId;
  2920 		aCb.iResult = KErrCompletion; //Mark the callback object to act properly during cancellation of this request.
  2983         TUint ResourceId = aResourceId;
       
  2984         TInt Level = pR->iCachedLevel;
       
  2985         TInt LevelOwnerId = pR->iLevelOwnerId;
       
  2986         TInt Result = KErrNone;
       
  2987         TAny* Param = aCb.iParam;
       
  2988         aCb.iPendingRequestCount++;
       
  2989         UnLock();
       
  2990         // Call the client specified callback function
       
  2991         aCb.iCallback(ClientId, ResourceId, Level, LevelOwnerId, Result, Param);   
       
  2992         Lock();
       
  2993         aCb.iPendingRequestCount--;
       
  2994         if(aCb.iPendingRequestCount == 0)
       
  2995             {
       
  2996             aCb.iResult = KErrCompletion; //Mark the callback object to act properly during cancellation of this request.
       
  2997             }
  2921 #ifdef PRM_INSTRUMENTATION_MACRO
  2998 #ifdef PRM_INSTRUMENTATION_MACRO
  2922 		TInt aState = pR->iCachedLevel;
  2999 		TInt aState = pR->iCachedLevel;
  2923         PRM_RESOURCE_GET_STATE_END_TRACE
  3000         PRM_RESOURCE_GET_STATE_END_TRACE
  2924 #endif
  3001 #endif
  2925 		return(KErrNone);
  3002 		UNLOCK_RETURN(KErrNone);
  2926 		}
  3003 		}
  2927 	TPowerRequest* req=NULL;
  3004 	TPowerRequest* req=NULL;
  2928 	if(pR->LatencyGet())
  3005 	if(pR->LatencyGet())
  2929 		{
  3006 		{
  2930 		//Check the client quota of requests
  3007 		//Check the client quota of requests
  2985 			}
  3062 			}
  2986 #ifdef PRM_ENABLE_EXTENDED_VERSION
  3063 #ifdef PRM_ENABLE_EXTENDED_VERSION
  2987 		if(aResourceId & KIdMaskDynamic)
  3064 		if(aResourceId & KIdMaskDynamic)
  2988 			((DDynamicPowerResource*)pR)->UnLock();
  3065 			((DDynamicPowerResource*)pR)->UnLock();
  2989 #endif
  3066 #endif
  2990 		UnLock();
  3067 
  2991 		// Call the client callback function directly as it is already executing in the context of client thread.
  3068         //Invoke callback function
  2992 		aCb.iCallback(aClientId, aResourceId, req->Level(), pR->iLevelOwnerId, r, aCb.iParam);
  3069         TUint ClientId = aClientId;
  2993 		aCb.iResult = KErrCompletion; //Mark the callback object to act properly during cancellation of this request.
  3070         TUint ResourceId = aResourceId;
       
  3071         TInt Level = req->Level();
       
  3072         TInt LevelOwnerId = pR->iLevelOwnerId;
       
  3073         TInt Result = r;
       
  3074         TAny* Param = aCb.iParam;
       
  3075         aCb.iPendingRequestCount++;
       
  3076         UnLock();
       
  3077         // Call the client specified callback function
       
  3078         aCb.iCallback(ClientId, ResourceId, Level, LevelOwnerId, Result, Param);   
       
  3079         Lock();
       
  3080         aCb.iPendingRequestCount--;
       
  3081         if(aCb.iPendingRequestCount == 0)
       
  3082             {
       
  3083             aCb.iResult = KErrCompletion; //Mark the callback object to act properly during cancellation of this request.
       
  3084             }       
       
  3085         UnLock(); 
  2994 		}
  3086 		}
  2995 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetResourceState(asynchronous), Level = %d", req->Level()));
  3087 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetResourceState(asynchronous), Level = %d", req->Level()));
  2996 	if(pR->LatencyGet())
  3088 	if(pR->LatencyGet())
  2997 		return r;
  3089 		return r;
  2998 #ifdef PRM_INSTRUMENTATION_MACRO
  3090 #ifdef PRM_INSTRUMENTATION_MACRO
  3008 @prototype 9.5
  3100 @prototype 9.5
  3009 
  3101 
  3010 Cancel an asynchronous request(or its callback).
  3102 Cancel an asynchronous request(or its callback).
  3011 
  3103 
  3012 @param aClientId       ID of the client which is requesting the cancellation of the request.
  3104 @param aClientId       ID of the client which is requesting the cancellation of the request.
  3013 @param aResourceId     ID for the resource which the request that is being cancelled operates
  3105 @param aResourceId     ID for the resource which the request that is being canceled operates
  3014                        upon.
  3106                        upon.
  3015 @param aCb             A reference to the resource callback object specified with the request
  3107 @param aCb             A reference to the resource callback object specified with the request
  3016                        that is being cancelled.
  3108                        that is being canceled.
  3017 
  3109 
  3018 @return KErrCancel if the request was cancelled.
  3110 @return KErrCancel if the request was canceled.
  3019         KErrNotFound if this resource ID could not be found in the current list of controllable
  3111         KErrNotFound if this resource ID could not be found in the current list of controllable
  3020                      resources.
  3112                      resources.
  3021         KErrCompletion if request is no longer pending.
  3113         KErrCompletion if request is no longer pending.
  3022         KErrAccessDenied if the client ID could not be found in the current list of registered
  3114         KErrAccessDenied if the client ID could not be found in the current list of registered
  3023 		clients or if the client was registered to be thread relative and this API is not called
  3115 		clients or if the client was registered to be thread relative and this API is not called
  3024 		from the same thread or if client is not the same that requested the resource state change.
  3116 		from the same thread or if client is not the same that requested the resource state change.
  3025 		KErrInUse if the request cannot be cancelled as processing of the request already started 
  3117 		KErrInUse if the request cannot be canceled as processing of the request already started 
  3026 		and will run to completion. 
  3118 		and will run to completion. 
  3027 
  3119 
  3028 @pre Interrupts must be enabled
  3120 @pre Interrupts must be enabled
  3029 @pre Kernel must be unlocked
  3121 @pre Kernel must be unlocked
  3030 @pre No fast mutex can be held
  3122 @pre No fast mutex can be held
  3140 						 thread relative and this API is not called from the same thread. 
  3232 						 thread relative and this API is not called from the same thread. 
  3141 		KErrInUse if the passed notification object is used already.
  3233 		KErrInUse if the passed notification object is used already.
  3142 NOTE: This API should return immediately; however the notification will
  3234 NOTE: This API should return immediately; however the notification will
  3143 only happen when a resource change occurs.Notification request is idempotent, 
  3235 only happen when a resource change occurs.Notification request is idempotent, 
  3144 if the same notification has already been requested for this resource ID, 
  3236 if the same notification has already been requested for this resource ID, 
  3145 the API returns with no further action.Notifications remain queued until they are cancelled.
  3237 the API returns with no further action.Notifications remain queued until they are canceled.
  3146 
  3238 
  3147 @pre Interrupts must be enabled
  3239 @pre Interrupts must be enabled
  3148 @pre Kernel must be unlocked
  3240 @pre Kernel must be unlocked
  3149 @pre No fast mutex can be held
  3241 @pre No fast mutex can be held
  3150 @pre Call in a thread context but not from null thread or DFC thread1
  3242 @pre Call in a thread context but not from null thread or DFC thread1
  3168 		}
  3260 		}
  3169 #ifdef PRM_ENABLE_EXTENDED_VERSION
  3261 #ifdef PRM_ENABLE_EXTENDED_VERSION
  3170 	DStaticPowerResource *pR = NULL;
  3262 	DStaticPowerResource *pR = NULL;
  3171 	GET_RESOURCE_FROM_LIST(aResourceId, pR)
  3263 	GET_RESOURCE_FROM_LIST(aResourceId, pR)
  3172 #else
  3264 #else
  3173 	if(aResourceId > iStaticResourceArrayEntries)
  3265 	if(aResourceId > (TUint)iStaticResourceArray.Count())
  3174 		{
  3266 		{
  3175         r = KErrNotFound;
  3267         r = KErrNotFound;
  3176 		PRM_POSTNOTIFICATION_REGISTER_TRACE
  3268 		PRM_POSTNOTIFICATION_REGISTER_TRACE
  3177 		UNLOCK_RETURN(r);
  3269 		UNLOCK_RETURN(r);
  3178 		}
  3270 		}
  3232 
  3324 
  3233 
  3325 
  3234 
  3326 
  3235 @return KErrNone if the operation of requesting a notification was successful.
  3327 @return KErrNone if the operation of requesting a notification was successful.
  3236         KErrNotFound if this resource ID could not be found in the current list
  3328         KErrNotFound if this resource ID could not be found in the current list
  3237                      of controllable reosurces.
  3329                      of controllable resources.
  3238         KErrAccessDenied if the client ID could not be found in the list of
  3330         KErrAccessDenied if the client ID could not be found in the list of
  3239                          registered clients or if the client was registered to be thread
  3331                          registered clients or if the client was registered to be thread
  3240 						 relative and this API is not called from the same thread. 
  3332 						 relative and this API is not called from the same thread. 
  3241 		KErrInUse if the passed notification object is used already.
  3333 		KErrInUse if the passed notification object is used already.
  3242 		KErrArgument if the specified threshold is out of range.
  3334 		KErrArgument if the specified threshold is out of range.
  3243 NOTE: This API should return immediately; however the notification will only
  3335 NOTE: This API should return immediately; however the notification will only
  3244 happen when a resource change occurs. Notification request is idempotent, 
  3336 happen when a resource change occurs. Notification request is idempotent, 
  3245 if the same notification has already been requested for this resource ID, 
  3337 if the same notification has already been requested for this resource ID, 
  3246 the API returns with no further action. Notification remain queued until they are cancelled.
  3338 the API returns with no further action. Notification remain queued until they are canceled.
  3247 
  3339 
  3248 @pre Interrupts must be enabled
  3340 @pre Interrupts must be enabled
  3249 @pre Kernel must be unlocked
  3341 @pre Kernel must be unlocked
  3250 @pre No fast mutex can be held
  3342 @pre No fast mutex can be held
  3251 @pre Call in a thread context but not from null thread or DFC thread1
  3343 @pre Call in a thread context but not from null thread or DFC thread1
  3271 		}
  3363 		}
  3272 #ifdef PRM_ENABLE_EXTENDED_VERSION
  3364 #ifdef PRM_ENABLE_EXTENDED_VERSION
  3273 	DStaticPowerResource *pR = NULL;
  3365 	DStaticPowerResource *pR = NULL;
  3274 	GET_RESOURCE_FROM_LIST(aResourceId, pR)
  3366 	GET_RESOURCE_FROM_LIST(aResourceId, pR)
  3275 #else
  3367 #else
  3276 	if(aResourceId > iStaticResourceArrayEntries)
  3368 	if(aResourceId > (TUint)iStaticResourceArray.Count())
  3277 		{
  3369 		{
  3278         r = KErrNotFound;
  3370         r = KErrNotFound;
  3279         PRM_POSTNOTIFICATION_REGISTER_TRACE
  3371         PRM_POSTNOTIFICATION_REGISTER_TRACE
  3280 		UNLOCK_RETURN(r);
  3372 		UNLOCK_RETURN(r);
  3281 		}
  3373 		}
  3335 Cancel and remove from queue a previously issued request for notification on a
  3427 Cancel and remove from queue a previously issued request for notification on a
  3336 resource state change.
  3428 resource state change.
  3337 
  3429 
  3338 @param aClientId ID of the client which is requesting to cancel the notification
  3430 @param aClientId ID of the client which is requesting to cancel the notification
  3339 @param aResourceId for the resource whose pending notification of state changes
  3431 @param aResourceId for the resource whose pending notification of state changes
  3340                    is being cancelled.
  3432                    is being canceled.
  3341 @param aN          A reference to the notification object that was associated with
  3433 @param aN          A reference to the notification object that was associated with
  3342                    the notification request that is being cancelled. This will be
  3434                    the notification request that is being canceled. This will be
  3343                    used to identify the notification that is being cancelled.
  3435                    used to identify the notification that is being canceled.
  3344 
  3436 
  3345 @return KErrCancel if the notification request was successfully cancelled.
  3437 @return KErrCancel if the notification request was successfully canceled.
  3346         KErrNotFound if the specified notification object is 
  3438         KErrNotFound if the specified notification object is 
  3347 					 not found in the current list of notification objects for the 
  3439 					 not found in the current list of notification objects for the 
  3348 					 specified resource.
  3440 					 specified resource.
  3349         KErrAccessDenied if the client requesting the cancellation is not the same
  3441         KErrAccessDenied if the client requesting the cancellation is not the same
  3350                          which registered the notification or if the resource id does not match or
  3442                          which registered the notification or if the resource id does not match or
  3494 	Lock();
  3586 	Lock();
  3495 	TInt clientPoolCount = iClientLevelPoolCount;
  3587 	TInt clientPoolCount = iClientLevelPoolCount;
  3496 	TInt requestPoolCount = iRequestPoolCount;
  3588 	TInt requestPoolCount = iRequestPoolCount;
  3497 	SPowerResourceClient* pC;
  3589 	SPowerResourceClient* pC;
  3498 	if(aRequest.ClientId() & USER_SIDE_CLIENT_BIT_MASK)
  3590 	if(aRequest.ClientId() & USER_SIDE_CLIENT_BIT_MASK)
  3499 		pC = iUserSideClientList[(TUint16)(aRequest.ClientId() & ID_INDEX_BIT_MASK)];
  3591 		pC = iUserSideClientList[(aRequest.ClientId() & ID_INDEX_BIT_MASK)];
  3500 	else																				
  3592 	else																				
  3501 		pC = iClientList[(TUint16)(aRequest.ClientId() & ID_INDEX_BIT_MASK)];
  3593 		pC = iClientList[(aRequest.ClientId() & ID_INDEX_BIT_MASK)];
  3502 	UnLock();
  3594 	UnLock();
  3503 
  3595 
  3504 	if(clientPoolCount < aRequest.ClientLevelCount())
  3596 	if(clientPoolCount < aRequest.ClientLevelCount())
  3505 		{
  3597 		{
  3506 		//Grow the client level pool
  3598 		//Grow the client level pool
  3595 	req->ReqType() = TPowerRequest::ERegisterUsersideClient;
  3687 	req->ReqType() = TPowerRequest::ERegisterUsersideClient;
  3596 	UnLock();
  3688 	UnLock();
  3597 	req->SendReceive(iMsgQ);
  3689 	req->SendReceive(iMsgQ);
  3598 	if(req->ReturnCode() == KErrNone)
  3690 	if(req->ReturnCode() == KErrNone)
  3599 		{
  3691 		{
  3600 		pC = iUserSideClientList[(TUint16)(req->ClientId() & ID_INDEX_BIT_MASK)];
  3692 		pC = iUserSideClientList[(req->ClientId() & ID_INDEX_BIT_MASK)];
  3601 		pC->iName=&aName;
  3693 		pC->iName=&aName;
  3602 		//Store the current thread Id;
  3694 		//Store the current thread Id;
  3603 		pC->iThreadId = t.iId;
  3695 		pC->iThreadId = t.iId;
  3604 		aClientId = pC->iClientId;
  3696 		aClientId = pC->iClientId;
  3605 		}
  3697 	    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterProxyClient, clientId = 0x%x", aClientId));
  3606 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterProxyClient, clientId = 0x%x", aClientId));
  3698 	    PRM_CLIENT_REGISTER_TRACE
  3607     PRM_CLIENT_REGISTER_TRACE
  3699 		}
  3608 	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  3700 	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  3609 	return KErrNone;
  3701 	return KErrNone;
  3610 	}
  3702 	}
  3611 
  3703 
  3612 /*  Deregister the specified user side client from resource controller.
  3704 /*  Deregister the specified user side client from resource controller.
  3620 	CHECK_CONTEXT(t)
  3712 	CHECK_CONTEXT(t)
  3621 	//Get the index from client ID
  3713 	//Get the index from client ID
  3622 	if(!(aClientId & USER_SIDE_CLIENT_BIT_MASK))
  3714 	if(!(aClientId & USER_SIDE_CLIENT_BIT_MASK))
  3623 		return KErrArgument;
  3715 		return KErrArgument;
  3624 	Lock();
  3716 	Lock();
  3625 	SPowerResourceClient* pC = iUserSideClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];
  3717 	SPowerResourceClient* pC = iUserSideClientList[(aClientId & ID_INDEX_BIT_MASK)];
  3626 	if(!pC)
  3718 	if(!pC)
  3627 		{
  3719 		{
  3628 		UnLock();
  3720 		UnLock();
  3629 		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  3721 		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  3630 		return KErrNotFound;
  3722 		return KErrNotFound;
  3668 	ResourceStateChangeOfClientLevels(pC);
  3760 	ResourceStateChangeOfClientLevels(pC);
  3669 	//Add reserved request to pool
  3761 	//Add reserved request to pool
  3670 	iRequestPoolCount = (TUint16)(iRequestPoolCount + pC->iReservedRm);
  3762 	iRequestPoolCount = (TUint16)(iRequestPoolCount + pC->iReservedRm);
  3671 	PRM_CLIENT_DEREGISTER_TRACE
  3763 	PRM_CLIENT_DEREGISTER_TRACE
  3672 	//Increment the free pool count for client level and request level.
  3764 	//Increment the free pool count for client level and request level.
  3673 	iUserSideClientList.Remove(pC, (TUint16)(pC->iClientId & ID_INDEX_BIT_MASK));
  3765 	iUserSideClientList.Remove(pC, (pC->iClientId & ID_INDEX_BIT_MASK));
  3674 	pC->iName = NULL;
  3766 	pC->iName = NULL;
  3675 	iUserSideClientCount--; //Decrement client count
  3767 	iUserSideClientCount--; //Decrement client count
  3676 	LIST_PUSH(iClientPool, pC, iNextInList);
  3768 	LIST_PUSH(iClientPool, pC, iNextInList);
  3677 	UnLock();
  3769 	UnLock();
  3678 	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  3770 	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  3705 	TUint count=0;
  3797 	TUint count=0;
  3706 	TUint id=0;
  3798 	TUint id=0;
  3707 	for(count=0;count<aNumResources;count++) //Check for valid resource ID.
  3799 	for(count=0;count<aNumResources;count++) //Check for valid resource ID.
  3708 		{
  3800 		{
  3709 #ifndef PRM_ENABLE_EXTENDED_VERSION
  3801 #ifndef PRM_ENABLE_EXTENDED_VERSION
  3710 		if((!pS->iResourceId) || (pS->iResourceId > iStaticResourceArrayEntries) || (!iStaticResourceArray[pS->iResourceId-1]))
  3802 		if((!pS->iResourceId) || (pS->iResourceId > (TUint)iStaticResourceArray.Count()) || (!iStaticResourceArray[pS->iResourceId-1]))
  3711 			{
  3803 			{
  3712 			UnLock();
  3804 			UnLock();
  3713 			LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  3805 			LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  3714 			return KErrNotFound;
  3806 			return KErrNotFound;
  3715 			}
  3807 			}
  3719 			UnLock();
  3811 			UnLock();
  3720 			LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  3812 			LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  3721 			return KErrNotSupported;
  3813 			return KErrNotSupported;
  3722 			}
  3814 			}
  3723 		if((!pS->iResourceId) || ((pS->iResourceId & KIdMaskResourceWithDependencies) && 
  3815 		if((!pS->iResourceId) || ((pS->iResourceId & KIdMaskResourceWithDependencies) && 
  3724 			     (pS->iResourceId > iStaticResDependencyCount)) || (!(pS->iResourceId & KIdMaskResourceWithDependencies) && 
  3816 			     (pS->iResourceId > (TUint)iStaticResDependencyArray.Count())) || (!(pS->iResourceId & KIdMaskResourceWithDependencies) && 
  3725 					((pS->iResourceId > iStaticResourceArrayEntries) || (!iStaticResourceArray[pS->iResourceId-1]))))
  3817 					((pS->iResourceId > (TUint)iStaticResourceArray.Count()) || (!iStaticResourceArray[pS->iResourceId-1]))))
  3726 			{
  3818 			{
  3727 			UnLock();
  3819 			UnLock();
  3728 			LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  3820 			LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  3729 			return KErrNotFound;
  3821 			return KErrNotFound;
  3730 			}
  3822 			}
  3745 		pS->iCurrentLevel = pR->iCachedLevel;
  3837 		pS->iCurrentLevel = pR->iCachedLevel;
  3746 		pR->iIdleListEntry=pS;
  3838 		pR->iIdleListEntry=pS;
  3747 		pS++;
  3839 		pS++;
  3748 		}
  3840 		}
  3749 	iListForIdle=(SIdleResourceInfo*)aBuf->Ptr();
  3841 	iListForIdle=(SIdleResourceInfo*)aBuf->Ptr();
  3750 	pS = (SIdleResourceInfo*)aBuf->Ptr();
       
  3751 	UnLock();
  3842 	UnLock();
  3752 	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  3843 	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  3753 	return KErrNone;
  3844 	return KErrNone;
  3754 	}
  3845 	}
  3755 	
  3846 	
  3795 #ifdef PRM_ENABLE_EXTENDED_VERSION
  3886 #ifdef PRM_ENABLE_EXTENDED_VERSION
  3796 	GET_RESOURCE_FROM_LIST(aResourceId, pR)
  3887 	GET_RESOURCE_FROM_LIST(aResourceId, pR)
  3797 	if(aResourceId & KIdMaskDynamic)
  3888 	if(aResourceId & KIdMaskDynamic)
  3798 		((DDynamicPowerResource*)pR)->Lock();
  3889 		((DDynamicPowerResource*)pR)->Lock();
  3799 #else
  3890 #else
  3800 	if(aResourceId > iStaticResourceArrayEntries)
  3891 	if(aResourceId > (TUint)iStaticResourceArray.Count())
  3801 		{
  3892 		{
  3802 		UNLOCK_RETURN(KErrNotFound);
  3893 		UNLOCK_RETURN(KErrNotFound);
  3803 		}
  3894 		}
  3804 	pR = iStaticResourceArray[aResourceId - 1];
  3895 	pR = iStaticResourceArray[aResourceId - 1];
  3805 	if(!pR)
  3896 	if(!pR)