Update contrib.
1 // Copyright (c) 1995-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\resmanus\d_resmanus.cpp
18 // LDD for Resource Manager user side API
20 #include <kernel/kern_priv.h>
21 #include <kernel/kernel.h>
25 #include <e32cmn_private.h>
26 #include <e32def_private.h>
27 #include <drivers/resource_extend.h>
29 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
30 #include "rescontrol_psl.h"
33 #ifdef PRM_US_INSTRUMENTATION_MACRO
34 #include <drivers/resmanus_trace.h>
37 #ifdef PRM_ENABLE_EXTENDED_VERSION2
38 _LIT(KResManUsThreadName,"ResManUsExtendedCoreLddThread");
39 #elif defined (PRM_ENABLE_EXTENDED_VERSION)
40 _LIT(KResManUsThreadName,"ResManUsExtendedLddThread");
42 _LIT(KResManUsThreadName,"ResManUsLddThread");
45 #define RESMANUS_FAULT() Kern::Fault("RESMANUS",__LINE__)
47 const TInt KResManUsThreadPriority = 24;
48 const TInt KResManUsRegistrationPriority = 5; // Arbitrary! Can be 0-7, 7 is highest
49 const TInt KResManCallBackPriority = 5; // Arbitrary! Can be 0-7, 7 is highest
51 //Macro to return appropriate request type.
52 #define GET_USER_REQUEST(request, buffer, type) \
54 if(type == EGetState) \
55 request = ((TTrackGetStateBuf*)buffer)->iRequest; \
56 else if(type == ESetState) \
57 request = ((TTrackSetStateBuf*)buffer)->iRequest; \
59 request = ((TTrackNotifyBuf*)buffer)->iRequest; \
62 /***************************************************************************************
63 class TTrackGetStateBuf
64 ***************************************************************************************/
65 TTrackGetStateBuf::TTrackGetStateBuf(TPowerResourceCbFn aFn, TAny* aPtr,
66 TDfcQue* aQue, TInt aPriority)
67 : iCtrlBlock(aFn, aPtr, aQue, aPriority)
72 /***************************************************************************************
73 class TTrackSetStateBuf
74 ***************************************************************************************/
75 TTrackSetStateBuf::TTrackSetStateBuf(TPowerResourceCbFn aFn, TAny* aPtr,
76 TDfcQue* aQue, TInt aPriority)
77 : iCtrlBlock(aFn, aPtr, aQue, aPriority)
82 /***************************************************************************************
84 ***************************************************************************************/
85 TTrackNotifyBuf::TTrackNotifyBuf(TPowerResourceCbFn aFn, TAny* aPtr,
86 TDfcQue* aQue, TInt aPriority)
87 : iNotifyBlock(aFn, aPtr, aQue, aPriority)
92 TTrackNotifyBuf::~TTrackNotifyBuf()
95 Kern::DestroyClientRequest(iRequest);
98 TTrackSetStateBuf::~TTrackSetStateBuf()
101 Kern::DestroyClientRequest(iRequest);
104 TTrackGetStateBuf::~TTrackGetStateBuf()
107 Kern::DestroyClientRequest(iRequest);
110 /***************************************************************************************
111 class DDeviceResManUs
112 ***************************************************************************************/
113 DDeviceResManUs::DDeviceResManUs()
116 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::DDeviceResManUs()"));
117 iParseMask=KDeviceAllowAll&~KDeviceAllowUnit; // Allow info and pdd, but not units
119 iVersion=TVersion(KResManUsMajorVersionNumber,
120 KResManUsMinorVersionNumber,
121 KResManUsBuildVersionNumber);
124 DDeviceResManUs::~DDeviceResManUs()
127 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::~DDeviceResManUs()"));
128 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
129 iSharedDfcQue->Destroy();
131 delete iSharedDfcQue;
135 TInt DDeviceResManUs::Install()
136 // Install the device driver.
138 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::Install()"));
139 // Create the message queue and initialise the DFC queue pointer
140 #ifndef RESOURCE_MANAGER_SIMULATED_PSL
141 TInt r=Kern::DfcQInit(iSharedDfcQue,KResManUsThreadPriority,&KResManUsThreadName);
143 TInt r = Kern::DynamicDfcQCreate(iSharedDfcQue,KResManUsThreadPriority,KResManUsThreadName);
145 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DfcQCreate r = %d", r));
149 #ifdef CPU_AFFINITY_ANY
150 NKern::ThreadSetCpuAffinity((NThread*)(iSharedDfcQue->iThread), KCpuAffinityAny);
152 r = SetName(&KLddRootName);
153 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> SetName, r = %d", r));
158 void DDeviceResManUs::GetCaps(TDes8& aDes) const
159 // Return the ResManUs capabilities.
161 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::GetCaps(TDes8& aDes) const"));
162 TPckgBuf<TCapsDevResManUs> b;
163 b().version=TVersion(KResManUsMajorVersionNumber,
164 KResManUsMinorVersionNumber,
165 KResManUsBuildVersionNumber);
166 Kern::InfoCopy(aDes,b);
170 TInt DDeviceResManUs::Create(DLogicalChannelBase*& aChannel)
171 // Create a channel on the device.
173 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::Create(DLogicalChannelBase*& aChannel)"));
174 if(iOpenChannels>=KMaxNumChannels)
176 aChannel=new DChannelResManUs;
177 return aChannel?KErrNone:KErrNoMemory;
181 /***************************************************************************************
182 class DChannelResManUs
183 ***************************************************************************************/
184 DChannelResManUs::DChannelResManUs()
187 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DChannelResManUs()"));
188 iClient=&Kern::CurrentThread();
189 // Increase the DThread's ref count so that it does not close without us
194 DChannelResManUs::~DChannelResManUs()
197 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::~DChannelResManUs()"));
199 // Cancel any outstanding requests
201 // For each tracker (Get, Set and notify)
203 if(iGetStateTracker != NULL)
205 CancelTrackerRequests(iGetStateTracker,EFalse,0,NULL); // EFalse,0, to ignore resource IDs
206 RemoveTrackingControl(iGetStateTracker);
208 if(iSetStateTracker != NULL)
210 CancelTrackerRequests(iSetStateTracker,EFalse,0,NULL); // EFalse,0, to ignore resource IDs
211 RemoveTrackingControl(iSetStateTracker);
213 if(iListenableTracker != NULL)
215 CancelTrackerRequests(iListenableTracker,EFalse,0,NULL); // EFalse,0, to ignore resource IDs
216 RemoveTrackingControl(iListenableTracker);
219 delete iUserNameUsed;
220 delete iResourceDependencyIds;
221 delete iClientNamesResCtrl;
222 delete iResourceInfoResCtrl;
224 // decrement the DThread's reference count
225 Kern::SafeClose((DObject*&)iClient, NULL);
229 static void AsyncCallBackFn(TUint aClient, TUint aResourceId, TInt aLevel, TInt aLevelOwnerId, TInt aResult, TAny* aTrackingBuffer)
231 // Callback function for asynchronous requests
232 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> AsyncCallBackFn aClient=0x%x aResourceId=0x%x, aLevel=0x%x, aResult=0x%x, aTrackingBuffer=0x%x\n",aClient, aResourceId, aLevel, aResult, aTrackingBuffer));
233 TTrackingBuffer* buffer = ((TTrackingBuffer*)aTrackingBuffer);
234 TTrackingControl* tracker = buffer->GetTrackingControl();
235 __ASSERT_ALWAYS((tracker!=NULL),RESMANUS_FAULT());
236 DChannelResManUs* channel = tracker->iOwningChannel;
238 #ifdef PRM_US_INSTRUMENTATION_MACRO
239 if(tracker->iType==EGetState)
241 PRM_US_GET_RESOURCE_STATE_END_TRACE;
243 else if(tracker->iType==ESetState)
245 PRM_US_SET_RESOURCE_STATE_END_TRACE;
248 if(tracker->iType == EGetState)
250 TTrackGetStateBuf* stateBuf = (TTrackGetStateBuf*)aTrackingBuffer;
251 if(aResult==KErrNone)
253 // Write the state value to the user-supplied variable
254 stateBuf->iRequest->Data1() = aLevel;
255 stateBuf->iRequest->Data2() = aLevelOwnerId;
257 Kern::QueueRequestComplete(channel->iClient, ((TTrackGetStateBuf*)buffer)->iRequest, aResult);
259 else if(tracker->iType == ESetState)
261 Kern::QueueRequestComplete(channel->iClient, ((TTrackSetStateBuf*)buffer)->iRequest, aResult);
263 // Once notified of a change in a resource state, must cancel the notification
264 // request in the Resource Controller to give the client the appearance of a
265 // 'one'shot' type of operation.
266 else if(tracker->iType==ENotify)
268 #ifdef PRM_ENABLE_EXTENDED_VERSION
269 if(((TInt)aClient==KDynamicResourceDeRegistering)&&(aResourceId&KIdMaskDynamic))
271 // Resource has de-registered from Resource Controller, so can't expect any more notifications
272 // of this type. Cancellation of notifications (i.e. invoke Resource Controller) and transfer of
273 // buffers to free queue (for both conditional and unconditional notifications) is already done.
274 // To distinguish removal of a dynamic resource, hijack aResult (the value used when completing
275 // the user-side TRequestStatus object) and set it to KErrDisconnected.
276 aResult = KErrDisconnected;
280 TInt r = (channel->iPddPtr)->CancelNotification(channel->ClientHandle(),aResourceId,
281 ((TTrackNotifyBuf*)buffer)->iNotifyBlock);
282 __ASSERT_ALWAYS((r == KErrCancel),RESMANUS_FAULT());
283 Kern::QueueRequestComplete(channel->iClient, ((TTrackNotifyBuf*)buffer)->iRequest, aResult);
286 // Return the tracking buffer to the free queue
287 channel->FreeTrackingBuffer(buffer);
290 TInt DChannelResManUs::GetValidName(const TDesC8* aInfo)
292 // Extract a usable name from that supplied by the client
293 __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::GetValidName"));
297 DThread* thread = &Kern::CurrentThread();
298 TInt nameLen = Kern::ThreadGetDesLength(thread, aInfo);
300 return nameLen; // return error code
301 iNameProvidedLength = nameLen;
302 if(nameLen > MAX_CLIENT_NAME_LENGTH)
306 nameLen = (nameLen<=MAX_NAME_LENGTH_IN_RESMAN) ? nameLen : MAX_NAME_LENGTH_IN_RESMAN;
307 if((iUserNameUsed = HBuf8::New(nameLen))==NULL)
309 err = Kern::ThreadDesRead(thread,aInfo,*iUserNameUsed,0);
319 TInt DChannelResManUs::RequestUserHandle(DThread* aThread, TOwnerType aType)
320 // Called when a user thread requests a handle to this channel
322 // Make sure that only our client can get a handle
323 __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::RequestUserHandle"));
324 if (aType!=EOwnerThread || aThread!=iClient)
325 return KErrAccessDenied;
329 void DChannelResManUs::RegistrationDfcFunc(TAny* aChannel)
331 __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::RegistrationDfcFunc"));
332 // DFC function invoked for registration with Resource Controller
333 DChannelResManUs* channel = (DChannelResManUs*)aChannel;
334 // RegisterProxyClient(TUint& aProxyId, const TDesC& aName);
337 __ASSERT_ALWAYS((r==KErrNone),RESMANUS_FAULT());
339 r=(channel->iPddPtr)->RegisterProxyClient(uintVal,*((TDesC8*)(channel->iUserNameUsed)));
342 // Registration failed
343 // Ensure that the client-side flag is cleared in uintVal
344 // so the failure can be detected in DoCreate
345 uintVal &= ~USER_SIDE_CLIENT_BIT_MASK; // Copied from rescontrol_export
347 channel->SetClientHandle((TInt)uintVal);
348 NKern::FSSignal(channel->iFastSem);
352 TInt DChannelResManUs::RegisterWithResCtrlr()
354 __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::RegisterWithResCtrlr"));
356 // Initialise the channel's fast semaphore
357 iFastSem = new NFastSemaphore();
362 iFastSem->iOwningThread = (NThreadBase*)NKern::CurrentThread();
364 // Attempt to perform registration with the Resource Controller on behalf of the client.
365 SetDfcQ(((DDeviceResManUs*)(iDevice))->iSharedDfcQue);
366 TDfc tempDfc(RegistrationDfcFunc, this, iDfcQ, KResManUsRegistrationPriority);
368 // Block this thread until the DFC has executed
370 NKern::FSWait(iFastSem);
371 // Have finished with iFastSem
374 // Registration complete - check success
375 if(!(USER_SIDE_CLIENT_BIT_MASK & ClientHandle()))
377 // Registration failed
378 r = KErrCouldNotConnect;
380 // Start receiving messages ...
386 TInt DChannelResManUs::DoCreate(TInt /*aUnit*/,
388 const TVersion &aVer)
389 // Create the channel from the passed info.
391 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer)"));
394 iPddPtr = ((DUserSideProxyInterface*)iPdd)->iController;
395 // Check client has appropriate capabilities
396 if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by DDevicePowerRsrc::Create")))
397 return KErrPermissionDenied;
399 // Check software version
400 if (!Kern::QueryVersionSupported(TVersion(KResManUsMajorVersionNumber,
401 KResManUsMinorVersionNumber,
402 KResManUsBuildVersionNumber),
404 return KErrNotSupported;
406 // Implementation note: if this method fails, the destructor will be invoked
407 // as part of which all successfully-allocated memory will be freed. Therefore,
408 // no memory will be explicitly freed in the event of failure in the code which follows.
410 // Allocate the arrays used for acquiring client, resource and dependency information
411 if((iClientNamesResCtrl = HBuf8::New(KNumClientNamesResCtrl * sizeof(TPowerClientInfoV01)))==NULL)
413 if((iResourceInfoResCtrl = HBuf8::New(KNumResourceInfoResCtrl * sizeof(TPowerResourceInfoV01)))==NULL)
415 if((iResourceDependencyIds = HBuf8::New(KNumResourceDependencies * sizeof(SResourceDependencyInfo)))==NULL)
417 // Obtain the channel name to use
418 if((r=GetValidName(aInfo))!=KErrNone)
420 #ifdef PRM_ENABLE_EXTENDED_VERSION
424 #ifdef PRM_US_INSTRUMENTATION_MACRO
425 PRM_US_OPEN_CHANNEL_START_TRACE;
428 // Set up the request tracking support
429 iGetStateTracker = new TTrackingControl();
430 iSetStateTracker = new TTrackingControl();;
431 iListenableTracker = new TTrackingControl();
432 if((iGetStateTracker==NULL) || (iSetStateTracker==NULL) || (iListenableTracker==NULL))
435 // Register with the Resource Controller
436 r = RegisterWithResCtrlr();
438 #ifdef PRM_US_INSTRUMENTATION_MACRO
439 PRM_US_OPEN_CHANNEL_END_TRACE;
445 //Override sendMsg to allow data copy in the context of client thread for WDP.
446 TInt DChannelResManUs::SendMsg(TMessageBase* aMsg)
448 TThreadMessage& m = *(TThreadMessage*)aMsg;
451 if (id != (TInt)ECloseMsg && id != KMaxTInt)
455 TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
456 r = SendRequest(aMsg);
458 Kern::RequestComplete(pS,r);
461 r = SendControl(aMsg);
464 r = DLogicalChannel::SendMsg(aMsg);
468 TInt DChannelResManUs::SendRequest(TMessageBase* aMsg)
470 TThreadMessage& m = *(TThreadMessage*)aMsg;
472 TRequestStatus* pS = (TRequestStatus*)m.Ptr0();
474 TTrackingBuffer *trackBuf = NULL;
476 TPowerResourceCb *callBack;
477 DPowerResourceNotification *prn;
481 case RBusDevResManUs::EChangeResourceState:
483 __ASSERT_ALWAYS(m.Ptr2() != NULL, RESMANUS_FAULT());
484 #ifdef _DUMP_TRACKERS
485 if((r=DumpTracker(iSetStateTracker))!=KErrNone)
488 r = GetAndInitTrackingBuffer(iSetStateTracker, trackBuf, (TUint)m.Ptr1(), pS);
491 callBack = &(((TTrackSetStateBuf*)trackBuf)->iCtrlBlock);
492 new (callBack) TPowerResourceCb(&AsyncCallBackFn, (TAny*)trackBuf, iDfcQ, KResManCallBackPriority);
493 parms[0] = (TUint)m.Ptr2();
494 parms[1] = (TUint)callBack;
495 m.iArg[2] = &(parms[0]);
498 case RBusDevResManUs::EGetResourceState:
500 __ASSERT_ALWAYS(m.Ptr2() != NULL, RESMANUS_FAULT());
501 umemget32(&(parms[0]), m.Ptr2(), 3*sizeof(TInt));
502 #ifdef _DUMP_TRACKERS
503 if((r=DumpTracker(iGetStateTracker))!=KErrNone)
506 r = GetStateBuffer(iGetStateTracker, trackBuf, (TUint)m.Ptr1(), (TInt*)parms[1], (TInt*)parms[2], callBack, pS);
509 parms[3] = (TUint)callBack;
510 m.iArg[2] = &(parms[0]);
513 case RBusDevResManUs::ERequestChangeNotification:
515 __ASSERT_ALWAYS(m.Ptr1() != NULL, RESMANUS_FAULT());
516 r = GetAndInitTrackingBuffer(iListenableTracker, trackBuf, (TUint)m.Ptr1(), pS);
519 prn = &(((TTrackNotifyBuf*)trackBuf)->iNotifyBlock);
520 new (prn) DPowerResourceNotification(&AsyncCallBackFn, (TAny*)trackBuf, iDfcQ, KResManCallBackPriority);
521 m.iArg[2] = (TAny*)prn;
524 case RBusDevResManUs::ERequestQualifiedChangeNotification:
526 __ASSERT_ALWAYS(m.Ptr1() != NULL, RESMANUS_FAULT());
527 __ASSERT_ALWAYS(m.Ptr2() != NULL, RESMANUS_FAULT());
528 umemget32(&(parms[0]), m.Ptr2(), 2*sizeof(TUint));
529 m.iArg[2] = &parms[0];
530 r = GetAndInitTrackingBuffer(iListenableTracker, trackBuf, (TUint)parms[0], pS);
533 prn = &(((TTrackNotifyBuf*)trackBuf)->iNotifyBlock);
534 new (prn) DPowerResourceNotification(&AsyncCallBackFn, (TAny*)trackBuf, iDfcQ, KResManCallBackPriority);
535 parms[2] = (TUint)prn;
540 return KErrNotSupported;
545 r = DLogicalChannel::SendMsg(aMsg);
547 FreeTrackingBuffer(trackBuf);
552 TInt DChannelResManUs::SendControl(TMessageBase* aMsg)
554 TThreadMessage& m = *(TThreadMessage*)aMsg;
563 case RBusDevResManUs::EInitialise:
565 __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
567 umemget(&(stateRes[0]), a1, 3*sizeof(TUint8));
568 m.iArg[0] = &(stateRes[0]);
571 case RBusDevResManUs::EGetNoOfResources:
572 case RBusDevResManUs::EGetResourceControllerVersion:
574 __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
578 case RBusDevResManUs::EGetNoOfClients:
579 case RBusDevResManUs::EGetNumClientsUsingResource:
581 __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
582 __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
583 umemget32(&(parms[0]), a2, 3*sizeof(TUint));
584 m.iArg[1] = &(parms[0]);
588 case RBusDevResManUs::EGetNumResourcesInUseByClient:
590 __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
591 __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
592 TBuf8 <MAX_NAME_LENGTH_IN_RESMAN> clientName;
593 Kern::KUDesGet(clientName, *(TDesC8*)m.Ptr0());
594 m.iArg[0] = (TAny*)&clientName;
595 umemget32(&(parms[0]), m.Ptr1(), 2*sizeof(TUint));
600 case RBusDevResManUs::EGetResourceIdByName:
602 __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
603 __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
604 TBuf8 <MAX_NAME_LENGTH_IN_RESMAN> resourceName;
605 Kern::KUDesGet(resourceName, *(TDesC8*)m.Ptr0());
606 m.iArg[0] = (TAny*)&resourceName;
610 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
611 case RBusDevResManUs::EGetNumCandidateAsyncResources:
612 case RBusDevResManUs::EGetNumCandidateSharedResources:
614 __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
618 case RBusDevResManUs::EGetCandidateAsyncResourceId:
619 case RBusDevResManUs::EGetCandidateSharedResourceId:
621 __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
626 case RBusDevResManUs::EGetNumDependentsForResource:
628 __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
629 __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
630 umemget32(&(parms[0]), m.Ptr1(), 2*sizeof(TUint));
631 m.iArg[1] = &(parms[0]);
635 case RBusDevResManUs::EGetDependentsIdForResource:
637 __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
638 __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
639 umemget32(&(parms[0]), m.Ptr1(), 3*sizeof(TUint));
641 ptr1 = (TAny*)parms[1];
642 Kern::KUDesInfo(*(const TDesC8*)parms[1], len, maxLen);
643 umemget32(¶m1, m.Ptr0(), sizeof(TUint));
644 if((maxLen - len) < (TInt)(param1 * sizeof(SResourceDependencyInfo)))
649 m.iArg[1] = &(parms[0]);
652 case RBusDevResManUs::EGetResourceInfo:
654 __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
655 __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
656 TResourceInfoBuf buf;
660 case RBusDevResManUs::EGetAllResourcesInfo:
662 __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
663 __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
664 umemget32(&(parms[0]), m.Ptr1(), 2*sizeof(TUint));
665 ptr1 = (TAny*)parms[0];
666 umemget32(¶m1, (TAny*)parms[0], sizeof(TUint));
667 parms[0] =(TUint)¶m1;
668 RSimplePointerArray<TResourceInfoBuf> infoPtrs;
669 umemget(&infoPtrs, m.Ptr0(), sizeof(RSimplePointerArray<TResourceInfoBuf>));
670 if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
672 m.iArg[1] = &(parms[0]);
675 case RBusDevResManUs::EGetInfoOnClientsUsingResource:
677 __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
678 __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
679 umemget32(&parms[0], m.Ptr1(), 4*sizeof(TUint));
680 ptr1 = (TAny*)parms[0];
681 umemget32(¶m1, (TAny*)parms[0], sizeof(TUint));
682 parms[0] = (TUint)¶m1;
683 RSimplePointerArray<TClientInfoBuf>infoPtrs;
684 umemget(&infoPtrs, m.Ptr0(), sizeof(RSimplePointerArray<TClientInfoBuf>));
685 if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
687 m.iArg[1] = &(parms[0]);
690 case RBusDevResManUs::EGetNamesAllClients:
692 __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
693 __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
694 umemget32(&parms[0], m.Ptr1(), 4*sizeof(TUint));
695 ptr1 = (TAny*)parms[0];
696 umemget32(¶m1, (TAny*)parms[0], sizeof(TUint));
697 parms[0] = (TUint)¶m1;
698 RSimplePointerArray<TClientName> infoPtrs;
699 umemget(&infoPtrs, m.Ptr0(), sizeof(RSimplePointerArray<TClientName>));
700 if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
702 m.iArg[1] = &(parms[0]);
705 case RBusDevResManUs::EGetInfoOnResourcesInUseByClient:
707 __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
708 __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
709 TBuf8 <MAX_NAME_LENGTH_IN_RESMAN> clientName;
710 Kern::KUDesGet(clientName, *(TDesC8*)m.Ptr0());
711 m.iArg[0] = (TAny*)&clientName;
712 umemget32(&parms[0], m.Ptr1(), 3*sizeof(TUint));
713 ptr1 = (TAny*)parms[0];
714 umemget32(¶m1, (TAny*)parms[0], sizeof(TUint));
715 parms[0] = (TUint)¶m1;
716 RSimplePointerArray<TResourceInfoBuf> infoPtrs;
717 umemget(&infoPtrs, (TAny*)parms[1], sizeof(RSimplePointerArray<TResourceInfoBuf>));
718 if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
720 m.iArg[1] = &(parms[0]);
725 TInt r = DLogicalChannel::SendMsg(aMsg);
731 case RBusDevResManUs::EGetNoOfResources:
732 case RBusDevResManUs::EGetNoOfClients:
733 case RBusDevResManUs::EGetNumClientsUsingResource:
734 case RBusDevResManUs::EGetResourceControllerVersion:
735 case RBusDevResManUs::EGetNumDependentsForResource:
737 umemput32(a1, (TAny*)¶m1, sizeof(TUint));
740 case RBusDevResManUs::EGetNumResourcesInUseByClient:
742 umemput32((TAny*)parms[0], (TAny*)¶m1, sizeof(TUint));
745 case RBusDevResManUs::EGetResourceIdByName:
747 umemput32(a2, (TAny*)¶m1, sizeof(TUint));
750 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
751 case RBusDevResManUs::EGetNumCandidateAsyncResources:
752 case RBusDevResManUs::EGetNumCandidateSharedResources:
754 umemput32(a1, (TAny*)¶m1, sizeof(TUint));
757 case RBusDevResManUs::EGetCandidateAsyncResourceId:
758 case RBusDevResManUs::EGetCandidateSharedResourceId:
760 umemput32(a2, (TAny*)¶m1, sizeof(TUint));
764 case RBusDevResManUs::EGetDependentsIdForResource:
766 r = Kern::ThreadDesWrite(iClient,(TAny*)ptr1, (const TDesC8&)*(SResourceDependencyInfo*)parms[1], 0);
767 if(r == KErrOverflow) //This is done to retain the error as per API spec
771 case RBusDevResManUs::EGetResourceInfo:
773 Kern::KUDesPut(*(TDes8*)a2, (const TDesC8&)*(TResourceInfoBuf*)m.Ptr1());
776 case RBusDevResManUs::EGetAllResourcesInfo:
779 RSimplePointerArray<TResourceInfoBuf> infoPtrs;
780 umemget(&infoPtrs, a1, sizeof(RSimplePointerArray<TResourceInfoBuf>));
781 numToCopy = (infoPtrs.Count() < param1) ? infoPtrs.Count() : param1;
782 umemput32(ptr1, (TAny*)¶m1, sizeof(TUint));
783 TResourceInfoBuf** entriesAddr = infoPtrs.Entries();
784 TInt* entryPtr = (TInt*)entriesAddr;
785 TPowerResourceInfoV01 *currRes = (TPowerResourceInfoV01*)iResourceInfoResCtrl->Ptr();
786 TResourceInfoBuf* clientAddr;
787 TResourceInfoBuf tempInfo;
788 for(TUint index = 0; index < numToCopy; index++)
790 umemget32(&clientAddr, entryPtr, sizeof(TResourceInfoBuf*));
792 r = ExtractResourceInfo(currRes, tempInfo);
795 umemput((TAny*)clientAddr, (TAny*)&(tempInfo), tempInfo.Length());
800 case RBusDevResManUs::EGetInfoOnClientsUsingResource:
803 RSimplePointerArray<TClientInfoBuf> infoPtrs;
804 umemget(&infoPtrs, a1, sizeof(RSimplePointerArray<TClientName>));
805 numToCopy = infoPtrs.Count();
806 TClientInfoBuf** entriesAddr = infoPtrs.Entries();
807 TInt* entryPtr = (TInt*)entriesAddr;
808 TPowerClientInfoV01* rcDataPtr = (TPowerClientInfoV01*)iClientNamesResCtrl->Ptr();
809 TClientInfoBuf* clientAddr;
810 TUint userSideClients = 0;
811 TClientInfoBuf tempInfo;
812 for(TInt index = 0; index < param1; index++)
814 if((!parms[1]) && !(rcDataPtr->iClientId & USER_SIDE_CLIENT_BIT_MASK))
824 umemget32(&clientAddr, entryPtr, sizeof(TClientName*));
826 tempInfo().iId = rcDataPtr->iClientId;
827 tempInfo().iName = *rcDataPtr->iClientName;
828 Kern::InfoCopy(*clientAddr, tempInfo);
834 umemput32(ptr1, (TAny*)¶m1, sizeof(TUint));
836 umemput32(ptr1, (TAny*)&userSideClients, sizeof(TUint));
839 case RBusDevResManUs::EGetNamesAllClients:
842 RSimplePointerArray<TClientName> infoPtrs;
843 umemget(&infoPtrs, a1, sizeof(RSimplePointerArray<TClientName>));
844 numToCopy = infoPtrs.Count();
845 TClientName** entriesAddr = infoPtrs.Entries();
846 TInt* entryPtr = (TInt*)entriesAddr;
847 TPowerClientInfoV01* rcDataPtr = (TPowerClientInfoV01*)iClientNamesResCtrl->Ptr();
848 TClientName* clientAddr;
849 TUint userSideClients = 0;
850 for(TInt index = 0; index < param1; index++)
852 if((!parms[1]) && !(rcDataPtr->iClientId & USER_SIDE_CLIENT_BIT_MASK))
862 umemget32(&clientAddr, entryPtr, sizeof(TClientName*));
864 Kern::KUDesPut(*((TDes8*)clientAddr), *(const TDesC8*)rcDataPtr->iClientName);
870 umemput32(ptr1, (TAny*)¶m1, sizeof(TUint));
872 umemput32(ptr1, (TAny*)&userSideClients, sizeof(TUint));
875 case RBusDevResManUs::EGetInfoOnResourcesInUseByClient:
878 RSimplePointerArray<TResourceInfoBuf> infoPtrs;
879 umemget(&infoPtrs, (TAny*)parms[1], sizeof(RSimplePointerArray<TResourceInfoBuf>));
880 numToCopy = (infoPtrs.Count() < param1) ? infoPtrs.Count() : param1;
881 umemput32(ptr1, (TAny*)¶m1, sizeof(TUint));
882 TResourceInfoBuf** entriesAddr = infoPtrs.Entries();
883 TInt* entryPtr = (TInt*)entriesAddr;
884 TPowerResourceInfoV01* currRes = (TPowerResourceInfoV01*)iResourceInfoResCtrl->Ptr();
885 TResourceInfoBuf* clientAddr;
886 TResourceInfoBuf tempInfo;
887 for(TUint index = 0; index < numToCopy; index++)
889 umemget32(&clientAddr, entryPtr, sizeof(TResourceInfoBuf*));
891 r = ExtractResourceInfo(currRes, tempInfo);
894 umemput((TAny*)clientAddr, (TAny*)&(tempInfo), tempInfo.Length());
903 void DChannelResManUs::HandleMsg(TMessageBase* aMsg)
905 TThreadMessage& m=*(TThreadMessage*)aMsg;
908 __KTRACE_OPT(KRESMANAGER, Kern::Printf(" >ldd: DChannelResManUs::HandleMsg(TMessageBase* aMsg) id=%d\n", id));
910 if (id==(TInt)ECloseMsg)
912 // Deregister here to ensure the correct thread ID is read
913 if(ClientHandle() != 0)
915 // Must de-register from Resource Controller before closing down
916 // Not checking return value - still need to delete allocated buffers
917 #ifdef PRM_US_INSTRUMENTATION_MACRO
918 PRM_US_DEREGISTER_CLIENT_START_TRACE;
920 ((DPowerResourceController*)iPddPtr)->DeregisterProxyClient(ClientHandle());
922 #ifdef PRM_US_INSTRUMENTATION_MACRO
923 PRM_US_DEREGISTER_CLIENT_END_TRACE;
927 iMsgQ.iMessage->Complete(KErrNone,EFalse);
930 else if (id==KMaxTInt)
934 m.Complete(KErrNone,ETrue);
941 TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
942 TInt r=DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
948 __KTRACE_OPT(KRESMANAGER, Kern::Printf(" >ldd: do control id=%d...\n", id));
949 TInt r=DoControl(id,m.Ptr0(),m.Ptr1());
954 TInt DChannelResManUs::CancelTrackerRequests(TTrackingControl* aTracker, TBool aSingleRsrc, TUint aResourceId, TRequestStatus* aStatus)
956 // Cancel all outstanding requests from this client for a specified operation on
957 // a specified resource
959 // Loop all entries in the iBusyQue of requests to locate a match for the
960 // operation type and resource ID
962 // For each match, remove the buffer from the busy queue and return to the free queue
963 // If the request is already being processed, and so the callback function will be called
964 // later, then the callback will exit gracefully.
966 __KTRACE_OPT(KRESMANAGER, Kern::Printf(" > DChannelResManUs::CancelTrackerRequests"));
967 TInt returnVal = KErrNone;
968 TBool statusMatched=EFalse;
969 TTrackingBuffer* firstLink = NULL;
970 TTrackingBuffer* lastLink = NULL;
971 TInt type = aTracker->iType;
973 #ifdef PRM_US_INSTRUMENTATION_MACRO
976 PRM_US_CANCEL_GET_RESOURCE_STATE_START_TRACE;
978 else if(type==ESetState)
980 PRM_US_CANCEL_SET_RESOURCE_STATE_START_TRACE;
984 if(aTracker->iBusyQue != NULL)
986 firstLink = (TTrackingBuffer*)(aTracker->iBusyQue->iA.iNext);
987 lastLink = (TTrackingBuffer*)(&(aTracker->iBusyQue->iA));
989 while(( firstLink!=lastLink )&&(!statusMatched))
991 TTrackingBuffer* buffer = firstLink;
992 TUint resourceId = buffer->GetResourceId();
994 if(resourceId != aResourceId) // Required resource?
996 firstLink=(TTrackingBuffer*)(firstLink->iNext);
1001 TClientRequest *request;
1002 GET_USER_REQUEST(request, buffer, type)
1003 if(request->StatusPtr() == aStatus)
1005 statusMatched = ETrue;
1009 firstLink=(TTrackingBuffer*)(firstLink->iNext);
1016 TTrackGetStateBuf* stateBuf = (TTrackGetStateBuf*)firstLink;
1017 r=((DPowerResourceController*)iPddPtr)->CancelAsyncRequestCallBack(ClientHandle(),
1018 resourceId, (stateBuf->iCtrlBlock));
1020 else if(type==ESetState)
1022 TTrackSetStateBuf* stateBuf = (TTrackSetStateBuf*)firstLink;
1023 r = ((DPowerResourceController*)iPddPtr)->CancelAsyncRequestCallBack(ClientHandle(),
1024 resourceId, (stateBuf->iCtrlBlock));
1026 else if(type==ENotify)
1028 TTrackNotifyBuf* notifyBuf = (TTrackNotifyBuf*)firstLink;
1029 r=((DPowerResourceController*)iPddPtr)->CancelNotification(ClientHandle(), resourceId,
1030 notifyBuf->iNotifyBlock);
1033 // Process the accumulated return value
1034 if((r==KErrCompletion)&&((returnVal==KErrNone)||(returnVal==KErrCancel)))
1036 returnVal=KErrCompletion;
1038 else if((r==KErrInUse)&&
1039 ((returnVal==KErrNone)||(returnVal==KErrCompletion)||(returnVal==KErrCancel)))
1041 returnVal=KErrInUse;
1043 else if(r!=KErrCancel)
1048 // Return the tracking buffer to the free queue
1049 TTrackingBuffer* tempLink = (TTrackingBuffer*)(firstLink->iNext);
1050 FreeTrackingBuffer(firstLink);
1051 firstLink = tempLink;
1053 #ifdef PRM_US_INSTRUMENTATION_MACRO
1056 PRM_US_CANCEL_GET_RESOURCE_STATE_END_TRACE;
1058 else if(type==ESetState)
1060 PRM_US_CANCEL_SET_RESOURCE_STATE_END_TRACE;
1063 // Complete the TRequestStatus object
1064 if((r!=KErrCompletion)&&(r!=KErrInUse))
1066 TClientRequest* request;
1067 GET_USER_REQUEST(request, buffer, type)
1068 Kern::QueueRequestComplete(iClient, request, r);
1076 TTrackingControl* DChannelResManUs::MapRequestToTracker(TInt aRequestType)
1077 // Utility function to map identifiers for cancel commands to request types.
1079 TTrackingControl *tracker=NULL;
1080 switch(aRequestType)
1082 case RBusDevResManUs::ECancelChangeResourceStateRequests:
1083 case RBusDevResManUs::ECancelChangeResourceState:
1085 tracker=iSetStateTracker;
1088 case RBusDevResManUs::ECancelGetResourceStateRequests:
1089 case RBusDevResManUs::ECancelGetResourceState:
1091 tracker=iGetStateTracker;
1094 case RBusDevResManUs::ECancelChangeNotificationRequests:
1095 case RBusDevResManUs::ECancelRequestChangeNotification:
1097 tracker=iListenableTracker;
1102 __ASSERT_ALWAYS(0,RESMANUS_FAULT());
1109 TInt DChannelResManUs::CancelRequestsOfType(TInt aRequestType, TRequestStatus* aStatus)
1110 // Cancel a particular request. This may be qualified by the type of operation
1112 __ASSERT_ALWAYS(((aRequestType==RBusDevResManUs::ECancelChangeResourceState)||
1113 (aRequestType==RBusDevResManUs::ECancelGetResourceState)||
1114 (aRequestType==RBusDevResManUs::ECancelRequestChangeNotification)||
1117 // For the KMaxTInt case, the type of the request is not known and so all trackers
1118 // must be considered before the request is found.
1119 // For all other cases, only the relevant tracker is searched.
1121 if(aRequestType!=KMaxTInt)
1123 TTrackingControl*tracker=MapRequestToTracker(aRequestType);
1124 r=CancelTrackerRequests(tracker, EFalse, 0, aStatus);
1128 TTrackingControl* tracker[3] = {iGetStateTracker, iSetStateTracker, iListenableTracker};
1130 while((index<3) && (r==KErrNone))
1132 r=CancelTrackerRequests(tracker[index], EFalse, 0, aStatus);
1137 r=KErrNone; // All cancellations were successful
1143 void DChannelResManUs::DoCancel(TInt aMask)
1144 // Cancel an outstanding request.
1146 TRequestStatus* status = (TRequestStatus*)aMask;
1147 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoCancel, TRequestStatus addr = 0x%x",(TInt)status));
1149 CancelRequestsOfType(KMaxTInt, status); // Ignore return value
1153 TInt DChannelResManUs::DoRequest(TInt aReqNo, TRequestStatus* /*aStatus*/, TAny* a1, TAny* a2)
1154 // Asynchronous requests.
1156 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)"));
1161 case RBusDevResManUs::EChangeResourceState:
1163 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case EChangeResourceState"));
1164 // a1 specifies the identifier of the required resource
1165 // a2 specifies the required state for the resource
1167 TUint *param = (TUint*)a2;
1168 TUint resourceId = (TUint)a1;
1169 TInt newState = (TInt)param[0];
1171 #ifdef PRM_US_INSTRUMENTATION_MACRO
1172 PRM_US_SET_RESOURCE_STATE_START_TRACE;
1175 r=((DPowerResourceController*)iPddPtr)->ChangeResourceState(ClientHandle(),
1176 resourceId, newState, (TPowerResourceCb*)param[1]);
1180 case RBusDevResManUs::EGetResourceState:
1182 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case EGetResourceState"));
1183 // a1 specifies the resource ID
1184 // a2 specifies the container stating if a cached value is required, the address of the variable
1185 // to be update with the state value and the address of the level owner ID
1187 TUint resourceId = (TUint)a1;
1188 TUint *parms = (TUint*)a2;
1189 TBool cached = (TBool)(parms[0]);
1191 #ifdef PRM_US_INSTRUMENTATION_MACRO
1192 PRM_US_GET_RESOURCE_STATE_START_TRACE;
1194 // Always invoke the asynchronous version of the API
1195 r=((DPowerResourceController*)iPddPtr)->GetResourceState(ClientHandle(),
1196 resourceId, cached, *((TPowerResourceCb*)parms[3]));
1201 case RBusDevResManUs::ERequestChangeNotification:
1203 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case ERequestChangeNotification"));
1204 // a1 specifies the resource ID
1205 r=((DPowerResourceController*)iPddPtr)->RequestNotification(ClientHandle(),
1206 (TUint)a1, *((DPowerResourceNotification*)a2));
1210 case RBusDevResManUs::ERequestQualifiedChangeNotification:
1212 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case ERequestQualifiedChangeNotification"));
1213 // a1 specifies the threshold value that the state is to change by
1214 // a2 specifies the address of the container holding the resourceID and the required direction
1215 TInt threshold = (TInt)a1;
1216 TUint *parms = (TUint*)a2;
1217 TUint resourceId = parms[0];
1218 TBool direction = (TBool)(parms[1]);
1219 r=((DPowerResourceController*)iPddPtr)->RequestNotification(ClientHandle(),
1220 resourceId, *((DPowerResourceNotification*)parms[2]), threshold, direction);
1225 return KErrNotSupported;
1230 TInt DChannelResManUs::DoControl(TInt aFunction, TAny* a1, TAny* a2)
1231 // Synchronous requests.
1233 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DoControl(TInt aFunction, TAny* a1, TAny* a2)") );
1238 case RBusDevResManUs::EInitialise:
1240 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EInitialise"));
1241 // a1 specifies the array describing the number of 'gettable' and 'settable' state resources
1242 // and the number of 'listenable' resources
1244 TUint8 *stateRes = (TUint8*)a1;
1245 #ifdef PRM_US_INSTRUMENTATION_MACRO
1246 PRM_US_REGISTER_CLIENT_START_TRACE;
1248 // The call to the Resource Controller's AllocReserve method requires two parameters:
1249 // the number of client level objects and the number of request message objects
1250 // Each 'settable' state resource requires a client level object and a request message object
1251 // Each 'gettable' state resource requires a request message object, only.
1252 // Call Resource Control to make allocations
1253 r=((DPowerResourceController*)iPddPtr)->AllocReserve(ClientHandle(),
1254 stateRes[1], // Number of settable
1255 (TUint8)(stateRes[1] + stateRes[0])); // Number of (settable + gettable)
1256 #ifdef PRM_US_INSTRUMENTATION_MACRO
1257 PRM_US_REGISTER_CLIENT_END_TRACE;
1261 // Require 1 TPowerResourceCb object per gettable resource state
1262 // Require 1 TPowerResourceCb object per settable resource state
1263 // Require 1 DPowerResourceNotification object per listenable resource
1266 r=InitTrackingControl(iGetStateTracker,EGetState,stateRes[0]);
1267 if((r==KErrNone) && (stateRes[1]>0))
1268 r=InitTrackingControl(iSetStateTracker,ESetState,stateRes[1]);
1269 if((r==KErrNone) && (stateRes[2]>0))
1270 r=InitTrackingControl(iListenableTracker,ENotify,stateRes[2]);
1271 #ifdef _DUMP_TRACKERS
1272 if((r=DumpTracker(iGetStateTracker))!=KErrNone)
1274 if((r=DumpTracker(iSetStateTracker))!=KErrNone)
1281 case RBusDevResManUs::EGetNoOfResources:
1283 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNoOfResources"));
1285 r=((DPowerResourceController*)iPddPtr)->GetNumResourcesInUseByClient(ClientHandle(),0,numResources);
1286 iResInfoValid = 0; // New numResources invalidates the iResInfoXXXX information
1287 iResInfoStoredClientId = 0;
1288 iResInfoStoredNum = 0;
1291 // a2 specifies whether the resource information should be loaded
1292 if((r==KErrNone)&&(a2!=NULL))
1294 TUint prevNumRes = 0;
1295 while((numResources != prevNumRes)&&(r==KErrNone))
1297 // if the number of resources is greater than can be accommodated by the array,
1299 if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
1301 prevNumRes = numResources;
1302 // Get the resource info from the Resource Controller
1303 // Specify 'aTargetClientId' as zero to access all resources
1304 iResourceInfoResCtrl->SetLength(0);
1305 r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
1306 ClientHandle(),0,numResources,iResourceInfoResCtrl);
1311 iResInfoStoredClientId = KAllResInfoStored;
1312 iResInfoStoredNum = numResources;
1316 *(TUint*)a1 = numResources;
1320 case RBusDevResManUs::EGetAllResourcesInfo:
1322 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetAllResourcesInfo"));
1323 // Parameters are passed in TUint* parms[2]
1324 // The address of the number of resources is at element 0
1325 // The flag to indicate if the resource info stored is to be refreshed is at element 1
1326 TUint* parms = (TUint*)a2;
1327 TUint numResources = *(TUint*)parms[0];
1328 TBool refresh=(TBool)(parms[1]);
1330 // The results are to be written to an RSimplePointerArray, the address is in a1
1331 // Check that the array has enough elements
1334 // For the refresh option, invoke Resource Controller API once, only (do not recurse)
1335 // If the number of requested resources is greater than can be accommodated by the array,
1337 if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
1339 // Get the resource info from the Resource Controller
1340 // Specify 'aTargetClientId' as zero to access all resources
1341 iResourceInfoResCtrl->SetLength(0);
1342 r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
1343 ClientHandle(),0,numResources,iResourceInfoResCtrl);
1344 if(numResources != iResInfoStoredNum)
1346 iResInfoValid = 0; // Assume cohesion is now lost
1347 iResInfoStoredClientId = 0;
1348 iResInfoStoredNum = 0;
1353 // If the information stored is not valid or is not for all resources return KErrNotReady
1354 if((iResInfoValid != 1)||(iResInfoStoredClientId != KAllResInfoStored))
1359 // The number of resources for which information is available in this case is iResInfoStoredNum
1360 numResources = iResInfoStoredNum;
1362 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
1363 TPowerResourceInfoV01* currRes = (TPowerResourceInfoV01*)iResourceInfoResCtrl->Ptr();
1364 for(TUint index = 0; index < numResources; index++)
1366 CheckForCandidateAsyncResource(currRes);
1367 CheckForCandidateSharedResource(currRes);
1371 *(TUint*)(parms[0]) = numResources;
1376 case RBusDevResManUs::EGetNoOfClients:
1377 case RBusDevResManUs::EGetNumClientsUsingResource:
1379 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNoOfClients"));
1380 // Parameters are passed in TUint parms[3]
1381 // The flag to indicate if kernel-side clients are to be included is at element 0
1382 // The ID of the resource of interest (0 is expected for EGetNoOfClients)
1383 // The flag to indicate if the client info is to be read now is at element 1
1384 TUint *parms = (TUint*)a2;
1385 TUint includeKern = parms[0];
1386 TUint resourceId = parms[1];
1387 TUint infoRead = parms[2];
1388 TUint requiredId = resourceId;
1389 if(aFunction == RBusDevResManUs::EGetNoOfClients)
1391 __ASSERT_ALWAYS(resourceId==0,RESMANUS_FAULT());
1392 requiredId = KAllClientInfoStored;
1394 TUint numClients = 0;
1397 // Client must exhibit PlatSec capability ReadDeviceData
1398 if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNoOfClients")))
1400 r = KErrPermissionDenied;
1404 r=((DPowerResourceController*)iPddPtr)->GetNumClientsUsingResource(ClientHandle(),resourceId,numClients);
1407 numClients = (TUint)(iDevice->iOpenChannels);
1409 // New numClients invalidates the iClientInfoXXXX information
1410 iClientInfoValid = 0;
1411 iClientInfoStoredResId = 0;
1412 iClientInfoStoredNum= 0;
1414 if((r==KErrNone)&&(infoRead==1))
1416 // Capability check already performed, so no need to repeat ...
1417 TUint prevNumClients = 0;
1418 while((numClients != prevNumClients)&&(r == KErrNone))
1420 // Ensure buffer is large enough to store the information
1421 if((r=EnsureSizeIsSufficient(iClientNamesResCtrl, (TInt)(numClients*sizeof(TPowerClientInfoV01))))!=KErrNone)
1423 prevNumClients = numClients;
1425 r=((DPowerResourceController*)iPddPtr)->GetInfoOnClientsUsingResource(ClientHandle(),
1426 resourceId,numClients,iClientNamesResCtrl);
1431 iClientInfoValid = 1;
1432 iClientInfoStoredResId = requiredId;
1433 iClientInfoStoredNum = numClients;
1436 TUint numAllClients = numClients;
1438 TPowerClientInfoV01* rcDataPtr = (TPowerClientInfoV01*)(iClientNamesResCtrl->Ptr());
1439 for(TUint i=0; i<numAllClients; i++)
1441 if( rcDataPtr->iClientId & USER_SIDE_CLIENT_BIT_MASK)
1449 *(TUint*)a1 = numClients;
1453 case RBusDevResManUs::EGetNamesAllClients:
1454 case RBusDevResManUs::EGetInfoOnClientsUsingResource:
1456 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNamesAllClients-EGetInfoOnClientsUsingResource"));
1457 // Parameters are passed in TUint* parms[4]
1458 // The address of the number of clients is at element 0
1459 // The flag to indicate if kernel-side info is requested is at element 1
1460 // The resource ID is at element 2
1461 // The flag to indicate if the client information stored is to be refreshed is at element 3
1462 TUint* parms = (TUint*)a2;
1463 TUint numClients = *(TUint*)parms[0];
1464 TBool includeKern=(TBool)(parms[1]);
1465 TUint resourceId=(TUint)(parms[2]);
1466 TBool refresh=(TBool)(parms[3]);
1468 TUint numClientsAvailable = 0;
1469 iClientNamesResCtrl->SetLength(0);
1473 // Client must exhibit PlatSec capability ReadDeviceData
1474 if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNamesAllClients-EGetInfoOnClientsUsingResource")))
1476 r = KErrPermissionDenied;
1477 break; // Early exit in event of error
1479 TUint requiredId = (resourceId==0)?(TUint)KAllClientInfoStored:resourceId;
1482 // For the refresh option, invoke Resource Controller API once, only (do not recurse)
1483 // If the number of clients is greater than can be accommodated by the array,
1485 if((r=EnsureSizeIsSufficient(iClientNamesResCtrl, (TInt)(numClients*sizeof(TPowerClientInfoV01))))!=KErrNone)
1488 numClientsAvailable = numClients; // Arbitrary initialisation (to silence compiler warning)
1489 r=((DPowerResourceController*)iPddPtr)->GetInfoOnClientsUsingResource(ClientHandle(),
1490 resourceId,numClientsAvailable,iClientNamesResCtrl);
1491 if((r!=KErrNone)||(numClientsAvailable != iClientInfoStoredNum)||(iClientInfoStoredResId != requiredId))
1493 iClientInfoValid = 0; // Assume cohesion is now lost
1494 iClientInfoStoredResId = 0;
1495 iClientInfoStoredNum = 0;
1500 // If the information stored is not valid, is not for the required resources return KErrNotReady
1501 if((iClientInfoValid != 1)||(iClientInfoStoredResId != requiredId))
1503 // The number of clients for which information is available in this case is iClientInfoStoredNum
1504 numClientsAvailable = iClientInfoStoredNum;
1509 // Resource Controller will return information for the number of clients requested,
1510 // taken in order from its internal storage - but this will be regardless of whether
1511 // they are kernel-side or user-side; the USER_SIDE_CLIENT_BIT_MASK bit must be
1512 // interrogated to determine this.
1514 // Therefore, need to read all the clients - but to do this, must find out how many
1515 // clients there are first.
1516 TUint numAllClients;
1517 r=((DPowerResourceController*)iPddPtr)->GetNumClientsUsingResource(ClientHandle(),resourceId,numAllClients);
1519 break; // Early exit in event of error
1520 if(numAllClients > 0)
1524 // For the refresh option, invoke Resource Controller API once, only (do not recurse)
1525 // If the number of clients is greater than can be accommodated by the array,
1527 if((r=EnsureSizeIsSufficient(iClientNamesResCtrl, (TInt)(numAllClients*sizeof(TPowerClientInfoV01))))!=KErrNone)
1530 r=((DPowerResourceController*)iPddPtr)->GetInfoOnClientsUsingResource(ClientHandle(),
1531 resourceId,numAllClients,iClientNamesResCtrl);
1532 TUint requiredId = (resourceId==0)?(TUint)KAllClientInfoStored:resourceId;
1533 if((r!=KErrNone)||(numClientsAvailable != iClientInfoStoredNum)||(iClientInfoStoredResId != requiredId))
1535 iClientInfoValid = 0; // Assume cohesion is now lost
1536 iClientInfoStoredResId = 0;
1537 iClientInfoStoredNum = 0;
1542 iClientInfoValid = 1;
1543 iClientInfoStoredResId = requiredId;
1544 iClientInfoStoredNum = numAllClients;
1549 // If the information stored is not valid, is not for the required resources return KErrNotReady
1550 TUint requiredId = (resourceId==0)?(TUint)KAllClientInfoStored:resourceId;
1551 if((iClientInfoValid != 1)||(iClientInfoStoredResId != requiredId))
1556 // The number of clients for which information is available in this case is iClientInfoStoredNum
1557 numAllClients = iClientInfoStoredNum;
1559 numClientsAvailable = numAllClients;
1560 } // if(numAllClients > 0)
1562 // Write the total number of user side cients available
1563 *(TUint*)parms[0] = numClientsAvailable;
1566 case RBusDevResManUs::EGetNumResourcesInUseByClient:
1568 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumResourcesInUseByClient"));
1569 // a1 specifies the container holding the client name
1572 // If client doesn't exist, return KErrNotFound
1573 // If client has appropriate capabilities, or if the client for which the information is sought
1574 // is user-side, invoke the Resource Controller API directly
1575 // Otherwise, return KErrPermissionDenied
1577 r=((DPowerResourceController*)iPddPtr)->GetClientId(ClientHandle(),
1578 *(TDesC8*)a1,clientId);
1580 return KErrNotFound;
1581 // Perform capability check
1582 if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNoOfClients")))
1584 if(!(clientId & USER_SIDE_CLIENT_BIT_MASK))
1585 return KErrPermissionDenied;
1587 TUint numResources=0;
1589 r=((DPowerResourceController*)iPddPtr)->GetNumResourcesInUseByClient(ClientHandle(),
1590 clientId,numResources);
1591 // New numResources invalidates the iResXXXX information
1593 iResInfoStoredClientId = 0;
1594 iResInfoStoredNum= 0;
1596 // parms[1] specifies whether the resource information should be loaded
1597 if((r==KErrNone)&&(*(TUint*)a2 != NULL))
1599 TUint prevNumRes = 0;
1600 while((numResources != prevNumRes)&&(r==KErrNone))
1602 // if the number of resources is greater than can be accommodated by the array,
1604 if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
1606 prevNumRes = numResources;
1607 // Get the resource info from the Resource Controller
1608 // Specify 'aTargetClientId' as zero to access all resources
1609 iResourceInfoResCtrl->SetLength(0);
1610 r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
1611 ClientHandle(),clientId,numResources,iResourceInfoResCtrl);
1616 iResInfoStoredClientId = clientId;
1617 iResInfoStoredNum = numResources;
1621 *(TUint*)a2 = numResources;
1625 case RBusDevResManUs::EGetInfoOnResourcesInUseByClient:
1627 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetInfoOnResourcesInUseByClient"));
1628 // a1 specifies the container holding the client name
1629 // a2 specifies an array TUint* parms[3] which contains:
1630 // - the address of the variable to write the number of reasources to
1631 // - a pointer to the container to hold the resources' information
1632 // - the flag to indicate whether the resource info should be (re-)read here
1635 TUint *parms = (TUint*)a2;
1636 TUint numResources = *(TUint*)parms[0];
1637 // The results are to be written to an RSimplePointerArray, the address is in parms[1]
1638 // Check that the array has enough elements
1639 // If client doesn't exist, return KErrNotFound
1640 // If client has appropriate capabilities, or if the client for which the information is sought
1641 // is user-side, invoke the Resource Controller API directly
1642 // Otherwise, return KErrPermissionDenied
1643 r=((DPowerResourceController*)iPddPtr)->GetClientId(ClientHandle(),
1644 *(TDesC8*)a1,clientId);
1646 return KErrNotFound;
1647 // Perform capability check
1648 if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNoOfClients")))
1650 if(!(clientId & USER_SIDE_CLIENT_BIT_MASK))
1651 return KErrPermissionDenied;
1654 TUint updatedNumResources = numResources;
1655 r=((DPowerResourceController*)iPddPtr)->GetNumResourcesInUseByClient(ClientHandle(),clientId,updatedNumResources);
1659 if(updatedNumResources>0)
1661 if((TUint)(parms[2] != 0))
1663 // For the refresh option, invoke Resource Controller API once, only (do not recurse)
1664 // If the number of requested resources is greater than can be accommodated by the array,
1666 if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
1668 // Get the resource info from the Resource Controller
1669 // Specify 'aTargetClientId' as zero to access all resources
1670 iResourceInfoResCtrl->SetLength(0);
1671 r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
1672 ClientHandle(),clientId,numResources,iResourceInfoResCtrl);
1673 if((numResources != iResInfoStoredNum)||(iResInfoStoredClientId != clientId))
1675 iResInfoValid = 0; // Assume cohesion is now lost
1676 iResInfoStoredClientId = 0;
1677 iResInfoStoredNum = 0;
1682 // If the information stored is not valid or is not for the required clientId return KErrNotReady
1683 if((iResInfoValid != 1)||(iResInfoStoredClientId != clientId))
1685 // The number of resources for which information is available in this case is iResInfoStoredNum
1686 numResources = iResInfoStoredNum;
1690 *(TUint*)parms[0] = updatedNumResources;
1695 case RBusDevResManUs::EGetResourceIdByName:
1697 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetResourceIdByName"));
1698 // a1 specifies the container holding the resource name
1699 // a2 specifies the variable to be update with the ID
1701 r=((DPowerResourceController*)iPddPtr)->GetResourceId(ClientHandle(), *(TDesC8*)a1, resourceId);
1703 *(TUint *)a2 = resourceId;
1707 case RBusDevResManUs::EGetResourceInfo:
1709 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetResourceInfo"));
1710 // a1 specifies the container holding the resource ID
1711 // a2 specifies the address of the container to be written to
1713 TUint resourceId= (TUint)a1;
1714 TPowerResourceInfoBuf01 resCtrlInfo;
1715 resCtrlInfo.SetLength(0);
1716 TResourceInfoBuf tempInfo;
1717 r=((DPowerResourceController*)iPddPtr)->GetResourceInfo(ClientHandle(),resourceId,&resCtrlInfo);
1720 // Copy the client buffer to tempInfo so that its size can be determined
1721 // by ExtractResourceInfo
1722 r=ExtractResourceInfo(&(resCtrlInfo()), tempInfo);
1726 // Write the resources' info to the client thread
1727 *(TResourceInfoBuf*)a2 = tempInfo;
1733 case RBusDevResManUs::ECancelChangeResourceStateRequests:
1734 case RBusDevResManUs::ECancelGetResourceStateRequests:
1735 case RBusDevResManUs::ECancelChangeNotificationRequests:
1737 TUint resourceId = (TUint)a1;
1738 TTrackingControl*tracker=MapRequestToTracker(aFunction);
1739 r=CancelTrackerRequests(tracker, ETrue, resourceId, NULL);
1741 r=KErrNone; // All cancellations were successful
1745 case RBusDevResManUs::ECancelChangeResourceState:
1746 case RBusDevResManUs::ECancelGetResourceState:
1747 case RBusDevResManUs::ECancelRequestChangeNotification:
1749 TRequestStatus* status = (TRequestStatus*)a1;
1750 r=CancelRequestsOfType(aFunction, status);
1755 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
1756 case RBusDevResManUs::EGetNumCandidateAsyncResources:
1758 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumCandidateAsyncResources"));
1760 GetNumCandidateAsyncResources(numResources);
1761 // Write the result to the client thread
1762 *(TUint*)a1 = numResources;
1765 case RBusDevResManUs::EGetCandidateAsyncResourceId:
1767 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetCandidateAsyncResourceId"));
1768 // Get the index to use
1769 TUint index = (TUint)a1;
1770 TUint resourceId = 0;
1771 r=GetCandidateAsyncResourceId(index, resourceId);
1772 if(r==KErrNone) // Write the result to the client thread
1773 *(TUint*)a2 = resourceId;
1777 case RBusDevResManUs::EGetNumCandidateSharedResources:
1779 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumCandidateSharedResources"));
1781 GetNumCandidateSharedResources(numResources);
1782 // Write the result to the client thread
1783 *(TUint*)a1 = numResources;
1786 case RBusDevResManUs::EGetCandidateSharedResourceId:
1788 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetCandidateSharedResourceId"));
1789 // Get the index to use
1790 TUint index = (TUint)a1;
1791 TUint resourceId = 0;
1792 r=GetCandidateSharedResourceId(index, resourceId);
1793 if(r==KErrNone) // Write the result to the client thread
1794 *(TUint*)a2 = resourceId;
1799 case RBusDevResManUs::EGetResourceControllerVersion:
1801 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetResourceControllerVersion"));
1802 // a1 specifies the address of the TVersion variable to be written to
1805 if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(),
1806 KResManControlIoGetVersion,
1811 // Write the required information
1812 *(TUint*)a1 = version;
1816 case RBusDevResManUs::EGetNumDependentsForResource:
1818 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumDependentsForResource"));
1819 // a1 specifies a pointer to the variable to be written to
1820 // a2 specifies an array TUint parms[2] which contains:
1821 // - the resource ID
1822 // - flag to indicate if dependency information is to be loaded as part of this call
1823 TUint *parms = (TUint*)a2;
1824 TUint numDependents = 0;
1825 r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(),
1826 KResManControlIoGetNumDependents,
1827 (TAny*)(parms[0]), // Resource ID
1830 iResDepsValid=EFalse; // The number of dependents may differ from the dependency information stored
1834 // Load the dependency information, if required.
1837 // The dependency information may be updated subsequent to the request for the number of dependents. In order
1838 // to provide a coherent number and array of dependents, the requests for dependency information will be
1839 // re-issued if the (new) number of dependents differs from that previously read.
1840 TUint prevNumDeps = 0;
1841 TUint newNumDeps = numDependents;
1842 while((newNumDeps != prevNumDeps)&&(r == KErrNone))
1844 if((r=EnsureSizeIsSufficient(iResourceDependencyIds, (TInt)(newNumDeps*sizeof(SResourceDependencyInfo))))!=KErrNone)
1846 prevNumDeps = newNumDeps;
1847 if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(),
1848 KResManControlIoGetDependentsId,
1849 (TAny*)(parms[0]), // Resource ID
1850 (TAny*)(iResourceDependencyIds),
1851 (TAny*)&newNumDeps))!=KErrNone)
1854 // Dependency information now in synch with number reported
1855 numDependents = newNumDeps;
1856 iNumResDepsStored = newNumDeps;
1857 iResDepsValid = ETrue;
1859 // Write the number of dependents to the client thread
1860 *(TUint*)a1 = numDependents;
1865 case RBusDevResManUs::EGetDependentsIdForResource:
1867 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetDependentsIdForResource"));
1868 // a1 specifies a pointer to the variable to hold the number of dependencies
1869 // a2 specifies an array TUint parms[4] which contains:
1870 // - the resource ID
1871 // - the address of the array to write the required IDs to
1872 // - flag to indicate if dependency information is to be (re-)loaded as part of this call
1873 TUint *parms = (TUint*)a2;
1874 TUint numDependents = 0;
1876 // (Re-)Load the dependency information, if required.
1879 if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(),
1880 KResManControlIoGetNumDependents,
1882 (TAny*)&numDependents,
1886 iResDepsValid=EFalse; // The number of dependents may differ from the dependency information stored
1887 // In order to provide a coherent number and array of dependents, the requests for dependency information
1888 // will be re-issued if the (new) number of dependents differs from that previously read.
1889 TUint prevNumDeps = 0;
1890 TUint newNumDeps = numDependents;
1891 while(newNumDeps != prevNumDeps)
1893 if((r=EnsureSizeIsSufficient(iResourceDependencyIds, (TInt)(newNumDeps*sizeof(SResourceDependencyInfo))))!=KErrNone)
1895 prevNumDeps = newNumDeps;
1896 if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(),
1897 KResManControlIoGetDependentsId,
1898 (TAny*)(parms[0]), // Resource ID
1899 (TAny*)(iResourceDependencyIds),
1900 (TAny*)&newNumDeps))!=KErrNone)
1904 // Dependency information now in synch with number reported
1905 numDependents = newNumDeps;
1906 iNumResDepsStored = newNumDeps;
1907 iResDepsValid = ETrue;
1910 // If iResDepsValid equals zero, the results are invalid - so return KErrNotReady.
1911 if(iResDepsValid==0)
1912 return KErrNotReady;
1914 // Write the number of dependencies available to the client
1915 *(TUint*)a1 = iNumResDepsStored;
1916 // Write the dependencies to the client array if it is of sufficient size
1917 // Copy the required dependency information to the user-supplied container.
1918 parms[1] = (TUint)iResourceDependencyIds;
1924 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl default 0x%x", aFunction));
1932 TInt DChannelResManUs::EnsureSizeIsSufficient(HBuf*& aBuffer, TInt aMinSize)
1934 // Utility function to ensure a buffer is of at least the minimum required size
1935 // If the buffer is to small, an attempt is made to increase its size.
1936 // If the re-sizing fails, KErrNoMemory is returned; otherwise KErrNone.
1937 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::EnsureSizeIsSufficient"));
1939 if(aBuffer->MaxLength() < aMinSize)
1941 aBuffer = aBuffer->ReAlloc(aMinSize);
1942 if(aBuffer->MaxLength() < aMinSize)
1943 return KErrNoMemory; // ReAlloc failed - aBuffer is unchanged
1945 aBuffer->SetLength(0);
1949 void DChannelResManUs::FreeTrackingBuffer(TTrackingBuffer*& aBuffer)
1951 __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::FreeTrackingBuffer"));
1952 // Function invoked for to free tracking buffers from the busy to free queue of a tracking control
1953 __ASSERT_ALWAYS((aBuffer!=NULL),RESMANUS_FAULT());
1954 NKern::FMWait(&iBufferFastMutex);
1955 TTrackingControl* tracker = aBuffer->GetTrackingControl();
1956 SDblQue* bufQue = aBuffer->GetQue();
1958 __ASSERT_ALWAYS(((tracker!=NULL)&&(bufQue!=NULL)),RESMANUS_FAULT());
1960 // Check that the buffer is still in the busy queue of the tracker - exit if not
1961 if(bufQue == tracker->iBusyQue)
1964 tracker->iFreeQue->Add(aBuffer);
1965 aBuffer->SetQue(tracker->iFreeQue);
1967 NKern::FMSignal(&iBufferFastMutex);
1971 TInt DChannelResManUs::GetAndInitTrackingBuffer(TTrackingControl*& aTracker, TTrackingBuffer*& aBuffer, TUint aResourceId, TRequestStatus* aStatus)
1973 // Utility function - perform the necessary processing to get a buffer to support
1974 // asynchronous requests to change the state of a resource
1975 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetAndInitTrackingBuffer"));
1977 NKern::FMWait(&iBufferFastMutex);
1978 if(aTracker->iFreeQue->IsEmpty())
1982 // Need intermediate cast from SDblQueLink* to TAny* before TTrackingBuffer*
1983 TAny* ptr = (TAny*)(aTracker->iFreeQue->GetFirst());
1984 aBuffer = (TTrackingBuffer*)ptr;
1985 aTracker->iBusyQue->Add((SDblQueLink*)ptr);
1986 aBuffer->SetQue(aTracker->iBusyQue);
1987 aBuffer->SetResourceId(aResourceId);
1988 TClientRequest* request;
1989 TTrackingControl* tracker = aBuffer->GetTrackingControl();
1990 GET_USER_REQUEST(request, aBuffer, tracker->iType);
1992 request->SetStatus(aStatus);
1994 NKern::FMSignal(&iBufferFastMutex);
1998 TInt DChannelResManUs::GetStateBuffer(TTrackingControl*& aTracker, TTrackingBuffer*& aBuffer, TUint aResourceId, TInt* aState, TInt* aLevelOwnerPtr, TPowerResourceCb*& aCb, TRequestStatus* aStatus)
2000 // Utility function - perform the necessary processing to get a buffer and control block
2001 // to support asynchronous requests to change the state of a resource
2002 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetStateBuffer"));
2004 TInt r=GetAndInitTrackingBuffer(aTracker, aBuffer, aResourceId, aStatus);
2007 TTrackGetStateBuf* stateBuf = (TTrackGetStateBuf*)aBuffer;
2008 stateBuf->iRequest->SetDestPtr1(aState);
2009 stateBuf->iRequest->SetDestPtr2(aLevelOwnerPtr);
2010 // Use placement new to update the content of the TPowerResourceCb
2011 aCb = &(stateBuf->iCtrlBlock);
2012 new (aCb) TPowerResourceCb(&AsyncCallBackFn,(TAny*)aBuffer,iDfcQ,KResManCallBackPriority);
2018 #ifdef _DUMP_TRACKERS
2019 TInt DChannelResManUs::DumpTracker(TTrackingControl* aTracker)
2021 Kern::Printf("\nDChannelResManUs::DumpTracker");
2022 Kern::Printf("Tracker at 0x%x\n",aTracker);
2025 Kern::Printf("iType=%d",aTracker->iType);
2026 switch(aTracker->iType)
2029 Kern::Printf("= GetState tracker\n");
2032 Kern::Printf("= SetState tracker\n");
2035 Kern::Printf("= Notify tracker\n");
2038 Kern::Printf("iOwningChannel at 0x%x\n",aTracker->iOwningChannel);
2039 Kern::Printf("iFreeQue at 0x%x\n",aTracker->iFreeQue);
2041 if(aTracker->iFreeQue!=NULL)
2043 buf=aTracker->iFreeQue->First();
2044 while(buf!=aTracker->iFreeQue->Last())
2046 Kern::Printf("iFreeQue buffer at 0x%x\n",buf);
2047 TAny* intermediatePtr = (TAny*)buf;
2048 if((aTracker->iType == EGetState)||(aTracker->iType == ESetState))
2050 TTrackStateBuf* tempBuf =(TTrackStateBuf*)intermediatePtr;
2051 Kern::Printf("buffer control block at 0x%x\n",tempBuf->iCtrlBlock);
2056 Kern::Printf("iBusyQue at 0x%x\n",aTracker->iBusyQue);
2057 if(aTracker->iBusyQue!=NULL)
2059 buf=aTracker->iBusyQue->First();
2060 while(buf!=aTracker->iBusyQue->Last())
2062 Kern::Printf("iBusyQue buffer at 0x%x\n",buf);
2063 TAny* intermediatePtr = (TAny*)buf;
2064 if((aTracker->iType == EGetState)||(aTracker->iType == ESetState))
2066 TTrackStateBuf* tempBuf =(TTrackStateBuf*)intermediatePtr;
2067 Kern::Printf("buffer control block at 0x%x\n",tempBuf->iCtrlBlock);
2077 TInt DChannelResManUs::InitTrackingControl(TTrackingControl*& aTracker, TUint8 aType, TUint8 aNumBuffers)
2079 // Set the tracker type, create the tracking queues and required tracking buffers.
2080 // Assign all the tracking buffers to the free queue.
2082 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::InitTrackingControl()"));
2085 aTracker->iType = (TAsyncOpType)aType;
2086 aTracker->iOwningChannel = this;
2087 aTracker->iFreeQue = new SDblQue();
2088 __ASSERT_DEBUG(aTracker->iFreeQue != NULL, RESMANUS_FAULT());
2089 if(aTracker->iFreeQue == NULL)
2093 aTracker->iBusyQue = new SDblQue();
2094 __ASSERT_DEBUG(aTracker->iBusyQue != NULL, RESMANUS_FAULT());
2095 if(aTracker->iBusyQue == NULL)
2097 delete aTracker->iFreeQue;
2103 for(TUint8 i=0; (i<aNumBuffers) && (r==KErrNone) ;i++)
2106 TAny* ptr=NULL; // To be assigned to non-NULL value later
2107 switch(aTracker->iType)
2111 buf = (TAny*)(new TTrackGetStateBuf(&AsyncCallBackFn,ptr,iDfcQ,KResManCallBackPriority));
2112 r = Kern::CreateClientDataRequest2(((TTrackGetStateBuf*)buf)->iRequest);
2117 buf = (TAny*)(new TTrackSetStateBuf(&AsyncCallBackFn, ptr, iDfcQ, KResManCallBackPriority));
2118 r = Kern::CreateClientRequest(((TTrackSetStateBuf*)buf)->iRequest);
2123 buf = (TAny*)(new TTrackNotifyBuf(&AsyncCallBackFn,ptr,iDfcQ,KResManCallBackPriority));
2124 r = Kern::CreateClientRequest(((TTrackNotifyBuf*)buf)->iRequest);
2128 __ASSERT_ALWAYS(0,RESMANUS_FAULT());
2130 __ASSERT_DEBUG(buf!=NULL, RESMANUS_FAULT());
2131 if((buf == NULL) || (r == KErrNoMemory))
2138 ((TTrackingBuffer*)buf)->SetTrackingControl(aTracker);
2139 (aTracker->iFreeQue)->Add((SDblQueLink*)buf);
2140 ((TTrackingBuffer*)buf)->SetQue(aTracker->iFreeQue);
2143 // If buffer allocation failed, need to remove all previously-allocated buffers and the queues
2146 SDblQueLink* ptr = (aTracker->iFreeQue)->First();
2149 SDblQueLink* next = NULL;
2154 } while ((ptr!=NULL)&&(ptr!=(aTracker->iFreeQue)->Last()));
2155 delete aTracker->iFreeQue;
2156 delete aTracker->iBusyQue;
2163 void DChannelResManUs::RemoveTrackingControl(TTrackingControl*& aTracker)
2165 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::RemoveTrackingControl()"));
2167 // Free the resource-tracking links and their respective queues
2169 if(aTracker->iFreeQue!=NULL)
2171 while(!aTracker->iFreeQue->IsEmpty())
2173 buf = (TAny*)(aTracker->iFreeQue->GetFirst()); // Dequeues the element
2176 delete aTracker->iFreeQue;
2179 if(aTracker->iBusyQue!=NULL)
2181 while(!aTracker->iBusyQue->IsEmpty())
2183 buf = (TAny*)(aTracker->iBusyQue->GetFirst()); // Dequeues the element
2186 delete aTracker->iBusyQue;
2192 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
2193 void DChannelResManUs::CheckForCandidateAsyncResource(TPowerResourceInfoV01* aResource)
2195 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::CheckForCandidateAsyncResource"));
2196 // Proceed only if we already have less that the maximum number of candidate resources
2197 if(iNoCandidateAsyncRes >= MAX_NUM_CANDIDATE_RESOURCES)
2199 // For the purposes of asynchronous testing, we need a long latency resource
2200 if(((TInt)(aResource->iLatencyGet)==(TInt)(EResLongLatency)) &&
2201 ((TInt)(aResource->iLatencySet)==(TInt)(EResLongLatency)))
2203 // An additional requirement is that the level of the resource can be
2204 // updated a sufficient amount of times to support the required testing.
2205 if(((aResource->iMaxLevel - aResource->iMinLevel) > LEVEL_GAP_REQUIRED_FOR_ASYNC_TESTING) &&
2206 ((TInt)(aResource->iSense) == (TInt)(EResPositive)) )
2208 TInt r=((DPowerResourceController*)iPddPtr)->GetResourceId(ClientHandle(), *(aResource->iResourceName), iCandidateAsyncResIds[iNoCandidateAsyncRes]);
2211 __KTRACE_OPT(KRESMANAGER, Kern::Printf("Failed to identify long latency resource\n"));
2215 __KTRACE_OPT(KRESMANAGER, Kern::Printf("Potential async resource ID = %d\n",iCandidateAsyncResIds[iNoCandidateAsyncRes]));
2216 iHaveLongLatencyResource = ETrue;
2217 ++iNoCandidateAsyncRes;
2224 void DChannelResManUs::GetNumCandidateAsyncResources(TUint& aNumResources)
2226 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetNumCandidateAsyncResources"));
2228 aNumResources = iNoCandidateAsyncRes;
2231 TInt DChannelResManUs::GetCandidateAsyncResourceId(TUint aIndex, TUint& aResourceId)
2233 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetCandidateAsyncResourceId"));
2235 if(aIndex>=iNoCandidateAsyncRes)
2238 aResourceId = iCandidateAsyncResIds[aIndex];
2242 void DChannelResManUs::CheckForCandidateSharedResource(TPowerResourceInfoV01* aResource)
2244 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::CheckForCandidateSharedResource"));
2246 // Proceed only if we already have less that the maximum number of candidate resources
2247 if(iNoCandidateSharedRes >= MAX_NUM_CANDIDATE_RESOURCES)
2250 // For the purposes of testing shared usgae of resources, we need a shareable resource
2251 if((TInt)(aResource->iUsage)==(TInt)(EResShared))
2253 // An additional requirement is that the level of the resource can be
2254 // updated a sufficient amount of times to support the required testing.
2255 if(((aResource->iMaxLevel - aResource->iMinLevel) > LEVEL_GAP_REQUIRED_FOR_SHARED_TESTING) &&
2256 ((TInt)(aResource->iSense) == (TInt)(EResPositive)) )
2258 TInt r=((DPowerResourceController*)iPddPtr)->GetResourceId(ClientHandle(), *(aResource->iResourceName), iCandidateSharedResIds[iNoCandidateSharedRes]);
2261 __KTRACE_OPT(KRESMANAGER, Kern::Printf("Failed to identify shared resource\n"));
2265 __KTRACE_OPT(KRESMANAGER, Kern::Printf("Potential shared resource ID = %d\n",iCandidateSharedResIds[iNoCandidateAsyncRes]));
2266 iHaveLongLatencyResource = ETrue;
2267 ++iNoCandidateSharedRes;
2273 void DChannelResManUs::GetNumCandidateSharedResources(TUint& aNumResources)
2275 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetNumCandidateSharedResources"));
2277 aNumResources = iNoCandidateSharedRes;
2280 TInt DChannelResManUs::GetCandidateSharedResourceId(TUint aIndex, TUint& aResourceId)
2282 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetCandidateSharedResourceId"));
2284 if(aIndex>=iNoCandidateSharedRes)
2287 aResourceId = iCandidateSharedResIds[aIndex];
2293 TInt DChannelResManUs::ExtractResourceInfo(const TPowerResourceInfoV01* aPwrResInfo, TResourceInfoBuf& aInfo)
2295 // Extract data from a TPowerResourceInfoV01 object to a TResourceInfo instance
2296 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::ExtractResourceInfo"));
2299 TInt copyLength=(((aInfo().iName).MaxLength())<((aPwrResInfo->iResourceName)->Length()))?
2300 (aInfo().iName).MaxLength():
2301 (aPwrResInfo->iResourceName)->Length();
2302 (aInfo().iName).Copy((aPwrResInfo->iResourceName)->Ptr(),copyLength);
2303 aInfo().iId = aPwrResInfo->iResourceId;
2304 aInfo().iClass = (TResourceClass)aPwrResInfo->iClass;
2305 aInfo().iType = (TResourceType)aPwrResInfo->iType;
2306 aInfo().iUsage = (TResourceUsage)aPwrResInfo->iUsage;
2307 aInfo().iSense = (TResourceSense)aPwrResInfo->iSense;
2308 aInfo().iMinLevel = aPwrResInfo->iMinLevel;
2309 aInfo().iMaxLevel = aPwrResInfo->iMaxLevel;
2311 #ifdef _DUMP_TRACKERS
2312 r=DumpResource(aPwrResInfo);
2317 #ifdef _DUMP_TRACKERS
2318 TInt DChannelResManUs::DumpResource(const TPowerResourceInfoV01* aResource)
2320 __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DumpResource"));
2321 __KTRACE_OPT(KRESMANAGER, Kern::Printf("Resource name = %S \n",aResource->iResourceName));
2322 __KTRACE_OPT(KRESMANAGER, Kern::Printf("Resource ID = 0x%d \n",aResource->iResourceId));
2323 switch(aResource->iClass)
2325 case DStaticPowerResource::EPhysical:
2327 __KTRACE_OPT(KRESMANAGER, Kern::Printf("class = EPhysical\n"));
2330 case DStaticPowerResource::ELogical:
2332 __KTRACE_OPT(KRESMANAGER, Kern::Printf("class = ELogical\n"));
2337 __KTRACE_OPT(KRESMANAGER, Kern::Printf("class = % is UNKNOWN!\n"));
2341 switch(aResource->iType)
2343 case DStaticPowerResource::EBinary:
2345 __KTRACE_OPT(KRESMANAGER, Kern::Printf("type = EBinary\n"));
2348 case DStaticPowerResource::EMultilevel:
2350 __KTRACE_OPT(KRESMANAGER, Kern::Printf("type = EMultilevel\n"));
2353 case DStaticPowerResource::EMultiProperty:
2355 __KTRACE_OPT(KRESMANAGER, Kern::Printf("type = EMultiProperty\n"));
2360 __KTRACE_OPT(KRESMANAGER, Kern::Printf("type = % is UNKNOWN!\n"));
2364 switch(aResource->iUsage)
2366 case DStaticPowerResource::ESingleUse:
2368 __KTRACE_OPT(KRESMANAGER, Kern::Printf("usage = ESingleUse\n"));
2371 case DStaticPowerResource::EShared:
2373 __KTRACE_OPT(KRESMANAGER, Kern::Printf("usage = EShared\n"));
2378 __KTRACE_OPT(KRESMANAGER, Kern::Printf("usage = % is UNKNOWN!\n"));
2382 switch(aResource->iSense)
2384 case DStaticPowerResource::EPositive:
2386 __KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = EPositive\n"));
2389 case DStaticPowerResource::ENegative:
2391 __KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = ENegative\n"));
2394 case DStaticPowerResource::ECustom:
2396 __KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = ECustom\n"));
2401 __KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = % is UNKNOWN!\n"));
2405 switch(aResource->iLatencyGet)
2407 case DStaticPowerResource::EInstantaneous:
2409 __KTRACE_OPT(KRESMANAGER, Kern::Printf("latency get = EInstantaneous\n"));
2412 case DStaticPowerResource::ENegative:
2414 __KTRACE_OPT(KRESMANAGER, Kern::Printf("latency get = ELongLatency\n"));
2419 __KTRACE_OPT(KRESMANAGER, Kern::Printf("latency get = % is UNKNOWN!\n"));
2423 switch(aResource->iLatencySet)
2425 case DStaticPowerResource::EInstantaneous:
2427 __KTRACE_OPT(KRESMANAGER, Kern::Printf("latency set = EInstantaneous\n"));
2430 case DStaticPowerResource::ENegative:
2432 __KTRACE_OPT(KRESMANAGER, Kern::Printf("latency set = ELongLatency\n"));
2437 __KTRACE_OPT(KRESMANAGER, Kern::Printf("latency set = % is UNKNOWN!\n"));
2441 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DefaultLevel = %d\n",aResource->iDefaultLevel));
2442 __KTRACE_OPT(KRESMANAGER, Kern::Printf("MinLevel = %d\n",aResource->iMinLevel));
2443 __KTRACE_OPT(KRESMANAGER, Kern::Printf("MaxLevel = %d\n",aResource->iMaxLevel));
2449 #ifndef RESOURCE_MANAGER_SIMULATED_PSL
2450 DECLARE_EXTENSION_LDD()
2452 return new DDeviceResManUs;
2456 DECLARE_STANDARD_EXTENSION()
2458 DDeviceResManUs* device = new DDeviceResManUs;
2459 __KTRACE_OPT(KBOOT, Kern::Printf("DECLARE_STANDARD_EXTENSION, device = 0x%x\n",device));
2462 return KErrNoMemory;
2465 device->iSharedDfcQue = new TDfcQue();
2466 if(device->iSharedDfcQue==NULL)
2467 return KErrNoMemory;
2469 return (Kern::InstallLogicalDevice(device));
2473 DECLARE_STANDARD_LDD()
2475 TInt r = DSimulatedPowerResourceController::CompleteResourceControllerInitialisation();
2478 // Unconditionally print message
2479 __KTRACE_OPT(KRESMANAGER, Kern::Printf("DECLARE_STANDARD_LDD: initialise Resource Controller failed with %d\n",r));
2482 DDeviceResManUs* device = new DDeviceResManUs;