kernel/eka/include/drivers/resourcecontrol.h
changeset 4 56f325a607ea
parent 0 a41df078684a
child 43 c1f20ce4abcf
equal deleted inserted replaced
2:4122176ea935 4:56f325a607ea
   224 		UNLOCK_RETURN(KErrNotFound);																	\
   224 		UNLOCK_RETURN(KErrNotFound);																	\
   225 		}
   225 		}
   226 
   226 
   227 /* Macro definition for entry point of Power Resource Controller */
   227 /* Macro definition for entry point of Power Resource Controller */
   228 #define DECLARE_RESOURCE_MANAGER_EXTENSION(TheController)															\
   228 #define DECLARE_RESOURCE_MANAGER_EXTENSION(TheController)															\
       
   229 	TDfc* resourceInitDfc = NULL;																					\
   229 	static void ResourceInit(TAny* aController)																		\
   230 	static void ResourceInit(TAny* aController)																		\
   230 		{																											\
   231 		{																											\
   231 		TInt aReason = NKern::EThread;																				\
   232 		TInt aReason = NKern::EThread;																				\
   232 		PRM_BOOTING_TRACE																							\
   233 		PRM_BOOTING_TRACE																							\
   233 		((DPowerResourceController*)aController)->InitResources();													\
   234 		((DPowerResourceController*)aController)->InitResources();													\
       
   235 		delete resourceInitDfc;																						\
   234 		return;																										\
   236 		return;																										\
   235 		}																											\
   237 		}																											\
   236 	void CreateController();																						\
   238 	void CreateController();																						\
   237 	GLDEF_C TInt KernelModuleEntry(TInt aReason)																	\
   239 	GLDEF_C TInt KernelModuleEntry(TInt aReason)																	\
   238 		{																											\
   240 		{																											\
   257 		if(!device)																									\
   259 		if(!device)																									\
   258 			return KErrNoMemory;																					\
   260 			return KErrNoMemory;																					\
   259 		r = Kern::InstallPhysicalDevice(device);																	\
   261 		r = Kern::InstallPhysicalDevice(device);																	\
   260 		if(r != KErrNone)																							\
   262 		if(r != KErrNone)																							\
   261 			return r;																								\
   263 			return r;																								\
   262 		TDfc* resourceInitDfc = new TDfc(&ResourceInit,(TAny*)&TheController,Kern::SvMsgQue(),KMaxDfcPriority-1);	\
   264 		resourceInitDfc = new TDfc(&ResourceInit,(TAny*)&TheController,Kern::SvMsgQue(),KMaxDfcPriority-1);			\
   263 		if(!resourceInitDfc)																						\
   265 		if(!resourceInitDfc)																						\
   264 			return KErrNoMemory;																					\
   266 			return KErrNoMemory;																					\
   265 		resourceInitDfc->Enque();																					\
   267 		resourceInitDfc->Enque();																					\
   266        	return KErrNone;																							\
   268        	return KErrNone;																							\
   267 		}																											\
   269 		}																											\
   268 		GLDEF_C void CreateController()
   270 		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 
   271 
   507 struct SPowerResourceClient;
   272 struct SPowerResourceClient;
   508 struct TPowerRequest;
   273 struct TPowerRequest;
   509 struct SPowerRequest;
   274 struct SPowerRequest;
   510 struct SPowerResourceClientLevel;
   275 struct SPowerResourceClientLevel;
   695 #ifdef PRM_ENABLE_EXTENDED_VERSION
   460 #ifdef PRM_ENABLE_EXTENDED_VERSION
   696 	/**@internalComponent*/
   461 	/**@internalComponent*/
   697 	TInt ReserveClientLevelPoolCount(TUint16 aCount);
   462 	TInt ReserveClientLevelPoolCount(TUint16 aCount);
   698 	/**@internalComponent*/
   463 	/**@internalComponent*/
   699 	void RemoveClientLevelFromPool(SPowerResourceClientLevel *&aLevelPtr);
   464 	void RemoveClientLevelFromPool(SPowerResourceClientLevel *&aLevelPtr);
       
   465 	/**@internalComponent*/
       
   466 	TInt HandleResourceChange(TPowerRequest &aRequest, TPropagation aProp, TUint aOriginatorId,
       
   467 									const TDesC8& aOriginatorName, DStaticPowerResourceD* aResource);
   700 #endif
   468 #endif
   701 protected:
   469 protected:
   702     //generic layer function to be called by the PSL
   470     //generic layer function to be called by the PSL
   703     DPowerResourceController();
   471     DPowerResourceController();
   704     void SetDfcQ(TDfcQue* aDfcQ);
   472     void SetDfcQ(TDfcQue* aDfcQ);
   767 #endif
   535 #endif
   768 private:
   536 private:
   769     DStaticPowerResource** iStaticResourceArray;
   537     DStaticPowerResource** iStaticResourceArray;
   770     DResourceCon<SPowerResourceClient> iClientList;
   538     DResourceCon<SPowerResourceClient> iClientList;
   771     DResourceCon<SPowerResourceClient> iUserSideClientList;
   539     DResourceCon<SPowerResourceClient> iUserSideClientList;
       
   540 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
       
   541 	RPointerArray<SPowerResourceClient> iCleanList;
       
   542 #endif
   772     SPowerResourceClient* iClientPool;
   543     SPowerResourceClient* iClientPool;
   773     SPowerRequest* iRequestPool;
   544     SPowerRequest* iRequestPool;
   774     SPowerResourceClientLevel* iClientLevelPool;
   545     SPowerResourceClientLevel* iClientLevelPool;
   775 	TUint iPowerControllerId; //Stores the ID allocated to PowerController
   546 	TUint iPowerControllerId; //Stores the ID allocated to PowerController
   776     SIdleResourceInfo* iListForIdle;
   547     SIdleResourceInfo* iListForIdle;