kernel/eka/include/drivers/resourcecontrol.h
changeset 9 96e5fb8b040d
equal deleted inserted replaced
-1:000000000000 9:96e5fb8b040d
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32\include\drivers\resourcecontrol.h
       
    15 // 
       
    16 // WARNING: This file contains some APIs which are internal and are subject
       
    17 //          to change without notice. Such APIs should therefore not be used
       
    18 //          outside the Kernel and Hardware Services package.
       
    19 //
       
    20 
       
    21 #ifndef __RESOURCECONTROL_H__
       
    22 #define __RESOURCECONTROL_H__
       
    23 #include <nklib.h>
       
    24 #include <kernel/kernel.h>
       
    25 #include <kernel/kern_priv.h>
       
    26 #include <e32ver.h>
       
    27 #define PRM_CONTROLLER
       
    28 #ifndef PRM_ENABLE_EXTENDED_VERSION
       
    29 #include <drivers/resource.h>
       
    30 #else
       
    31 #include <drivers/resource_extend.h>
       
    32 #endif 
       
    33 #include <drivers/resourceman.h>
       
    34 
       
    35 /** #defines for client bit masks */
       
    36 #define ID_INDEX_BIT_MASK 0x3FFF  /* bit 0 -13 */
       
    37 #define USER_SIDE_CLIENT_BIT_MASK 0x4000 //Bit 14
       
    38 #define CLIENT_THREAD_RELATIVE_BIT_MASK 0x80000000 //Bit 31
       
    39 #define INSTANCE_COUNT_BIT_MASK 0x1FFF //13 Bits
       
    40 #define INSTANCE_COUNT_POS 18
       
    41 #define CLIENT_POWER_CONTROLLER_BIT_MASK 0x8000 //Bit 15
       
    42 /** Bit to indicate valid post boot level in resource */
       
    43 #define SET_VALID_POST_BOOT_LEVEL 0x8000 //Bit 15
       
    44 
       
    45 #define RESOURCE_NOT_IN_OPERATION 0x1	
       
    46 #define PRM_DYNAMIC_RESOURCE_INITIAL_SIZE 2
       
    47 
       
    48 #define PRM_STATIC_RESOURCE					0x0
       
    49 #define PRM_STATIC_DEPENDENCY_RESOURCE		0x1
       
    50 #define PRM_DYNAMIC_RESOURCE				0x2	
       
    51 #define PRM_DYNAMIC_DEPENDENCY_RESOURCE		0x3
       
    52 #define RESOURCE_BIT_IN_ID_CHECK			16
       
    53 
       
    54 
       
    55 static const TInt KMaxResourceNameLength=0x20; //Maximum allowable resource length is 32 characters.
       
    56 static const TInt KMaxClientNameLength=0x20; //Maximum allowable client length is 32 characters.
       
    57 
       
    58 
       
    59 _LIT8(KPowerController, "PowerController");
       
    60 _LIT8(KDfcThread1Name, "DfcThread1");
       
    61 _LIT8(KDfcThread0Name, "DfcThread0");
       
    62 _LIT8(KNullThreadName, "Null");
       
    63 _LIT8(KNoClient, "NoClient");
       
    64 _LIT8(KParentResource, "ParentResource");
       
    65 /** Macro to check the context of client calling RM API.
       
    66     Panics if it is called from ISR, IDFC, NULL thread or DFC thread1 */
       
    67 #ifdef DEBUG_VERSION
       
    68 #define CHECK_CONTEXT(t)																\
       
    69 	__ASSERT_ALWAYS(NKern::CurrentContext() == NKern::EThread, Panic(ECalledFromIsr));	\
       
    70 	const TDesC8* pDfc1 = &KDfcThread1Name;												\
       
    71 	if(!pDfc1->Compare(*(TDesC8*)t.iName))												\
       
    72 		Panic(ECalledFromDfcThread1);													\
       
    73     const TDesC8* pNull = &KNullThreadName;												\
       
    74 	if(!pNull->Compare(*(TDesC8*)t.iName))												\
       
    75 		Panic(ECalledFromNullThread);
       
    76 #else
       
    77 #define CHECK_CONTEXT(t)
       
    78 #endif
       
    79 
       
    80 /** Macro to unlock and return */
       
    81 #define UNLOCK_RETURN(retval)       \
       
    82     {                               \
       
    83     UnLock();                       \
       
    84     return(retval);                 \
       
    85     }
       
    86 
       
    87 /** Macro to push the item into the specified list. Item are pushed to the head of the list. */
       
    88 #define LIST_PUSH(list,item,link)	\
       
    89 	{                               \
       
    90 	(item)->link = (list);			\
       
    91 	(list) = (item);                \
       
    92 	}
       
    93 
       
    94 /** Macro to pop the item from the specified list. Item are poped from the head of the list. */
       
    95 #define LIST_POP(list,item,link)	\
       
    96 	{                               \
       
    97 	(item) = (list);				\
       
    98 	if ((item))						\
       
    99 		{							\
       
   100 		(list) = (item)->link;		\
       
   101 		(item)->link = NULL;		\
       
   102 		}                           \
       
   103 	}
       
   104 
       
   105 /** Macro to remove the item from the list. */
       
   106 #define LIST_REMOVE(list,item,link,className)		\
       
   107 	if (list)										\
       
   108 		{											\
       
   109 		className* current = (list);				\
       
   110 		if (current==(item))						\
       
   111 			{										\
       
   112 			(list) = (item)->link;					\
       
   113 			(item)->link = NULL;					\
       
   114 			}										\
       
   115 		else										\
       
   116 			{										\
       
   117 			className* next = current->link;		\
       
   118 			while (next)							\
       
   119 				{									\
       
   120 				if ((item)==next)					\
       
   121 					{								\
       
   122 					current->link=next->link;		\
       
   123 					next->link = NULL;				\
       
   124 					break;							\
       
   125 					}								\
       
   126 				current = next;						\
       
   127 				next = next->link;					\
       
   128 				}									\
       
   129 			}										\
       
   130 		}
       
   131 
       
   132 
       
   133 /* Macro to add dynamic resource to appropriate containers. Used only in extended version */
       
   134 #define ADD_TO_RESOURCE_CONTAINER(list, res, resId, resIdCount)				\
       
   135 	{																		\
       
   136 	TUint16 growBy = (list).GrowBy();										\
       
   137 	if(!growBy)																\
       
   138 		(list).Initialise((TUint16)PRM_DYNAMIC_RESOURCE_INITIAL_SIZE);		\
       
   139 	if((list).Add(res, resId) == KErrNoMemory)								\
       
   140 		{																	\
       
   141 		TInt r = (list).ReSize(growBy);										\
       
   142 		if(r != KErrNone)													\
       
   143 			return r;														\
       
   144 		(list).Add(res, resId);												\
       
   145 		}																	\
       
   146 	res->iResourceId |= resId;												\
       
   147 	resId = res->iResourceId;												\
       
   148 	resIdCount++;															\
       
   149 	}
       
   150 	
       
   151 /* Macro to get the resource from appropriate list. Used only in extended version */
       
   152 #define GET_RESOURCE_FROM_LIST(resId, res)														\
       
   153 	{																							\
       
   154 	switch((resId >> RESOURCE_BIT_IN_ID_CHECK) & 0x3)											\
       
   155 		{																						\
       
   156 		case PRM_STATIC_RESOURCE:																\
       
   157 			if(resId > iStaticResourceArrayEntries)												\
       
   158 				UNLOCK_RETURN(KErrNotFound);													\
       
   159 			res = iStaticResourceArray[resId - 1];												\
       
   160 			if(!res)																			\
       
   161 				UNLOCK_RETURN(KErrNotFound);													\
       
   162 			break;																				\
       
   163 		case PRM_STATIC_DEPENDENCY_RESOURCE:													\
       
   164 			if((TUint16)(resId & ID_INDEX_BIT_MASK) > iStaticResDependencyCount)				\
       
   165 				UNLOCK_RETURN(KErrNotFound);													\
       
   166 			res = iStaticResDependencyArray[(TUint16)(resId & ID_INDEX_BIT_MASK)  - 1];			\
       
   167 			break;																				\
       
   168 		case PRM_DYNAMIC_RESOURCE:																\
       
   169 			res = iDynamicResourceList[(TUint16)(resId & ID_INDEX_BIT_MASK)];					\
       
   170 			if(!res)																			\
       
   171 				UNLOCK_RETURN(KErrNotFound);													\
       
   172 			break;																				\
       
   173 		case PRM_DYNAMIC_DEPENDENCY_RESOURCE:													\
       
   174 			res = iDynamicResDependencyList[(TUint16)(resId & ID_INDEX_BIT_MASK)];				\
       
   175 			if(!res)																			\
       
   176 				UNLOCK_RETURN(KErrNotFound);													\
       
   177 			break;																				\
       
   178 		default:																				\
       
   179 			UNLOCK_RETURN(KErrArgument);														\
       
   180 		}																						\
       
   181 	}
       
   182 
       
   183 /**Macro to get the client from appropriate client list based on bit 14 of client ID.
       
   184    If the client is registered as thread relative, then check is made to make sure
       
   185    it is called from the same thread. */
       
   186 #define VALIDATE_CLIENT(t)																						\
       
   187 	if(aClientId & USER_SIDE_CLIENT_BIT_MASK)																	\
       
   188 		pC = iUserSideClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];										\
       
   189 	else																										\
       
   190 		pC = iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];												\
       
   191 	if(!pC)																										\
       
   192 		{																										\
       
   193 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found"));											\
       
   194 		UNLOCK_RETURN(KErrAccessDenied);																		\
       
   195 		}																										\
       
   196 	if(pC->iClientId  != aClientId)																				\
       
   197 		{																										\
       
   198 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID does not match"));									\
       
   199 		UNLOCK_RETURN(KErrAccessDenied);																		\
       
   200 		}																										\
       
   201 	if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK)															\
       
   202 		{																										\
       
   203 		if(pC->iThreadId != t.iId)																				\
       
   204 			{																									\
       
   205 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client not called from thread context(Thread Relative)"));	\
       
   206 			UNLOCK_RETURN(KErrAccessDenied);																	\
       
   207 			}																									\
       
   208 		}
       
   209 
       
   210 /** Macro to get the target client from appropriate client list based on bit 14 of client ID. */
       
   211 #define GET_TARGET_CLIENT()																				\
       
   212 	if(aTargetClientId & USER_SIDE_CLIENT_BIT_MASK) 													\
       
   213 		pC = iUserSideClientList[(TUint16)(aTargetClientId & ID_INDEX_BIT_MASK)];	    				\
       
   214 	else																								\
       
   215 		pC = iClientList[(TUint16)(aTargetClientId & ID_INDEX_BIT_MASK)];								\
       
   216 	if(!pC)																								\
       
   217 		{																								\
       
   218 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Target Client ID not found"));							\
       
   219 		UNLOCK_RETURN(KErrNotFound);																	\
       
   220 		}																								\
       
   221 	if(pC->iClientId != aTargetClientId)																\
       
   222 		{																								\
       
   223 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID does not match"));							\
       
   224 		UNLOCK_RETURN(KErrNotFound);																	\
       
   225 		}
       
   226 
       
   227 /* Macro definition for entry point of Power Resource Controller */
       
   228 #define DECLARE_RESOURCE_MANAGER_EXTENSION(TheController)															\
       
   229 	TDfc* resourceInitDfc = NULL;																					\
       
   230 	static void ResourceInit(TAny* aController)																		\
       
   231 		{																											\
       
   232 		TInt aReason = NKern::EThread;																				\
       
   233 		PRM_BOOTING_TRACE																							\
       
   234 		((DPowerResourceController*)aController)->InitResources();													\
       
   235 		delete resourceInitDfc;																						\
       
   236 		return;																										\
       
   237 		}																											\
       
   238 	void CreateController();																						\
       
   239 	GLDEF_C TInt KernelModuleEntry(TInt aReason)																	\
       
   240 		{																											\
       
   241 		if(aReason==KModuleEntryReasonVariantInit0)																	\
       
   242 			{																										\
       
   243 			__KTRACE_OPT(KBOOT, Kern::Printf("Create Resource Controller"));										\
       
   244 			CreateController();																						\
       
   245 			return KErrNone;																						\
       
   246 			}																										\
       
   247 		if (aReason==KModuleEntryReasonExtensionInit0)																\
       
   248 			return KExtensionMaximumPriority;																		\
       
   249 		if (aReason!=KModuleEntryReasonExtensionInit1)																\
       
   250 			return KErrArgument;																					\
       
   251 		PRM_BOOTING_TRACE																							\
       
   252 		__KTRACE_OPT(KBOOT, Kern::Printf("Initialise Resource Controller"));										\
       
   253 		TInt r = KErrNone;																							\
       
   254 		r = DPowerResourceController::InitController();																\
       
   255 		if(r != KErrNone)																							\
       
   256 			return r;																								\
       
   257 		__KTRACE_OPT(KBOOT, Kern::Printf("Create PDD and queue ResourceInit DFC"));									\
       
   258 		DResConPddFactory* device = new DResConPddFactory;															\
       
   259 		if(!device)																									\
       
   260 			return KErrNoMemory;																					\
       
   261 		r = Kern::InstallPhysicalDevice(device);																	\
       
   262 		if(r != KErrNone)																							\
       
   263 			return r;																								\
       
   264 		resourceInitDfc = new TDfc(&ResourceInit,(TAny*)&TheController,Kern::SvMsgQue(),KMaxDfcPriority-1);			\
       
   265 		if(!resourceInitDfc)																						\
       
   266 			return KErrNoMemory;																					\
       
   267 		resourceInitDfc->Enque();																					\
       
   268        	return KErrNone;																							\
       
   269 		}																											\
       
   270 		GLDEF_C void CreateController()
       
   271 
       
   272 struct SPowerResourceClient;
       
   273 struct TPowerRequest;
       
   274 struct SPowerRequest;
       
   275 struct SPowerResourceClientLevel;
       
   276 struct SIdleResourceInfo;
       
   277 class DPowerResourceController;
       
   278 
       
   279 /**
       
   280 @internalComponent
       
   281 @prototype 9.5
       
   282 Interface class for Resource Manager
       
   283 Functions from PowerResourceManager calls corresponding functions of this 
       
   284 class which in turn calls Powercontroller functions.
       
   285 */
       
   286 class TInterface
       
   287 	{
       
   288 public:
       
   289     static TInt RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType=EOwnerProcess);
       
   290     static TInt DeRegisterClient(TUint aClientId);
       
   291     static TInt GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName);
       
   292     static TInt GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId);
       
   293     static TInt GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId);
       
   294     static TInt GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo);
       
   295     static TInt GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources);
       
   296     static TInt GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources, TAny* aInfo);
       
   297     static TInt GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients);
       
   298     static TInt GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients, TAny* aInfo);
       
   299     static TInt AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm);
       
   300     static TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL);
       
   301     static TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId);
       
   302     static TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb);
       
   303     static TInt CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb);
       
   304     static TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
       
   305     static TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, TInt aThreshold, TBool aDirection);
       
   306     static TInt CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
       
   307 	static TInt DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId);
       
   308     static DPowerResourceController* GetPowerResourceController(void);
       
   309     static TInt ControlIO(TUint aClientId, TUint aFunction, TAny* aParam1, TAny* aParam2, TAny* aParam3);
       
   310 	};
       
   311 
       
   312 /**
       
   313 @internalComponent
       
   314 @prototype 9.5
       
   315 Container class to create containers of pointers to clients.
       
   316 */
       
   317 template <class T>
       
   318 class DResourceCon : public DBase
       
   319 	{
       
   320 public:
       
   321     inline TInt Initialise(TUint16 aInitialSize);
       
   322     inline void Delete();
       
   323     inline T*  operator[](TUint16 aIndex);
       
   324     inline TInt Remove(T* aObj, TUint16 aIndex);
       
   325     inline TInt Add(T* aObj, TUint &aId);
       
   326     inline TInt Find(T*& anEntry, TDesC& aName);
       
   327     inline TInt ReSize(TUint16 aGrowBy);
       
   328     inline TUint16 Count() {return iCount;}
       
   329     inline TUint16 Allocd() {return iAllocated;}
       
   330 	inline TUint16 GrowBy() {return iGrowBy;}
       
   331 private:
       
   332     TUint16 iGrowBy; //Size to grow the size of the array.
       
   333     TUint16 iAllocated;  //Size of the array
       
   334     TUint16 iCount; //Valid entries in the array
       
   335     TUint16 iInstanceCount; //FreeCounter incremented whenever an entry is added.
       
   336     TUint16 iFreeLoc; //Cached free location in the array
       
   337     TUint16 iSpare;
       
   338     T** iArray;
       
   339 	};
       
   340 
       
   341 /** 
       
   342 @internalComponent
       
   343 @prototype 9.5
       
   344 Factory class for physical device 
       
   345 */
       
   346 NONSHARABLE_CLASS(DResConPddFactory) : public DPhysicalDevice
       
   347 	{
       
   348 public:
       
   349 	/**
       
   350 	Structure for holding PDD capabilities information
       
   351 	*/
       
   352 	class TCaps
       
   353 		{
       
   354 	public:
       
   355 		TVersion iVersion;
       
   356 		};
       
   357 public:
       
   358     DResConPddFactory();
       
   359     virtual TInt Install();
       
   360     virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
       
   361     virtual TInt Validate(TInt aUint, const TDesC8* anInfo, const TVersion& aVer);
       
   362     virtual void GetCaps(TDes8& aDes) const;
       
   363     inline static TVersion VersionRequired();
       
   364 	};
       
   365 
       
   366 /**
       
   367 @internalComponent
       
   368 @prototype 9.5
       
   369 Interface class for user side resource controller proxy. For each user side channel opened an object of 
       
   370 this class is created in heap and pointer to resource controller is stored in iController member variable. 
       
   371 User side resource controller proxy calls the resource controller API's by deferencing the pointer. 
       
   372 This class is required as when the channel is closed the device driver framework tries to delete 
       
   373 the object stored in ipdd, because of which it is not possible to pass the controller pointer directly.
       
   374 */
       
   375 class DUserSideProxyInterface: public DBase
       
   376 	{
       
   377 	public:
       
   378 	DPowerResourceController *iController;
       
   379 	};
       
   380 
       
   381 
       
   382 /** 
       
   383 @publishedPartner
       
   384 @prototype 9.5
       
   385 resource manager implementation base class
       
   386 */
       
   387 NONSHARABLE_CLASS (DPowerResourceController) : public DBase
       
   388 	{
       
   389 public:
       
   390     TInt RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType=EOwnerProcess);
       
   391     TInt DeRegisterClient(TUint aClientId);
       
   392     virtual TInt GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName);
       
   393     virtual TInt GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId);
       
   394     virtual TInt GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId);
       
   395     virtual TInt GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo);
       
   396     virtual TInt GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources);
       
   397     virtual TInt GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources, TAny* aInfo);
       
   398     virtual TInt GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients);
       
   399     virtual TInt GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients, TAny* aInfo);
       
   400     virtual TInt AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm);
       
   401     virtual TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL);
       
   402     virtual TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId);
       
   403     virtual TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb);
       
   404     virtual TInt CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb);
       
   405     virtual TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
       
   406     virtual TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, TInt aThreshold, TBool aDirection);
       
   407     virtual TInt CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
       
   408     virtual TInt DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId);
       
   409 public:
       
   410 	enum TResConPanic
       
   411 		{
       
   412 		ECalledFromDfcThread0 = 0,
       
   413 		ECalledFromIsr = 1,
       
   414 		ECalledFromNullThread = 2,
       
   415 		ECalledFromDfcThread1 = 3,
       
   416 		EClientHasPendingAsyncRequest = 4,
       
   417 		EClientHasNotificationObject = 5,
       
   418 		EControllerAlreadyExists = 6,
       
   419 		ECustomFunctionNotSet = 7,
       
   420 		EClientIdNotInClientLevelList = 8,
       
   421 		ENoMemToCreatePowerControllerClient = 9,
       
   422 		EResourceNameExceedsLimit = 10, 
       
   423 		EObjectNotFoundInList = 11 
       
   424 		};
       
   425 #ifdef PRM_ENABLE_EXTENDED_VERSION	
       
   426 	enum TExtendedResConPanic
       
   427 		{
       
   428 		EClosedLoopDependencies = EObjectNotFoundInList + 2, //13
       
   429 		ERegisteringNonDependentStaticResource = 14,
       
   430 		EClientHasDynamicResourceRegistered = 15,
       
   431 		EDynamicResourceStillRegistered = 16,
       
   432 		ERegisteringDependentStaticResourceWithHoles = 17
       
   433 		};
       
   434 #endif
       
   435 	enum TResConStartSequence
       
   436 		{
       
   437 		EResConCreated,
       
   438 		EResConInitialised,
       
   439 		EResConStartupCompleted
       
   440 		};
       
   441     //early initialization
       
   442     IMPORT_C static TInt InitController();
       
   443     TInt InitResources();
       
   444     //request a post-boot level for the resource
       
   445     IMPORT_C static TInt PostBootLevel(TUint aResId, TInt aLevel);
       
   446     //request registration of static resource
       
   447     IMPORT_C static TInt RegisterStaticResource(TUint aClientId, DStaticPowerResource* pR);
       
   448 	//request registration of group/array of static resources
       
   449 	IMPORT_C static TInt RegisterArrayOfStaticResources(TUint aClientId, DStaticPowerResource**& aStaticResourceArray, TUint aResCount);
       
   450     //registration for proxy client
       
   451     virtual TInt RegisterProxyClient(TUint& aProxyId, const TDesC8& aName);
       
   452     virtual TInt DeregisterProxyClient(TUint aClientId);
       
   453     //register list of resources whose state matter to Idle
       
   454     virtual TInt RegisterResourcesForIdle(TInt aPowerControllerId, TUint aNumResources, TPtr* aBuf);
       
   455     static void Panic(TUint8 aPanic);
       
   456     virtual TInt GetInterface(TUint aClientId, TUint aInterfaceId, TAny* aParam1, TAny* aParam2, TAny* aParam3);
       
   457 	virtual ~DPowerResourceController();
       
   458 	/**@internalComponent*/
       
   459 	void CompleteNotifications(TInt aClientId, DStaticPowerResource* aResource, TInt aState, TInt aReturnCode, TInt aLevelOwnerId, TBool aLock = ETrue);
       
   460 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   461 	/**@internalComponent*/
       
   462 	TInt ReserveClientLevelPoolCount(TUint16 aCount);
       
   463 	/**@internalComponent*/
       
   464 	void RemoveClientLevelFromPool(SPowerResourceClientLevel *&aLevelPtr);
       
   465 	/**@internalComponent*/
       
   466 	TInt HandleResourceChange(TPowerRequest &aRequest, TPropagation aProp, TUint aOriginatorId,
       
   467 									const TDesC8& aOriginatorName, DStaticPowerResourceD* aResource);
       
   468 #endif
       
   469 protected:
       
   470     //generic layer function to be called by the PSL
       
   471     DPowerResourceController();
       
   472     void SetDfcQ(TDfcQue* aDfcQ);
       
   473 	#ifdef PRM_ENABLE_EXTENDED_VERSION
       
   474     void SetDfcQDependency(TDfcQue* aDfcQ);
       
   475 	#endif
       
   476     TInt InitPools(TUint16 aKClients, TUint16 aUClients, TUint16 aNClientLevels, TUint16 aNRequests);
       
   477 	/* Lock the resource controller mutex */
       
   478 	inline void Lock()	{ NKern::ThreadEnterCS();
       
   479 						  Kern::MutexWait(*iResourceMutex); }
       
   480 	inline void UnLock()	{ Kern::MutexSignal(*iResourceMutex);
       
   481 							  NKern::ThreadLeaveCS();}
       
   482 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   483 	//Default implementation, PSL re-implements these if features supported
       
   484 	virtual TInt DoRegisterStaticResourcesDependency(DStaticPowerResourceD**& aStaticResourceDArray, TUint16& aStaticResourceDCount);
       
   485 #endif
       
   486 private:
       
   487     // pure virtual implemented by PSL - to be called by PIL
       
   488     virtual TInt DoInitController()=0;
       
   489     virtual TInt DoRegisterStaticResources(DStaticPowerResource**& aStaticResourceArray, TUint16& aStaticResourceCount)=0;
       
   490     /**@internalComponent*/
       
   491     TInt CheckLevelAndAddClient(SPowerResourceClient* pC, TPowerRequest* Request);
       
   492     static void MsgQFunc(TAny* aPtr);
       
   493     #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   494     static void MsgQDependencyFunc(TAny* aPtr);
       
   495     #endif
       
   496     
       
   497 	/**@internalComponent*/
       
   498 	void ResourceStateChangeOfClientLevels(SPowerResourceClient* pC);
       
   499 	/**@internalComponent*/
       
   500     void HandleMsg(TPowerRequest& aRequest);
       
   501 	#ifdef PRM_ENABLE_EXTENDED_VERSION
       
   502     /**@internalComponent*/
       
   503     void HandleDependencyMsg(TPowerRequest& aRequest);
       
   504 	#endif
       
   505 	/**@internalComponent*/
       
   506     void CompleteRequest(TPowerRequest& aRequest);
       
   507 	/**@internalComponent*/
       
   508     void MoveRequestToFreePool(TPowerRequest *aReq);
       
   509 	/**@internalComponent*/
       
   510 	TInt HandleReservationOfObjects(TPowerRequest& aRequest);
       
   511 	/**@internalComponent*/
       
   512 	TInt HandleClientRegistration(TPowerRequest& aRequest);
       
   513 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   514 	TInt RegisterDynamicResource(SPowerResourceClient* aClientPtr, DDynamicPowerResource* aPDRes, TUint* aDynamicResourceId);
       
   515 	TInt DeregisterDynamicResource(SPowerResourceClient* aClientPtr, TUint aDynamicResourceId, TInt* aPDefLevel);
       
   516 	TInt RegisterResourceDependency(SPowerResourceClient* aClientPtr, SResourceDependencyInfo* aInfo1, SResourceDependencyInfo* aInfo2);
       
   517 	/**@internalComponent*/
       
   518 	void CheckForDependencyLoop(DStaticPowerResourceD* pR, TUint aParentResId, TUint aTargetResId);
       
   519 	TInt DeregisterResourceDependency(SPowerResourceClient* aClientPtr, TUint aResId1, TUint aResId2);
       
   520 	/**@internalComponent*/
       
   521 	TInt HandleDependencyResourceStateChange(SPowerResourceClient* pC, TPowerRequest& aRequest);
       
   522 	TInt GetNumDependentsForResource(TUint aResourceId, TUint* aNumResources);
       
   523 	TInt GetDependentsIdForResource(TUint aResourceId, TAny* aInfo, TUint* aNumDepResources);
       
   524 	TInt HandleResourceRegistration(TPowerRequest& aReq);
       
   525 #endif
       
   526 public:
       
   527 	DMutex* iResourceMutex;
       
   528 protected:
       
   529     TDfcQue* iDfcQ;
       
   530     TMessageQue *iMsgQ;
       
   531 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   532 	TDfcQue* iDfcQDependency;
       
   533 	TMessageQue* iMsgQDependency;
       
   534 	TBool iDfcQDependencyLock;
       
   535 #endif
       
   536 private:
       
   537     DStaticPowerResource** iStaticResourceArray;
       
   538     DResourceCon<SPowerResourceClient> iClientList;
       
   539     DResourceCon<SPowerResourceClient> iUserSideClientList;
       
   540 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
       
   541 	RPointerArray<SPowerResourceClient> iCleanList;
       
   542 #endif
       
   543     SPowerResourceClient* iClientPool;
       
   544     SPowerRequest* iRequestPool;
       
   545     SPowerResourceClientLevel* iClientLevelPool;
       
   546 	TUint iPowerControllerId; //Stores the ID allocated to PowerController
       
   547     SIdleResourceInfo* iListForIdle;
       
   548     TUint iInitialised;
       
   549     TUint16 iClientCount;
       
   550     TUint16 iUserSideClientCount;
       
   551     TUint16 iClientLevelPoolCount;
       
   552     TUint16 iClientLevelPoolGrowBy;
       
   553     TUint16 iRequestPoolCount;
       
   554     TUint16 iRequestPoolGrowBy;
       
   555     TUint16 iStaticResourceArrayEntries; //Number of entries in the array including holes if any.
       
   556 	TUint16 iStaticResourceCount;  //Actual number of static resources registered (valid entries).
       
   557 	TUint	iReserved2; //Reserved for future use
       
   558 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   559 	DResourceCon<DDynamicPowerResource> iDynamicResourceList;
       
   560 	DResourceCon<DDynamicPowerResourceD> iDynamicResDependencyList;
       
   561 	DStaticPowerResourceD** iStaticResDependencyArray;
       
   562 	SPowerResourceClientLevel* iResourceLevelPool;
       
   563 	TUint16 iResourceLevelPoolCount;
       
   564 	TUint16 iStaticResDependencyCount;
       
   565 	TUint16 iDynamicResourceCount;
       
   566 	TUint8 iDynamicResDependencyCount;
       
   567 	TUint8 iSpare2;
       
   568 	TUint  iReserved3; //Reserved for future use.
       
   569 #endif
       
   570 	};
       
   571 
       
   572 /**
       
   573 @publishedPartner
       
   574 @prototype 9.5
       
   575 power level of client in a shared resource
       
   576 */
       
   577 struct SPowerResourceClientLevel : public SDblQueLink
       
   578 	{
       
   579     TUint iClientId;
       
   580     TUint iResourceId;
       
   581     TInt iLevel;
       
   582     SPowerResourceClientLevel* iNextInList;
       
   583 	};
       
   584 
       
   585 /**
       
   586 @internalComponent 
       
   587 @prototype 9.5
       
   588 respresent client in resource manager
       
   589 */
       
   590 struct SPowerResourceClient
       
   591 	{
       
   592     TUint iClientId;
       
   593     const TDesC8* iName;
       
   594     SPowerResourceClient* iNextInList;
       
   595     SPowerResourceClientLevel* iLevelList;
       
   596     DPowerResourceNotification* iNotificationList;
       
   597     TUint8 iReservedCl;
       
   598     TUint8 iReservedRm;
       
   599     TUint8 iPendingReqCount;
       
   600     TUint8 iUnderFlowRmCount;
       
   601     TUint8 iUnderFlowClCount;
       
   602 	TUint8 iDynamicResCount; //Counter for dynamic resource registered by the client. Used only in extended version
       
   603 	TUint8 iSpare1;
       
   604 	TUint8 iSpare2;
       
   605     union
       
   606        {
       
   607        TUint iThreadId;
       
   608        TAny* iSpare3;
       
   609        };
       
   610 	};
       
   611 
       
   612 /**
       
   613 @publishedPartner
       
   614 @prototype 9.5
       
   615 represents a request inside the resource manager
       
   616 */
       
   617 struct TPowerRequest : public TThreadMessage
       
   618 	{
       
   619     /** requests can either be to get the resource value or to change the resource value*/
       
   620     enum TReqType {EGet, EChange, ESetDefaultLevel, ERegisterKernelClient, ERegisterUsersideClient, EAllocReserve,
       
   621 					ERegisterDynamicResource	};
       
   622     /** @return thread's own message and turn into a power request. Used for sync/instant calls*/
       
   623     inline static TPowerRequest& Get()
       
   624             {return (TPowerRequest&)Kern::Message();}
       
   625     /** @return type of request get or set */
       
   626     inline TReqType& ReqType()		// one of TReqType
       
   627             {return *(TReqType*)&iValue;}
       
   628     /** @return resource id which is being requested*/
       
   629     inline TUint& ResourceId()
       
   630             {return *(TUint*)&iArg[0];}
       
   631     /** @return id of client making request (only valid on change requests)*/
       
   632     inline TInt& ClientId()
       
   633             {return *(TInt*)&iArg[1];}
       
   634 	/**
       
   635 	    On resource state change operations the PIL sets this field with the required level before 
       
   636 		invoking the DoRequest(..) function; on return from DoRequest(..) function the PSL sets this field
       
   637 		with the real state of the resource to be cached by the PIL.On resource state read operations PSL
       
   638 		sets it with the level read.
       
   639 	*/
       
   640 	inline TInt& Level()		
       
   641             {return *(TInt*)&iArg[2];}
       
   642     /** @return pointer the resource being requested */
       
   643     inline DStaticPowerResource*& Resource()
       
   644             {return *(DStaticPowerResource**)&iArg[3];}
       
   645     /** @return pointer to resource callback structure, used for async requests */
       
   646     inline TPowerResourceCb*& ResourceCb()
       
   647             {return *(TPowerResourceCb**)&iArg[4];}
       
   648     /** @return return code of resource's DoRequest function when request has been processed */
       
   649     inline TInt& ReturnCode()
       
   650             {return *(TInt*)&iArg[5];}
       
   651     /** @return return ETrue if a change is required on a shared resource */
       
   652     inline TBool& RequiresChange()
       
   653             {return *(TInt*)&iArg[6];}
       
   654 	/** @return number of client level objects requested by a client to reserve */
       
   655 	inline TInt& ClientLevelCount()
       
   656 			{return *(TInt*)&iArg[7];}
       
   657 	/** @return number of request objects requested by a client to reserve */
       
   658 	inline TInt& RequestCount()
       
   659 			{return *(TInt*)&iArg[8];}
       
   660 	};
       
   661 
       
   662 /**
       
   663 @internalComponent
       
   664 @prototype 9.5
       
   665 */
       
   666 struct SPowerRequest
       
   667 	{
       
   668     TPowerRequest iRequest;
       
   669     SPowerRequest* iNext;
       
   670 	};
       
   671 
       
   672 /**
       
   673 @publishedPartner
       
   674 @prototype 9.5
       
   675 Structure representing resource information used for Idle power management
       
   676 */
       
   677 struct SIdleResourceInfo
       
   678 	{
       
   679     TUint iResourceId; 
       
   680     TInt iLevelOwnerId; //Owner of the resource.  
       
   681     TInt iCurrentLevel; //Cached resource state
       
   682 	TInt iReserved1;	//Reserved for future use.
       
   683 	TInt iReserved2;	//Reserved for future use.
       
   684 	TInt iReserved3;	//Reserved for future use.
       
   685 	};
       
   686 
       
   687 #include <drivers/resourcecontrol.inl>
       
   688 
       
   689 #endif //__RESOURCECONTROL_H__
       
   690 
       
   691