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; |
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 |
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 |