os/kernelhwsrv/kernel/eka/drivers/resourceman/resourcecontrol_extended.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2007-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\resourceman\resourcecontrol_extended.cpp
    15 // 
    16 //
    17 
    18 #include <drivers/resourcecontrol.h>
    19 		
    20 extern DPowerResourceController* PowerResourceController;
    21 /**
    22 @internalComponent
    23 @prototype 9.5
    24 
    25 Reserves the client level from pool to be used for updating resource client level in dependency resource.
    26 
    27 @param aCount Number of client levels to reserve from pool
    28 
    29 @return KErrNone On success 
    30 @return KErrNoMemory Not enough memory to grow the pool
    31 */
    32 TInt DPowerResourceController::ReserveClientLevelPoolCount(TUint16 aCount)
    33 	{
    34 	if(aCount < iResourceLevelPoolCount) 
    35 		iResourceLevelPoolCount = (TUint16)(iResourceLevelPoolCount - aCount);
    36 	else
    37 		{
    38 		TUint allocCount = (iStaticResDependencyCount / 2) + aCount;
    39 		// coverity[alloc_fn]
    40 		SPowerResourceClientLevel* pCL = new SPowerResourceClientLevel[allocCount];
    41 		if(!pCL)
    42 			return KErrNoMemory;
    43 		for(TUint count = 0;count<(TUint)(allocCount);count++)
    44 			LIST_PUSH(iResourceLevelPool, &pCL[count], iNextInList);
    45 		iResourceLevelPoolCount= (TUint16)(iResourceLevelPoolCount + (iStaticResDependencyCount / 2));
    46 #ifdef PRM_INSTRUMENTATION_MACRO
    47 		TUint size = allocCount * sizeof(SPowerResourceClientLevel);
    48 		PRM_MEMORY_USAGE_TRACE
    49 #endif
    50 		}
    51 	return KErrNone;
    52 	}
    53 
    54 /**
    55 @internalComponent
    56 @prototype 9.5
    57 
    58 Return a client level object from pool.
    59 
    60 @param aLevelPtr Pointer to update the client level object.
    61 
    62 @return None 
    63 */
    64 void DPowerResourceController::RemoveClientLevelFromPool(SPowerResourceClientLevel *&aLevelPtr)
    65 	{
    66 	LIST_POP(iResourceLevelPool, aLevelPtr, iNextInList);
    67 	return;
    68 	}
    69 
    70 /**
    71 Update with number of dependent resources for the specified resource. 
    72 */
    73 TInt DPowerResourceController::GetNumDependentsForResource(TUint aResourceId, TUint* aNumResources)
    74 	{
    75 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetNumDependentsForResource"));
    76 	
    77 	if(!(aResourceId & KIdMaskResourceWithDependencies))
    78 		return KErrNotSupported;
    79 	SNode* pN;
    80 	if(aResourceId & KIdMaskDynamic)
    81 		{
    82 		DDynamicPowerResourceD* pDR = iDynamicResDependencyList[(TUint16)(aResourceId & ID_INDEX_BIT_MASK)];		
    83 		if(!pDR)														
    84 			return KErrNotFound;
    85 		pN = pDR->iDependencyList;
    86 		}
    87 	else
    88 		{
    89 		if((aResourceId & ID_INDEX_BIT_MASK) > iStaticResDependencyCount)
    90 			return KErrNotFound;
    91 		DStaticPowerResourceD* pDR = iStaticResDependencyArray[(TUint16)(aResourceId & ID_INDEX_BIT_MASK) - 1];
    92 		pN = pDR->iDependencyList;
    93 		}
    94 	*aNumResources = 0;
    95 	for(;pN != NULL; pN = pN->iNext)
    96 		(*aNumResources)++;
    97 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetNumDependentsForResource"));
    98 	return KErrNone;
    99 	}
   100 
   101 /**
   102 Update the specified array with dependent resource Id's of the specified resource. 
   103 */
   104 TInt DPowerResourceController::GetDependentsIdForResource(TUint aResourceId, TAny* aInfo, TUint* aNumDepResources)
   105 	{
   106 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetDependentsIdForResource"));
   107 
   108 	if(!(aResourceId & KIdMaskResourceWithDependencies))
   109 		return KErrNotSupported;
   110 	
   111 	if(!aInfo || !*aNumDepResources)
   112 		{
   113 		return KErrArgument;
   114 		}
   115 
   116 	TDes8 *pInfo = (TDes8*)aInfo;
   117 	
   118 	if((TUint)(pInfo->MaxLength() - pInfo->Length()) < (sizeof(SResourceDependencyInfo)*(*aNumDepResources)))
   119 		return KErrArgument;
   120      
   121 	SResourceDependencyInfo sResDepInfo;
   122 	
   123 	SNode* pN;
   124 	if(aResourceId & KIdMaskDynamic)
   125 		{
   126 		DDynamicPowerResourceD* pDR = iDynamicResDependencyList[(TUint16)(aResourceId & ID_INDEX_BIT_MASK)];
   127 		if(!pDR)
   128 			return KErrNotFound;
   129 		pN = pDR->iDependencyList;
   130 		}
   131 	else
   132 		{
   133 		if((aResourceId & ID_INDEX_BIT_MASK) > iStaticResDependencyCount)
   134 			return KErrNotFound;
   135 		DStaticPowerResourceD* pDR = iStaticResDependencyArray[(TUint16)(aResourceId & ID_INDEX_BIT_MASK) -1];
   136 		pN = pDR->iDependencyList;
   137 		}
   138 	TUint count = 0;
   139 	TUint resCount = 0;
   140 
   141 	for(; pN != NULL; pN = pN->iNext)
   142 		{
   143 		resCount++;
   144 		if(count == *aNumDepResources)
   145 			continue;
   146 		sResDepInfo.iResourceId = pN->iResource->iResourceId;
   147 		sResDepInfo.iDependencyPriority = pN->iPriority;
   148 		pInfo->Append(TPckgC<SResourceDependencyInfo>(sResDepInfo));
   149 		}
   150 	*aNumDepResources = resCount;
   151 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetDependentsIdForResource"));
   152 	return KErrNone;
   153 	}
   154 
   155 /**
   156 Registers resource dependency. This could be between 2 dynamic resource or between
   157 dynamic and static resource.
   158 */
   159 TInt DPowerResourceController::RegisterResourceDependency(SPowerResourceClient* aClientPtr, SResourceDependencyInfo* aInfo1, 
   160 														              SResourceDependencyInfo* aInfo2)
   161 	{
   162 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DExtendedResourceController::RegisterResourceDependency"));
   163 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("ClientId = 0x%x, ResourceId1 = 0x%x, ResourceId2 = 0x%x", 
   164 		                             aClientPtr->iClientId, aInfo1->iResourceId, aInfo2->iResourceId));
   165 		                             
   166 	if(iDfcQDependencyLock)
   167 		{
   168 		__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterResourceDependency::Resource In Use"));
   169 		return KErrInUse;
   170 		}
   171 	
   172 	TInt r = KErrNone;
   173 	//One of the resource must be dynamic resource
   174 	if(!(aInfo1->iResourceId & KIdMaskDynamic) && !(aInfo2->iResourceId & KIdMaskDynamic))
   175 		return KErrNotSupported;
   176 	//Both the resources should have dependency resource bit set in its id. 
   177 	if(!(aInfo1->iResourceId & KIdMaskResourceWithDependencies) || !(aInfo2->iResourceId & KIdMaskResourceWithDependencies))
   178 		return KErrNotSupported;
   179 	
   180 	DDynamicPowerResourceD* pR1 = NULL;
   181 	DDynamicPowerResourceD* pR2 = NULL;
   182 	SNode* pN1 = NULL;
   183 	SNode* pN2 = NULL;
   184 	//Retrieve resource1 from the corresponding list.
   185 	if(aInfo1->iResourceId & KIdMaskDynamic)
   186 		{
   187 		pR1 = iDynamicResDependencyList[(TUint16)(aInfo1->iResourceId & ID_INDEX_BIT_MASK)];
   188 		if(!pR1)
   189 			return KErrNotFound;
   190 		pN1 = pR1->iDependencyList;
   191 		}
   192 	else 
   193 		{
   194 		if((aInfo1->iResourceId & ID_INDEX_BIT_MASK) > iStaticResDependencyCount)
   195 			return KErrNotFound;
   196 		pR1 = (DDynamicPowerResourceD*)iStaticResDependencyArray[(TUint16)(aInfo1->iResourceId & ID_INDEX_BIT_MASK) - 1];
   197 		pN1 = ((DStaticPowerResourceD*)pR1)->iDependencyList;
   198 		}
   199 	//Retrieve resource2 from the corresponding list.
   200 	if(aInfo2->iResourceId & KIdMaskDynamic)
   201 		{
   202 		pR2 = iDynamicResDependencyList[(TUint16)(aInfo2->iResourceId & ID_INDEX_BIT_MASK)];
   203 		if(!pR2)
   204 			return KErrNotFound;
   205 		pN2 = pR2->iDependencyList;
   206 		}
   207 	else
   208 		{
   209 		if((aInfo2->iResourceId & ID_INDEX_BIT_MASK) > iStaticResDependencyCount)
   210 			return KErrNotFound;
   211 		pR2 = (DDynamicPowerResourceD*)iStaticResDependencyArray[(TUint16)(aInfo2->iResourceId & ID_INDEX_BIT_MASK) - 1];
   212 		pN2 = ((DStaticPowerResourceD*)pR2)->iDependencyList;
   213 		}
   214 
   215 	//Only long latency resource is allowed to have dependents.
   216 	if(!pR1->LatencySet())
   217 		pR1->iFlags |= KLongLatencySet;
   218 	if(!pR2->LatencySet())
   219 		pR2->iFlags |= KLongLatencySet;
   220 	
   221 	//Check for closed loop
   222 	//NOTE: Panics, if any closed loop is encountered
   223 	if(pN1)
   224 		CheckForDependencyLoop((DStaticPowerResourceD*)pR1, pR1->iResourceId, pR2->iResourceId);
   225 
   226 	if(pN2)
   227 		CheckForDependencyLoop((DStaticPowerResourceD*)pR2, pR2->iResourceId, pR1->iResourceId);
   228 
   229 	//Check whether the passed priority already exists.Code will return with KErrAlreadyExists, if it exists.
   230 	CHECK_IF_PRIORITY_ALREADY_EXISTS(pN1, aInfo2->iDependencyPriority)
   231 	CHECK_IF_PRIORITY_ALREADY_EXISTS(pN2, aInfo1->iDependencyPriority)
   232 	UnLock();
   233 	//Allocate nodes
   234 	// coverity[alloc_fn]
   235 	SNode* pSN1 = new (SNode);
   236 	// coverity[alloc_fn]
   237 	SNode* pSN2 = new (SNode);
   238 	Lock();
   239 	if(!pSN1 || !pSN2)
   240 		return KErrNoMemory;
   241 	//Add the link
   242 	pSN1->iResource = (DStaticPowerResourceD*)pR1;
   243 	pSN1->iPropagatedLevel = 0;
   244 	pSN1->iPriority = aInfo1->iDependencyPriority;
   245 	pSN1->iVisited = EFalse;
   246 	pSN1->iNext = NULL;
   247 
   248 	pSN2->iResource = (DStaticPowerResourceD*)pR2;
   249 	pSN2->iPropagatedLevel = 0;
   250 	pSN2->iPriority = aInfo2->iDependencyPriority;
   251 	pSN2->iVisited = EFalse;
   252 	pSN2->iNext = NULL;
   253 
   254 	if(aInfo1->iResourceId & KIdMaskDynamic) //Dynamic resource
   255 		// coverity[memory_leak]
   256 		ADD_DEPENDENCY_NODE(pSN2, ((DDynamicPowerResourceD*)pR1)->iDependencyList)
   257 	else
   258 		((DStaticPowerResourceD*)pR1)->AddNode(pSN2);
   259 	
   260 	//Add the second node
   261 	if(aInfo2->iResourceId & KIdMaskDynamic) //Dynamic resource
   262 		// coverity[memory_leak]
   263 		ADD_DEPENDENCY_NODE(pSN1, ((DDynamicPowerResourceD*)pR2)->iDependencyList)
   264 	else
   265 		((DStaticPowerResourceD*)pR2)->AddNode(pSN1);
   266 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DExtendedResourceController::RegisterResourceDependency"));
   267 #ifdef PRM_INSTRUMENTATION_MACRO
   268 	PRM_REGISTER_RESOURCE_DEPENDENCY_TRACE
   269 #endif
   270 	return r;
   271 	}
   272 
   273 /**
   274 Registers dynamic resource. 
   275 */
   276 TInt DPowerResourceController::RegisterDynamicResource(SPowerResourceClient* aClientPtr, DDynamicPowerResource* aPDRes, 
   277 													                 TUint* aDynamicResourceId)
   278 	{
   279 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DExtendedResourceController::RegisterDynamicResource"));
   280 	TInt r = KErrNone;
   281 	//Check for dynamic resource
   282 	if(!(aPDRes->iResourceId & KIdMaskDynamic))
   283 		return KErrNotSupported;
   284 	//check for count
   285 	else if(aPDRes->LockCount() != 0) 
   286 		return KErrAlreadyExists;
   287 	
   288 	TPowerRequest* req = (TPowerRequest*)&TPowerRequest::Get();
   289 	req->ReqType() = TPowerRequest::ERegisterDynamicResource;
   290 	req->Resource() = (DStaticPowerResource*)aPDRes;
   291 	UnLock();
   292 	req->SendReceive(iMsgQ);
   293 	Lock();
   294 	if(req->ReturnCode() == KErrNone)
   295 		{
   296 		*aDynamicResourceId = req->ResourceId();
   297 		aPDRes-> iOwnerId = aClientPtr->iClientId;
   298 		aPDRes->Lock();
   299 		//Increment dynamic resource count in client
   300 		aClientPtr->iDynamicResCount++;
   301 		}
   302 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DExtendedResourceController::RegisterDynamicResource, resource ID = 0x%x", 
   303 		                                                                                  *aDynamicResourceId));
   304 #ifdef PRM_INSTRUMENTATION_MACRO
   305 	PRM_REGISTER_DYNAMIC_RESOURCE_TRACE
   306 #endif
   307 	return r;
   308 	}
   309 
   310 /**
   311 Deregisters dynamic resource.
   312 */
   313 TInt DPowerResourceController::DeregisterDynamicResource(SPowerResourceClient* aClientPtr, TUint aResourceId, 
   314 														 TInt* aPDefLevel)
   315 	{
   316 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DExtendedResourceController::DeregisterDynamicResource"));
   317 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("aClientId = 0x%x, aDynamicResourceId = 0x%x, Default Level = %d", 
   318 		                               aClientPtr->iClientId, aResourceId, aPDefLevel ? *aPDefLevel : 0));
   319 	TInt r = KErrNone;
   320 	DDynamicPowerResource* pDR = NULL;
   321 	//Check for dynamic resource bit
   322 	if(!(aResourceId & KIdMaskDynamic))
   323 		return KErrNotSupported;
   324 
   325 	//Get the resource from appropriate container
   326 	if(aResourceId & KIdMaskResourceWithDependencies)
   327 		{
   328 		pDR = iDynamicResDependencyList[(TUint16)(aResourceId & ID_INDEX_BIT_MASK)];		
   329 		if(!pDR)														
   330 			return KErrNotFound;
   331 		}
   332 	else
   333 		{
   334 		pDR = iDynamicResourceList[(TUint16)(aResourceId & ID_INDEX_BIT_MASK)];		
   335 		if(!pDR)														
   336 			return KErrNotFound;
   337 		}
   338 	//Client which registered the dynamic resource is only allowed to deregister. 
   339 	if(aClientPtr->iClientId != pDR->iOwnerId)
   340 		{
   341 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client attempting to deregister a dynamic resource which is not the owner!"));
   342 		return KErrAccessDenied;
   343 		}
   344 	// Don't allow to deregister if the some other operation is in progress or if the resource is shared and
   345 	// another client holds requirement on this resource
   346 	if((pDR->LockCount() > RESOURCE_NOT_IN_OPERATION) || pDR->InUse())
   347 		{
   348 		return KErrInUse;
   349 		}
   350 	TPowerRequest* req = (TPowerRequest*)&TPowerRequest::Get();
   351 	req->ResourceCb() = NULL;
   352 	req->ReturnCode() = KErrNone;
   353 	req->RequiresChange() = EFalse;
   354 	pDR->UnLock(); //Marked as deleted so that no other operation will be taking place.
   355 	req->ReqType() = TPowerRequest::ESetDefaultLevel;
   356 	//Handle dynamic resource with dependencies
   357 	if(aResourceId & KIdMaskResourceWithDependencies)
   358 		{
   359 		for(SNode* pNode = ((DDynamicPowerResourceD*)pDR)->iDependencyList; pNode != NULL; pNode = pNode->iNext)
   360 			{
   361 			if((TUint)pNode->iResource->iLevelOwnerId == aResourceId)
   362 				{
   363 				req->ResourceId() = pNode->iResource->iResourceId;
   364 				req->ClientId() = aResourceId;
   365 				req->Level() = pNode->iResource->iCachedLevel;
   366 				req->Resource() = pNode->iResource; 
   367 				((DDynamicPowerResourceD*)(pNode->iResource))->Lock();
   368 				UnLock();
   369 				req->SendReceive(iMsgQDependency);
   370 				Lock();
   371 				}
   372 			//Remove entry from resource dependency list
   373 			for(SNode* pSN = pNode->iResource->iDependencyList; pSN != NULL; pSN = pSN->iNext)
   374 				{
   375 				if(pSN->iResource->iResourceId == aResourceId)
   376 					{
   377 					LIST_REMOVE(pNode->iResource->iDependencyList, pSN, iNext, SNode);
   378 					UnLock();
   379 					delete pSN;
   380 					Lock();
   381 					break;
   382 					}
   383 				}
   384 			//Remove from dependent resource "resource client level" list
   385 			for(SPowerResourceClientLevel* pL = ((DDynamicPowerResourceD*)(pNode->iResource))->iResourceClientList; 
   386 			                                                                pL != NULL; pL = pL->iNextInList)
   387 				{
   388 				if(pL->iClientId == aResourceId)
   389 					{
   390 					LIST_REMOVE(((DDynamicPowerResourceD*)(pNode->iResource))->iResourceClientList, pL, iNextInList, 
   391 						                                                                SPowerResourceClientLevel);
   392 					//Move to free pool
   393 					LIST_PUSH(iResourceLevelPool, pL, iNextInList);
   394 					iResourceLevelPoolCount++;
   395 					}
   396 				}
   397 			((DDynamicPowerResource*)(pNode->iResource))->UnLock();
   398 			}
   399 		//Move the resource to default level
   400 		req->ClientId() = -1;
   401 		req->ResourceId() = aResourceId;
   402 		req->Resource() = pDR;
   403 		if(aPDefLevel)
   404 			req->Level() = *aPDefLevel; //Set the resource to the passed level
   405 		else
   406 			req->Level() = pDR->iDefaultLevel; //Set the resource level to default level
   407 		UnLock();
   408 		req->SendReceive(iMsgQDependency);
   409 		}
   410 	else
   411 		{
   412 		UnLock();
   413 		req->ResourceId() = aResourceId;
   414 		req->ClientId() = KDynamicResourceDeRegistering;
   415 		req->Resource() = pDR;
   416 		req->ResourceCb() = NULL;
   417 		if(aPDefLevel)
   418 			req->Level() = *aPDefLevel; //Set the resource to the passed level
   419 		else
   420 			req->Level() = pDR->iDefaultLevel; //Set the resource level to default level
   421 		if(pDR->LatencySet())
   422 			{
   423 			r = req->SendReceive(iMsgQ);
   424 			}
   425 		else
   426 			{
   427 			//Call custom function for custom sense resource
   428 			if(pDR->Sense() == DStaticPowerResource::ECustom)
   429 				{
   430 				if(!pDR->iCustomFunction)
   431 					Panic(ECustomFunctionNotSet);
   432 				pDR->iCustomFunction(req->ClientId(), *(aClientPtr->iName), aResourceId,
   433 				                     EDynamicResourceDeregister, req->Level(),
   434 				                     (TAny*)&pDR->iClientList, NULL);
   435 				}
   436 			//Not checking for error condition as the resource needs to be moved to default state
   437 			if(aPDefLevel)
   438 				{
   439 				//If the resource change to requested level fails trying to change it to default level.
   440 				req->ReqType() = TPowerRequest::EChange;
   441 				r = pDR->DoRequest(*req);
   442 				if(r != KErrNone)
   443 					{
   444 					req->ReqType() = TPowerRequest::ESetDefaultLevel;
   445 					req->Level() = pDR->iDefaultLevel;
   446 					pDR->DoRequest(*req);
   447 					}
   448 				}
   449 			else
   450 				pDR->DoRequest(*req);
   451 			//Send notifications. Passing -2 in clientId to indicate that this dynamic resource is deregistering
   452 			CompleteNotifications(KDynamicResourceDeRegistering, pDR, req->Level(),KErrNone, req->ClientId());
   453 			}
   454 		}
   455 	Lock();
   456 	//Remove client level
   457 	SPowerResourceClientLevel *pCL;
   458 	SPowerResourceClient *pC;
   459 	for(SDblQueLink* pRC = pDR->iClientList.First(); pRC != &pDR->iClientList.iA; pRC = pRC->iNext)
   460 		{
   461 		pCL = (SPowerResourceClientLevel*)pRC;
   462 		if(pCL->iClientId & USER_SIDE_CLIENT_BIT_MASK)
   463 			pC = iUserSideClientList[(TUint16)(pCL->iClientId & ID_INDEX_BIT_MASK)];								
   464 		else																										
   465 			pC = iClientList[(TUint16)(pCL->iClientId & ID_INDEX_BIT_MASK)];										
   466 		LIST_REMOVE(pC->iLevelList, pCL, iNextInList, SPowerResourceClientLevel);
   467 		LIST_PUSH(iClientLevelPool, pCL, iNextInList);
   468 		if(pC->iUnderFlowClCount > 0)
   469 			{
   470 			pC->iUnderFlowClCount--;
   471 			iClientLevelPoolCount++;
   472 			}
   473 		else
   474 			pC->iReservedCl++;
   475 		}
   476 	//Decrement dynamic resource count in client
   477 	aClientPtr->iDynamicResCount--;
   478 	if(aResourceId & KIdMaskResourceWithDependencies)
   479 		{
   480 		iDynamicResDependencyList.Remove((DDynamicPowerResourceD*)pDR, (TUint16)(pDR->iResourceId & ID_INDEX_BIT_MASK));
   481 		iDynamicResDependencyCount--;
   482 		}
   483 	else
   484 		{
   485 		iDynamicResourceList.Remove(pDR, (TUint16)(pDR->iResourceId & ID_INDEX_BIT_MASK));
   486 		iDynamicResourceCount--;
   487 		}
   488 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DExtendedResourceController::DeregisterDynamicResource"));
   489 #ifdef PRM_INSTRUMENTATION_MACRO
   490 	TInt level = req->Level();
   491 	PRM_DEREGISTER_DYNAMIC_RESOURCE_TRACE
   492 #endif
   493 	return r;
   494 	}
   495 
   496 /**
   497 @publishedPartner
   498 @prototype 9.6
   499 Default implementation, PSL re-implements this if features supported.
   500 */
   501 TInt DPowerResourceController::DoRegisterStaticResourcesDependency(DStaticPowerResourceD**& aStaticResourceDArray, 
   502 																    TUint16& aStaticResourceDCount)
   503 	{
   504 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("DExtendedResourceController::DoRegisterStaticResourcesDependency default implementation"));
   505 	aStaticResourceDArray = NULL;
   506 	aStaticResourceDCount = 0;
   507 	return KErrNone;
   508 	}
   509 
   510 /**
   511 This function checks for any closed loop dependency, if so panics.
   512 */
   513 void DPowerResourceController::CheckForDependencyLoop(DStaticPowerResourceD* pR, TUint aParentResId, TUint aTargetResId)
   514 	{
   515 	SNode *pN;
   516 
   517 	if(pR->iResourceId & KIdMaskDynamic)
   518 		pN = ((DDynamicPowerResourceD*)pR)->iDependencyList;
   519 	else
   520 		pN = pR->iDependencyList;
   521 
   522 	for(; pN != NULL; pN = pN->iNext)
   523 		{
   524 		if(pN->iResource->iResourceId == aParentResId)
   525 			continue;
   526 		if(pN->iVisited || (pN->iResource->iResourceId == aTargetResId))
   527 			{
   528 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Loop encountered\n"));
   529 			DPowerResourceController::Panic(DPowerResourceController::EClosedLoopDependencies);
   530 			}
   531 		pN->iVisited = ETrue;
   532 		CheckForDependencyLoop(pN->iResource, pR->iResourceId, aTargetResId);
   533 		pN->iVisited = EFalse;
   534 		}
   535 	}
   536 
   537 /**
   538 This is called from the controller thread to handle the dependency resource state change operation.
   539 */
   540 TInt DPowerResourceController::HandleDependencyResourceStateChange(SPowerResourceClient* pC, TPowerRequest& aRequest)
   541 	{
   542 	DStaticPowerResourceD* pR = (DStaticPowerResourceD*)aRequest.Resource();
   543 	if(aRequest.ReqType() == TPowerRequest::EChange) //Handle resource change operation
   544 		{
   545 		if(aRequest.Resource()->Usage()) //Shared resource
   546 			{
   547 			Lock();
   548 			aRequest.ReturnCode() = CheckLevelAndAddClient(pC, &aRequest);
   549 			UnLock();
   550 			if((aRequest.ReturnCode()!= KErrNone) || (!aRequest.RequiresChange()))
   551 				{
   552 				aRequest.Level() = pR->iCachedLevel; //If no change then send the current level back.
   553 				return aRequest.ReturnCode();
   554 				}
   555 			}
   556 		else if(pR->iClientList.IsEmpty())
   557 			{
   558 			Lock();
   559 			if(pC->iReservedCl==0 && !iClientLevelPoolCount)
   560 				{
   561 				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Reserved Client Level exhausted and its free pool empty"));
   562                 aRequest.ReturnCode() = KErrUnderflow;
   563 				UNLOCK_RETURN(KErrUnderflow);
   564 				}
   565 			SPowerResourceClientLevel* pSCL=NULL;
   566 			LIST_POP(iClientLevelPool, pSCL, iNextInList);
   567 			pSCL->iClientId=pC->iClientId;
   568 			pSCL->iResourceId=aRequest.ResourceId();
   569 			pSCL->iLevel=aRequest.Level();
   570 			LIST_PUSH(pC->iLevelList, pSCL, iNextInList); //Add to client
   571 			pR->iClientList.Add(pSCL); //Add in resource
   572 			if(pC->iReservedCl==0)
   573 				{
   574 				iClientLevelPoolCount--;
   575 				pC->iUnderFlowClCount++;
   576 				}
   577             else
   578 			   pC->iReservedCl--;
   579 			if(pR->iCachedLevel == aRequest.Level())
   580 				{
   581 				pR->iLevelOwnerId = aRequest.ClientId();
   582 				if(pR->iIdleListEntry)
   583 					pR->iIdleListEntry->iLevelOwnerId = aRequest.ClientId();
   584 				aRequest.ReturnCode() = KErrNone;
   585 				UNLOCK_RETURN(KErrNone);
   586 				}
   587 			UnLock();
   588 			}
   589 		else
   590 			{
   591 			//Update the level in the client list.
   592 			SPowerResourceClientLevel* pSCL = (SPowerResourceClientLevel*)pR->iClientList.First();
   593 			pSCL->iLevel = aRequest.Level();
   594 			}
   595 	//Call appropriate resource's handle change propagation function
   596 	if(pR->iResourceId & KIdMaskDynamic)
   597 		aRequest.ReturnCode() = ((DDynamicPowerResourceD*)pR)->HandleChangePropagation(aRequest, EChangeStart, pC->iClientId, *(pC->iName));
   598 	else
   599 		aRequest.ReturnCode() = pR->HandleChangePropagation(aRequest, EChangeStart,pC->iClientId, *(pC->iName));
   600 	return aRequest.ReturnCode();
   601 	}
   602 	if(aRequest.ClientId() == -1) //Special where the resource needs to set to default level, when dynamic resource deregisters
   603 		{
   604 		//If resource is asked to change to certain value, instead of default then 
   605 		//try to set it to that value. If not able to set then try to set it to default level.
   606 		if(aRequest.Level() != pR->iDefaultLevel)
   607 			aRequest.ReqType() = TPowerRequest::EChange;
   608 		aRequest.ReturnCode() = pR->DoRequest(aRequest);
   609 		if((aRequest.ReturnCode() != KErrNone) && (aRequest.ReqType() == TPowerRequest::EChange))
   610 			{
   611 			aRequest.ReqType() = TPowerRequest::ESetDefaultLevel;
   612 			aRequest.Level() = pR->iDefaultLevel;
   613 			pR->DoRequest(aRequest);
   614 			}
   615 		//Set clientId to -2, indicating that the resource is deregistered.
   616 		CompleteNotifications(KDynamicResourceDeRegistering, pR, aRequest.Level(), KErrNone, aRequest.ClientId());
   617 		return KErrNone;
   618 		}
   619 	//Handle custom sense resource
   620 	if(aRequest.Resource()->Sense() == DStaticPowerResource::ECustom)
   621 		{
   622 		if(pR->iResourceId & KIdMaskDynamic)
   623 		    {
   624 			aRequest.RequiresChange() = ((DDynamicPowerResourceD*)pR)->iDepCustomFunction(aRequest.ClientId(), *(pC->iName), aRequest.ResourceId(), 
   625 			                                                                              EClientRelinquishLevel, aRequest.Level(), (TAny*)&pR->iClientList,
   626 			                                                                              (TAny*)&((DDynamicPowerResourceD*)pR)->iResourceClientList, NULL);
   627 			}
   628 		else
   629 		    {
   630 			aRequest.RequiresChange() = pR->iDepCustomFunction(aRequest.ClientId(), *(pC->iName), aRequest.ResourceId(),
   631 			                                                   EClientRelinquishLevel, aRequest.Level(), (TAny*)&pR->iClientList,
   632 			                                                   (TAny*)&pR->iResourceClientList, NULL);
   633 		    }
   634 		}
   635 	else
   636 		{
   637 		SPowerResourceClientLevel* pL = NULL;
   638 		SPowerResourceClientLevel* pMCL = NULL;
   639 		TInt maxLevel = KMinTInt;
   640 		//Find the maximum level from client
   641 		for(SDblQueLink* pCL = pR->iClientList.First(); pCL != &pR->iClientList.iA; pCL = pCL->iNext)
   642 			{
   643 			pL = (SPowerResourceClientLevel*)pCL;
   644 			if(pL->iClientId == (TUint)aRequest.ClientId())
   645 				continue;
   646 			if(pMCL == NULL)
   647 				{	
   648 				maxLevel = pL->iLevel;
   649 				pMCL = pL;
   650 				continue;
   651 				}
   652 			if(((pR->Sense() == DStaticPowerResource::ENegative) && (pL->iLevel < maxLevel)) || 
   653 				                    ((pR->Sense() == DStaticPowerResource::EPositive) && (pL->iLevel > maxLevel)))
   654 				{
   655 				maxLevel = pL->iLevel;
   656 				pMCL = pL;
   657 				}
   658 			}	
   659 		//Find the maximum level from resource client level
   660 		if(pR->iResourceId & KIdMaskDynamic)
   661 			pL = ((DDynamicPowerResourceD*)pR)->iResourceClientList;
   662 		else
   663 			pL = pR->iResourceClientList;
   664 		for(; pL != NULL; pL = pL->iNextInList)
   665 			{
   666 			if(pL->iClientId == (TUint)aRequest.ClientId())
   667 				continue;
   668 			if(pMCL == NULL)
   669 					{
   670 				maxLevel = pL->iLevel;
   671 				pMCL = pL;
   672 				continue;
   673 				}
   674 			if(((pR->Sense() == DStaticPowerResource::ENegative) && (pL->iLevel < maxLevel)) || 
   675 				           ((pR->Sense() == DStaticPowerResource::EPositive) && (pL->iLevel > maxLevel)))
   676 				{
   677 				maxLevel = pL->iLevel;
   678 				pMCL = pL;
   679 				}
   680 			}
   681 		if(pMCL == NULL)
   682 			{
   683 			aRequest.ClientId() = -1;
   684 			aRequest.Level() = pR->iDefaultLevel;
   685 			}
   686 		else
   687 			{
   688 			aRequest.ClientId() = pMCL->iClientId;
   689 			aRequest.Level() = maxLevel;
   690 			}
   691 		}
   692 	if((aRequest.Level() == pR->iCachedLevel) && !aRequest.RequiresChange()) //No need to change the resource just update the owner 
   693 		{
   694 		pR->iLevelOwnerId = aRequest.ClientId();
   695 		if(pR->iIdleListEntry)
   696 			pR->iIdleListEntry->iLevelOwnerId = aRequest.ClientId();
   697 		aRequest.ReturnCode() = KErrNone;
   698 		return KErrNone;
   699 		}
   700 	aRequest.ReqType() = TPowerRequest::EChange; //Make the change otherwise PSL set to default level
   701 
   702 	const TDesC8 *name;
   703 	if(aRequest.ClientId() == -1)
   704 		name = &KNoClient;
   705 	else
   706 		{
   707 		if(aRequest.ClientId() & (1 << RESOURCE_BIT_IN_ID_CHECK))										
   708 			{																							
   709 			DStaticPowerResourceD* pResource;												
   710 			if(aRequest.ClientId() & KIdMaskDynamic)										
   711 				pResource = (DStaticPowerResourceD*)iDynamicResDependencyList[(TUint16)(aRequest.ClientId() & ID_INDEX_BIT_MASK)];
   712 			else																						
   713 				pResource = iStaticResDependencyArray[(TUint16)(aRequest.ClientId() & ID_INDEX_BIT_MASK)  - 1];	
   714 			name = pResource->iName;																	
   715 			}																							
   716 		else																							
   717 			{																							
   718 			SPowerResourceClient* pClient;																
   719 			if(aRequest.ClientId() & USER_SIDE_CLIENT_BIT_MASK)										
   720 				pClient = iUserSideClientList[(TUint16)(aRequest.ClientId() & ID_INDEX_BIT_MASK)];	
   721 			else // coverity[returned_null]
   722 				pClient = iClientList[(TUint16)(aRequest.ClientId() & ID_INDEX_BIT_MASK)];			
   723 			name = pClient->iName;				
   724 			}
   725 		}
   726 
   727 	if(pR->iResourceId & KIdMaskDynamic)
   728 		aRequest.ReturnCode() = ((DDynamicPowerResourceD*)pR)->HandleChangePropagation(aRequest, EChangeStart, aRequest.ClientId(), *name);
   729 	else
   730 		aRequest.ReturnCode() = pR->HandleChangePropagation(aRequest, EChangeStart, aRequest.ClientId(), *name);
   731 	if(aRequest.ReturnCode() == KErrPermissionDenied) //Update the ownerId alone
   732 		{
   733 		pR->iLevelOwnerId = aRequest.ClientId();
   734 		if(pR->iIdleListEntry)
   735 			pR->iIdleListEntry->iLevelOwnerId = aRequest.ClientId();
   736 		}
   737 	return KErrNone;
   738 	}
   739 
   740 /**
   741 Deregisters resource dependency.
   742 */
   743 TInt DPowerResourceController::DeregisterResourceDependency(SPowerResourceClient* aClientPtr, TUint aResId1, TUint aResId2)
   744 	{
   745 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::DeregisterResourceDependency"));
   746 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("ClientId = 0x%x, ResourceId1 = 0x%x, ResourceId2 = 0x%x", 
   747 		                                                                  aClientPtr->iClientId, aResId1, aResId2));
   748 	if(iDfcQDependencyLock)
   749 		{
   750 		__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterResourceDependency::Resource In Use"));
   751 		UNLOCK_RETURN(KErrInUse);
   752 		}
   753 	DDynamicPowerResourceD *pDR1 = NULL;
   754 	DDynamicPowerResourceD *pDR2 = NULL;
   755 	SNode* pN1 = NULL;
   756 	SNode* pN2 = NULL;
   757 	SPowerResourceClientLevel* pCL1 = NULL;
   758 	SPowerResourceClientLevel* pCL2 = NULL;
   759 	//Get first resource from list
   760 	if(!(aResId1 & KIdMaskResourceWithDependencies) || !(aResId2 & KIdMaskResourceWithDependencies))
   761 		UNLOCK_RETURN(KErrAccessDenied);
   762 
   763 	if(aResId1 & KIdMaskDynamic)
   764 		{
   765 		pDR1 = iDynamicResDependencyList[(TUint16)(aResId1 & ID_INDEX_BIT_MASK)];	
   766 		if(!pDR1)															
   767 			UNLOCK_RETURN(KErrNotFound);
   768 		pN1 = pDR1->iDependencyList;
   769 		pCL1 = pDR1->iResourceClientList;
   770 		}
   771 	else
   772 		{
   773 		if((aResId1 & ID_INDEX_BIT_MASK) > iStaticResDependencyCount)			
   774 			UNLOCK_RETURN(KErrNotFound);			
   775 		pDR1 = (DDynamicPowerResourceD*)iStaticResDependencyArray[(aResId1 & ID_INDEX_BIT_MASK) - 1];
   776 		pN1 = ((DStaticPowerResourceD*)pDR1)->iDependencyList;
   777 		pCL1 = ((DStaticPowerResourceD*)pDR1)->iResourceClientList;
   778 		}
   779 
   780 	//Get second resource from list
   781 	if(aResId2 & KIdMaskDynamic)
   782 		{
   783 		pDR2 = iDynamicResDependencyList[(TUint16)(aResId2 & ID_INDEX_BIT_MASK)];	
   784 		if(!pDR2)															
   785 			UNLOCK_RETURN(KErrNotFound);
   786 		pN2 = pDR2->iDependencyList;
   787 		pCL2 = pDR2->iResourceClientList;
   788 		}
   789 	else
   790 		{
   791 		if((aResId2 & ID_INDEX_BIT_MASK)> iStaticResDependencyCount)			
   792 				UNLOCK_RETURN(KErrNotFound);			
   793 		pDR2 = (DDynamicPowerResourceD*)iStaticResDependencyArray[(TUint16)(aResId2 & ID_INDEX_BIT_MASK) - 1];
   794 		pN2 = ((DStaticPowerResourceD*)pDR2)->iDependencyList;
   795 		pCL2 = ((DStaticPowerResourceD*)pDR2)->iResourceClientList;
   796 		}
   797 
   798 	//Check whether dependency exist between the two
   799 	SNode* pN = NULL;
   800 	for(pN = pN1; pN != NULL; pN = pN->iNext)
   801 		{
   802 		if(pN->iResource->iResourceId == pDR2->iResourceId)
   803 			break;
   804 		}
   805 	if(pN == NULL)
   806 		UNLOCK_RETURN(KErrNotFound);
   807 	pN1 = pN; //Storing for later use.
   808 	for(pN = pN2; pN != NULL; pN = pN->iNext)
   809 		{
   810 		if(pN->iResource->iResourceId == pDR1->iResourceId)
   811 			break;
   812 		}
   813 	if(pN == NULL)
   814 		return KErrNotFound;
   815 	pN2 = pN; //Storing for later use
   816 	//Remove the dependency link from both the resource
   817 	if(aResId1 & KIdMaskDynamic)
   818 		{
   819 		LIST_REMOVE(pDR1->iDependencyList, pN1, iNext, SNode);
   820 		}
   821 	else
   822 		{
   823 		LIST_REMOVE(((DStaticPowerResourceD*)pDR1)->iDependencyList, pN1, iNext, SNode);
   824 		}
   825 
   826 	if(aResId2 & KIdMaskDynamic)
   827 		{	
   828 		LIST_REMOVE(pDR2->iDependencyList, pN2, iNext, SNode);
   829 		}
   830 	else
   831 		{	
   832 		LIST_REMOVE(((DStaticPowerResourceD*)pDR2)->iDependencyList, pN2, iNext, SNode);
   833 		}
   834 
   835 	//Remove the resource client level from each resource
   836 	for(; pCL1 != NULL; pCL1 = pCL1->iNextInList)
   837 		{
   838 		if(pCL1->iClientId == pDR2->iResourceId)
   839 			{
   840 			if(aResId1 & KIdMaskDynamic)
   841 				{	
   842 				LIST_REMOVE(pDR1->iResourceClientList, pCL1, iNextInList, SPowerResourceClientLevel);
   843 				}	
   844 			else
   845 				{
   846 				LIST_REMOVE(((DStaticPowerResourceD*)pDR1)->iResourceClientList, pCL1, iNextInList, 
   847 					                                            SPowerResourceClientLevel);
   848 				}
   849 			LIST_PUSH(iResourceLevelPool, pCL1, iNextInList);
   850 			iResourceLevelPoolCount++;
   851 			break;
   852 			}
   853 		}
   854 	for(; pCL2 != NULL; pCL2 = pCL2->iNextInList)
   855 		{
   856 		if(pCL2->iClientId == pDR1->iResourceId)
   857 			{
   858 			if(aResId2 & KIdMaskDynamic)
   859 				{	
   860 				LIST_REMOVE(pDR2->iResourceClientList, pCL2, iNextInList, SPowerResourceClientLevel);
   861 				}
   862 			else
   863 				{
   864 				LIST_REMOVE(((DStaticPowerResourceD*)pDR2)->iResourceClientList, pCL2, iNextInList, 
   865 					                                              SPowerResourceClientLevel);
   866 				}
   867 			LIST_PUSH(iResourceLevelPool, pCL2, iNextInList);
   868 			iResourceLevelPoolCount++;
   869 			break;
   870 			}
   871 		}
   872 
   873 	TPowerRequest* req = (TPowerRequest*)&TPowerRequest::Get();
   874 	req->ResourceCb() = NULL;
   875 	req->ReqType() = TPowerRequest::ESetDefaultLevel;
   876 	req->RequiresChange() = EFalse;
   877 	req->ReturnCode() = KErrNone;
   878 	if((TUint)pDR1->iLevelOwnerId == pDR2->iResourceId)
   879 		{
   880 		//Ask to change to default level. Process this in the RC thread;
   881 		req->ResourceId() = pDR1->iResourceId;
   882 		req->ClientId() = pDR2->iResourceId;
   883 		req->Resource() = pDR1;
   884 		req->Level() = pDR1->iDefaultLevel;
   885 		if(aResId1 & KIdMaskDynamic)
   886 			pDR1->Lock();
   887 		UnLock();
   888 		req->SendReceive(iMsgQDependency);
   889 		Lock();
   890 		if(aResId1 & KIdMaskDynamic)
   891 			pDR1->UnLock();
   892 		}
   893 	if((TUint)pDR2->iLevelOwnerId == pDR1->iResourceId)
   894 		{
   895 		//Ask to change to default level. Process this in the RC thread.
   896 		req->ResourceId() = pDR2->iResourceId;
   897 		req->ClientId() = pDR1->iResourceId;
   898 		req->Resource() = pDR2;
   899 		req->Level() = pDR2->iDefaultLevel;
   900 		if(aResId2 & KIdMaskDynamic)
   901 			pDR2->Lock();
   902 		UnLock();
   903 		req->SendReceive(iMsgQDependency);
   904 		Lock();
   905 		if(aResId2 & KIdMaskDynamic)
   906 			pDR2->UnLock();
   907 		}
   908 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::DeregisterResourceDependency"));
   909 #ifdef PRM_INSTRUMENTATION_MACRO
   910 	PRM_DEREGISTER_RESOURCE_DEPENDENCY_TRACE
   911 #endif
   912 	UnLock();
   913 	delete pN1;
   914 	delete pN2;
   915 	return KErrNone;
   916 	}
   917 
   918 /**
   919 This function takes care of resource state change of static dependency resource.
   920 This propagates the change to all of its dependents.
   921 This function takes Originator name and id as parameter as this needs to be passed for custom sense function.
   922 */
   923 TInt DStaticPowerResourceD::HandleChangePropagation(TPowerRequest aRequest, TPropagation aProp, TUint aOriginatorId, const TDesC8& aOriginatorName)
   924 	{
   925 	TInt result = KErrNone;
   926 	result = PowerResourceController->HandleResourceChange(aRequest, aProp, aOriginatorId, aOriginatorName, this);
   927 	return result;
   928 	}
   929 //Function to change the resource state of dependency resource. 
   930 TInt DPowerResourceController::HandleResourceChange(TPowerRequest &aRequest, TPropagation aProp, TUint aOriginatorId, 
   931 													const TDesC8& aOriginatorName, DStaticPowerResourceD* aResource)
   932 	{
   933 	static TUint16 clientLevelCount = 0;
   934 	DStaticPowerResourceD* pDR = (DStaticPowerResourceD*)aRequest.Resource();
   935 	DStaticPowerResourceD* pDepRes = NULL;
   936 	SNode* dependencyList = NULL;
   937 	TPowerRequest depRequest;
   938 	TInt result = KErrNone;
   939 	TInt resState;
   940 	depRequest.ReqType() = TPowerRequest::EChange;
   941 	depRequest.ResourceCb() = NULL;
   942 	depRequest.ReturnCode() = KErrNone;
   943 	depRequest.RequiresChange() = EFalse;
   944 
   945 	if(pDR->iResourceId & KIdMaskDynamic)
   946 		dependencyList = ((DDynamicPowerResourceD*)pDR)->iDependencyList;
   947 	else
   948 		dependencyList = pDR->iDependencyList;
   949 	switch(aProp)																									
   950 		{																											
   951 		case EChangeStart:																							
   952 			{
   953 			if(!dependencyList) /*No dependents so change state of the resource*/
   954 				{																									
   955 				aRequest.ReturnCode() = pDR->DoRequest(aRequest);													
   956 				if(aRequest.ReturnCode() == KErrNone)																
   957 					{																								
   958 					aResource->iCachedLevel = aRequest.Level();																
   959 					aResource->iLevelOwnerId = aRequest.ClientId();															
   960 					if(aResource->iIdleListEntry)																				
   961 						{																							
   962 						aResource->iIdleListEntry->iCurrentLevel = aRequest.Level();											
   963 						aResource->iIdleListEntry->iLevelOwnerId = aRequest.ClientId();										
   964 						}			
   965 					CompleteNotifications(aRequest.ClientId(), pDR,									
   966 							aRequest.Level(), aRequest.ReturnCode(), aRequest.ClientId());							
   967 					}																								
   968 					break;																		
   969 				}					
   970 			depRequest.ResourceId() = aRequest.ResourceId();														
   971 			depRequest.ClientId() = aRequest.ResourceId();															
   972 			depRequest.Level() = aRequest.Level();																	
   973 			depRequest.Resource() = pDR;
   974 			result = pDR->HandleChangePropagation(depRequest, ECheckChangeAllowed, aOriginatorId, aOriginatorName);	
   975 			if(result != KErrNone)																					
   976 				return result;																						
   977 			/*Adjust resource client level*/																		
   978 			if(clientLevelCount)																					
   979 				{					
   980 				result = ReserveClientLevelPoolCount(clientLevelCount);								
   981 				if(result != KErrNone)																				
   982 					return result;																					
   983 				}																									
   984 			/*Resource change of dependents */																		
   985 			pDR->HandleChangePropagation(aRequest, ERequestStateChange, aOriginatorId, aOriginatorName);				
   986 			/*Notification to dependents */																			
   987 			pDR->HandleChangePropagation(aRequest, EIssueNotifications, aOriginatorId, aOriginatorName);				
   988 			break;																									
   989 			}																										
   990 		case ECheckChangeAllowed:																					
   991 			{																										
   992 			TChangePropagationStatus status;																		
   993 			for(SNode* depNode = dependencyList; depNode != NULL; depNode = depNode->iNext)					
   994 				{																									
   995 				pDepRes = depNode->iResource;													
   996 				if((aRequest.ClientId() & KIdMaskResourceWithDependencies) &&										
   997 						(pDepRes->iResourceId == (TUint)aRequest.ClientId()))										
   998 					continue;	
   999 				/*Resource need not change if it is already in that state, so continue with							
  1000 						another dependent state.*/																	
  1001 				if(pDepRes->iResourceId & KIdMaskDynamic)															
  1002 					status = ((DDynamicPowerResourceD*)pDepRes)->TranslateDependentState(aRequest.ResourceId(),		
  1003 																				aRequest.Level(), resState);		
  1004 				else																								
  1005 					status = ((DStaticPowerResourceD*)pDepRes)->TranslateDependentState(aRequest.ResourceId(),		
  1006 																					aRequest.Level(), resState);	
  1007 				if((status == ENoChange) || (pDepRes->iCachedLevel == resState))									
  1008 					{																								
  1009 					depNode->iRequiresChange = EFalse;																
  1010 					continue;																						
  1011 					}																								
  1012 				if(status == EChangeNotAccepted)																	
  1013 					return KErrPermissionDenied;	
  1014 				depRequest.ResourceId() = pDepRes->iResourceId;														
  1015 				depRequest.ClientId() = aRequest.ResourceId(); /*ID of the dependent resource */					
  1016 				depRequest.Level() = resState;																		
  1017 				depRequest.Resource() = pDepRes;		
  1018 				/*Check resource client list and resource list to see whether change is allowed.*/					
  1019 				if(pDepRes->Sense() == DStaticPowerResource::ECustom)												
  1020 					{																								
  1021 					/*Call custom function to check whether change is allowed.*/									
  1022 					if(pDepRes->iResourceId & KIdMaskDynamic)														
  1023 						depRequest.RequiresChange() = ((DDynamicPowerResourceD*)pDepRes)->iDepCustomFunction(depRequest.ClientId(),	
  1024 							aOriginatorName, depRequest.ResourceId(), EClientRequestLevel, depRequest.Level(), (TAny*)&pDepRes->iClientList,		
  1025 									(TAny*)&((DDynamicPowerResourceD*)pDepRes)->iResourceClientList, NULL);				
  1026 					else																							
  1027 						depRequest.RequiresChange() = ((DStaticPowerResourceD*)pDepRes)->iDepCustomFunction(depRequest.ClientId(),		
  1028 							aOriginatorName, depRequest.ResourceId(), EClientRequestLevel, depRequest.Level(), (TAny*)&pDepRes->iClientList,		
  1029 									(TAny*)&((DStaticPowerResourceD*)pDepRes)->iResourceClientList, NULL);				
  1030 					if(!depRequest.RequiresChange())																
  1031 						return KErrPermissionDenied;																
  1032 					}						
  1033 				SPowerResourceClientLevel*pN=NULL;																	
  1034 				for(SDblQueLink* pNL=pDepRes->iClientList.First();pNL!=&pDepRes->iClientList.iA; pNL=pNL->iNext)	
  1035 					{																								
  1036 					pN = (SPowerResourceClientLevel*)pNL;															
  1037 					if(pDepRes->Sense() == DStaticPowerResource::EPositive)											
  1038 						{																							
  1039 						if(pN->iLevel > depRequest.Level())															
  1040 							return KErrPermissionDenied;															
  1041 						}																							
  1042 					else if(pDepRes->Sense() == DStaticPowerResource::ENegative)									
  1043 						{																							
  1044 						if(pN->iLevel < depRequest.Level())															
  1045 							return KErrPermissionDenied;															
  1046 						}																							
  1047 					}																								
  1048 				/*check through the resource client level */														
  1049 				SPowerResourceClientLevel*pCL = NULL;																
  1050 				if(pDepRes->iResourceId & KIdMaskDynamic)															
  1051 					pCL = ((DDynamicPowerResourceD*)pDepRes)->iResourceClientList;									
  1052 				else																								
  1053 					pCL = ((DStaticPowerResourceD*)pDepRes)->iResourceClientList;									
  1054 				for(; pCL != NULL; pCL = pCL->iNextInList)															
  1055 					{																								
  1056 					if(pCL->iClientId == pDR->iResourceId)															
  1057 						break;																						
  1058 					}																								
  1059 				if(!pCL)																							
  1060 					clientLevelCount++;																				
  1061 				/*check dependent resource client list & resource list to see whether change is allowed */			
  1062 				if(pDepRes->iResourceId & KIdMaskDynamic)															
  1063 					result = ((DDynamicPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest,				
  1064 																ECheckChangeAllowed, aOriginatorId, aOriginatorName);	
  1065 				else																								
  1066 					result = ((DStaticPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest,					
  1067 											ECheckChangeAllowed, aOriginatorId, aOriginatorName);						
  1068 				if(result != KErrNone)																				
  1069 					return result;																					
  1070 				depNode->iPropagatedLevel = resState;																
  1071 				depNode->iRequiresChange = ETrue;																	
  1072 				}																									
  1073 			break;																									
  1074 			}																										
  1075 		case ERequestStateChange:																					
  1076 			{																										
  1077 			SPowerResourceClientLevel* pCL = NULL;																	
  1078 			for(SNode* depNode = dependencyList; depNode != NULL; depNode = depNode->iNext)					
  1079 				{																									
  1080 				pDepRes = depNode->iResource;													
  1081 				if((!depNode->iRequiresChange) || (pDepRes->iResourceId == (TUint)aRequest.ClientId()))				
  1082 					continue;																						
  1083 				depRequest.ResourceId() = pDepRes->iResourceId;														
  1084 				depRequest.ClientId() = aRequest.ResourceId();														
  1085 				depRequest.Level() = depNode->iPropagatedLevel;														
  1086 				depRequest.Resource() = pDepRes;									
  1087 				if(pDepRes->iResourceId & KIdMaskDynamic)															
  1088 					((DDynamicPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, ERequestStateChange,	
  1089 																					aOriginatorId, aOriginatorName);	
  1090 				else																								
  1091 					((DStaticPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, ERequestStateChange,		
  1092 																					aOriginatorId, aOriginatorName);	
  1093 				/*Update level if resource client level is already present for this resource.*/						
  1094 				if(pDepRes->iResourceId & KIdMaskDynamic)															
  1095 					pCL = ((DDynamicPowerResourceD*)pDepRes)->iResourceClientList;									
  1096 				else																								
  1097 					pCL = ((DStaticPowerResourceD*)pDepRes)->iResourceClientList;									
  1098 				for(; pCL != NULL; pCL = pCL->iNextInList)															
  1099 					{																								
  1100 					if(pCL->iClientId == pDR->iResourceId)															
  1101 						{																							
  1102 						pCL->iLevel = depNode->iPropagatedLevel;													
  1103 						break;																						
  1104 						}																							
  1105 					}																								
  1106 				if(!pCL) /*Create a new resource client level*/														
  1107 					{																								
  1108 					RemoveClientLevelFromPool(pCL);													
  1109 					pCL->iClientId = pDR->iResourceId;																
  1110 					pCL->iResourceId = pDepRes->iResourceId;														
  1111 					pCL->iLevel = depNode->iPropagatedLevel;														
  1112 					if(pDepRes->iResourceId & KIdMaskDynamic)														
  1113 						{																							
  1114 						LIST_PUSH(((DDynamicPowerResourceD*)pDepRes)->iResourceClientList, pCL, iNextInList);		
  1115 						}																							
  1116 					else																							
  1117 						{																							
  1118 						LIST_PUSH(((DStaticPowerResourceD*)pDepRes)->iResourceClientList, pCL, iNextInList);		
  1119 						}																							
  1120 					clientLevelCount--;																				
  1121 					}																								
  1122 				}	
  1123 #ifdef PRM_INSTRUMENTATION_MACRO			
  1124 			if(aRequest.ClientId() & KIdMaskResourceWithDependencies)								
  1125 				{																									
  1126 				SPowerResourceClient res;																			
  1127 				SPowerResourceClient* pC = &res;																	
  1128 				pC->iClientId = aRequest.ClientId();																
  1129 				pC->iName = &KParentResource;																		
  1130 				DStaticPowerResource*pR = (DStaticPowerResource*)pDR;												
  1131 				TUint aResourceId = pDR->iResourceId;																
  1132 				TInt aNewState = aRequest.Level();																	
  1133 				PRM_CLIENT_CHANGE_STATE_START_TRACE																	
  1134 				}																									
  1135 #endif
  1136 				aResource->DoRequest(aRequest);																				
  1137 #ifdef PRM_INSTRUMENTATION_MACRO
  1138 			if(aRequest.ClientId() & KIdMaskResourceWithDependencies)								
  1139 				{																									
  1140 				SPowerResourceClient res;																			
  1141 				SPowerResourceClient* pC = &res;																	
  1142 				pC->iClientId = aRequest.ClientId();																
  1143 				pC->iName = &KParentResource;																		
  1144 				DStaticPowerResource*pR = (DStaticPowerResource*)pDR;												
  1145 				TUint aResourceId = pDR->iResourceId;																
  1146 				TInt aNewState = aRequest.Level();																	
  1147 				TInt r = KErrNone;																					
  1148 				PRM_CLIENT_CHANGE_STATE_END_TRACE																	
  1149 				}													
  1150 #endif												
  1151 			pDR->iCachedLevel = aRequest.Level();																	
  1152 			pDR->iLevelOwnerId = aRequest.ClientId();																
  1153 			if(pDR->iIdleListEntry)																					
  1154 				{																									
  1155 				pDR->iIdleListEntry->iCurrentLevel = aRequest.Level();												
  1156 				pDR->iIdleListEntry->iLevelOwnerId = aRequest.ClientId();											
  1157 				}									
  1158 			break;																									
  1159 			}																										
  1160 		case EIssueNotifications:																					
  1161 			{																										
  1162 			for(SNode* depNode = dependencyList; depNode != NULL; depNode = depNode->iNext)					
  1163 				{																									
  1164 				pDepRes = depNode->iResource;													
  1165 				if((!depNode->iRequiresChange) || (pDepRes->iResourceId == (TUint)aRequest.ClientId()))				
  1166 					continue;																						
  1167 				depRequest.ResourceId() = pDepRes->iResourceId;														
  1168 				depRequest.ClientId() = pDepRes->iLevelOwnerId;														
  1169 				depRequest.Level() = pDepRes->iCachedLevel;															
  1170 				depRequest.Resource() = pDepRes;																	
  1171 				if(pDepRes->iResourceId & KIdMaskDynamic)															
  1172 					((DDynamicPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, EIssueNotifications,	
  1173 																					aOriginatorId, aOriginatorName);	
  1174 				else																								
  1175 					((DStaticPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, EIssueNotifications,		
  1176 																					aOriginatorId, aOriginatorName);	
  1177 				}							
  1178 			CompleteNotifications(aRequest.ClientId(), pDR, aRequest.Level(), KErrNone,				
  1179 																					aRequest.ClientId());			
  1180 			break;																									
  1181 			}																										
  1182 		default:																									
  1183 			return KErrNotSupported;																				
  1184 		}																											
  1185 	return result;
  1186 	}
  1187 
  1188