author | Mark Wilcox <markw@symbian.org> |
Tue, 25 May 2010 13:20:47 +0100 | |
changeset 116 | 57eea1054f46 |
parent 31 | 56f325a607ea |
child 244 | a77889bee936 |
child 256 | c1f20ce4abcf |
permissions | -rw-r--r-- |
0 | 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) \ |
|
31
56f325a607ea
Revision: 200951
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
229 |
TDfc* resourceInitDfc = NULL; \ |
0 | 230 |
static void ResourceInit(TAny* aController) \ |
231 |
{ \ |
|
232 |
TInt aReason = NKern::EThread; \ |
|
233 |
PRM_BOOTING_TRACE \ |
|
234 |
((DPowerResourceController*)aController)->InitResources(); \ |
|
31
56f325a607ea
Revision: 200951
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
235 |
delete resourceInitDfc; \ |
0 | 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; \ |
|
31
56f325a607ea
Revision: 200951
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
264 |
resourceInitDfc = new TDfc(&ResourceInit,(TAny*)&TheController,Kern::SvMsgQue(),KMaxDfcPriority-1); \ |
0 | 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); |
|
31
56f325a607ea
Revision: 200951
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
465 |
/**@internalComponent*/ |
56f325a607ea
Revision: 200951
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
466 |
TInt HandleResourceChange(TPowerRequest &aRequest, TPropagation aProp, TUint aOriginatorId, |
56f325a607ea
Revision: 200951
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
467 |
const TDesC8& aOriginatorName, DStaticPowerResourceD* aResource); |
0 | 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; |
|
31
56f325a607ea
Revision: 200951
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
540 |
#ifdef RESOURCE_MANAGER_SIMULATED_PSL |
56f325a607ea
Revision: 200951
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
541 |
RPointerArray<SPowerResourceClient> iCleanList; |
56f325a607ea
Revision: 200951
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
542 |
#endif |
0 | 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 |