|
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 static void ResourceInit(TAny* aController) \ |
|
230 { \ |
|
231 TInt aReason = NKern::EThread; \ |
|
232 PRM_BOOTING_TRACE \ |
|
233 ((DPowerResourceController*)aController)->InitResources(); \ |
|
234 return; \ |
|
235 } \ |
|
236 void CreateController(); \ |
|
237 GLDEF_C TInt KernelModuleEntry(TInt aReason) \ |
|
238 { \ |
|
239 if(aReason==KModuleEntryReasonVariantInit0) \ |
|
240 { \ |
|
241 __KTRACE_OPT(KBOOT, Kern::Printf("Create Resource Controller")); \ |
|
242 CreateController(); \ |
|
243 return KErrNone; \ |
|
244 } \ |
|
245 if (aReason==KModuleEntryReasonExtensionInit0) \ |
|
246 return KExtensionMaximumPriority; \ |
|
247 if (aReason!=KModuleEntryReasonExtensionInit1) \ |
|
248 return KErrArgument; \ |
|
249 PRM_BOOTING_TRACE \ |
|
250 __KTRACE_OPT(KBOOT, Kern::Printf("Initialise Resource Controller")); \ |
|
251 TInt r = KErrNone; \ |
|
252 r = DPowerResourceController::InitController(); \ |
|
253 if(r != KErrNone) \ |
|
254 return r; \ |
|
255 __KTRACE_OPT(KBOOT, Kern::Printf("Create PDD and queue ResourceInit DFC")); \ |
|
256 DResConPddFactory* device = new DResConPddFactory; \ |
|
257 if(!device) \ |
|
258 return KErrNoMemory; \ |
|
259 r = Kern::InstallPhysicalDevice(device); \ |
|
260 if(r != KErrNone) \ |
|
261 return r; \ |
|
262 TDfc* resourceInitDfc = new TDfc(&ResourceInit,(TAny*)&TheController,Kern::SvMsgQue(),KMaxDfcPriority-1); \ |
|
263 if(!resourceInitDfc) \ |
|
264 return KErrNoMemory; \ |
|
265 resourceInitDfc->Enque(); \ |
|
266 return KErrNone; \ |
|
267 } \ |
|
268 GLDEF_C void CreateController() |
|
269 |
|
270 /* Macro defintion for handling dependency resource state change. This is used only in extended version */ |
|
271 #define HANDLE_CHANGE_PROPAGATION(TheController, resourceTypePointer, traceEnabled, originatorId, originatorName) \ |
|
272 switch(aProp) \ |
|
273 { \ |
|
274 case EChangeStart: \ |
|
275 { \ |
|
276 if(!pDR->iDependencyList) /*No dependents so change state of the resource*/ \ |
|
277 { \ |
|
278 aRequest.ReturnCode() = pDR->DoRequest(aRequest); \ |
|
279 if(aRequest.ReturnCode() == KErrNone) \ |
|
280 { \ |
|
281 iCachedLevel = aRequest.Level(); \ |
|
282 iLevelOwnerId = aRequest.ClientId(); \ |
|
283 if(iIdleListEntry) \ |
|
284 { \ |
|
285 iIdleListEntry->iCurrentLevel = aRequest.Level(); \ |
|
286 iIdleListEntry->iLevelOwnerId = aRequest.ClientId(); \ |
|
287 } \ |
|
288 TheController->CompleteNotifications(aRequest.ClientId(), pDR, \ |
|
289 aRequest.Level(), aRequest.ReturnCode(), aRequest.ClientId()); \ |
|
290 } \ |
|
291 break; \ |
|
292 } \ |
|
293 depRequest.ResourceId() = aRequest.ResourceId(); \ |
|
294 depRequest.ClientId() = aRequest.ResourceId(); \ |
|
295 depRequest.Level() = aRequest.Level(); \ |
|
296 depRequest.Resource() = pDR; \ |
|
297 result = pDR->HandleChangePropagation(depRequest, ECheckChangeAllowed, originatorId, originatorName); \ |
|
298 if(result != KErrNone) \ |
|
299 return result; \ |
|
300 /*Adjust resource client level*/ \ |
|
301 if(clientLevelCount) \ |
|
302 { \ |
|
303 result = TheController->ReserveClientLevelPoolCount(clientLevelCount); \ |
|
304 if(result != KErrNone) \ |
|
305 return result; \ |
|
306 } \ |
|
307 /*Resource change of dependents */ \ |
|
308 pDR->HandleChangePropagation(aRequest, ERequestStateChange, originatorId, originatorName); \ |
|
309 /*Notification to dependents */ \ |
|
310 pDR->HandleChangePropagation(aRequest, EIssueNotifications, originatorId, originatorName); \ |
|
311 break; \ |
|
312 } \ |
|
313 case ECheckChangeAllowed: \ |
|
314 { \ |
|
315 TChangePropagationStatus status; \ |
|
316 for(SNode* depNode = pDR->iDependencyList; depNode != NULL; depNode = depNode->iNext) \ |
|
317 { \ |
|
318 pDepRes = (resourceTypePointer)depNode->iResource; \ |
|
319 if((aRequest.ClientId() & KIdMaskResourceWithDependencies) && \ |
|
320 (pDepRes->iResourceId == (TUint)aRequest.ClientId())) \ |
|
321 continue; \ |
|
322 /*Resource need not change if it is already in that state, so continue with \ |
|
323 another dependent state.*/ \ |
|
324 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
325 status = ((DDynamicPowerResourceD*)pDepRes)->TranslateDependentState(aRequest.ResourceId(), \ |
|
326 aRequest.Level(), resState); \ |
|
327 else \ |
|
328 status = ((DStaticPowerResourceD*)pDepRes)->TranslateDependentState(aRequest.ResourceId(), \ |
|
329 aRequest.Level(), resState); \ |
|
330 if((status == ENoChange) || (pDepRes->iCachedLevel == resState)) \ |
|
331 { \ |
|
332 depNode->iRequiresChange = EFalse; \ |
|
333 continue; \ |
|
334 } \ |
|
335 if(status == EChangeNotAccepted) \ |
|
336 return KErrPermissionDenied; \ |
|
337 depRequest.ResourceId() = pDepRes->iResourceId; \ |
|
338 depRequest.ClientId() = aRequest.ResourceId(); /*ID of the dependent resource */ \ |
|
339 depRequest.Level() = resState; \ |
|
340 depRequest.Resource() = pDepRes; \ |
|
341 /*Check resource client list and resource list to see whether change is allowed.*/ \ |
|
342 if(pDepRes->Sense() == DStaticPowerResource::ECustom) \ |
|
343 { \ |
|
344 /*Call custom function to check whether change is allowed.*/ \ |
|
345 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
346 depRequest.RequiresChange() = ((DDynamicPowerResourceD*)pDepRes)->iDepCustomFunction(depRequest.ClientId(), \ |
|
347 originatorName, depRequest.ResourceId(), EClientChangeLevel, depRequest.Level(), (TAny*)&pDepRes->iClientList, \ |
|
348 (TAny*)&((DDynamicPowerResourceD*)pDepRes)->iResourceClientList, NULL); \ |
|
349 else \ |
|
350 depRequest.RequiresChange() = ((DStaticPowerResourceD*)pDepRes)->iDepCustomFunction(depRequest.ClientId(), \ |
|
351 originatorName, depRequest.ResourceId(), EClientChangeLevel, depRequest.Level(), (TAny*)&pDepRes->iClientList, \ |
|
352 (TAny*)&((DStaticPowerResourceD*)pDepRes)->iResourceClientList, NULL); \ |
|
353 if(!depRequest.RequiresChange()) \ |
|
354 return KErrPermissionDenied; \ |
|
355 } \ |
|
356 SPowerResourceClientLevel*pN=NULL; \ |
|
357 for(SDblQueLink* pNL=pDepRes->iClientList.First();pNL!=&pDepRes->iClientList.iA; pNL=pNL->iNext) \ |
|
358 { \ |
|
359 pN = (SPowerResourceClientLevel*)pNL; \ |
|
360 if(pDepRes->Sense() == DStaticPowerResource::EPositive) \ |
|
361 { \ |
|
362 if(pN->iLevel > depRequest.Level()) \ |
|
363 return KErrPermissionDenied; \ |
|
364 } \ |
|
365 else if(pDepRes->Sense() == DStaticPowerResource::ENegative) \ |
|
366 { \ |
|
367 if(pN->iLevel < depRequest.Level()) \ |
|
368 return KErrPermissionDenied; \ |
|
369 } \ |
|
370 } \ |
|
371 \ |
|
372 /*check through the resource client level */ \ |
|
373 SPowerResourceClientLevel*pCL = NULL; \ |
|
374 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
375 pCL = ((DDynamicPowerResourceD*)pDepRes)->iResourceClientList; \ |
|
376 else \ |
|
377 pCL = ((DStaticPowerResourceD*)pDepRes)->iResourceClientList; \ |
|
378 for(; pCL != NULL; pCL = pCL->iNextInList) \ |
|
379 { \ |
|
380 if(pCL->iClientId == pDR->iResourceId) \ |
|
381 break; \ |
|
382 } \ |
|
383 if(!pCL) \ |
|
384 clientLevelCount++; \ |
|
385 /*check dependent resource client list & resource list to see whether change is allowed */ \ |
|
386 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
387 result = ((DDynamicPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, \ |
|
388 ECheckChangeAllowed, originatorId, originatorName); \ |
|
389 else \ |
|
390 result = ((DStaticPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, \ |
|
391 ECheckChangeAllowed, originatorId, originatorName); \ |
|
392 if(result != KErrNone) \ |
|
393 return result; \ |
|
394 depNode->iPropagatedLevel = resState; \ |
|
395 depNode->iRequiresChange = ETrue; \ |
|
396 } \ |
|
397 break; \ |
|
398 } \ |
|
399 case ERequestStateChange: \ |
|
400 { \ |
|
401 SPowerResourceClientLevel* pCL = NULL; \ |
|
402 for(SNode* depNode = pDR->iDependencyList; depNode != NULL; depNode = depNode->iNext) \ |
|
403 { \ |
|
404 pDepRes = (resourceTypePointer)depNode->iResource; \ |
|
405 if((!depNode->iRequiresChange) || (pDepRes->iResourceId == (TUint)aRequest.ClientId())) \ |
|
406 continue; \ |
|
407 depRequest.ResourceId() = pDepRes->iResourceId; \ |
|
408 depRequest.ClientId() = aRequest.ResourceId(); \ |
|
409 depRequest.Level() = depNode->iPropagatedLevel; \ |
|
410 depRequest.Resource() = pDepRes; \ |
|
411 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
412 ((DDynamicPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, ERequestStateChange, \ |
|
413 originatorId, originatorName); \ |
|
414 else \ |
|
415 ((DStaticPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, ERequestStateChange, \ |
|
416 originatorId, originatorName); \ |
|
417 /*Update level if resource client level is already present for this resource.*/ \ |
|
418 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
419 pCL = ((DDynamicPowerResourceD*)pDepRes)->iResourceClientList; \ |
|
420 else \ |
|
421 pCL = ((DStaticPowerResourceD*)pDepRes)->iResourceClientList; \ |
|
422 for(; pCL != NULL; pCL = pCL->iNextInList) \ |
|
423 { \ |
|
424 if(pCL->iClientId == pDR->iResourceId) \ |
|
425 { \ |
|
426 pCL->iLevel = depNode->iPropagatedLevel; \ |
|
427 break; \ |
|
428 } \ |
|
429 } \ |
|
430 if(!pCL) /*Create a new resource client level*/ \ |
|
431 { \ |
|
432 TheController->RemoveClientLevelFromPool(pCL); \ |
|
433 pCL->iClientId = pDR->iResourceId; \ |
|
434 pCL->iResourceId = pDepRes->iResourceId; \ |
|
435 pCL->iLevel = depNode->iPropagatedLevel; \ |
|
436 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
437 { \ |
|
438 LIST_PUSH(((DDynamicPowerResourceD*)pDepRes)->iResourceClientList, pCL, iNextInList); \ |
|
439 } \ |
|
440 else \ |
|
441 { \ |
|
442 LIST_PUSH(((DStaticPowerResourceD*)pDepRes)->iResourceClientList, pCL, iNextInList); \ |
|
443 } \ |
|
444 clientLevelCount--; \ |
|
445 } \ |
|
446 } \ |
|
447 if(traceEnabled && (aRequest.ClientId() & KIdMaskResourceWithDependencies)) \ |
|
448 { \ |
|
449 SPowerResourceClient res; \ |
|
450 SPowerResourceClient* pC = &res; \ |
|
451 pC->iClientId = aRequest.ClientId(); \ |
|
452 pC->iName = &KParentResource; \ |
|
453 DStaticPowerResource*pR = (DStaticPowerResource*)pDR; \ |
|
454 TUint aResourceId = pDR->iResourceId; \ |
|
455 TInt aNewState = aRequest.Level(); \ |
|
456 PRM_CLIENT_CHANGE_STATE_START_TRACE \ |
|
457 } \ |
|
458 DoRequest(aRequest); \ |
|
459 if(traceEnabled && (aRequest.ClientId() & KIdMaskResourceWithDependencies)) \ |
|
460 { \ |
|
461 SPowerResourceClient res; \ |
|
462 SPowerResourceClient* pC = &res; \ |
|
463 pC->iClientId = aRequest.ClientId(); \ |
|
464 pC->iName = &KParentResource; \ |
|
465 DStaticPowerResource*pR = (DStaticPowerResource*)pDR; \ |
|
466 TUint aResourceId = pDR->iResourceId; \ |
|
467 TInt aNewState = aRequest.Level(); \ |
|
468 TInt r = KErrNone; \ |
|
469 PRM_CLIENT_CHANGE_STATE_END_TRACE \ |
|
470 } \ |
|
471 pDR->iCachedLevel = aRequest.Level(); \ |
|
472 pDR->iLevelOwnerId = aRequest.ClientId(); \ |
|
473 if(pDR->iIdleListEntry) \ |
|
474 { \ |
|
475 pDR->iIdleListEntry->iCurrentLevel = aRequest.Level(); \ |
|
476 pDR->iIdleListEntry->iLevelOwnerId = aRequest.ClientId(); \ |
|
477 } \ |
|
478 break; \ |
|
479 } \ |
|
480 case EIssueNotifications: \ |
|
481 { \ |
|
482 for(SNode* depNode = pDR->iDependencyList; depNode != NULL; depNode = depNode->iNext) \ |
|
483 { \ |
|
484 pDepRes = (resourceTypePointer)depNode->iResource; \ |
|
485 if((!depNode->iRequiresChange) || (pDepRes->iResourceId == (TUint)aRequest.ClientId())) \ |
|
486 continue; \ |
|
487 depRequest.ResourceId() = pDepRes->iResourceId; \ |
|
488 depRequest.ClientId() = pDepRes->iLevelOwnerId; \ |
|
489 depRequest.Level() = pDepRes->iCachedLevel; \ |
|
490 depRequest.Resource() = pDepRes; \ |
|
491 if(pDepRes->iResourceId & KIdMaskDynamic) \ |
|
492 ((DDynamicPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, EIssueNotifications, \ |
|
493 originatorId, originatorName); \ |
|
494 else \ |
|
495 ((DStaticPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, EIssueNotifications, \ |
|
496 originatorId, originatorName); \ |
|
497 } \ |
|
498 TheController->CompleteNotifications(aRequest.ClientId(), pDR, aRequest.Level(), KErrNone, \ |
|
499 aRequest.ClientId()); \ |
|
500 break; \ |
|
501 } \ |
|
502 default: \ |
|
503 return KErrNotSupported; \ |
|
504 } \ |
|
505 return result; |
|
506 |
|
507 struct SPowerResourceClient; |
|
508 struct TPowerRequest; |
|
509 struct SPowerRequest; |
|
510 struct SPowerResourceClientLevel; |
|
511 struct SIdleResourceInfo; |
|
512 class DPowerResourceController; |
|
513 |
|
514 /** |
|
515 @internalComponent |
|
516 @prototype 9.5 |
|
517 Interface class for Resource Manager |
|
518 Functions from PowerResourceManager calls corresponding functions of this |
|
519 class which in turn calls Powercontroller functions. |
|
520 */ |
|
521 class TInterface |
|
522 { |
|
523 public: |
|
524 static TInt RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType=EOwnerProcess); |
|
525 static TInt DeRegisterClient(TUint aClientId); |
|
526 static TInt GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName); |
|
527 static TInt GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId); |
|
528 static TInt GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId); |
|
529 static TInt GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo); |
|
530 static TInt GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources); |
|
531 static TInt GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources, TAny* aInfo); |
|
532 static TInt GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients); |
|
533 static TInt GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients, TAny* aInfo); |
|
534 static TInt AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm); |
|
535 static TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL); |
|
536 static TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId); |
|
537 static TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb); |
|
538 static TInt CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb); |
|
539 static TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN); |
|
540 static TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, TInt aThreshold, TBool aDirection); |
|
541 static TInt CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN); |
|
542 static TInt DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId); |
|
543 static DPowerResourceController* GetPowerResourceController(void); |
|
544 static TInt ControlIO(TUint aClientId, TUint aFunction, TAny* aParam1, TAny* aParam2, TAny* aParam3); |
|
545 }; |
|
546 |
|
547 /** |
|
548 @internalComponent |
|
549 @prototype 9.5 |
|
550 Container class to create containers of pointers to clients. |
|
551 */ |
|
552 template <class T> |
|
553 class DResourceCon : public DBase |
|
554 { |
|
555 public: |
|
556 inline TInt Initialise(TUint16 aInitialSize); |
|
557 inline void Delete(); |
|
558 inline T* operator[](TUint16 aIndex); |
|
559 inline TInt Remove(T* aObj, TUint16 aIndex); |
|
560 inline TInt Add(T* aObj, TUint &aId); |
|
561 inline TInt Find(T*& anEntry, TDesC& aName); |
|
562 inline TInt ReSize(TUint16 aGrowBy); |
|
563 inline TUint16 Count() {return iCount;} |
|
564 inline TUint16 Allocd() {return iAllocated;} |
|
565 inline TUint16 GrowBy() {return iGrowBy;} |
|
566 private: |
|
567 TUint16 iGrowBy; //Size to grow the size of the array. |
|
568 TUint16 iAllocated; //Size of the array |
|
569 TUint16 iCount; //Valid entries in the array |
|
570 TUint16 iInstanceCount; //FreeCounter incremented whenever an entry is added. |
|
571 TUint16 iFreeLoc; //Cached free location in the array |
|
572 TUint16 iSpare; |
|
573 T** iArray; |
|
574 }; |
|
575 |
|
576 /** |
|
577 @internalComponent |
|
578 @prototype 9.5 |
|
579 Factory class for physical device |
|
580 */ |
|
581 NONSHARABLE_CLASS(DResConPddFactory) : public DPhysicalDevice |
|
582 { |
|
583 public: |
|
584 /** |
|
585 Structure for holding PDD capabilities information |
|
586 */ |
|
587 class TCaps |
|
588 { |
|
589 public: |
|
590 TVersion iVersion; |
|
591 }; |
|
592 public: |
|
593 DResConPddFactory(); |
|
594 virtual TInt Install(); |
|
595 virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); |
|
596 virtual TInt Validate(TInt aUint, const TDesC8* anInfo, const TVersion& aVer); |
|
597 virtual void GetCaps(TDes8& aDes) const; |
|
598 inline static TVersion VersionRequired(); |
|
599 }; |
|
600 |
|
601 /** |
|
602 @internalComponent |
|
603 @prototype 9.5 |
|
604 Interface class for user side resource controller proxy. For each user side channel opened an object of |
|
605 this class is created in heap and pointer to resource controller is stored in iController member variable. |
|
606 User side resource controller proxy calls the resource controller API's by deferencing the pointer. |
|
607 This class is required as when the channel is closed the device driver framework tries to delete |
|
608 the object stored in ipdd, because of which it is not possible to pass the controller pointer directly. |
|
609 */ |
|
610 class DUserSideProxyInterface: public DBase |
|
611 { |
|
612 public: |
|
613 DPowerResourceController *iController; |
|
614 }; |
|
615 |
|
616 |
|
617 /** |
|
618 @publishedPartner |
|
619 @prototype 9.5 |
|
620 resource manager implementation base class |
|
621 */ |
|
622 NONSHARABLE_CLASS (DPowerResourceController) : public DBase |
|
623 { |
|
624 public: |
|
625 TInt RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType=EOwnerProcess); |
|
626 TInt DeRegisterClient(TUint aClientId); |
|
627 virtual TInt GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName); |
|
628 virtual TInt GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId); |
|
629 virtual TInt GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId); |
|
630 virtual TInt GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo); |
|
631 virtual TInt GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources); |
|
632 virtual TInt GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources, TAny* aInfo); |
|
633 virtual TInt GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients); |
|
634 virtual TInt GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients, TAny* aInfo); |
|
635 virtual TInt AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm); |
|
636 virtual TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL); |
|
637 virtual TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId); |
|
638 virtual TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb); |
|
639 virtual TInt CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb); |
|
640 virtual TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN); |
|
641 virtual TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, TInt aThreshold, TBool aDirection); |
|
642 virtual TInt CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN); |
|
643 virtual TInt DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId); |
|
644 public: |
|
645 enum TResConPanic |
|
646 { |
|
647 ECalledFromDfcThread0 = 0, |
|
648 ECalledFromIsr = 1, |
|
649 ECalledFromNullThread = 2, |
|
650 ECalledFromDfcThread1 = 3, |
|
651 EClientHasPendingAsyncRequest = 4, |
|
652 EClientHasNotificationObject = 5, |
|
653 EControllerAlreadyExists = 6, |
|
654 ECustomFunctionNotSet = 7, |
|
655 EClientIdNotInClientLevelList = 8, |
|
656 ENoMemToCreatePowerControllerClient = 9, |
|
657 EResourceNameExceedsLimit = 10, |
|
658 EObjectNotFoundInList = 11 |
|
659 }; |
|
660 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
661 enum TExtendedResConPanic |
|
662 { |
|
663 EClosedLoopDependencies = EObjectNotFoundInList + 2, //13 |
|
664 ERegisteringNonDependentStaticResource = 14, |
|
665 EClientHasDynamicResourceRegistered = 15, |
|
666 EDynamicResourceStillRegistered = 16, |
|
667 ERegisteringDependentStaticResourceWithHoles = 17 |
|
668 }; |
|
669 #endif |
|
670 enum TResConStartSequence |
|
671 { |
|
672 EResConCreated, |
|
673 EResConInitialised, |
|
674 EResConStartupCompleted |
|
675 }; |
|
676 //early initialization |
|
677 IMPORT_C static TInt InitController(); |
|
678 TInt InitResources(); |
|
679 //request a post-boot level for the resource |
|
680 IMPORT_C static TInt PostBootLevel(TUint aResId, TInt aLevel); |
|
681 //request registration of static resource |
|
682 IMPORT_C static TInt RegisterStaticResource(TUint aClientId, DStaticPowerResource* pR); |
|
683 //request registration of group/array of static resources |
|
684 IMPORT_C static TInt RegisterArrayOfStaticResources(TUint aClientId, DStaticPowerResource**& aStaticResourceArray, TUint aResCount); |
|
685 //registration for proxy client |
|
686 virtual TInt RegisterProxyClient(TUint& aProxyId, const TDesC8& aName); |
|
687 virtual TInt DeregisterProxyClient(TUint aClientId); |
|
688 //register list of resources whose state matter to Idle |
|
689 virtual TInt RegisterResourcesForIdle(TInt aPowerControllerId, TUint aNumResources, TPtr* aBuf); |
|
690 static void Panic(TUint8 aPanic); |
|
691 virtual TInt GetInterface(TUint aClientId, TUint aInterfaceId, TAny* aParam1, TAny* aParam2, TAny* aParam3); |
|
692 virtual ~DPowerResourceController(); |
|
693 /**@internalComponent*/ |
|
694 void CompleteNotifications(TInt aClientId, DStaticPowerResource* aResource, TInt aState, TInt aReturnCode, TInt aLevelOwnerId, TBool aLock = ETrue); |
|
695 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
696 /**@internalComponent*/ |
|
697 TInt ReserveClientLevelPoolCount(TUint16 aCount); |
|
698 /**@internalComponent*/ |
|
699 void RemoveClientLevelFromPool(SPowerResourceClientLevel *&aLevelPtr); |
|
700 #endif |
|
701 protected: |
|
702 //generic layer function to be called by the PSL |
|
703 DPowerResourceController(); |
|
704 void SetDfcQ(TDfcQue* aDfcQ); |
|
705 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
706 void SetDfcQDependency(TDfcQue* aDfcQ); |
|
707 #endif |
|
708 TInt InitPools(TUint16 aKClients, TUint16 aUClients, TUint16 aNClientLevels, TUint16 aNRequests); |
|
709 /* Lock the resource controller mutex */ |
|
710 inline void Lock() { NKern::ThreadEnterCS(); |
|
711 Kern::MutexWait(*iResourceMutex); } |
|
712 inline void UnLock() { Kern::MutexSignal(*iResourceMutex); |
|
713 NKern::ThreadLeaveCS();} |
|
714 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
715 //Default implementation, PSL re-implements these if features supported |
|
716 virtual TInt DoRegisterStaticResourcesDependency(DStaticPowerResourceD**& aStaticResourceDArray, TUint16& aStaticResourceDCount); |
|
717 #endif |
|
718 private: |
|
719 // pure virtual implemented by PSL - to be called by PIL |
|
720 virtual TInt DoInitController()=0; |
|
721 virtual TInt DoRegisterStaticResources(DStaticPowerResource**& aStaticResourceArray, TUint16& aStaticResourceCount)=0; |
|
722 /**@internalComponent*/ |
|
723 TInt CheckLevelAndAddClient(SPowerResourceClient* pC, TPowerRequest* Request); |
|
724 static void MsgQFunc(TAny* aPtr); |
|
725 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
726 static void MsgQDependencyFunc(TAny* aPtr); |
|
727 #endif |
|
728 |
|
729 /**@internalComponent*/ |
|
730 void ResourceStateChangeOfClientLevels(SPowerResourceClient* pC); |
|
731 /**@internalComponent*/ |
|
732 void HandleMsg(TPowerRequest& aRequest); |
|
733 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
734 /**@internalComponent*/ |
|
735 void HandleDependencyMsg(TPowerRequest& aRequest); |
|
736 #endif |
|
737 /**@internalComponent*/ |
|
738 void CompleteRequest(TPowerRequest& aRequest); |
|
739 /**@internalComponent*/ |
|
740 void MoveRequestToFreePool(TPowerRequest *aReq); |
|
741 /**@internalComponent*/ |
|
742 TInt HandleReservationOfObjects(TPowerRequest& aRequest); |
|
743 /**@internalComponent*/ |
|
744 TInt HandleClientRegistration(TPowerRequest& aRequest); |
|
745 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
746 TInt RegisterDynamicResource(SPowerResourceClient* aClientPtr, DDynamicPowerResource* aPDRes, TUint* aDynamicResourceId); |
|
747 TInt DeregisterDynamicResource(SPowerResourceClient* aClientPtr, TUint aDynamicResourceId, TInt* aPDefLevel); |
|
748 TInt RegisterResourceDependency(SPowerResourceClient* aClientPtr, SResourceDependencyInfo* aInfo1, SResourceDependencyInfo* aInfo2); |
|
749 /**@internalComponent*/ |
|
750 void CheckForDependencyLoop(DStaticPowerResourceD* pR, TUint aParentResId, TUint aTargetResId); |
|
751 TInt DeregisterResourceDependency(SPowerResourceClient* aClientPtr, TUint aResId1, TUint aResId2); |
|
752 /**@internalComponent*/ |
|
753 TInt HandleDependencyResourceStateChange(SPowerResourceClient* pC, TPowerRequest& aRequest); |
|
754 TInt GetNumDependentsForResource(TUint aResourceId, TUint* aNumResources); |
|
755 TInt GetDependentsIdForResource(TUint aResourceId, TAny* aInfo, TUint* aNumDepResources); |
|
756 TInt HandleResourceRegistration(TPowerRequest& aReq); |
|
757 #endif |
|
758 public: |
|
759 DMutex* iResourceMutex; |
|
760 protected: |
|
761 TDfcQue* iDfcQ; |
|
762 TMessageQue *iMsgQ; |
|
763 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
764 TDfcQue* iDfcQDependency; |
|
765 TMessageQue* iMsgQDependency; |
|
766 TBool iDfcQDependencyLock; |
|
767 #endif |
|
768 private: |
|
769 DStaticPowerResource** iStaticResourceArray; |
|
770 DResourceCon<SPowerResourceClient> iClientList; |
|
771 DResourceCon<SPowerResourceClient> iUserSideClientList; |
|
772 SPowerResourceClient* iClientPool; |
|
773 SPowerRequest* iRequestPool; |
|
774 SPowerResourceClientLevel* iClientLevelPool; |
|
775 TUint iPowerControllerId; //Stores the ID allocated to PowerController |
|
776 SIdleResourceInfo* iListForIdle; |
|
777 TUint iInitialised; |
|
778 TUint16 iClientCount; |
|
779 TUint16 iUserSideClientCount; |
|
780 TUint16 iClientLevelPoolCount; |
|
781 TUint16 iClientLevelPoolGrowBy; |
|
782 TUint16 iRequestPoolCount; |
|
783 TUint16 iRequestPoolGrowBy; |
|
784 TUint16 iStaticResourceArrayEntries; //Number of entries in the array including holes if any. |
|
785 TUint16 iStaticResourceCount; //Actual number of static resources registered (valid entries). |
|
786 TUint iReserved2; //Reserved for future use |
|
787 #ifdef PRM_ENABLE_EXTENDED_VERSION |
|
788 DResourceCon<DDynamicPowerResource> iDynamicResourceList; |
|
789 DResourceCon<DDynamicPowerResourceD> iDynamicResDependencyList; |
|
790 DStaticPowerResourceD** iStaticResDependencyArray; |
|
791 SPowerResourceClientLevel* iResourceLevelPool; |
|
792 TUint16 iResourceLevelPoolCount; |
|
793 TUint16 iStaticResDependencyCount; |
|
794 TUint16 iDynamicResourceCount; |
|
795 TUint8 iDynamicResDependencyCount; |
|
796 TUint8 iSpare2; |
|
797 TUint iReserved3; //Reserved for future use. |
|
798 #endif |
|
799 }; |
|
800 |
|
801 /** |
|
802 @publishedPartner |
|
803 @prototype 9.5 |
|
804 power level of client in a shared resource |
|
805 */ |
|
806 struct SPowerResourceClientLevel : public SDblQueLink |
|
807 { |
|
808 TUint iClientId; |
|
809 TUint iResourceId; |
|
810 TInt iLevel; |
|
811 SPowerResourceClientLevel* iNextInList; |
|
812 }; |
|
813 |
|
814 /** |
|
815 @internalComponent |
|
816 @prototype 9.5 |
|
817 respresent client in resource manager |
|
818 */ |
|
819 struct SPowerResourceClient |
|
820 { |
|
821 TUint iClientId; |
|
822 const TDesC8* iName; |
|
823 SPowerResourceClient* iNextInList; |
|
824 SPowerResourceClientLevel* iLevelList; |
|
825 DPowerResourceNotification* iNotificationList; |
|
826 TUint8 iReservedCl; |
|
827 TUint8 iReservedRm; |
|
828 TUint8 iPendingReqCount; |
|
829 TUint8 iUnderFlowRmCount; |
|
830 TUint8 iUnderFlowClCount; |
|
831 TUint8 iDynamicResCount; //Counter for dynamic resource registered by the client. Used only in extended version |
|
832 TUint8 iSpare1; |
|
833 TUint8 iSpare2; |
|
834 union |
|
835 { |
|
836 TUint iThreadId; |
|
837 TAny* iSpare3; |
|
838 }; |
|
839 }; |
|
840 |
|
841 /** |
|
842 @publishedPartner |
|
843 @prototype 9.5 |
|
844 represents a request inside the resource manager |
|
845 */ |
|
846 struct TPowerRequest : public TThreadMessage |
|
847 { |
|
848 /** requests can either be to get the resource value or to change the resource value*/ |
|
849 enum TReqType {EGet, EChange, ESetDefaultLevel, ERegisterKernelClient, ERegisterUsersideClient, EAllocReserve, |
|
850 ERegisterDynamicResource }; |
|
851 /** @return thread's own message and turn into a power request. Used for sync/instant calls*/ |
|
852 inline static TPowerRequest& Get() |
|
853 {return (TPowerRequest&)Kern::Message();} |
|
854 /** @return type of request get or set */ |
|
855 inline TReqType& ReqType() // one of TReqType |
|
856 {return *(TReqType*)&iValue;} |
|
857 /** @return resource id which is being requested*/ |
|
858 inline TUint& ResourceId() |
|
859 {return *(TUint*)&iArg[0];} |
|
860 /** @return id of client making request (only valid on change requests)*/ |
|
861 inline TInt& ClientId() |
|
862 {return *(TInt*)&iArg[1];} |
|
863 /** |
|
864 On resource state change operations the PIL sets this field with the required level before |
|
865 invoking the DoRequest(..) function; on return from DoRequest(..) function the PSL sets this field |
|
866 with the real state of the resource to be cached by the PIL.On resource state read operations PSL |
|
867 sets it with the level read. |
|
868 */ |
|
869 inline TInt& Level() |
|
870 {return *(TInt*)&iArg[2];} |
|
871 /** @return pointer the resource being requested */ |
|
872 inline DStaticPowerResource*& Resource() |
|
873 {return *(DStaticPowerResource**)&iArg[3];} |
|
874 /** @return pointer to resource callback structure, used for async requests */ |
|
875 inline TPowerResourceCb*& ResourceCb() |
|
876 {return *(TPowerResourceCb**)&iArg[4];} |
|
877 /** @return return code of resource's DoRequest function when request has been processed */ |
|
878 inline TInt& ReturnCode() |
|
879 {return *(TInt*)&iArg[5];} |
|
880 /** @return return ETrue if a change is required on a shared resource */ |
|
881 inline TBool& RequiresChange() |
|
882 {return *(TInt*)&iArg[6];} |
|
883 /** @return number of client level objects requested by a client to reserve */ |
|
884 inline TInt& ClientLevelCount() |
|
885 {return *(TInt*)&iArg[7];} |
|
886 /** @return number of request objects requested by a client to reserve */ |
|
887 inline TInt& RequestCount() |
|
888 {return *(TInt*)&iArg[8];} |
|
889 }; |
|
890 |
|
891 /** |
|
892 @internalComponent |
|
893 @prototype 9.5 |
|
894 */ |
|
895 struct SPowerRequest |
|
896 { |
|
897 TPowerRequest iRequest; |
|
898 SPowerRequest* iNext; |
|
899 }; |
|
900 |
|
901 /** |
|
902 @publishedPartner |
|
903 @prototype 9.5 |
|
904 Structure representing resource information used for Idle power management |
|
905 */ |
|
906 struct SIdleResourceInfo |
|
907 { |
|
908 TUint iResourceId; |
|
909 TInt iLevelOwnerId; //Owner of the resource. |
|
910 TInt iCurrentLevel; //Cached resource state |
|
911 TInt iReserved1; //Reserved for future use. |
|
912 TInt iReserved2; //Reserved for future use. |
|
913 TInt iReserved3; //Reserved for future use. |
|
914 }; |
|
915 |
|
916 #include <drivers/resourcecontrol.inl> |
|
917 |
|
918 #endif //__RESOURCECONTROL_H__ |
|
919 |
|
920 |