os/kernelhwsrv/kernel/eka/include/drivers/resourcecontrol.h
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kernel/eka/include/drivers/resourcecontrol.h	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,691 @@
     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\include\drivers\resourcecontrol.h
    1.18 +// 
    1.19 +// WARNING: This file contains some APIs which are internal and are subject
    1.20 +//          to change without notice. Such APIs should therefore not be used
    1.21 +//          outside the Kernel and Hardware Services package.
    1.22 +//
    1.23 +
    1.24 +#ifndef __RESOURCECONTROL_H__
    1.25 +#define __RESOURCECONTROL_H__
    1.26 +#include <nklib.h>
    1.27 +#include <kernel/kernel.h>
    1.28 +#include <kernel/kern_priv.h>
    1.29 +#include <e32ver.h>
    1.30 +#define PRM_CONTROLLER
    1.31 +#ifndef PRM_ENABLE_EXTENDED_VERSION
    1.32 +#include <drivers/resource.h>
    1.33 +#else
    1.34 +#include <drivers/resource_extend.h>
    1.35 +#endif 
    1.36 +#include <drivers/resourceman.h>
    1.37 +
    1.38 +/** #defines for client bit masks */
    1.39 +#define ID_INDEX_BIT_MASK 0x3FFF  /* bit 0 -13 */
    1.40 +#define USER_SIDE_CLIENT_BIT_MASK 0x4000 //Bit 14
    1.41 +#define CLIENT_THREAD_RELATIVE_BIT_MASK 0x80000000 //Bit 31
    1.42 +#define INSTANCE_COUNT_BIT_MASK 0x1FFF //13 Bits
    1.43 +#define INSTANCE_COUNT_POS 18
    1.44 +#define CLIENT_POWER_CONTROLLER_BIT_MASK 0x8000 //Bit 15
    1.45 +/** Bit to indicate valid post boot level in resource */
    1.46 +#define SET_VALID_POST_BOOT_LEVEL 0x8000 //Bit 15
    1.47 +
    1.48 +#define RESOURCE_NOT_IN_OPERATION 0x1	
    1.49 +#define PRM_DYNAMIC_RESOURCE_INITIAL_SIZE 2
    1.50 +
    1.51 +#define PRM_STATIC_RESOURCE					0x0
    1.52 +#define PRM_STATIC_DEPENDENCY_RESOURCE		0x1
    1.53 +#define PRM_DYNAMIC_RESOURCE				0x2	
    1.54 +#define PRM_DYNAMIC_DEPENDENCY_RESOURCE		0x3
    1.55 +#define RESOURCE_BIT_IN_ID_CHECK			16
    1.56 +
    1.57 +
    1.58 +static const TInt KMaxResourceNameLength=0x20; //Maximum allowable resource length is 32 characters.
    1.59 +static const TInt KMaxClientNameLength=0x20; //Maximum allowable client length is 32 characters.
    1.60 +
    1.61 +
    1.62 +_LIT8(KPowerController, "PowerController");
    1.63 +_LIT8(KDfcThread1Name, "DfcThread1");
    1.64 +_LIT8(KDfcThread0Name, "DfcThread0");
    1.65 +_LIT8(KNullThreadName, "Null");
    1.66 +_LIT8(KNoClient, "NoClient");
    1.67 +_LIT8(KParentResource, "ParentResource");
    1.68 +/** Macro to check the context of client calling RM API.
    1.69 +    Panics if it is called from ISR, IDFC, NULL thread or DFC thread1 */
    1.70 +#ifdef DEBUG_VERSION
    1.71 +#define CHECK_CONTEXT(t)																\
    1.72 +	__ASSERT_ALWAYS(NKern::CurrentContext() == NKern::EThread, Panic(ECalledFromIsr));	\
    1.73 +	const TDesC8* pDfc1 = &KDfcThread1Name;												\
    1.74 +	if(!pDfc1->Compare(*(TDesC8*)t.iName))												\
    1.75 +		Panic(ECalledFromDfcThread1);													\
    1.76 +    const TDesC8* pNull = &KNullThreadName;												\
    1.77 +	if(!pNull->Compare(*(TDesC8*)t.iName))												\
    1.78 +		Panic(ECalledFromNullThread);
    1.79 +#else
    1.80 +#define CHECK_CONTEXT(t)
    1.81 +#endif
    1.82 +
    1.83 +/** Macro to unlock and return */
    1.84 +#define UNLOCK_RETURN(retval)       \
    1.85 +    {                               \
    1.86 +    UnLock();                       \
    1.87 +    return(retval);                 \
    1.88 +    }
    1.89 +
    1.90 +/** Macro to push the item into the specified list. Item are pushed to the head of the list. */
    1.91 +#define LIST_PUSH(list,item,link)	\
    1.92 +	{                               \
    1.93 +	(item)->link = (list);			\
    1.94 +	(list) = (item);                \
    1.95 +	}
    1.96 +
    1.97 +/** Macro to pop the item from the specified list. Item are poped from the head of the list. */
    1.98 +#define LIST_POP(list,item,link)	\
    1.99 +	{                               \
   1.100 +	(item) = (list);				\
   1.101 +	if ((item))						\
   1.102 +		{							\
   1.103 +		(list) = (item)->link;		\
   1.104 +		(item)->link = NULL;		\
   1.105 +		}                           \
   1.106 +	}
   1.107 +
   1.108 +/** Macro to remove the item from the list. */
   1.109 +#define LIST_REMOVE(list,item,link,className)		\
   1.110 +	if (list)										\
   1.111 +		{											\
   1.112 +		className* current = (list);				\
   1.113 +		if (current==(item))						\
   1.114 +			{										\
   1.115 +			(list) = (item)->link;					\
   1.116 +			(item)->link = NULL;					\
   1.117 +			}										\
   1.118 +		else										\
   1.119 +			{										\
   1.120 +			className* next = current->link;		\
   1.121 +			while (next)							\
   1.122 +				{									\
   1.123 +				if ((item)==next)					\
   1.124 +					{								\
   1.125 +					current->link=next->link;		\
   1.126 +					next->link = NULL;				\
   1.127 +					break;							\
   1.128 +					}								\
   1.129 +				current = next;						\
   1.130 +				next = next->link;					\
   1.131 +				}									\
   1.132 +			}										\
   1.133 +		}
   1.134 +
   1.135 +
   1.136 +/* Macro to add dynamic resource to appropriate containers. Used only in extended version */
   1.137 +#define ADD_TO_RESOURCE_CONTAINER(list, res, resId, resIdCount)				\
   1.138 +	{																		\
   1.139 +	TUint16 growBy = (list).GrowBy();										\
   1.140 +	if(!growBy)																\
   1.141 +		(list).Initialise((TUint16)PRM_DYNAMIC_RESOURCE_INITIAL_SIZE);		\
   1.142 +	if((list).Add(res, resId) == KErrNoMemory)								\
   1.143 +		{																	\
   1.144 +		TInt r = (list).ReSize(growBy);										\
   1.145 +		if(r != KErrNone)													\
   1.146 +			return r;														\
   1.147 +		(list).Add(res, resId);												\
   1.148 +		}																	\
   1.149 +	res->iResourceId |= resId;												\
   1.150 +	resId = res->iResourceId;												\
   1.151 +	resIdCount++;															\
   1.152 +	}
   1.153 +	
   1.154 +/* Macro to get the resource from appropriate list. Used only in extended version */
   1.155 +#define GET_RESOURCE_FROM_LIST(resId, res)														\
   1.156 +	{																							\
   1.157 +	switch((resId >> RESOURCE_BIT_IN_ID_CHECK) & 0x3)											\
   1.158 +		{																						\
   1.159 +		case PRM_STATIC_RESOURCE:																\
   1.160 +			if(resId > iStaticResourceArrayEntries)												\
   1.161 +				UNLOCK_RETURN(KErrNotFound);													\
   1.162 +			res = iStaticResourceArray[resId - 1];												\
   1.163 +			if(!res)																			\
   1.164 +				UNLOCK_RETURN(KErrNotFound);													\
   1.165 +			break;																				\
   1.166 +		case PRM_STATIC_DEPENDENCY_RESOURCE:													\
   1.167 +			if((TUint16)(resId & ID_INDEX_BIT_MASK) > iStaticResDependencyCount)				\
   1.168 +				UNLOCK_RETURN(KErrNotFound);													\
   1.169 +			res = iStaticResDependencyArray[(TUint16)(resId & ID_INDEX_BIT_MASK)  - 1];			\
   1.170 +			break;																				\
   1.171 +		case PRM_DYNAMIC_RESOURCE:																\
   1.172 +			res = iDynamicResourceList[(TUint16)(resId & ID_INDEX_BIT_MASK)];					\
   1.173 +			if(!res)																			\
   1.174 +				UNLOCK_RETURN(KErrNotFound);													\
   1.175 +			break;																				\
   1.176 +		case PRM_DYNAMIC_DEPENDENCY_RESOURCE:													\
   1.177 +			res = iDynamicResDependencyList[(TUint16)(resId & ID_INDEX_BIT_MASK)];				\
   1.178 +			if(!res)																			\
   1.179 +				UNLOCK_RETURN(KErrNotFound);													\
   1.180 +			break;																				\
   1.181 +		default:																				\
   1.182 +			UNLOCK_RETURN(KErrArgument);														\
   1.183 +		}																						\
   1.184 +	}
   1.185 +
   1.186 +/**Macro to get the client from appropriate client list based on bit 14 of client ID.
   1.187 +   If the client is registered as thread relative, then check is made to make sure
   1.188 +   it is called from the same thread. */
   1.189 +#define VALIDATE_CLIENT(t)																						\
   1.190 +	if(aClientId & USER_SIDE_CLIENT_BIT_MASK)																	\
   1.191 +		pC = iUserSideClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];										\
   1.192 +	else																										\
   1.193 +		pC = iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];												\
   1.194 +	if(!pC)																										\
   1.195 +		{																										\
   1.196 +		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found"));											\
   1.197 +		UNLOCK_RETURN(KErrAccessDenied);																		\
   1.198 +		}																										\
   1.199 +	if(pC->iClientId  != aClientId)																				\
   1.200 +		{																										\
   1.201 +		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID does not match"));									\
   1.202 +		UNLOCK_RETURN(KErrAccessDenied);																		\
   1.203 +		}																										\
   1.204 +	if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK)															\
   1.205 +		{																										\
   1.206 +		if(pC->iThreadId != t.iId)																				\
   1.207 +			{																									\
   1.208 +			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client not called from thread context(Thread Relative)"));	\
   1.209 +			UNLOCK_RETURN(KErrAccessDenied);																	\
   1.210 +			}																									\
   1.211 +		}
   1.212 +
   1.213 +/** Macro to get the target client from appropriate client list based on bit 14 of client ID. */
   1.214 +#define GET_TARGET_CLIENT()																				\
   1.215 +	if(aTargetClientId & USER_SIDE_CLIENT_BIT_MASK) 													\
   1.216 +		pC = iUserSideClientList[(TUint16)(aTargetClientId & ID_INDEX_BIT_MASK)];	    				\
   1.217 +	else																								\
   1.218 +		pC = iClientList[(TUint16)(aTargetClientId & ID_INDEX_BIT_MASK)];								\
   1.219 +	if(!pC)																								\
   1.220 +		{																								\
   1.221 +		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Target Client ID not found"));							\
   1.222 +		UNLOCK_RETURN(KErrNotFound);																	\
   1.223 +		}																								\
   1.224 +	if(pC->iClientId != aTargetClientId)																\
   1.225 +		{																								\
   1.226 +		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID does not match"));							\
   1.227 +		UNLOCK_RETURN(KErrNotFound);																	\
   1.228 +		}
   1.229 +
   1.230 +/* Macro definition for entry point of Power Resource Controller */
   1.231 +#define DECLARE_RESOURCE_MANAGER_EXTENSION(TheController)															\
   1.232 +	TDfc* resourceInitDfc = NULL;																					\
   1.233 +	static void ResourceInit(TAny* aController)																		\
   1.234 +		{																											\
   1.235 +		TInt aReason = NKern::EThread;																				\
   1.236 +		PRM_BOOTING_TRACE																							\
   1.237 +		((DPowerResourceController*)aController)->InitResources();													\
   1.238 +		delete resourceInitDfc;																						\
   1.239 +		return;																										\
   1.240 +		}																											\
   1.241 +	void CreateController();																						\
   1.242 +	GLDEF_C TInt KernelModuleEntry(TInt aReason)																	\
   1.243 +		{																											\
   1.244 +		if(aReason==KModuleEntryReasonVariantInit0)																	\
   1.245 +			{																										\
   1.246 +			__KTRACE_OPT(KBOOT, Kern::Printf("Create Resource Controller"));										\
   1.247 +			CreateController();																						\
   1.248 +			return KErrNone;																						\
   1.249 +			}																										\
   1.250 +		if (aReason==KModuleEntryReasonExtensionInit0)																\
   1.251 +			return KExtensionMaximumPriority;																		\
   1.252 +		if (aReason!=KModuleEntryReasonExtensionInit1)																\
   1.253 +			return KErrArgument;																					\
   1.254 +		PRM_BOOTING_TRACE																							\
   1.255 +		__KTRACE_OPT(KBOOT, Kern::Printf("Initialise Resource Controller"));										\
   1.256 +		TInt r = KErrNone;																							\
   1.257 +		r = DPowerResourceController::InitController();																\
   1.258 +		if(r != KErrNone)																							\
   1.259 +			return r;																								\
   1.260 +		__KTRACE_OPT(KBOOT, Kern::Printf("Create PDD and queue ResourceInit DFC"));									\
   1.261 +		DResConPddFactory* device = new DResConPddFactory;															\
   1.262 +		if(!device)																									\
   1.263 +			return KErrNoMemory;																					\
   1.264 +		r = Kern::InstallPhysicalDevice(device);																	\
   1.265 +		if(r != KErrNone)																							\
   1.266 +			return r;																								\
   1.267 +		resourceInitDfc = new TDfc(&ResourceInit,(TAny*)&TheController,Kern::SvMsgQue(),KMaxDfcPriority-1);			\
   1.268 +		if(!resourceInitDfc)																						\
   1.269 +			return KErrNoMemory;																					\
   1.270 +		resourceInitDfc->Enque();																					\
   1.271 +       	return KErrNone;																							\
   1.272 +		}																											\
   1.273 +		GLDEF_C void CreateController()
   1.274 +
   1.275 +struct SPowerResourceClient;
   1.276 +struct TPowerRequest;
   1.277 +struct SPowerRequest;
   1.278 +struct SPowerResourceClientLevel;
   1.279 +struct SIdleResourceInfo;
   1.280 +class DPowerResourceController;
   1.281 +
   1.282 +/**
   1.283 +@internalComponent
   1.284 +@prototype 9.5
   1.285 +Interface class for Resource Manager
   1.286 +Functions from PowerResourceManager calls corresponding functions of this 
   1.287 +class which in turn calls Powercontroller functions.
   1.288 +*/
   1.289 +class TInterface
   1.290 +	{
   1.291 +public:
   1.292 +    static TInt RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType=EOwnerProcess);
   1.293 +    static TInt DeRegisterClient(TUint aClientId);
   1.294 +    static TInt GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName);
   1.295 +    static TInt GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId);
   1.296 +    static TInt GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId);
   1.297 +    static TInt GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo);
   1.298 +    static TInt GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources);
   1.299 +    static TInt GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources, TAny* aInfo);
   1.300 +    static TInt GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients);
   1.301 +    static TInt GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients, TAny* aInfo);
   1.302 +    static TInt AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm);
   1.303 +    static TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL);
   1.304 +    static TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId);
   1.305 +    static TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb);
   1.306 +    static TInt CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb);
   1.307 +    static TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
   1.308 +    static TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, TInt aThreshold, TBool aDirection);
   1.309 +    static TInt CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
   1.310 +	static TInt DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId);
   1.311 +    static DPowerResourceController* GetPowerResourceController(void);
   1.312 +    static TInt ControlIO(TUint aClientId, TUint aFunction, TAny* aParam1, TAny* aParam2, TAny* aParam3);
   1.313 +	};
   1.314 +
   1.315 +/**
   1.316 +@internalComponent
   1.317 +@prototype 9.5
   1.318 +Container class to create containers of pointers to clients.
   1.319 +*/
   1.320 +template <class T>
   1.321 +class DResourceCon : public DBase
   1.322 +	{
   1.323 +public:
   1.324 +    inline TInt Initialise(TUint16 aInitialSize);
   1.325 +    inline void Delete();
   1.326 +    inline T*  operator[](TUint16 aIndex);
   1.327 +    inline TInt Remove(T* aObj, TUint16 aIndex);
   1.328 +    inline TInt Add(T* aObj, TUint &aId);
   1.329 +    inline TInt Find(T*& anEntry, TDesC& aName);
   1.330 +    inline TInt ReSize(TUint16 aGrowBy);
   1.331 +    inline TUint16 Count() {return iCount;}
   1.332 +    inline TUint16 Allocd() {return iAllocated;}
   1.333 +	inline TUint16 GrowBy() {return iGrowBy;}
   1.334 +private:
   1.335 +    TUint16 iGrowBy; //Size to grow the size of the array.
   1.336 +    TUint16 iAllocated;  //Size of the array
   1.337 +    TUint16 iCount; //Valid entries in the array
   1.338 +    TUint16 iInstanceCount; //FreeCounter incremented whenever an entry is added.
   1.339 +    TUint16 iFreeLoc; //Cached free location in the array
   1.340 +    TUint16 iSpare;
   1.341 +    T** iArray;
   1.342 +	};
   1.343 +
   1.344 +/** 
   1.345 +@internalComponent
   1.346 +@prototype 9.5
   1.347 +Factory class for physical device 
   1.348 +*/
   1.349 +NONSHARABLE_CLASS(DResConPddFactory) : public DPhysicalDevice
   1.350 +	{
   1.351 +public:
   1.352 +	/**
   1.353 +	Structure for holding PDD capabilities information
   1.354 +	*/
   1.355 +	class TCaps
   1.356 +		{
   1.357 +	public:
   1.358 +		TVersion iVersion;
   1.359 +		};
   1.360 +public:
   1.361 +    DResConPddFactory();
   1.362 +    virtual TInt Install();
   1.363 +    virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
   1.364 +    virtual TInt Validate(TInt aUint, const TDesC8* anInfo, const TVersion& aVer);
   1.365 +    virtual void GetCaps(TDes8& aDes) const;
   1.366 +    inline static TVersion VersionRequired();
   1.367 +	};
   1.368 +
   1.369 +/**
   1.370 +@internalComponent
   1.371 +@prototype 9.5
   1.372 +Interface class for user side resource controller proxy. For each user side channel opened an object of 
   1.373 +this class is created in heap and pointer to resource controller is stored in iController member variable. 
   1.374 +User side resource controller proxy calls the resource controller API's by deferencing the pointer. 
   1.375 +This class is required as when the channel is closed the device driver framework tries to delete 
   1.376 +the object stored in ipdd, because of which it is not possible to pass the controller pointer directly.
   1.377 +*/
   1.378 +class DUserSideProxyInterface: public DBase
   1.379 +	{
   1.380 +	public:
   1.381 +	DPowerResourceController *iController;
   1.382 +	};
   1.383 +
   1.384 +
   1.385 +/** 
   1.386 +@publishedPartner
   1.387 +@prototype 9.5
   1.388 +resource manager implementation base class
   1.389 +*/
   1.390 +NONSHARABLE_CLASS (DPowerResourceController) : public DBase
   1.391 +	{
   1.392 +public:
   1.393 +    TInt RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType=EOwnerProcess);
   1.394 +    TInt DeRegisterClient(TUint aClientId);
   1.395 +    virtual TInt GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName);
   1.396 +    virtual TInt GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId);
   1.397 +    virtual TInt GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId);
   1.398 +    virtual TInt GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo);
   1.399 +    virtual TInt GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources);
   1.400 +    virtual TInt GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources, TAny* aInfo);
   1.401 +    virtual TInt GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients);
   1.402 +    virtual TInt GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients, TAny* aInfo);
   1.403 +    virtual TInt AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm);
   1.404 +    virtual TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL);
   1.405 +    virtual TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId);
   1.406 +    virtual TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb);
   1.407 +    virtual TInt CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb);
   1.408 +    virtual TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
   1.409 +    virtual TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, TInt aThreshold, TBool aDirection);
   1.410 +    virtual TInt CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
   1.411 +    virtual TInt DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId);
   1.412 +public:
   1.413 +	enum TResConPanic
   1.414 +		{
   1.415 +		ECalledFromDfcThread0 = 0,
   1.416 +		ECalledFromIsr = 1,
   1.417 +		ECalledFromNullThread = 2,
   1.418 +		ECalledFromDfcThread1 = 3,
   1.419 +		EClientHasPendingAsyncRequest = 4,
   1.420 +		EClientHasNotificationObject = 5,
   1.421 +		EControllerAlreadyExists = 6,
   1.422 +		ECustomFunctionNotSet = 7,
   1.423 +		EClientIdNotInClientLevelList = 8,
   1.424 +		ENoMemToCreatePowerControllerClient = 9,
   1.425 +		EResourceNameExceedsLimit = 10, 
   1.426 +		EObjectNotFoundInList = 11 
   1.427 +		};
   1.428 +#ifdef PRM_ENABLE_EXTENDED_VERSION	
   1.429 +	enum TExtendedResConPanic
   1.430 +		{
   1.431 +		EClosedLoopDependencies = EObjectNotFoundInList + 2, //13
   1.432 +		ERegisteringNonDependentStaticResource = 14,
   1.433 +		EClientHasDynamicResourceRegistered = 15,
   1.434 +		EDynamicResourceStillRegistered = 16,
   1.435 +		ERegisteringDependentStaticResourceWithHoles = 17
   1.436 +		};
   1.437 +#endif
   1.438 +	enum TResConStartSequence
   1.439 +		{
   1.440 +		EResConCreated,
   1.441 +		EResConInitialised,
   1.442 +		EResConStartupCompleted
   1.443 +		};
   1.444 +    //early initialization
   1.445 +    IMPORT_C static TInt InitController();
   1.446 +    TInt InitResources();
   1.447 +    //request a post-boot level for the resource
   1.448 +    IMPORT_C static TInt PostBootLevel(TUint aResId, TInt aLevel);
   1.449 +    //request registration of static resource
   1.450 +    IMPORT_C static TInt RegisterStaticResource(TUint aClientId, DStaticPowerResource* pR);
   1.451 +	//request registration of group/array of static resources
   1.452 +	IMPORT_C static TInt RegisterArrayOfStaticResources(TUint aClientId, DStaticPowerResource**& aStaticResourceArray, TUint aResCount);
   1.453 +    //registration for proxy client
   1.454 +    virtual TInt RegisterProxyClient(TUint& aProxyId, const TDesC8& aName);
   1.455 +    virtual TInt DeregisterProxyClient(TUint aClientId);
   1.456 +    //register list of resources whose state matter to Idle
   1.457 +    virtual TInt RegisterResourcesForIdle(TInt aPowerControllerId, TUint aNumResources, TPtr* aBuf);
   1.458 +    static void Panic(TUint8 aPanic);
   1.459 +    virtual TInt GetInterface(TUint aClientId, TUint aInterfaceId, TAny* aParam1, TAny* aParam2, TAny* aParam3);
   1.460 +	virtual ~DPowerResourceController();
   1.461 +	/**@internalComponent*/
   1.462 +	void CompleteNotifications(TInt aClientId, DStaticPowerResource* aResource, TInt aState, TInt aReturnCode, TInt aLevelOwnerId, TBool aLock = ETrue);
   1.463 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.464 +	/**@internalComponent*/
   1.465 +	TInt ReserveClientLevelPoolCount(TUint16 aCount);
   1.466 +	/**@internalComponent*/
   1.467 +	void RemoveClientLevelFromPool(SPowerResourceClientLevel *&aLevelPtr);
   1.468 +	/**@internalComponent*/
   1.469 +	TInt HandleResourceChange(TPowerRequest &aRequest, TPropagation aProp, TUint aOriginatorId,
   1.470 +									const TDesC8& aOriginatorName, DStaticPowerResourceD* aResource);
   1.471 +#endif
   1.472 +protected:
   1.473 +    //generic layer function to be called by the PSL
   1.474 +    DPowerResourceController();
   1.475 +    void SetDfcQ(TDfcQue* aDfcQ);
   1.476 +	#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.477 +    void SetDfcQDependency(TDfcQue* aDfcQ);
   1.478 +	#endif
   1.479 +    TInt InitPools(TUint16 aKClients, TUint16 aUClients, TUint16 aNClientLevels, TUint16 aNRequests);
   1.480 +	/* Lock the resource controller mutex */
   1.481 +	inline void Lock()	{ NKern::ThreadEnterCS();
   1.482 +						  Kern::MutexWait(*iResourceMutex); }
   1.483 +	inline void UnLock()	{ Kern::MutexSignal(*iResourceMutex);
   1.484 +							  NKern::ThreadLeaveCS();}
   1.485 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.486 +	//Default implementation, PSL re-implements these if features supported
   1.487 +	virtual TInt DoRegisterStaticResourcesDependency(DStaticPowerResourceD**& aStaticResourceDArray, TUint16& aStaticResourceDCount);
   1.488 +#endif
   1.489 +private:
   1.490 +    // pure virtual implemented by PSL - to be called by PIL
   1.491 +    virtual TInt DoInitController()=0;
   1.492 +    virtual TInt DoRegisterStaticResources(DStaticPowerResource**& aStaticResourceArray, TUint16& aStaticResourceCount)=0;
   1.493 +    /**@internalComponent*/
   1.494 +    TInt CheckLevelAndAddClient(SPowerResourceClient* pC, TPowerRequest* Request);
   1.495 +    static void MsgQFunc(TAny* aPtr);
   1.496 +    #ifdef PRM_ENABLE_EXTENDED_VERSION
   1.497 +    static void MsgQDependencyFunc(TAny* aPtr);
   1.498 +    #endif
   1.499 +    
   1.500 +	/**@internalComponent*/
   1.501 +	void ResourceStateChangeOfClientLevels(SPowerResourceClient* pC);
   1.502 +	/**@internalComponent*/
   1.503 +    void HandleMsg(TPowerRequest& aRequest);
   1.504 +	#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.505 +    /**@internalComponent*/
   1.506 +    void HandleDependencyMsg(TPowerRequest& aRequest);
   1.507 +	#endif
   1.508 +	/**@internalComponent*/
   1.509 +    void CompleteRequest(TPowerRequest& aRequest);
   1.510 +	/**@internalComponent*/
   1.511 +    void MoveRequestToFreePool(TPowerRequest *aReq);
   1.512 +	/**@internalComponent*/
   1.513 +	TInt HandleReservationOfObjects(TPowerRequest& aRequest);
   1.514 +	/**@internalComponent*/
   1.515 +	TInt HandleClientRegistration(TPowerRequest& aRequest);
   1.516 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.517 +	TInt RegisterDynamicResource(SPowerResourceClient* aClientPtr, DDynamicPowerResource* aPDRes, TUint* aDynamicResourceId);
   1.518 +	TInt DeregisterDynamicResource(SPowerResourceClient* aClientPtr, TUint aDynamicResourceId, TInt* aPDefLevel);
   1.519 +	TInt RegisterResourceDependency(SPowerResourceClient* aClientPtr, SResourceDependencyInfo* aInfo1, SResourceDependencyInfo* aInfo2);
   1.520 +	/**@internalComponent*/
   1.521 +	void CheckForDependencyLoop(DStaticPowerResourceD* pR, TUint aParentResId, TUint aTargetResId);
   1.522 +	TInt DeregisterResourceDependency(SPowerResourceClient* aClientPtr, TUint aResId1, TUint aResId2);
   1.523 +	/**@internalComponent*/
   1.524 +	TInt HandleDependencyResourceStateChange(SPowerResourceClient* pC, TPowerRequest& aRequest);
   1.525 +	TInt GetNumDependentsForResource(TUint aResourceId, TUint* aNumResources);
   1.526 +	TInt GetDependentsIdForResource(TUint aResourceId, TAny* aInfo, TUint* aNumDepResources);
   1.527 +	TInt HandleResourceRegistration(TPowerRequest& aReq);
   1.528 +#endif
   1.529 +public:
   1.530 +	DMutex* iResourceMutex;
   1.531 +protected:
   1.532 +    TDfcQue* iDfcQ;
   1.533 +    TMessageQue *iMsgQ;
   1.534 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.535 +	TDfcQue* iDfcQDependency;
   1.536 +	TMessageQue* iMsgQDependency;
   1.537 +	TBool iDfcQDependencyLock;
   1.538 +#endif
   1.539 +private:
   1.540 +    DStaticPowerResource** iStaticResourceArray;
   1.541 +    DResourceCon<SPowerResourceClient> iClientList;
   1.542 +    DResourceCon<SPowerResourceClient> iUserSideClientList;
   1.543 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
   1.544 +	RPointerArray<SPowerResourceClient> iCleanList;
   1.545 +#endif
   1.546 +    SPowerResourceClient* iClientPool;
   1.547 +    SPowerRequest* iRequestPool;
   1.548 +    SPowerResourceClientLevel* iClientLevelPool;
   1.549 +	TUint iPowerControllerId; //Stores the ID allocated to PowerController
   1.550 +    SIdleResourceInfo* iListForIdle;
   1.551 +    TUint iInitialised;
   1.552 +    TUint16 iClientCount;
   1.553 +    TUint16 iUserSideClientCount;
   1.554 +    TUint16 iClientLevelPoolCount;
   1.555 +    TUint16 iClientLevelPoolGrowBy;
   1.556 +    TUint16 iRequestPoolCount;
   1.557 +    TUint16 iRequestPoolGrowBy;
   1.558 +    TUint16 iStaticResourceArrayEntries; //Number of entries in the array including holes if any.
   1.559 +	TUint16 iStaticResourceCount;  //Actual number of static resources registered (valid entries).
   1.560 +	TUint	iReserved2; //Reserved for future use
   1.561 +#ifdef PRM_ENABLE_EXTENDED_VERSION
   1.562 +	DResourceCon<DDynamicPowerResource> iDynamicResourceList;
   1.563 +	DResourceCon<DDynamicPowerResourceD> iDynamicResDependencyList;
   1.564 +	DStaticPowerResourceD** iStaticResDependencyArray;
   1.565 +	SPowerResourceClientLevel* iResourceLevelPool;
   1.566 +	TUint16 iResourceLevelPoolCount;
   1.567 +	TUint16 iStaticResDependencyCount;
   1.568 +	TUint16 iDynamicResourceCount;
   1.569 +	TUint8 iDynamicResDependencyCount;
   1.570 +	TUint8 iSpare2;
   1.571 +	TUint  iReserved3; //Reserved for future use.
   1.572 +#endif
   1.573 +	};
   1.574 +
   1.575 +/**
   1.576 +@publishedPartner
   1.577 +@prototype 9.5
   1.578 +power level of client in a shared resource
   1.579 +*/
   1.580 +struct SPowerResourceClientLevel : public SDblQueLink
   1.581 +	{
   1.582 +    TUint iClientId;
   1.583 +    TUint iResourceId;
   1.584 +    TInt iLevel;
   1.585 +    SPowerResourceClientLevel* iNextInList;
   1.586 +	};
   1.587 +
   1.588 +/**
   1.589 +@internalComponent 
   1.590 +@prototype 9.5
   1.591 +respresent client in resource manager
   1.592 +*/
   1.593 +struct SPowerResourceClient
   1.594 +	{
   1.595 +    TUint iClientId;
   1.596 +    const TDesC8* iName;
   1.597 +    SPowerResourceClient* iNextInList;
   1.598 +    SPowerResourceClientLevel* iLevelList;
   1.599 +    DPowerResourceNotification* iNotificationList;
   1.600 +    TUint8 iReservedCl;
   1.601 +    TUint8 iReservedRm;
   1.602 +    TUint8 iPendingReqCount;
   1.603 +    TUint8 iUnderFlowRmCount;
   1.604 +    TUint8 iUnderFlowClCount;
   1.605 +	TUint8 iDynamicResCount; //Counter for dynamic resource registered by the client. Used only in extended version
   1.606 +	TUint8 iSpare1;
   1.607 +	TUint8 iSpare2;
   1.608 +    union
   1.609 +       {
   1.610 +       TUint iThreadId;
   1.611 +       TAny* iSpare3;
   1.612 +       };
   1.613 +	};
   1.614 +
   1.615 +/**
   1.616 +@publishedPartner
   1.617 +@prototype 9.5
   1.618 +represents a request inside the resource manager
   1.619 +*/
   1.620 +struct TPowerRequest : public TThreadMessage
   1.621 +	{
   1.622 +    /** requests can either be to get the resource value or to change the resource value*/
   1.623 +    enum TReqType {EGet, EChange, ESetDefaultLevel, ERegisterKernelClient, ERegisterUsersideClient, EAllocReserve,
   1.624 +					ERegisterDynamicResource	};
   1.625 +    /** @return thread's own message and turn into a power request. Used for sync/instant calls*/
   1.626 +    inline static TPowerRequest& Get()
   1.627 +            {return (TPowerRequest&)Kern::Message();}
   1.628 +    /** @return type of request get or set */
   1.629 +    inline TReqType& ReqType()		// one of TReqType
   1.630 +            {return *(TReqType*)&iValue;}
   1.631 +    /** @return resource id which is being requested*/
   1.632 +    inline TUint& ResourceId()
   1.633 +            {return *(TUint*)&iArg[0];}
   1.634 +    /** @return id of client making request (only valid on change requests)*/
   1.635 +    inline TInt& ClientId()
   1.636 +            {return *(TInt*)&iArg[1];}
   1.637 +	/**
   1.638 +	    On resource state change operations the PIL sets this field with the required level before 
   1.639 +		invoking the DoRequest(..) function; on return from DoRequest(..) function the PSL sets this field
   1.640 +		with the real state of the resource to be cached by the PIL.On resource state read operations PSL
   1.641 +		sets it with the level read.
   1.642 +	*/
   1.643 +	inline TInt& Level()		
   1.644 +            {return *(TInt*)&iArg[2];}
   1.645 +    /** @return pointer the resource being requested */
   1.646 +    inline DStaticPowerResource*& Resource()
   1.647 +            {return *(DStaticPowerResource**)&iArg[3];}
   1.648 +    /** @return pointer to resource callback structure, used for async requests */
   1.649 +    inline TPowerResourceCb*& ResourceCb()
   1.650 +            {return *(TPowerResourceCb**)&iArg[4];}
   1.651 +    /** @return return code of resource's DoRequest function when request has been processed */
   1.652 +    inline TInt& ReturnCode()
   1.653 +            {return *(TInt*)&iArg[5];}
   1.654 +    /** @return return ETrue if a change is required on a shared resource */
   1.655 +    inline TBool& RequiresChange()
   1.656 +            {return *(TInt*)&iArg[6];}
   1.657 +	/** @return number of client level objects requested by a client to reserve */
   1.658 +	inline TInt& ClientLevelCount()
   1.659 +			{return *(TInt*)&iArg[7];}
   1.660 +	/** @return number of request objects requested by a client to reserve */
   1.661 +	inline TInt& RequestCount()
   1.662 +			{return *(TInt*)&iArg[8];}
   1.663 +	};
   1.664 +
   1.665 +/**
   1.666 +@internalComponent
   1.667 +@prototype 9.5
   1.668 +*/
   1.669 +struct SPowerRequest
   1.670 +	{
   1.671 +    TPowerRequest iRequest;
   1.672 +    SPowerRequest* iNext;
   1.673 +	};
   1.674 +
   1.675 +/**
   1.676 +@publishedPartner
   1.677 +@prototype 9.5
   1.678 +Structure representing resource information used for Idle power management
   1.679 +*/
   1.680 +struct SIdleResourceInfo
   1.681 +	{
   1.682 +    TUint iResourceId; 
   1.683 +    TInt iLevelOwnerId; //Owner of the resource.  
   1.684 +    TInt iCurrentLevel; //Cached resource state
   1.685 +	TInt iReserved1;	//Reserved for future use.
   1.686 +	TInt iReserved2;	//Reserved for future use.
   1.687 +	TInt iReserved3;	//Reserved for future use.
   1.688 +	};
   1.689 +
   1.690 +#include <drivers/resourcecontrol.inl>
   1.691 +
   1.692 +#endif //__RESOURCECONTROL_H__
   1.693 +
   1.694 +