Update contrib.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\drivers\resourceman\rescontrol_export.cpp
18 #include <drivers/resourcecontrol.h>
21 #define GET_CRITICAL_SECTION_COUNT(thread) \
22 TInt CsCount = thread.iNThread.iCsCount;
24 #define LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread) \
25 if(thread.iNThread.iCsCount != CsCount) \
26 Kern::Fault("PowerResourceController", __LINE__); \
27 if(pRC->iResourceMutex->iHoldCount != 0) \
28 Kern::Fault("PowerResourceController", __LINE__);
30 #define GET_CRITICAL_SECTION_COUNT(thread)
31 #define LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
37 Kernel extension or variants can call this API to set the post bool value without registering
38 as client with the resource controller. This can be used by the resource controller PSL to set the
39 specified static resources to appropriate value before resource controller is fully initialized.
40 @param aResId ID of the resource whose level should be set after initialisation
41 @param aLevel Resource level to set
42 @return KErrNone, if operation is success
43 KErrNotFound, if resource ID could not be found in the static resource array.
44 KErrNotSupported, if this API is called after resource controller is fully initialized
46 EXPORT_C TInt DPowerResourceController::PostBootLevel(TUint aResId, TInt aLevel)
49 DThread& thread = Kern::CurrentThread();
50 GET_CRITICAL_SECTION_COUNT(thread)
52 __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::PostBootLevel, aResId = 0x%x, aLevel = %d",
54 DPowerResourceController* pRC = TInterface::GetPowerResourceController();
59 //Accept the postboot level only if issued before controller is fully initialised.
60 if(pRC->iInitialised == EResConStartupCompleted)
63 LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
64 return KErrNotSupported;
66 #ifndef PRM_ENABLE_EXTENDED_VERSION
67 // coverity[deref_ptr]
68 // aResId is checked to be more than the array entries before dereferencing pRC->iStaticResourceArray
69 if((!aResId) || (aResId > pRC->iStaticResourceArrayEntries) || (!pRC->iStaticResourceArray[aResId-1]))
72 LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
76 if(!aResId || ((aResId & KIdMaskResourceWithDependencies) && ((aResId & ID_INDEX_BIT_MASK) > pRC->iStaticResDependencyCount))
77 || (!(aResId & KIdMaskResourceWithDependencies) && ((aResId > pRC->iStaticResourceArrayEntries)
78 || (!pRC->iStaticResourceArray[aResId-1]))))
81 LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
84 if(aResId & KIdMaskResourceWithDependencies)
86 aResId &= ID_INDEX_BIT_MASK;
87 DStaticPowerResource* pR = pRC->iStaticResDependencyArray[--aResId];
88 pR->iPostBootLevel=aLevel;
89 pR->iFlags |= SET_VALID_POST_BOOT_LEVEL;
93 if(pRC->iStaticResourceArray)
95 DStaticPowerResource* pR=pRC->iStaticResourceArray[--aResId];
96 pR->iPostBootLevel=aLevel;
97 pR->iFlags |= SET_VALID_POST_BOOT_LEVEL; // To indicate valid post boot level is set.
100 LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
107 Kernel extensions or variants can call this API to register the static resources before resource controller
108 is fully initialised.
109 @Param aClientId ID of the client that is requesting resource registration
110 @Param aStaticResourceArray Static resources to register with RC.
111 @Param aResCount Number of static resources to register with RC. This equals the size of the passed array.
112 @return KErrNone, if operation is success
113 KErrAccessDenied if clientId could not be found in the current list of registered clients or if this
114 client was registered as thread relative and was not called from the same thread.
115 KErrNotSupported if called after resource controller is fully initialised or if called from user side proxy
116 or if the resource is dynamic or dependency resource.
117 KErrNoMemory if there is insufficient memory.
118 KErrArgument if passed array is null or passed number of resources count is 0.
120 EXPORT_C TInt DPowerResourceController::RegisterArrayOfStaticResources(TUint aClientId, DStaticPowerResource**& aStaticResourceArray, TUint aResCount)
122 DThread& thread = Kern::CurrentThread();
123 __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterStaticResource"));
124 DPowerResourceController* pRC = TInterface::GetPowerResourceController();
128 if(!aStaticResourceArray || (aResCount == 0))
130 CHECK_CONTEXT(thread)
131 //Accept the registration of static resource only if issued before controller is fully initialised.
132 if(pRC->iInitialised == EResConStartupCompleted)
134 return KErrNotSupported;
136 //User side clients and resource with dependency are not supported.
137 if(aClientId & USER_SIDE_CLIENT_BIT_MASK)
139 return KErrNotSupported;
141 #ifdef PRM_ENABLE_EXTENDED_VERSION
144 if((((DStaticPowerResource*)aStaticResourceArray)->iResourceId & KIdMaskResourceWithDependencies) ||
145 (((DStaticPowerResource*)aStaticResourceArray)->iResourceId & KIdMaskDynamic))
147 return KErrNotSupported;
152 for(TUint rescount = 0; rescount < aResCount; rescount++)
154 if(aStaticResourceArray[rescount] && ((aStaticResourceArray[rescount]->iResourceId & KIdMaskResourceWithDependencies) ||
155 (aStaticResourceArray[rescount]->iResourceId & KIdMaskDynamic)))
157 return KErrNotSupported;
162 SPowerResourceClient* pC = pRC->iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];
165 __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found"));
166 return KErrAccessDenied;
168 if(pC->iClientId != aClientId)
170 __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID instance count does not match"));
171 return KErrAccessDenied;
173 if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK)
175 if(pC->iThreadId != thread.iId)
177 __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client not called from thread context(Thread Relative)"));
178 return KErrAccessDenied;
182 TInt r = Kern::SafeReAlloc((TAny*&)pRC->iStaticResourceArray, pRC->iStaticResourceArrayEntries*sizeof(DStaticPowerResource*),
183 (pRC->iStaticResourceArrayEntries + aResCount)*sizeof(DStaticPowerResource*));
190 pRC->iStaticResourceArray[pRC->iStaticResourceArrayEntries++] = (DStaticPowerResource*)aStaticResourceArray;
191 if((DStaticPowerResource*)aStaticResourceArray)
192 pRC->iStaticResourceCount++;
196 for(TUint count = 0; count < aResCount; count++)
198 pRC->iStaticResourceArray[pRC->iStaticResourceArrayEntries++] = aStaticResourceArray[count];
199 if(aStaticResourceArray[count])
200 pRC->iStaticResourceCount++;
209 Kernel extensions or variants can call this API to register the static resources before resource controller
210 is fully initialized.
211 @Param aClientId ID of the client that is requesting resource registration
212 @Param pR Static resource to register with RC.
213 @return KErrNone, if operation is success
214 KErrAccessDenied if clientId could not be found in the current list of registered clients or if this
215 client was registered as thread relative and was not called from the same thread.
216 KErrNotSupported if called after resource controller is fully initialized or if called from user side proxy
217 or if the resource is dynamic or dependency resource
218 KErrNoMemory if there is insufficient memory.
219 KErrArgument if passed array is null
221 EXPORT_C TInt DPowerResourceController::RegisterStaticResource(TUint aClientId, DStaticPowerResource* pR)
223 return RegisterArrayOfStaticResources(aClientId, (DStaticPowerResource**&)pR, 1);
229 This function initialises the controller.
230 @return KErrNone, if operation is success or one of the system wide errors.
232 EXPORT_C TInt DPowerResourceController::InitController()
234 __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::InitController()"));
235 DPowerResourceController* pRC = TInterface::GetPowerResourceController();
238 if(pRC->iInitialised >= EResConInitialised)
240 __KTRACE_OPT(KRESMANAGER, Kern::Printf("InitController already initialised %d\n", pRC->iInitialised));
243 _LIT(KResMutexName, "RESCTRL");
245 //Create the message queue
246 pRC->iMsgQ = new TMessageQue(DPowerResourceController::MsgQFunc, pRC, NULL, 2);
249 #ifdef PRM_ENABLE_EXTENDED_VERSION
250 //Create the message queue for dependency resource processing.
251 pRC->iMsgQDependency = new TMessageQue(DPowerResourceController::MsgQDependencyFunc, pRC, NULL, 1);
252 if(!pRC->iMsgQDependency)
255 // Call PSL to create all static resources and populate the iStaticResourceArray with pointers to resources and
256 // update static resource count
257 r=pRC->DoRegisterStaticResources(pRC->iStaticResourceArray, pRC->iStaticResourceArrayEntries);
260 //Get the actual number of static resource registered count
261 for(TInt resCnt = 0; resCnt < pRC->iStaticResourceArrayEntries; resCnt++)
263 if(pRC->iStaticResourceArray[resCnt])
264 pRC->iStaticResourceCount++;
266 __KTRACE_OPT(KRESMANAGER, Kern::Printf("Actual number of static resource registered = %d\n", pRC->iStaticResourceCount));
267 #ifdef PRM_INSTRUMENTATION_MACRO
268 // Btrace output of resource information of each resource.
269 DStaticPowerResource* pR = NULL;
270 TPowerResourceInfoBuf01 resInfo;
271 TPowerResourceInfoV01 *pResInfo;
272 for(TInt resCount = 0; resCount < pRC->iStaticResourceArrayEntries; resCount++)
274 pR = pRC->iStaticResourceArray[resCount];
277 pR->GetInfo((TDes8*)resInfo.Ptr());
278 pResInfo = (TPowerResourceInfoV01*)resInfo.Ptr();
279 PRM_REGISTER_RESOURCE_TRACE
283 #ifdef PRM_ENABLE_EXTENDED_VERSION
284 //Call PSL to register static resources with dependency if any exists
285 r = pRC->DoRegisterStaticResourcesDependency(pRC->iStaticResDependencyArray, pRC->iStaticResDependencyCount);
288 if(pRC->iStaticResDependencyCount)
290 DStaticPowerResourceD* pRD = NULL;
292 //Assign resource index in resource id
293 for(count = 0; count < pRC->iStaticResDependencyCount; count++)
295 pRD = pRC->iStaticResDependencyArray[count];
297 Panic(DPowerResourceController::ERegisteringDependentStaticResourceWithHoles);
298 pRD->iResourceId |= ((count + 1) & ID_INDEX_BIT_MASK);
300 //Check for dependency closed loops
301 for(count = 0; count < pRC->iStaticResDependencyCount; count++)
303 pRD = pRC->iStaticResDependencyArray[count];
304 if(!(pRD->iResourceId & KIdMaskStaticWithDependencies))
305 Panic(DPowerResourceController::ERegisteringNonDependentStaticResource);
306 //Upgrade latency state change from instantaneous to long latency
307 if(!pRD->LatencySet())
308 pRD->iFlags |= KLongLatencySet;
309 pRC->CheckForDependencyLoop(pRD, pRD->iResourceId, pRD->iResourceId);
311 #ifdef PRM_INSTRUMENTATION_MACRO
312 for(count = 0; count < pRC->iStaticResDependencyCount; count++)
314 pR = pRC->iStaticResDependencyArray[count];
315 pR->GetInfo((TDes8*)resInfo.Ptr());
316 pResInfo = (TPowerResourceInfoV01*)resInfo.Ptr();
317 PRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY_TRACE
321 #endif // PRM_ENABLE_EXTENDED_VERSION
322 // Create mutex object
323 r=Kern::MutexCreate(pRC->iResourceMutex, KResMutexName, KMutexOrdResourceManager);
324 if(r==KErrNone) // Call PSL to create DFC queue and creation of pools with the help API's provided by generic layer.
325 r=pRC->DoInitController();
326 __KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::InitController()"));
329 pRC->iInitialised = EResConInitialised;
331 pRC->iMsgQ->Receive();
332 #ifdef PRM_ENABLE_EXTENDED_VERSION
333 if(pRC->iDfcQDependency)
334 pRC->iMsgQDependency->Receive();