sl@0
|
1 |
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
// All rights reserved.
|
sl@0
|
3 |
// This component and the accompanying materials are made available
|
sl@0
|
4 |
// under the terms of the License "Eclipse Public License v1.0"
|
sl@0
|
5 |
// which accompanies this distribution, and is available
|
sl@0
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
//
|
sl@0
|
8 |
// Initial Contributors:
|
sl@0
|
9 |
// Nokia Corporation - initial contribution.
|
sl@0
|
10 |
//
|
sl@0
|
11 |
// Contributors:
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// Description:
|
sl@0
|
14 |
// e32\drivers\resourceman\rescontrol_export.cpp
|
sl@0
|
15 |
//
|
sl@0
|
16 |
//
|
sl@0
|
17 |
|
sl@0
|
18 |
#include <drivers/resourcecontrol.h>
|
sl@0
|
19 |
|
sl@0
|
20 |
#ifdef DEBUG_VERSION
|
sl@0
|
21 |
#define GET_CRITICAL_SECTION_COUNT(thread) \
|
sl@0
|
22 |
TInt CsCount = thread.iNThread.iCsCount;
|
sl@0
|
23 |
|
sl@0
|
24 |
#define LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread) \
|
sl@0
|
25 |
if(thread.iNThread.iCsCount != CsCount) \
|
sl@0
|
26 |
Kern::Fault("PowerResourceController", __LINE__); \
|
sl@0
|
27 |
if(pRC->iResourceMutex->iHoldCount != 0) \
|
sl@0
|
28 |
Kern::Fault("PowerResourceController", __LINE__);
|
sl@0
|
29 |
#else
|
sl@0
|
30 |
#define GET_CRITICAL_SECTION_COUNT(thread)
|
sl@0
|
31 |
#define LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
|
sl@0
|
32 |
#endif
|
sl@0
|
33 |
|
sl@0
|
34 |
/**
|
sl@0
|
35 |
@publishedPartner
|
sl@0
|
36 |
@prototype 9.5
|
sl@0
|
37 |
Kernel extension or variants can call this API to set the post bool value without registering
|
sl@0
|
38 |
as client with the resource controller. This can be used by the resource controller PSL to set the
|
sl@0
|
39 |
specified static resources to appropriate value before resource controller is fully initialized.
|
sl@0
|
40 |
@param aResId ID of the resource whose level should be set after initialisation
|
sl@0
|
41 |
@param aLevel Resource level to set
|
sl@0
|
42 |
@return KErrNone, if operation is success
|
sl@0
|
43 |
KErrNotFound, if resource ID could not be found in the static resource array.
|
sl@0
|
44 |
KErrNotSupported, if this API is called after resource controller is fully initialized
|
sl@0
|
45 |
*/
|
sl@0
|
46 |
EXPORT_C TInt DPowerResourceController::PostBootLevel(TUint aResId, TInt aLevel)
|
sl@0
|
47 |
{
|
sl@0
|
48 |
#ifdef DEBUG_VERSION
|
sl@0
|
49 |
DThread& thread = Kern::CurrentThread();
|
sl@0
|
50 |
GET_CRITICAL_SECTION_COUNT(thread)
|
sl@0
|
51 |
#endif
|
sl@0
|
52 |
__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::PostBootLevel, aResId = 0x%x, aLevel = %d",
|
sl@0
|
53 |
aResId, aLevel));
|
sl@0
|
54 |
DPowerResourceController* pRC = TInterface::GetPowerResourceController();
|
sl@0
|
55 |
if(!pRC)
|
sl@0
|
56 |
return KErrNotFound;
|
sl@0
|
57 |
pRC->Lock();
|
sl@0
|
58 |
CHECK_CONTEXT(thread)
|
sl@0
|
59 |
//Accept the postboot level only if issued before controller is fully initialised.
|
sl@0
|
60 |
if(pRC->iInitialised == EResConStartupCompleted)
|
sl@0
|
61 |
{
|
sl@0
|
62 |
pRC->UnLock();
|
sl@0
|
63 |
LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
|
sl@0
|
64 |
return KErrNotSupported;
|
sl@0
|
65 |
}
|
sl@0
|
66 |
#ifndef PRM_ENABLE_EXTENDED_VERSION
|
sl@0
|
67 |
// coverity[deref_ptr]
|
sl@0
|
68 |
// aResId is checked to be more than the array entries before dereferencing pRC->iStaticResourceArray
|
sl@0
|
69 |
if((!aResId) || (aResId > pRC->iStaticResourceArrayEntries) || (!pRC->iStaticResourceArray[aResId-1]))
|
sl@0
|
70 |
{
|
sl@0
|
71 |
pRC->UnLock();
|
sl@0
|
72 |
LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
|
sl@0
|
73 |
return KErrNotFound;
|
sl@0
|
74 |
}
|
sl@0
|
75 |
#else
|
sl@0
|
76 |
if(!aResId || ((aResId & KIdMaskResourceWithDependencies) && ((aResId & ID_INDEX_BIT_MASK) > pRC->iStaticResDependencyCount))
|
sl@0
|
77 |
|| (!(aResId & KIdMaskResourceWithDependencies) && ((aResId > pRC->iStaticResourceArrayEntries)
|
sl@0
|
78 |
|| (!pRC->iStaticResourceArray[aResId-1]))))
|
sl@0
|
79 |
{
|
sl@0
|
80 |
pRC->UnLock();
|
sl@0
|
81 |
LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
|
sl@0
|
82 |
return KErrNotFound;
|
sl@0
|
83 |
}
|
sl@0
|
84 |
if(aResId & KIdMaskResourceWithDependencies)
|
sl@0
|
85 |
{
|
sl@0
|
86 |
aResId &= ID_INDEX_BIT_MASK;
|
sl@0
|
87 |
DStaticPowerResource* pR = pRC->iStaticResDependencyArray[--aResId];
|
sl@0
|
88 |
pR->iPostBootLevel=aLevel;
|
sl@0
|
89 |
pR->iFlags |= SET_VALID_POST_BOOT_LEVEL;
|
sl@0
|
90 |
}
|
sl@0
|
91 |
else
|
sl@0
|
92 |
#endif
|
sl@0
|
93 |
if(pRC->iStaticResourceArray)
|
sl@0
|
94 |
{
|
sl@0
|
95 |
DStaticPowerResource* pR=pRC->iStaticResourceArray[--aResId];
|
sl@0
|
96 |
pR->iPostBootLevel=aLevel;
|
sl@0
|
97 |
pR->iFlags |= SET_VALID_POST_BOOT_LEVEL; // To indicate valid post boot level is set.
|
sl@0
|
98 |
}
|
sl@0
|
99 |
pRC->UnLock();
|
sl@0
|
100 |
LOCK_AND_CRITICAL_SECTION_COUNT_CHECK(thread)
|
sl@0
|
101 |
return KErrNone;
|
sl@0
|
102 |
}
|
sl@0
|
103 |
|
sl@0
|
104 |
/**
|
sl@0
|
105 |
@publishedPartner
|
sl@0
|
106 |
@prototype 9.5
|
sl@0
|
107 |
Kernel extensions or variants can call this API to register the static resources before resource controller
|
sl@0
|
108 |
is fully initialised.
|
sl@0
|
109 |
@Param aClientId ID of the client that is requesting resource registration
|
sl@0
|
110 |
@Param aStaticResourceArray Static resources to register with RC.
|
sl@0
|
111 |
@Param aResCount Number of static resources to register with RC. This equals the size of the passed array.
|
sl@0
|
112 |
@return KErrNone, if operation is success
|
sl@0
|
113 |
KErrAccessDenied if clientId could not be found in the current list of registered clients or if this
|
sl@0
|
114 |
client was registered as thread relative and was not called from the same thread.
|
sl@0
|
115 |
KErrNotSupported if called after resource controller is fully initialised or if called from user side proxy
|
sl@0
|
116 |
or if the resource is dynamic or dependency resource.
|
sl@0
|
117 |
KErrNoMemory if there is insufficient memory.
|
sl@0
|
118 |
KErrArgument if passed array is null or passed number of resources count is 0.
|
sl@0
|
119 |
*/
|
sl@0
|
120 |
EXPORT_C TInt DPowerResourceController::RegisterArrayOfStaticResources(TUint aClientId, DStaticPowerResource**& aStaticResourceArray, TUint aResCount)
|
sl@0
|
121 |
{
|
sl@0
|
122 |
DThread& thread = Kern::CurrentThread();
|
sl@0
|
123 |
__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::RegisterStaticResource"));
|
sl@0
|
124 |
DPowerResourceController* pRC = TInterface::GetPowerResourceController();
|
sl@0
|
125 |
if(!pRC)
|
sl@0
|
126 |
return KErrNotFound;
|
sl@0
|
127 |
|
sl@0
|
128 |
if(!aStaticResourceArray || (aResCount == 0))
|
sl@0
|
129 |
return KErrArgument;
|
sl@0
|
130 |
CHECK_CONTEXT(thread)
|
sl@0
|
131 |
//Accept the registration of static resource only if issued before controller is fully initialised.
|
sl@0
|
132 |
if(pRC->iInitialised == EResConStartupCompleted)
|
sl@0
|
133 |
{
|
sl@0
|
134 |
return KErrNotSupported;
|
sl@0
|
135 |
}
|
sl@0
|
136 |
//User side clients and resource with dependency are not supported.
|
sl@0
|
137 |
if(aClientId & USER_SIDE_CLIENT_BIT_MASK)
|
sl@0
|
138 |
{
|
sl@0
|
139 |
return KErrNotSupported;
|
sl@0
|
140 |
}
|
sl@0
|
141 |
#ifdef PRM_ENABLE_EXTENDED_VERSION
|
sl@0
|
142 |
if(aResCount == 1)
|
sl@0
|
143 |
{
|
sl@0
|
144 |
if((((DStaticPowerResource*)aStaticResourceArray)->iResourceId & KIdMaskResourceWithDependencies) ||
|
sl@0
|
145 |
(((DStaticPowerResource*)aStaticResourceArray)->iResourceId & KIdMaskDynamic))
|
sl@0
|
146 |
{
|
sl@0
|
147 |
return KErrNotSupported;
|
sl@0
|
148 |
}
|
sl@0
|
149 |
}
|
sl@0
|
150 |
else
|
sl@0
|
151 |
{
|
sl@0
|
152 |
for(TUint rescount = 0; rescount < aResCount; rescount++)
|
sl@0
|
153 |
{
|
sl@0
|
154 |
if(aStaticResourceArray[rescount] && ((aStaticResourceArray[rescount]->iResourceId & KIdMaskResourceWithDependencies) ||
|
sl@0
|
155 |
(aStaticResourceArray[rescount]->iResourceId & KIdMaskDynamic)))
|
sl@0
|
156 |
{
|
sl@0
|
157 |
return KErrNotSupported;
|
sl@0
|
158 |
}
|
sl@0
|
159 |
}
|
sl@0
|
160 |
}
|
sl@0
|
161 |
#endif
|
sl@0
|
162 |
SPowerResourceClient* pC = pRC->iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)];
|
sl@0
|
163 |
if(!pC)
|
sl@0
|
164 |
{
|
sl@0
|
165 |
__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found"));
|
sl@0
|
166 |
return KErrAccessDenied;
|
sl@0
|
167 |
}
|
sl@0
|
168 |
if(pC->iClientId != aClientId)
|
sl@0
|
169 |
{
|
sl@0
|
170 |
__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID instance count does not match"));
|
sl@0
|
171 |
return KErrAccessDenied;
|
sl@0
|
172 |
}
|
sl@0
|
173 |
if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK)
|
sl@0
|
174 |
{
|
sl@0
|
175 |
if(pC->iThreadId != thread.iId)
|
sl@0
|
176 |
{
|
sl@0
|
177 |
__KTRACE_OPT(KRESMANAGER, Kern::Printf("Client not called from thread context(Thread Relative)"));
|
sl@0
|
178 |
return KErrAccessDenied;
|
sl@0
|
179 |
}
|
sl@0
|
180 |
}
|
sl@0
|
181 |
|
sl@0
|
182 |
TInt r = Kern::SafeReAlloc((TAny*&)pRC->iStaticResourceArray, pRC->iStaticResourceArrayEntries*sizeof(DStaticPowerResource*),
|
sl@0
|
183 |
(pRC->iStaticResourceArrayEntries + aResCount)*sizeof(DStaticPowerResource*));
|
sl@0
|
184 |
if(r != KErrNone)
|
sl@0
|
185 |
{
|
sl@0
|
186 |
return r;
|
sl@0
|
187 |
}
|
sl@0
|
188 |
if(aResCount == 1)
|
sl@0
|
189 |
{
|
sl@0
|
190 |
pRC->iStaticResourceArray[pRC->iStaticResourceArrayEntries++] = (DStaticPowerResource*)aStaticResourceArray;
|
sl@0
|
191 |
if((DStaticPowerResource*)aStaticResourceArray)
|
sl@0
|
192 |
pRC->iStaticResourceCount++;
|
sl@0
|
193 |
}
|
sl@0
|
194 |
else
|
sl@0
|
195 |
{
|
sl@0
|
196 |
for(TUint count = 0; count < aResCount; count++)
|
sl@0
|
197 |
{
|
sl@0
|
198 |
pRC->iStaticResourceArray[pRC->iStaticResourceArrayEntries++] = aStaticResourceArray[count];
|
sl@0
|
199 |
if(aStaticResourceArray[count])
|
sl@0
|
200 |
pRC->iStaticResourceCount++;
|
sl@0
|
201 |
}
|
sl@0
|
202 |
}
|
sl@0
|
203 |
return KErrNone;
|
sl@0
|
204 |
}
|
sl@0
|
205 |
|
sl@0
|
206 |
/**
|
sl@0
|
207 |
@publishedPartner
|
sl@0
|
208 |
@prototype 9.5
|
sl@0
|
209 |
Kernel extensions or variants can call this API to register the static resources before resource controller
|
sl@0
|
210 |
is fully initialized.
|
sl@0
|
211 |
@Param aClientId ID of the client that is requesting resource registration
|
sl@0
|
212 |
@Param pR Static resource to register with RC.
|
sl@0
|
213 |
@return KErrNone, if operation is success
|
sl@0
|
214 |
KErrAccessDenied if clientId could not be found in the current list of registered clients or if this
|
sl@0
|
215 |
client was registered as thread relative and was not called from the same thread.
|
sl@0
|
216 |
KErrNotSupported if called after resource controller is fully initialized or if called from user side proxy
|
sl@0
|
217 |
or if the resource is dynamic or dependency resource
|
sl@0
|
218 |
KErrNoMemory if there is insufficient memory.
|
sl@0
|
219 |
KErrArgument if passed array is null
|
sl@0
|
220 |
*/
|
sl@0
|
221 |
EXPORT_C TInt DPowerResourceController::RegisterStaticResource(TUint aClientId, DStaticPowerResource* pR)
|
sl@0
|
222 |
{
|
sl@0
|
223 |
return RegisterArrayOfStaticResources(aClientId, (DStaticPowerResource**&)pR, 1);
|
sl@0
|
224 |
}
|
sl@0
|
225 |
|
sl@0
|
226 |
/**
|
sl@0
|
227 |
@publishedPartner
|
sl@0
|
228 |
@prototype 9.5
|
sl@0
|
229 |
This function initialises the controller.
|
sl@0
|
230 |
@return KErrNone, if operation is success or one of the system wide errors.
|
sl@0
|
231 |
*/
|
sl@0
|
232 |
EXPORT_C TInt DPowerResourceController::InitController()
|
sl@0
|
233 |
{
|
sl@0
|
234 |
__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DPowerResourceController::InitController()"));
|
sl@0
|
235 |
DPowerResourceController* pRC = TInterface::GetPowerResourceController();
|
sl@0
|
236 |
if(!pRC)
|
sl@0
|
237 |
return KErrNotFound;
|
sl@0
|
238 |
if(pRC->iInitialised >= EResConInitialised)
|
sl@0
|
239 |
{
|
sl@0
|
240 |
__KTRACE_OPT(KRESMANAGER, Kern::Printf("InitController already initialised %d\n", pRC->iInitialised));
|
sl@0
|
241 |
return KErrNone;
|
sl@0
|
242 |
}
|
sl@0
|
243 |
_LIT(KResMutexName, "RESCTRL");
|
sl@0
|
244 |
TInt r=KErrNone;
|
sl@0
|
245 |
//Create the message queue
|
sl@0
|
246 |
pRC->iMsgQ = new TMessageQue(DPowerResourceController::MsgQFunc, pRC, NULL, 2);
|
sl@0
|
247 |
if(!pRC->iMsgQ)
|
sl@0
|
248 |
return KErrNoMemory;
|
sl@0
|
249 |
#ifdef PRM_ENABLE_EXTENDED_VERSION
|
sl@0
|
250 |
//Create the message queue for dependency resource processing.
|
sl@0
|
251 |
pRC->iMsgQDependency = new TMessageQue(DPowerResourceController::MsgQDependencyFunc, pRC, NULL, 1);
|
sl@0
|
252 |
if(!pRC->iMsgQDependency)
|
sl@0
|
253 |
return KErrNoMemory;
|
sl@0
|
254 |
#endif
|
sl@0
|
255 |
// Call PSL to create all static resources and populate the iStaticResourceArray with pointers to resources and
|
sl@0
|
256 |
// update static resource count
|
sl@0
|
257 |
r=pRC->DoRegisterStaticResources(pRC->iStaticResourceArray, pRC->iStaticResourceArrayEntries);
|
sl@0
|
258 |
if(r!=KErrNone)
|
sl@0
|
259 |
return r;
|
sl@0
|
260 |
//Get the actual number of static resource registered count
|
sl@0
|
261 |
for(TInt resCnt = 0; resCnt < pRC->iStaticResourceArrayEntries; resCnt++)
|
sl@0
|
262 |
{
|
sl@0
|
263 |
if(pRC->iStaticResourceArray[resCnt])
|
sl@0
|
264 |
pRC->iStaticResourceCount++;
|
sl@0
|
265 |
}
|
sl@0
|
266 |
__KTRACE_OPT(KRESMANAGER, Kern::Printf("Actual number of static resource registered = %d\n", pRC->iStaticResourceCount));
|
sl@0
|
267 |
#ifdef PRM_INSTRUMENTATION_MACRO
|
sl@0
|
268 |
// Btrace output of resource information of each resource.
|
sl@0
|
269 |
DStaticPowerResource* pR = NULL;
|
sl@0
|
270 |
TPowerResourceInfoBuf01 resInfo;
|
sl@0
|
271 |
TPowerResourceInfoV01 *pResInfo;
|
sl@0
|
272 |
for(TInt resCount = 0; resCount < pRC->iStaticResourceArrayEntries; resCount++)
|
sl@0
|
273 |
{
|
sl@0
|
274 |
pR = pRC->iStaticResourceArray[resCount];
|
sl@0
|
275 |
if(!pR)
|
sl@0
|
276 |
continue;
|
sl@0
|
277 |
pR->GetInfo((TDes8*)resInfo.Ptr());
|
sl@0
|
278 |
pResInfo = (TPowerResourceInfoV01*)resInfo.Ptr();
|
sl@0
|
279 |
PRM_REGISTER_RESOURCE_TRACE
|
sl@0
|
280 |
}
|
sl@0
|
281 |
#endif
|
sl@0
|
282 |
|
sl@0
|
283 |
#ifdef PRM_ENABLE_EXTENDED_VERSION
|
sl@0
|
284 |
//Call PSL to register static resources with dependency if any exists
|
sl@0
|
285 |
r = pRC->DoRegisterStaticResourcesDependency(pRC->iStaticResDependencyArray, pRC->iStaticResDependencyCount);
|
sl@0
|
286 |
if(r != KErrNone)
|
sl@0
|
287 |
return r;
|
sl@0
|
288 |
if(pRC->iStaticResDependencyCount)
|
sl@0
|
289 |
{
|
sl@0
|
290 |
DStaticPowerResourceD* pRD = NULL;
|
sl@0
|
291 |
TUint count;
|
sl@0
|
292 |
//Assign resource index in resource id
|
sl@0
|
293 |
for(count = 0; count < pRC->iStaticResDependencyCount; count++)
|
sl@0
|
294 |
{
|
sl@0
|
295 |
pRD = pRC->iStaticResDependencyArray[count];
|
sl@0
|
296 |
if(!pRD)
|
sl@0
|
297 |
Panic(DPowerResourceController::ERegisteringDependentStaticResourceWithHoles);
|
sl@0
|
298 |
pRD->iResourceId |= ((count + 1) & ID_INDEX_BIT_MASK);
|
sl@0
|
299 |
}
|
sl@0
|
300 |
//Check for dependency closed loops
|
sl@0
|
301 |
for(count = 0; count < pRC->iStaticResDependencyCount; count++)
|
sl@0
|
302 |
{
|
sl@0
|
303 |
pRD = pRC->iStaticResDependencyArray[count];
|
sl@0
|
304 |
if(!(pRD->iResourceId & KIdMaskStaticWithDependencies))
|
sl@0
|
305 |
Panic(DPowerResourceController::ERegisteringNonDependentStaticResource);
|
sl@0
|
306 |
//Upgrade latency state change from instantaneous to long latency
|
sl@0
|
307 |
if(!pRD->LatencySet())
|
sl@0
|
308 |
pRD->iFlags |= KLongLatencySet;
|
sl@0
|
309 |
pRC->CheckForDependencyLoop(pRD, pRD->iResourceId, pRD->iResourceId);
|
sl@0
|
310 |
}
|
sl@0
|
311 |
#ifdef PRM_INSTRUMENTATION_MACRO
|
sl@0
|
312 |
for(count = 0; count < pRC->iStaticResDependencyCount; count++)
|
sl@0
|
313 |
{
|
sl@0
|
314 |
pR = pRC->iStaticResDependencyArray[count];
|
sl@0
|
315 |
pR->GetInfo((TDes8*)resInfo.Ptr());
|
sl@0
|
316 |
pResInfo = (TPowerResourceInfoV01*)resInfo.Ptr();
|
sl@0
|
317 |
PRM_REGISTER_STATIC_RESOURCE_WITH_DEPENDENCY_TRACE
|
sl@0
|
318 |
}
|
sl@0
|
319 |
#endif
|
sl@0
|
320 |
}
|
sl@0
|
321 |
#endif // PRM_ENABLE_EXTENDED_VERSION
|
sl@0
|
322 |
// Create mutex object
|
sl@0
|
323 |
r=Kern::MutexCreate(pRC->iResourceMutex, KResMutexName, KMutexOrdResourceManager);
|
sl@0
|
324 |
if(r==KErrNone) // Call PSL to create DFC queue and creation of pools with the help API's provided by generic layer.
|
sl@0
|
325 |
r=pRC->DoInitController();
|
sl@0
|
326 |
__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DPowerResourceController::InitController()"));
|
sl@0
|
327 |
if(r == KErrNone)
|
sl@0
|
328 |
{
|
sl@0
|
329 |
pRC->iInitialised = EResConInitialised;
|
sl@0
|
330 |
if(pRC->iDfcQ)
|
sl@0
|
331 |
pRC->iMsgQ->Receive();
|
sl@0
|
332 |
#ifdef PRM_ENABLE_EXTENDED_VERSION
|
sl@0
|
333 |
if(pRC->iDfcQDependency)
|
sl@0
|
334 |
pRC->iMsgQDependency->Receive();
|
sl@0
|
335 |
#endif
|
sl@0
|
336 |
}
|
sl@0
|
337 |
return r;
|
sl@0
|
338 |
}
|