kernel/eka/drivers/resourceman/rescontrol_export.cpp
changeset 0 a41df078684a
child 43 c1f20ce4abcf
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\drivers\resourceman\rescontrol_export.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <drivers/resourcecontrol.h>
       
    19 
       
    20 #ifdef DEBUG_VERSION
       
    21 #define GET_CRITICAL_SECTION_COUNT(thread)				\
       
    22 	TInt CsCount = thread.iNThread.iCsCount;
       
    23 
       
    24 #define LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)			\
       
    25 	if(thread.iNThread.iCsCount != CsCount)						\
       
    26 		Kern::Fault("PowerResourceController", __LINE__);		\
       
    27 	if(pRC->iResourceMutex->iHoldCount != 0)					\
       
    28 		Kern::Fault("PowerResourceController", __LINE__);	
       
    29 #else
       
    30 #define GET_CRITICAL_SECTION_COUNT(thread)
       
    31 #define LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
       
    32 #endif
       
    33 
       
    34 /**
       
    35 	@publishedPartner
       
    36 	@prototype 9.5
       
    37 	Kernel extension or variants can call this API to set the post bool value without registering
       
    38 	as client with the resource controller. This can be used by the resource controller PSL to set the
       
    39 	specified static resources to appropriate value before resource controller is fully initialized.
       
    40 	@param aResId ID of the resource whose level should be set after initialisation
       
    41 	@param aLevel Resource level to set
       
    42 	@return KErrNone, if operation is success
       
    43 			KErrNotFound, if resource ID could not be found in the static resource array.
       
    44 			KErrNotSupported, if this API is called after resource controller is fully initialized
       
    45 	*/
       
    46 EXPORT_C TInt DPowerResourceController::PostBootLevel(TUint aResId, TInt aLevel)
       
    47 	{
       
    48 #ifdef DEBUG_VERSION
       
    49 	DThread& thread = Kern::CurrentThread();
       
    50 	GET_CRITICAL_SECTION_COUNT(thread)
       
    51 #endif
       
    52     __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::PostBootLevel, aResId = 0x%x, aLevel = %d", 
       
    53 	                                                                          aResId, aLevel));
       
    54     DPowerResourceController* pRC = TInterface::GetPowerResourceController();
       
    55 	if(!pRC)
       
    56 		return KErrNotFound;
       
    57 	pRC->Lock();
       
    58     CHECK_CONTEXT(thread)
       
    59 	//Accept the postboot level only if issued before controller is fully initialised.
       
    60 	if(pRC->iInitialised == EResConStartupCompleted)
       
    61 		{
       
    62 		pRC->UnLock();
       
    63 		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
       
    64 		return KErrNotSupported;
       
    65 		}	
       
    66 #ifndef PRM_ENABLE_EXTENDED_VERSION
       
    67     // coverity[deref_ptr]
       
    68     // aResId is checked to be more than the array entries before dereferencing pRC->iStaticResourceArray
       
    69 	if((!aResId) || (aResId > pRC->iStaticResourceArrayEntries) || (!pRC->iStaticResourceArray[aResId-1]))
       
    70 		{
       
    71 		pRC->UnLock();
       
    72 		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
       
    73 		return KErrNotFound;
       
    74 		}
       
    75 #else
       
    76 	if(!aResId || ((aResId & KIdMaskResourceWithDependencies) && ((aResId & ID_INDEX_BIT_MASK) > pRC->iStaticResDependencyCount)) 
       
    77 				|| (!(aResId & KIdMaskResourceWithDependencies) && ((aResId > pRC->iStaticResourceArrayEntries)
       
    78 				|| (!pRC->iStaticResourceArray[aResId-1]))))
       
    79 		{
       
    80 		pRC->UnLock();
       
    81 		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
       
    82 		return KErrNotFound;
       
    83 		}
       
    84 	if(aResId & KIdMaskResourceWithDependencies)
       
    85 		{
       
    86 		aResId &= ID_INDEX_BIT_MASK;
       
    87 		DStaticPowerResource* pR = pRC->iStaticResDependencyArray[--aResId];
       
    88 		pR->iPostBootLevel=aLevel;
       
    89 		pR->iFlags |= SET_VALID_POST_BOOT_LEVEL;
       
    90 		}
       
    91 	else
       
    92 #endif
       
    93     if(pRC->iStaticResourceArray) 
       
    94 		{
       
    95 		DStaticPowerResource* pR=pRC->iStaticResourceArray[--aResId];
       
    96 		pR->iPostBootLevel=aLevel;
       
    97 		pR->iFlags |= SET_VALID_POST_BOOT_LEVEL; // To indicate valid post boot level is set.
       
    98 		}
       
    99 	pRC->UnLock();
       
   100 	LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
       
   101 	return KErrNone;
       
   102     }
       
   103 
       
   104 /** 
       
   105 	@publishedPartner
       
   106 	@prototype 9.5
       
   107 	Kernel extensions or variants can call this API to register the static resources before resource controller
       
   108 	is fully initialised.
       
   109 	@Param aClientId             ID of the client that is requesting resource registration
       
   110 	@Param aStaticResourceArray  Static resources to register with RC. 
       
   111 	@Param aResCount             Number of static resources to register with RC. This equals the size of the passed array.
       
   112 	@return KErrNone, if operation is success
       
   113 	        KErrAccessDenied if clientId could not be found in the current list of registered clients or if this
       
   114 			                 client was registered as thread relative and was not called from the same thread.
       
   115 			KErrNotSupported if called after resource controller is fully initialised or if called from user side proxy
       
   116 			                 or if the resource is dynamic or dependency resource.
       
   117 			KErrNoMemory     if there is insufficient memory.
       
   118 			KErrArgument     if passed array is null or passed number of resources count is 0.
       
   119 	*/
       
   120 EXPORT_C TInt DPowerResourceController::RegisterArrayOfStaticResources(TUint aClientId, DStaticPowerResource**& aStaticResourceArray, TUint aResCount)
       
   121 	{
       
   122 	DThread& thread = Kern::CurrentThread();
       
   123 	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterStaticResource"));
       
   124     DPowerResourceController* pRC = TInterface::GetPowerResourceController();
       
   125 	if(!pRC)
       
   126 		return KErrNotFound;
       
   127 
       
   128 	if(!aStaticResourceArray || (aResCount == 0))
       
   129 		return KErrArgument;
       
   130     CHECK_CONTEXT(thread)
       
   131 	//Accept the registration of static resource only if issued before controller is fully initialised.
       
   132 	if(pRC->iInitialised == EResConStartupCompleted)
       
   133 		{
       
   134 		return KErrNotSupported;
       
   135 		}
       
   136 	//User side clients and resource with dependency are not supported.
       
   137 	if(aClientId & USER_SIDE_CLIENT_BIT_MASK)
       
   138 		{
       
   139 		return KErrNotSupported;
       
   140 		}
       
   141 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   142 	if(aResCount == 1)
       
   143 		{
       
   144 		if((((DStaticPowerResource*)aStaticResourceArray)->iResourceId & KIdMaskResourceWithDependencies) ||
       
   145 										(((DStaticPowerResource*)aStaticResourceArray)->iResourceId & KIdMaskDynamic))
       
   146 			{
       
   147 			return KErrNotSupported;
       
   148 			}
       
   149 		}
       
   150 	else
       
   151 		{
       
   152 		for(TUint rescount = 0; rescount < aResCount; rescount++)
       
   153 			{
       
   154 			if(aStaticResourceArray[rescount] && ((aStaticResourceArray[rescount]->iResourceId & KIdMaskResourceWithDependencies) || 
       
   155 				                          (aStaticResourceArray[rescount]->iResourceId & KIdMaskDynamic)))
       
   156 				{
       
   157 				return KErrNotSupported;
       
   158 				}
       
   159 			}
       
   160 		}
       
   161 #endif
       
   162 	SPowerResourceClient* pC = pRC->iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];								
       
   163 	if(!pC)																										
       
   164 		{																										
       
   165 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found"));											
       
   166 		return KErrAccessDenied;																		
       
   167 		}																										
       
   168 	if(pC->iClientId != aClientId)				
       
   169 		{																										
       
   170 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID instance count does not match"));						
       
   171 		return KErrAccessDenied;																		
       
   172 		}																										
       
   173 	if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK)															
       
   174 		{																										
       
   175 		if(pC->iThreadId != thread.iId)																				
       
   176 			{																									
       
   177 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client not called from thread context(Thread Relative)"));	
       
   178 			return KErrAccessDenied;																	
       
   179 			}																									
       
   180 		}
       
   181  
       
   182     TInt r = Kern::SafeReAlloc((TAny*&)pRC->iStaticResourceArray, pRC->iStaticResourceArrayEntries*sizeof(DStaticPowerResource*), 
       
   183 		                                         (pRC->iStaticResourceArrayEntries + aResCount)*sizeof(DStaticPowerResource*));
       
   184     if(r != KErrNone)
       
   185 		{
       
   186         return r;
       
   187 		}
       
   188 	if(aResCount == 1)
       
   189 		{
       
   190 		pRC->iStaticResourceArray[pRC->iStaticResourceArrayEntries++] = (DStaticPowerResource*)aStaticResourceArray;
       
   191 		if((DStaticPowerResource*)aStaticResourceArray)
       
   192 			pRC->iStaticResourceCount++;
       
   193 		}
       
   194 	else
       
   195 		{
       
   196 		for(TUint count = 0; count < aResCount; count++)
       
   197 			{
       
   198 			pRC->iStaticResourceArray[pRC->iStaticResourceArrayEntries++] = aStaticResourceArray[count];
       
   199 			if(aStaticResourceArray[count])
       
   200 				pRC->iStaticResourceCount++;
       
   201 			}
       
   202 		}
       
   203     return KErrNone;
       
   204 	}
       
   205 
       
   206 /**
       
   207 	@publishedPartner
       
   208 	@prototype 9.5
       
   209 	Kernel extensions or variants can call this API to register the static resources before resource controller
       
   210 	is fully initialized. 
       
   211 	@Param aClientId ID of the client that is requesting resource registration
       
   212 	@Param pR        Static resource to register with RC. 
       
   213 	@return KErrNone, if operation is success
       
   214 			KErrAccessDenied if clientId could not be found in the current list of registered clients or if this 
       
   215 							 client was registered as thread relative and was not called from the same thread. 
       
   216 			KErrNotSupported if called after resource controller is fully initialized or if called from user side proxy
       
   217 							 or if the resource is dynamic or dependency resource
       
   218 			KErrNoMemory if there is insufficient memory.
       
   219 			KErrArgument if passed array is null
       
   220 	*/
       
   221 EXPORT_C TInt DPowerResourceController::RegisterStaticResource(TUint aClientId, DStaticPowerResource* pR)
       
   222 	{
       
   223 	return RegisterArrayOfStaticResources(aClientId, (DStaticPowerResource**&)pR, 1);
       
   224     }
       
   225 
       
   226 /**
       
   227 	@publishedPartner
       
   228 	@prototype 9.5
       
   229 	This function initialises the controller. 
       
   230 	@return KErrNone, if operation is success or one of the system wide errors.
       
   231 	*/
       
   232 EXPORT_C TInt DPowerResourceController::InitController()
       
   233 	{
       
   234     __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::InitController()"));
       
   235 	DPowerResourceController* pRC = TInterface::GetPowerResourceController();
       
   236 	if(!pRC)
       
   237 		return KErrNotFound;
       
   238 	if(pRC->iInitialised >= EResConInitialised)
       
   239 		{
       
   240 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("InitController already initialised %d\n", pRC->iInitialised));
       
   241 		return KErrNone;
       
   242 		}
       
   243     _LIT(KResMutexName, "RESCTRL");
       
   244     TInt r=KErrNone;
       
   245 	//Create the message queue
       
   246 	pRC->iMsgQ = new TMessageQue(DPowerResourceController::MsgQFunc, pRC, NULL, 2);
       
   247 	if(!pRC->iMsgQ)
       
   248 		return KErrNoMemory;
       
   249 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   250 	//Create the message queue for dependency resource processing.
       
   251 	pRC->iMsgQDependency = new TMessageQue(DPowerResourceController::MsgQDependencyFunc, pRC, NULL, 1);
       
   252 	if(!pRC->iMsgQDependency)
       
   253 		return KErrNoMemory;
       
   254 #endif
       
   255 	// Call PSL to create all static resources and populate the iStaticResourceArray with pointers to resources and
       
   256 	// update static resource count
       
   257     r=pRC->DoRegisterStaticResources(pRC->iStaticResourceArray, pRC->iStaticResourceArrayEntries);
       
   258     if(r!=KErrNone)
       
   259 		return r;
       
   260 	//Get the actual number of static resource registered count
       
   261 	for(TInt resCnt = 0; resCnt < pRC->iStaticResourceArrayEntries; resCnt++)
       
   262 		{
       
   263 		if(pRC->iStaticResourceArray[resCnt])
       
   264 			pRC->iStaticResourceCount++;
       
   265 		}
       
   266 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("Actual number of static resource registered = %d\n", pRC->iStaticResourceCount));
       
   267 #ifdef PRM_INSTRUMENTATION_MACRO
       
   268 	// Btrace output of resource information of each resource.
       
   269 	DStaticPowerResource* pR = NULL;
       
   270 	TPowerResourceInfoBuf01 resInfo;
       
   271 	TPowerResourceInfoV01 *pResInfo;
       
   272 	for(TInt resCount = 0; resCount < pRC->iStaticResourceArrayEntries; resCount++)
       
   273 		{
       
   274 		pR = pRC->iStaticResourceArray[resCount];
       
   275 		if(!pR)
       
   276 			continue;
       
   277 		pR->GetInfo((TDes8*)resInfo.Ptr());
       
   278 		pResInfo = (TPowerResourceInfoV01*)resInfo.Ptr();
       
   279 		PRM_REGISTER_RESOURCE_TRACE
       
   280 		}
       
   281 #endif
       
   282 
       
   283 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   284 	//Call PSL to register static resources with dependency if any exists
       
   285 	r = pRC->DoRegisterStaticResourcesDependency(pRC->iStaticResDependencyArray, pRC->iStaticResDependencyCount);
       
   286 	if(r != KErrNone)
       
   287 		return r;
       
   288 	if(pRC->iStaticResDependencyCount)
       
   289 		{
       
   290 		DStaticPowerResourceD* pRD = NULL;
       
   291 		TUint count;
       
   292 		//Assign resource index in resource id
       
   293 		for(count = 0; count < pRC->iStaticResDependencyCount; count++)
       
   294 			{
       
   295 			pRD = pRC->iStaticResDependencyArray[count];
       
   296 			if(!pRD)
       
   297 				Panic(DPowerResourceController::ERegisteringDependentStaticResourceWithHoles);
       
   298 			pRD->iResourceId |= ((count + 1) & ID_INDEX_BIT_MASK);
       
   299 			}
       
   300 		//Check for dependency closed loops
       
   301 		for(count = 0; count < pRC->iStaticResDependencyCount; count++)
       
   302 			{
       
   303 			pRD = pRC->iStaticResDependencyArray[count];
       
   304 			if(!(pRD->iResourceId & KIdMaskStaticWithDependencies))
       
   305 				Panic(DPowerResourceController::ERegisteringNonDependentStaticResource);
       
   306 			//Upgrade latency state change from instantaneous to long latency 
       
   307 			if(!pRD->LatencySet()) 
       
   308 				pRD->iFlags |= KLongLatencySet;
       
   309 			pRC->CheckForDependencyLoop(pRD, pRD->iResourceId, pRD->iResourceId);
       
   310 			}
       
   311 #ifdef PRM_INSTRUMENTATION_MACRO
       
   312 		for(count = 0; count < pRC->iStaticResDependencyCount; count++)
       
   313 			{
       
   314 			pR = pRC->iStaticResDependencyArray[count];
       
   315 			pR->GetInfo((TDes8*)resInfo.Ptr());
       
   316 			pResInfo = (TPowerResourceInfoV01*)resInfo.Ptr();
       
   317 			PRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY_TRACE
       
   318 			}
       
   319 #endif
       
   320 		}
       
   321 #endif // PRM_ENABLE_EXTENDED_VERSION
       
   322 	// Create mutex object
       
   323 	r=Kern::MutexCreate(pRC->iResourceMutex, KResMutexName, KMutexOrdResourceManager);
       
   324 	if(r==KErrNone) // Call PSL to create DFC queue and creation of pools with the help API's provided by generic layer.
       
   325 		r=pRC->DoInitController();
       
   326 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::InitController()"));
       
   327 	if(r == KErrNone)
       
   328 		{
       
   329 		pRC->iInitialised = EResConInitialised;
       
   330 	    if(pRC->iDfcQ)
       
   331 			pRC->iMsgQ->Receive();
       
   332 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   333 	    if(pRC->iDfcQDependency)
       
   334 			pRC->iMsgQDependency->Receive();
       
   335 #endif
       
   336 		}
       
   337     return r;
       
   338 	}