kernel/eka/drivers/resourceman/resourcecontrol_extended.cpp
changeset 0 a41df078684a
child 4 56f325a607ea
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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 * 4;
       
    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 \
       
   505 		                                                               implementation"));
       
   506 	aStaticResourceDArray = NULL;
       
   507 	aStaticResourceDCount = 0;
       
   508 	return KErrNone;
       
   509 	}
       
   510 
       
   511 /**
       
   512 This function checks for any closed loop dependency, if so panics.
       
   513 */
       
   514 void DPowerResourceController::CheckForDependencyLoop(DStaticPowerResourceD* pR, TUint aParentResId, TUint aTargetResId)
       
   515 	{
       
   516 	SNode *pN;
       
   517 
       
   518 	if(pR->iResourceId & KIdMaskDynamic)
       
   519 		pN = ((DDynamicPowerResourceD*)pR)->iDependencyList;
       
   520 	else
       
   521 		pN = pR->iDependencyList;
       
   522 
       
   523 	for(; pN != NULL; pN = pN->iNext)
       
   524 		{
       
   525 		if(pN->iResource->iResourceId == aParentResId)
       
   526 			continue;
       
   527 		if(pN->iVisited || (pN->iResource->iResourceId == aTargetResId))
       
   528 			{
       
   529 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Loop encountered\n"));
       
   530 			DPowerResourceController::Panic(DPowerResourceController::EClosedLoopDependencies);
       
   531 			}
       
   532 		pN->iVisited = ETrue;
       
   533 		CheckForDependencyLoop(pN->iResource, pR->iResourceId, aTargetResId);
       
   534 		pN->iVisited = EFalse;
       
   535 		}
       
   536 	}
       
   537 
       
   538 /**
       
   539 This is called from the controller thread to handle the dependency resource state change operation.
       
   540 */
       
   541 TInt DPowerResourceController::HandleDependencyResourceStateChange(SPowerResourceClient* pC, TPowerRequest& aRequest)
       
   542 	{
       
   543 	DStaticPowerResourceD* pR = (DStaticPowerResourceD*)aRequest.Resource();
       
   544 	if(aRequest.ReqType() == TPowerRequest::EChange) //Handle resource change operation
       
   545 		{
       
   546 		if(aRequest.Resource()->Usage()) //Shared resource
       
   547 			{
       
   548 			Lock();
       
   549 			aRequest.ReturnCode() = CheckLevelAndAddClient(pC, &aRequest);
       
   550 			UnLock();
       
   551 			if((aRequest.ReturnCode()!= KErrNone) || (!aRequest.RequiresChange()))
       
   552 				{
       
   553 				aRequest.Level() = pR->iCachedLevel; //If no change then send the current level back.
       
   554 				return aRequest.ReturnCode();
       
   555 				}
       
   556 			}
       
   557 		else if(pR->iClientList.IsEmpty())
       
   558 			{
       
   559 			Lock();
       
   560 			if(pC->iReservedCl==0 && !iClientLevelPoolCount)
       
   561 				{
       
   562 				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Reserved Client Level exhausted and its free pool empty"));
       
   563                 aRequest.ReturnCode() = KErrUnderflow;
       
   564 				UNLOCK_RETURN(KErrUnderflow);
       
   565 				}
       
   566 			SPowerResourceClientLevel* pSCL=NULL;
       
   567 			LIST_POP(iClientLevelPool, pSCL, iNextInList);
       
   568 			pSCL->iClientId=pC->iClientId;
       
   569 			pSCL->iResourceId=aRequest.ResourceId();
       
   570 			pSCL->iLevel=aRequest.Level();
       
   571 			LIST_PUSH(pC->iLevelList, pSCL, iNextInList); //Add to client
       
   572 			pR->iClientList.Add(pSCL); //Add in resource
       
   573 			if(pC->iReservedCl==0)
       
   574 				{
       
   575 				iClientLevelPoolCount--;
       
   576 				pC->iUnderFlowClCount++;
       
   577 				}
       
   578             else
       
   579 			   pC->iReservedCl--;
       
   580 			if(pR->iCachedLevel == aRequest.Level())
       
   581 				{
       
   582 				pR->iLevelOwnerId = aRequest.ClientId();
       
   583 				if(pR->iIdleListEntry)
       
   584 					pR->iIdleListEntry->iLevelOwnerId = aRequest.ClientId();
       
   585 				aRequest.ReturnCode() = KErrNone;
       
   586 				UNLOCK_RETURN(KErrNone);
       
   587 				}
       
   588 			UnLock();
       
   589 			}
       
   590 		else
       
   591 			{
       
   592 			//Update the level in the client list.
       
   593 			SPowerResourceClientLevel* pSCL = (SPowerResourceClientLevel*)pR->iClientList.First();
       
   594 			pSCL->iLevel = aRequest.Level();
       
   595 			}
       
   596 	//Call appropriate resource's handle change propagation function
       
   597 	if(pR->iResourceId & KIdMaskDynamic)
       
   598 		aRequest.ReturnCode() = ((DDynamicPowerResourceD*)pR)->HandleChangePropagation(aRequest, EChangeStart, pC->iClientId, *(pC->iName));
       
   599 	else
       
   600 		aRequest.ReturnCode() = pR->HandleChangePropagation(aRequest, EChangeStart,pC->iClientId, *(pC->iName));
       
   601 	return aRequest.ReturnCode();
       
   602 	}
       
   603 	if(aRequest.ClientId() == -1) //Special where the resource needs to set to default level, when dynamic resource deregisters
       
   604 		{
       
   605 		//If resource is asked to change to certain value, instead of default then 
       
   606 		//try to set it to that value. If not able to set then try to set it to default level.
       
   607 		if(aRequest.Level() != pR->iDefaultLevel)
       
   608 			aRequest.ReqType() = TPowerRequest::EChange;
       
   609 		aRequest.ReturnCode() = pR->DoRequest(aRequest);
       
   610 		if((aRequest.ReturnCode() != KErrNone) && (aRequest.ReqType() == TPowerRequest::EChange))
       
   611 			{
       
   612 			aRequest.ReqType() = TPowerRequest::ESetDefaultLevel;
       
   613 			aRequest.Level() = pR->iDefaultLevel;
       
   614 			pR->DoRequest(aRequest);
       
   615 			}
       
   616 		//Set clientId to -2, indicating that the resource is deregistered.
       
   617 		CompleteNotifications(KDynamicResourceDeRegistering, pR, aRequest.Level(), KErrNone, aRequest.ClientId());
       
   618 		return KErrNone;
       
   619 		}
       
   620 	//Handle custom sense resource
       
   621 	if(aRequest.Resource()->Sense() == DStaticPowerResource::ECustom)
       
   622 		{
       
   623 		if(pR->iResourceId & KIdMaskDynamic)
       
   624 		    {
       
   625 			aRequest.RequiresChange() = ((DDynamicPowerResourceD*)pR)->iDepCustomFunction(aRequest.ClientId(), *(pC->iName), aRequest.ResourceId(), 
       
   626 			                                                                              EClientRelinquishLevel, aRequest.Level(), (TAny*)&pR->iClientList,
       
   627 			                                                                              (TAny*)&((DDynamicPowerResourceD*)pR)->iResourceClientList, NULL);
       
   628 			}
       
   629 		else
       
   630 		    {
       
   631 			aRequest.RequiresChange() = pR->iDepCustomFunction(aRequest.ClientId(), *(pC->iName), aRequest.ResourceId(),
       
   632 			                                                   EClientRelinquishLevel, aRequest.Level(), (TAny*)&pR->iClientList,
       
   633 			                                                   (TAny*)&pR->iResourceClientList, NULL);
       
   634 		    }
       
   635 		}
       
   636 	else
       
   637 		{
       
   638 		SPowerResourceClientLevel* pL = NULL;
       
   639 		SPowerResourceClientLevel* pMCL = NULL;
       
   640 		TInt maxLevel = KMinTInt;
       
   641 		//Find the maximum level from client
       
   642 		for(SDblQueLink* pCL = pR->iClientList.First(); pCL != &pR->iClientList.iA; pCL = pCL->iNext)
       
   643 			{
       
   644 			pL = (SPowerResourceClientLevel*)pCL;
       
   645 			if(pL->iClientId == (TUint)aRequest.ClientId())
       
   646 				continue;
       
   647 			if(pMCL == NULL)
       
   648 				{	
       
   649 				maxLevel = pL->iLevel;
       
   650 				pMCL = pL;
       
   651 				continue;
       
   652 				}
       
   653 			if(((pR->Sense() == DStaticPowerResource::ENegative) && (pL->iLevel < maxLevel)) || 
       
   654 				                    ((pR->Sense() == DStaticPowerResource::EPositive) && (pL->iLevel > maxLevel)))
       
   655 				{
       
   656 				maxLevel = pL->iLevel;
       
   657 				pMCL = pL;
       
   658 				}
       
   659 			}	
       
   660 		//Find the maximum level from resource client level
       
   661 		if(pR->iResourceId & KIdMaskDynamic)
       
   662 			pL = ((DDynamicPowerResourceD*)pR)->iResourceClientList;
       
   663 		else
       
   664 			pL = pR->iResourceClientList;
       
   665 		for(; pL != NULL; pL = pL->iNextInList)
       
   666 			{
       
   667 			if(pL->iClientId == (TUint)aRequest.ClientId())
       
   668 				continue;
       
   669 			if(pMCL == NULL)
       
   670 					{
       
   671 				maxLevel = pL->iLevel;
       
   672 				pMCL = pL;
       
   673 				continue;
       
   674 				}
       
   675 			if(((pR->Sense() == DStaticPowerResource::ENegative) && (pL->iLevel < maxLevel)) || 
       
   676 				           ((pR->Sense() == DStaticPowerResource::EPositive) && (pL->iLevel > maxLevel)))
       
   677 				{
       
   678 				maxLevel = pL->iLevel;
       
   679 				pMCL = pL;
       
   680 				}
       
   681 			}
       
   682 		if(pMCL == NULL)
       
   683 			{
       
   684 			aRequest.ClientId() = -1;
       
   685 			aRequest.Level() = pR->iDefaultLevel;
       
   686 			}
       
   687 		else
       
   688 			{
       
   689 			aRequest.ClientId() = pMCL->iClientId;
       
   690 			aRequest.Level() = maxLevel;
       
   691 			}
       
   692 		}
       
   693 	if((aRequest.Level() == pR->iCachedLevel) && !aRequest.RequiresChange()) //No need to change the resource just update the owner 
       
   694 		{
       
   695 		pR->iLevelOwnerId = aRequest.ClientId();
       
   696 		if(pR->iIdleListEntry)
       
   697 			pR->iIdleListEntry->iLevelOwnerId = aRequest.ClientId();
       
   698 		aRequest.ReturnCode() = KErrNone;
       
   699 		return KErrNone;
       
   700 		}
       
   701 	aRequest.ReqType() = TPowerRequest::EChange; //Make the change otherwise PSL set to default level
       
   702 
       
   703 	const TDesC8 *name;
       
   704 	if(aRequest.ClientId() == -1)
       
   705 		name = &KNoClient;
       
   706 	else
       
   707 		{
       
   708 		if(aRequest.ClientId() & (1 << RESOURCE_BIT_IN_ID_CHECK))										
       
   709 			{																							
       
   710 			DStaticPowerResourceD* pResource;												
       
   711 			if(aRequest.ClientId() & KIdMaskDynamic)										
       
   712 				pResource = (DStaticPowerResourceD*)iDynamicResDependencyList[(TUint16)(aRequest.ClientId() & ID_INDEX_BIT_MASK)];
       
   713 			else																						
       
   714 				pResource = iStaticResDependencyArray[(TUint16)(aRequest.ClientId() & ID_INDEX_BIT_MASK)  - 1];	
       
   715 			name = pResource->iName;																	
       
   716 			}																							
       
   717 		else																							
       
   718 			{																							
       
   719 			SPowerResourceClient* pClient;																
       
   720 			if(aRequest.ClientId() & USER_SIDE_CLIENT_BIT_MASK)										
       
   721 				pClient = iUserSideClientList[(TUint16)(aRequest.ClientId() & ID_INDEX_BIT_MASK)];	
       
   722 			else // coverity[returned_null]
       
   723 				pClient = iClientList[(TUint16)(aRequest.ClientId() & ID_INDEX_BIT_MASK)];			
       
   724 			name = pClient->iName;				
       
   725 			}
       
   726 		}
       
   727 
       
   728 	if(pR->iResourceId & KIdMaskDynamic)
       
   729 		aRequest.ReturnCode() = ((DDynamicPowerResourceD*)pR)->HandleChangePropagation(aRequest, EChangeStart, aRequest.ClientId(), *name);
       
   730 	else
       
   731 		aRequest.ReturnCode() = pR->HandleChangePropagation(aRequest, EChangeStart, aRequest.ClientId(), *name);
       
   732 	if(aRequest.ReturnCode() == KErrPermissionDenied) //Update the ownerId alone
       
   733 		{
       
   734 		pR->iLevelOwnerId = aRequest.ClientId();
       
   735 		if(pR->iIdleListEntry)
       
   736 			pR->iIdleListEntry->iLevelOwnerId = aRequest.ClientId();
       
   737 		}
       
   738 	return KErrNone;
       
   739 	}
       
   740 
       
   741 /**
       
   742 Deregisters resource dependency.
       
   743 */
       
   744 TInt DPowerResourceController::DeregisterResourceDependency(SPowerResourceClient* aClientPtr, TUint aResId1, TUint aResId2)
       
   745 	{
       
   746 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::DeregisterResourceDependency"));
       
   747 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("ClientId = 0x%x, ResourceId1 = 0x%x, ResourceId2 = 0x%x", 
       
   748 		                                                                  aClientPtr->iClientId, aResId1, aResId2));
       
   749 	if(iDfcQDependencyLock)
       
   750 		{
       
   751 		__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterResourceDependency::Resource In Use"));
       
   752 		UNLOCK_RETURN(KErrInUse);
       
   753 		}
       
   754 	DDynamicPowerResourceD *pDR1 = NULL;
       
   755 	DDynamicPowerResourceD *pDR2 = NULL;
       
   756 	SNode* pN1 = NULL;
       
   757 	SNode* pN2 = NULL;
       
   758 	SPowerResourceClientLevel* pCL1 = NULL;
       
   759 	SPowerResourceClientLevel* pCL2 = NULL;
       
   760 	//Get first resource from list
       
   761 	if(!(aResId1 & KIdMaskResourceWithDependencies) || !(aResId2 & KIdMaskResourceWithDependencies))
       
   762 		UNLOCK_RETURN(KErrAccessDenied);
       
   763 
       
   764 	if(aResId1 & KIdMaskDynamic)
       
   765 		{
       
   766 		pDR1 = iDynamicResDependencyList[(TUint16)(aResId1 & ID_INDEX_BIT_MASK)];	
       
   767 		if(!pDR1)															
       
   768 			UNLOCK_RETURN(KErrNotFound);
       
   769 		pN1 = pDR1->iDependencyList;
       
   770 		pCL1 = pDR1->iResourceClientList;
       
   771 		}
       
   772 	else
       
   773 		{
       
   774 		if((aResId1 & ID_INDEX_BIT_MASK) > iStaticResDependencyCount)			
       
   775 			UNLOCK_RETURN(KErrNotFound);			
       
   776 		pDR1 = (DDynamicPowerResourceD*)iStaticResDependencyArray[(aResId1 & ID_INDEX_BIT_MASK) - 1];
       
   777 		pN1 = ((DStaticPowerResourceD*)pDR1)->iDependencyList;
       
   778 		pCL1 = ((DStaticPowerResourceD*)pDR1)->iResourceClientList;
       
   779 		}
       
   780 
       
   781 	//Get second resource from list
       
   782 	if(aResId2 & KIdMaskDynamic)
       
   783 		{
       
   784 		pDR2 = iDynamicResDependencyList[(TUint16)(aResId2 & ID_INDEX_BIT_MASK)];	
       
   785 		if(!pDR2)															
       
   786 			UNLOCK_RETURN(KErrNotFound);
       
   787 		pN2 = pDR2->iDependencyList;
       
   788 		pCL2 = pDR2->iResourceClientList;
       
   789 		}
       
   790 	else
       
   791 		{
       
   792 		if((aResId2 & ID_INDEX_BIT_MASK)> iStaticResDependencyCount)			
       
   793 				UNLOCK_RETURN(KErrNotFound);			
       
   794 		pDR2 = (DDynamicPowerResourceD*)iStaticResDependencyArray[(TUint16)(aResId2 & ID_INDEX_BIT_MASK) - 1];
       
   795 		pN2 = ((DStaticPowerResourceD*)pDR2)->iDependencyList;
       
   796 		pCL2 = ((DStaticPowerResourceD*)pDR2)->iResourceClientList;
       
   797 		}
       
   798 
       
   799 	//Check whether dependency exist between the two
       
   800 	SNode* pN = NULL;
       
   801 	for(pN = pN1; pN != NULL; pN = pN->iNext)
       
   802 		{
       
   803 		if(pN->iResource->iResourceId == pDR2->iResourceId)
       
   804 			break;
       
   805 		}
       
   806 	if(pN == NULL)
       
   807 		UNLOCK_RETURN(KErrNotFound);
       
   808 	pN1 = pN; //Storing for later use.
       
   809 	for(pN = pN2; pN != NULL; pN = pN->iNext)
       
   810 		{
       
   811 		if(pN->iResource->iResourceId == pDR1->iResourceId)
       
   812 			break;
       
   813 		}
       
   814 	if(pN == NULL)
       
   815 		return KErrNotFound;
       
   816 	pN2 = pN; //Storing for later use
       
   817 	//Remove the dependency link from both the resource
       
   818 	if(aResId1 & KIdMaskDynamic)
       
   819 		{
       
   820 		LIST_REMOVE(pDR1->iDependencyList, pN1, iNext, SNode);
       
   821 		}
       
   822 	else
       
   823 		{
       
   824 		LIST_REMOVE(((DStaticPowerResourceD*)pDR1)->iDependencyList, pN1, iNext, SNode);
       
   825 		}
       
   826 
       
   827 	if(aResId2 & KIdMaskDynamic)
       
   828 		{	
       
   829 		LIST_REMOVE(pDR2->iDependencyList, pN2, iNext, SNode);
       
   830 		}
       
   831 	else
       
   832 		{	
       
   833 		LIST_REMOVE(((DStaticPowerResourceD*)pDR2)->iDependencyList, pN2, iNext, SNode);
       
   834 		}
       
   835 
       
   836 	//Remove the resource client level from each resource
       
   837 	for(; pCL1 != NULL; pCL1 = pCL1->iNextInList)
       
   838 		{
       
   839 		if(pCL1->iClientId == pDR2->iResourceId)
       
   840 			{
       
   841 			if(aResId1 & KIdMaskDynamic)
       
   842 				{	
       
   843 				LIST_REMOVE(pDR1->iResourceClientList, pCL1, iNextInList, SPowerResourceClientLevel);
       
   844 				}	
       
   845 			else
       
   846 				{
       
   847 				LIST_REMOVE(((DStaticPowerResourceD*)pDR1)->iResourceClientList, pCL1, iNextInList, 
       
   848 					                                            SPowerResourceClientLevel);
       
   849 				}
       
   850 			LIST_PUSH(iResourceLevelPool, pCL1, iNextInList);
       
   851 			iResourceLevelPoolCount++;
       
   852 			break;
       
   853 			}
       
   854 		}
       
   855 	for(; pCL2 != NULL; pCL2 = pCL2->iNextInList)
       
   856 		{
       
   857 		if(pCL2->iClientId == pDR1->iResourceId)
       
   858 			{
       
   859 			if(aResId2 & KIdMaskDynamic)
       
   860 				{	
       
   861 				LIST_REMOVE(pDR2->iResourceClientList, pCL2, iNextInList, SPowerResourceClientLevel);
       
   862 				}
       
   863 			else
       
   864 				{
       
   865 				LIST_REMOVE(((DStaticPowerResourceD*)pDR2)->iResourceClientList, pCL2, iNextInList, 
       
   866 					                                              SPowerResourceClientLevel);
       
   867 				}
       
   868 			LIST_PUSH(iResourceLevelPool, pCL2, iNextInList);
       
   869 			iResourceLevelPoolCount++;
       
   870 			break;
       
   871 			}
       
   872 		}
       
   873 
       
   874 	TPowerRequest* req = (TPowerRequest*)&TPowerRequest::Get();
       
   875 	req->ResourceCb() = NULL;
       
   876 	req->ReqType() = TPowerRequest::ESetDefaultLevel;
       
   877 	req->RequiresChange() = EFalse;
       
   878 	req->ReturnCode() = KErrNone;
       
   879 	if((TUint)pDR1->iLevelOwnerId == pDR2->iResourceId)
       
   880 		{
       
   881 		//Ask to change to default level. Process this in the RC thread;
       
   882 		req->ResourceId() = pDR1->iResourceId;
       
   883 		req->ClientId() = pDR2->iResourceId;
       
   884 		req->Resource() = pDR1;
       
   885 		req->Level() = pDR1->iDefaultLevel;
       
   886 		if(aResId1 & KIdMaskDynamic)
       
   887 			pDR1->Lock();
       
   888 		UnLock();
       
   889 		req->SendReceive(iMsgQDependency);
       
   890 		Lock();
       
   891 		if(aResId1 & KIdMaskDynamic)
       
   892 			pDR1->UnLock();
       
   893 		}
       
   894 	if((TUint)pDR2->iLevelOwnerId == pDR1->iResourceId)
       
   895 		{
       
   896 		//Ask to change to default level. Process this in the RC thread.
       
   897 		req->ResourceId() = pDR2->iResourceId;
       
   898 		req->ClientId() = pDR1->iResourceId;
       
   899 		req->Resource() = pDR2;
       
   900 		req->Level() = pDR2->iDefaultLevel;
       
   901 		if(aResId2 & KIdMaskDynamic)
       
   902 			pDR2->Lock();
       
   903 		UnLock();
       
   904 		req->SendReceive(iMsgQDependency);
       
   905 		Lock();
       
   906 		if(aResId2 & KIdMaskDynamic)
       
   907 			pDR2->UnLock();
       
   908 		}
       
   909 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::DeregisterResourceDependency"));
       
   910 #ifdef PRM_INSTRUMENTATION_MACRO
       
   911 	PRM_DEREGISTER_RESOURCE_DEPENDENCY_TRACE
       
   912 #endif
       
   913 	UnLock();
       
   914 	delete pN1;
       
   915 	delete pN2;
       
   916 	return KErrNone;
       
   917 	}
       
   918 
       
   919 /**
       
   920 This function takes care of resource state change of static dependency resource.
       
   921 This propagates the change to all of its dependents.
       
   922 This function takes Originator name and id as parameter as this needs to be passed for custom sense function.
       
   923 */
       
   924 TInt DStaticPowerResourceD::HandleChangePropagation(TPowerRequest aRequest, TPropagation aProp, TUint aOriginatorId, const TDesC8& aOriginatorName)
       
   925 	{
       
   926 	static TUint16 clientLevelCount = 0;
       
   927 	DStaticPowerResourceD* pDR = (DStaticPowerResourceD*)aRequest.Resource();
       
   928 	TInt result = KErrNone;
       
   929 	TInt resState;
       
   930 	TPowerRequest depRequest;
       
   931 	depRequest.ReqType() = TPowerRequest::EChange;
       
   932 	depRequest.ResourceCb() = NULL;
       
   933 	depRequest.ReturnCode() = KErrNone;
       
   934 	depRequest.RequiresChange() = EFalse;
       
   935 	DStaticPowerResourceD* pDepRes = NULL;
       
   936 	TBool traceEnabled = EFalse;
       
   937 #ifdef PRM_INSTRUMENTATION_MACRO
       
   938 	traceEnabled = ETrue;
       
   939 #endif
       
   940 	HANDLE_CHANGE_PROPAGATION(PowerResourceController, DStaticPowerResourceD*, traceEnabled, aOriginatorId, aOriginatorName)
       
   941 	}
       
   942 
       
   943