os/kernelhwsrv/kernel/eka/drivers/resourceman/resourcecontrol.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kernel/eka/drivers/resourceman/resourcecontrol.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,4002 @@
     1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// e32\drivers\resourceman\resourcecontrol.cpp
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +#include <drivers/resourcecontrol.h>
    1.22 +#include <drivers/resourcecontrol_trace.h>
    1.23 +#ifdef DEBUG_VERSION
    1.24 +#define GET_CRITICAL_SECTION_COUNT				\
    1.25 +	DThread& thread = Kern::CurrentThread();	\
    1.26 +	TInt CsCount = thread.iNThread.iCsCount;
    1.27 +
    1.28 +#define LOCK_AND_CRITICAL_SECTION_COUNT_CHECK						\
    1.29 +	if(thread.iNThread.iCsCount != CsCount)							\
    1.30 +		Kern::Fault("PowerResourceController CScount", __LINE__);	\
    1.31 +	if(PowerResourceController->iResourceMutex->iHoldCount != 0)	\
    1.32 +		Kern::Fault("PowerResourceController HoldCount", __LINE__);
    1.33 +#else
    1.34 +#define GET_CRITICAL_SECTION_COUNT
    1.35 +#define LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
    1.36 +#endif
    1.37 +
    1.38 +/** Allow interface class to call this. */
    1.39 +DPowerResourceController* PowerResourceController = NULL;
    1.40 +
    1.41 +/** Resource Controller factory class implementation */
    1.42 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
    1.43 +#ifndef PRM_ENABLE_EXTENDED_VERSION
    1.44 +_LIT(KPddName,"resourcecontroller.pdd");
    1.45 +#else
    1.46 +_LIT(KPddName, "resourcecontrollerextended.pdd");
    1.47 +#endif
    1.48 +#else
    1.49 +#ifndef PRM_ENABLE_EXTENDED_VERSION
    1.50 +_LIT(KPddName, "resman.pdd");
    1.51 +#else
    1.52 +_LIT(KPddName, "resmanextended.pdd");
    1.53 +#endif
    1.54 +#endif
    1.55 +
    1.56 +/** Factory class constructor */
    1.57 +DResConPddFactory::DResConPddFactory()
    1.58 +	{
    1.59 +    //Set Version number
    1.60 +    iVersion = DResConPddFactory::VersionRequired();
    1.61 +	}
    1.62 +
    1.63 +TInt DResConPddFactory::Install()
    1.64 +    {
    1.65 +    // Set a Name for Resource Controller Factory class object.
    1.66 +    return(SetName(&KPddName));
    1.67 +    }
    1.68 +
    1.69 +/**  Called by the kernel's device driver framework to create a Physical Channel. */
    1.70 +TInt DResConPddFactory::Create(DBase*& aChannel, TInt /*aUint*/, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/)
    1.71 +    {
    1.72 +    //Create new interface for each channel.
    1.73 +	DUserSideProxyInterface *pI = new (DUserSideProxyInterface);
    1.74 +	if(!pI)
    1.75 +		return KErrNoMemory;
    1.76 +	pI->iController = PowerResourceController; //Store the resource controller. 
    1.77 +	aChannel = (DBase*)pI;
    1.78 +    return KErrNone;
    1.79 +    }
    1.80 +
    1.81 +/**  Called by the kernel's device driver framework to check if this PDD is suitable for use with a Logical Channel.*/
    1.82 +TInt DResConPddFactory::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
    1.83 +    {
    1.84 +   	if (!Kern::QueryVersionSupported(DResConPddFactory::VersionRequired(),aVer))
    1.85 +		return(KErrNotSupported);
    1.86 +    return KErrNone;
    1.87 +    }
    1.88 +
    1.89 +/** Return the driver capabilities */
    1.90 +void DResConPddFactory::GetCaps(TDes8& aDes) const
    1.91 +    {
    1.92 +	// Create a capabilities object
    1.93 +	TCaps caps;
    1.94 +	caps.iVersion = iVersion;
    1.95 +	// Zero the buffer
    1.96 +	TInt maxLen = aDes.MaxLength();
    1.97 +	aDes.FillZ(maxLen);
    1.98 +	// Copy cpabilities
    1.99 +	TInt size=sizeof(caps);
   1.100 +	if(size>maxLen)
   1.101 +	   size=maxLen;
   1.102 +	aDes.Copy((TUint8*)&caps,size);
   1.103 +    }
   1.104 +
   1.105 +/** Entry point for a standard physical device driver (PDD) that is also an extension */
   1.106 +#ifndef RESOURCE_MANAGER_SIMULATED_PSL
   1.107 +DECLARE_EXTENSION_PDD()
   1.108 +    {
   1.109 +    return new DResConPddFactory;
   1.110 +    }
   1.111 +#endif
   1.112 +
   1.113 +/** Interface class implementation */
   1.114 +TInt TInterface::RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType)
   1.115 +    {
   1.116 +	GET_CRITICAL_SECTION_COUNT
   1.117 +	TInt r;
   1.118 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::RegisterClient"));
   1.119 +	r = PowerResourceController->RegisterClient(aClientId, aName, aType);
   1.120 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.121 +	return r;
   1.122 +    }
   1.123 + 
   1.124 +TInt TInterface::DeRegisterClient(TUint aClientId)
   1.125 +    {
   1.126 +	GET_CRITICAL_SECTION_COUNT
   1.127 +	TInt r;
   1.128 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::DeRegisterClient"));
   1.129 +	r = PowerResourceController->DeRegisterClient(aClientId);
   1.130 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.131 +	return r;
   1.132 +    }
   1.133 +
   1.134 +TInt TInterface::GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName)
   1.135 +    {
   1.136 +	GET_CRITICAL_SECTION_COUNT
   1.137 +	TInt r;
   1.138 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::GetClientName"));
   1.139 +	r = PowerResourceController->GetClientName(aClientId, aTargetClientId, aName);
   1.140 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.141 +	return r;
   1.142 +    }
   1.143 +
   1.144 +TInt TInterface::GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId)
   1.145 +    {
   1.146 +	GET_CRITICAL_SECTION_COUNT
   1.147 +	TInt r;
   1.148 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::GetClientId"));
   1.149 +	r = PowerResourceController->GetClientId(aClientId, aClientName, aTargetClientId);
   1.150 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.151 +	return r;
   1.152 +    }
   1.153 +
   1.154 +TInt TInterface::GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId)
   1.155 +    {
   1.156 +	GET_CRITICAL_SECTION_COUNT
   1.157 +	TInt r;
   1.158 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::GetResourceId"));
   1.159 +	r = PowerResourceController->GetResourceId(aClientId, aResourceName, aResourceId);
   1.160 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.161 +	return r;
   1.162 +    }
   1.163 +
   1.164 +TInt TInterface::GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo)
   1.165 +    {
   1.166 +	GET_CRITICAL_SECTION_COUNT
   1.167 +	TInt r;
   1.168 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::GetResourceInfo"));
   1.169 +	r = PowerResourceController->GetResourceInfo(aClientId, aResourceId, aInfo);
   1.170 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.171 +	return r;
   1.172 +    }
   1.173 +
   1.174 +TInt TInterface::GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResource)
   1.175 +    {
   1.176 +	GET_CRITICAL_SECTION_COUNT
   1.177 +	TInt r;
   1.178 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::GetNumResourcesInUseByClient"));
   1.179 +	r = PowerResourceController->GetNumResourcesInUseByClient(aClientId, aTargetClientId, aNumResource);
   1.180 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.181 +	return r;
   1.182 +    }
   1.183 +
   1.184 +TInt TInterface::GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources, TAny* aInfo)
   1.185 +    {
   1.186 +	GET_CRITICAL_SECTION_COUNT
   1.187 +	TInt r;
   1.188 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::GetInfoOnResourcesInUseByClient"));
   1.189 +	r = PowerResourceController->GetInfoOnResourcesInUseByClient(aClientId, aTargetClientId, aNumResources, aInfo);
   1.190 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.191 +	return r;
   1.192 +    }
   1.193 +
   1.194 +TInt TInterface::GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients)
   1.195 +    {
   1.196 +	GET_CRITICAL_SECTION_COUNT
   1.197 +	TInt r;
   1.198 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::GetNumClientsUsingResource"));
   1.199 +	r = PowerResourceController->GetNumClientsUsingResource(aClientId, aResourceId, aNumClients);
   1.200 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.201 +	return r;
   1.202 +    }
   1.203 +
   1.204 +TInt TInterface::GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients, TAny* aInfo)
   1.205 +    {
   1.206 +	GET_CRITICAL_SECTION_COUNT
   1.207 +	TInt r;
   1.208 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::GetInfoOnClientsUsingResource"));
   1.209 +	r = PowerResourceController->GetInfoOnClientsUsingResource(aClientId, aResourceId, aNumClients, aInfo);
   1.210 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.211 +	return r;
   1.212 +    }
   1.213 +
   1.214 +TInt TInterface::ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb)
   1.215 +    {
   1.216 +	GET_CRITICAL_SECTION_COUNT
   1.217 +	TInt r;
   1.218 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::ChangeResourceState"));
   1.219 +	r = PowerResourceController->ChangeResourceState(aClientId, aResourceId, aNewState, aCb);
   1.220 +	if(!aCb) //Not checking incase of asynchronous function as mutex might be held in RC thread, when this is checked.
   1.221 +		{
   1.222 +		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.223 +		}
   1.224 +	return r;
   1.225 +    }
   1.226 +
   1.227 +TInt TInterface::GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId)
   1.228 +    {
   1.229 +	GET_CRITICAL_SECTION_COUNT
   1.230 +	TInt r;
   1.231 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::GetResourceState"));
   1.232 +    r = PowerResourceController->GetResourceState(aClientId, aResourceId, aCached, aState, aLevelOwnerId);
   1.233 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.234 +	return r;
   1.235 +    }
   1.236 +
   1.237 +TInt TInterface::GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb)
   1.238 +    {
   1.239 +	TInt r;
   1.240 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::GetResourceState"));
   1.241 +    r = PowerResourceController->GetResourceState(aClientId, aResourceId, aCached, aCb);
   1.242 +	return r;
   1.243 +    }
   1.244 +
   1.245 +TInt TInterface::CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb)
   1.246 +    {
   1.247 +	GET_CRITICAL_SECTION_COUNT
   1.248 +	TInt r;
   1.249 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::CancelAsyncRequestCallback"));
   1.250 +    r = PowerResourceController->CancelAsyncRequestCallBack(aClientId, aResourceId, aCb);
   1.251 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.252 +	return r;
   1.253 +    }
   1.254 +
   1.255 +TInt TInterface::RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN)
   1.256 +    {
   1.257 +	GET_CRITICAL_SECTION_COUNT
   1.258 +	TInt r;
   1.259 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::RequestNotification"));
   1.260 +    r = PowerResourceController->RequestNotification(aClientId, aResourceId, aN);
   1.261 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.262 +	return r;
   1.263 +    }
   1.264 +
   1.265 +TInt TInterface::RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, TInt aThreshold, 
   1.266 +									                                                               TBool aDirection)
   1.267 +    {
   1.268 +	GET_CRITICAL_SECTION_COUNT
   1.269 +	TInt r;
   1.270 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::RequestNotification"));
   1.271 +    r = PowerResourceController->RequestNotification(aClientId, aResourceId, aN, aThreshold, aDirection);
   1.272 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.273 +	return r;
   1.274 +    }
   1.275 +
   1.276 +TInt TInterface::CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN)
   1.277 +    {
   1.278 +	GET_CRITICAL_SECTION_COUNT
   1.279 +	TInt r;
   1.280 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::CancelNotification"));
   1.281 +    r = PowerResourceController->CancelNotification(aClientId, aResourceId, aN);
   1.282 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.283 +	return r;
   1.284 +    }
   1.285 +
   1.286 +TInt TInterface::DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId)
   1.287 +	{
   1.288 +	GET_CRITICAL_SECTION_COUNT
   1.289 +	TInt r;
   1.290 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::DeRegisterClientLevelFromResource"));
   1.291 +    r = PowerResourceController->DeRegisterClientLevelFromResource(aClientId, aResourceId);
   1.292 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.293 +	return r;
   1.294 +    }
   1.295 +
   1.296 +TInt TInterface::AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm)
   1.297 +    {
   1.298 +	GET_CRITICAL_SECTION_COUNT
   1.299 +	TInt r;
   1.300 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::AllocReserve"));
   1.301 +    r = PowerResourceController->AllocReserve(aClientId, aNumCl, aNumRm);
   1.302 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
   1.303 +	return r;
   1.304 +    }
   1.305 +
   1.306 +/** This function is used by export functions of Resource contoller defined in seperate file */
   1.307 +DPowerResourceController* TInterface::GetPowerResourceController(void)
   1.308 +    {
   1.309 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::GetPowerResourceController"));
   1.310 +    return PowerResourceController;
   1.311 +    }
   1.312 +
   1.313 +TInt TInterface::ControlIO(TUint aClientId, TUint aFunction, TAny* aParam1, TAny* aParam2, TAny* aParam3)
   1.314 +    {
   1.315 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">TInterface::ControlIO"));
   1.316 +    return PowerResourceController->GetInterface(aClientId, aFunction, aParam1, aParam2, aParam3);
   1.317 +    }
   1.318 +
   1.319 +/** Resouce controller panic */
   1.320 +void DPowerResourceController::Panic(TUint8 aPanic)
   1.321 +	{
   1.322 +	Kern::Fault("Power Resource Controller", aPanic);
   1.323 +	}
   1.324 +
   1.325 +/** Constructor for power controller. Creates message queue and generates ID for power controller to use. */
   1.326 +DPowerResourceController::DPowerResourceController()
   1.327 +	{
   1.328 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf("DPowerResourceController::DPowerResouceController()"));
   1.329 +	//Constructor is expected to invoke multiple times (during creation, variant init 0 and extension init 1)
   1.330 +	if(PowerResourceController) 
   1.331 +		return;
   1.332 +    PowerResourceController = this;
   1.333 +	iClientList.Initialise(0);
   1.334 +	iUserSideClientList.Initialise(0);
   1.335 +	iInitialised = EResConCreated;
   1.336 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.337 +	iDynamicResourceList.Initialise(0);
   1.338 +	iDynamicResDependencyList.Initialise(0);
   1.339 +#endif
   1.340 +	}
   1.341 +
   1.342 +/** Destructor for power controller. Frees the memory allocated in kernel heap. */
   1.343 +DPowerResourceController::~DPowerResourceController()
   1.344 +	{
   1.345 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("DPowerResourceController::~DPowerResourceController()"));
   1.346 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
   1.347 +	iCleanList.ResetAndDestroy();
   1.348 +#endif
   1.349 +	iClientList.Delete();
   1.350 +	iUserSideClientList.Delete();
   1.351 +
   1.352 +
   1.353 +		
   1.354 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.355 +	iDynamicResourceList.Delete();
   1.356 +	iDynamicResDependencyList.Delete();
   1.357 +#endif
   1.358 +
   1.359 +	SPowerResourceClientLevel *pCL = iClientLevelPool;
   1.360 +	while(iClientLevelPool) //Find the starting position of array to delete
   1.361 +		{
   1.362 +		if(iClientLevelPool < pCL)
   1.363 +			pCL = iClientLevelPool;
   1.364 +		iClientLevelPool = iClientLevelPool->iNextInList;
   1.365 +		}
   1.366 +	//delete pCL;
   1.367 +	delete []pCL;
   1.368 +	SPowerRequest *pReq = iRequestPool;
   1.369 +	while(iRequestPool) //Find the starting position of array to delete
   1.370 +		{
   1.371 +		if(iRequestPool < pReq)
   1.372 +			pReq = iRequestPool;
   1.373 +		iRequestPool = iRequestPool->iNext;
   1.374 +		}
   1.375 +	//delete pR
   1.376 +	delete []pReq;
   1.377 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.378 +	pCL = iResourceLevelPool;
   1.379 +	while(iResourceLevelPool)
   1.380 +		{
   1.381 +		if(iResourceLevelPool < pCL)
   1.382 +			pCL = iResourceLevelPool;
   1.383 +		iResourceLevelPool = iResourceLevelPool->iNextInList;
   1.384 +		}
   1.385 +	//delete resource pool
   1.386 +	delete []pCL;
   1.387 +	//delete Message Queue dependency
   1.388 +	delete iMsgQDependency;
   1.389 +#endif
   1.390 +	//delete Message Queue
   1.391 +	delete iMsgQ;
   1.392 +	}
   1.393 +
   1.394 +/** Send notificatins to clients registered for it for the specified resource. */
   1.395 +void DPowerResourceController::CompleteNotifications(TInt aClientId, DStaticPowerResource* aResource, TInt aState, 
   1.396 +													      TInt aReturnCode, TInt aLevelOwnerId, TBool aLock)
   1.397 +	{
   1.398 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::CompleteNotifications"));
   1.399 +    if(aLock)
   1.400 +		Lock();
   1.401 +    DPowerResourceNotification*pN=NULL;
   1.402 +    for(SDblQueLink* pNL=aResource->iNotificationList.First();pNL!=&aResource->iNotificationList.iA; pNL=pNL->iNext)
   1.403 +		{
   1.404 +        pN = _LOFF(pNL, DPowerResourceNotification, iNotificationLink);
   1.405 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.406 +		//If dyanmic resource is deregistering, send notification to all clients requested for it
   1.407 +		if((pN->iCallback.iResourceId & KIdMaskDynamic) && (aClientId == KDynamicResourceDeRegistering))
   1.408 +			{
   1.409 +			pN->iCallback.iResult = aReturnCode;
   1.410 +			pN->iCallback.iLevel = aState;
   1.411 +			pN->iCallback.iClientId = aClientId;
   1.412 +			pN->iCallback.iLevelOwnerId = aLevelOwnerId;
   1.413 +			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Notification ClientId = 0x%x, ResourceId = %d, state = %d, Result = %d", 
   1.414 +									pN->iCallback.iClientId, pN->iCallback.iResourceId, aState, aReturnCode));
   1.415 +			PRM_POSTNOTIFICATION_SENT_TRACE
   1.416 +			pN->iCallback.Enque();
   1.417 +			continue;
   1.418 +			}	
   1.419 +#endif
   1.420 +		if((pN->iType==DPowerResourceNotification::EUnconditional) || 
   1.421 +				(pN->iDirection && ((pN->iPreviousLevel < pN->iThreshold) && (aState >= pN->iThreshold))) ||
   1.422 +				(!pN->iDirection && ((pN->iPreviousLevel > pN->iThreshold) && (aState <= pN->iThreshold))))
   1.423 +			{
   1.424 +            pN->iCallback.iResult=aReturnCode;
   1.425 +            pN->iCallback.iLevel=aState;
   1.426 +            pN->iCallback.iClientId = aClientId;
   1.427 +			pN->iCallback.iLevelOwnerId = aLevelOwnerId;
   1.428 +			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Notifications ClientId = 0x%x, ResourceId = %d, State = %d, Result = %d",
   1.429 +										pN->iCallback.iClientId, pN->iCallback.iResourceId, aState, aReturnCode));
   1.430 +			PRM_POSTNOTIFICATION_SENT_TRACE
   1.431 +            pN->iCallback.Enque();
   1.432 +			}
   1.433 +		pN->iPreviousLevel = aState; //Update the state
   1.434 +		}
   1.435 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::CompleteNotifications"));
   1.436 +	if(aLock)
   1.437 +		UnLock();
   1.438 +	return;
   1.439 +	}
   1.440 +
   1.441 +/** Complete the asynchronous request. */
   1.442 +void DPowerResourceController::CompleteRequest(TPowerRequest& aRequest)
   1.443 +	{
   1.444 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::CompleteRequest"));
   1.445 + 	// Complete notification for state change operation
   1.446 +    DStaticPowerResource* pR=aRequest.Resource();
   1.447 +	//If request in EChange or ESetDefaultValue and no error and if shared resources and if change is done then 
   1.448 +	//issue notification.
   1.449 +	if(((aRequest.ReqType() == TPowerRequest::EChange) || (aRequest.ReqType() == TPowerRequest::ESetDefaultLevel)) 
   1.450 +		         && (aRequest.ReturnCode() == KErrNone) && ((!pR->Usage()) || (pR->Usage() && aRequest.RequiresChange())))
   1.451 +		{	
   1.452 +    	CompleteNotifications(aRequest.ClientId(), aRequest.Resource(), aRequest.Level(), 
   1.453 +		                                                     aRequest.ReturnCode(), aRequest.ClientId());
   1.454 +		}
   1.455 +	//Do not update the level if the resource is shared and change is not required or any error.
   1.456 +    if(aRequest.ReturnCode()==KErrNone && ((aRequest.ReqType() ==TPowerRequest::EGet) || 
   1.457 +		       (((aRequest.ReqType()==TPowerRequest::EChange) || (aRequest.ReqType()==TPowerRequest::ESetDefaultLevel)) 
   1.458 +			   && ((!pR->Usage()) || (pR->Usage() && aRequest.RequiresChange())))))
   1.459 +        {
   1.460 +        Lock();
   1.461 +		// Cache the latest value
   1.462 +        pR->iCachedLevel=aRequest.Level();
   1.463 +		//Need to update client ID only during state change.
   1.464 +		if(aRequest.ReqType() != TPowerRequest::EGet)
   1.465 +			pR->iLevelOwnerId=aRequest.ClientId();
   1.466 +		// Cache Idle list entry for this reosurce if requested.
   1.467 +        if(pR->iIdleListEntry)
   1.468 +            {
   1.469 +            SIdleResourceInfo* pI=pR->iIdleListEntry;
   1.470 +            if(aRequest.ReqType() != TPowerRequest::EGet)
   1.471 +				pI->iLevelOwnerId= aRequest.ClientId();
   1.472 +            pI->iCurrentLevel=aRequest.Level();
   1.473 +            }
   1.474 +         UnLock();
   1.475 +        }
   1.476 +	
   1.477 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::CompleteRequest"));
   1.478 +	}
   1.479 +
   1.480 +/** Handle/process the asynchronous request sent to resource controller.
   1.481 +   The request can be one of the following
   1.482 +   1) State change of long latency reosurce
   1.483 +   2) Get the state of long latency resource
   1.484 +   3) Set the default value of long latency resource */
   1.485 +void DPowerResourceController::HandleMsg(TPowerRequest& aRequest)
   1.486 +	{
   1.487 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::HandleMsg"));
   1.488 +    DStaticPowerResource* pR=aRequest.Resource();
   1.489 +	//Get client using client ID
   1.490 +	TUint aClientId = aRequest.ClientId();
   1.491 +	SPowerResourceClient* pC = NULL;
   1.492 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.493 +	if((TInt)aClientId != KDynamicResourceDeRegistering)
   1.494 +		{
   1.495 +		if(aClientId & USER_SIDE_CLIENT_BIT_MASK)
   1.496 +			pC = iUserSideClientList[TUint16(aClientId & ID_INDEX_BIT_MASK)];
   1.497 +		else
   1.498 +			pC = iClientList[TUint16(aClientId & ID_INDEX_BIT_MASK)];
   1.499 +		}
   1.500 +#else
   1.501 +		if(aClientId & USER_SIDE_CLIENT_BIT_MASK)
   1.502 +			pC = iUserSideClientList[TUint16(aClientId & ID_INDEX_BIT_MASK)];
   1.503 +		else
   1.504 +			pC = iClientList[TUint16(aClientId & ID_INDEX_BIT_MASK)];
   1.505 +#endif		
   1.506 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("Request Type = %d, ClientId = 0x%x, ResourceId = %d",
   1.507 +		                             aRequest.ReqType(), aRequest.ClientId(), aRequest.ResourceId()));
   1.508 +    if(aRequest.ReqType()==TPowerRequest::EChange)
   1.509 +		{
   1.510 +        if(pR->Usage()) //Handling shared resource
   1.511 +			{
   1.512 +			Lock(); //To avoid race condition between deregister resource level.
   1.513 +			aRequest.ReturnCode() = CheckLevelAndAddClient(pC, &aRequest);
   1.514 +			UnLock();
   1.515 +			if((aRequest.ReturnCode()!= KErrNone) || (!aRequest.RequiresChange()))
   1.516 +				{
   1.517 +				aRequest.Level() = pR->iCachedLevel; //If no change then send the current level back.
   1.518 +    			CompleteRequest(aRequest);
   1.519 +				return;
   1.520 +				}
   1.521 +			}
   1.522 +		else if(pR->iLevelOwnerId ==-1)  //No existing client.
   1.523 +			{
   1.524 +			// Add client Level
   1.525 +			if(pC->iReservedCl==0 && !iClientLevelPoolCount)
   1.526 +				{
   1.527 +				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Reserved Client Level exhausted and its free pool empty"));
   1.528 +                aRequest.ReturnCode() = KErrUnderflow;
   1.529 +                CompleteRequest(aRequest);
   1.530 +				return;
   1.531 +				}
   1.532 +			SPowerResourceClientLevel* pSCL=NULL;
   1.533 +			LIST_POP(iClientLevelPool, pSCL, iNextInList);
   1.534 +			pSCL->iClientId=aClientId;
   1.535 +			pSCL->iResourceId=aRequest.ResourceId();
   1.536 +			pSCL->iLevel=aRequest.Level();
   1.537 +			LIST_PUSH(pC->iLevelList, pSCL, iNextInList); //Add to client
   1.538 +			pR->iClientList.Add(pSCL); //Add in resource
   1.539 +			if(pC->iReservedCl==0)
   1.540 +				{
   1.541 +				iClientLevelPoolCount--;
   1.542 +				pC->iUnderFlowClCount++;
   1.543 +				}
   1.544 +            else
   1.545 +			   pC->iReservedCl--;
   1.546 +			}
   1.547 +		else
   1.548 +			{
   1.549 +			//Update the level in the client list.
   1.550 +			SPowerResourceClientLevel* pSCL = (SPowerResourceClientLevel*)pR->iClientList.First();
   1.551 +			pSCL->iLevel = aRequest.Level();
   1.552 +			}
   1.553 +		}
   1.554 +	else if(aRequest.ReqType()==TPowerRequest::ESetDefaultLevel)	
   1.555 +		{
   1.556 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.557 +		if((aRequest.ResourceId() & KIdMaskDynamic) && ((TInt)aClientId == KDynamicResourceDeRegistering))
   1.558 +			{
   1.559 +			//Try to change the resource to requested level and if that fails try to change it to default level
   1.560 +			if(pR->iDefaultLevel != aRequest.Level())
   1.561 +				{
   1.562 +				aRequest.ReqType() = TPowerRequest::EChange;
   1.563 +				aRequest.ReturnCode() = pR->DoRequest(aRequest);
   1.564 +				if(aRequest.ReturnCode() != KErrNone)
   1.565 +					{
   1.566 +					aRequest.ReqType() = TPowerRequest::ESetDefaultLevel;
   1.567 +					aRequest.Level() = pR->iDefaultLevel;
   1.568 +					pR->DoRequest(aRequest);
   1.569 +					}
   1.570 +				}
   1.571 +			else
   1.572 +				pR->DoRequest(aRequest);
   1.573 +			aRequest.ReturnCode() = KErrNone;
   1.574 +			aRequest.RequiresChange() = ETrue;
   1.575 +			CompleteRequest(aRequest);
   1.576 +			return;
   1.577 +			}
   1.578 +#endif
   1.579 +        if(pR->Usage())
   1.580 +			{
   1.581 +			aRequest.ReturnCode() = CheckLevelAndAddClient(pC, &aRequest);
   1.582 +			if((aRequest.ReturnCode()!= KErrNone) || (!aRequest.RequiresChange()))
   1.583 +				{
   1.584 +				aRequest.Level() = pR->iCachedLevel; //If no change then send the current level back.
   1.585 +    			CompleteRequest(aRequest);
   1.586 +				return;
   1.587 +				}
   1.588 +			}
   1.589 +		else
   1.590 +			{
   1.591 +			aRequest.ClientId() = -1;
   1.592 +			aRequest.Level() = pR->iDefaultLevel;
   1.593 +			}
   1.594 +		}
   1.595 +	if((aRequest.ReqType() == TPowerRequest::EGet) || (pR->iCachedLevel != aRequest.Level()))
   1.596 +		aRequest.ReturnCode() = pR->DoRequest(aRequest);
   1.597 +	CompleteRequest(aRequest);
   1.598 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::HandleMsg"));
   1.599 +	}
   1.600 +
   1.601 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.602 +/** Handle/process the dependency resource.
   1.603 +   The request can be one of the following
   1.604 +   1) State change of a dependency resource
   1.605 +   2) Get the state of a dependency resource
   1.606 +   3) Set the default value of a dependency resource */
   1.607 +void DPowerResourceController::HandleDependencyMsg(TPowerRequest& aRequest)
   1.608 +	{
   1.609 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::HandleDependencyMsg"));
   1.610 +    DStaticPowerResource* pR=aRequest.Resource();
   1.611 +	//Get client using client ID
   1.612 +	TUint aClientId = aRequest.ClientId();
   1.613 +	SPowerResourceClient* pC = NULL;
   1.614 +
   1.615 +	if((TInt)aClientId != KDynamicResourceDeRegistering)
   1.616 +		{
   1.617 +		if(aClientId & USER_SIDE_CLIENT_BIT_MASK)
   1.618 +			pC = iUserSideClientList[TUint16(aClientId & ID_INDEX_BIT_MASK)];
   1.619 +		else
   1.620 +			pC = iClientList[TUint16(aClientId & ID_INDEX_BIT_MASK)];
   1.621 +		}
   1.622 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("Request Type = %d, ClientId = 0x%x, ResourceId = %d",  
   1.623 +		                             aRequest.ReqType(), aRequest.ClientId(), aRequest.ResourceId()));
   1.624 +	if((aRequest.ResourceId() & KIdMaskResourceWithDependencies) && (aRequest.ReqType() != TPowerRequest::EGet))
   1.625 +		{
   1.626 +		Lock();
   1.627 +		iDfcQDependencyLock = ETrue;
   1.628 +		UnLock();
   1.629 +		PowerResourceController->HandleDependencyResourceStateChange(pC, aRequest);
   1.630 +		Lock();
   1.631 +		iDfcQDependencyLock = EFalse;
   1.632 +		UnLock();		
   1.633 +		return;
   1.634 +		}
   1.635 +	//Get the resource current level.
   1.636 +	aRequest.ReturnCode() = pR->DoRequest(aRequest);
   1.637 +	CompleteRequest(aRequest);
   1.638 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::HandleDependencyMsg"));
   1.639 +	}
   1.640 +#endif
   1.641 +
   1.642 +/** Function called whenever there is a message in resource controller message queue. */
   1.643 +void DPowerResourceController::MsgQFunc(TAny* aPtr)
   1.644 +	{
   1.645 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::MsgQFunc"));
   1.646 +    DPowerResourceController* pRC=(DPowerResourceController*)aPtr;
   1.647 +    TPowerRequest* aReq=(TPowerRequest*)pRC->iMsgQ->iMessage;
   1.648 +	DStaticPowerResource *pR = aReq->Resource();
   1.649 +	if(aReq->ReqType() == TPowerRequest::EAllocReserve)
   1.650 +		{
   1.651 +		aReq->ReturnCode() = pRC->HandleReservationOfObjects(*aReq);
   1.652 +		aReq->Complete(aReq->ReturnCode(),ETrue);
   1.653 +		return;
   1.654 +		}
   1.655 +	if((aReq->ReqType() == TPowerRequest::ERegisterKernelClient) || (aReq->ReqType() == TPowerRequest::ERegisterUsersideClient))
   1.656 +		{
   1.657 +		aReq->ReturnCode() = pRC->HandleClientRegistration(*aReq);
   1.658 +		aReq->Complete(aReq->ReturnCode(), ETrue);
   1.659 +		return;
   1.660 +		}
   1.661 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.662 +	if(aReq->ReqType() == TPowerRequest::ERegisterDynamicResource)
   1.663 +		{
   1.664 +		aReq->ReturnCode() = pRC->HandleResourceRegistration(*aReq);
   1.665 +		aReq->Complete(aReq->ReturnCode(), ETrue);
   1.666 +		return;
   1.667 +		}
   1.668 +#endif
   1.669 +    pRC->HandleMsg(*aReq);
   1.670 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.671 +	if((aReq->ResourceId() & KIdMaskDynamic) && (aReq->ResourceCb()))
   1.672 +		{
   1.673 +		pRC->Lock();
   1.674 +		((DDynamicPowerResource*)aReq->Resource())->UnLock();
   1.675 +		pRC->UnLock();
   1.676 +		}
   1.677 +#endif
   1.678 +	//Below code is for Btrace
   1.679 +#ifdef PRM_INSTRUMENTATION_MACRO
   1.680 +	SPowerResourceClient* pC = NULL;
   1.681 +	SPowerResourceClient tRes;
   1.682 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.683 + if((aReq->ClientId() == -1) || (aReq->ClientId() == KDynamicResourceDeRegistering))
   1.684 +#else
   1.685 +	if(aReq->ClientId() == -1)
   1.686 +#endif
   1.687 +		{
   1.688 +        pC = &tRes;
   1.689 +        pC->iClientId = (TUint)-1;
   1.690 +        pC->iName = &KNoClient;
   1.691 +		}
   1.692 +    else if(aReq->ClientId() & USER_SIDE_CLIENT_BIT_MASK)
   1.693 +		pC = pRC->iUserSideClientList[TUint16(aReq->ClientId() & ID_INDEX_BIT_MASK)];
   1.694 +	else
   1.695 +		pC = pRC->iClientList[TUint16(aReq->ClientId() & ID_INDEX_BIT_MASK)];
   1.696 +
   1.697 +    TUint aResourceId = aReq->ResourceId();
   1.698 +    TInt r = aReq->ReturnCode();
   1.699 +    if(aReq->ReqType()==TPowerRequest::EGet)
   1.700 +		{
   1.701 +		TInt aState = aReq->Level();
   1.702 +		PRM_RESOURCE_GET_STATE_END_TRACE
   1.703 +		}
   1.704 +    else
   1.705 +		{
   1.706 +		TInt aNewState = aReq->Level();
   1.707 +		PRM_CLIENT_CHANGE_STATE_END_TRACE
   1.708 +		}
   1.709 +#endif
   1.710 +	//Check whether callback is cancelled and if not queue the DFC.
   1.711 +    TPowerResourceCb* pCb = aReq->ResourceCb();
   1.712 +    if(pCb)
   1.713 +		{
   1.714 +        pCb->iResult=aReq->ReturnCode();
   1.715 +        pCb->iLevel=aReq->Level();
   1.716 +        pCb->iResourceId=aReq->ResourceId();
   1.717 +        pCb->iClientId=aReq->ClientId();
   1.718 +		pCb->iLevelOwnerId = pR->iLevelOwnerId;
   1.719 +	    pCb->Enque();
   1.720 +		}
   1.721 +    aReq->Complete(aReq->ReturnCode(),ETrue);
   1.722 +	if(aReq->ResourceCb())
   1.723 +		pRC->MoveRequestToFreePool(aReq);
   1.724 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::MsgQFunc"));
   1.725 +	return;
   1.726 +    }
   1.727 +
   1.728 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.729 +/** Function called whenever there is a message in resource controller Dependency message queue. */
   1.730 +void DPowerResourceController::MsgQDependencyFunc(TAny* aPtr)
   1.731 +	{
   1.732 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::MsgQDependencyFunc"));
   1.733 +    DPowerResourceController* pRC=(DPowerResourceController*)aPtr;
   1.734 +    TPowerRequest* aReq=(TPowerRequest*)pRC->iMsgQDependency->iMessage;
   1.735 +	DStaticPowerResource *pR = aReq->Resource();
   1.736 +	pRC->HandleDependencyMsg(*aReq);
   1.737 +	if((aReq->ResourceId() & KIdMaskDynamic) && (aReq->ResourceCb()))
   1.738 +		{
   1.739 +		pRC->Lock();
   1.740 +		((DDynamicPowerResource*)aReq->Resource())->UnLock();
   1.741 +		pRC->UnLock();
   1.742 +		}
   1.743 +	//Below code is for Btrace
   1.744 +#ifdef PRM_INSTRUMENTATION_MACRO
   1.745 +	SPowerResourceClient* pC = NULL;
   1.746 +	SPowerResourceClient tRes;
   1.747 +	if((aReq->ClientId() != -1) && (aReq->ClientId() != KDynamicResourceDeRegistering) && 
   1.748 +		                                        (aReq->ClientId() & KIdMaskResourceWithDependencies))
   1.749 +		{
   1.750 +		pC = &tRes;
   1.751 +		pC->iClientId = aReq->ClientId();
   1.752 +		DDynamicPowerResourceD* pDRes;
   1.753 +		if(aReq->ClientId() & KIdMaskDynamic)
   1.754 +			pDRes = pRC->iDynamicResDependencyList[(TUint16)(aReq->ClientId() & ID_INDEX_BIT_MASK)];	
   1.755 +		else
   1.756 +			pDRes = (DDynamicPowerResourceD*)pRC->iStaticResDependencyArray[(aReq->ClientId() & ID_INDEX_BIT_MASK) - 1];
   1.757 +		pC->iName = pDRes->iName;
   1.758 +		}
   1.759 +	else if((aReq->ClientId() == -1) || (aReq->ClientId() == KDynamicResourceDeRegistering))
   1.760 +		{
   1.761 +        pC = &tRes;
   1.762 +        pC->iClientId = (TUint)-1;
   1.763 +        pC->iName = &KNoClient;
   1.764 +		}
   1.765 +    else if(aReq->ClientId() & USER_SIDE_CLIENT_BIT_MASK)
   1.766 +		pC = pRC->iUserSideClientList[TUint16(aReq->ClientId() & ID_INDEX_BIT_MASK)];
   1.767 +	else
   1.768 +		pC = pRC->iClientList[TUint16(aReq->ClientId() & ID_INDEX_BIT_MASK)];
   1.769 +
   1.770 +    TUint aResourceId = aReq->ResourceId();
   1.771 +    TInt r = aReq->ReturnCode();
   1.772 +    if(aReq->ReqType()==TPowerRequest::EGet)
   1.773 +		{
   1.774 +		TInt aState = aReq->Level();
   1.775 +		PRM_RESOURCE_GET_STATE_END_TRACE
   1.776 +		}
   1.777 +    else
   1.778 +		{
   1.779 +		TInt aNewState = aReq->Level();
   1.780 +		PRM_CLIENT_CHANGE_STATE_END_TRACE
   1.781 +		}
   1.782 +#endif
   1.783 +	//Check whether callback is cancelled and if not queue the DFC.
   1.784 +    TPowerResourceCb* pCb = aReq->ResourceCb();
   1.785 +    if(pCb)
   1.786 +		{
   1.787 +        pCb->iResult=aReq->ReturnCode();
   1.788 +        pCb->iLevel=aReq->Level();
   1.789 +        pCb->iResourceId=aReq->ResourceId();
   1.790 +        pCb->iClientId=aReq->ClientId();
   1.791 +		pCb->iLevelOwnerId = pR->iLevelOwnerId;
   1.792 +	    pCb->Enque();
   1.793 +		}
   1.794 +    aReq->Complete(aReq->ReturnCode(),ETrue);
   1.795 +	if(aReq->ResourceCb())
   1.796 +		pRC->MoveRequestToFreePool(aReq);
   1.797 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::MsgQDependencyFunc"));
   1.798 +	return;
   1.799 +    }
   1.800 +#endif
   1.801 +/** Function to move the request object to free pool and update client request count accordingly. */
   1.802 +void DPowerResourceController::MoveRequestToFreePool(TPowerRequest *aReq)
   1.803 +	{
   1.804 +    //Return request to free pool
   1.805 +    SPowerRequest* pS=_LOFF(aReq, SPowerRequest, iRequest);
   1.806 +    Lock();
   1.807 +    LIST_PUSH(iRequestPool, pS, iNext);
   1.808 +	SPowerResourceClient* pC = NULL;
   1.809 +	if(aReq->ClientId() & USER_SIDE_CLIENT_BIT_MASK)
   1.810 +		pC = iUserSideClientList[TUint16(aReq->ClientId() & ID_INDEX_BIT_MASK)];
   1.811 +	else
   1.812 +		pC = iClientList[TUint16(aReq->ClientId() & ID_INDEX_BIT_MASK)];
   1.813 +	pC->iPendingReqCount--;
   1.814 +	if(pC->iUnderFlowRmCount > 0)
   1.815 +		{
   1.816 +        iRequestPoolCount++;
   1.817 +        pC->iUnderFlowRmCount--;
   1.818 +		}
   1.819 +    else
   1.820 +        pC->iReservedRm++;
   1.821 +    UnLock();
   1.822 +    return;
   1.823 +	}
   1.824 +
   1.825 +/** This function is called by PSL to set the DFC queue created */
   1.826 +void DPowerResourceController::SetDfcQ(TDfcQue* aDfcQ)
   1.827 +	{
   1.828 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::SetDfcQ"));
   1.829 +    iDfcQ=aDfcQ;
   1.830 +    iMsgQ->SetDfcQ(iDfcQ);
   1.831 +	}
   1.832 +
   1.833 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.834 +/** This function is called by PSL to set the DFC Dependency queue created */
   1.835 +void DPowerResourceController::SetDfcQDependency(TDfcQue* aDfcQDependency)
   1.836 +	{
   1.837 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::SetDfcQDependency"));
   1.838 +    iDfcQDependency=aDfcQDependency;
   1.839 +    iMsgQDependency->SetDfcQ(iDfcQDependency);
   1.840 +	}
   1.841 +#endif
   1.842 +/**This is called as a result of DFC queued in supervisor thread to complete the initialisation
   1.843 +   of resource controller.It registers the resource controller with the power controller. It also
   1.844 +   calls PSL (DoInitResources()) to initialise all static resources to their post-reboot state.
   1.845 +   Finally mark resource controller as fully initialised (ready to accept state change and get request)
   1.846 +   and start the message queue if exists. */
   1.847 +TInt DPowerResourceController::InitResources()
   1.848 +	{
   1.849 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::InitResources()"));
   1.850 +	TUint16 count;
   1.851 +	//Create a Kernel client object for Power Controller
   1.852 +	Lock();
   1.853 +	SPowerResourceClient * pC = NULL;
   1.854 +	// By now client pool should be created
   1.855 +	LIST_POP(iClientPool, pC, iNextInList);
   1.856 +	TUint16 growBy = iClientList.GrowBy();
   1.857 +	if(!pC)
   1.858 +		{
   1.859 +		UnLock();
   1.860 +		// coverity[alloc_fn]
   1.861 +		SPowerResourceClient *pCL = new SPowerResourceClient[growBy];
   1.862 +		if(!pCL)
   1.863 +			{
   1.864 +			__KTRACE_OPT(KRESMANAGER, Kern::Printf("No memory to grow client pool"));
   1.865 +			Panic(ENoMemToCreatePowerControllerClient);
   1.866 +			}
   1.867 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
   1.868 +		iCleanList.Append(pCL);
   1.869 +#endif
   1.870 +		Lock();
   1.871 +        for(count = 0; count < growBy-1; count++)
   1.872 +			LIST_PUSH(iClientPool, &pCL[count], iNextInList);
   1.873 +		pC = &pCL[count];
   1.874 +#ifdef PRM_INSTRUMENTATION_MACRO
   1.875 +	TUint size = growBy *sizeof(SPowerResourceClient);
   1.876 +	PRM_MEMORY_USAGE_TRACE
   1.877 +#endif
   1.878 +		}
   1.879 +	pC->iName = (const TDesC8*)&KPowerController;
   1.880 +	UnLock();
   1.881 +	if(iClientList.Allocd()==iClientList.Count())
   1.882 +		{
   1.883 +		if(iClientList.ReSize(growBy))
   1.884 +			{
   1.885 +			Panic(ENoMemToCreatePowerControllerClient);
   1.886 +			}
   1.887 +		}
   1.888 +	Lock();
   1.889 +	iClientList.Add(pC, iPowerControllerId);
   1.890 +	pC->iClientId = iPowerControllerId | CLIENT_POWER_CONTROLLER_BIT_MASK;
   1.891 +	iPowerControllerId = pC->iClientId;
   1.892 +    iClientCount++;
   1.893 +    if(TPowerController::PowerController())
   1.894 +       TPowerController::PowerController()->RegisterResourceController(this, iPowerControllerId);
   1.895 +	iInitialised =EResConStartupCompleted;
   1.896 +	UnLock();
   1.897 +	//Check the resource for postboot level and send notifications to clients registered for it.
   1.898 +	DStaticPowerResource *pR = NULL;
   1.899 +	TInt r;
   1.900 +	TPowerRequest req = TPowerRequest::Get();
   1.901 +	//For Static resource with no dependencies
   1.902 +    for(count = 0; count< iStaticResourceArrayEntries; count++)
   1.903 +		{
   1.904 +		pR = iStaticResourceArray[count];
   1.905 +		if(pR && (pR->iFlags & SET_VALID_POST_BOOT_LEVEL))
   1.906 +			{
   1.907 +            //Form the request message
   1.908 +			req.ReqType() = TPowerRequest::EChange;
   1.909 +			req.ResourceId() = count+1;
   1.910 +			req.ClientId() = -1;
   1.911 +			req.Level() = pR->iPostBootLevel;
   1.912 +			req.Resource() = pR;
   1.913 +			req.ResourceCb() = NULL;
   1.914 +			req.RequiresChange() = ETrue;
   1.915 +			r = pR->DoRequest(req);
   1.916 +			if(r == KErrNone)
   1.917 +				{
   1.918 +				CompleteNotifications(-1, pR, req.Level(), r, -1, ETrue);
   1.919 +				pR->iCachedLevel = req.Level(); //Update the cached level.
   1.920 +				}
   1.921 +			}
   1.922 +		}
   1.923 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.924 +	//For Static resource with dependencies 
   1.925 +	for(count = 0; count < iStaticResDependencyCount; count++)
   1.926 +		{
   1.927 +		pR = iStaticResDependencyArray[count];
   1.928 +		if(pR->iFlags & SET_VALID_POST_BOOT_LEVEL)
   1.929 +			{
   1.930 +			req.ReqType() = TPowerRequest::EChange;
   1.931 +			req.ResourceId() = ((DStaticPowerResourceD*)pR)->iResourceId;
   1.932 +			req.ClientId() = -1;
   1.933 +			req.Level() = pR->iPostBootLevel;
   1.934 +			req.Resource() = pR;
   1.935 +			req.ResourceCb() = NULL;
   1.936 +			req.RequiresChange() = ETrue;
   1.937 +			//Form the request message
   1.938 +			((DStaticPowerResourceD*)pR)->HandleChangePropagation(req, EChangeStart, req.ClientId(), KNoClient);
   1.939 +			}
   1.940 +		}
   1.941 +#endif
   1.942 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::InitResources()"));
   1.943 +    return KErrNone;
   1.944 +	}
   1.945 +
   1.946 +/** @internalComponent
   1.947 +   This function is called for shared resources to determine level for the shared resource.
   1.948 +   This takes care of updating the resource level for each client. 
   1.949 +*/
   1.950 +TInt DPowerResourceController::CheckLevelAndAddClient(SPowerResourceClient* pC, TPowerRequest* aReq)
   1.951 +	{
   1.952 +    //Client level addition in state change needs to be taken care.
   1.953 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf("DPowerResourceController::CheckLevelAndAddClient, ClientId = 0x%x, ResourceId = %d, ReqType = %d",
   1.954 +													pC->iClientId, aReq->ResourceId(), aReq->ReqType()));
   1.955 +	
   1.956 +	SPowerResourceClientLevel* pSCL=NULL; //Place to hold the current client
   1.957 +	SPowerResourceClientLevel* pMCL=NULL; //Place to hold the prevailing client.
   1.958 +	DStaticPowerResource* aResource = aReq->Resource();
   1.959 +    aReq->RequiresChange() = EFalse;
   1.960 +    TInt maxLevel=KMinTInt;
   1.961 +   	TInt CurrentLevel;
   1.962 +	TInt count = 0;
   1.963 +	//Get the nextmaximum, current client information.If the change is requested by client holding the prevailing
   1.964 +	//level of the resource then maxlevel will be next highest level with respect to sense. Otherwise will contain
   1.965 +	//the maximum level.
   1.966 +	SPowerResourceClientLevel* pL = NULL;
   1.967 +    for(SDblQueLink* pCL=aResource->iClientList.First();pCL!=&aResource->iClientList.iA;pCL=pCL->iNext,count++)
   1.968 +		{
   1.969 +        pL=(SPowerResourceClientLevel*)pCL;
   1.970 +		if(pL->iClientId == pC->iClientId)
   1.971 +			{
   1.972 +			pSCL=pL;
   1.973 +			if(aResource->Sense() == DStaticPowerResource::ECustom)
   1.974 +				break;
   1.975 +			continue;
   1.976 +			}
   1.977 +		
   1.978 +		if((count == 0) || ((pSCL != NULL) && (maxLevel == KMinTInt)))
   1.979 +			{
   1.980 +			maxLevel = pL->iLevel;
   1.981 +			pMCL = pL;
   1.982 +			continue;
   1.983 +			}
   1.984 +		if(((aResource->Sense() == DStaticPowerResource::ENegative) && (pL->iLevel < maxLevel)) || 
   1.985 +			                      ((aResource->Sense() == DStaticPowerResource::EPositive) && (pL->iLevel > maxLevel)))
   1.986 +			{
   1.987 +			maxLevel=pL->iLevel;
   1.988 +			pMCL = pL;
   1.989 +		    }
   1.990 +		}
   1.991 +	//Get the current level.
   1.992 +	if(((TInt)pC->iClientId == aResource->iLevelOwnerId))
   1.993 +		// coverity[var_deref_op]
   1.994 +		CurrentLevel = pSCL->iLevel;
   1.995 +    else
   1.996 +		CurrentLevel = maxLevel;
   1.997 +
   1.998 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.999 +	if(aResource->iLevelOwnerId & KIdMaskResourceWithDependencies)
  1.1000 +		{
  1.1001 +		CurrentLevel = aResource->iCachedLevel;
  1.1002 +		}
  1.1003 +#endif
  1.1004 +	TBool newClient = EFalse;
  1.1005 +    if(!pSCL)
  1.1006 +		{
  1.1007 +		// If the client is new, get free client level from pool and populate with client information
  1.1008 +		// and add it to the client list and in resource list.
  1.1009 +        if((pC->iReservedCl ==0) && !iClientLevelPoolCount)
  1.1010 +			{
  1.1011 +			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client level quota exhausted and its free pool empty, iReservedCl = %d, iClientLevelPoolCount = %d", 
  1.1012 +													pC->iReservedCl, iClientLevelPoolCount));
  1.1013 +			return KErrUnderflow;
  1.1014 +			}
  1.1015 +        LIST_POP(iClientLevelPool, pSCL, iNextInList);
  1.1016 +        pSCL->iClientId=pC->iClientId;
  1.1017 +        pSCL->iResourceId=aReq->ResourceId();
  1.1018 +        pSCL->iLevel = aReq->Level();
  1.1019 +        //Add to the resource list
  1.1020 +        aResource->iClientList.Add(pSCL);
  1.1021 +        //Add to the client List
  1.1022 +        LIST_PUSH(pC->iLevelList, pSCL, iNextInList);
  1.1023 +        if(pC->iReservedCl == 0)
  1.1024 +			{
  1.1025 +			iClientLevelPoolCount--;
  1.1026 +			pC->iUnderFlowClCount++;
  1.1027 +			}
  1.1028 +        else
  1.1029 +          pC->iReservedCl--;
  1.1030 +		//If no client is holding the resource already and is not custom sense resource, then change is allowed
  1.1031 +        if((aResource->iLevelOwnerId == -1) && (aResource->Sense() != DStaticPowerResource::ECustom))
  1.1032 +			{
  1.1033 +			aReq->RequiresChange() = ETrue;
  1.1034 +			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DPowerResourceController::CheckLevelAndAddClient"));
  1.1035 +			return KErrNone;
  1.1036 +			}
  1.1037 +		if(aResource->Sense() == DStaticPowerResource::ECustom)
  1.1038 +			newClient = ETrue;
  1.1039 +		}
  1.1040 +    else
  1.1041 +		// Capture the new level requested by the client.
  1.1042 +        pSCL->iLevel=aReq->Level();
  1.1043 +
  1.1044 +    if(aResource->Sense() == DStaticPowerResource::ECustom)
  1.1045 +		{
  1.1046 +		
  1.1047 +        if(!aResource->iCustomFunction)
  1.1048 +            Panic(ECustomFunctionNotSet);
  1.1049 +		// coverity[var_deref_op]
  1.1050 +		if(aReq->ReqType() == TPowerRequest::EChange)
  1.1051 +		    {
  1.1052 +            aReq->RequiresChange() = aResource->iCustomFunction(aReq->ClientId(), *(pC->iName), aReq->ResourceId(),
  1.1053 +                                                                newClient ? EClientRequestLevel : EClientChangeLevel,
  1.1054 +                                                                aReq->Level(), (TAny*)&aResource->iClientList, NULL);
  1.1055 +		    }
  1.1056 +		else
  1.1057 +		    {
  1.1058 +            aReq->RequiresChange() = aResource->iCustomFunction(aReq->ClientId(), *(pC->iName), aReq->ResourceId(),
  1.1059 +                                                                EClientRelinquishLevel,
  1.1060 +                                                                aReq->Level(), (TAny*)&aResource->iClientList, NULL);
  1.1061 +		    }
  1.1062 +		if((aReq->ClientId() != -1) && (aReq->ClientId() != (TInt)pC->iClientId) )
  1.1063 +			{
  1.1064 +			//Check whether the updated client Id (by custom function) is in the client level list. 
  1.1065 +			for(SDblQueLink* pCL=aResource->iClientList.First();pCL!=&aResource->iClientList.iA;pCL=pCL->iNext)
  1.1066 +				{
  1.1067 +				pL = (SPowerResourceClientLevel*)pCL;
  1.1068 +				if((TInt)pL->iClientId == aReq->ClientId())
  1.1069 +					break;
  1.1070 +				}
  1.1071 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.1072 +			if(aReq->ClientId() & (1 << RESOURCE_BIT_IN_ID_CHECK))
  1.1073 +				{
  1.1074 +				if(aResource->iResourceId & KIdMaskDynamic)
  1.1075 +					pL = ((DDynamicPowerResourceD*)aResource)->iResourceClientList;
  1.1076 +				else
  1.1077 +					pL = ((DStaticPowerResourceD*)aResource)->iResourceClientList;
  1.1078 +				while(pL != NULL)
  1.1079 +					{
  1.1080 +					if((TInt)pL->iClientId == aReq->ClientId())
  1.1081 +						break;
  1.1082 +					}
  1.1083 +				}
  1.1084 +#endif
  1.1085 +			// coverity[var_deref_op]
  1.1086 +			if((TInt)pL->iClientId != aReq->ClientId())
  1.1087 +				Panic(EClientIdNotInClientLevelList);
  1.1088 +			}
  1.1089 +		if(!aReq->RequiresChange() && (aReq->ClientId() != (TInt)pC->iClientId))
  1.1090 +	        {
  1.1091 +		    aResource->iLevelOwnerId=aReq->ClientId();
  1.1092 +			//Update resource details for Idle
  1.1093 +		    if(aResource->iIdleListEntry)
  1.1094 +				aResource->iIdleListEntry->iLevelOwnerId=aReq->ClientId();
  1.1095 +			}
  1.1096 +		__KTRACE_OPT(KRESMANAGER, Kern::Printf("DPowerResourceController::CheckLevelAndAddClient"));
  1.1097 +        return KErrNone;
  1.1098 +		}
  1.1099 +    //Handle client deregistration
  1.1100 +	if(aReq->ReqType() == TPowerRequest::ESetDefaultLevel) 
  1.1101 +		{
  1.1102 +		aReq->RequiresChange() = ETrue;
  1.1103 +		// If the client is the only ask PSL to set to default level.
  1.1104 +		if(count == 1)
  1.1105 +			{
  1.1106 +			aReq->ReqType() = TPowerRequest::ESetDefaultLevel;
  1.1107 +			aReq->Level() = aResource->iDefaultLevel;
  1.1108 +			aReq->ClientId() = -1;
  1.1109 +			}
  1.1110 +        else
  1.1111 +			{
  1.1112 +			//Change the state to next maximum level with respect to sense.
  1.1113 +			aReq->ReqType() = TPowerRequest::EChange;
  1.1114 +			// coverity[var_deref_op]
  1.1115 +			aReq->ClientId() = pMCL->iClientId;
  1.1116 +			aReq->Level() = pMCL->iLevel;
  1.1117 +			if(pSCL->iLevel == pMCL->iLevel)
  1.1118 +				{
  1.1119 +                //Change the client alone and level remains the same.
  1.1120 +                aResource->iLevelOwnerId = pMCL->iClientId;
  1.1121 +                if(aResource->iIdleListEntry)
  1.1122 +                    aResource->iIdleListEntry->iLevelOwnerId = pMCL->iClientId;
  1.1123 +                aReq->RequiresChange() = EFalse;
  1.1124 +				}
  1.1125 +			}
  1.1126 +		__KTRACE_OPT(KRESMANAGER, Kern::Printf("DPowerResourceController::CheckLevelAndAddClient"));
  1.1127 +		return KErrNone;
  1.1128 +		}
  1.1129 +
  1.1130 +	//If the level is in increasing order with respect to sense the change is allowed.
  1.1131 +    if(((aResource->Sense() == DStaticPowerResource::ENegative) && aReq->Level()<CurrentLevel) || 
  1.1132 +		                 ((aResource->Sense() == DStaticPowerResource::EPositive) && aReq->Level()>CurrentLevel))
  1.1133 +		{
  1.1134 +		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Resource is in increasing order with respect to sense and level is %d",
  1.1135 +			                                                                                           aReq->Level()));
  1.1136 +        aReq->RequiresChange()=ETrue;
  1.1137 +        return KErrNone;
  1.1138 +		}
  1.1139 +    if((TInt)pC->iClientId == aResource->iLevelOwnerId)
  1.1140 +		{
  1.1141 +         if(aReq->Level() == CurrentLevel)
  1.1142 +			{
  1.1143 +			 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DPowerResourceController::CheckLevelAndAddClient"));
  1.1144 +			return KErrNone;
  1.1145 +			}
  1.1146 +         if(count == 1)
  1.1147 +           {
  1.1148 +           aReq->RequiresChange() = ETrue;
  1.1149 +		   __KTRACE_OPT(KRESMANAGER, Kern::Printf("DPowerResourceController::CheckLevelAndAddClient"));
  1.1150 +           return KErrNone;
  1.1151 +           }
  1.1152 +		// If the client requesting is the client holding current level, then chnage it to the nextmaximum level.
  1.1153 +		// Next maximum level is the max of requesting level or next maximum level.
  1.1154 +		if(((aResource->Sense()==DStaticPowerResource::ENegative) && maxLevel < aReq->Level()) || 
  1.1155 +			                  ((aResource->Sense()==DStaticPowerResource::EPositive) && maxLevel > aReq->Level()))
  1.1156 +		    {
  1.1157 +			aReq->Level() = maxLevel;
  1.1158 +			aReq->ClientId() = pMCL->iClientId;
  1.1159 +			if(maxLevel == CurrentLevel)
  1.1160 +				{
  1.1161 +       			aResource->iLevelOwnerId=pMCL->iClientId;
  1.1162 +				//Update resource details for Idle
  1.1163 +				if(aResource->iIdleListEntry)
  1.1164 +             		aResource->iIdleListEntry->iLevelOwnerId=pMCL->iClientId;
  1.1165 +				aReq->RequiresChange() = EFalse;
  1.1166 +				__KTRACE_OPT(KRESMANAGER, Kern::Printf("DPowerResourceController::CheckLevelAndAddClient"));
  1.1167 +				return KErrNone;
  1.1168 +				}
  1.1169 +			}
  1.1170 +	      	aReq->RequiresChange() = ETrue;
  1.1171 +		}
  1.1172 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("DPowerResourceController::CheckLevelAndAddClient"));
  1.1173 +    return KErrNone;
  1.1174 +	}
  1.1175 +
  1.1176 +/**
  1.1177 +    Initialise pools of request structures, client strutures and client power level structures. 
  1.1178 +	By preallocating sufficiently large structures we remove any allocations whilst the resource manager mutex is held.
  1.1179 +    The function basically ensures that sufficient memory is preallocated to the resource manager to ensure that none is
  1.1180 +    required at run time.
  1.1181 +    @param aKClients number of kernel side clients expected in the resource manager
  1.1182 +    @param aUClients number of user side clients expected in the resource manager
  1.1183 +    @param aNClientLevels number of client levels the RM should preallocate. This is roughly the number of clients
  1.1184 +        that are expected to use shared resources multiplied by the number of shared resources.
  1.1185 +    @param aNRequest number of simultaneous asynchronous requests the resource manager is likely to handle
  1.1186 +    @return KErrNone if preallocations succeed
  1.1187 +    @return KErrNoMemory if one the prealocations fails
  1.1188 +    */
  1.1189 +TInt DPowerResourceController::InitPools(TUint16 aKClients, TUint16 aUClients, TUint16 aNClientLevels, TUint16 aNRequests)
  1.1190 +	{
  1.1191 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::InitPools"));
  1.1192 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("aKClients = %d, aUClients = %d, aNClientLevels = %d, aNRequests = %d",
  1.1193 +		                                                     aKClients, aUClients, aNClientLevels, aNRequests));
  1.1194 +    __ASSERT_ALWAYS((iInitialised == EResConCreated) && !(iClientPool || iRequestPool || iClientLevelPool), Kern::Fault("Already initialized"
  1.1195 +		                                                     __FILE__, __LINE__));
  1.1196 +
  1.1197 +    // Create client pool
  1.1198 +	SPowerResourceClient* pC = NULL;
  1.1199 +	SPowerResourceClientLevel* pCL = NULL;
  1.1200 +	SPowerRequest* pR = NULL;
  1.1201 +	aKClients++; //Add one default for PowerController
  1.1202 +	if(aKClients + aUClients)
  1.1203 +		{
  1.1204 +		// coverity[alloc_fn]
  1.1205 +		pC = new SPowerResourceClient[aKClients+aUClients];
  1.1206 +		if(!pC)
  1.1207 +			{
  1.1208 +			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client Pool Allocation Failed"));
  1.1209 +			return KErrNoMemory;
  1.1210 +			}
  1.1211 +		}
  1.1212 +    // Create Client level pool
  1.1213 +	if(aNClientLevels)
  1.1214 +		{
  1.1215 +		// coverity[alloc_fn]
  1.1216 +		pCL = new SPowerResourceClientLevel[aNClientLevels];
  1.1217 +		if(!pCL)
  1.1218 +			{
  1.1219 +			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client Level Pool Allocation Failed"));
  1.1220 +			delete []pC;
  1.1221 +			return KErrNoMemory;
  1.1222 +			}
  1.1223 +		}
  1.1224 +    // Create Request pool
  1.1225 +	if(aNRequests)
  1.1226 +		{
  1.1227 +		// coverity[alloc_fn]
  1.1228 +		pR = new SPowerRequest[aNRequests];
  1.1229 +		if(!pR)
  1.1230 +			{
  1.1231 +			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Request Pool Allocation Failed"));
  1.1232 +			delete []pC;
  1.1233 +			delete []pCL;
  1.1234 +			return KErrNoMemory;
  1.1235 +			}
  1.1236 +		}
  1.1237 +    //Create the client Array for kernel and user side clients.
  1.1238 +	if(iClientList.Initialise(aKClients))
  1.1239 +		{
  1.1240 +        delete []pC;
  1.1241 +        delete []pCL;
  1.1242 +        delete []pR;
  1.1243 +        return KErrNoMemory;
  1.1244 +		}
  1.1245 + 	if(iUserSideClientList.Initialise(aUClients))
  1.1246 + 		{
  1.1247 +        delete []pC;
  1.1248 +        delete []pCL;
  1.1249 +        delete []pR;
  1.1250 +        iClientList.Delete();
  1.1251 +		return KErrNoMemory;
  1.1252 +		}
  1.1253 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.1254 +	SPowerResourceClientLevel* pRL = NULL;
  1.1255 +	if(iStaticResDependencyCount)
  1.1256 +		{
  1.1257 +		pRL = new SPowerResourceClientLevel[iStaticResDependencyCount];
  1.1258 +		if(!pRL)
  1.1259 +			{
  1.1260 +			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Resource level Pool Allocation Failed"));
  1.1261 +			delete []pC;
  1.1262 +			delete []pCL;
  1.1263 +			delete []pR;
  1.1264 +			iClientList.Delete();
  1.1265 +			iUserSideClientList.Delete();
  1.1266 +			return KErrNoMemory;
  1.1267 +			}
  1.1268 +		}
  1.1269 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
  1.1270 +	iCleanList.Append(pC);
  1.1271 +#endif
  1.1272 +	Lock();
  1.1273 +	TUint16 c;
  1.1274 +	for(c = 0; c < iStaticResDependencyCount; c++)
  1.1275 +		{
  1.1276 +		LIST_PUSH(iResourceLevelPool, &pRL[c], iNextInList);
  1.1277 +		}
  1.1278 +	iResourceLevelPoolCount = iStaticResDependencyCount;
  1.1279 +#else
  1.1280 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
  1.1281 +    iCleanList.Append(pC);
  1.1282 +#endif
  1.1283 +    Lock();
  1.1284 +    TUint16 c;
  1.1285 +#endif
  1.1286 +    // Create Client pool list
  1.1287 +    for(c = 0; c< (aKClients + aUClients); c++)
  1.1288 +		{
  1.1289 +        LIST_PUSH(iClientPool, &pC[c], iNextInList);
  1.1290 +		}
  1.1291 +    // Create client level pool list
  1.1292 +    for(c = 0; c < aNClientLevels; c++)
  1.1293 +		{
  1.1294 +        LIST_PUSH(iClientLevelPool, &pCL[c], iNextInList);
  1.1295 +		}
  1.1296 +    // Create request pool list
  1.1297 +    for(c = 0; c < aNRequests; c++)
  1.1298 +		{
  1.1299 +        LIST_PUSH(iRequestPool, &pR[c], iNext);
  1.1300 +		}
  1.1301 +    // When the pool is exhausted they are increased by half of initial size. */
  1.1302 +    iClientLevelPoolGrowBy=(TUint16)(aNClientLevels/2);
  1.1303 +    iRequestPoolGrowBy=(TUint16)(aNRequests/2);
  1.1304 +    // Initialise the free pool size
  1.1305 +    iClientLevelPoolCount=aNClientLevels;
  1.1306 +    iRequestPoolCount=aNRequests;
  1.1307 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.1308 +	TUint size = (((aKClients + aUClients)*sizeof(SPowerResourceClient)) + 
  1.1309 +		         (aNClientLevels * sizeof(SPowerResourceClientLevel)) + (aNRequests * sizeof(SPowerRequest)));
  1.1310 +    PRM_MEMORY_USAGE_TRACE
  1.1311 +#endif
  1.1312 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::InitPools"));
  1.1313 +    UNLOCK_RETURN(KErrNone);
  1.1314 +	}
  1.1315 +
  1.1316 +/**
  1.1317 +@publishedPartner
  1.1318 +@prototype 9.5
  1.1319 +
  1.1320 +Register a client with the Resource Manager. 
  1.1321 +
  1.1322 +@param aClientId  A reference to a client ID: returns a unique handle if registration was
  1.1323 +                  successful, 0 otherwise.
  1.1324 +@param aName      Descriptor with name for client. The descriptor is created by the client
  1.1325 +                  in kernel data space or its user address space.
  1.1326 +                  NOTE: Name should ideally relate to component name and should take care
  1.1327 +                  of name uniqueness as it is checked only if DEBUG_VERSION macro is enabled.
  1.1328 +@param aType      Defines ownership
  1.1329 +                  EOwnerProcess - The client ID can be used by all thread in the process to
  1.1330 +                  call the resource manager API's
  1.1331 +                  EOwnerThread - The client ID can only be used by the thread that registered
  1.1332 +                  the client to resource manager to call the PRM API's
  1.1333 +                  By default this is set to EOwnerProcess.
  1.1334 +
  1.1335 +@return           KErrNone if the operation was successful,
  1.1336 +                  KErrNoMemory if a new client link was needed but could not be created and
  1.1337 +								added to the client list,
  1.1338 +                  KErrTooBig if the length of the descriptor passed is greater than 32.
  1.1339 +				  KErrAlreadyExists if the specified name already exists. This is valid only if
  1.1340 +								DEBUG_VERSION macro is enabled. 
  1.1341 +				  KErrNotSupported if number of expected kernel side clients is set to zero by 
  1.1342 +								PSL.
  1.1343 +
  1.1344 +@pre Interrupts must be enabled.
  1.1345 +@pre Kernel must be unlocked.
  1.1346 +@pre No fast mutex can be held.
  1.1347 +@pre Call in a thread context, but not from null thread or DFC thread1.
  1.1348 +@pre Can be used in a device driver
  1.1349 +*/
  1.1350 +TInt DPowerResourceController::RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType)
  1.1351 +	{
  1.1352 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterClient, Name = %S, Type = %d", &aName, aType));
  1.1353 +	DThread& thread = Kern::CurrentThread();	
  1.1354 +	CHECK_CONTEXT(thread)
  1.1355 +	//If number of expected kernel side clients is set to 0 during initial configuration
  1.1356 +	//then dont allow to configure kernel side clients.
  1.1357 +	if(!iClientList.GrowBy())
  1.1358 +		return KErrNotSupported;
  1.1359 +	if (aName.Length() > KMaxClientNameLength) return KErrTooBig;
  1.1360 +	SPowerResourceClient *pC = NULL;
  1.1361 +	Lock();
  1.1362 +#ifdef DEBUG_VERSION
  1.1363 +   if(!iClientList.Find(pC, (TDesC8&)aName))
  1.1364 +       UNLOCK_RETURN(KErrAlreadyExists);
  1.1365 +#endif
  1.1366 +	//Call from thread Id.
  1.1367 +	TPowerRequest* req = (TPowerRequest*)&TPowerRequest::Get();
  1.1368 +	req->ReqType() = TPowerRequest::ERegisterKernelClient;
  1.1369 +	UnLock();
  1.1370 +	req->SendReceive(iMsgQ);
  1.1371 +	if(req->ReturnCode() == KErrNone)
  1.1372 +		{
  1.1373 +		pC = iClientList[(TUint16)(req->ClientId() & ID_INDEX_BIT_MASK)];
  1.1374 +		if(aType == EOwnerThread)
  1.1375 +			{
  1.1376 +			pC->iClientId |= CLIENT_THREAD_RELATIVE_BIT_MASK; //Set 31st bit;
  1.1377 +			//Store the current thread Id;
  1.1378 +			pC->iThreadId = thread.iId;
  1.1379 +			}
  1.1380 +		pC->iName = &aName;
  1.1381 +		aClientId = pC->iClientId;
  1.1382 +		}
  1.1383 +    PRM_CLIENT_REGISTER_TRACE
  1.1384 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterClient, clientId = 0x%x", aClientId));
  1.1385 +	return(req->ReturnCode());
  1.1386 +	}
  1.1387 +
  1.1388 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.1389 +TInt DPowerResourceController::HandleResourceRegistration(TPowerRequest& aReq)
  1.1390 +	{
  1.1391 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::HandleResourceRegistration"));
  1.1392 +	DDynamicPowerResource* pDRes = (DDynamicPowerResource*)aReq.Resource();
  1.1393 +		//Add to appropriate container
  1.1394 +	if(pDRes->iResourceId & KIdMaskResourceWithDependencies)
  1.1395 +		ADD_TO_RESOURCE_CONTAINER(iDynamicResDependencyList, ((DDynamicPowerResourceD*)pDRes), aReq.ResourceId(), 
  1.1396 +		                                                                   iDynamicResDependencyCount)
  1.1397 +	else 
  1.1398 +		ADD_TO_RESOURCE_CONTAINER(iDynamicResourceList, pDRes, aReq.ResourceId(), iDynamicResourceCount)
  1.1399 +
  1.1400 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::HandleResourceRegistration"));
  1.1401 +	return KErrNone;
  1.1402 +	}
  1.1403 +#endif
  1.1404 +
  1.1405 +/**
  1.1406 +@internalComponent
  1.1407 +@prototype 9.5
  1.1408 +
  1.1409 +This function runs in the context of the RC thread and 
  1.1410 +handles registration of client (kernel and user side). 
  1.1411 +*/
  1.1412 +TInt DPowerResourceController::HandleClientRegistration(TPowerRequest& aRequest)
  1.1413 +	{
  1.1414 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterClient"));
  1.1415 +	SPowerResourceClient* pC = NULL;
  1.1416 +	TUint clientId;
  1.1417 +	if(aRequest.ReqType() == TPowerRequest::ERegisterKernelClient)
  1.1418 +		{
  1.1419 +		//Get Next client from FreePool
  1.1420 +		LIST_POP(iClientPool, pC, iNextInList);
  1.1421 +
  1.1422 +		TUint16 growBy = iClientList.GrowBy();
  1.1423 +		if(!pC)
  1.1424 +			{
  1.1425 +			//Free Pool is empty, so try to grow the pool.
  1.1426 +			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client pool exhausted so growing client Pool by %d", growBy));
  1.1427 +			// coverity[alloc_fn]
  1.1428 +			SPowerResourceClient *pCL = (SPowerResourceClient*)Kern::Alloc(sizeof(SPowerResourceClient) * growBy);
  1.1429 +			if(!pCL)
  1.1430 +				{
  1.1431 +				__KTRACE_OPT(KRESMANAGER, Kern::Printf("No memory to grow client pool"));
  1.1432 +				return(KErrNoMemory);
  1.1433 +				}
  1.1434 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
  1.1435 +			iCleanList.Append(pCL);
  1.1436 +#endif
  1.1437 +			Lock();
  1.1438 +			TUint16 count;
  1.1439 +			for(count = 0; count < growBy-1; count++)
  1.1440 +				LIST_PUSH(iClientPool, &pCL[count], iNextInList);
  1.1441 +			UnLock();
  1.1442 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.1443 +	TUint size = growBy *sizeof(SPowerResourceClient);
  1.1444 +	PRM_MEMORY_USAGE_TRACE
  1.1445 +#endif
  1.1446 +			pC = &pCL[count];
  1.1447 +			}
  1.1448 +		pC->iClientId = 0;
  1.1449 +		if(iClientList.Allocd()==iClientList.Count())
  1.1450 +			{
  1.1451 +			//Resize the container for holding client list
  1.1452 +			if(iClientList.ReSize(growBy)!=KErrNone)
  1.1453 +				{
  1.1454 +				__KTRACE_OPT(KRESMANAGER, Kern::Printf("No memory for client container allocation"));
  1.1455 +				return(KErrNoMemory);
  1.1456 +				}
  1.1457 +			}
  1.1458 +		Lock();
  1.1459 +		iClientList.Add(pC, clientId);
  1.1460 +		++iClientCount;
  1.1461 +		UnLock();
  1.1462 +		}
  1.1463 +	else // Request is registration of user side client
  1.1464 +		{
  1.1465 +		//Get Next client from FreePool
  1.1466 +		LIST_POP(iClientPool, pC, iNextInList);
  1.1467 +		TUint16 growBy = iUserSideClientList.GrowBy();
  1.1468 +		if(!pC)
  1.1469 +			{
  1.1470 +			//Free Pool is empty, so try to grow the pool.
  1.1471 +			SPowerResourceClient *pCL = (SPowerResourceClient*)Kern::Alloc(sizeof(SPowerResourceClient) * growBy);
  1.1472 +			if(!pCL)
  1.1473 +				{
  1.1474 +				return KErrNoMemory;
  1.1475 +				}
  1.1476 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
  1.1477 +			iCleanList.Append(pCL);
  1.1478 +#endif
  1.1479 +			Lock();
  1.1480 +			TUint16 count;
  1.1481 +			for(count = 0; count < growBy - 1; count++)
  1.1482 +				LIST_PUSH(iClientPool, &pCL[count], iNextInList);
  1.1483 +			UnLock();
  1.1484 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.1485 +		TUint size = growBy * sizeof(SPowerResourceClient);
  1.1486 +		PRM_MEMORY_USAGE_TRACE
  1.1487 +#endif
  1.1488 +    		pC = &pCL[count];
  1.1489 +			}
  1.1490 +		pC->iClientId = 0;
  1.1491 +		//User side clients are always thread relative as they execute in the context of proxy driver.
  1.1492 +		pC->iClientId = CLIENT_THREAD_RELATIVE_BIT_MASK; //Set 31st bit;
  1.1493 +		pC->iClientId|=USER_SIDE_CLIENT_BIT_MASK;
  1.1494 +		if(iUserSideClientList.Allocd()==iUserSideClientList.Count())
  1.1495 +			{
  1.1496 +			//Resize the container for holding client list
  1.1497 +			if(iUserSideClientList.ReSize(growBy)!=KErrNone)
  1.1498 +				{
  1.1499 +				__KTRACE_OPT(KRESMANAGER, Kern::Printf("No memory for container class allocation"));
  1.1500 +				return KErrNoMemory;
  1.1501 +				}
  1.1502 +			}
  1.1503 +		Lock();
  1.1504 +		iUserSideClientList.Add(pC, clientId);
  1.1505 +		++iUserSideClientCount;
  1.1506 +		UnLock();
  1.1507 +		}
  1.1508 +	//Create the unique handle for each client
  1.1509 +	//Client Handle format
  1.1510 +	//  31  30								   18 16    15    14 13	                                 0
  1.1511 +	// ¦----¦-----------------------------------¦----¦-----¦-----¦-----------------------------------¦
  1.1512 +	// ¦ T/P¦ Container's instance count(15 bits¦C/R ¦  PC ¦ K/U ¦ Index into Client array container ¦
  1.1513 +	// ¦----¦-----------------------------------¦----¦-----¦-----¦-----------------------------------¦
  1.1514 +	// T/P -> Thread / process relative
  1.1515 +	// PC -> Power Controller reserved ID.
  1.1516 +	// K/U -> Kernel / User side clients
  1.1517 +	// C/R -> Client / Resource Id. This bit will be set for dependency resource Id, zero for clientId.
  1.1518 +  	pC->iLevelList = NULL;
  1.1519 +    pC->iNotificationList = NULL;
  1.1520 +	pC->iDynamicResCount = 0; 	
  1.1521 +    pC->iReservedCl = 0;
  1.1522 +    pC->iReservedRm = 0;
  1.1523 +    pC->iPendingReqCount = 0;
  1.1524 +    pC->iUnderFlowRmCount = 0;
  1.1525 +    pC->iUnderFlowClCount = 0;
  1.1526 +	pC->iClientId |= clientId;
  1.1527 +	aRequest.ClientId() = pC->iClientId;
  1.1528 +	return KErrNone;
  1.1529 +	}
  1.1530 +
  1.1531 +/**	@internalComponent
  1.1532 +	@prototype 9.5
  1.1533 +	This is called as the result of client deregistration and takes care of resource state changes
  1.1534 +	(to appropriate levels) of all the resources the client is holding active requirement. */
  1.1535 +void DPowerResourceController::ResourceStateChangeOfClientLevels(SPowerResourceClient* pC)
  1.1536 +	{
  1.1537 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::ResourceStateChangeOfClientLevels"));
  1.1538 +    TPowerRequest* pReq = (TPowerRequest*)&TPowerRequest::Get();
  1.1539 +    DStaticPowerResource* pR = NULL;
  1.1540 +    SPowerResourceClientLevel* pCL = pC->iLevelList;
  1.1541 +    SPowerResourceClientLevel* pCLL = NULL;
  1.1542 +	while(pCL != NULL)
  1.1543 +		{
  1.1544 +        __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client 0x%x has requirement on resource %d", pCL->iClientId, pCL->iResourceId));
  1.1545 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.1546 +		switch((pCL->iResourceId >>RESOURCE_BIT_IN_ID_CHECK) & 0x3)													
  1.1547 +		{																		
  1.1548 +		case PRM_STATIC_RESOURCE:												
  1.1549 +			pR = iStaticResourceArray[pCL->iResourceId - 1];								
  1.1550 +			break;																
  1.1551 +		case PRM_DYNAMIC_RESOURCE:												
  1.1552 +			pR = (iDynamicResourceList[(TUint16)(pCL->iResourceId & ID_INDEX_BIT_MASK)]);			
  1.1553 +			break;																
  1.1554 +		case PRM_STATIC_DEPENDENCY_RESOURCE:									
  1.1555 +			pR = (iStaticResDependencyArray[(TUint16)(pCL->iResourceId & ID_INDEX_BIT_MASK) - 1]);						
  1.1556 +			break;																
  1.1557 +		case PRM_DYNAMIC_DEPENDENCY_RESOURCE:									
  1.1558 +			pR = (iDynamicResDependencyList[(TUint16)(pCL->iResourceId & ID_INDEX_BIT_MASK)]);		
  1.1559 +			break;																
  1.1560 +		}
  1.1561 +#else
  1.1562 +		pR = iStaticResourceArray[pCL->iResourceId -1];
  1.1563 +#endif
  1.1564 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.1565 +		if(((pR->Sense() == DStaticPowerResource::ECustom) || ((TInt)pCL->iClientId == pR->iLevelOwnerId)) && (!(pCL->iResourceId & KIdMaskDynamic) ||
  1.1566 +			         ((pCL->iResourceId & KIdMaskDynamic) && (((DDynamicPowerResource*)pR)->LockCount() != 0))))
  1.1567 +#else
  1.1568 +		if((pR->Sense() == DStaticPowerResource::ECustom) || ((TInt)pCL->iClientId == pR->iLevelOwnerId)) 
  1.1569 +#endif
  1.1570 +		    {
  1.1571 +            pReq->ReqType() = TPowerRequest::ESetDefaultLevel;
  1.1572 +            pReq->ResourceId() = pCL->iResourceId;
  1.1573 +            pReq->ClientId() = pCL->iClientId;
  1.1574 +            pReq->Resource() = pR;
  1.1575 +			pReq->Level() = pR->iCachedLevel;
  1.1576 +            pReq->ResourceCb() = NULL;
  1.1577 +			pReq->ReturnCode() = KErrNone;
  1.1578 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.1579 +			//Setting level to current level as correct level will be known only at the end,
  1.1580 +			TInt aNewState = pR->iCachedLevel; 
  1.1581 +			TUint aResourceId = pReq->ResourceId(); 
  1.1582 +			PRM_CLIENT_CHANGE_STATE_START_TRACE
  1.1583 +#endif
  1.1584 +			TInt r = KErrNone;
  1.1585 +			if(pR->LatencySet())
  1.1586 +				{
  1.1587 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.1588 +				if(pCL->iResourceId & KIdMaskDynamic)
  1.1589 +					((DDynamicPowerResource*)pR)->Lock();
  1.1590 +#endif
  1.1591 +				UnLock();
  1.1592 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.1593 +				if(pR->iResourceId & KIdMaskResourceWithDependencies) //Dependency resource
  1.1594 +					r = pReq->SendReceive(iMsgQDependency);	
  1.1595 +				else
  1.1596 +#endif
  1.1597 +				r = pReq->SendReceive(iMsgQ);
  1.1598 +				Lock();
  1.1599 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.1600 +				if(pCL->iResourceId & KIdMaskDynamic)
  1.1601 +					((DDynamicPowerResource*)pR)->UnLock();
  1.1602 +#endif
  1.1603 +				}
  1.1604 +			else
  1.1605 +				{
  1.1606 +	            if(pR->Usage())
  1.1607 +					{
  1.1608 +					//Not checking return value as there is no memory allocation at this point
  1.1609 +					CheckLevelAndAddClient(pC, pReq); 
  1.1610 +					}
  1.1611 +				else
  1.1612 +					{
  1.1613 +					pReq->ClientId() = -1;
  1.1614 +					pReq->Level() = pR->iDefaultLevel;
  1.1615 +					}
  1.1616 +
  1.1617 +				if((!pR->Usage()) || (pR->Usage() && pReq->RequiresChange()))
  1.1618 +					{
  1.1619 +					// NOTE:Not checking error here as no action can be taken based on error.
  1.1620 +					if(pR->iCachedLevel != pReq->Level())
  1.1621 +						{
  1.1622 +						UnLock();
  1.1623 +						r = pR->DoRequest(*pReq);
  1.1624 +						Lock();
  1.1625 +						}
  1.1626 +					CompleteNotifications(pReq->ClientId(), pReq->Resource(), pReq->Level(), 
  1.1627 +						                            pReq->ReturnCode(), pReq->ClientId(), EFalse);
  1.1628 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.1629 +					PRM_CLIENT_CHANGE_STATE_END_TRACE
  1.1630 +#endif
  1.1631 +					pR->iLevelOwnerId = pReq->ClientId();
  1.1632 +					pR->iCachedLevel = pReq->Level();
  1.1633 +					if(pR->iIdleListEntry)
  1.1634 +						{
  1.1635 +						SIdleResourceInfo* pI = (SIdleResourceInfo*)pR->iIdleListEntry;
  1.1636 +						pI->iLevelOwnerId = pReq->ClientId();
  1.1637 +						pI->iCurrentLevel = pReq->Level();
  1.1638 +						}
  1.1639 +					}
  1.1640 +				}
  1.1641 +
  1.1642 +			}
  1.1643 +		/* Deque from resource */
  1.1644 +		pCLL = pCL;
  1.1645 +		pCL = pCL->iNextInList;
  1.1646 +		pCLL->Deque();
  1.1647 +		iClientLevelPoolCount++;
  1.1648 +		LIST_PUSH(iClientLevelPool,pCLL,iNextInList); // back to free pool
  1.1649 +		}
  1.1650 +	pC->iLevelList = NULL;
  1.1651 +	//Add reserved client level to free pool
  1.1652 +	iClientLevelPoolCount = (TUint16)(iClientLevelPoolCount + (TUint16)pC->iReservedCl);
  1.1653 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::ResourceStateChangeOfClientLevels"));
  1.1654 +	}
  1.1655 +
  1.1656 +/**
  1.1657 +@publishedPartner
  1.1658 +@prototype 9.5
  1.1659 +
  1.1660 +Deregister a client with the resource manager
  1.1661 +
  1.1662 +@param aClientId    The ID of the client which is being deregistered
  1.1663 +
  1.1664 +@return KErrNone if the operation was successful
  1.1665 +        KErrNotFound if this client ID could not be found in the current
  1.1666 +					 list of clients
  1.1667 +		KErrArgument if user side client Id is specified or client ID to be used 
  1.1668 +					 by Power Controller is specified.
  1.1669 +		KErrAccessDenied if client was registered to be thread relative and this 
  1.1670 +						 API is not called from the same thread.							
  1.1671 +
  1.1672 +@pre Interrupts must be enabled
  1.1673 +@pre Kernel must be unlocked
  1.1674 +@pre No fast mutex can be held
  1.1675 +@pre Call in a thread context but not from null thread or DFC thread1
  1.1676 +@pre Can be used in a device driver
  1.1677 +*/
  1.1678 +TInt DPowerResourceController::DeRegisterClient(TUint aClientId)
  1.1679 +	{
  1.1680 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::DeRegisterClient, ClientId = 0x%x", aClientId));
  1.1681 +	DThread& thread = Kern::CurrentThread();	
  1.1682 +	CHECK_CONTEXT(thread)
  1.1683 +	if((aClientId & USER_SIDE_CLIENT_BIT_MASK) || (aClientId == iPowerControllerId))
  1.1684 +		return KErrArgument;
  1.1685 +	//Get the index from client ID
  1.1686 +	Lock();
  1.1687 +	SPowerResourceClient* pC = iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];
  1.1688 +    if(!pC)
  1.1689 +	    {
  1.1690 +        __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found"));
  1.1691 +        UNLOCK_RETURN(KErrNotFound);
  1.1692 +		}
  1.1693 +	if(pC->iClientId != aClientId)
  1.1694 +		{
  1.1695 +        __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID does not match"));
  1.1696 +	     UNLOCK_RETURN(KErrNotFound);
  1.1697 +		}
  1.1698 +	if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK)
  1.1699 +		{
  1.1700 +        if(pC->iThreadId != thread.iId)
  1.1701 +			{
  1.1702 +            __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client not called from thread context(Thread Relative)"));
  1.1703 +            UNLOCK_RETURN(KErrAccessDenied);
  1.1704 +			}
  1.1705 +		}	
  1.1706 +	//Check for any pending request
  1.1707 +	if(pC->iPendingReqCount)
  1.1708 +		{
  1.1709 +		UnLock();
  1.1710 +		Panic(EClientHasPendingAsyncRequest);
  1.1711 +		}
  1.1712 +	//Check for notification request
  1.1713 +	if(pC->iNotificationList)
  1.1714 +		{
  1.1715 +		UnLock();
  1.1716 +		Panic(EClientHasNotificationObject);
  1.1717 +		}
  1.1718 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.1719 +	if(pC->iDynamicResCount)
  1.1720 +		{
  1.1721 +		UnLock();
  1.1722 +		Panic(DPowerResourceController::EClientHasDynamicResourceRegistered);
  1.1723 +		}
  1.1724 +#endif
  1.1725 +	//Check for registration of dynamic resource
  1.1726 +	ResourceStateChangeOfClientLevels(pC);
  1.1727 +	// Add reserved request to pool
  1.1728 +	iRequestPoolCount = (TUint16)(iRequestPoolCount + (TUint16)pC->iReservedRm);
  1.1729 +	PRM_CLIENT_DEREGISTER_TRACE
  1.1730 +	//Increment the free pool count for client level and request level.
  1.1731 +	iClientList.Remove(pC, (TUint16)(pC->iClientId & ID_INDEX_BIT_MASK));
  1.1732 +	pC->iName = NULL;
  1.1733 +	iClientCount--; //Decrement client count
  1.1734 +	LIST_PUSH(iClientPool, pC, iNextInList);
  1.1735 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::DeRegisterClient"));
  1.1736 +	UNLOCK_RETURN(KErrNone);
  1.1737 +	}
  1.1738 +
  1.1739 +/**
  1.1740 +@publishedPartner
  1.1741 +@prototype 9.5
  1.1742 +
  1.1743 +Obtain the name of a registered client of the resource manager
  1.1744 +
  1.1745 +@param aClientId   The ID of the client which is requesting the name of
  1.1746 +                   another client whose ID is specified in aTargetClientId.
  1.1747 +@param aTargetClientId The ID of the client whose name is being requested.
  1.1748 +@param aName       Descriptor to be filled with the name of the client. The descriptor
  1.1749 +                   is created by the client in kernel stack or heap.
  1.1750 +
  1.1751 +@return            KErrNone if the operation was successful
  1.1752 +                   KErrNotFound if this client ID (aTargetClientId) could not be
  1.1753 +                   found in the current list of registered clients.
  1.1754 +                   KErrAccessDenied if the client ID (aClientId) could not be found
  1.1755 +                   in the current list of registered clients or if client was registered
  1.1756 +				   to be thread relative and this API is not called from the same thread. 
  1.1757 +                   KErrArgument if size of aName is less than 32.
  1.1758 +
  1.1759 +@pre Interrupts must be enabled
  1.1760 +@pre Kernel must be unlocked
  1.1761 +@pre No fast mutex can be held
  1.1762 +@pre Call in a thread context but not from null thread or DFC thread1
  1.1763 +@pre Can be used in a device driver
  1.1764 +*/
  1.1765 +TInt DPowerResourceController::GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName)
  1.1766 +	{
  1.1767 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetClientName, CallingClientId = 0x%x, TargetClientId = 0x%x", aClientId, aTargetClientId));
  1.1768 +	DThread& thread = Kern::CurrentThread();	
  1.1769 +	CHECK_CONTEXT(thread)
  1.1770 +	if((aName.MaxLength() - aName.Length()) < KMaxClientNameLength)
  1.1771 +		return KErrArgument;
  1.1772 +	SPowerResourceClient* pC = NULL;
  1.1773 +	Lock();
  1.1774 +	VALIDATE_CLIENT(thread);
  1.1775 +	GET_TARGET_CLIENT();
  1.1776 +	aName.Append(*pC->iName);
  1.1777 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetClientName, ClientName = %S", &aName));
  1.1778 +	UNLOCK_RETURN(KErrNone);
  1.1779 +	}
  1.1780 +
  1.1781 +/**
  1.1782 +@publishedPartner
  1.1783 +@prototype 9.5
  1.1784 +
  1.1785 +Obtain the Id of registered client of the resource manager
  1.1786 +
  1.1787 +@param aClientId   ID of the client which is requesting the ID of the another
  1.1788 +                   client whose name is specified in aClientName
  1.1789 +@param aClientName Descriptor containing the name of the client whose ID is being
  1.1790 +                   requested. The client must create the descriptor in kernel stack
  1.1791 +                   or heap.
  1.1792 +                   NOTE: Resource manager does not check for uniqueness of client
  1.1793 +                   name during registration, so if there are multiple clients registered
  1.1794 +                   to PRM with same name it will return the ID of the first client it encounters.
  1.1795 +@param aTargetClientId Updates with ID of the requested client on success
  1.1796 +
  1.1797 +@return  KErrNone if the operation was successful
  1.1798 +         KErrNotFound if this client name could not be found in the current list of registered
  1.1799 +                      client
  1.1800 +         KErrAccessDenied if the client ID (aClientId) could not be found in the current
  1.1801 +                          list of registered client or if the client was registered to be 
  1.1802 +						  thread relative and this API is not called from the same thread. 
  1.1803 +         KErrTooBig if the length of the descriptor passed is greater than 32.
  1.1804 +
  1.1805 +@pre Interrupts must be enabled
  1.1806 +@pre Kernel must be unlocked
  1.1807 +@pre No fast mutex can be held
  1.1808 +@pre Call in a thread context but not from null thread or DFC thread1
  1.1809 +@pre Can be used in a device driver
  1.1810 +*/
  1.1811 +TInt DPowerResourceController::GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId)
  1.1812 +	{
  1.1813 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetClientId CallingClientId = 0x%x, ClientName = %S", aClientId, &aClientName));
  1.1814 +	DThread& thread = Kern::CurrentThread();	
  1.1815 +	CHECK_CONTEXT(thread)
  1.1816 +	if(aClientName.Length() > KMaxClientNameLength)
  1.1817 +		return KErrTooBig;
  1.1818 +	SPowerResourceClient* pC = NULL;
  1.1819 +	Lock();
  1.1820 +	VALIDATE_CLIENT(thread);
  1.1821 +	//Find the client ID with the specified name first from kernel client list & then user side.
  1.1822 +	if(iClientList.Find(pC, aClientName) && iUserSideClientList.Find(pC, aClientName))
  1.1823 +		UNLOCK_RETURN(KErrNotFound);
  1.1824 +	aTargetClientId = pC->iClientId;
  1.1825 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetClientId TargetClientId = 0x%x", aTargetClientId));
  1.1826 +	UNLOCK_RETURN(KErrNone);
  1.1827 +	}
  1.1828 +
  1.1829 +/**
  1.1830 +@publishedPartner
  1.1831 +@prototype 9.5
  1.1832 +
  1.1833 +Obtain the ID of registered resource of the resource manager.
  1.1834 +NOTE: ID of the first matching name found in the resource list will be returned
  1.1835 +
  1.1836 +@param aClientId      ID of the client which is requesting the ID of the
  1.1837 +                      resource, by specifying its name.
  1.1838 +@param aResourceName  Descriptor containing the name of the resource whose
  1.1839 +                      ID is being requested.
  1.1840 +@param aResourceId    Updates with ID of the requested resource on success
  1.1841 +
  1.1842 +@return KErrNone if the operation was successful
  1.1843 +        KErrAccessDenied if the ID of the client could not be found in the
  1.1844 +                         current list of registered clients or if the client was 
  1.1845 +						 registered to be thread relative and this API is not called
  1.1846 +						 from the same thread. 
  1.1847 +        KErrNotFound if this resource name could not be found in the current
  1.1848 +                     list of registered resources.
  1.1849 +		KErrTooBig if the length of the descriptor passed is greater than maximum
  1.1850 +				   allowable resource name length (32).
  1.1851 +@pre Interrupts must be enabled
  1.1852 +@pre Kernel must be unlocked
  1.1853 +@pre No fast mutex can be held
  1.1854 +@pre Call in a thread context but not from null thread or DFC thread1
  1.1855 +@pre Can be used in a device driver
  1.1856 +*/
  1.1857 +TInt DPowerResourceController::GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId)
  1.1858 +	{
  1.1859 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetResourceId"));
  1.1860 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("CallingClientId = 0x%x, ResourceName = %S", aClientId, &aResourceName));
  1.1861 +	DThread& thread = Kern::CurrentThread();	
  1.1862 +	CHECK_CONTEXT(thread)
  1.1863 +	SPowerResourceClient* pC;
  1.1864 +	if(aResourceName.Length() > KMaxResourceNameLength)
  1.1865 +		return KErrTooBig;
  1.1866 +	Lock();
  1.1867 +	VALIDATE_CLIENT(thread);
  1.1868 +	TUint count = 0;
  1.1869 +	//Search in static resource with no dependencies array for specified resource name.
  1.1870 +	for(count = 0; count < iStaticResourceArrayEntries; count++)
  1.1871 +		{
  1.1872 +		if((iStaticResourceArray[count]) && (!(aResourceName.Compare(*(const TDesC8*)iStaticResourceArray[count]->iName))))
  1.1873 +			{
  1.1874 +			aResourceId = ++count;
  1.1875 +			__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetResourceId, ResourceId = 0x%x", aResourceId));
  1.1876 +			UNLOCK_RETURN(KErrNone);
  1.1877 +			}
  1.1878 +		}
  1.1879 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.1880 +	//Search in dynamic resource with no dependencies array for specified resource name.
  1.1881 +	DDynamicPowerResource* pDR = NULL;
  1.1882 +	if(PowerResourceController->iDynamicResourceCount && 
  1.1883 +		           !PowerResourceController->iDynamicResourceList.Find(pDR, aResourceName))
  1.1884 +		{
  1.1885 +		aResourceId = pDR->iResourceId;
  1.1886 +		__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetResourceId, ResourceId = 0x%x", aResourceId));
  1.1887 +		UNLOCK_RETURN(KErrNone);
  1.1888 +		}
  1.1889 +	//Search in static resource with dependencies (if exists) for specified resource name
  1.1890 +	for(count = 0; count < iStaticResDependencyCount; count++)
  1.1891 +		{
  1.1892 +		if(!(aResourceName.Compare(*(const TDesC8*)iStaticResDependencyArray[count]->iName)))
  1.1893 +			{
  1.1894 +			aResourceId = iStaticResDependencyArray[count]->iResourceId;
  1.1895 +			__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetResourceId, ResourceId = 0x%x", aResourceId));
  1.1896 +			UNLOCK_RETURN(KErrNone);
  1.1897 +			}
  1.1898 +		}
  1.1899 +	//Search in dynamic resource with dependencies (if exists) for specified resource name
  1.1900 +	DDynamicPowerResourceD* pDRD;
  1.1901 +	if(iDynamicResDependencyCount && !iDynamicResDependencyList.Find(pDRD, aResourceName))
  1.1902 +		{
  1.1903 +		aResourceId = pDRD->iResourceId;
  1.1904 +		__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetResourceId, ResourceId = 0x%x", aResourceId));
  1.1905 +		UNLOCK_RETURN(KErrNone);
  1.1906 +		}
  1.1907 +#endif
  1.1908 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetResourceId, ResourceID not found"));
  1.1909 +	UNLOCK_RETURN(KErrNotFound);
  1.1910 +	}
  1.1911 +
  1.1912 +/**
  1.1913 +@publishedPartner
  1.1914 +@prototype 9.5
  1.1915 +
  1.1916 +Request a structure containing information on a resource.
  1.1917 +
  1.1918 +@param aClientId    ID of the client which is requesting the resource information
  1.1919 +@param aResourceId  ID of the resource whose information is being requested.
  1.1920 +@param aInfo        A pointer to descriptor containing resource information
  1.1921 +                    structure (TPowerResourceInfoV01) to be filled in
  1.1922 +                    with the requested resource information. The client must
  1.1923 +                    create the descriptor in kernel stack or heap.
  1.1924 +
  1.1925 +@return KErrNone if the operation was successful
  1.1926 +        KErrAccessDenied if the client ID could not be found in the current list
  1.1927 +                         of registered clients or if the client was registered to be 
  1.1928 +						 thread relative and this API is not called from the same thread.
  1.1929 +        KErrNotFound if this resource ID could not be found in the current list
  1.1930 +                     of controllable resource.
  1.1931 +        KErrArgument if aInfo is NULL or size of descriptor passed is less than size of
  1.1932 +					 TPowerResourceInfoV01.
  1.1933 +@pre Interrupts must be enabled
  1.1934 +@pre Kernel must be unlocked
  1.1935 +@pre No fast mutex can be held
  1.1936 +@pre Call in a thread context but not from null thread or DFC thread1
  1.1937 +@pre Can be used in a device driver
  1.1938 +*/
  1.1939 +TInt DPowerResourceController::GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo)
  1.1940 +	{
  1.1941 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetResourceInfo"));
  1.1942 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("CallingClientId = 0x%x, ResourceId = %d", aClientId, aResourceId));
  1.1943 +	DThread& thread = Kern::CurrentThread();	
  1.1944 +	CHECK_CONTEXT(thread)
  1.1945 +	if(!aInfo)
  1.1946 +		return KErrArgument;
  1.1947 +	SPowerResourceClient* pC = NULL;
  1.1948 +	Lock();
  1.1949 +	VALIDATE_CLIENT(thread);
  1.1950 +	TDes8* buf = (TDes8*)aInfo;
  1.1951 +	TInt r = KErrNone;
  1.1952 +	DStaticPowerResource *pR = NULL; 
  1.1953 +
  1.1954 +	//Validate buffer size
  1.1955 +	if((TUint)(buf->MaxLength() - buf->Length()) < sizeof(TPowerResourceInfoV01))
  1.1956 +	   UNLOCK_RETURN(KErrArgument);
  1.1957 +
  1.1958 +#ifndef PRM_ENABLE_EXTENDED_VERSION
  1.1959 +	if((!aResourceId) || (aResourceId > iStaticResourceArrayEntries))
  1.1960 +		UNLOCK_RETURN(KErrNotFound);
  1.1961 +	//Get resource from static resource array. 0(1) operation.
  1.1962 +	pR = iStaticResourceArray[aResourceId-1];
  1.1963 +	if(!pR)
  1.1964 +		{
  1.1965 +		UNLOCK_RETURN(KErrNotFound);
  1.1966 +		}
  1.1967 +#else
  1.1968 +	if(!aResourceId)
  1.1969 +		{
  1.1970 +		__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetResourceInfo, return value = %d", KErrNotFound));
  1.1971 +		UNLOCK_RETURN(KErrNotFound);
  1.1972 +		}
  1.1973 +	//Get resource from corresponding container
  1.1974 +	GET_RESOURCE_FROM_LIST(aResourceId, pR) 
  1.1975 +#endif
  1.1976 +	//Update resource info
  1.1977 +	TPowerResourceInfoBuf01 infoBuf;
  1.1978 +	r = pR->GetInfo((TDes8*)infoBuf.Ptr());
  1.1979 +	//Update ResourceId
  1.1980 +	((TPowerResourceInfoV01*)infoBuf.Ptr())->iResourceId = aResourceId;
  1.1981 +	if(r == KErrNone)
  1.1982 +	   buf->Append(infoBuf);
  1.1983 +	UNLOCK_RETURN(r);
  1.1984 +	}
  1.1985 +
  1.1986 +/**
  1.1987 +@publishedPartner
  1.1988 +@prototype 9.5
  1.1989 +
  1.1990 +Request number of resources the specified client (aTargetClientId) has
  1.1991 +requirement on resource level. Client ID starts from 1, so if 0 is specified in
  1.1992 +aTargetClientId, returns the number of controllable resources registered with PRM.
  1.1993 +
  1.1994 +@param aClientId ID of the client which is requesting the number of resources
  1.1995 +                 the specified client (aTargetClientId) holds requirement on
  1.1996 +                 resource level change.
  1.1997 +@param aTargetClientId ID of the client. The number of resources on which it
  1.1998 +                       has requirement on resource level change is requested.
  1.1999 +@param aNumResource Updated with the number of resources the specified client
  1.2000 +                    has requirement on resource level change, if valid client
  1.2001 +                    ID is passed. If client ID is 0, updates the total number
  1.2002 +                    of resources registered with resource manager.
  1.2003 +
  1.2004 +@return KErrNone if the operation was successful.
  1.2005 +        KErrAccessDenied if the client ID (aClientId) could not be found in the
  1.2006 +                         current list of registered clients or if the client was registered
  1.2007 +						 to be thread relative and this API is not called from the same thread. 
  1.2008 +        KErrNotFound if the client ID (aTargetClientId) could not be found in the
  1.2009 +                     current list of registered clients and is not 0.
  1.2010 +
  1.2011 +@pre Interrupts must be enabled
  1.2012 +@pre Kernel must be unlocked
  1.2013 +@pre No fast mutex can be held
  1.2014 +@pre Call in a thread context but not from null thread or DFC thread1
  1.2015 +@pre Can be used in a device driver
  1.2016 +*/
  1.2017 +TInt DPowerResourceController::GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResource)
  1.2018 +	{
  1.2019 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetNumResourcesInUseByClient"));
  1.2020 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("CallingClientId = 0x%x, TargetClientId = 0x%x", aClientId, aTargetClientId));
  1.2021 +	DThread& thread = Kern::CurrentThread();	
  1.2022 +	CHECK_CONTEXT(thread)
  1.2023 +	SPowerResourceClient* pC = NULL;
  1.2024 +	Lock();
  1.2025 +	VALIDATE_CLIENT(thread);
  1.2026 +	//Special case, return number of resources registered resource controller.
  1.2027 +	if(!aTargetClientId)
  1.2028 +		{
  1.2029 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2030 +		aNumResource = iStaticResourceCount + iDynamicResourceCount + iStaticResDependencyCount + 
  1.2031 +			                                                          iDynamicResDependencyCount; 
  1.2032 +#else
  1.2033 +		aNumResource = iStaticResourceCount;
  1.2034 +#endif
  1.2035 +		__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetNumResourcesInUseByClient, numResources = %d", aNumResource));
  1.2036 +		UNLOCK_RETURN(KErrNone);
  1.2037 +		}
  1.2038 +	GET_TARGET_CLIENT();
  1.2039 +	SPowerResourceClientLevel* pCL = pC->iLevelList;
  1.2040 +	aNumResource = 0;
  1.2041 +	while(pCL)
  1.2042 +		{
  1.2043 +		aNumResource++;
  1.2044 +		pCL = pCL->iNextInList;
  1.2045 +		}
  1.2046 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetNumResourcesInUseByClient, numResources = %d", aNumResource));
  1.2047 +	UNLOCK_RETURN(KErrNone);
  1.2048 +	}
  1.2049 +
  1.2050 +/**
  1.2051 +@publishedPartner
  1.2052 +@prototype 9.5
  1.2053 +
  1.2054 +Request information on resources.
  1.2055 +If client ID (aTargetClientId) is valid, aInfo is updated with the information of the resources 
  1.2056 +this client hold requirement on the resource level.
  1.2057 +If client ID (aTargetClientId) is 0, aInfo is updated with the information of the resources 
  1.2058 +registered with resource controller.
  1.2059 +Number of resource information updated will be equal or less than the number specified in aNumResources.
  1.2060 +
  1.2061 +@param aClientId   ID of the client which is requesting the resource information.
  1.2062 +@param aTargetClientId ID of the client. The information of all the resources on
  1.2063 +                       which it has requirement on resource level change is requested.
  1.2064 +                       Client ID starts from 1, so calling this API with client ID 0 will
  1.2065 +                       fill the details of all the controllable resource registered with
  1.2066 +                       resource manager.
  1.2067 +@param aNumResources   Number of resource whose information needs to be filled in aInfo i.e,
  1.2068 +                       it specifies the size of aInfo array.
  1.2069 +@param aInfo           A pointer to an array of descriptor containing an information structure
  1.2070 +                       (TPowerResourceInfoV01) to be filled in with the information
  1.2071 +                       on the resources. It will be assumed that array allocated will be equal
  1.2072 +                       to the number passed in aNumResources. The client must create the array
  1.2073 +                       in Kernel stack or heap.
  1.2074 +
  1.2075 +@return KErrNone if the operation was successful
  1.2076 +        KErrAccessDenied if client ID (aClientId) could not be found in the registered
  1.2077 +                         client list or if the client was registered to be thread relative
  1.2078 +						 and this API is not called from the same thread. 
  1.2079 +        KErrNotFound if client ID (aTargetClientId) could not be found in the current list
  1.2080 +                     of registered client and is also not 0.
  1.2081 +        KErrArgument if aNumResources is 0 or aInfo is NULL or if size of aInfo is not sufficient
  1.2082 +				     to hold the resource information of number of resources specified in aNumResources.
  1.2083 +
  1.2084 +@pre Interrupts must be enabled
  1.2085 +@pre Kernel must be unlocked
  1.2086 +@pre No fast mutex can be held
  1.2087 +@pre Call in a thread context but not from null thread or DFC thread1
  1.2088 +@pre Can be used in a device driver
  1.2089 +*/
  1.2090 +TInt DPowerResourceController::GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, 
  1.2091 +															    TUint& aNumResources, TAny* anInfo)
  1.2092 +	{
  1.2093 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetInfoOnResourcesInUseByClient"));
  1.2094 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("CallingClientId = 0x%x, TargetClientId = 0x%x, NumResources = %d", \
  1.2095 +		                                                            aClientId, aTargetClientId, aNumResources));
  1.2096 +	DThread& thread = Kern::CurrentThread();	
  1.2097 +	CHECK_CONTEXT(thread)
  1.2098 +	if(!anInfo || !aNumResources)
  1.2099 +		return KErrArgument;
  1.2100 +	SPowerResourceClient* pC = NULL;
  1.2101 +	Lock();
  1.2102 +	VALIDATE_CLIENT(thread);
  1.2103 +	DStaticPowerResource* pR = NULL;
  1.2104 +    TDes8 *pInfo = (TDes8*)anInfo;
  1.2105 +    if((TUint)(pInfo->MaxLength() - pInfo->Length()) < (sizeof(TPowerResourceInfoV01) * aNumResources))
  1.2106 +         UNLOCK_RETURN(KErrArgument);
  1.2107 +    TPowerResourceInfoBuf01 buf;
  1.2108 +
  1.2109 +	TUint16 count = 0;
  1.2110 +	TInt r = KErrNone;
  1.2111 +	//Special case, if aTargetClientId is 0 fill with all the resource
  1.2112 +	if(!aTargetClientId)
  1.2113 +		{
  1.2114 +		TUint numResources = aNumResources;
  1.2115 +#ifndef PRM_ENABLE_EXTENDED_VERSION
  1.2116 +		aNumResources = iStaticResourceCount;
  1.2117 +#else
  1.2118 +		aNumResources = iStaticResourceCount + iDynamicResourceCount + iStaticResDependencyCount + 
  1.2119 +			                                                           iDynamicResDependencyCount;
  1.2120 +#endif
  1.2121 +		UnLock();
  1.2122 +		while(count < iStaticResourceArrayEntries)
  1.2123 +			{
  1.2124 +			if(numResources <=0)
  1.2125 +				return KErrNone;
  1.2126 +			pR = iStaticResourceArray[count++];
  1.2127 +			if(!pR)
  1.2128 +				continue;
  1.2129 +            r = pR->GetInfo((TDes8*)buf.Ptr());
  1.2130 +			if(r != KErrNone)
  1.2131 +				return r;
  1.2132 +            //Update Resource Id.
  1.2133 +            ((TPowerResourceInfoV01*)buf.Ptr())->iResourceId = count;
  1.2134 +			pInfo->Append(buf);
  1.2135 +			numResources--;
  1.2136 +			}	
  1.2137 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2138 +		count = 0;
  1.2139 +		while(count < iStaticResDependencyCount)
  1.2140 +			{
  1.2141 +			if(count >= numResources)
  1.2142 +				return KErrNone;
  1.2143 +			pR = iStaticResDependencyArray[count++];
  1.2144 +			r = pR->GetInfo((TDes8*)buf.Ptr());
  1.2145 +			//Update Resource Id.
  1.2146 +			((TPowerResourceInfoV01*)buf.Ptr())->iResourceId = ((DStaticPowerResourceD*)pR)->iResourceId;
  1.2147 +			if(r != KErrNone)
  1.2148 +				return r;
  1.2149 +			pInfo->Append(buf);
  1.2150 +			}
  1.2151 +		numResources -= iStaticResDependencyCount;
  1.2152 +		if((!numResources) || (!iDynamicResourceCount && !iDynamicResDependencyCount))
  1.2153 +			return r;
  1.2154 +		Lock();
  1.2155 +		TUint resCount = 0;
  1.2156 +		for(count = 0; count < iDynamicResourceList.Allocd(); count++)
  1.2157 +			{
  1.2158 +			pR = iDynamicResourceList[count];
  1.2159 +			if(!pR)
  1.2160 +				continue;
  1.2161 +			if((resCount >= iDynamicResourceCount) || (resCount >= numResources))
  1.2162 +				UNLOCK_RETURN(KErrNone);
  1.2163 +			r = pR->GetInfo((TDes8*)buf.Ptr());  
  1.2164 +			if(r != KErrNone)
  1.2165 +				UNLOCK_RETURN(r);
  1.2166 +			((TPowerResourceInfoV01*)buf.Ptr())->iResourceId = ((DDynamicPowerResource*)pR)->iResourceId;
  1.2167 +			pInfo->Append(buf);
  1.2168 +			resCount++;
  1.2169 +			}
  1.2170 +		numResources -= resCount;
  1.2171 +		resCount = 0;
  1.2172 +		for(count = 0; count < iDynamicResDependencyList.Allocd(); count++) 
  1.2173 +			{
  1.2174 +			pR = iDynamicResDependencyList[count];
  1.2175 +			if(!pR)
  1.2176 +				continue;
  1.2177 +			if((resCount >= iDynamicResDependencyCount) || (resCount >= numResources))
  1.2178 +				UNLOCK_RETURN(KErrNone);
  1.2179 +			r = pR->GetInfo((TDes8*)buf.Ptr());
  1.2180 +			if(r != KErrNone)
  1.2181 +				UNLOCK_RETURN(r);
  1.2182 +			((TPowerResourceInfoV01*)buf.Ptr())->iResourceId = ((DDynamicPowerResourceD*)pR)->iResourceId;
  1.2183 +			pInfo->Append(buf);
  1.2184 +			resCount++;
  1.2185 +			}
  1.2186 +		UnLock();
  1.2187 +#endif
  1.2188 +		return r;
  1.2189 +		}
  1.2190 +	GET_TARGET_CLIENT();
  1.2191 +	SPowerResourceClientLevel* pCL = pC->iLevelList;
  1.2192 +	for (count= 0; pCL; count++, pCL = pCL->iNextInList)
  1.2193 +		{
  1.2194 +		if(count >= aNumResources)
  1.2195 +			continue;
  1.2196 +#ifndef PRM_ENABLE_EXTENDED_VERSION
  1.2197 +		pR = iStaticResourceArray[pCL->iResourceId-1];
  1.2198 +#else
  1.2199 +		GET_RESOURCE_FROM_LIST(pCL->iResourceId, pR);
  1.2200 +#endif
  1.2201 +		r = pR->GetInfo((TDes8*)buf.Ptr());
  1.2202 +        //Update Resource Id.
  1.2203 +        ((TPowerResourceInfoV01*)buf.Ptr())->iResourceId = pCL->iResourceId;
  1.2204 +		if(r != KErrNone)
  1.2205 +			UNLOCK_RETURN(r);
  1.2206 +		pInfo->Append(buf);
  1.2207 +		}
  1.2208 +	aNumResources = count;
  1.2209 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetInfoOnResourcesInUseByClient, AcutalNoOfResources = %d", aNumResources));
  1.2210 +	UNLOCK_RETURN(KErrNone);
  1.2211 +	}
  1.2212 +
  1.2213 +/**
  1.2214 +@publishedPartner
  1.2215 +@prototype 9.5
  1.2216 +
  1.2217 +Request number of clients which has requirements on the resource level of the specified
  1.2218 +resource. Resource ID starts from 1, so 0 can be used to get the number of clients
  1.2219 +registered with resource manager.
  1.2220 +
  1.2221 +@param aClientId         ID of the client which is requesting number of clients
  1.2222 +                         holding requirement on specified resource.
  1.2223 +@param aResourceId       ID of the resource. 
  1.2224 +@param aNumClient        This is updated with number of clients having a requirement
  1.2225 +                         on resource level if valid resource ID is specified.
  1.2226 +                         If resource ID is 0, then it is updated with number of clients
  1.2227 +                         registered with PRM.
  1.2228 +
  1.2229 +@return  KErrNone if the operation was successful
  1.2230 +         KErrAccessDenied if the client ID could not found in the current list of
  1.2231 +                          registered clients or if the client was registered to be thread 
  1.2232 +						  relative and this API is not called from the same thread. 
  1.2233 +         KErrNotFound     If this resource ID could not be found in the current list
  1.2234 +                          of registered resource and is also not 0.
  1.2235 +
  1.2236 +@pre Interrupts must be enabled
  1.2237 +@pre Kernel must be unlocked
  1.2238 +@pre No fast mutex can be held
  1.2239 +@pre Call in a thread context but not from null thread or DFC thread1
  1.2240 +@pre Can be used in a device driver
  1.2241 +*/
  1.2242 +TInt DPowerResourceController::GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients)
  1.2243 +	{
  1.2244 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetNumClientsUsingResource"));
  1.2245 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("ClientId = 0x%x, ResourceId = %d", aClientId, aResourceId));
  1.2246 +	DThread& thread = Kern::CurrentThread();	
  1.2247 +	CHECK_CONTEXT(thread)
  1.2248 +	SPowerResourceClient* pC = NULL;
  1.2249 +	Lock();
  1.2250 +	VALIDATE_CLIENT(thread);
  1.2251 +	if(!aResourceId)
  1.2252 +		{
  1.2253 +		//Special case return the number of clients registered with resource controller.
  1.2254 +		aNumClients = iClientCount + iUserSideClientCount;
  1.2255 +		UNLOCK_RETURN(KErrNone);
  1.2256 +		}
  1.2257 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2258 +	DStaticPowerResource* pR = NULL;
  1.2259 +	GET_RESOURCE_FROM_LIST(aResourceId, pR) 
  1.2260 +#else
  1.2261 +	if(aResourceId > iStaticResourceArrayEntries)
  1.2262 +		UNLOCK_RETURN(KErrNotFound);
  1.2263 +	DStaticPowerResource* pR = iStaticResourceArray[aResourceId-1];
  1.2264 +	if(!pR)
  1.2265 +		UNLOCK_RETURN(KErrNotFound);
  1.2266 +#endif
  1.2267 +	aNumClients = 0;
  1.2268 +	for(SDblQueLink*pCL = pR->iClientList.First(); pCL != &pR->iClientList.iA; pCL=pCL->iNext)
  1.2269 +	   aNumClients++;
  1.2270 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetNumClientsUsingResource, NumClients = %d", aNumClients));
  1.2271 +	UNLOCK_RETURN(KErrNone);
  1.2272 +	}
  1.2273 +
  1.2274 +/**
  1.2275 +@publishedPartner
  1.2276 +@prototype 9.5
  1.2277 +
  1.2278 +Request information on clients
  1.2279 +If resource ID is valid, aInfo is updated with the information of the clients
  1.2280 +which have a requirement on the resource level for the specified resource
  1.2281 +If resource ID is 0, aInfo is updated with the information of the clients registered
  1.2282 +with resource manager, starting from client ID 1.
  1.2283 +The number of clients for which information will be provided will be equal to or less 
  1.2284 +than the number specified in aNumClients.
  1.2285 +@param aClientId        ID of the client which is requesting the information on
  1.2286 +                        the clients which holds requirement on specified
  1.2287 +                        resource's level change.
  1.2288 +@param aResourceId      Id of the resource.
  1.2289 +@param aNumClients		Number of clients whose information needs to be filled in aInfo
  1.2290 +						i.e., it specifies the size of aInfo array.
  1.2291 +@param aInfo            A pointer to an array of descriptor containing an information
  1.2292 +                        structure (TPowerClientInfoV01) to be filled in with
  1.2293 +                        the information on the client. It will be assumed that array
  1.2294 +                        allocated will be equal to the number passed in aNumClients.
  1.2295 +                        The Client must create the array of descriptors in kernel stack
  1.2296 +                        or heap.
  1.2297 +
  1.2298 +@return KErrNone if the operation was successful.
  1.2299 +        KErrNotFound if resource ID could not be found in the registered resource list and is not 0.
  1.2300 +		KErrAccessDenied if client ID (aClientId) could not be found in the registered client
  1.2301 +						 list or if the client was registered to be thread relative and this API is not
  1.2302 +						 called from the same thread.
  1.2303 +        KErrArgument if aNumClients is 0 or aInfo is NULL or if size of aInfo is not sufficient to hold
  1.2304 +					 client information of specified client number in aNumClients.
  1.2305 +
  1.2306 +@pre Interrupts must be enabled
  1.2307 +@pre Kernel must be unlocked
  1.2308 +@pre No fast mutex can be held
  1.2309 +@pre Call in a thread context but not from null thread or DFC thread1
  1.2310 +@pre Can be used in a device driver
  1.2311 +*/
  1.2312 +TInt DPowerResourceController::GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, 
  1.2313 +															  TUint& aNumClients, TAny* anInfo)
  1.2314 +	{
  1.2315 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetInfoOnClientsUsingResource"));
  1.2316 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("ClientId = 0x%x, ResourceId = %d, NumClients = %d", \
  1.2317 +		                                                      aClientId, aResourceId, aNumClients));
  1.2318 +	DThread& thread = Kern::CurrentThread();	
  1.2319 +	CHECK_CONTEXT(thread)
  1.2320 +	if(!anInfo || !aNumClients)
  1.2321 +		return KErrArgument;
  1.2322 +	SPowerResourceClient* pC = NULL;
  1.2323 +	Lock();
  1.2324 +	VALIDATE_CLIENT(thread);
  1.2325 +    TDes8 *pInfo = (TDes8*)anInfo;
  1.2326 +    if((TUint)(pInfo->MaxLength() - pInfo->Length()) < (sizeof(TPowerClientInfoV01) * aNumClients))
  1.2327 +        UNLOCK_RETURN(KErrArgument);
  1.2328 +    TPowerClientInfoV01 info;
  1.2329 +	if(aResourceId == 0)
  1.2330 +		{
  1.2331 +        TUint16 count = 0, resCount = 0;
  1.2332 +        for(count = 0; count < iClientList.Allocd(); count++)
  1.2333 +		    {
  1.2334 +            if((resCount >= iClientCount) || (resCount >= aNumClients))
  1.2335 +				break;
  1.2336 +            pC = iClientList[count];
  1.2337 +            if(!pC)
  1.2338 +				continue;
  1.2339 +            resCount++;
  1.2340 +            info.iClientId = pC->iClientId;
  1.2341 +            info.iClientName = (TDesC8*)pC->iName;
  1.2342 +            pInfo->Append(TPckgC<TPowerClientInfoV01>(info));
  1.2343 +	        }
  1.2344 +        aNumClients -= resCount;
  1.2345 +        resCount = 0;
  1.2346 +        for(count = 0; count < iUserSideClientList.Allocd(); count++)
  1.2347 +	        {
  1.2348 +            if((resCount >= iUserSideClientCount) || (resCount >= aNumClients))
  1.2349 +				break;
  1.2350 +            pC = iUserSideClientList[count];
  1.2351 +            if(!pC)
  1.2352 +				continue;
  1.2353 +            resCount++;
  1.2354 +            info.iClientId = pC->iClientId;
  1.2355 +            info.iClientName = (TDesC8*)pC->iName;
  1.2356 +            pInfo->Append(TPckgC<TPowerClientInfoV01>(info));
  1.2357 +			}
  1.2358 +		aNumClients = iClientCount + iUserSideClientCount;
  1.2359 +		UNLOCK_RETURN(KErrNone);
  1.2360 +		}
  1.2361 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2362 +	DStaticPowerResource* pR = NULL;
  1.2363 +	GET_RESOURCE_FROM_LIST(aResourceId, pR) 
  1.2364 +#else
  1.2365 +	if(aResourceId > iStaticResourceArrayEntries)
  1.2366 +		UNLOCK_RETURN(KErrNotFound);
  1.2367 +	DStaticPowerResource* pR = iStaticResourceArray[aResourceId-1];
  1.2368 +	if(!pR)
  1.2369 +		UNLOCK_RETURN(KErrNotFound);
  1.2370 +#endif
  1.2371 +	SPowerResourceClientLevel* pCL = NULL;
  1.2372 +    TUint c = 0;
  1.2373 +	for(SDblQueLink* pRC = pR->iClientList.First(); pRC != &pR->iClientList.iA; pRC = pRC->iNext, c++)
  1.2374 +		{
  1.2375 +		if(c >= aNumClients)
  1.2376 +			continue;
  1.2377 +		pCL = (SPowerResourceClientLevel*)pRC;
  1.2378 +		if(pCL->iClientId & USER_SIDE_CLIENT_BIT_MASK)
  1.2379 +			pC = iUserSideClientList[(TUint16)(pCL->iClientId & ID_INDEX_BIT_MASK)];
  1.2380 +		else
  1.2381 +			pC = iClientList[(TUint16)(pCL->iClientId & ID_INDEX_BIT_MASK)];
  1.2382 +		info.iClientId = pC->iClientId;
  1.2383 +		info.iClientName =  (TDesC8*)pC->iName;
  1.2384 +        pInfo->Append(TPckgC<TPowerClientInfoV01>(info));
  1.2385 +		}
  1.2386 +	aNumClients = c;
  1.2387 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetInfoOnClientsUsingResource, NumClients = %d", aNumClients));
  1.2388 +	UNLOCK_RETURN(KErrNone);
  1.2389 +	}
  1.2390 +
  1.2391 +/**
  1.2392 +@publishedPartner
  1.2393 +@prototype 9.5
  1.2394 +
  1.2395 +Request changing the state of a resource
  1.2396 +NOTE: If a resource callback is specified for instantaneous resource, then callback
  1.2397 +      will be called after resource change and will be executed in the context of the
  1.2398 +      client thread.
  1.2399 +      If a resource callback is specified for long latency reosurces, then it will be
  1.2400 +      executed asynchronously.When the request is accepted the API returns immediately
  1.2401 +	  and the calling thread is unblocked: the callback (called in the client's context) 
  1.2402 +	  will be invoked when the resource change finally takes place.
  1.2403 +      If aCb is not specified (NULL by default) the API executes synchronously and will
  1.2404 +      only return when the resource change has taken place for long latency resource.
  1.2405 +      The client thread is blocked throughout
  1.2406 +      When state change for a shared resource is requested, only minimum state that
  1.2407 +      satisfy the requirement is guaranteed and it is not guaranteed for the absolute
  1.2408 +      value change.
  1.2409 +
  1.2410 +@param aClientId   ID of the client which is requesting the resource change.
  1.2411 +@param aResourceId ID of the resource whose state is to be changed.
  1.2412 +@param aNewState   The new state of the resource. This could be a binary value for a
  1.2413 +                   binary resource, an integer level for a multilevel resource or some
  1.2414 +                   platform specific token for a multi-property resource.
  1.2415 +@param aCb         For Long latency resource
  1.2416 +                       A pointer to a resource callback object which encapsulates a
  1.2417 +                       callback function to be called whenever the resource state change
  1.2418 +                       happens (if left NULL the API will execute synchrounously).
  1.2419 +                   For Instantaneous resource
  1.2420 +                       A pointer to a resource callback object which encapsulates a callback
  1.2421 +                       function to be called after resource change. This executes in the
  1.2422 +                       context of the client thread.
  1.2423 +
  1.2424 +@return KErrNone   If the API is to be executed synchronously it indicates the change was
  1.2425 +                   successful, if the API is to be executed asynchronously it indicates
  1.2426 +                   the request to change the resource state has been accepted.
  1.2427 +        KErrNotFound if the resource ID could not be found in the current list of
  1.2428 +                     controllable resources.
  1.2429 +        KErrAccessDenied if the client ID could not be found in the list of
  1.2430 +                         registered clients or if the client was registered to be thread 
  1.2431 +						 relative and this API is not called from the same thread or if the
  1.2432 +						 resource is single user resource and another client is already holding 
  1.2433 +						 the resource.
  1.2434 +        KErrNotReady if the request is issued before the resource controller completes its
  1.2435 +                     internal initialisation.
  1.2436 +        KErrUnderflow if the client has exceeded the reserved number of
  1.2437 +                      SPowerResourceClientLevel and the free pool is empty or if it is
  1.2438 +                      an asynchronous operation on a long latency resource and the client has 
  1.2439 +					  exceeded the reserved number of TPowerRequest and the free pool is empty.
  1.2440 +		KErrArgument if requested level is out of range (outside of min and max levels).
  1.2441 +		KErrCorrupt  if internal data structure is corrupted.
  1.2442 +		KErrPermissionDenied if the requested state of the resource is not accepted by its dependents. 
  1.2443 +							 This error is valid only for dependent resource state change in extended version
  1.2444 +							 of PRM.
  1.2445 +
  1.2446 +@pre Interrupts must be enabled
  1.2447 +@pre Kernel must be unlocked
  1.2448 +@pre No fast mutex can be held
  1.2449 +@pre Call in a thread context but not from null thread or DFC thread1
  1.2450 +@pre Can be used in a device driver
  1.2451 +@pre Do not call synchronous version from DFC thread 0 for long latency resource 
  1.2452 +*/
  1.2453 +TInt DPowerResourceController::ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, 
  1.2454 +												                                TPowerResourceCb* aCb)
  1.2455 +	{
  1.2456 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::ChangeResourceState"));
  1.2457 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("ClientId = 0x%x, ResourceId = %d, NewState = %d", aClientId, \
  1.2458 +		                                                                          aResourceId, aNewState));
  1.2459 +	DThread& thread = Kern::CurrentThread();	
  1.2460 +	CHECK_CONTEXT(thread)
  1.2461 +	if(iInitialised <= EResConCreated)
  1.2462 +		return KErrNotReady;
  1.2463 +	if(!aResourceId)
  1.2464 +		return KErrNotFound;
  1.2465 +	SPowerResourceClient* pC = NULL;
  1.2466 +	TInt r = KErrNone;
  1.2467 +	Lock();
  1.2468 +	VALIDATE_CLIENT(thread);
  1.2469 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2470 +	DStaticPowerResource *pR = NULL;
  1.2471 +	GET_RESOURCE_FROM_LIST(aResourceId, pR) 
  1.2472 +#else
  1.2473 +	if(aResourceId > iStaticResourceArrayEntries)
  1.2474 +		UNLOCK_RETURN(KErrNotFound);
  1.2475 +	DStaticPowerResource* pR = iStaticResourceArray[aResourceId-1];
  1.2476 +	if(!pR)
  1.2477 +		UNLOCK_RETURN(KErrNotFound);
  1.2478 +#endif
  1.2479 +	//Return if the resource is already in that state and client is also the same.
  1.2480 +	if((aNewState == pR->iCachedLevel) && ((TInt)aClientId == pR->iLevelOwnerId))
  1.2481 +		UNLOCK_RETURN(KErrNone);
  1.2482 +
  1.2483 +	
  1.2484 +	PRM_CLIENT_CHANGE_STATE_START_TRACE
  1.2485 +	//If long latency resource requested synchronously from DFC thread 0 Panic
  1.2486 +
  1.2487 +    const TDesC8* pDfc0 = &KDfcThread0Name;
  1.2488 +	if((pR->LatencySet() && !aCb) && !(pDfc0->Compare(*(TDesC8*)thread.iName)))
  1.2489 +		{
  1.2490 +		UnLock();
  1.2491 +		Panic(ECalledFromDfcThread0);
  1.2492 +		}
  1.2493 +	if(!pR->Usage() && !pR->iClientList.IsEmpty())
  1.2494 +		{
  1.2495 +		SPowerResourceClientLevel* pCL = (SPowerResourceClientLevel*)pR->iClientList.First();
  1.2496 +		if((pCL != NULL) && (pCL->iClientId != pC->iClientId))
  1.2497 +			{
  1.2498 +			r = KErrAccessDenied;
  1.2499 +			PRM_CLIENT_CHANGE_STATE_END_TRACE
  1.2500 +			UNLOCK_RETURN(r);
  1.2501 +			}
  1.2502 +		}
  1.2503 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2504 +	if(aResourceId & KIdMaskDynamic)
  1.2505 +		{
  1.2506 +		//Resource in the process of deregistration
  1.2507 +		if(((DDynamicPowerResource*)pR)->LockCount() == 0) 
  1.2508 +			{
  1.2509 +			r = KErrNotFound;
  1.2510 +			PRM_CLIENT_CHANGE_STATE_END_TRACE
  1.2511 +			UNLOCK_RETURN(r);
  1.2512 +			}
  1.2513 +		}
  1.2514 +#endif
  1.2515 +    //Validate requested level
  1.2516 +    TPowerResourceInfoBuf01 buf;
  1.2517 +    r = pR->GetInfo((TDes8*)buf.Ptr());
  1.2518 +    if(r != KErrNone)
  1.2519 +		{
  1.2520 +		PRM_CLIENT_CHANGE_STATE_END_TRACE
  1.2521 +		UNLOCK_RETURN(r);
  1.2522 +		}
  1.2523 +    TPowerResourceInfoV01 *pBuf = (TPowerResourceInfoV01*)buf.Ptr();
  1.2524 +    if(((pBuf->iMinLevel > pBuf->iMaxLevel) && ((aNewState > pBuf->iMinLevel) || (aNewState < pBuf->iMaxLevel))) 
  1.2525 +		    || ((pBuf->iMaxLevel > pBuf->iMinLevel) && ((aNewState > pBuf->iMaxLevel) || (aNewState < pBuf->iMinLevel))))
  1.2526 +		{
  1.2527 +        r = KErrArgument;
  1.2528 +        PRM_CLIENT_CHANGE_STATE_END_TRACE
  1.2529 +        UNLOCK_RETURN(r);
  1.2530 +		}
  1.2531 +
  1.2532 +	TPowerRequest* req;
  1.2533 +	SPowerRequest* pS=NULL;
  1.2534 +	if(pR->LatencySet() && aCb)
  1.2535 +		{
  1.2536 +		// Get request object from free pool, as it is long latency reosurce as client
  1.2537 +		// will be unblocked once message is sent to controller, so cant use thread message.
  1.2538 +		if(pC->iReservedRm ==0 && !iRequestPoolCount)
  1.2539 +			{
  1.2540 +            r = KErrUnderflow;
  1.2541 +            PRM_CLIENT_CHANGE_STATE_END_TRACE
  1.2542 +			UNLOCK_RETURN(r);
  1.2543 +			}
  1.2544 +
  1.2545 +		LIST_POP(iRequestPool, pS, iNext);
  1.2546 +		if(!pS)
  1.2547 +			UNLOCK_RETURN(KErrCorrupt); //This should not happen
  1.2548 +		if(pC->iReservedRm==0)
  1.2549 +			{
  1.2550 +			iRequestPoolCount--;
  1.2551 +			pC->iUnderFlowRmCount++;
  1.2552 +			}
  1.2553 +		else
  1.2554 +		    pC->iReservedRm--;
  1.2555 +		req=&pS->iRequest;
  1.2556 +		pC->iPendingReqCount++;
  1.2557 +		}
  1.2558 +	else
  1.2559 +        req=(TPowerRequest*)&TPowerRequest::Get();
  1.2560 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2561 +	if(aResourceId & KIdMaskDynamic)
  1.2562 +		((DDynamicPowerResource*)pR)->Lock();
  1.2563 +#endif
  1.2564 +	req->Level() = aNewState;
  1.2565 +	req->ResourceId() = aResourceId;
  1.2566 +	req->ClientId() = aClientId;
  1.2567 +	req->ReqType() = TPowerRequest::EChange;
  1.2568 +	req->Resource() = pR;
  1.2569 +	if(aCb)
  1.2570 +		{
  1.2571 +		aCb->iResult = KErrNone;
  1.2572 +		aCb->iResourceId = aResourceId;
  1.2573 +		aCb->iClientId = aClientId;
  1.2574 +		}
  1.2575 +	req->ResourceCb() = aCb;
  1.2576 +	if(pR->LatencySet())
  1.2577 +		{
  1.2578 +		UnLock();
  1.2579 +		if(aCb)
  1.2580 +			{
  1.2581 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2582 +			if (aCb->iResourceId & KIdMaskResourceWithDependencies) //Dependency resource
  1.2583 +				{
  1.2584 +				req->Send(iMsgQDependency); // Send the request to DFC thread.
  1.2585 +				return KErrNone;
  1.2586 +				}
  1.2587 +			else
  1.2588 +#endif
  1.2589 +				{
  1.2590 +				req->Send(iMsgQ); // Send the request to Resource Controler thread.
  1.2591 +				return KErrNone;
  1.2592 +				}
  1.2593 +			}
  1.2594 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2595 +		if(aResourceId & KIdMaskResourceWithDependencies) //Dependency resource
  1.2596 +			{
  1.2597 +			r = req->SendReceive(iMsgQDependency); // Send the request to DFC thread.
  1.2598 +			}
  1.2599 +#endif
  1.2600 +		else
  1.2601 +			{
  1.2602 +			r = req->SendReceive(iMsgQ); // Block till the controller completes with the request.
  1.2603 +			}
  1.2604 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2605 +		Lock();
  1.2606 +		if(aResourceId & KIdMaskDynamic)
  1.2607 +			((DDynamicPowerResource*)pR)->UnLock();
  1.2608 +		UnLock();
  1.2609 +#endif
  1.2610 +		return r;
  1.2611 +		}
  1.2612 +	if(pR->Usage())
  1.2613 +		{
  1.2614 +		r = CheckLevelAndAddClient(pC, req);
  1.2615 +		if((r != KErrNone)|| !req->RequiresChange())
  1.2616 +			{
  1.2617 +			req->Level() = pR->iCachedLevel;
  1.2618 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2619 +		    if(aResourceId & KIdMaskDynamic)
  1.2620 +				((DDynamicPowerResource*)pR)->UnLock();
  1.2621 +#endif
  1.2622 +			UnLock();
  1.2623 +			if(aCb)
  1.2624 +				{
  1.2625 +				//Invoke callback function
  1.2626 +				aCb->iCallback(req->ClientId(), aResourceId, req->Level(), pR->iLevelOwnerId, r, aCb->iParam);
  1.2627 +				//Mark the callback object to act properly during cancellation of this request.
  1.2628 +				aCb->iResult = KErrCompletion; 
  1.2629 +				}
  1.2630 +			PRM_CLIENT_CHANGE_STATE_END_TRACE
  1.2631 +			return(r);
  1.2632 +			}
  1.2633 +		}
  1.2634 +	else if(pR->iLevelOwnerId == -1)
  1.2635 +		{
  1.2636 +		/* Add client Level */
  1.2637 +		if(pC->iReservedCl<=0 && !iClientLevelPoolCount)
  1.2638 +			{
  1.2639 +			r = KErrUnderflow;
  1.2640 +			PRM_CLIENT_CHANGE_STATE_END_TRACE
  1.2641 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2642 +			if(aResourceId & KIdMaskDynamic)
  1.2643 +				((DDynamicPowerResource*)pR)->UnLock();
  1.2644 +#endif
  1.2645 +			UnLock();
  1.2646 +     		return(r);
  1.2647 +			}
  1.2648 +		SPowerResourceClientLevel* pSCL=NULL;
  1.2649 +		LIST_POP(iClientLevelPool, pSCL, iNextInList);
  1.2650 +		pSCL->iClientId=aClientId;
  1.2651 +		pSCL->iResourceId=aResourceId;
  1.2652 +		pSCL->iLevel=aNewState;
  1.2653 +		LIST_PUSH(pC->iLevelList, pSCL, iNextInList);
  1.2654 +		pR->iClientList.Add(pSCL);
  1.2655 +		if(pC->iReservedCl==0)
  1.2656 +			{
  1.2657 +			iClientLevelPoolCount--;
  1.2658 +			pC->iUnderFlowClCount++;
  1.2659 +			}
  1.2660 +		else
  1.2661 +		     pC->iReservedCl--;
  1.2662 +		}
  1.2663 +	else
  1.2664 +		{
  1.2665 +		//Update the level in the client list.
  1.2666 +		SPowerResourceClientLevel* pSCL = (SPowerResourceClientLevel*)pR->iClientList.First();
  1.2667 +		pSCL->iLevel = aNewState;
  1.2668 +		}
  1.2669 +	UnLock();
  1.2670 +	r = pR->DoRequest(*req);
  1.2671 +	Lock();
  1.2672 +	if(r==KErrNone)
  1.2673 +		{
  1.2674 +		//Notification to clients
  1.2675 +		CompleteNotifications(req->ClientId(), pR, req->Level(), r, aClientId, EFalse);
  1.2676 +		//Cache the state
  1.2677 +		pR->iCachedLevel=req->Level();
  1.2678 +		pR->iLevelOwnerId=req->ClientId();
  1.2679 +		//Update resource details for Idle
  1.2680 +		if(pR->iIdleListEntry)
  1.2681 +			{
  1.2682 +            pR->iIdleListEntry->iLevelOwnerId=req->ClientId();
  1.2683 +			pR->iIdleListEntry->iCurrentLevel=req->Level();
  1.2684 +			}
  1.2685 +		}
  1.2686 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2687 +	if(aResourceId & KIdMaskDynamic)
  1.2688 +		((DDynamicPowerResource*)pR)->UnLock();
  1.2689 +#endif
  1.2690 +	UnLock();
  1.2691 +	if(aCb)
  1.2692 +		{
  1.2693 +		//Invoke callback function
  1.2694 +		aCb->iCallback(req->ClientId(), aResourceId, req->Level(), pR->iLevelOwnerId, r, aCb->iParam);
  1.2695 +		aCb->iResult = KErrCompletion; //Mark the callback object to act properly during cancellation of this request.
  1.2696 +		}
  1.2697 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::ChangeResourceState, Level = %d", req->Level()));
  1.2698 +    PRM_CLIENT_CHANGE_STATE_END_TRACE
  1.2699 +    return r;
  1.2700 +	}
  1.2701 +
  1.2702 +/**
  1.2703 +@publishedPartner
  1.2704 +@prototype 9.5
  1.2705 +
  1.2706 +Request the state of the resource synchronously
  1.2707 +
  1.2708 +@param aClientId  ID of the client which is requesting the resource state.
  1.2709 +@param aResourceId ID of the resource whose state is being requested.
  1.2710 +@param aCached     If ETrue, cached value will be updated in aState.
  1.2711 +                   If EFalse, aState will be updated after the resource
  1.2712 +                   state is read from resource.
  1.2713 +@param aState      Returns the resource state if operation was successful. This
  1.2714 +                   could be a binary value for a binary resource, an integer level
  1.2715 +                   for a multilevel resource or some platform specific tolen for a
  1.2716 +                   multi-property resource.
  1.2717 +@param aLevelOwnerId Returns the Id of the client that is currently holding the resource.
  1.2718 +					 -1	is returned when no client is holding the resource.
  1.2719 +
  1.2720 +@return KErrNone   if operation was successful
  1.2721 +        KErrAccessDenied if the client ID could not be found in the current list
  1.2722 +                         of registered clients or if the client was registered to be thread
  1.2723 +						 relative and this API is not called from the same thread. 
  1.2724 +        KErrNotFound if this resource ID could not be found in the current list
  1.2725 +                     of controllable resources.
  1.2726 +        KErrNotReady if the request is issued before the resource controller completes
  1.2727 +                     its internal initialization.
  1.2728 +
  1.2729 +
  1.2730 +@pre Interrupts must be enabled
  1.2731 +@pre Kernel must be unlocked
  1.2732 +@pre No fast mutex can be held
  1.2733 +@pre Call in a thread context but not from null thread or DFC thread1
  1.2734 +@pre Can be used in a device driver
  1.2735 +@pre Do not call from DFC thread 0 for long latency resource with caching disabled.
  1.2736 +*/
  1.2737 +TInt DPowerResourceController::GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, 
  1.2738 +																						TInt& aLevelOwnerId)
  1.2739 +	{
  1.2740 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetResourceState(synchronous)"));
  1.2741 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("ClientId = 0x%x, ResourceId = %d, Cached = %d", aClientId, aResourceId, aCached));
  1.2742 +
  1.2743 +	DThread& thread = Kern::CurrentThread();	
  1.2744 +	CHECK_CONTEXT(thread)
  1.2745 +	if(iInitialised <= EResConCreated) 
  1.2746 +		return KErrNotReady;
  1.2747 +	SPowerResourceClient* pC = NULL;
  1.2748 +	TInt r = KErrNone;
  1.2749 +	Lock();
  1.2750 +	VALIDATE_CLIENT(thread);
  1.2751 +	if(!aResourceId)
  1.2752 +		UNLOCK_RETURN(KErrNotFound);
  1.2753 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2754 +	DStaticPowerResource *pR = NULL;
  1.2755 +	GET_RESOURCE_FROM_LIST(aResourceId, pR) 
  1.2756 +	if(aResourceId & KIdMaskDynamic)
  1.2757 +		{
  1.2758 +		if(((DDynamicPowerResource*)pR)->LockCount() == 0)
  1.2759 +			UNLOCK_RETURN(KErrNotFound);
  1.2760 +		}
  1.2761 +#else
  1.2762 +	if(aResourceId > iStaticResourceArrayEntries)
  1.2763 +		UNLOCK_RETURN(KErrNotFound);
  1.2764 +	DStaticPowerResource *pR = iStaticResourceArray[aResourceId-1];
  1.2765 +	if(!pR)
  1.2766 +		UNLOCK_RETURN(KErrNotFound);
  1.2767 +#endif
  1.2768 +	PRM_RESOURCE_GET_STATE_START_TRACE
  1.2769 +	//Panic if long latency resource called to execute synchronously from DFC thread0
  1.2770 +	const TDesC8* pDfc0 = &KDfcThread0Name;
  1.2771 +	if((!aCached && pR->LatencyGet()) && !(pDfc0->Compare(*(TDesC*)thread.iName)))
  1.2772 +		{
  1.2773 +		UnLock();
  1.2774 +		Panic(ECalledFromDfcThread0);
  1.2775 +		}
  1.2776 +	if(aCached)
  1.2777 +		{
  1.2778 +		//Return the cached value.
  1.2779 +		aState = pR->iCachedLevel;
  1.2780 +		aLevelOwnerId = pR->iLevelOwnerId;
  1.2781 +        PRM_RESOURCE_GET_STATE_END_TRACE
  1.2782 +    	UNLOCK_RETURN(KErrNone);
  1.2783 +		}
  1.2784 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2785 +	if(aResourceId & KIdMaskDynamic)
  1.2786 +		((DDynamicPowerResource*)pR)->Lock();
  1.2787 +#endif
  1.2788 +	//Call from thread Id.
  1.2789 +	TPowerRequest* req = (TPowerRequest*)&TPowerRequest::Get();
  1.2790 +	req->ResourceId() = aResourceId;
  1.2791 +	req->ReqType() = TPowerRequest::EGet;
  1.2792 +	req->ClientId() = aClientId;
  1.2793 +	req->Resource() = pR;
  1.2794 +	req->ResourceCb() = NULL;
  1.2795 +	if(pR->LatencyGet())
  1.2796 +		{
  1.2797 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2798 +		if(	req->ResourceId() & KIdMaskResourceWithDependencies ) // Dependency Resource
  1.2799 +			{
  1.2800 +			UnLock();
  1.2801 +			req->SendReceive(iMsgQDependency); //Send the request to DFC Thread
  1.2802 +			Lock();
  1.2803 +			}
  1.2804 +		else  // Plain resource
  1.2805 +#endif
  1.2806 +			{
  1.2807 +			UnLock();
  1.2808 +			req->SendReceive(iMsgQ);
  1.2809 +			Lock();
  1.2810 +			}
  1.2811 +		}
  1.2812 +	else
  1.2813 +		{
  1.2814 +		UnLock();
  1.2815 +		r = pR->DoRequest(*req); // Call PSL to get the state of resource.
  1.2816 +		Lock();
  1.2817 +		if(r==KErrNone)
  1.2818 +			{
  1.2819 +			//Update the cache value and cache for idle thread usage if requested for this resource.
  1.2820 +			pR->iCachedLevel=req->Level();
  1.2821 +			if(pR->iIdleListEntry)
  1.2822 +				{
  1.2823 +				SIdleResourceInfo* pI=pR->iIdleListEntry;
  1.2824 +				pI->iCurrentLevel=req->Level();
  1.2825 +				}
  1.2826 +			}
  1.2827 +		}
  1.2828 +	aState = req->Level();
  1.2829 +	aLevelOwnerId = pR->iLevelOwnerId;
  1.2830 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2831 +	if(aResourceId & KIdMaskDynamic)
  1.2832 +		((DDynamicPowerResource*)pR)->UnLock();
  1.2833 +#endif
  1.2834 +	UnLock();
  1.2835 +    __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetResourceState(synchronous), Level = %d", aState));
  1.2836 +	if(pR->LatencyGet()) //For long latency resource btrace is done in controller thread.
  1.2837 +		return r;
  1.2838 +	PRM_RESOURCE_GET_STATE_END_TRACE
  1.2839 +	return r;
  1.2840 +	}
  1.2841 +
  1.2842 +/**   
  1.2843 +@publishedPartner
  1.2844 +@prototype 9.5
  1.2845 +
  1.2846 +Request the state of the resource asynchrounously for long latency resource and
  1.2847 +synchronously for instantaneous resource
  1.2848 +
  1.2849 +@param aClientId  ID of the client which is requesting the resource state.
  1.2850 +@param aResourceId ID of the resource whose state is being requested.
  1.2851 +@param aCached If ETrue, cached value will be updated in aState
  1.2852 +               If EFalse, will be updated after the resource state is read from resource
  1.2853 +@param aCb     For long latency resource:
  1.2854 +               A pointer to a resource callback object which encapsulates a callback function
  1.2855 +               to be called whenever the state of the resource is available for the long
  1.2856 +               latency resource (executes in the context of resource manager)
  1.2857 +               For instantaneous resource:
  1.2858 +               A pointer to a resource callback object which encapsulates a callback
  1.2859 +               function to be called after the resource state is read. This is executed
  1.2860 +               synchronously in the context of the calling thread.
  1.2861 +               NOTE: The client must create the callback object in kernel heap or
  1.2862 +               data section.
  1.2863 +
  1.2864 +@return KErrNone if the operation was successful
  1.2865 +		KErrArgument if callback object is NULL
  1.2866 +        KErrAccessDenied if the client ID could not be found in the current list
  1.2867 +                         of registered clients or if the client was registered to be thread
  1.2868 +						 relative and this API is not called from the same thread.
  1.2869 +        KErrNotFound if this resource ID could not be found in the current list
  1.2870 +                     of controllable resources.
  1.2871 +        KErrNotReady if the request is issued before the resource controller completes
  1.2872 +                     its internal initialisation
  1.2873 +        KErrUnderflow if the client has exceeded the reserved number of TPowerRequest
  1.2874 +                      and the TPowerRequest free pool is empty for long latency resource.
  1.2875 +		KErrCorrupt if internal data structure is corrupt.
  1.2876 +
  1.2877 +@pre Interrupts must be enabled
  1.2878 +@pre Kernel must be unlocked
  1.2879 +@pre No fast mutex can be held
  1.2880 +@pre Call in a thread context but not from null thread or DFC thread1
  1.2881 +@pre Can be used in a device driver
  1.2882 +*/
  1.2883 +TInt DPowerResourceController::GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached,  TPowerResourceCb& aCb)
  1.2884 +	{
  1.2885 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetResourceState(asynchronous)"));
  1.2886 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("ClientId = 0x%x, ResourceId = %d, Cached = %d", aClientId, aResourceId, aCached));
  1.2887 +
  1.2888 +	DThread& thread = Kern::CurrentThread();	
  1.2889 +	CHECK_CONTEXT(thread)
  1.2890 +	if(iInitialised <= EResConCreated) 
  1.2891 +		return KErrNotReady;
  1.2892 +	SPowerResourceClient* pC = NULL;
  1.2893 +	TInt r = KErrNone;
  1.2894 +	Lock();
  1.2895 +	VALIDATE_CLIENT(thread);
  1.2896 +	if(!aResourceId)
  1.2897 +		UNLOCK_RETURN(KErrNotFound);
  1.2898 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2899 +	DStaticPowerResource *pR = NULL;
  1.2900 +	GET_RESOURCE_FROM_LIST(aResourceId, pR) 
  1.2901 +	if(aResourceId & KIdMaskDynamic)
  1.2902 +		{
  1.2903 +		//Dynamic resource in process of deregistration
  1.2904 +		if(((DDynamicPowerResource*)pR)->LockCount() == 0)
  1.2905 +			UNLOCK_RETURN(KErrNotFound);
  1.2906 +		}
  1.2907 +#else
  1.2908 +	if(aResourceId > iStaticResourceArrayEntries)
  1.2909 +		UNLOCK_RETURN(KErrNotFound);
  1.2910 +	DStaticPowerResource *pR = iStaticResourceArray[aResourceId-1];
  1.2911 +	if(!pR)
  1.2912 +		UNLOCK_RETURN(KErrNotFound);
  1.2913 +#endif
  1.2914 +	aCb.iResult = KErrNone;
  1.2915 +	aCb.iResourceId = aResourceId;
  1.2916 +	aCb.iClientId = aClientId;
  1.2917 +
  1.2918 +	PRM_RESOURCE_GET_STATE_START_TRACE
  1.2919 +	if(aCached) //Call the callback directly
  1.2920 +		{
  1.2921 +		UnLock();
  1.2922 +		aCb.iCallback(aClientId, aResourceId, pR->iCachedLevel, pR->iLevelOwnerId, KErrNone, aCb.iParam);
  1.2923 +		aCb.iResult = KErrCompletion; //Mark the callback object to act properly during cancellation of this request.
  1.2924 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.2925 +		TInt aState = pR->iCachedLevel;
  1.2926 +        PRM_RESOURCE_GET_STATE_END_TRACE
  1.2927 +#endif
  1.2928 +		return(KErrNone);
  1.2929 +		}
  1.2930 +	TPowerRequest* req=NULL;
  1.2931 +	if(pR->LatencyGet())
  1.2932 +		{
  1.2933 +		//Check the client quota of requests
  1.2934 +		if(pC->iReservedRm==0 && !iRequestPoolCount)
  1.2935 +			UNLOCK_RETURN(KErrUnderflow);
  1.2936 +		if(pC->iReservedRm ==0)
  1.2937 +			{
  1.2938 +			iRequestPoolCount--;
  1.2939 +			pC->iUnderFlowRmCount++;
  1.2940 +			}
  1.2941 +		else
  1.2942 +		    pC->iReservedRm--;
  1.2943 +		//Get the request from pool
  1.2944 +		SPowerRequest* pS;
  1.2945 +		LIST_POP(iRequestPool, pS, iNext);
  1.2946 +		if(!pS)
  1.2947 +			UNLOCK_RETURN(KErrCorrupt); //This should not be called
  1.2948 +		req = &pS->iRequest;
  1.2949 +		//Increment pending request count of the client
  1.2950 +		pC->iPendingReqCount++;
  1.2951 +		}
  1.2952 +	else
  1.2953 +		//Asynchronous instantaneous resource execute in the context of client thread.
  1.2954 +		req = (TPowerRequest*)&TPowerRequest::Get();
  1.2955 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2956 +	if(aResourceId & KIdMaskDynamic)
  1.2957 +		((DDynamicPowerResource*)pR)->Lock();
  1.2958 +#endif
  1.2959 +	UnLock();
  1.2960 +	req->ReqType() = TPowerRequest::EGet;
  1.2961 +	req->ResourceId() = aResourceId;
  1.2962 +	req->ClientId() = aClientId;
  1.2963 +	req->Resource() = pR;
  1.2964 +	req->ResourceCb() = &aCb;
  1.2965 +	if(pR->LatencyGet())
  1.2966 +		{
  1.2967 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2968 +		if(	req->ResourceId() & KIdMaskResourceWithDependencies ) // Dependency Resource
  1.2969 +			{
  1.2970 +			req->Send(iMsgQDependency); // Send the request to DFC thread.
  1.2971 +			}
  1.2972 +		else  // Plain resource
  1.2973 +#endif
  1.2974 +			{
  1.2975 +			req->Send(iMsgQ);
  1.2976 +			}
  1.2977 +		}
  1.2978 +	else
  1.2979 +		{
  1.2980 +		r = pR->DoRequest(*req);
  1.2981 +		Lock();
  1.2982 +		if(r == KErrNone)
  1.2983 +			{
  1.2984 +			//Update the cache value and cache for idle thread usage if requested for this resource.
  1.2985 +			pR->iCachedLevel = req->Level();
  1.2986 +			if(pR->iIdleListEntry)
  1.2987 +				pR->iIdleListEntry->iCurrentLevel=req->Level();
  1.2988 +			}
  1.2989 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.2990 +		if(aResourceId & KIdMaskDynamic)
  1.2991 +			((DDynamicPowerResource*)pR)->UnLock();
  1.2992 +#endif
  1.2993 +		UnLock();
  1.2994 +		// Call the client callback function directly as it is already executing in the context of client thread.
  1.2995 +		aCb.iCallback(aClientId, aResourceId, req->Level(), pR->iLevelOwnerId, r, aCb.iParam);
  1.2996 +		aCb.iResult = KErrCompletion; //Mark the callback object to act properly during cancellation of this request.
  1.2997 +		}
  1.2998 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetResourceState(asynchronous), Level = %d", req->Level()));
  1.2999 +	if(pR->LatencyGet())
  1.3000 +		return r;
  1.3001 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.3002 +	TInt aState = req->Level();
  1.3003 +	PRM_RESOURCE_GET_STATE_END_TRACE
  1.3004 +#endif
  1.3005 +	return r;
  1.3006 +	}
  1.3007 +
  1.3008 +
  1.3009 +/**
  1.3010 +@publishedPartner
  1.3011 +@prototype 9.5
  1.3012 +
  1.3013 +Cancel an asynchronous request(or its callback).
  1.3014 +
  1.3015 +@param aClientId       ID of the client which is requesting the cancellation of the request.
  1.3016 +@param aResourceId     ID for the resource which the request that is being cancelled operates
  1.3017 +                       upon.
  1.3018 +@param aCb             A reference to the resource callback object specified with the request
  1.3019 +                       that is being cancelled.
  1.3020 +
  1.3021 +@return KErrCancel if the request was cancelled.
  1.3022 +        KErrNotFound if this resource ID could not be found in the current list of controllable
  1.3023 +                     resources.
  1.3024 +        KErrCompletion if request is no longer pending.
  1.3025 +        KErrAccessDenied if the client ID could not be found in the current list of registered
  1.3026 +		clients or if the client was registered to be thread relative and this API is not called
  1.3027 +		from the same thread or if client is not the same that requested the resource state change.
  1.3028 +		KErrInUse if the request cannot be cancelled as processing of the request already started 
  1.3029 +		and will run to completion. 
  1.3030 +
  1.3031 +@pre Interrupts must be enabled
  1.3032 +@pre Kernel must be unlocked
  1.3033 +@pre No fast mutex can be held
  1.3034 +@pre Call in a thread context but not from null thread or DFC thread1
  1.3035 +@pre Can be used in a device driver
  1.3036 +*/
  1.3037 +TInt DPowerResourceController::CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb)
  1.3038 +	{
  1.3039 +    TInt r = KErrInUse;
  1.3040 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::CancelAsyncRequestCallBack"));
  1.3041 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("ClientId = 0x%x, ResourceId = %d", aClientId, aResourceId));
  1.3042 +	DThread& thread = Kern::CurrentThread();	
  1.3043 +	CHECK_CONTEXT(thread)
  1.3044 +	SPowerResourceClient* pC = NULL;
  1.3045 +	Lock();
  1.3046 +	VALIDATE_CLIENT(thread);
  1.3047 +	if((!aResourceId) || (aCb.iResourceId != aResourceId))
  1.3048 +		UNLOCK_RETURN(KErrNotFound);
  1.3049 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.3050 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.3051 +    DStaticPowerResource *pR = NULL;
  1.3052 +	GET_RESOURCE_FROM_LIST(aResourceId, pR)
  1.3053 +#else
  1.3054 +	DStaticPowerResource *pR = iStaticResourceArray[aResourceId-1];
  1.3055 +	if(!pR)
  1.3056 +		UNLOCK_RETURN(KErrNotFound);
  1.3057 +#endif
  1.3058 +#endif
  1.3059 +	if(aCb.iClientId != aClientId)
  1.3060 +		{
  1.3061 +        __KTRACE_OPT(KRESMANAGER, Kern::Printf("aCb.iClientId = 0x%x, aClientId = 0x%x", aCb.iClientId, aClientId));
  1.3062 +        r = KErrAccessDenied;
  1.3063 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.3064 +        PRM_RESOURCE_CANCEL_LONGLATENCY_OPERATION_TRACE
  1.3065 +#endif
  1.3066 +        UNLOCK_RETURN(r);
  1.3067 +		}
  1.3068 +	if(aCb.iResult == KErrCompletion)
  1.3069 +		{
  1.3070 +        r = KErrCompletion;
  1.3071 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.3072 +        PRM_RESOURCE_CANCEL_LONGLATENCY_OPERATION_TRACE
  1.3073 +#endif
  1.3074 +		UNLOCK_RETURN(r);
  1.3075 +		}
  1.3076 +	//Search in the controller message queue for this message
  1.3077 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.3078 +	if(aResourceId & KIdMaskResourceWithDependencies) //long latency resource with dependency and will be processed in dependency thread.
  1.3079 +		{
  1.3080 +		//Search in the controller message queue for this message
  1.3081 +		for(SDblQueLink* pRM = iMsgQDependency->iQ.First(); pRM != &(iMsgQDependency->iQ.iA); pRM = pRM->iNext)
  1.3082 +			{
  1.3083 +			TMessageBase* pMsgQ = (TMessageBase*)pRM;
  1.3084 +			TPowerRequest* pReq=(TPowerRequest*)pMsgQ;
  1.3085 +			if(pReq->ResourceCb() == &aCb)
  1.3086 +				{
  1.3087 +				r = KErrCancel;
  1.3088 +				pRM->Deque();
  1.3089 +				pMsgQ->iState = TMessageBase::EFree; //Reset the state
  1.3090 +				MoveRequestToFreePool(pReq);
  1.3091 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.3092 +				PRM_RESOURCE_CANCEL_LONGLATENCY_OPERATION_TRACE
  1.3093 +#endif
  1.3094 +				UNLOCK_RETURN(r);
  1.3095 +				}
  1.3096 +			}
  1.3097 +		}
  1.3098 +	else // long latency resource without dependency and will be processed in RC thread.
  1.3099 +#endif
  1.3100 +		{
  1.3101 +		for(SDblQueLink* pRM = iMsgQ->iQ.First(); pRM != &(iMsgQ->iQ.iA); pRM = pRM->iNext)
  1.3102 +			{
  1.3103 +			TMessageBase* pMsgQ = (TMessageBase*)pRM;
  1.3104 +			TPowerRequest* pReq=(TPowerRequest*)pMsgQ;
  1.3105 +			if(pReq->ResourceCb() == &aCb)
  1.3106 +				{
  1.3107 +				r = KErrCancel;
  1.3108 +				pRM->Deque();
  1.3109 +				pMsgQ->iState = TMessageBase::EFree; //Reset the state
  1.3110 +				MoveRequestToFreePool(pReq);
  1.3111 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.3112 +				PRM_RESOURCE_CANCEL_LONGLATENCY_OPERATION_TRACE
  1.3113 +#endif
  1.3114 +				UNLOCK_RETURN(r);
  1.3115 +				}
  1.3116 +			}
  1.3117 +		}
  1.3118 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.3119 +    PRM_RESOURCE_CANCEL_LONGLATENCY_OPERATION_TRACE
  1.3120 +#endif
  1.3121 +	UNLOCK_RETURN(r);
  1.3122 +	}
  1.3123 +
  1.3124 +/**
  1.3125 +@publishedPartner
  1.3126 +@prototype 9.5
  1.3127 +
  1.3128 +Request notification of changes to the state of a resource.
  1.3129 +
  1.3130 +@param aClientId     ID of the client which is requesting the notification.
  1.3131 +@param aResourceId   ID of the resource for which notification of state changes
  1.3132 +                     is being requested.
  1.3133 +@param aN            A reference to a notification object which encapsulates a callback
  1.3134 +                     function to be called whenever a resource state change takes place.
  1.3135 +                     NOTE: The client must create the notification object in kernel heap
  1.3136 +                           or data section.
  1.3137 +
  1.3138 +@return KErrNone if the operation of requesting a notification was successful.
  1.3139 +        KErrNotFound if this resource ID could not be found in the current list
  1.3140 +                     of controllable resources.
  1.3141 +        KErrAccessDenied if the client ID could not be found in the current
  1.3142 +                         list of registered clients or if the client was registered to be 
  1.3143 +						 thread relative and this API is not called from the same thread. 
  1.3144 +		KErrInUse if the passed notification object is used already.
  1.3145 +NOTE: This API should return immediately; however the notification will
  1.3146 +only happen when a resource change occurs.Notification request is idempotent, 
  1.3147 +if the same notification has already been requested for this resource ID, 
  1.3148 +the API returns with no further action.Notifications remain queued until they are cancelled.
  1.3149 +
  1.3150 +@pre Interrupts must be enabled
  1.3151 +@pre Kernel must be unlocked
  1.3152 +@pre No fast mutex can be held
  1.3153 +@pre Call in a thread context but not from null thread or DFC thread1
  1.3154 +@pre Can be used in a device driver
  1.3155 +*/
  1.3156 +TInt DPowerResourceController::RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN)
  1.3157 +	{
  1.3158 +    TInt r = KErrNone;    
  1.3159 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RequestNotification(unconditional)"));
  1.3160 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("ClientId = 0x%x, ResourceId = %d", aClientId, aResourceId));
  1.3161 +	DThread& thread = Kern::CurrentThread();	
  1.3162 +	CHECK_CONTEXT(thread)
  1.3163 +	SPowerResourceClient* pC = NULL;
  1.3164 +	Lock();
  1.3165 +	VALIDATE_CLIENT(thread);
  1.3166 +	if((!aResourceId))
  1.3167 +		{
  1.3168 +        r = KErrNotFound;
  1.3169 +        PRM_POSTNOTIFICATION_REGISTER_TRACE
  1.3170 +		UNLOCK_RETURN(r);
  1.3171 +		}
  1.3172 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.3173 +	DStaticPowerResource *pR = NULL;
  1.3174 +	GET_RESOURCE_FROM_LIST(aResourceId, pR)
  1.3175 +#else
  1.3176 +	if(aResourceId > iStaticResourceArrayEntries)
  1.3177 +		{
  1.3178 +        r = KErrNotFound;
  1.3179 +		PRM_POSTNOTIFICATION_REGISTER_TRACE
  1.3180 +		UNLOCK_RETURN(r);
  1.3181 +		}
  1.3182 +
  1.3183 +	DStaticPowerResource *pR = iStaticResourceArray[aResourceId-1];
  1.3184 +	if(!pR)
  1.3185 +		{
  1.3186 +		r = KErrNotFound;
  1.3187 +		PRM_POSTNOTIFICATION_REGISTER_TRACE
  1.3188 +		UNLOCK_RETURN(r);
  1.3189 +		}
  1.3190 +#endif
  1.3191 +	if(aN.iRegistered) //Check if the same notification object is used already
  1.3192 +		{
  1.3193 +        r = KErrInUse;
  1.3194 +        PRM_POSTNOTIFICATION_REGISTER_TRACE
  1.3195 +		UNLOCK_RETURN(r);
  1.3196 +		}
  1.3197 +	aN.iRegistered++;
  1.3198 +	aN.iType = DPowerResourceNotification::EUnconditional;
  1.3199 +	aN.iOwnerId=(TUint16)aClientId;
  1.3200 +	aN.iCallback.iClientId= aClientId;
  1.3201 +	aN.iCallback.iResourceId=aResourceId;
  1.3202 +	//Add to resource notification list
  1.3203 +	pR->iNotificationList.Add(&(aN.iNotificationLink));
  1.3204 +	//Add to client notification list
  1.3205 +	LIST_PUSH(pC->iNotificationList, &aN, iNextInClient);
  1.3206 +    PRM_POSTNOTIFICATION_REGISTER_TRACE
  1.3207 +	UNLOCK_RETURN(KErrNone);
  1.3208 +	}
  1.3209 +
  1.3210 +/**
  1.3211 +@publishedPartner
  1.3212 +@prototype 9.5
  1.3213 +
  1.3214 +Request notification when the state of a resource reaches a specified threshold or
  1.3215 +goes above or below that threshold (for multilevel resource only) based on direction.
  1.3216 +In other words it is issued when a threshold on the specified resource state is crossed
  1.3217 +in the direction specified.
  1.3218 +
  1.3219 +@param aClientId  ID of the client which is requesting the notification.
  1.3220 +@param aResourceId ID for the resource whose notification of state changes is
  1.3221 +                   being requested.
  1.3222 +@param aN          A reference to a notification object which encapsulates a callback
  1.3223 +                   function to be called whenever the conditions to issue the notification
  1.3224 +                   (specified in the API) are met.
  1.3225 +                   NOTE: The client must create the notification object in kernel heap
  1.3226 +                   or data section.
  1.3227 +@param aThreshold  The level of the resource state that will trigger the notification
  1.3228 +                   when reached.
  1.3229 +@param aDirection  Specifies the direction of change of the resource state that will
  1.3230 +                   trigger a notification. EFalse means the notification will be issued
  1.3231 +                   when the resource state change to a specified threshold value or below
  1.3232 +                   the specified threshold, ETrue means the notification will be issued
  1.3233 +                   when the resource state change to a specified threshold value or above
  1.3234 +                   the specified threshold.
  1.3235 +
  1.3236 +
  1.3237 +
  1.3238 +@return KErrNone if the operation of requesting a notification was successful.
  1.3239 +        KErrNotFound if this resource ID could not be found in the current list
  1.3240 +                     of controllable reosurces.
  1.3241 +        KErrAccessDenied if the client ID could not be found in the list of
  1.3242 +                         registered clients or if the client was registered to be thread
  1.3243 +						 relative and this API is not called from the same thread. 
  1.3244 +		KErrInUse if the passed notification object is used already.
  1.3245 +		KErrArgument if the specified threshold is out of range.
  1.3246 +NOTE: This API should return immediately; however the notification will only
  1.3247 +happen when a resource change occurs. Notification request is idempotent, 
  1.3248 +if the same notification has already been requested for this resource ID, 
  1.3249 +the API returns with no further action. Notification remain queued until they are cancelled.
  1.3250 +
  1.3251 +@pre Interrupts must be enabled
  1.3252 +@pre Kernel must be unlocked
  1.3253 +@pre No fast mutex can be held
  1.3254 +@pre Call in a thread context but not from null thread or DFC thread1
  1.3255 +@pre Can be used in a device driver
  1.3256 +*/
  1.3257 +TInt DPowerResourceController::RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, 
  1.3258 +																					TInt aThreshold, TBool aDirection)
  1.3259 +	{
  1.3260 +    TInt r = KErrNone;
  1.3261 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RequestNotification(conditional)"));
  1.3262 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("ClientId = 0x%x, ResourceId = %d, Threshold = %d, Direction = %d", \
  1.3263 +																aClientId, aResourceId, aThreshold, aDirection));
  1.3264 +	DThread& thread = Kern::CurrentThread();	
  1.3265 +	CHECK_CONTEXT(thread)
  1.3266 +	Lock();
  1.3267 +	SPowerResourceClient* pC = NULL;
  1.3268 +	VALIDATE_CLIENT(thread);
  1.3269 +	if(!aResourceId)
  1.3270 +		{
  1.3271 +        r = KErrNotFound;
  1.3272 +		PRM_POSTNOTIFICATION_REGISTER_TRACE
  1.3273 +		UNLOCK_RETURN(r);
  1.3274 +		}
  1.3275 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.3276 +	DStaticPowerResource *pR = NULL;
  1.3277 +	GET_RESOURCE_FROM_LIST(aResourceId, pR)
  1.3278 +#else
  1.3279 +	if(aResourceId > iStaticResourceArrayEntries)
  1.3280 +		{
  1.3281 +        r = KErrNotFound;
  1.3282 +        PRM_POSTNOTIFICATION_REGISTER_TRACE
  1.3283 +		UNLOCK_RETURN(r);
  1.3284 +		}
  1.3285 +
  1.3286 +	DStaticPowerResource *pR = iStaticResourceArray[aResourceId-1];
  1.3287 +	if(!pR)
  1.3288 +		{
  1.3289 +		r = KErrNotFound;
  1.3290 +		PRM_POSTNOTIFICATION_REGISTER_TRACE
  1.3291 +		UNLOCK_RETURN(r);
  1.3292 +		}
  1.3293 +#endif
  1.3294 +	if(aN.iRegistered) //Check if the same notification object is used already
  1.3295 +		{
  1.3296 +        r = KErrInUse;
  1.3297 +        PRM_POSTNOTIFICATION_REGISTER_TRACE
  1.3298 +		UNLOCK_RETURN(r);
  1.3299 +		}
  1.3300 +
  1.3301 +	//Validate threshold for correctness
  1.3302 +    TPowerResourceInfoBuf01 buf;
  1.3303 +    r = pR->GetInfo((TDes8*)buf.Ptr());
  1.3304 +    if(r != KErrNone)
  1.3305 +		{
  1.3306 +		PRM_POSTNOTIFICATION_REGISTER_TRACE
  1.3307 +		UNLOCK_RETURN(r);
  1.3308 +		}
  1.3309 +    TPowerResourceInfoV01 *pBuf = (TPowerResourceInfoV01*)buf.Ptr();
  1.3310 +    if(((pBuf->iMinLevel > pBuf->iMaxLevel) && ((aThreshold > pBuf->iMinLevel) || (aThreshold < pBuf->iMaxLevel))) || 
  1.3311 +		     ((pBuf->iMaxLevel > pBuf->iMinLevel) && ((aThreshold > pBuf->iMaxLevel) || (aThreshold < pBuf->iMinLevel))))
  1.3312 +		{
  1.3313 +        r = KErrArgument;
  1.3314 +        PRM_POSTNOTIFICATION_REGISTER_TRACE
  1.3315 +        UNLOCK_RETURN(r);
  1.3316 +		}
  1.3317 +	aN.iRegistered++;
  1.3318 +	aN.iType = DPowerResourceNotification::EConditional;
  1.3319 +	aN.iThreshold = aThreshold;
  1.3320 +	aN.iDirection = aDirection;
  1.3321 +	aN.iOwnerId = (TUint16)aClientId;
  1.3322 +	aN.iCallback.iClientId = aClientId;
  1.3323 +	aN.iCallback.iResourceId = aResourceId;
  1.3324 +	//Store the current level of the resource as will be used for issuing notification
  1.3325 +	aN.iPreviousLevel = pR->iCachedLevel; 
  1.3326 +	//Add to resource notification list
  1.3327 +	pR->iNotificationList.Add(&(aN.iNotificationLink));
  1.3328 +	//Add to client notification list
  1.3329 +	LIST_PUSH(pC->iNotificationList, &aN, iNextInClient);
  1.3330 +	PRM_POSTNOTIFICATION_REGISTER_TRACE
  1.3331 +	UNLOCK_RETURN(KErrNone);
  1.3332 +	}
  1.3333 +
  1.3334 +/**
  1.3335 +@publishedPartner
  1.3336 +@prototype 9.5
  1.3337 +
  1.3338 +Cancel and remove from queue a previously issued request for notification on a
  1.3339 +resource state change.
  1.3340 +
  1.3341 +@param aClientId ID of the client which is requesting to cancel the notification
  1.3342 +@param aResourceId for the resource whose pending notification of state changes
  1.3343 +                   is being cancelled.
  1.3344 +@param aN          A reference to the notification object that was associated with
  1.3345 +                   the notification request that is being cancelled. This will be
  1.3346 +                   used to identify the notification that is being cancelled.
  1.3347 +
  1.3348 +@return KErrCancel if the notification request was successfully cancelled.
  1.3349 +        KErrNotFound if the specified notification object is 
  1.3350 +					 not found in the current list of notification objects for the 
  1.3351 +					 specified resource.
  1.3352 +        KErrAccessDenied if the client requesting the cancellation is not the same
  1.3353 +                         which registered the notification or if the resource id does not match or
  1.3354 +						 if the client ID could not be found in the list of registered clients or 
  1.3355 +						 if the client was registered to be thread relative and this API is 
  1.3356 +						 not called from the same thread. 
  1.3357 +
  1.3358 +@pre Interrupts must be enabled
  1.3359 +@pre Kernel must be unlocked
  1.3360 +@pre No fast mutex can be held
  1.3361 +@pre Call in a thread context but not from null thread or DFC thread1
  1.3362 +@pre Can be used in a device driver
  1.3363 +*/
  1.3364 +TInt DPowerResourceController::CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN)
  1.3365 +	{
  1.3366 +     TInt r = KErrCancel;
  1.3367 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::CancelNotification"));
  1.3368 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("ClientId = 0x%x, ResourceId = %d", aClientId, aResourceId));
  1.3369 +	DThread& thread = Kern::CurrentThread();	
  1.3370 +	CHECK_CONTEXT(thread)
  1.3371 +	SPowerResourceClient* pC = NULL;
  1.3372 +	Lock();
  1.3373 +	VALIDATE_CLIENT(thread);
  1.3374 +
  1.3375 +	if(!aN.iRegistered)
  1.3376 +		{
  1.3377 +        r = KErrNotFound;
  1.3378 +        PRM_POSTNOTIFICATION_DEREGISTER_TRACE
  1.3379 +		UNLOCK_RETURN(r);
  1.3380 +		}
  1.3381 +	//Remove from the client list
  1.3382 +	TBool found = EFalse;
  1.3383 +	DPowerResourceNotification* pCNL = pC->iNotificationList;
  1.3384 +	DPowerResourceNotification* pCNLNext = pCNL;
  1.3385 +	if(pCNL == &aN)
  1.3386 +		{
  1.3387 +        if(pCNL->iOwnerId != (TUint16)aClientId)
  1.3388 +	        {
  1.3389 +            r = KErrAccessDenied;
  1.3390 +            PRM_POSTNOTIFICATION_DEREGISTER_TRACE
  1.3391 +           UNLOCK_RETURN(r);
  1.3392 +		    }
  1.3393 +        found = ETrue;
  1.3394 +		}
  1.3395 +    else
  1.3396 +		{
  1.3397 +		while(pCNLNext)
  1.3398 +			{
  1.3399 +			if(pCNLNext == &aN)
  1.3400 +				{
  1.3401 +				if(pCNL->iOwnerId != (TUint16)aClientId)
  1.3402 +					{
  1.3403 +					r = KErrAccessDenied;
  1.3404 +					PRM_POSTNOTIFICATION_DEREGISTER_TRACE
  1.3405 +					UNLOCK_RETURN(r);
  1.3406 +					}
  1.3407 +				pCNL->iNextInClient = pCNLNext->iNextInClient;
  1.3408 +				pCNL = pCNLNext;
  1.3409 +				found = ETrue;
  1.3410 +				break;
  1.3411 +				}
  1.3412 +			pCNL = pCNLNext;
  1.3413 +			pCNLNext = pCNLNext->iNextInClient;
  1.3414 +			}
  1.3415 +		}
  1.3416 +	if(!found)
  1.3417 +		{
  1.3418 +        r = KErrNotFound;
  1.3419 +        PRM_POSTNOTIFICATION_DEREGISTER_TRACE
  1.3420 +		UNLOCK_RETURN(r);
  1.3421 +		}
  1.3422 +	if(pCNL->iCallback.iResourceId != aResourceId)
  1.3423 +		{
  1.3424 +		r = KErrAccessDenied;
  1.3425 +		PRM_POSTNOTIFICATION_DEREGISTER_TRACE
  1.3426 +		UNLOCK_RETURN(r);
  1.3427 +		}
  1.3428 +	//Remove from resource list
  1.3429 +	pCNL->iNotificationLink.Deque();
  1.3430 +	pCNL->iCallback.Cancel();
  1.3431 +	//Remove from client list
  1.3432 +	LIST_REMOVE(pC->iNotificationList, pCNL, iNextInClient, DPowerResourceNotification);
  1.3433 +	pCNL->iRegistered--;
  1.3434 +	PRM_POSTNOTIFICATION_DEREGISTER_TRACE
  1.3435 +	UNLOCK_RETURN(KErrCancel);
  1.3436 +	}
  1.3437 +
  1.3438 +/**
  1.3439 +@publishedPartner
  1.3440 +@prototype 9.5
  1.3441 +
  1.3442 +Request pre-allocation of specified number of client level and request message objects.
  1.3443 +
  1.3444 +@param aClientId  ID of the client which is requesting the pre-allocation.
  1.3445 +@param aNumCl     Number of client level objects that needs to be pre-allocated
  1.3446 +                  for this client.
  1.3447 +@param aNumRm     Number of request message objects that needs to be pre-allocated
  1.3448 +                  for this client.
  1.3449 +
  1.3450 +@return KErrNone if the allocation was successful
  1.3451 +        KErrAccessDenied if the client ID could not be found in the list of
  1.3452 +                         registered clients or if the client was registered to be thread
  1.3453 +						 relative and this API is not called from the same thread. 
  1.3454 +        KErrNoMemory if there is no sufficient memory for allocation of requested
  1.3455 +                     number of objects.
  1.3456 +
  1.3457 +@pre Interrupts must be enabled
  1.3458 +@pre Kernel must be unlocked
  1.3459 +@pre No fast mutex can be held
  1.3460 +@pre Call in a thread context but not from null thread or DFC thread1
  1.3461 +@pre Can be used in a device driver
  1.3462 +*/
  1.3463 +TInt DPowerResourceController::AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm)
  1.3464 +	{
  1.3465 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::AllocReserve"));
  1.3466 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("ClientId = 0x%x, Numclients = %d, NumResource = %d", aClientId, aNumCl, aNumRm));
  1.3467 +	DThread& thread = Kern::CurrentThread();	
  1.3468 +	CHECK_CONTEXT(thread)
  1.3469 +	SPowerResourceClient* pC = NULL;
  1.3470 +	Lock();
  1.3471 +	VALIDATE_CLIENT(thread);
  1.3472 +	//Call from thread Id.
  1.3473 +	TPowerRequest* req = (TPowerRequest*)&TPowerRequest::Get();
  1.3474 +	req->ReqType() = TPowerRequest::EAllocReserve;
  1.3475 +	req->ClientId() = aClientId;
  1.3476 +	req->RequestCount() = aNumRm;
  1.3477 +	req->ClientLevelCount() = aNumCl;
  1.3478 +
  1.3479 +	UnLock();
  1.3480 +	req->SendReceive(iMsgQ);
  1.3481 +	return (req->ReturnCode());
  1.3482 +	}
  1.3483 +/**
  1.3484 +@internalComponent
  1.3485 +@prototype 9.5
  1.3486 +
  1.3487 +This function runs in the context of the RC thread and 
  1.3488 +handles creation of memory pools. 
  1.3489 +*/
  1.3490 +TInt DPowerResourceController::HandleReservationOfObjects(TPowerRequest& aRequest)
  1.3491 +	{
  1.3492 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::AllocReserve"));
  1.3493 +
  1.3494 +	SPowerResourceClientLevel* pCL = NULL;
  1.3495 +	SPowerRequest* pR = NULL;
  1.3496 +
  1.3497 +	Lock();
  1.3498 +	TInt clientPoolCount = iClientLevelPoolCount;
  1.3499 +	TInt requestPoolCount = iRequestPoolCount;
  1.3500 +	SPowerResourceClient* pC;
  1.3501 +	if(aRequest.ClientId() & USER_SIDE_CLIENT_BIT_MASK)
  1.3502 +		pC = iUserSideClientList[(TUint16)(aRequest.ClientId() & ID_INDEX_BIT_MASK)];
  1.3503 +	else																				
  1.3504 +		pC = iClientList[(TUint16)(aRequest.ClientId() & ID_INDEX_BIT_MASK)];
  1.3505 +	UnLock();
  1.3506 +
  1.3507 +	if(clientPoolCount < aRequest.ClientLevelCount())
  1.3508 +		{
  1.3509 +		//Grow the client level pool
  1.3510 +		// coverity[alloc_fn]
  1.3511 +		pCL = new SPowerResourceClientLevel[iClientLevelPoolGrowBy + aRequest.ClientLevelCount()];
  1.3512 +		if(!pCL)
  1.3513 +			return(KErrNoMemory);
  1.3514 +		}
  1.3515 +	if(requestPoolCount < aRequest.RequestCount())
  1.3516 +		{
  1.3517 +		//Grow the request pool
  1.3518 +		// coverity[alloc_fn]
  1.3519 +		pR = new SPowerRequest[iRequestPoolGrowBy + aRequest.RequestCount()];
  1.3520 +		if(!pR)
  1.3521 +			{
  1.3522 +			if(pCL) //If client level is allocated delete the same.
  1.3523 +				delete []pCL;
  1.3524 +			return(KErrNoMemory);
  1.3525 +			}
  1.3526 +		}
  1.3527 +	//Push the memory to list and adjust the counter.
  1.3528 +	Lock();
  1.3529 +	TUint count;
  1.3530 +	if(pCL)
  1.3531 +		{
  1.3532 +		for(count = 0;count<(TUint)(iClientLevelPoolGrowBy+aRequest.ClientLevelCount());count++)
  1.3533 +			LIST_PUSH(iClientLevelPool, &pCL[count], iNextInList);
  1.3534 +		iClientLevelPoolCount= (TUint16)(iClientLevelPoolCount + iClientLevelPoolGrowBy);
  1.3535 +		pC->iReservedCl= (TUint8)(pC->iReservedCl + aRequest.ClientLevelCount());
  1.3536 +		}
  1.3537 +		else
  1.3538 +		{
  1.3539 +		//Reserve memory from free pool to this client
  1.3540 +		iClientLevelPoolCount = (TUint16)(iClientLevelPoolCount - aRequest.ClientLevelCount());
  1.3541 +		pC->iReservedCl = (TUint8)(pC->iReservedCl + aRequest.ClientLevelCount());
  1.3542 +		}
  1.3543 +
  1.3544 +	if(pR)
  1.3545 +		{
  1.3546 +		for(count=0;count<(TUint)(iRequestPoolGrowBy+aRequest.RequestCount());count++)
  1.3547 + 			LIST_PUSH(iRequestPool, &pR[count], iNext);
  1.3548 +		iRequestPoolCount = (TUint16)(iRequestPoolCount + iRequestPoolGrowBy);
  1.3549 +		pC->iReservedRm =(TUint8)(pC->iReservedRm + aRequest.RequestCount());
  1.3550 +		}
  1.3551 +	else
  1.3552 +		{
  1.3553 +		//Reserve memory from free pool to this client
  1.3554 +		iRequestPoolCount = (TUint16)(iRequestPoolCount - aRequest.RequestCount());
  1.3555 +		pC->iReservedRm = (TUint8)(pC->iReservedRm + aRequest.RequestCount());
  1.3556 +		}
  1.3557 +	UnLock();
  1.3558 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.3559 +    TUint size =0;
  1.3560 +    if(pCL)
  1.3561 +		size = (iClientLevelPoolGrowBy+aRequest.ClientLevelCount())*sizeof(SPowerResourceClientLevel);
  1.3562 +    if(pR)
  1.3563 +		size += (iRequestPoolGrowBy+aRequest.RequestCount())*sizeof(SPowerRequest);
  1.3564 +    if(size)
  1.3565 +        PRM_MEMORY_USAGE_TRACE
  1.3566 +#endif
  1.3567 +	return(KErrNone);
  1.3568 +	}
  1.3569 +
  1.3570 +/*  Register the proxy client to resource controller.
  1.3571 +	This is called as the result of new user side client opening a channel.*/
  1.3572 +TInt DPowerResourceController::RegisterProxyClient(TUint& aClientId, const TDesC8& aName)
  1.3573 +	{
  1.3574 +	GET_CRITICAL_SECTION_COUNT
  1.3575 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterProxyClient"));
  1.3576 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("Proxy client name %S", &aName));
  1.3577 +
  1.3578 +	DThread& t = Kern::CurrentThread();	
  1.3579 +	CHECK_CONTEXT(t)
  1.3580 +	//If number of expected user side clients is set to 0 during initial configuration
  1.3581 +	//then dont allow to configure user side clients.
  1.3582 +	if(!iUserSideClientList.GrowBy())
  1.3583 +		return KErrNotSupported;
  1.3584 +	//Maximum allowable length of a client's name is 32 characters.
  1.3585 +	if (aName.Length() > KMaxClientNameLength) return KErrTooBig;
  1.3586 +
  1.3587 +	SPowerResourceClient *pC = NULL;
  1.3588 +    Lock();
  1.3589 +#ifdef DEBUG_VERSION
  1.3590 +    if(!iUserSideClientList.Find(pC, (TDesC8&)aName))
  1.3591 +		{
  1.3592 +		UnLock();
  1.3593 +		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  1.3594 +		return KErrAlreadyExists;
  1.3595 +		}
  1.3596 +#endif
  1.3597 +	TPowerRequest* req = (TPowerRequest*)&TPowerRequest::Get();
  1.3598 +	req->ReqType() = TPowerRequest::ERegisterUsersideClient;
  1.3599 +	UnLock();
  1.3600 +	req->SendReceive(iMsgQ);
  1.3601 +	if(req->ReturnCode() == KErrNone)
  1.3602 +		{
  1.3603 +		pC = iUserSideClientList[(TUint16)(req->ClientId() & ID_INDEX_BIT_MASK)];
  1.3604 +		pC->iName=&aName;
  1.3605 +		//Store the current thread Id;
  1.3606 +		pC->iThreadId = t.iId;
  1.3607 +		aClientId = pC->iClientId;
  1.3608 +		}
  1.3609 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterProxyClient, clientId = 0x%x", aClientId));
  1.3610 +    PRM_CLIENT_REGISTER_TRACE
  1.3611 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  1.3612 +	return KErrNone;
  1.3613 +	}
  1.3614 +
  1.3615 +/*  Deregister the specified user side client from resource controller.
  1.3616 +	This is called as the result of client closing the channel. */
  1.3617 +TInt DPowerResourceController::DeregisterProxyClient(TUint aClientId)
  1.3618 +	{
  1.3619 +	GET_CRITICAL_SECTION_COUNT
  1.3620 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::DeregisterProxyClient"));
  1.3621 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("ClientId = 0x%x", aClientId));
  1.3622 +	DThread& t = Kern::CurrentThread();	
  1.3623 +	CHECK_CONTEXT(t)
  1.3624 +	//Get the index from client ID
  1.3625 +	if(!(aClientId & USER_SIDE_CLIENT_BIT_MASK))
  1.3626 +		return KErrArgument;
  1.3627 +	Lock();
  1.3628 +	SPowerResourceClient* pC = iUserSideClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];
  1.3629 +	if(!pC)
  1.3630 +		{
  1.3631 +		UnLock();
  1.3632 +		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  1.3633 +		return KErrNotFound;
  1.3634 +		}
  1.3635 +	if(pC->iClientId != aClientId)
  1.3636 +		{
  1.3637 +        __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID does not match"));
  1.3638 +	     UNLOCK_RETURN(KErrNotFound);
  1.3639 +		}
  1.3640 +	if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK)
  1.3641 +		{
  1.3642 +		if(pC->iThreadId != t.iId)
  1.3643 +			{
  1.3644 +			UnLock();
  1.3645 +			LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  1.3646 +			return KErrAccessDenied;
  1.3647 +			}
  1.3648 +		}
  1.3649 +	//Check for any pending request
  1.3650 +	if(pC->iPendingReqCount)
  1.3651 +		{
  1.3652 +		UnLock();
  1.3653 +		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  1.3654 +		Panic(EClientHasPendingAsyncRequest);
  1.3655 +		}
  1.3656 +	//Check for notification request
  1.3657 +	if(pC->iNotificationList)
  1.3658 +		{
  1.3659 +		UnLock();
  1.3660 +		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  1.3661 +		Panic(EClientHasNotificationObject);
  1.3662 +		}
  1.3663 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.3664 +	if(pC->iDynamicResCount)
  1.3665 +		{
  1.3666 +		UnLock();
  1.3667 +		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  1.3668 +		Panic(DPowerResourceController::EClientHasDynamicResourceRegistered);
  1.3669 +		}
  1.3670 +#endif
  1.3671 +	ResourceStateChangeOfClientLevels(pC);
  1.3672 +	//Add reserved request to pool
  1.3673 +	iRequestPoolCount = (TUint16)(iRequestPoolCount + pC->iReservedRm);
  1.3674 +	PRM_CLIENT_DEREGISTER_TRACE
  1.3675 +	//Increment the free pool count for client level and request level.
  1.3676 +	iUserSideClientList.Remove(pC, (TUint16)(pC->iClientId & ID_INDEX_BIT_MASK));
  1.3677 +	pC->iName = NULL;
  1.3678 +	iUserSideClientCount--; //Decrement client count
  1.3679 +	LIST_PUSH(iClientPool, pC, iNextInList);
  1.3680 +	UnLock();
  1.3681 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  1.3682 +	return KErrNone;
  1.3683 +	}
  1.3684 +
  1.3685 +/* This is called from power controller to cache the state of resource whose
  1.3686 +   state information it is interested in for accessing from null thread. This
  1.3687 +   list needs to be accessed from the Idle thread using direct access. */
  1.3688 +TInt DPowerResourceController::RegisterResourcesForIdle(TInt aPowerControllerId, TUint aNumResources, TPtr* aBuf)
  1.3689 +	{
  1.3690 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterResourceForIdle"));
  1.3691 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("PowerControllerId = 0x%x, NumResources = %d", aPowerControllerId, aNumResources));
  1.3692 +#ifdef DEBUG_VERSION //Surrounding with macro to avoid warnings.
  1.3693 +	DThread& t = Kern::CurrentThread();	
  1.3694 +	CHECK_CONTEXT(t)
  1.3695 +#endif
  1.3696 +	if(!aBuf)
  1.3697 +		return KErrArgument;
  1.3698 +	if((TUint)aPowerControllerId != iPowerControllerId)
  1.3699 +		return KErrAccessDenied;
  1.3700 +	if(iListForIdle) //Only one list is allowed.
  1.3701 +		return KErrInUse;
  1.3702 +	if((TUint)(aBuf->MaxLength() - aBuf->Length()) < (sizeof(SIdleResourceInfo) * aNumResources))
  1.3703 +		return KErrArgument;
  1.3704 +	GET_CRITICAL_SECTION_COUNT
  1.3705 +	Lock();
  1.3706 +	SIdleResourceInfo* pS=(SIdleResourceInfo*)aBuf->Ptr();
  1.3707 +	DStaticPowerResource* pR=NULL;
  1.3708 +	TUint count=0;
  1.3709 +	TUint id=0;
  1.3710 +	for(count=0;count<aNumResources;count++) //Check for valid resource ID.
  1.3711 +		{
  1.3712 +#ifndef PRM_ENABLE_EXTENDED_VERSION
  1.3713 +		if((!pS->iResourceId) || (pS->iResourceId > iStaticResourceArrayEntries) || (!iStaticResourceArray[pS->iResourceId-1]))
  1.3714 +			{
  1.3715 +			UnLock();
  1.3716 +			LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  1.3717 +			return KErrNotFound;
  1.3718 +			}
  1.3719 +#else
  1.3720 +		if(pS->iResourceId & KIdMaskDynamic)
  1.3721 +			{
  1.3722 +			UnLock();
  1.3723 +			LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  1.3724 +			return KErrNotSupported;
  1.3725 +			}
  1.3726 +		if((!pS->iResourceId) || ((pS->iResourceId & KIdMaskResourceWithDependencies) && 
  1.3727 +			     (pS->iResourceId > iStaticResDependencyCount)) || (!(pS->iResourceId & KIdMaskResourceWithDependencies) && 
  1.3728 +					((pS->iResourceId > iStaticResourceArrayEntries) || (!iStaticResourceArray[pS->iResourceId-1]))))
  1.3729 +			{
  1.3730 +			UnLock();
  1.3731 +			LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  1.3732 +			return KErrNotFound;
  1.3733 +			}
  1.3734 +#endif
  1.3735 +		pS++;
  1.3736 +		}
  1.3737 +	pS = (SIdleResourceInfo*)aBuf->Ptr();
  1.3738 +	for(count=0;count<aNumResources;count++)
  1.3739 +		{
  1.3740 +		id=pS->iResourceId;
  1.3741 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.3742 +		if(id & KIdMaskResourceWithDependencies) //Dependency resource
  1.3743 +			pR = iStaticResDependencyArray[(id & ID_INDEX_BIT_MASK)-1];
  1.3744 +		else
  1.3745 +#endif
  1.3746 +		pR=iStaticResourceArray[id-1];
  1.3747 +		pS->iLevelOwnerId = pR->iLevelOwnerId;
  1.3748 +		pS->iCurrentLevel = pR->iCachedLevel;
  1.3749 +		pR->iIdleListEntry=pS;
  1.3750 +		pS++;
  1.3751 +		}
  1.3752 +	iListForIdle=(SIdleResourceInfo*)aBuf->Ptr();
  1.3753 +	pS = (SIdleResourceInfo*)aBuf->Ptr();
  1.3754 +	UnLock();
  1.3755 +	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK
  1.3756 +	return KErrNone;
  1.3757 +	}
  1.3758 +	
  1.3759 +/**
  1.3760 +@publishedPartner
  1.3761 +@prototype 9.6
  1.3762 +
  1.3763 +Request to deregister client level from the specified resource for the specified client. 
  1.3764 +
  1.3765 +@param aClientId	ID of the client which is requesting the deregistration of client level.
  1.3766 +@param aResourceId	ID of the resource from which to remove the specified client's level.
  1.3767 +
  1.3768 +@return KErrNone			if successful
  1.3769 +		KErrAccessDenied	if the client ID could not be found in the list of registered clients or
  1.3770 +							if the client was registered to be thread relative and this API is not 
  1.3771 +							called from the same thread.
  1.3772 +		KErrNotFound		if the resource ID could not be found in the current list of controllable 
  1.3773 +							resources or if the client is not holding any level with the specified 
  1.3774 +							resource (no client level found for the specified client).
  1.3775 +
  1.3776 +@pre Interrupts must be enabled
  1.3777 +@pre Kernel must be unlocked
  1.3778 +@pre No fast mutex can be held
  1.3779 +@pre Call in a thread context but not from null thread or DFC thread1
  1.3780 +@pre Can be used in a device driver.
  1.3781 +*/
  1.3782 +TInt DPowerResourceController::DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId)
  1.3783 +	{
  1.3784 +	TInt r = KErrNone;
  1.3785 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::DeRegisterClientLevelFromResource\n"));
  1.3786 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("aClientId = 0x%x, aResourceId = 0x%x\n", aClientId, aResourceId));
  1.3787 +	DThread& thread = Kern::CurrentThread();	
  1.3788 +	CHECK_CONTEXT(thread)
  1.3789 +	SPowerResourceClient* pC = NULL;
  1.3790 +	Lock();
  1.3791 +	VALIDATE_CLIENT(thread);
  1.3792 +	//Validate resource
  1.3793 +	if((!aResourceId))
  1.3794 +		{
  1.3795 +		UNLOCK_RETURN(KErrNotFound);
  1.3796 +		}
  1.3797 +	DStaticPowerResource *pR = NULL;
  1.3798 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.3799 +	GET_RESOURCE_FROM_LIST(aResourceId, pR)
  1.3800 +	if(aResourceId & KIdMaskDynamic)
  1.3801 +		((DDynamicPowerResource*)pR)->Lock();
  1.3802 +#else
  1.3803 +	if(aResourceId > iStaticResourceArrayEntries)
  1.3804 +		{
  1.3805 +		UNLOCK_RETURN(KErrNotFound);
  1.3806 +		}
  1.3807 +	pR = iStaticResourceArray[aResourceId - 1];
  1.3808 +	if(!pR)
  1.3809 +		UNLOCK_RETURN(KErrNotFound);
  1.3810 +#endif
  1.3811 +	//Need to change the state of the resource if the client is holding the current resource.
  1.3812 +	if((pR->iLevelOwnerId == (TInt)aClientId) || (pR->Sense() == DStaticPowerResource::ECustom)) 
  1.3813 +		{
  1.3814 +		//If Longlatency resource then process it in the resource controller thread
  1.3815 +		TPowerRequest* req = (TPowerRequest*)&TPowerRequest::Get();
  1.3816 +		req->ResourceId() = aResourceId;
  1.3817 +		req->ReqType() = TPowerRequest::ESetDefaultLevel;
  1.3818 +		req->ClientId() = aClientId;
  1.3819 +		req->Resource() = pR;
  1.3820 +		req->ResourceCb() = NULL;
  1.3821 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.3822 +		//Setting to current state as exact state will be known only before calling the PSL.
  1.3823 +		TInt aNewState = pR->iCachedLevel; 
  1.3824 +		PRM_CLIENT_CHANGE_STATE_START_TRACE
  1.3825 +#endif
  1.3826 +		if(pR->LatencySet())
  1.3827 +			{
  1.3828 +			UnLock();
  1.3829 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.3830 +			if(pR->iResourceId & KIdMaskResourceWithDependencies) //Dependency resource
  1.3831 +				{
  1.3832 +				r = req->SendReceive(iMsgQDependency); // Send the request to DFC thread.
  1.3833 +				}
  1.3834 +			else
  1.3835 +#endif
  1.3836 +				{
  1.3837 +				r = req->SendReceive(iMsgQ); //Long latency resource request are processed in controller thread.
  1.3838 +				}
  1.3839 +			Lock();
  1.3840 +			}
  1.3841 +		else if(pR->Usage())
  1.3842 +			{
  1.3843 +			//Shared resource
  1.3844 +			//Not checking the return value here because there is no allocation of client levels. 
  1.3845 +			CheckLevelAndAddClient(pC, req); 
  1.3846 +			}
  1.3847 +		else
  1.3848 +			{
  1.3849 +			//Single user set it to default
  1.3850 +			req->ClientId() = -1;
  1.3851 +			req->ReqType() = TPowerRequest::ESetDefaultLevel;
  1.3852 +			}
  1.3853 +		//Change the state of resource for instantaneous resource.
  1.3854 +		if((!pR->LatencySet()) && ((!pR->Usage()) || (pR->Usage() && req->RequiresChange())))
  1.3855 +			{
  1.3856 +			UnLock();
  1.3857 +			r = pR->DoRequest(*req);
  1.3858 +			Lock();
  1.3859 +			if(r == KErrNone)
  1.3860 +				{
  1.3861 +				//Complete notifications
  1.3862 +				CompleteNotifications(req->ClientId(), pR, req->Level(), KErrNone, req->ClientId(), EFalse);
  1.3863 +				//Update the cache
  1.3864 +				pR->iLevelOwnerId = req->ClientId();
  1.3865 +				pR->iCachedLevel = req->Level();
  1.3866 +				if(pR->iIdleListEntry)
  1.3867 +					{
  1.3868 +					pR->iIdleListEntry->iLevelOwnerId = req->ClientId();
  1.3869 +					pR->iIdleListEntry->iCurrentLevel = req->Level();
  1.3870 +					}
  1.3871 +				}
  1.3872 +			}
  1.3873 +#ifdef PRM_INSTRUMENTATION_MACRO
  1.3874 +		if(!pR->LatencySet())
  1.3875 +			{
  1.3876 +			aNewState = req->Level();
  1.3877 +			PRM_CLIENT_CHANGE_STATE_END_TRACE
  1.3878 +			}
  1.3879 +#endif
  1.3880 +		}
  1.3881 +	//Remove clientLevel from client
  1.3882 +	r = KErrNotFound;
  1.3883 +	for(SPowerResourceClientLevel* pCL = pC->iLevelList; pCL != NULL; pCL= pCL->iNextInList)
  1.3884 +		{
  1.3885 +		if(pCL->iResourceId == aResourceId)
  1.3886 +			{
  1.3887 +			LIST_REMOVE(pC->iLevelList, pCL, iNextInList, SPowerResourceClientLevel);
  1.3888 +			//Remove from Resource
  1.3889 +			pCL->Deque();
  1.3890 +			LIST_PUSH(iClientLevelPool,pCL,iNextInList); // back to free pool
  1.3891 +			if(pC->iUnderFlowClCount > 0)
  1.3892 +				{
  1.3893 +				pC->iUnderFlowClCount--;
  1.3894 +				iClientLevelPoolCount++;
  1.3895 +				}
  1.3896 +			else
  1.3897 +				pC->iReservedCl++;
  1.3898 +			r = KErrNone;
  1.3899 +			break;
  1.3900 +			}
  1.3901 +		}
  1.3902 +#ifdef PRM_ENABLE_EXTENDED_VERSION
  1.3903 +	if(aResourceId & KIdMaskDynamic)
  1.3904 +		((DDynamicPowerResource*)pR)->UnLock();
  1.3905 +#endif
  1.3906 +	UNLOCK_RETURN(r);
  1.3907 +	}
  1.3908 +
  1.3909 +/**
  1.3910 +@publishedPartner
  1.3911 +@prototype 9.5
  1.3912 +
  1.3913 +Interface to provide extended functionality.This provides support
  1.3914 +to register and deregister dynamic resources and handling of resource dependency, registering
  1.3915 +and deregistering resource dependency.
  1.3916 +This is not supported in basic version
  1.3917 +
  1.3918 +@pre Interrupts must be enabled
  1.3919 +@pre Kernel must be unlocked
  1.3920 +@pre No fast mutex can be held
  1.3921 +@pre Call in a thread context but not from null thread or DFC thread1
  1.3922 +@pre Can be used in a device driver.
  1.3923 +*/
  1.3924 +TInt DPowerResourceController::GetInterface(TUint aClientId, TUint aInterfaceId, TAny* aParam1, TAny* aParam2, 
  1.3925 +											                                             TAny* aParam3)
  1.3926 +	{
  1.3927 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::GetInterface"));
  1.3928 +	DThread& thread = Kern::CurrentThread();	
  1.3929 +	CHECK_CONTEXT(thread)
  1.3930 +	if((iInitialised != EResConStartupCompleted) && (aInterfaceId != KResManControlIoGetVersion))
  1.3931 +		return KErrNotSupported;
  1.3932 +	TInt r = KErrNone;
  1.3933 +	Lock();
  1.3934 +	SPowerResourceClient* pC = NULL;
  1.3935 +	VALIDATE_CLIENT(thread);
  1.3936 +#ifndef PRM_ENABLE_EXTENDED_VERSION
  1.3937 +	if(aInterfaceId == KResManControlIoGetVersion)
  1.3938 +		{
  1.3939 +		if(!aParam1)
  1.3940 +			r = KErrArgument;
  1.3941 +		else
  1.3942 +			*(TUint*)aParam1  = KResControllerBasicVersion;
  1.3943 +		}
  1.3944 +	else
  1.3945 +		r = KErrNotSupported;
  1.3946 +	(void) aParam2;
  1.3947 +	(void) aParam3;
  1.3948 +#else
  1.3949 +	//User side client is not allowed to register/deregister dynamic resource and dependencies
  1.3950 +	if((aClientId & USER_SIDE_CLIENT_BIT_MASK) && (aInterfaceId >= KResManControlIoRegisterDynamicResource) && 
  1.3951 +		                                                 (aInterfaceId <= KResManControlIoDeregisterDependency))
  1.3952 +		return KErrAccessDenied;
  1.3953 +	switch (aInterfaceId)
  1.3954 +		{
  1.3955 +		case KResManControlIoGetVersion:
  1.3956 +			{
  1.3957 +			if(!aParam1)
  1.3958 +				r = KErrArgument;
  1.3959 +			else
  1.3960 +				*(TUint*)aParam1 = KResControllerExtendedVersion;
  1.3961 +			break;
  1.3962 +			}
  1.3963 +		case KResManControlIoRegisterDynamicResource:
  1.3964 +			{
  1.3965 +			r = RegisterDynamicResource(pC, (DDynamicPowerResource *)aParam1, (TUint*)aParam2);
  1.3966 +			break;
  1.3967 +			}
  1.3968 +		case KResManControlIoDeregisterDynamicResource:
  1.3969 +			{
  1.3970 +			r = DeregisterDynamicResource(pC, (TUint)aParam1, (TInt*)aParam2);
  1.3971 +			break;
  1.3972 +			}
  1.3973 +		case KResManControlIoRegisterDependency:
  1.3974 +			{
  1.3975 +
  1.3976 +			r = RegisterResourceDependency(pC, (SResourceDependencyInfo*)aParam1, (SResourceDependencyInfo*)aParam2);
  1.3977 +			break;
  1.3978 +			}
  1.3979 +		case KResManControlIoDeregisterDependency:
  1.3980 +			{
  1.3981 +			r = DeregisterResourceDependency(pC, (TUint)aParam1, (TUint)aParam2);
  1.3982 +			__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetInterface"));
  1.3983 +			return(r);
  1.3984 +			}
  1.3985 +		case KResManControlIoGetNumDependents:
  1.3986 +			{
  1.3987 +			r = GetNumDependentsForResource((TUint)aParam1, (TUint*)aParam2);
  1.3988 +			break;
  1.3989 +			}
  1.3990 +		case KResManControlIoGetDependentsId:
  1.3991 +			{
  1.3992 +			r = GetDependentsIdForResource((TUint)aParam1, (TAny*)aParam2, (TUint*)aParam3);
  1.3993 +			break;
  1.3994 +			}
  1.3995 +		default:
  1.3996 +			{
  1.3997 +			r = KErrNotSupported;
  1.3998 +			break;
  1.3999 +			}
  1.4000 +		}
  1.4001 +#endif
  1.4002 +	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::GetInterface"));
  1.4003 +	UNLOCK_RETURN(r);
  1.4004 +	}
  1.4005 +