|
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\include\drivers\resourcecontrol.h |
|
15 // |
|
16 // WARNING: This file contains some APIs which are internal and are subject |
|
17 // to change without notice. Such APIs should therefore not be used |
|
18 // outside the Kernel and Hardware Services package. |
|
19 // |
|
20 |
|
21 #ifndef __RESOURCECONTROL_H__ |
|
22 #define __RESOURCECONTROL_H__ |
|
23 #include <nklib.h> |
|
24 #include <kernel/kernel.h> |
|
25 #include <kernel/kern_priv.h> |
|
26 #include <e32ver.h> |
|
27 #define PRM_CONTROLLER |
|
28 #ifndef PRM_ENABLE_EXTENDED_VERSION |
|
29 #include <drivers/resource.h> |
|
30 #else |
|
31 #include <drivers/resource_extend.h> |
|
32 #endif |
|
33 #include <drivers/resourceman.h> |
|
34 |
|
35 /** #defines for client bit masks */ |
|
36 #define ID_INDEX_BIT_MASK 0x3FFF /* bit 0 -13 */ |
|
37 #define USER_SIDE_CLIENT_BIT_MASK 0x4000 //Bit 14 |
|
38 #define CLIENT_THREAD_RELATIVE_BIT_MASK 0x80000000 //Bit 31 |
|
39 #define INSTANCE_COUNT_BIT_MASK 0x1FFF //13 Bits |
|
40 #define INSTANCE_COUNT_POS 18 |
|
41 #define CLIENT_POWER_CONTROLLER_BIT_MASK 0x8000 //Bit 15 |
|
42 /** Bit to indicate valid post boot level in resource */ |
|
43 #define SET_VALID_POST_BOOT_LEVEL 0x8000 //Bit 15 |
|
44 |
|
45 #define RESOURCE_NOT_IN_OPERATION 0x1 |
|
46 #define PRM_DYNAMIC_RESOURCE_INITIAL_SIZE 2 |
|
47 |
|
48 #define PRM_STATIC_RESOURCE 0x0 |
|
49 #define PRM_STATIC_DEPENDENCY_RESOURCE 0x1 |
|
50 #define PRM_DYNAMIC_RESOURCE 0x2 |
|
51 #define PRM_DYNAMIC_DEPENDENCY_RESOURCE 0x3 |
|
52 #define RESOURCE_BIT_IN_ID_CHECK 16 |
|
53 |
|
54 |
|
55 static const TInt KMaxResourceNameLength=0x20; //Maximum allowable resource length is 32 characters. |
|
56 static const TInt KMaxClientNameLength=0x20; //Maximum allowable client length is 32 characters. |
|
57 |
|
58 |
|
59 _LIT8(KPowerController, "PowerController"); |
|
60 _LIT8(KDfcThread1Name, "DfcThread1"); |
|
61 _LIT8(KDfcThread0Name, "DfcThread0"); |
|
62 _LIT8(KNullThreadName, "Null"); |
|
63 _LIT8(KNoClient, "NoClient"); |
|
64 _LIT8(KParentResource, "ParentResource"); |
|
65 /** Macro to check the context of client calling RM API. |
|
66 Panics if it is called from ISR, IDFC, NULL thread or DFC thread1 */ |
|
67 #ifdef DEBUG_VERSION |
|
68 #define CHECK_CONTEXT(t) \ |
|
69 __ASSERT_ALWAYS(NKern::CurrentContext() == NKern::EThread, Panic(ECalledFromIsr)); \ |
|
70 const TDesC8* pDfc1 = &KDfcThread1Name; \ |
|
71 if(!pDfc1->Compare(*(TDesC8*)t.iName)) \ |
|
72 Panic(ECalledFromDfcThread1); \ |
|
73 const TDesC8* pNull = &KNullThreadName; \ |
|
74 if(!pNull->Compare(*(TDesC8*)t.iName)) \ |
|
75 Panic(ECalledFromNullThread); |
|
76 #else |
|
77 #define CHECK_CONTEXT(t) |
|
78 #endif |
|
79 |
|
80 /** Macro to unlock and return */ |
|
81 #define UNLOCK_RETURN(retval) \ |
|
82 { \ |
|
83 UnLock(); \ |
|
84 return(retval); \ |
|
85 } |
|
86 |
|
87 /** Macro to push the item into the specified list. Item are pushed to the head of the list. */ |
|
88 #define LIST_PUSH(list,item,link) \ |
|
89 { \ |
|
90 (item)->link = (list); \ |
|
91 (list) = (item); \ |
|
92 } |
|
93 |
|
94 /** Macro to pop the item from the specified list. Item are poped from the head of the list. */ |
|
95 #define LIST_POP(list,item,link) \ |
|
96 { \ |
|
97 (item) = (list); \ |
|
98 if ((item)) \ |
|
99 { \ |
|
100 (list) = (item)->link; \ |
|
101 (item)->link = NULL; \ |
|
102 } \ |
|
103 } |
|
104 |
|
105 /** Macro to remove the item from the list. */ |
|
106 #define LIST_REMOVE(list,item,link,className) \ |
|
107 if (list) \ |
|
108 { \ |
|
109 className* current = (list); \ |
|
110 if (current==(item)) \ |
|
111 { \ |
|
112 (list) = (item)->link; \ |
|
113 (item)->link = NULL; \ |
|
114 } \ |
|
115 else \ |
|
116 { \ |
|
117 className* next = current->link; \ |
|
118 while (next) \ |
|
119 { \ |
|
120 if ((item)==next) \ |
|
121 { \ |
|
122 current->link=next->link; \ |
|
123 next->link = NULL; \ |
|
124 break; \ |
|
125 } \ |
|
126 current = next; \ |
|
127 next = next->link; \ |
|
128 } \ |
|
129 } \ |
|
130 } |
|
131 |
|
132 |
|
133 /* Macro to add dynamic resource to appropriate containers. Used only in extended version */ |
|
134 #define ADD_TO_RESOURCE_CONTAINER(list, res, resId, resIdCount) \ |
|
135 { \ |
|
136 TUint16 growBy = (list).GrowBy(); \ |
|
137 if(!growBy) \ |
|
138 (list).Initialise((TUint16)PRM_DYNAMIC_RESOURCE_INITIAL_SIZE); \ |
|
139 if((list).Add(res, resId) == KErrNoMemory) \ |
|
140 { \ |
|
141 TInt r = (list).ReSize(growBy); \ |
|
142 if(r != KErrNone) \ |
|
143 return r; \ |
|
144 (list).Add(res, resId); \ |
|
145 } \ |
|
146 res->iResourceId |= resId; \ |
|
147 resId = res->iResourceId; \ |
|
148 resIdCount++; \ |
|
149 } |
|
150 |
|
151 /* Macro to get the resource from appropriate list. Used only in extended version */ |
|
152 #define GET_RESOURCE_FROM_LIST(resId, res) \ |
|
153 { \ |
|
154 switch((resId >> RESOURCE_BIT_IN_ID_CHECK) & 0x3) \ |
|
155 { \ |
|
156 case PRM_STATIC_RESOURCE: \ |
|
157 if(resId > iStaticResourceArrayEntries) \ |
|
158 UNLOCK_RETURN(KErrNotFound); \ |
|
159 res = iStaticResourceArray[resId - 1]; \ |
|
160 if(!res) \ |
|
161 UNLOCK_RETURN(KErrNotFound); \ |
|
162 break; \ |
|
163 case PRM_STATIC_DEPENDENCY_RESOURCE: \ |
|
164 if((TUint16)(resId & ID_INDEX_BIT_MASK) > iStaticResDependencyCount) \ |
|
165 UNLOCK_RETURN(KErrNotFound); \ |
|
166 res = iStaticResDependencyArray[(TUint16)(resId & ID_INDEX_BIT_MASK) - 1]; \ |
|
167 break; \ |
|
168 case PRM_DYNAMIC_RESOURCE: \ |
|
169 res = iDynamicResourceList[(TUint16)(resId & ID_INDEX_BIT_MASK)]; \ |
|
170 if(!res) \ |
|
171 UNLOCK_RETURN(KErrNotFound); \ |
|
172 break; \ |
|
173 case PRM_DYNAMIC_DEPENDENCY_RESOURCE: \ |
|
174 res = iDynamicResDependencyList[(TUint16)(resId & ID_INDEX_BIT_MASK)]; \ |
|
175 if(!res) \ |
|
176 UNLOCK_RETURN(KErrNotFound); \ |
|
177 break; \ |
|
178 default: \ |
|
179 UNLOCK_RETURN(KErrArgument); \ |
|
180 } \ |
|
181 } |
|
182 |
|
183 /**Macro to get the client from appropriate client list based on bit 14 of client ID. |
|
184 If the client is registered as thread relative, then check is made to make sure |
|
185 it is called from the same thread. */ |
|
186 #define VALIDATE_CLIENT(t) \ |
|
187 if(aClientId & USER_SIDE_CLIENT_BIT_MASK) \ |
|
188 pC = iUserSideClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)]; \ |
|
189 else \ |
|
190 pC = iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)]; \ |
|
191 if(!pC) \ |
|
192 { \ |
|
193 __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found")); \ |
|
194 UNLOCK_RETURN(KErrAccessDenied); \ |
|
195 } \ |
|
196 if(pC->iClientId != aClientId) \ |
|
197 { \ |
|
198 __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID does not match")); \ |
|
199 UNLOCK_RETURN(KErrAccessDenied); \ |
|
200 } \ |
|
201 if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK) \ |
|
202 { \ |
|
203 if(pC->iThreadId != t.iId) \ |
|
204 { \ |
|
205 __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client not called from thread context(Thread Relative)")); \ |
|
206 UNLOCK_RETURN(KErrAccessDenied); \ |
|
207 } \ |
|
208 } |
|
209 |
|
210 /** Macro to get the target client from appropriate client list based on bit 14 of client ID. */ |
|
211 #define GET_TARGET_CLIENT() \ |
|
212 if(aTargetClientId & USER_SIDE_CLIENT_BIT_MASK) \ |
|
213 pC = iUserSideClientList[(TUint16)(aTargetClientId & ID_INDEX_BIT_MASK)]; \ |
|
214 else \ |
|
215 pC = iClientList[(TUint16)(aTargetClientId & ID_INDEX_BIT_MASK)]; \ |
|
216 if(!pC) \ |
|
217 { \ |
|
218 __KTRACE_OPT(KRESMANAGER, Kern::Printf("Target Client ID not found")); \ |
|
219 UNLOCK_RETURN(KErrNotFound); \ |
|
220 } \ |
|
221 if(pC->iClientId != aTargetClientId) \ |
|
222 { \ |
|
223 __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID does not match")); \ |
|
224 UNLOCK_RETURN(KErrNotFound); \ |
|
225 } |
|
226 |
|
227 /* Macro definition for entry point of Power Resource Controller */ |
|
228 #define DECLARE_RESOURCE_MANAGER_EXTENSION(TheController) \ |
|
229 TDfc* resourceInitDfc = NULL; \ |
|
230 static void ResourceInit(TAny* aController) \ |
|
231 { \ |
|
232 TInt aReason = NKern::EThread; \ |
|
233 PRM_BOOTING_TRACE \ |
|
234 ((DPowerResourceController*)aController)->InitResources(); \ |
|
235 delete resourceInitDfc; \ |
|
236 return; \ |
|
237 } \ |
|
238 void CreateController(); \ |
|
239 GLDEF_C TInt KernelModuleEntry(TInt aReason) \ |
|
240 { \ |
|
241 if(aReason==KModuleEntryReasonVariantInit0) \ |
|
242 { \ |
|
243 __KTRACE_OPT(KBOOT, Kern::Printf("Create Resource Controller")); \ |
|
244 CreateController(); \ |
|
245 return KErrNone; \ |
|
246 } \ |
|
247 if (aReason==KModuleEntryReasonExtensionInit0) \ |
|
248 return KExtensionMaximumPriority; \ |
|
249 if (aReason!=KModuleEntryReasonExtensionInit1) \ |
|
250 return KErrArgument; \ |
|
251 PRM_BOOTING_TRACE \ |
|
252 __KTRACE_OPT(KBOOT, Kern::Printf("Initialise Resource Controller")); \ |
|
253 TInt r = KErrNone; \ |
|
254 r = DPowerResourceController::InitController(); \ |
|
255 if(r != KErrNone) \ |
|
256 return r; \ |
|
257 __KTRACE_OPT(KBOOT, Kern::Printf("Create PDD and queue ResourceInit DFC")); \ |
|
258 DResConPddFactory* device = new DResConPddFactory; \ |
|
259 if(!device) \ |
|
260 return KErrNoMemory; \ |
|
261 r = Kern::InstallPhysicalDevice(device); \ |
|
262 if(r != KErrNone) \ |
|
263 return r; \ |
|
264 resourceInitDfc = new TDfc(&ResourceInit,(TAny*)&TheController,Kern::SvMsgQue(),KMaxDfcPriority-1); \ |
|
265 if(!resourceInitDfc) \ |
|
266 return KErrNoMemory; \ |
|
267 resourceInitDfc->Enque(); \ |
|
268 return KErrNone; \ |
|
269 } \ |
|
270 GLDEF_C void CreateController() |
|
271 |
|
272 struct SPowerResourceClient; |
|
273 struct TPowerRequest; |
|
274 struct SPowerRequest; |
|
275 struct SPowerResourceClientLevel; |
|
276 struct SIdleResourceInfo; |
|
277 class DPowerResourceController; |
|
278 |
|
279 /** |
|
280 @internalComponent |
|
281 @prototype 9.5 |
|
282 Interface class for Resource Manager |
|
283 Functions from PowerResourceManager calls corresponding functions of this |
|
284 class which in turn calls Powercontroller functions. |
|
285 */ |
|
286 class TInterface |
|
287 { |
|
288 public: |
|
289 static TInt RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType=EOwnerProcess); |
|
290 static TInt DeRegisterClient(TUint aClientId); |
|
291 static TInt GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName); |
|
292 static TInt GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId); |
|
293 static TInt GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId); |
|
294 static TInt GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo); |
|
295 static TInt GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources); |
|
296 static TInt GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources, TAny* aInfo); |
|
297 static TInt GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients); |
|
298 static TInt GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients, TAny* aInfo); |
|
299 static TInt AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm); |
|
300 static TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL); |
|
301 static TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId); |
|
302 static TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb); |
|
303 static TInt CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb); |
|
304 static TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN); |
|
305 static TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, TInt aThreshold, TBool aDirection); |
|
306 static TInt CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN); |
|
307 static TInt DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId); |
|
308 static DPowerResourceController* GetPowerResourceController(void); |
|
309 static TInt ControlIO(TUint aClientId, TUint aFunction, TAny* aParam1, TAny* aParam2, TAny* aParam3); |
|
310 }; |
|
311 |
|
312 /** |
|
313 @internalComponent |
|
314 @prototype 9.5 |
|
315 Container class to create containers of pointers to clients. |
|
316 */ |
|
317 template <class T> |
|
318 class DResourceCon : public DBase |
|
319 { |
|
320 public: |
|
321 inline TInt Initialise(TUint16 aInitialSize); |
|
322 inline void Delete(); |
|
323 inline T* operator[](TUint16 aIndex); |
|
324 inline TInt Remove(T* aObj, TUint16 aIndex); |
|
325 inline TInt Add(T* aObj, TUint &aId); |
|
326 inline TInt Find(T*& anEntry, TDesC& aName); |
|
327 inline TInt ReSize(TUint16 aGrowBy); |
|
328 inline TUint16 Count() {return iCount;} |
|
329 inline TUint16 Allocd() {return iAllocated;} |
|
330 inline TUint16 GrowBy() {return iGrowBy;} |
|
331 private: |
|
332 TUint16 iGrowBy; //Size to grow the size of the array. |
|
333 TUint16 iAllocated; //Size of the array |
|
334 TUint16 iCount; //Valid entries in the array |
|
335 TUint16 iInstanceCount; //FreeCounter incremented whenever an entry is added. |
|
336 TUint16 iFreeLoc; //Cached free location in the array |
|
337 TUint16 iSpare; |
|
338 T** iArray; |
|
339 }; |
|
340 |
|
341 /** |
|
342 @internalComponent |
|
343 @prototype 9.5 |
|
344 Factory class for physical device |
|
345 */ |
|
346 NONSHARABLE_CLASS(DResConPddFactory) : public DPhysicalDevice |
|
347 { |
|
348 public: |
|
349 /** |
|
350 Structure for holding PDD capabilities information |
|
351 */ |
|
352 class TCaps |
|
353 { |
|
354 public: |
|
355 TVersion iVersion; |
|
356 }; |
|
357 public: |
|
358 DResConPddFactory(); |
|
359 virtual TInt Install(); |
|
360 virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); |
|
361 virtual TInt Validate(TInt aUint, const TDesC8* anInfo, const TVersion& aVer); |
|
362 virtual void GetCaps(TDes8& aDes) const; |
|
363 inline static TVersion VersionRequired(); |
|
364 }; |
|
365 |
|
366 /** |
|
367 @internalComponent |
|
368 @prototype 9.5 |
|
369 Interface class for user side resource controller proxy. For each user side channel opened an object of |
|
370 this class is created in heap and pointer to resource controller is stored in iController member variable. |
|
371 User side resource controller proxy calls the resource controller API's by deferencing the pointer. |
|
372 This class is required as when the channel is closed the device driver framework tries to delete |
|
373 the object stored in ipdd, because of which it is not possible to pass the controller pointer directly. |
|
374 */ |
|
375 class DUserSideProxyInterface: public DBase |
|
376 { |
|
377 public: |
|
378 DPowerResourceController *iController; |
|
379 }; |
|
380 |
|
381 |
|
382 /** |
|
383 @publishedPartner |
|
384 @prototype 9.5 |
|
385 resource manager implementation base class |
|
386 */ |
|
387 NONSHARABLE_CLASS (DPowerResourceController) : public DBase |
|
388 { |
|
389 public: |
|
390 TInt RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType=EOwnerProcess); |
|
391 TInt DeRegisterClient(TUint aClientId); |
|
392 virtual TInt GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName); |
|
393 virtual TInt GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId); |
|
394 virtual TInt GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId); |
|
395 virtual TInt GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo); |
|
396 virtual TInt GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources); |
|
397 virtual TInt GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources, TAny* aInfo); |
|
398 virtual TInt GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients); |
|
399 virtual TInt GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients, TAny* aInfo); |
|
400 virtual TInt AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm); |
|
401 virtual TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL); |
|
402 virtual TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId); |
|
403 virtual TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb); |
|
404 virtual TInt CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb); |
|
405 virtual TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN); |
|
406 virtual TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, TInt aThreshold, TBool aDirection); |
|
407 virtual TInt CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN); |
|
408 virtual TInt DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId); |
|
409 public: |
|
410 enum TResConPanic |
|
411 { |
|
412 ECalledFromDfcThread0 = 0, |
|
413 ECalledFromIsr = 1, |
|
414 ECalledFromNullThread = 2, |
|
415 ECalledFromDfcThread1 = 3, |
|
416 EClientHasPendingAsyncRequest = 4, |
|
417 EClientHasNotificationObject = 5, |
|
418 EControllerAlreadyExists = 6, |
|
419 ECustomFunctionNotSet = 7, |
|
420 EClientIdNotInClientLevelList = 8, |
|
421 ENoMemToCreatePowerControllerClient = 9, |
|
422 EResourceNameExceedsLimit = 10, |
|
423 EObjectNotFoundInList = 11 |
|
424 }; |
|
425 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
426 enum TExtendedResConPanic |
|
427 { |
|
428 EClosedLoopDependencies = EObjectNotFoundInList + 2, //13 |
|
429 ERegisteringNonDependentStaticResource = 14, |
|
430 EClientHasDynamicResourceRegistered = 15, |
|
431 EDynamicResourceStillRegistered = 16, |
|
432 ERegisteringDependentStaticResourceWithHoles = 17 |
|
433 }; |
|
434 #endif |
|
435 enum TResConStartSequence |
|
436 { |
|
437 EResConCreated, |
|
438 EResConInitialised, |
|
439 EResConStartupCompleted |
|
440 }; |
|
441 //early initialization |
|
442 IMPORT_C static TInt InitController(); |
|
443 TInt InitResources(); |
|
444 //request a post-boot level for the resource |
|
445 IMPORT_C static TInt PostBootLevel(TUint aResId, TInt aLevel); |
|
446 //request registration of static resource |
|
447 IMPORT_C static TInt RegisterStaticResource(TUint aClientId, DStaticPowerResource* pR); |
|
448 //request registration of group/array of static resources |
|
449 IMPORT_C static TInt RegisterArrayOfStaticResources(TUint aClientId, DStaticPowerResource**& aStaticResourceArray, TUint aResCount); |
|
450 //registration for proxy client |
|
451 virtual TInt RegisterProxyClient(TUint& aProxyId, const TDesC8& aName); |
|
452 virtual TInt DeregisterProxyClient(TUint aClientId); |
|
453 //register list of resources whose state matter to Idle |
|
454 virtual TInt RegisterResourcesForIdle(TInt aPowerControllerId, TUint aNumResources, TPtr* aBuf); |
|
455 static void Panic(TUint8 aPanic); |
|
456 virtual TInt GetInterface(TUint aClientId, TUint aInterfaceId, TAny* aParam1, TAny* aParam2, TAny* aParam3); |
|
457 virtual ~DPowerResourceController(); |
|
458 /**@internalComponent*/ |
|
459 void CompleteNotifications(TInt aClientId, DStaticPowerResource* aResource, TInt aState, TInt aReturnCode, TInt aLevelOwnerId, TBool aLock = ETrue); |
|
460 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
461 /**@internalComponent*/ |
|
462 TInt ReserveClientLevelPoolCount(TUint16 aCount); |
|
463 /**@internalComponent*/ |
|
464 void RemoveClientLevelFromPool(SPowerResourceClientLevel *&aLevelPtr); |
|
465 /**@internalComponent*/ |
|
466 TInt HandleResourceChange(TPowerRequest &aRequest, TPropagation aProp, TUint aOriginatorId, |
|
467 const TDesC8& aOriginatorName, DStaticPowerResourceD* aResource); |
|
468 #endif |
|
469 protected: |
|
470 //generic layer function to be called by the PSL |
|
471 DPowerResourceController(); |
|
472 void SetDfcQ(TDfcQue* aDfcQ); |
|
473 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
474 void SetDfcQDependency(TDfcQue* aDfcQ); |
|
475 #endif |
|
476 TInt InitPools(TUint16 aKClients, TUint16 aUClients, TUint16 aNClientLevels, TUint16 aNRequests); |
|
477 /* Lock the resource controller mutex */ |
|
478 inline void Lock() { NKern::ThreadEnterCS(); |
|
479 Kern::MutexWait(*iResourceMutex); } |
|
480 inline void UnLock() { Kern::MutexSignal(*iResourceMutex); |
|
481 NKern::ThreadLeaveCS();} |
|
482 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
483 //Default implementation, PSL re-implements these if features supported |
|
484 virtual TInt DoRegisterStaticResourcesDependency(DStaticPowerResourceD**& aStaticResourceDArray, TUint16& aStaticResourceDCount); |
|
485 #endif |
|
486 private: |
|
487 // pure virtual implemented by PSL - to be called by PIL |
|
488 virtual TInt DoInitController()=0; |
|
489 virtual TInt DoRegisterStaticResources(DStaticPowerResource**& aStaticResourceArray, TUint16& aStaticResourceCount)=0; |
|
490 /**@internalComponent*/ |
|
491 TInt CheckLevelAndAddClient(SPowerResourceClient* pC, TPowerRequest* Request); |
|
492 static void MsgQFunc(TAny* aPtr); |
|
493 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
494 static void MsgQDependencyFunc(TAny* aPtr); |
|
495 #endif |
|
496 |
|
497 /**@internalComponent*/ |
|
498 void ResourceStateChangeOfClientLevels(SPowerResourceClient* pC); |
|
499 /**@internalComponent*/ |
|
500 void HandleMsg(TPowerRequest& aRequest); |
|
501 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
502 /**@internalComponent*/ |
|
503 void HandleDependencyMsg(TPowerRequest& aRequest); |
|
504 #endif |
|
505 /**@internalComponent*/ |
|
506 void CompleteRequest(TPowerRequest& aRequest); |
|
507 /**@internalComponent*/ |
|
508 void MoveRequestToFreePool(TPowerRequest *aReq); |
|
509 /**@internalComponent*/ |
|
510 TInt HandleReservationOfObjects(TPowerRequest& aRequest); |
|
511 /**@internalComponent*/ |
|
512 TInt HandleClientRegistration(TPowerRequest& aRequest); |
|
513 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
514 TInt RegisterDynamicResource(SPowerResourceClient* aClientPtr, DDynamicPowerResource* aPDRes, TUint* aDynamicResourceId); |
|
515 TInt DeregisterDynamicResource(SPowerResourceClient* aClientPtr, TUint aDynamicResourceId, TInt* aPDefLevel); |
|
516 TInt RegisterResourceDependency(SPowerResourceClient* aClientPtr, SResourceDependencyInfo* aInfo1, SResourceDependencyInfo* aInfo2); |
|
517 /**@internalComponent*/ |
|
518 void CheckForDependencyLoop(DStaticPowerResourceD* pR, TUint aParentResId, TUint aTargetResId); |
|
519 TInt DeregisterResourceDependency(SPowerResourceClient* aClientPtr, TUint aResId1, TUint aResId2); |
|
520 /**@internalComponent*/ |
|
521 TInt HandleDependencyResourceStateChange(SPowerResourceClient* pC, TPowerRequest& aRequest); |
|
522 TInt GetNumDependentsForResource(TUint aResourceId, TUint* aNumResources); |
|
523 TInt GetDependentsIdForResource(TUint aResourceId, TAny* aInfo, TUint* aNumDepResources); |
|
524 TInt HandleResourceRegistration(TPowerRequest& aReq); |
|
525 #endif |
|
526 public: |
|
527 DMutex* iResourceMutex; |
|
528 protected: |
|
529 TDfcQue* iDfcQ; |
|
530 TMessageQue *iMsgQ; |
|
531 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
532 TDfcQue* iDfcQDependency; |
|
533 TMessageQue* iMsgQDependency; |
|
534 TBool iDfcQDependencyLock; |
|
535 #endif |
|
536 private: |
|
537 DStaticPowerResource** iStaticResourceArray; |
|
538 DResourceCon<SPowerResourceClient> iClientList; |
|
539 DResourceCon<SPowerResourceClient> iUserSideClientList; |
|
540 #ifdef RESOURCE_MANAGER_SIMULATED_PSL |
|
541 RPointerArray<SPowerResourceClient> iCleanList; |
|
542 #endif |
|
543 SPowerResourceClient* iClientPool; |
|
544 SPowerRequest* iRequestPool; |
|
545 SPowerResourceClientLevel* iClientLevelPool; |
|
546 TUint iPowerControllerId; //Stores the ID allocated to PowerController |
|
547 SIdleResourceInfo* iListForIdle; |
|
548 TUint iInitialised; |
|
549 TUint16 iClientCount; |
|
550 TUint16 iUserSideClientCount; |
|
551 TUint16 iClientLevelPoolCount; |
|
552 TUint16 iClientLevelPoolGrowBy; |
|
553 TUint16 iRequestPoolCount; |
|
554 TUint16 iRequestPoolGrowBy; |
|
555 TUint16 iStaticResourceArrayEntries; //Number of entries in the array including holes if any. |
|
556 TUint16 iStaticResourceCount; //Actual number of static resources registered (valid entries). |
|
557 TUint iReserved2; //Reserved for future use |
|
558 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
559 DResourceCon<DDynamicPowerResource> iDynamicResourceList; |
|
560 DResourceCon<DDynamicPowerResourceD> iDynamicResDependencyList; |
|
561 DStaticPowerResourceD** iStaticResDependencyArray; |
|
562 SPowerResourceClientLevel* iResourceLevelPool; |
|
563 TUint16 iResourceLevelPoolCount; |
|
564 TUint16 iStaticResDependencyCount; |
|
565 TUint16 iDynamicResourceCount; |
|
566 TUint8 iDynamicResDependencyCount; |
|
567 TUint8 iSpare2; |
|
568 TUint iReserved3; //Reserved for future use. |
|
569 #endif |
|
570 }; |
|
571 |
|
572 /** |
|
573 @publishedPartner |
|
574 @prototype 9.5 |
|
575 power level of client in a shared resource |
|
576 */ |
|
577 struct SPowerResourceClientLevel : public SDblQueLink |
|
578 { |
|
579 TUint iClientId; |
|
580 TUint iResourceId; |
|
581 TInt iLevel; |
|
582 SPowerResourceClientLevel* iNextInList; |
|
583 }; |
|
584 |
|
585 /** |
|
586 @internalComponent |
|
587 @prototype 9.5 |
|
588 respresent client in resource manager |
|
589 */ |
|
590 struct SPowerResourceClient |
|
591 { |
|
592 TUint iClientId; |
|
593 const TDesC8* iName; |
|
594 SPowerResourceClient* iNextInList; |
|
595 SPowerResourceClientLevel* iLevelList; |
|
596 DPowerResourceNotification* iNotificationList; |
|
597 TUint8 iReservedCl; |
|
598 TUint8 iReservedRm; |
|
599 TUint8 iPendingReqCount; |
|
600 TUint8 iUnderFlowRmCount; |
|
601 TUint8 iUnderFlowClCount; |
|
602 TUint8 iDynamicResCount; //Counter for dynamic resource registered by the client. Used only in extended version |
|
603 TUint8 iSpare1; |
|
604 TUint8 iSpare2; |
|
605 union |
|
606 { |
|
607 TUint iThreadId; |
|
608 TAny* iSpare3; |
|
609 }; |
|
610 }; |
|
611 |
|
612 /** |
|
613 @publishedPartner |
|
614 @prototype 9.5 |
|
615 represents a request inside the resource manager |
|
616 */ |
|
617 struct TPowerRequest : public TThreadMessage |
|
618 { |
|
619 /** requests can either be to get the resource value or to change the resource value*/ |
|
620 enum TReqType {EGet, EChange, ESetDefaultLevel, ERegisterKernelClient, ERegisterUsersideClient, EAllocReserve, |
|
621 ERegisterDynamicResource }; |
|
622 /** @return thread's own message and turn into a power request. Used for sync/instant calls*/ |
|
623 inline static TPowerRequest& Get() |
|
624 {return (TPowerRequest&)Kern::Message();} |
|
625 /** @return type of request get or set */ |
|
626 inline TReqType& ReqType() // one of TReqType |
|
627 {return *(TReqType*)&iValue;} |
|
628 /** @return resource id which is being requested*/ |
|
629 inline TUint& ResourceId() |
|
630 {return *(TUint*)&iArg[0];} |
|
631 /** @return id of client making request (only valid on change requests)*/ |
|
632 inline TInt& ClientId() |
|
633 {return *(TInt*)&iArg[1];} |
|
634 /** |
|
635 On resource state change operations the PIL sets this field with the required level before |
|
636 invoking the DoRequest(..) function; on return from DoRequest(..) function the PSL sets this field |
|
637 with the real state of the resource to be cached by the PIL.On resource state read operations PSL |
|
638 sets it with the level read. |
|
639 */ |
|
640 inline TInt& Level() |
|
641 {return *(TInt*)&iArg[2];} |
|
642 /** @return pointer the resource being requested */ |
|
643 inline DStaticPowerResource*& Resource() |
|
644 {return *(DStaticPowerResource**)&iArg[3];} |
|
645 /** @return pointer to resource callback structure, used for async requests */ |
|
646 inline TPowerResourceCb*& ResourceCb() |
|
647 {return *(TPowerResourceCb**)&iArg[4];} |
|
648 /** @return return code of resource's DoRequest function when request has been processed */ |
|
649 inline TInt& ReturnCode() |
|
650 {return *(TInt*)&iArg[5];} |
|
651 /** @return return ETrue if a change is required on a shared resource */ |
|
652 inline TBool& RequiresChange() |
|
653 {return *(TInt*)&iArg[6];} |
|
654 /** @return number of client level objects requested by a client to reserve */ |
|
655 inline TInt& ClientLevelCount() |
|
656 {return *(TInt*)&iArg[7];} |
|
657 /** @return number of request objects requested by a client to reserve */ |
|
658 inline TInt& RequestCount() |
|
659 {return *(TInt*)&iArg[8];} |
|
660 }; |
|
661 |
|
662 /** |
|
663 @internalComponent |
|
664 @prototype 9.5 |
|
665 */ |
|
666 struct SPowerRequest |
|
667 { |
|
668 TPowerRequest iRequest; |
|
669 SPowerRequest* iNext; |
|
670 }; |
|
671 |
|
672 /** |
|
673 @publishedPartner |
|
674 @prototype 9.5 |
|
675 Structure representing resource information used for Idle power management |
|
676 */ |
|
677 struct SIdleResourceInfo |
|
678 { |
|
679 TUint iResourceId; |
|
680 TInt iLevelOwnerId; //Owner of the resource. |
|
681 TInt iCurrentLevel; //Cached resource state |
|
682 TInt iReserved1; //Reserved for future use. |
|
683 TInt iReserved2; //Reserved for future use. |
|
684 TInt iReserved3; //Reserved for future use. |
|
685 }; |
|
686 |
|
687 #include <drivers/resourcecontrol.inl> |
|
688 |
|
689 #endif //__RESOURCECONTROL_H__ |
|
690 |
|
691 |