kernel/eka/drivers/resourceman/rescontrol_export.cpp
branchRCL_3
changeset 257 3e88ff8f41d5
parent 256 c1f20ce4abcf
equal deleted inserted replaced
256:c1f20ce4abcf 257:3e88ff8f41d5
    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 > (TUint)pRC->iStaticResourceArray.Count()) || (!pRC->iStaticResourceArray[aResId-1]))
    69 	if((!aResId) || (aResId > pRC->iStaticResourceArrayEntries) || (!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) > (TUint)pRC->iStaticResDependencyArray.Count())) 
    76 	if(!aResId || ((aResId & KIdMaskResourceWithDependencies) && ((aResId & ID_INDEX_BIT_MASK) > pRC->iStaticResDependencyCount)) 
    77 				|| (!(aResId & KIdMaskResourceWithDependencies) && ((aResId > (TUint)pRC->iStaticResourceArray.Count())
    77 				|| (!(aResId & KIdMaskResourceWithDependencies) && ((aResId > pRC->iStaticResourceArrayEntries)
    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((TUint)pRC->iStaticResourceArray.Count() > aResId - 1)
    93     if(pRC->iStaticResourceArray) 
    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*).
       
   113 	@Param aResCount             Number of static resources to register with RC. This equals the size of the passed array.
   111 	@Param aResCount             Number of static resources to register with RC. This equals the size of the passed array.
   114 	@return KErrNone, if operation is success
   112 	@return KErrNone, if operation is success
   115 	        KErrAccessDenied if clientId could not be found in the current list of registered clients or if this
   113 	        KErrAccessDenied if clientId could not be found in the current list of registered clients or if this
   116 			                 client was registered as thread relative and was not called from the same thread.
   114 			                 client was registered as thread relative and was not called from the same thread.
   117 			KErrNotSupported if called after resource controller is fully initialised or if called from user side proxy
   115 			KErrNotSupported if called after resource controller is fully initialised or if called from user side proxy
   127 	if(!pRC)
   125 	if(!pRC)
   128 		return KErrNotFound;
   126 		return KErrNotFound;
   129 
   127 
   130 	if(!aStaticResourceArray || (aResCount == 0))
   128 	if(!aStaticResourceArray || (aResCount == 0))
   131 		return KErrArgument;
   129 		return KErrArgument;
   132 	CHECK_CONTEXT(thread);
   130     CHECK_CONTEXT(thread)
   133 	//Accept the registration of static resource only if issued before controller is fully initialised.
   131 	//Accept the registration of static resource only if issued before controller is fully initialised.
   134 	if(pRC->iInitialised == EResConStartupCompleted)
   132 	if(pRC->iInitialised == EResConStartupCompleted)
   135 		{
   133 		{
   136 		return KErrNotSupported;
   134 		return KErrNotSupported;
   137 		}
   135 		}
   139 	if(aClientId & USER_SIDE_CLIENT_BIT_MASK)
   137 	if(aClientId & USER_SIDE_CLIENT_BIT_MASK)
   140 		{
   138 		{
   141 		return KErrNotSupported;
   139 		return KErrNotSupported;
   142 		}
   140 		}
   143 #ifdef PRM_ENABLE_EXTENDED_VERSION
   141 #ifdef PRM_ENABLE_EXTENDED_VERSION
   144 	// if aResCount equals to 1 aStaticResourceArray contains not an array, but simply a pointer to the resource.
       
   145 	if(aResCount == 1)
   142 	if(aResCount == 1)
   146 		{
   143 		{
   147 		if(((DStaticPowerResource*)aStaticResourceArray)->iResourceId & (KIdMaskResourceWithDependencies | KIdMaskDynamic))
   144 		if((((DStaticPowerResource*)aStaticResourceArray)->iResourceId & KIdMaskResourceWithDependencies) ||
       
   145 										(((DStaticPowerResource*)aStaticResourceArray)->iResourceId & KIdMaskDynamic))
   148 			{
   146 			{
   149 			return KErrNotSupported;
   147 			return KErrNotSupported;
   150 			}
   148 			}
   151 		}
   149 		}
   152 	else
   150 	else
   153 		{
   151 		{
   154 		for(TUint rescount = 0; rescount < aResCount; rescount++)
   152 		for(TUint rescount = 0; rescount < aResCount; rescount++)
   155 			{
   153 			{
   156 			if(aStaticResourceArray[rescount] &&
   154 			if(aStaticResourceArray[rescount] && ((aStaticResourceArray[rescount]->iResourceId & KIdMaskResourceWithDependencies) || 
   157 			  (aStaticResourceArray[rescount]->iResourceId & (KIdMaskResourceWithDependencies | KIdMaskDynamic)))
   155 				                          (aStaticResourceArray[rescount]->iResourceId & KIdMaskDynamic)))
   158 				{
   156 				{
   159 				return KErrNotSupported;
   157 				return KErrNotSupported;
   160 				}
   158 				}
   161 			}
   159 			}
   162 		}
   160 		}
   163 #endif
   161 #endif
   164 	SPowerResourceClient* pC = pRC->iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];
   162 	SPowerResourceClient* pC = pRC->iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];								
   165 	if(!pC)
   163 	if(!pC)																										
   166 		{
   164 		{																										
   167 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found"));
   165 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found"));											
   168 		return KErrAccessDenied;
   166 		return KErrAccessDenied;																		
   169 		}
   167 		}																										
   170 	if(pC->iClientId != aClientId)
   168 	if(pC->iClientId != aClientId)				
   171 		{
   169 		{																										
   172 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID instance count does not match"));
   170 		__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID instance count does not match"));						
   173 		return KErrAccessDenied;
   171 		return KErrAccessDenied;																		
   174 		}
   172 		}																										
   175 	if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK)
   173 	if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK)															
   176 		{
   174 		{																										
   177 		if(pC->iThreadId != thread.iId)
   175 		if(pC->iThreadId != thread.iId)																				
   178 			{
   176 			{																									
   179 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client not called from thread context(Thread Relative)"));
   177 			__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client not called from thread context(Thread Relative)"));	
   180 			return KErrAccessDenied;
   178 			return KErrAccessDenied;																	
   181 			}
   179 			}																									
   182 		}
   180 		}
   183 
   181  
   184     TInt r = KErrNone;
   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 		}
   185 	if(aResCount == 1)
   188 	if(aResCount == 1)
   186 		{
   189 		{
   187 		// if aResCount equals to one, threat the pointer as a pointer to resource
   190 		pRC->iStaticResourceArray[pRC->iStaticResourceArrayEntries++] = (DStaticPowerResource*)aStaticResourceArray;
   188 		r = pRC->iStaticResourceArray.Append((DStaticPowerResource*)aStaticResourceArray);
   191 		if((DStaticPowerResource*)aStaticResourceArray)
   189 		// increment count of valid resources
       
   190 		if(r == KErrNone && aStaticResourceArray)
       
   191 			pRC->iStaticResourceCount++;
   192 			pRC->iStaticResourceCount++;
   192 		}
   193 		}
   193 	else
   194 	else
   194 		{
   195 		{
   195 		for(TUint count = 0; count < aResCount; count++)
   196 		for(TUint count = 0; count < aResCount; count++)
   196 			{
   197 			{
   197 			r = pRC->iStaticResourceArray.Append(aStaticResourceArray[count]);
   198 			pRC->iStaticResourceArray[pRC->iStaticResourceArrayEntries++] = 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
       
   204 			if(aStaticResourceArray[count])
   199 			if(aStaticResourceArray[count])
   205 				pRC->iStaticResourceCount++;
   200 				pRC->iStaticResourceCount++;
   206 			}
   201 			}
   207 		}
   202 		}
   208 
   203     return KErrNone;
   209 	return r;
       
   210 	}
   204 	}
   211 
   205 
   212 /**
   206 /**
   213 	@publishedPartner
   207 	@publishedPartner
   214 	@prototype 9.5
   208 	@prototype 9.5
   233 	@publishedPartner
   227 	@publishedPartner
   234 	@prototype 9.5
   228 	@prototype 9.5
   235 	This function initialises the controller. 
   229 	This function initialises the controller. 
   236 	@return KErrNone, if operation is success or one of the system wide errors.
   230 	@return KErrNone, if operation is success or one of the system wide errors.
   237 	*/
   231 	*/
   238 RPointerArray <DStaticPowerResource> *StaticResourceArrayPtr;
       
   239 #ifdef PRM_ENABLE_EXTENDED_VERSION
       
   240 RPointerArray <DStaticPowerResourceD> *StaticResourceDependencyArrayPtr;
       
   241 #endif
       
   242 EXPORT_C TInt DPowerResourceController::InitController()
   232 EXPORT_C TInt DPowerResourceController::InitController()
   243 	{
   233 	{
   244     __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::InitController()"));
   234     __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::InitController()"));
   245 	DPowerResourceController* pRC = TInterface::GetPowerResourceController();
   235 	DPowerResourceController* pRC = TInterface::GetPowerResourceController();
   246 	if(!pRC)
   236 	if(!pRC)
   260 	//Create the message queue for dependency resource processing.
   250 	//Create the message queue for dependency resource processing.
   261 	pRC->iMsgQDependency = new TMessageQue(DPowerResourceController::MsgQDependencyFunc, pRC, NULL, 1);
   251 	pRC->iMsgQDependency = new TMessageQue(DPowerResourceController::MsgQDependencyFunc, pRC, NULL, 1);
   262 	if(!pRC->iMsgQDependency)
   252 	if(!pRC->iMsgQDependency)
   263 		return KErrNoMemory;
   253 		return KErrNoMemory;
   264 #endif
   254 #endif
   265 	// This method can be called in two situations - before the constructor of DPowerResourceController was called 
   255 	// Call PSL to create all static resources and populate the iStaticResourceArray with pointers to resources and
   266 	// for the second time (placement new in the extension psl entry macro) e.g. as a result of the call to InitResources() 
   256 	// update static resource count
   267 	// from the variant::Init3() method) or after that.
   257     r=pRC->DoRegisterStaticResources(pRC->iStaticResourceArray, pRC->iStaticResourceArrayEntries);
   268 
   258     if(r!=KErrNone)
   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)
       
   283 		return r;
   259 		return r;
   284 
   260 	//Get the actual number of static resource registered count
   285 	// make a copy (see above comment)
   261 	for(TInt resCnt = 0; resCnt < pRC->iStaticResourceArrayEntries; resCnt++)
   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++)
       
   290 		{
   262 		{
   291 		if(pRC->iStaticResourceArray[resCnt])
   263 		if(pRC->iStaticResourceArray[resCnt])
   292 			pRC->iStaticResourceCount++;
   264 			pRC->iStaticResourceCount++;
   293 		}
   265 		}
   294 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("Actual number of static resource registered = %d\n", pRC->iStaticResourceCount));
   266 	__KTRACE_OPT(KRESMANAGER, Kern::Printf("Actual number of static resource registered = %d\n", pRC->iStaticResourceCount));
   295 #ifdef PRM_INSTRUMENTATION_MACRO
   267 #ifdef PRM_INSTRUMENTATION_MACRO
   296 	// Btrace output of resource information of each resource.
   268 	// Btrace output of resource information of each resource.
   297 	DStaticPowerResource* pR = NULL;
   269 	DStaticPowerResource* pR = NULL;
   298 	TPowerResourceInfoBuf01 resInfo;
   270 	TPowerResourceInfoBuf01 resInfo;
   299 	TPowerResourceInfoV01 *pResInfo;
   271 	TPowerResourceInfoV01 *pResInfo;
   300 	for(TInt resCount = 0; resCount < pRC->iStaticResourceArray.Count(); resCount++)
   272 	for(TInt resCount = 0; resCount < pRC->iStaticResourceArrayEntries; resCount++)
   301 		{
   273 		{
   302 		pR = pRC->iStaticResourceArray[resCount];
   274 		pR = pRC->iStaticResourceArray[resCount];
   303 		if(!pR)
   275 		if(!pR)
   304 			continue;
   276 			continue;
   305 		pR->GetInfo((TDes8*)resInfo.Ptr());
   277 		pR->GetInfo((TDes8*)resInfo.Ptr());
   307 		PRM_REGISTER_RESOURCE_TRACE
   279 		PRM_REGISTER_RESOURCE_TRACE
   308 		}
   280 		}
   309 #endif
   281 #endif
   310 
   282 
   311 #ifdef PRM_ENABLE_EXTENDED_VERSION
   283 #ifdef PRM_ENABLE_EXTENDED_VERSION
   312 	StaticResourceDependencyArrayPtr = new RPointerArray <DStaticPowerResourceD>;
   284 	//Call PSL to register static resources with dependency if any exists
   313 	if(!StaticResourceDependencyArrayPtr)
   285 	r = pRC->DoRegisterStaticResourcesDependency(pRC->iStaticResDependencyArray, pRC->iStaticResDependencyCount);
   314 		return KErrNoMemory;
       
   315 
       
   316 	// Call PSL to register static resources with dependency if any exists
       
   317 	r = pRC->DoRegisterStaticResourcesDependency(pRC->iStaticResDependencyArray);
       
   318 
       
   319 	if(r != KErrNone)
   286 	if(r != KErrNone)
   320 		return r;
   287 		return r;
   321 
   288 	if(pRC->iStaticResDependencyCount)
   322 	// make a copy (see above comments for StaticResourceArrayPtr)
       
   323 	*StaticResourceDependencyArrayPtr = pRC->iStaticResDependencyArray;
       
   324 
       
   325 	if(pRC->iStaticResDependencyArray.Count())
       
   326 		{
   289 		{
   327 		DStaticPowerResourceD* pRD = NULL;
   290 		DStaticPowerResourceD* pRD = NULL;
   328 		TUint count;
   291 		TUint count;
   329 		//Assign resource index in resource id
   292 		//Assign resource index in resource id
   330 		for(count = 0; count < (TUint)pRC->iStaticResDependencyArray.Count(); count++)
   293 		for(count = 0; count < pRC->iStaticResDependencyCount; count++)
   331 			{
   294 			{
   332 			pRD = pRC->iStaticResDependencyArray[count];
   295 			pRD = pRC->iStaticResDependencyArray[count];
   333 			if(!pRD)
   296 			if(!pRD)
   334 				Panic(DPowerResourceController::ERegisteringDependentStaticResourceWithHoles);
   297 				Panic(DPowerResourceController::ERegisteringDependentStaticResourceWithHoles);
   335 			pRD->iResourceId |= ((count + 1) & ID_INDEX_BIT_MASK);
   298 			pRD->iResourceId |= ((count + 1) & ID_INDEX_BIT_MASK);
   336 			}
   299 			}
   337 		//Check for dependency closed loops
   300 		//Check for dependency closed loops
   338 		for(count = 0; count < (TUint)pRC->iStaticResDependencyArray.Count(); count++)
   301 		for(count = 0; count < pRC->iStaticResDependencyCount; count++)
   339 			{
   302 			{
   340 			pRD = pRC->iStaticResDependencyArray[count];
   303 			pRD = pRC->iStaticResDependencyArray[count];
   341 			if(!(pRD->iResourceId & KIdMaskStaticWithDependencies))
   304 			if(!(pRD->iResourceId & KIdMaskStaticWithDependencies))
   342 				Panic(DPowerResourceController::ERegisteringNonDependentStaticResource);
   305 				Panic(DPowerResourceController::ERegisteringNonDependentStaticResource);
   343 			//Upgrade latency state change from instantaneous to long latency 
   306 			//Upgrade latency state change from instantaneous to long latency 
   344 			if(!pRD->LatencySet()) 
   307 			if(!pRD->LatencySet()) 
   345 				pRD->iFlags |= KLongLatencySet;
   308 				pRD->iFlags |= KLongLatencySet;
   346 			pRC->CheckForDependencyLoop(pRD, pRD->iResourceId, pRD->iResourceId);
   309 			pRC->CheckForDependencyLoop(pRD, pRD->iResourceId, pRD->iResourceId);
   347 			}
   310 			}
   348 #ifdef PRM_INSTRUMENTATION_MACRO
   311 #ifdef PRM_INSTRUMENTATION_MACRO
   349 		for(count = 0; count < (TUint)pRC->iStaticResDependencyArray.Count(); count++)
   312 		for(count = 0; count < pRC->iStaticResDependencyCount; count++)
   350 			{
   313 			{
   351 			pR = pRC->iStaticResDependencyArray[count];
   314 			pR = pRC->iStaticResDependencyArray[count];
   352 			pR->GetInfo((TDes8*)resInfo.Ptr());
   315 			pR->GetInfo((TDes8*)resInfo.Ptr());
   353 			pResInfo = (TPowerResourceInfoV01*)resInfo.Ptr();
   316 			pResInfo = (TPowerResourceInfoV01*)resInfo.Ptr();
   354 			PRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY_TRACE
   317 			PRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY_TRACE