kernel/eka/drivers/resourceman/rescontrol_export.cpp
changeset 259 57b9594f5772
parent 0 a41df078684a
child 257 3e88ff8f41d5
equal deleted inserted replaced
247:d8d70de2bd36 259:57b9594f5772
    10 //
    10 //
    11 // Contributors:
    11 // Contributors:
    12 //
    12 //
    13 // Description:
    13 // Description:
    14 // e32\drivers\resourceman\rescontrol_export.cpp
    14 // e32\drivers\resourceman\rescontrol_export.cpp
    15 // 
    15 //
    16 //
    16 //
    17 
    17 
    18 #include <drivers/resourcecontrol.h>
    18 #include <drivers/resourcecontrol.h>
    19 
    19 
    20 #ifdef DEBUG_VERSION
    20 #ifdef DEBUG_VERSION
    53 	                                                                          aResId, aLevel));
    53 	                                                                          aResId, aLevel));
    54     DPowerResourceController* pRC = TInterface::GetPowerResourceController();
    54     DPowerResourceController* pRC = TInterface::GetPowerResourceController();
    55 	if(!pRC)
    55 	if(!pRC)
    56 		return KErrNotFound;
    56 		return KErrNotFound;
    57 	pRC->Lock();
    57 	pRC->Lock();
    58     CHECK_CONTEXT(thread)
    58     CHECK_CONTEXT(thread);
    59 	//Accept the postboot level only if issued before controller is fully initialised.
    59 	//Accept the postboot level only if issued before controller is fully initialised.
    60 	if(pRC->iInitialised == EResConStartupCompleted)
    60 	if(pRC->iInitialised == EResConStartupCompleted)
    61 		{
    61 		{
    62 		pRC->UnLock();
    62 		pRC->UnLock();
    63 		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
    63 		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
    64 		return KErrNotSupported;
    64 		return KErrNotSupported;
    65 		}	
    65 		}	
    66 #ifndef PRM_ENABLE_EXTENDED_VERSION
    66 #ifndef PRM_ENABLE_EXTENDED_VERSION
    67     // coverity[deref_ptr]
    67     // coverity[deref_ptr]
    68     // aResId is checked to be more than the array entries before dereferencing pRC->iStaticResourceArray
    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]))
    69 	if((!aResId) || (aResId > (TUint)pRC->iStaticResourceArray.Count()) || (!pRC->iStaticResourceArray[aResId-1]))
    70 		{
    70 		{
    71 		pRC->UnLock();
    71 		pRC->UnLock();
    72 		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
    72 		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
    73 		return KErrNotFound;
    73 		return KErrNotFound;
    74 		}
    74 		}
    75 #else
    75 #else
    76 	if(!aResId || ((aResId & KIdMaskResourceWithDependencies) && ((aResId & ID_INDEX_BIT_MASK) > pRC->iStaticResDependencyCount)) 
    76 	if(!aResId || ((aResId & KIdMaskResourceWithDependencies) && ((aResId & ID_INDEX_BIT_MASK) > (TUint)pRC->iStaticResDependencyArray.Count())) 
    77 				|| (!(aResId & KIdMaskResourceWithDependencies) && ((aResId > pRC->iStaticResourceArrayEntries)
    77 				|| (!(aResId & KIdMaskResourceWithDependencies) && ((aResId > (TUint)pRC->iStaticResourceArray.Count())
    78 				|| (!pRC->iStaticResourceArray[aResId-1]))))
    78 				|| (!pRC->iStaticResourceArray[aResId-1]))))
    79 		{
    79 		{
    80 		pRC->UnLock();
    80 		pRC->UnLock();
    81 		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
    81 		LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
    82 		return KErrNotFound;
    82 		return KErrNotFound;
    88 		pR->iPostBootLevel=aLevel;
    88 		pR->iPostBootLevel=aLevel;
    89 		pR->iFlags |= SET_VALID_POST_BOOT_LEVEL;
    89 		pR->iFlags |= SET_VALID_POST_BOOT_LEVEL;
    90 		}
    90 		}
    91 	else
    91 	else
    92 #endif
    92 #endif
    93     if(pRC->iStaticResourceArray) 
    93     if((TUint)pRC->iStaticResourceArray.Count() > aResId - 1)
    94 		{
    94 		{
    95 		DStaticPowerResource* pR=pRC->iStaticResourceArray[--aResId];
    95 		DStaticPowerResource* pR=pRC->iStaticResourceArray[--aResId];
    96 		pR->iPostBootLevel=aLevel;
    96 		pR->iPostBootLevel=aLevel;
    97 		pR->iFlags |= SET_VALID_POST_BOOT_LEVEL; // To indicate valid post boot level is set.
    97 		pR->iFlags |= SET_VALID_POST_BOOT_LEVEL; // To indicate valid post boot level is set.
    98 		}
    98 		}
   105 	@publishedPartner
   105 	@publishedPartner
   106 	@prototype 9.5
   106 	@prototype 9.5
   107 	Kernel extensions or variants can call this API to register the static resources before resource controller
   107 	Kernel extensions or variants can call this API to register the static resources before resource controller
   108 	is fully initialised.
   108 	is fully initialised.
   109 	@Param aClientId             ID of the client that is requesting resource registration
   109 	@Param aClientId             ID of the client that is requesting resource registration
   110 	@Param aStaticResourceArray  Static resources to register with RC. 
   110 	@Param aStaticResourceArray  Static resources to register with RC.
       
   111 	                             Note, that in the special case, when aResCount equals to one, this parameter is treated as a pointer to the
       
   112 	                             DStaticPowerResource (DStaticPowerResource*). Otherwise - is the pointer to array of such pointers (DStaticPowerResource*).
   111 	@Param aResCount             Number of static resources to register with RC. This equals the size of the passed array.
   113 	@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
   114 	@return KErrNone, if operation is success
   113 	        KErrAccessDenied if clientId could not be found in the current list of registered clients or if this
   115 	        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.
   116 			                 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
   117 			KErrNotSupported if called after resource controller is fully initialised or if called from user side proxy
   125 	if(!pRC)
   127 	if(!pRC)
   126 		return KErrNotFound;
   128 		return KErrNotFound;
   127 
   129 
   128 	if(!aStaticResourceArray || (aResCount == 0))
   130 	if(!aStaticResourceArray || (aResCount == 0))
   129 		return KErrArgument;
   131 		return KErrArgument;
   130     CHECK_CONTEXT(thread)
   132 	CHECK_CONTEXT(thread);
   131 	//Accept the registration of static resource only if issued before controller is fully initialised.
   133 	//Accept the registration of static resource only if issued before controller is fully initialised.
   132 	if(pRC->iInitialised == EResConStartupCompleted)
   134 	if(pRC->iInitialised == EResConStartupCompleted)
   133 		{
   135 		{
   134 		return KErrNotSupported;
   136 		return KErrNotSupported;
   135 		}
   137 		}
   137 	if(aClientId & USER_SIDE_CLIENT_BIT_MASK)
   139 	if(aClientId & USER_SIDE_CLIENT_BIT_MASK)
   138 		{
   140 		{
   139 		return KErrNotSupported;
   141 		return KErrNotSupported;
   140 		}
   142 		}
   141 #ifdef PRM_ENABLE_EXTENDED_VERSION
   143 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   144 	// if aResCount equals to 1 aStaticResourceArray contains not an array, but simply a pointer to the resource.
   142 	if(aResCount == 1)
   145 	if(aResCount == 1)
   143 		{
   146 		{
   144 		if((((DStaticPowerResource*)aStaticResourceArray)->iResourceId & KIdMaskResourceWithDependencies) ||
   147 		if(((DStaticPowerResource*)aStaticResourceArray)->iResourceId & (KIdMaskResourceWithDependencies | KIdMaskDynamic))
   145 										(((DStaticPowerResource*)aStaticResourceArray)->iResourceId & KIdMaskDynamic))
       
   146 			{
   148 			{
   147 			return KErrNotSupported;
   149 			return KErrNotSupported;
   148 			}
   150 			}
   149 		}
   151 		}
   150 	else
   152 	else
   151 		{
   153 		{
   152 		for(TUint rescount = 0; rescount < aResCount; rescount++)
   154 		for(TUint rescount = 0; rescount < aResCount; rescount++)
   153 			{
   155 			{
   154 			if(aStaticResourceArray[rescount] && ((aStaticResourceArray[rescount]->iResourceId & KIdMaskResourceWithDependencies) || 
   156 			if(aStaticResourceArray[rescount] &&
   155 				                          (aStaticResourceArray[rescount]->iResourceId & KIdMaskDynamic)))
   157 			  (aStaticResourceArray[rescount]->iResourceId & (KIdMaskResourceWithDependencies | KIdMaskDynamic)))
   156 				{
   158 				{
   157 				return KErrNotSupported;
   159 				return KErrNotSupported;
   158 				}
   160 				}
   159 			}
   161 			}
   160 		}
   162 		}
   161 #endif
   163 #endif
   162 	SPowerResourceClient* pC = pRC->iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];								
   164 	SPowerResourceClient* pC = pRC->iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];
   163 	if(!pC)																										
   165 	if(!pC)
   164 		{																										
   166 		{
   165 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found"));											
   167 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found"));
   166 		return KErrAccessDenied;																		
   168 		return KErrAccessDenied;
   167 		}																										
   169 		}
   168 	if(pC->iClientId != aClientId)				
   170 	if(pC->iClientId != aClientId)
   169 		{																										
   171 		{
   170 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID instance count does not match"));						
   172 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID instance count does not match"));
   171 		return KErrAccessDenied;																		
   173 		return KErrAccessDenied;
   172 		}																										
   174 		}
   173 	if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK)															
   175 	if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK)
   174 		{																										
   176 		{
   175 		if(pC->iThreadId != thread.iId)																				
   177 		if(pC->iThreadId != thread.iId)
   176 			{																									
   178 			{
   177 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client not called from thread context(Thread Relative)"));	
   179 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client not called from thread context(Thread Relative)"));
   178 			return KErrAccessDenied;																	
   180 			return KErrAccessDenied;
   179 			}																									
   181 			}
   180 		}
   182 		}
   181  
   183 
   182     TInt r = Kern::SafeReAlloc((TAny*&)pRC->iStaticResourceArray, pRC->iStaticResourceArrayEntries*sizeof(DStaticPowerResource*), 
   184     TInt r = KErrNone;
   183 		                                         (pRC->iStaticResourceArrayEntries + aResCount)*sizeof(DStaticPowerResource*));
       
   184     if(r != KErrNone)
       
   185 		{
       
   186         return r;
       
   187 		}
       
   188 	if(aResCount == 1)
   185 	if(aResCount == 1)
   189 		{
   186 		{
   190 		pRC->iStaticResourceArray[pRC->iStaticResourceArrayEntries++] = (DStaticPowerResource*)aStaticResourceArray;
   187 		// if aResCount equals to one, threat the pointer as a pointer to resource
   191 		if((DStaticPowerResource*)aStaticResourceArray)
   188 		r = pRC->iStaticResourceArray.Append((DStaticPowerResource*)aStaticResourceArray);
       
   189 		// increment count of valid resources
       
   190 		if(r == KErrNone && aStaticResourceArray)
   192 			pRC->iStaticResourceCount++;
   191 			pRC->iStaticResourceCount++;
   193 		}
   192 		}
   194 	else
   193 	else
   195 		{
   194 		{
   196 		for(TUint count = 0; count < aResCount; count++)
   195 		for(TUint count = 0; count < aResCount; count++)
   197 			{
   196 			{
   198 			pRC->iStaticResourceArray[pRC->iStaticResourceArrayEntries++] = aStaticResourceArray[count];
   197 			r = pRC->iStaticResourceArray.Append(aStaticResourceArray[count]);
       
   198 			if(r != KErrNone)
       
   199 				{
       
   200 				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Could not add new static resources, r = %d", r));
       
   201 				break;
       
   202 				}
       
   203 			// increment count of valid resources
   199 			if(aStaticResourceArray[count])
   204 			if(aStaticResourceArray[count])
   200 				pRC->iStaticResourceCount++;
   205 				pRC->iStaticResourceCount++;
   201 			}
   206 			}
   202 		}
   207 		}
   203     return KErrNone;
   208 
       
   209 	return r;
   204 	}
   210 	}
   205 
   211 
   206 /**
   212 /**
   207 	@publishedPartner
   213 	@publishedPartner
   208 	@prototype 9.5
   214 	@prototype 9.5
   227 	@publishedPartner
   233 	@publishedPartner
   228 	@prototype 9.5
   234 	@prototype 9.5
   229 	This function initialises the controller. 
   235 	This function initialises the controller. 
   230 	@return KErrNone, if operation is success or one of the system wide errors.
   236 	@return KErrNone, if operation is success or one of the system wide errors.
   231 	*/
   237 	*/
       
   238 RPointerArray <DStaticPowerResource> *StaticResourceArrayPtr;
       
   239 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   240 RPointerArray <DStaticPowerResourceD> *StaticResourceDependencyArrayPtr;
       
   241 #endif
   232 EXPORT_C TInt DPowerResourceController::InitController()
   242 EXPORT_C TInt DPowerResourceController::InitController()
   233 	{
   243 	{
   234     __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::InitController()"));
   244     __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::InitController()"));
   235 	DPowerResourceController* pRC = TInterface::GetPowerResourceController();
   245 	DPowerResourceController* pRC = TInterface::GetPowerResourceController();
   236 	if(!pRC)
   246 	if(!pRC)
   250 	//Create the message queue for dependency resource processing.
   260 	//Create the message queue for dependency resource processing.
   251 	pRC->iMsgQDependency = new TMessageQue(DPowerResourceController::MsgQDependencyFunc, pRC, NULL, 1);
   261 	pRC->iMsgQDependency = new TMessageQue(DPowerResourceController::MsgQDependencyFunc, pRC, NULL, 1);
   252 	if(!pRC->iMsgQDependency)
   262 	if(!pRC->iMsgQDependency)
   253 		return KErrNoMemory;
   263 		return KErrNoMemory;
   254 #endif
   264 #endif
   255 	// Call PSL to create all static resources and populate the iStaticResourceArray with pointers to resources and
   265 	// This method can be called in two situations - before the constructor of DPowerResourceController was called 
   256 	// update static resource count
   266 	// for the second time (placement new in the extension psl entry macro) e.g. as a result of the call to InitResources() 
   257     r=pRC->DoRegisterStaticResources(pRC->iStaticResourceArray, pRC->iStaticResourceArrayEntries);
   267 	// from the variant::Init3() method) or after that.
   258     if(r!=KErrNone)
   268 
       
   269 	// In order not to make any assumption on number of constructor invocations, a copy (binary) of the iStaticResourceArray object 
       
   270 	// is created below, so that it could be used to later restore the original iStaticResoureceArray object if the constructor
       
   271 	// was called after this method. The reason for that is, that in this destructor calls the default RPointerArrayBase()
       
   272 	// which resets the array, i.e. it looses the information, but allocated area and pointers still exist in the memory. 
       
   273 	// It is then valid to restore the object directly (which will copy all members, including iSize and iEntries pointers). 
       
   274 	// This temporary object will be deleted in DPowerResourceController::InitResources() at the last stage of initialization.
       
   275 	// (see also comments in DPowerResourceController::DPowerResourceController()) 
       
   276 
       
   277 	StaticResourceArrayPtr = new RPointerArray <DStaticPowerResource>;
       
   278 	if(!StaticResourceArrayPtr)
       
   279 		return KErrNoMemory;
       
   280 
       
   281 	r = pRC->DoRegisterStaticResources(pRC->iStaticResourceArray);
       
   282 	if(r != KErrNone)
   259 		return r;
   283 		return r;
   260 	//Get the actual number of static resource registered count
   284 
   261 	for(TInt resCnt = 0; resCnt < pRC->iStaticResourceArrayEntries; resCnt++)
   285 	// make a copy (see above comment)
       
   286 	*StaticResourceArrayPtr = pRC->iStaticResourceArray; 
       
   287 
       
   288 	// Get the actual number of static resource registered count
       
   289 	for(TInt resCnt = 0; resCnt < pRC->iStaticResourceArray.Count(); resCnt++)
   262 		{
   290 		{
   263 		if(pRC->iStaticResourceArray[resCnt])
   291 		if(pRC->iStaticResourceArray[resCnt])
   264 			pRC->iStaticResourceCount++;
   292 			pRC->iStaticResourceCount++;
   265 		}
   293 		}
   266 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("Actual number of static resource registered = %d\n", pRC->iStaticResourceCount));
   294 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("Actual number of static resource registered = %d\n", pRC->iStaticResourceCount));
   267 #ifdef PRM_INSTRUMENTATION_MACRO
   295 #ifdef PRM_INSTRUMENTATION_MACRO
   268 	// Btrace output of resource information of each resource.
   296 	// Btrace output of resource information of each resource.
   269 	DStaticPowerResource* pR = NULL;
   297 	DStaticPowerResource* pR = NULL;
   270 	TPowerResourceInfoBuf01 resInfo;
   298 	TPowerResourceInfoBuf01 resInfo;
   271 	TPowerResourceInfoV01 *pResInfo;
   299 	TPowerResourceInfoV01 *pResInfo;
   272 	for(TInt resCount = 0; resCount < pRC->iStaticResourceArrayEntries; resCount++)
   300 	for(TInt resCount = 0; resCount < pRC->iStaticResourceArray.Count(); resCount++)
   273 		{
   301 		{
   274 		pR = pRC->iStaticResourceArray[resCount];
   302 		pR = pRC->iStaticResourceArray[resCount];
   275 		if(!pR)
   303 		if(!pR)
   276 			continue;
   304 			continue;
   277 		pR->GetInfo((TDes8*)resInfo.Ptr());
   305 		pR->GetInfo((TDes8*)resInfo.Ptr());
   279 		PRM_REGISTER_RESOURCE_TRACE
   307 		PRM_REGISTER_RESOURCE_TRACE
   280 		}
   308 		}
   281 #endif
   309 #endif
   282 
   310 
   283 #ifdef PRM_ENABLE_EXTENDED_VERSION
   311 #ifdef PRM_ENABLE_EXTENDED_VERSION
   284 	//Call PSL to register static resources with dependency if any exists
   312 	StaticResourceDependencyArrayPtr = new RPointerArray <DStaticPowerResourceD>;
   285 	r = pRC->DoRegisterStaticResourcesDependency(pRC->iStaticResDependencyArray, pRC->iStaticResDependencyCount);
   313 	if(!StaticResourceDependencyArrayPtr)
       
   314 		return KErrNoMemory;
       
   315 
       
   316 	// Call PSL to register static resources with dependency if any exists
       
   317 	r = pRC->DoRegisterStaticResourcesDependency(pRC->iStaticResDependencyArray);
       
   318 
   286 	if(r != KErrNone)
   319 	if(r != KErrNone)
   287 		return r;
   320 		return r;
   288 	if(pRC->iStaticResDependencyCount)
   321 
       
   322 	// make a copy (see above comments for StaticResourceArrayPtr)
       
   323 	*StaticResourceDependencyArrayPtr = pRC->iStaticResDependencyArray;
       
   324 
       
   325 	if(pRC->iStaticResDependencyArray.Count())
   289 		{
   326 		{
   290 		DStaticPowerResourceD* pRD = NULL;
   327 		DStaticPowerResourceD* pRD = NULL;
   291 		TUint count;
   328 		TUint count;
   292 		//Assign resource index in resource id
   329 		//Assign resource index in resource id
   293 		for(count = 0; count < pRC->iStaticResDependencyCount; count++)
   330 		for(count = 0; count < (TUint)pRC->iStaticResDependencyArray.Count(); count++)
   294 			{
   331 			{
   295 			pRD = pRC->iStaticResDependencyArray[count];
   332 			pRD = pRC->iStaticResDependencyArray[count];
   296 			if(!pRD)
   333 			if(!pRD)
   297 				Panic(DPowerResourceController::ERegisteringDependentStaticResourceWithHoles);
   334 				Panic(DPowerResourceController::ERegisteringDependentStaticResourceWithHoles);
   298 			pRD->iResourceId |= ((count + 1) & ID_INDEX_BIT_MASK);
   335 			pRD->iResourceId |= ((count + 1) & ID_INDEX_BIT_MASK);
   299 			}
   336 			}
   300 		//Check for dependency closed loops
   337 		//Check for dependency closed loops
   301 		for(count = 0; count < pRC->iStaticResDependencyCount; count++)
   338 		for(count = 0; count < (TUint)pRC->iStaticResDependencyArray.Count(); count++)
   302 			{
   339 			{
   303 			pRD = pRC->iStaticResDependencyArray[count];
   340 			pRD = pRC->iStaticResDependencyArray[count];
   304 			if(!(pRD->iResourceId & KIdMaskStaticWithDependencies))
   341 			if(!(pRD->iResourceId & KIdMaskStaticWithDependencies))
   305 				Panic(DPowerResourceController::ERegisteringNonDependentStaticResource);
   342 				Panic(DPowerResourceController::ERegisteringNonDependentStaticResource);
   306 			//Upgrade latency state change from instantaneous to long latency 
   343 			//Upgrade latency state change from instantaneous to long latency 
   307 			if(!pRD->LatencySet()) 
   344 			if(!pRD->LatencySet()) 
   308 				pRD->iFlags |= KLongLatencySet;
   345 				pRD->iFlags |= KLongLatencySet;
   309 			pRC->CheckForDependencyLoop(pRD, pRD->iResourceId, pRD->iResourceId);
   346 			pRC->CheckForDependencyLoop(pRD, pRD->iResourceId, pRD->iResourceId);
   310 			}
   347 			}
   311 #ifdef PRM_INSTRUMENTATION_MACRO
   348 #ifdef PRM_INSTRUMENTATION_MACRO
   312 		for(count = 0; count < pRC->iStaticResDependencyCount; count++)
   349 		for(count = 0; count < (TUint)pRC->iStaticResDependencyArray.Count(); count++)
   313 			{
   350 			{
   314 			pR = pRC->iStaticResDependencyArray[count];
   351 			pR = pRC->iStaticResDependencyArray[count];
   315 			pR->GetInfo((TDes8*)resInfo.Ptr());
   352 			pR->GetInfo((TDes8*)resInfo.Ptr());
   316 			pResInfo = (TPowerResourceInfoV01*)resInfo.Ptr();
   353 			pResInfo = (TPowerResourceInfoV01*)resInfo.Ptr();
   317 			PRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY_TRACE
   354 			PRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY_TRACE