kernel/eka/include/drivers/resourcecontrol.h
changeset 0 a41df078684a
child 4 56f325a607ea
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32\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 	static void ResourceInit(TAny* aController)																		\
       
   230 		{																											\
       
   231 		TInt aReason = NKern::EThread;																				\
       
   232 		PRM_BOOTING_TRACE																							\
       
   233 		((DPowerResourceController*)aController)->InitResources();													\
       
   234 		return;																										\
       
   235 		}																											\
       
   236 	void CreateController();																						\
       
   237 	GLDEF_C TInt KernelModuleEntry(TInt aReason)																	\
       
   238 		{																											\
       
   239 		if(aReason==KModuleEntryReasonVariantInit0)																	\
       
   240 			{																										\
       
   241 			__KTRACE_OPT(KBOOT, Kern::Printf("Create Resource Controller"));										\
       
   242 			CreateController();																						\
       
   243 			return KErrNone;																						\
       
   244 			}																										\
       
   245 		if (aReason==KModuleEntryReasonExtensionInit0)																\
       
   246 			return KExtensionMaximumPriority;																		\
       
   247 		if (aReason!=KModuleEntryReasonExtensionInit1)																\
       
   248 			return KErrArgument;																					\
       
   249 		PRM_BOOTING_TRACE																							\
       
   250 		__KTRACE_OPT(KBOOT, Kern::Printf("Initialise Resource Controller"));										\
       
   251 		TInt r = KErrNone;																							\
       
   252 		r = DPowerResourceController::InitController();																\
       
   253 		if(r != KErrNone)																							\
       
   254 			return r;																								\
       
   255 		__KTRACE_OPT(KBOOT, Kern::Printf("Create PDD and queue ResourceInit DFC"));									\
       
   256 		DResConPddFactory* device = new DResConPddFactory;															\
       
   257 		if(!device)																									\
       
   258 			return KErrNoMemory;																					\
       
   259 		r = Kern::InstallPhysicalDevice(device);																	\
       
   260 		if(r != KErrNone)																							\
       
   261 			return r;																								\
       
   262 		TDfc* resourceInitDfc = new TDfc(&ResourceInit,(TAny*)&TheController,Kern::SvMsgQue(),KMaxDfcPriority-1);	\
       
   263 		if(!resourceInitDfc)																						\
       
   264 			return KErrNoMemory;																					\
       
   265 		resourceInitDfc->Enque();																					\
       
   266        	return KErrNone;																							\
       
   267 		}																											\
       
   268 		GLDEF_C void CreateController()
       
   269 
       
   270 /* Macro defintion for handling dependency resource state change. This is used only in extended version */
       
   271 #define HANDLE_CHANGE_PROPAGATION(TheController, resourceTypePointer, traceEnabled, originatorId, originatorName)																	\
       
   272 	switch(aProp)																									\
       
   273 		{																											\
       
   274 		case EChangeStart:																							\
       
   275 			{																										\
       
   276 			if(!pDR->iDependencyList) /*No dependents so change state of the resource*/								\
       
   277 				{																									\
       
   278 				aRequest.ReturnCode() = pDR->DoRequest(aRequest);													\
       
   279 				if(aRequest.ReturnCode() == KErrNone)																\
       
   280 					{																								\
       
   281 					iCachedLevel = aRequest.Level();																\
       
   282 					iLevelOwnerId = aRequest.ClientId();															\
       
   283 					if(iIdleListEntry)																				\
       
   284 						{																							\
       
   285 						iIdleListEntry->iCurrentLevel = aRequest.Level();											\
       
   286 						iIdleListEntry->iLevelOwnerId = aRequest.ClientId();										\
       
   287 						}																							\
       
   288 					TheController->CompleteNotifications(aRequest.ClientId(), pDR,									\
       
   289 							aRequest.Level(), aRequest.ReturnCode(), aRequest.ClientId());							\
       
   290 					}																								\
       
   291 					break;																							\
       
   292 				}																									\
       
   293 			depRequest.ResourceId() = aRequest.ResourceId();														\
       
   294 			depRequest.ClientId() = aRequest.ResourceId();															\
       
   295 			depRequest.Level() = aRequest.Level();																	\
       
   296 			depRequest.Resource() = pDR;																			\
       
   297 			result = pDR->HandleChangePropagation(depRequest, ECheckChangeAllowed, originatorId, originatorName);	\
       
   298 			if(result != KErrNone)																					\
       
   299 				return result;																						\
       
   300 			/*Adjust resource client level*/																		\
       
   301 			if(clientLevelCount)																					\
       
   302 				{																									\
       
   303 				result = TheController->ReserveClientLevelPoolCount(clientLevelCount);								\
       
   304 				if(result != KErrNone)																				\
       
   305 					return result;																					\
       
   306 				}																									\
       
   307 			/*Resource change of dependents */																		\
       
   308 			pDR->HandleChangePropagation(aRequest, ERequestStateChange, originatorId, originatorName);				\
       
   309 			/*Notification to dependents */																			\
       
   310 			pDR->HandleChangePropagation(aRequest, EIssueNotifications, originatorId, originatorName);				\
       
   311 			break;																									\
       
   312 			}																										\
       
   313 		case ECheckChangeAllowed:																					\
       
   314 			{																										\
       
   315 			TChangePropagationStatus status;																		\
       
   316 			for(SNode* depNode = pDR->iDependencyList; depNode != NULL; depNode = depNode->iNext)					\
       
   317 				{																									\
       
   318 				pDepRes = (resourceTypePointer)depNode->iResource;													\
       
   319 				if((aRequest.ClientId() & KIdMaskResourceWithDependencies) &&										\
       
   320 						(pDepRes->iResourceId == (TUint)aRequest.ClientId()))										\
       
   321 					continue;																						\
       
   322 				/*Resource need not change if it is already in that state, so continue with							\
       
   323 						another dependent state.*/																	\
       
   324 				if(pDepRes->iResourceId & KIdMaskDynamic)															\
       
   325 					status = ((DDynamicPowerResourceD*)pDepRes)->TranslateDependentState(aRequest.ResourceId(),		\
       
   326 																				aRequest.Level(), resState);		\
       
   327 				else																								\
       
   328 					status = ((DStaticPowerResourceD*)pDepRes)->TranslateDependentState(aRequest.ResourceId(),		\
       
   329 																					aRequest.Level(), resState);	\
       
   330 				if((status == ENoChange) || (pDepRes->iCachedLevel == resState))									\
       
   331 					{																								\
       
   332 					depNode->iRequiresChange = EFalse;																\
       
   333 					continue;																						\
       
   334 					}																								\
       
   335 				if(status == EChangeNotAccepted)																	\
       
   336 					return KErrPermissionDenied;																	\
       
   337 				depRequest.ResourceId() = pDepRes->iResourceId;														\
       
   338 				depRequest.ClientId() = aRequest.ResourceId(); /*ID of the dependent resource */					\
       
   339 				depRequest.Level() = resState;																		\
       
   340 				depRequest.Resource() = pDepRes;																	\
       
   341 				/*Check resource client list and resource list to see whether change is allowed.*/					\
       
   342 				if(pDepRes->Sense() == DStaticPowerResource::ECustom)												\
       
   343 					{																								\
       
   344 					/*Call custom function to check whether change is allowed.*/									\
       
   345 					if(pDepRes->iResourceId & KIdMaskDynamic)														\
       
   346 						depRequest.RequiresChange() = ((DDynamicPowerResourceD*)pDepRes)->iDepCustomFunction(depRequest.ClientId(),	\
       
   347 							originatorName, depRequest.ResourceId(), EClientChangeLevel, depRequest.Level(), (TAny*)&pDepRes->iClientList,		\
       
   348 									(TAny*)&((DDynamicPowerResourceD*)pDepRes)->iResourceClientList, NULL);				\
       
   349 					else																							\
       
   350 						depRequest.RequiresChange() = ((DStaticPowerResourceD*)pDepRes)->iDepCustomFunction(depRequest.ClientId(),		\
       
   351 							originatorName, depRequest.ResourceId(), EClientChangeLevel, depRequest.Level(), (TAny*)&pDepRes->iClientList,		\
       
   352 									(TAny*)&((DStaticPowerResourceD*)pDepRes)->iResourceClientList, NULL);				\
       
   353 					if(!depRequest.RequiresChange())																\
       
   354 						return KErrPermissionDenied;																\
       
   355 					}																								\
       
   356 				SPowerResourceClientLevel*pN=NULL;																	\
       
   357 				for(SDblQueLink* pNL=pDepRes->iClientList.First();pNL!=&pDepRes->iClientList.iA; pNL=pNL->iNext)	\
       
   358 					{																								\
       
   359 					pN = (SPowerResourceClientLevel*)pNL;															\
       
   360 					if(pDepRes->Sense() == DStaticPowerResource::EPositive)											\
       
   361 						{																							\
       
   362 						if(pN->iLevel > depRequest.Level())															\
       
   363 							return KErrPermissionDenied;															\
       
   364 						}																							\
       
   365 					else if(pDepRes->Sense() == DStaticPowerResource::ENegative)									\
       
   366 						{																							\
       
   367 						if(pN->iLevel < depRequest.Level())															\
       
   368 							return KErrPermissionDenied;															\
       
   369 						}																							\
       
   370 					}																								\
       
   371 																													\
       
   372 				/*check through the resource client level */														\
       
   373 				SPowerResourceClientLevel*pCL = NULL;																\
       
   374 				if(pDepRes->iResourceId & KIdMaskDynamic)															\
       
   375 					pCL = ((DDynamicPowerResourceD*)pDepRes)->iResourceClientList;									\
       
   376 				else																								\
       
   377 					pCL = ((DStaticPowerResourceD*)pDepRes)->iResourceClientList;									\
       
   378 				for(; pCL != NULL; pCL = pCL->iNextInList)															\
       
   379 					{																								\
       
   380 					if(pCL->iClientId == pDR->iResourceId)															\
       
   381 						break;																						\
       
   382 					}																								\
       
   383 				if(!pCL)																							\
       
   384 					clientLevelCount++;																				\
       
   385 				/*check dependent resource client list & resource list to see whether change is allowed */			\
       
   386 				if(pDepRes->iResourceId & KIdMaskDynamic)															\
       
   387 					result = ((DDynamicPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest,				\
       
   388 																ECheckChangeAllowed, originatorId, originatorName);	\
       
   389 				else																								\
       
   390 					result = ((DStaticPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest,					\
       
   391 											ECheckChangeAllowed, originatorId, originatorName);						\
       
   392 				if(result != KErrNone)																				\
       
   393 					return result;																					\
       
   394 				depNode->iPropagatedLevel = resState;																\
       
   395 				depNode->iRequiresChange = ETrue;																	\
       
   396 				}																									\
       
   397 			break;																									\
       
   398 			}																										\
       
   399 		case ERequestStateChange:																					\
       
   400 			{																										\
       
   401 			SPowerResourceClientLevel* pCL = NULL;																	\
       
   402 			for(SNode* depNode = pDR->iDependencyList; depNode != NULL; depNode = depNode->iNext)					\
       
   403 				{																									\
       
   404 				pDepRes = (resourceTypePointer)depNode->iResource;													\
       
   405 				if((!depNode->iRequiresChange) || (pDepRes->iResourceId == (TUint)aRequest.ClientId()))				\
       
   406 					continue;																						\
       
   407 				depRequest.ResourceId() = pDepRes->iResourceId;														\
       
   408 				depRequest.ClientId() = aRequest.ResourceId();														\
       
   409 				depRequest.Level() = depNode->iPropagatedLevel;														\
       
   410 				depRequest.Resource() = pDepRes;																	\
       
   411 				if(pDepRes->iResourceId & KIdMaskDynamic)															\
       
   412 					((DDynamicPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, ERequestStateChange,	\
       
   413 																					originatorId, originatorName);	\
       
   414 				else																								\
       
   415 					((DStaticPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, ERequestStateChange,		\
       
   416 																					originatorId, originatorName);	\
       
   417 				/*Update level if resource client level is already present for this resource.*/						\
       
   418 				if(pDepRes->iResourceId & KIdMaskDynamic)															\
       
   419 					pCL = ((DDynamicPowerResourceD*)pDepRes)->iResourceClientList;									\
       
   420 				else																								\
       
   421 					pCL = ((DStaticPowerResourceD*)pDepRes)->iResourceClientList;									\
       
   422 				for(; pCL != NULL; pCL = pCL->iNextInList)															\
       
   423 					{																								\
       
   424 					if(pCL->iClientId == pDR->iResourceId)															\
       
   425 						{																							\
       
   426 						pCL->iLevel = depNode->iPropagatedLevel;													\
       
   427 						break;																						\
       
   428 						}																							\
       
   429 					}																								\
       
   430 				if(!pCL) /*Create a new resource client level*/														\
       
   431 					{																								\
       
   432 					TheController->RemoveClientLevelFromPool(pCL);													\
       
   433 					pCL->iClientId = pDR->iResourceId;																\
       
   434 					pCL->iResourceId = pDepRes->iResourceId;														\
       
   435 					pCL->iLevel = depNode->iPropagatedLevel;														\
       
   436 					if(pDepRes->iResourceId & KIdMaskDynamic)														\
       
   437 						{																							\
       
   438 						LIST_PUSH(((DDynamicPowerResourceD*)pDepRes)->iResourceClientList, pCL, iNextInList);		\
       
   439 						}																							\
       
   440 					else																							\
       
   441 						{																							\
       
   442 						LIST_PUSH(((DStaticPowerResourceD*)pDepRes)->iResourceClientList, pCL, iNextInList);		\
       
   443 						}																							\
       
   444 					clientLevelCount--;																				\
       
   445 					}																								\
       
   446 				}																									\
       
   447 			if(traceEnabled && (aRequest.ClientId() & KIdMaskResourceWithDependencies))								\
       
   448 				{																									\
       
   449 				SPowerResourceClient res;																			\
       
   450 				SPowerResourceClient* pC = &res;																	\
       
   451 				pC->iClientId = aRequest.ClientId();																\
       
   452 				pC->iName = &KParentResource;																		\
       
   453 				DStaticPowerResource*pR = (DStaticPowerResource*)pDR;												\
       
   454 				TUint aResourceId = pDR->iResourceId;																\
       
   455 				TInt aNewState = aRequest.Level();																	\
       
   456 				PRM_CLIENT_CHANGE_STATE_START_TRACE																	\
       
   457 				}																									\
       
   458 			DoRequest(aRequest);																					\
       
   459 			if(traceEnabled && (aRequest.ClientId() & KIdMaskResourceWithDependencies))								\
       
   460 				{																									\
       
   461 				SPowerResourceClient res;																			\
       
   462 				SPowerResourceClient* pC = &res;																	\
       
   463 				pC->iClientId = aRequest.ClientId();																\
       
   464 				pC->iName = &KParentResource;																		\
       
   465 				DStaticPowerResource*pR = (DStaticPowerResource*)pDR;												\
       
   466 				TUint aResourceId = pDR->iResourceId;																\
       
   467 				TInt aNewState = aRequest.Level();																	\
       
   468 				TInt r = KErrNone;																					\
       
   469 				PRM_CLIENT_CHANGE_STATE_END_TRACE																	\
       
   470 				}																									\
       
   471 			pDR->iCachedLevel = aRequest.Level();																	\
       
   472 			pDR->iLevelOwnerId = aRequest.ClientId();																\
       
   473 			if(pDR->iIdleListEntry)																					\
       
   474 				{																									\
       
   475 				pDR->iIdleListEntry->iCurrentLevel = aRequest.Level();												\
       
   476 				pDR->iIdleListEntry->iLevelOwnerId = aRequest.ClientId();											\
       
   477 				}																									\
       
   478 			break;																									\
       
   479 			}																										\
       
   480 		case EIssueNotifications:																					\
       
   481 			{																										\
       
   482 			for(SNode* depNode = pDR->iDependencyList; depNode != NULL; depNode = depNode->iNext)					\
       
   483 				{																									\
       
   484 				pDepRes = (resourceTypePointer)depNode->iResource;													\
       
   485 				if((!depNode->iRequiresChange) || (pDepRes->iResourceId == (TUint)aRequest.ClientId()))				\
       
   486 					continue;																						\
       
   487 				depRequest.ResourceId() = pDepRes->iResourceId;														\
       
   488 				depRequest.ClientId() = pDepRes->iLevelOwnerId;														\
       
   489 				depRequest.Level() = pDepRes->iCachedLevel;															\
       
   490 				depRequest.Resource() = pDepRes;																	\
       
   491 				if(pDepRes->iResourceId & KIdMaskDynamic)															\
       
   492 					((DDynamicPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, EIssueNotifications,	\
       
   493 																					originatorId, originatorName);	\
       
   494 				else																								\
       
   495 					((DStaticPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, EIssueNotifications,		\
       
   496 																					originatorId, originatorName);	\
       
   497 				}																									\
       
   498 			TheController->CompleteNotifications(aRequest.ClientId(), pDR, aRequest.Level(), KErrNone,				\
       
   499 																					aRequest.ClientId());			\
       
   500 			break;																									\
       
   501 			}																										\
       
   502 		default:																									\
       
   503 			return KErrNotSupported;																				\
       
   504 		}																											\
       
   505 		return result;
       
   506 
       
   507 struct SPowerResourceClient;
       
   508 struct TPowerRequest;
       
   509 struct SPowerRequest;
       
   510 struct SPowerResourceClientLevel;
       
   511 struct SIdleResourceInfo;
       
   512 class DPowerResourceController;
       
   513 
       
   514 /**
       
   515 @internalComponent
       
   516 @prototype 9.5
       
   517 Interface class for Resource Manager
       
   518 Functions from PowerResourceManager calls corresponding functions of this 
       
   519 class which in turn calls Powercontroller functions.
       
   520 */
       
   521 class TInterface
       
   522 	{
       
   523 public:
       
   524     static TInt RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType=EOwnerProcess);
       
   525     static TInt DeRegisterClient(TUint aClientId);
       
   526     static TInt GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName);
       
   527     static TInt GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId);
       
   528     static TInt GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId);
       
   529     static TInt GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo);
       
   530     static TInt GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources);
       
   531     static TInt GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources, TAny* aInfo);
       
   532     static TInt GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients);
       
   533     static TInt GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients, TAny* aInfo);
       
   534     static TInt AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm);
       
   535     static TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL);
       
   536     static TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId);
       
   537     static TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb);
       
   538     static TInt CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb);
       
   539     static TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
       
   540     static TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, TInt aThreshold, TBool aDirection);
       
   541     static TInt CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
       
   542 	static TInt DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId);
       
   543     static DPowerResourceController* GetPowerResourceController(void);
       
   544     static TInt ControlIO(TUint aClientId, TUint aFunction, TAny* aParam1, TAny* aParam2, TAny* aParam3);
       
   545 	};
       
   546 
       
   547 /**
       
   548 @internalComponent
       
   549 @prototype 9.5
       
   550 Container class to create containers of pointers to clients.
       
   551 */
       
   552 template <class T>
       
   553 class DResourceCon : public DBase
       
   554 	{
       
   555 public:
       
   556     inline TInt Initialise(TUint16 aInitialSize);
       
   557     inline void Delete();
       
   558     inline T*  operator[](TUint16 aIndex);
       
   559     inline TInt Remove(T* aObj, TUint16 aIndex);
       
   560     inline TInt Add(T* aObj, TUint &aId);
       
   561     inline TInt Find(T*& anEntry, TDesC& aName);
       
   562     inline TInt ReSize(TUint16 aGrowBy);
       
   563     inline TUint16 Count() {return iCount;}
       
   564     inline TUint16 Allocd() {return iAllocated;}
       
   565 	inline TUint16 GrowBy() {return iGrowBy;}
       
   566 private:
       
   567     TUint16 iGrowBy; //Size to grow the size of the array.
       
   568     TUint16 iAllocated;  //Size of the array
       
   569     TUint16 iCount; //Valid entries in the array
       
   570     TUint16 iInstanceCount; //FreeCounter incremented whenever an entry is added.
       
   571     TUint16 iFreeLoc; //Cached free location in the array
       
   572     TUint16 iSpare;
       
   573     T** iArray;
       
   574 	};
       
   575 
       
   576 /** 
       
   577 @internalComponent
       
   578 @prototype 9.5
       
   579 Factory class for physical device 
       
   580 */
       
   581 NONSHARABLE_CLASS(DResConPddFactory) : public DPhysicalDevice
       
   582 	{
       
   583 public:
       
   584 	/**
       
   585 	Structure for holding PDD capabilities information
       
   586 	*/
       
   587 	class TCaps
       
   588 		{
       
   589 	public:
       
   590 		TVersion iVersion;
       
   591 		};
       
   592 public:
       
   593     DResConPddFactory();
       
   594     virtual TInt Install();
       
   595     virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
       
   596     virtual TInt Validate(TInt aUint, const TDesC8* anInfo, const TVersion& aVer);
       
   597     virtual void GetCaps(TDes8& aDes) const;
       
   598     inline static TVersion VersionRequired();
       
   599 	};
       
   600 
       
   601 /**
       
   602 @internalComponent
       
   603 @prototype 9.5
       
   604 Interface class for user side resource controller proxy. For each user side channel opened an object of 
       
   605 this class is created in heap and pointer to resource controller is stored in iController member variable. 
       
   606 User side resource controller proxy calls the resource controller API's by deferencing the pointer. 
       
   607 This class is required as when the channel is closed the device driver framework tries to delete 
       
   608 the object stored in ipdd, because of which it is not possible to pass the controller pointer directly.
       
   609 */
       
   610 class DUserSideProxyInterface: public DBase
       
   611 	{
       
   612 	public:
       
   613 	DPowerResourceController *iController;
       
   614 	};
       
   615 
       
   616 
       
   617 /** 
       
   618 @publishedPartner
       
   619 @prototype 9.5
       
   620 resource manager implementation base class
       
   621 */
       
   622 NONSHARABLE_CLASS (DPowerResourceController) : public DBase
       
   623 	{
       
   624 public:
       
   625     TInt RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType=EOwnerProcess);
       
   626     TInt DeRegisterClient(TUint aClientId);
       
   627     virtual TInt GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName);
       
   628     virtual TInt GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId);
       
   629     virtual TInt GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId);
       
   630     virtual TInt GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo);
       
   631     virtual TInt GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources);
       
   632     virtual TInt GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources, TAny* aInfo);
       
   633     virtual TInt GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients);
       
   634     virtual TInt GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients, TAny* aInfo);
       
   635     virtual TInt AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm);
       
   636     virtual TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL);
       
   637     virtual TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId);
       
   638     virtual TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb);
       
   639     virtual TInt CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb);
       
   640     virtual TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
       
   641     virtual TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, TInt aThreshold, TBool aDirection);
       
   642     virtual TInt CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
       
   643     virtual TInt DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId);
       
   644 public:
       
   645 	enum TResConPanic
       
   646 		{
       
   647 		ECalledFromDfcThread0 = 0,
       
   648 		ECalledFromIsr = 1,
       
   649 		ECalledFromNullThread = 2,
       
   650 		ECalledFromDfcThread1 = 3,
       
   651 		EClientHasPendingAsyncRequest = 4,
       
   652 		EClientHasNotificationObject = 5,
       
   653 		EControllerAlreadyExists = 6,
       
   654 		ECustomFunctionNotSet = 7,
       
   655 		EClientIdNotInClientLevelList = 8,
       
   656 		ENoMemToCreatePowerControllerClient = 9,
       
   657 		EResourceNameExceedsLimit = 10, 
       
   658 		EObjectNotFoundInList = 11 
       
   659 		};
       
   660 #ifdef PRM_ENABLE_EXTENDED_VERSION	
       
   661 	enum TExtendedResConPanic
       
   662 		{
       
   663 		EClosedLoopDependencies = EObjectNotFoundInList + 2, //13
       
   664 		ERegisteringNonDependentStaticResource = 14,
       
   665 		EClientHasDynamicResourceRegistered = 15,
       
   666 		EDynamicResourceStillRegistered = 16,
       
   667 		ERegisteringDependentStaticResourceWithHoles = 17
       
   668 		};
       
   669 #endif
       
   670 	enum TResConStartSequence
       
   671 		{
       
   672 		EResConCreated,
       
   673 		EResConInitialised,
       
   674 		EResConStartupCompleted
       
   675 		};
       
   676     //early initialization
       
   677     IMPORT_C static TInt InitController();
       
   678     TInt InitResources();
       
   679     //request a post-boot level for the resource
       
   680     IMPORT_C static TInt PostBootLevel(TUint aResId, TInt aLevel);
       
   681     //request registration of static resource
       
   682     IMPORT_C static TInt RegisterStaticResource(TUint aClientId, DStaticPowerResource* pR);
       
   683 	//request registration of group/array of static resources
       
   684 	IMPORT_C static TInt RegisterArrayOfStaticResources(TUint aClientId, DStaticPowerResource**& aStaticResourceArray, TUint aResCount);
       
   685     //registration for proxy client
       
   686     virtual TInt RegisterProxyClient(TUint& aProxyId, const TDesC8& aName);
       
   687     virtual TInt DeregisterProxyClient(TUint aClientId);
       
   688     //register list of resources whose state matter to Idle
       
   689     virtual TInt RegisterResourcesForIdle(TInt aPowerControllerId, TUint aNumResources, TPtr* aBuf);
       
   690     static void Panic(TUint8 aPanic);
       
   691     virtual TInt GetInterface(TUint aClientId, TUint aInterfaceId, TAny* aParam1, TAny* aParam2, TAny* aParam3);
       
   692 	virtual ~DPowerResourceController();
       
   693 	/**@internalComponent*/
       
   694 	void CompleteNotifications(TInt aClientId, DStaticPowerResource* aResource, TInt aState, TInt aReturnCode, TInt aLevelOwnerId, TBool aLock = ETrue);
       
   695 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   696 	/**@internalComponent*/
       
   697 	TInt ReserveClientLevelPoolCount(TUint16 aCount);
       
   698 	/**@internalComponent*/
       
   699 	void RemoveClientLevelFromPool(SPowerResourceClientLevel *&aLevelPtr);
       
   700 #endif
       
   701 protected:
       
   702     //generic layer function to be called by the PSL
       
   703     DPowerResourceController();
       
   704     void SetDfcQ(TDfcQue* aDfcQ);
       
   705 	#ifdef PRM_ENABLE_EXTENDED_VERSION
       
   706     void SetDfcQDependency(TDfcQue* aDfcQ);
       
   707 	#endif
       
   708     TInt InitPools(TUint16 aKClients, TUint16 aUClients, TUint16 aNClientLevels, TUint16 aNRequests);
       
   709 	/* Lock the resource controller mutex */
       
   710 	inline void Lock()	{ NKern::ThreadEnterCS();
       
   711 						  Kern::MutexWait(*iResourceMutex); }
       
   712 	inline void UnLock()	{ Kern::MutexSignal(*iResourceMutex);
       
   713 							  NKern::ThreadLeaveCS();}
       
   714 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   715 	//Default implementation, PSL re-implements these if features supported
       
   716 	virtual TInt DoRegisterStaticResourcesDependency(DStaticPowerResourceD**& aStaticResourceDArray, TUint16& aStaticResourceDCount);
       
   717 #endif
       
   718 private:
       
   719     // pure virtual implemented by PSL - to be called by PIL
       
   720     virtual TInt DoInitController()=0;
       
   721     virtual TInt DoRegisterStaticResources(DStaticPowerResource**& aStaticResourceArray, TUint16& aStaticResourceCount)=0;
       
   722     /**@internalComponent*/
       
   723     TInt CheckLevelAndAddClient(SPowerResourceClient* pC, TPowerRequest* Request);
       
   724     static void MsgQFunc(TAny* aPtr);
       
   725     #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   726     static void MsgQDependencyFunc(TAny* aPtr);
       
   727     #endif
       
   728     
       
   729 	/**@internalComponent*/
       
   730 	void ResourceStateChangeOfClientLevels(SPowerResourceClient* pC);
       
   731 	/**@internalComponent*/
       
   732     void HandleMsg(TPowerRequest& aRequest);
       
   733 	#ifdef PRM_ENABLE_EXTENDED_VERSION
       
   734     /**@internalComponent*/
       
   735     void HandleDependencyMsg(TPowerRequest& aRequest);
       
   736 	#endif
       
   737 	/**@internalComponent*/
       
   738     void CompleteRequest(TPowerRequest& aRequest);
       
   739 	/**@internalComponent*/
       
   740     void MoveRequestToFreePool(TPowerRequest *aReq);
       
   741 	/**@internalComponent*/
       
   742 	TInt HandleReservationOfObjects(TPowerRequest& aRequest);
       
   743 	/**@internalComponent*/
       
   744 	TInt HandleClientRegistration(TPowerRequest& aRequest);
       
   745 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   746 	TInt RegisterDynamicResource(SPowerResourceClient* aClientPtr, DDynamicPowerResource* aPDRes, TUint* aDynamicResourceId);
       
   747 	TInt DeregisterDynamicResource(SPowerResourceClient* aClientPtr, TUint aDynamicResourceId, TInt* aPDefLevel);
       
   748 	TInt RegisterResourceDependency(SPowerResourceClient* aClientPtr, SResourceDependencyInfo* aInfo1, SResourceDependencyInfo* aInfo2);
       
   749 	/**@internalComponent*/
       
   750 	void CheckForDependencyLoop(DStaticPowerResourceD* pR, TUint aParentResId, TUint aTargetResId);
       
   751 	TInt DeregisterResourceDependency(SPowerResourceClient* aClientPtr, TUint aResId1, TUint aResId2);
       
   752 	/**@internalComponent*/
       
   753 	TInt HandleDependencyResourceStateChange(SPowerResourceClient* pC, TPowerRequest& aRequest);
       
   754 	TInt GetNumDependentsForResource(TUint aResourceId, TUint* aNumResources);
       
   755 	TInt GetDependentsIdForResource(TUint aResourceId, TAny* aInfo, TUint* aNumDepResources);
       
   756 	TInt HandleResourceRegistration(TPowerRequest& aReq);
       
   757 #endif
       
   758 public:
       
   759 	DMutex* iResourceMutex;
       
   760 protected:
       
   761     TDfcQue* iDfcQ;
       
   762     TMessageQue *iMsgQ;
       
   763 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   764 	TDfcQue* iDfcQDependency;
       
   765 	TMessageQue* iMsgQDependency;
       
   766 	TBool iDfcQDependencyLock;
       
   767 #endif
       
   768 private:
       
   769     DStaticPowerResource** iStaticResourceArray;
       
   770     DResourceCon<SPowerResourceClient> iClientList;
       
   771     DResourceCon<SPowerResourceClient> iUserSideClientList;
       
   772     SPowerResourceClient* iClientPool;
       
   773     SPowerRequest* iRequestPool;
       
   774     SPowerResourceClientLevel* iClientLevelPool;
       
   775 	TUint iPowerControllerId; //Stores the ID allocated to PowerController
       
   776     SIdleResourceInfo* iListForIdle;
       
   777     TUint iInitialised;
       
   778     TUint16 iClientCount;
       
   779     TUint16 iUserSideClientCount;
       
   780     TUint16 iClientLevelPoolCount;
       
   781     TUint16 iClientLevelPoolGrowBy;
       
   782     TUint16 iRequestPoolCount;
       
   783     TUint16 iRequestPoolGrowBy;
       
   784     TUint16 iStaticResourceArrayEntries; //Number of entries in the array including holes if any.
       
   785 	TUint16 iStaticResourceCount;  //Actual number of static resources registered (valid entries).
       
   786 	TUint	iReserved2; //Reserved for future use
       
   787 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   788 	DResourceCon<DDynamicPowerResource> iDynamicResourceList;
       
   789 	DResourceCon<DDynamicPowerResourceD> iDynamicResDependencyList;
       
   790 	DStaticPowerResourceD** iStaticResDependencyArray;
       
   791 	SPowerResourceClientLevel* iResourceLevelPool;
       
   792 	TUint16 iResourceLevelPoolCount;
       
   793 	TUint16 iStaticResDependencyCount;
       
   794 	TUint16 iDynamicResourceCount;
       
   795 	TUint8 iDynamicResDependencyCount;
       
   796 	TUint8 iSpare2;
       
   797 	TUint  iReserved3; //Reserved for future use.
       
   798 #endif
       
   799 	};
       
   800 
       
   801 /**
       
   802 @publishedPartner
       
   803 @prototype 9.5
       
   804 power level of client in a shared resource
       
   805 */
       
   806 struct SPowerResourceClientLevel : public SDblQueLink
       
   807 	{
       
   808     TUint iClientId;
       
   809     TUint iResourceId;
       
   810     TInt iLevel;
       
   811     SPowerResourceClientLevel* iNextInList;
       
   812 	};
       
   813 
       
   814 /**
       
   815 @internalComponent 
       
   816 @prototype 9.5
       
   817 respresent client in resource manager
       
   818 */
       
   819 struct SPowerResourceClient
       
   820 	{
       
   821     TUint iClientId;
       
   822     const TDesC8* iName;
       
   823     SPowerResourceClient* iNextInList;
       
   824     SPowerResourceClientLevel* iLevelList;
       
   825     DPowerResourceNotification* iNotificationList;
       
   826     TUint8 iReservedCl;
       
   827     TUint8 iReservedRm;
       
   828     TUint8 iPendingReqCount;
       
   829     TUint8 iUnderFlowRmCount;
       
   830     TUint8 iUnderFlowClCount;
       
   831 	TUint8 iDynamicResCount; //Counter for dynamic resource registered by the client. Used only in extended version
       
   832 	TUint8 iSpare1;
       
   833 	TUint8 iSpare2;
       
   834     union
       
   835        {
       
   836        TUint iThreadId;
       
   837        TAny* iSpare3;
       
   838        };
       
   839 	};
       
   840 
       
   841 /**
       
   842 @publishedPartner
       
   843 @prototype 9.5
       
   844 represents a request inside the resource manager
       
   845 */
       
   846 struct TPowerRequest : public TThreadMessage
       
   847 	{
       
   848     /** requests can either be to get the resource value or to change the resource value*/
       
   849     enum TReqType {EGet, EChange, ESetDefaultLevel, ERegisterKernelClient, ERegisterUsersideClient, EAllocReserve,
       
   850 					ERegisterDynamicResource	};
       
   851     /** @return thread's own message and turn into a power request. Used for sync/instant calls*/
       
   852     inline static TPowerRequest& Get()
       
   853             {return (TPowerRequest&)Kern::Message();}
       
   854     /** @return type of request get or set */
       
   855     inline TReqType& ReqType()		// one of TReqType
       
   856             {return *(TReqType*)&iValue;}
       
   857     /** @return resource id which is being requested*/
       
   858     inline TUint& ResourceId()
       
   859             {return *(TUint*)&iArg[0];}
       
   860     /** @return id of client making request (only valid on change requests)*/
       
   861     inline TInt& ClientId()
       
   862             {return *(TInt*)&iArg[1];}
       
   863 	/**
       
   864 	    On resource state change operations the PIL sets this field with the required level before 
       
   865 		invoking the DoRequest(..) function; on return from DoRequest(..) function the PSL sets this field
       
   866 		with the real state of the resource to be cached by the PIL.On resource state read operations PSL
       
   867 		sets it with the level read.
       
   868 	*/
       
   869 	inline TInt& Level()		
       
   870             {return *(TInt*)&iArg[2];}
       
   871     /** @return pointer the resource being requested */
       
   872     inline DStaticPowerResource*& Resource()
       
   873             {return *(DStaticPowerResource**)&iArg[3];}
       
   874     /** @return pointer to resource callback structure, used for async requests */
       
   875     inline TPowerResourceCb*& ResourceCb()
       
   876             {return *(TPowerResourceCb**)&iArg[4];}
       
   877     /** @return return code of resource's DoRequest function when request has been processed */
       
   878     inline TInt& ReturnCode()
       
   879             {return *(TInt*)&iArg[5];}
       
   880     /** @return return ETrue if a change is required on a shared resource */
       
   881     inline TBool& RequiresChange()
       
   882             {return *(TInt*)&iArg[6];}
       
   883 	/** @return number of client level objects requested by a client to reserve */
       
   884 	inline TInt& ClientLevelCount()
       
   885 			{return *(TInt*)&iArg[7];}
       
   886 	/** @return number of request objects requested by a client to reserve */
       
   887 	inline TInt& RequestCount()
       
   888 			{return *(TInt*)&iArg[8];}
       
   889 	};
       
   890 
       
   891 /**
       
   892 @internalComponent
       
   893 @prototype 9.5
       
   894 */
       
   895 struct SPowerRequest
       
   896 	{
       
   897     TPowerRequest iRequest;
       
   898     SPowerRequest* iNext;
       
   899 	};
       
   900 
       
   901 /**
       
   902 @publishedPartner
       
   903 @prototype 9.5
       
   904 Structure representing resource information used for Idle power management
       
   905 */
       
   906 struct SIdleResourceInfo
       
   907 	{
       
   908     TUint iResourceId; 
       
   909     TInt iLevelOwnerId; //Owner of the resource.  
       
   910     TInt iCurrentLevel; //Cached resource state
       
   911 	TInt iReserved1;	//Reserved for future use.
       
   912 	TInt iReserved2;	//Reserved for future use.
       
   913 	TInt iReserved3;	//Reserved for future use.
       
   914 	};
       
   915 
       
   916 #include <drivers/resourcecontrol.inl>
       
   917 
       
   918 #endif //__RESOURCECONTROL_H__
       
   919 
       
   920