1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/drivers/resmanus/d_resmanus.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,2485 @@
1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\drivers\resmanus\d_resmanus.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +// LDD for Resource Manager user side API
1.22 +#include "resmanus.h"
1.23 +#include <kernel/kern_priv.h>
1.24 +#include <kernel/kernel.h>
1.25 +#include <e32hal.h>
1.26 +#include <e32uid.h>
1.27 +#include <e32cmn.h>
1.28 +#include <e32cmn_private.h>
1.29 +#include <e32def_private.h>
1.30 +#include <drivers/resource_extend.h>
1.31 +
1.32 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
1.33 +#include "rescontrol_psl.h"
1.34 +#endif
1.35 +
1.36 +#ifdef PRM_US_INSTRUMENTATION_MACRO
1.37 +#include <drivers/resmanus_trace.h>
1.38 +#endif
1.39 +
1.40 +#ifdef PRM_ENABLE_EXTENDED_VERSION2
1.41 +_LIT(KResManUsThreadName,"ResManUsExtendedCoreLddThread");
1.42 +#elif defined (PRM_ENABLE_EXTENDED_VERSION)
1.43 +_LIT(KResManUsThreadName,"ResManUsExtendedLddThread");
1.44 +#else
1.45 +_LIT(KResManUsThreadName,"ResManUsLddThread");
1.46 +#endif
1.47 +
1.48 +#define RESMANUS_FAULT() Kern::Fault("RESMANUS",__LINE__)
1.49 +
1.50 +const TInt KResManUsThreadPriority = 24;
1.51 +const TInt KResManUsRegistrationPriority = 5; // Arbitrary! Can be 0-7, 7 is highest
1.52 +const TInt KResManCallBackPriority = 5; // Arbitrary! Can be 0-7, 7 is highest
1.53 +
1.54 +//Macro to return appropriate request type.
1.55 +#define GET_USER_REQUEST(request, buffer, type) \
1.56 + { \
1.57 + if(type == EGetState) \
1.58 + request = ((TTrackGetStateBuf*)buffer)->iRequest; \
1.59 + else if(type == ESetState) \
1.60 + request = ((TTrackSetStateBuf*)buffer)->iRequest; \
1.61 + else \
1.62 + request = ((TTrackNotifyBuf*)buffer)->iRequest; \
1.63 + }
1.64 +
1.65 +/***************************************************************************************
1.66 + class TTrackGetStateBuf
1.67 + ***************************************************************************************/
1.68 +TTrackGetStateBuf::TTrackGetStateBuf(TPowerResourceCbFn aFn, TAny* aPtr,
1.69 + TDfcQue* aQue, TInt aPriority)
1.70 + : iCtrlBlock(aFn, aPtr, aQue, aPriority)
1.71 + {
1.72 + iRequest = NULL;
1.73 + }
1.74 +
1.75 +/***************************************************************************************
1.76 + class TTrackSetStateBuf
1.77 + ***************************************************************************************/
1.78 +TTrackSetStateBuf::TTrackSetStateBuf(TPowerResourceCbFn aFn, TAny* aPtr,
1.79 + TDfcQue* aQue, TInt aPriority)
1.80 + : iCtrlBlock(aFn, aPtr, aQue, aPriority)
1.81 + {
1.82 + iRequest = NULL;
1.83 + }
1.84 +
1.85 +/***************************************************************************************
1.86 + class TTrackNotifyBuf
1.87 + ***************************************************************************************/
1.88 +TTrackNotifyBuf::TTrackNotifyBuf(TPowerResourceCbFn aFn, TAny* aPtr,
1.89 + TDfcQue* aQue, TInt aPriority)
1.90 + : iNotifyBlock(aFn, aPtr, aQue, aPriority)
1.91 + {
1.92 + iRequest = NULL;
1.93 + }
1.94 +
1.95 +TTrackNotifyBuf::~TTrackNotifyBuf()
1.96 + {
1.97 + if(iRequest)
1.98 + Kern::DestroyClientRequest(iRequest);
1.99 + }
1.100 +
1.101 +TTrackSetStateBuf::~TTrackSetStateBuf()
1.102 + {
1.103 + if(iRequest)
1.104 + Kern::DestroyClientRequest(iRequest);
1.105 + }
1.106 +
1.107 +TTrackGetStateBuf::~TTrackGetStateBuf()
1.108 + {
1.109 + if(iRequest)
1.110 + Kern::DestroyClientRequest(iRequest);
1.111 + }
1.112 +
1.113 +/***************************************************************************************
1.114 + class DDeviceResManUs
1.115 + ***************************************************************************************/
1.116 +DDeviceResManUs::DDeviceResManUs()
1.117 +// Constructor
1.118 + {
1.119 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::DDeviceResManUs()"));
1.120 + iParseMask=KDeviceAllowAll&~KDeviceAllowUnit; // Allow info and pdd, but not units
1.121 + iUnitsMask=0;
1.122 + iVersion=TVersion(KResManUsMajorVersionNumber,
1.123 + KResManUsMinorVersionNumber,
1.124 + KResManUsBuildVersionNumber);
1.125 + }
1.126 +
1.127 +DDeviceResManUs::~DDeviceResManUs()
1.128 +// Destructor
1.129 + {
1.130 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::~DDeviceResManUs()"));
1.131 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
1.132 + iSharedDfcQue->Destroy();
1.133 +#else
1.134 + delete iSharedDfcQue;
1.135 +#endif
1.136 + }
1.137 +
1.138 +TInt DDeviceResManUs::Install()
1.139 +// Install the device driver.
1.140 + {
1.141 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::Install()"));
1.142 + // Create the message queue and initialise the DFC queue pointer
1.143 +#ifndef RESOURCE_MANAGER_SIMULATED_PSL
1.144 + TInt r=Kern::DfcQInit(iSharedDfcQue,KResManUsThreadPriority,&KResManUsThreadName);
1.145 +#else
1.146 + TInt r = Kern::DynamicDfcQCreate(iSharedDfcQue,KResManUsThreadPriority,KResManUsThreadName);
1.147 +#endif
1.148 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DfcQCreate r = %d", r));
1.149 + if(r!=KErrNone)
1.150 + return r;
1.151 +
1.152 +#ifdef CPU_AFFINITY_ANY
1.153 + NKern::ThreadSetCpuAffinity((NThread*)(iSharedDfcQue->iThread), KCpuAffinityAny);
1.154 +#endif
1.155 + r = SetName(&KLddRootName);
1.156 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> SetName, r = %d", r));
1.157 + return r;
1.158 + }
1.159 +
1.160 +
1.161 +void DDeviceResManUs::GetCaps(TDes8& aDes) const
1.162 +// Return the ResManUs capabilities.
1.163 + {
1.164 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::GetCaps(TDes8& aDes) const"));
1.165 + TPckgBuf<TCapsDevResManUs> b;
1.166 + b().version=TVersion(KResManUsMajorVersionNumber,
1.167 + KResManUsMinorVersionNumber,
1.168 + KResManUsBuildVersionNumber);
1.169 + Kern::InfoCopy(aDes,b);
1.170 + }
1.171 +
1.172 +
1.173 +TInt DDeviceResManUs::Create(DLogicalChannelBase*& aChannel)
1.174 +// Create a channel on the device.
1.175 + {
1.176 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::Create(DLogicalChannelBase*& aChannel)"));
1.177 + if(iOpenChannels>=KMaxNumChannels)
1.178 + return KErrOverflow;
1.179 + aChannel=new DChannelResManUs;
1.180 + return aChannel?KErrNone:KErrNoMemory;
1.181 + }
1.182 +
1.183 +
1.184 +/***************************************************************************************
1.185 + class DChannelResManUs
1.186 + ***************************************************************************************/
1.187 +DChannelResManUs::DChannelResManUs()
1.188 +// Constructor
1.189 + {
1.190 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DChannelResManUs()"));
1.191 + iClient=&Kern::CurrentThread();
1.192 + // Increase the DThread's ref count so that it does not close without us
1.193 + iClient->Open();
1.194 + }
1.195 +
1.196 +
1.197 +DChannelResManUs::~DChannelResManUs()
1.198 +// Destructor
1.199 + {
1.200 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::~DChannelResManUs()"));
1.201 +
1.202 + // Cancel any outstanding requests
1.203 + //
1.204 + // For each tracker (Get, Set and notify)
1.205 + //
1.206 + if(iGetStateTracker != NULL)
1.207 + {
1.208 + CancelTrackerRequests(iGetStateTracker,EFalse,0,NULL); // EFalse,0, to ignore resource IDs
1.209 + RemoveTrackingControl(iGetStateTracker);
1.210 + }
1.211 + if(iSetStateTracker != NULL)
1.212 + {
1.213 + CancelTrackerRequests(iSetStateTracker,EFalse,0,NULL); // EFalse,0, to ignore resource IDs
1.214 + RemoveTrackingControl(iSetStateTracker);
1.215 + }
1.216 + if(iListenableTracker != NULL)
1.217 + {
1.218 + CancelTrackerRequests(iListenableTracker,EFalse,0,NULL); // EFalse,0, to ignore resource IDs
1.219 + RemoveTrackingControl(iListenableTracker);
1.220 + }
1.221 +
1.222 + delete iUserNameUsed;
1.223 + delete iResourceDependencyIds;
1.224 + delete iClientNamesResCtrl;
1.225 + delete iResourceInfoResCtrl;
1.226 +
1.227 + // decrement the DThread's reference count
1.228 + Kern::SafeClose((DObject*&)iClient, NULL);
1.229 + }
1.230 +
1.231 +
1.232 +static void AsyncCallBackFn(TUint aClient, TUint aResourceId, TInt aLevel, TInt aLevelOwnerId, TInt aResult, TAny* aTrackingBuffer)
1.233 + {
1.234 +// Callback function for asynchronous requests
1.235 + __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));
1.236 + TTrackingBuffer* buffer = ((TTrackingBuffer*)aTrackingBuffer);
1.237 + TTrackingControl* tracker = buffer->GetTrackingControl();
1.238 + __ASSERT_ALWAYS((tracker!=NULL),RESMANUS_FAULT());
1.239 + DChannelResManUs* channel = tracker->iOwningChannel;
1.240 +
1.241 +#ifdef PRM_US_INSTRUMENTATION_MACRO
1.242 + if(tracker->iType==EGetState)
1.243 + {
1.244 + PRM_US_GET_RESOURCE_STATE_END_TRACE;
1.245 + }
1.246 + else if(tracker->iType==ESetState)
1.247 + {
1.248 + PRM_US_SET_RESOURCE_STATE_END_TRACE;
1.249 + }
1.250 +#endif
1.251 + if(tracker->iType == EGetState)
1.252 + {
1.253 + TTrackGetStateBuf* stateBuf = (TTrackGetStateBuf*)aTrackingBuffer;
1.254 + if(aResult==KErrNone)
1.255 + {
1.256 + // Write the state value to the user-supplied variable
1.257 + stateBuf->iRequest->Data1() = aLevel;
1.258 + stateBuf->iRequest->Data2() = aLevelOwnerId;
1.259 + }
1.260 + Kern::QueueRequestComplete(channel->iClient, ((TTrackGetStateBuf*)buffer)->iRequest, aResult);
1.261 + }
1.262 + else if(tracker->iType == ESetState)
1.263 + {
1.264 + Kern::QueueRequestComplete(channel->iClient, ((TTrackSetStateBuf*)buffer)->iRequest, aResult);
1.265 + }
1.266 + // Once notified of a change in a resource state, must cancel the notification
1.267 + // request in the Resource Controller to give the client the appearance of a
1.268 + // 'one'shot' type of operation.
1.269 + else if(tracker->iType==ENotify)
1.270 + {
1.271 +#ifdef PRM_ENABLE_EXTENDED_VERSION
1.272 + if(((TInt)aClient==KDynamicResourceDeRegistering)&&(aResourceId&KIdMaskDynamic))
1.273 + {
1.274 + // Resource has de-registered from Resource Controller, so can't expect any more notifications
1.275 + // of this type. Cancellation of notifications (i.e. invoke Resource Controller) and transfer of
1.276 + // buffers to free queue (for both conditional and unconditional notifications) is already done.
1.277 + // To distinguish removal of a dynamic resource, hijack aResult (the value used when completing
1.278 + // the user-side TRequestStatus object) and set it to KErrDisconnected.
1.279 + aResult = KErrDisconnected;
1.280 + }
1.281 +
1.282 +#endif
1.283 + TInt r = (channel->iPddPtr)->CancelNotification(channel->ClientHandle(),aResourceId,
1.284 + ((TTrackNotifyBuf*)buffer)->iNotifyBlock);
1.285 + __ASSERT_ALWAYS((r == KErrCancel),RESMANUS_FAULT());
1.286 + Kern::QueueRequestComplete(channel->iClient, ((TTrackNotifyBuf*)buffer)->iRequest, aResult);
1.287 + }
1.288 +
1.289 + // Return the tracking buffer to the free queue
1.290 + channel->FreeTrackingBuffer(buffer);
1.291 + }
1.292 +
1.293 +TInt DChannelResManUs::GetValidName(const TDesC8* aInfo)
1.294 + {
1.295 +// Extract a usable name from that supplied by the client
1.296 + __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::GetValidName"));
1.297 + TInt err=KErrNone;
1.298 + if(aInfo)
1.299 + {
1.300 + DThread* thread = &Kern::CurrentThread();
1.301 + TInt nameLen = Kern::ThreadGetDesLength(thread, aInfo);
1.302 + if(nameLen<0)
1.303 + return nameLen; // return error code
1.304 + iNameProvidedLength = nameLen;
1.305 + if(nameLen > MAX_CLIENT_NAME_LENGTH)
1.306 + err=KErrBadName;
1.307 + else
1.308 + {
1.309 + nameLen = (nameLen<=MAX_NAME_LENGTH_IN_RESMAN) ? nameLen : MAX_NAME_LENGTH_IN_RESMAN;
1.310 + if((iUserNameUsed = HBuf8::New(nameLen))==NULL)
1.311 + return KErrNoMemory;
1.312 + err = Kern::ThreadDesRead(thread,aInfo,*iUserNameUsed,0);
1.313 + if(err!=KErrNone)
1.314 + return err;
1.315 + }
1.316 + }
1.317 + else
1.318 + err=KErrBadName;
1.319 + return err;
1.320 + }
1.321 +
1.322 +TInt DChannelResManUs::RequestUserHandle(DThread* aThread, TOwnerType aType)
1.323 +// Called when a user thread requests a handle to this channel
1.324 + {
1.325 + // Make sure that only our client can get a handle
1.326 + __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::RequestUserHandle"));
1.327 + if (aType!=EOwnerThread || aThread!=iClient)
1.328 + return KErrAccessDenied;
1.329 + return KErrNone;
1.330 + }
1.331 +
1.332 +void DChannelResManUs::RegistrationDfcFunc(TAny* aChannel)
1.333 + {
1.334 + __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::RegistrationDfcFunc"));
1.335 + // DFC function invoked for registration with Resource Controller
1.336 + DChannelResManUs* channel = (DChannelResManUs*)aChannel;
1.337 + // RegisterProxyClient(TUint& aProxyId, const TDesC& aName);
1.338 + TUint uintVal=0;
1.339 + TInt r = KErrNone;
1.340 + __ASSERT_ALWAYS((r==KErrNone),RESMANUS_FAULT());
1.341 +
1.342 + r=(channel->iPddPtr)->RegisterProxyClient(uintVal,*((TDesC8*)(channel->iUserNameUsed)));
1.343 + if(r!=KErrNone)
1.344 + {
1.345 + // Registration failed
1.346 + // Ensure that the client-side flag is cleared in uintVal
1.347 + // so the failure can be detected in DoCreate
1.348 + uintVal &= ~USER_SIDE_CLIENT_BIT_MASK; // Copied from rescontrol_export
1.349 + }
1.350 + channel->SetClientHandle((TInt)uintVal);
1.351 + NKern::FSSignal(channel->iFastSem);
1.352 + }
1.353 +
1.354 +
1.355 +TInt DChannelResManUs::RegisterWithResCtrlr()
1.356 + {
1.357 + __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::RegisterWithResCtrlr"));
1.358 + TInt r = KErrNone;
1.359 + // Initialise the channel's fast semaphore
1.360 + iFastSem = new NFastSemaphore();
1.361 + if(iFastSem == NULL)
1.362 + r = KErrNoMemory;
1.363 + else
1.364 + {
1.365 + iFastSem->iOwningThread = (NThreadBase*)NKern::CurrentThread();
1.366 +
1.367 + // Attempt to perform registration with the Resource Controller on behalf of the client.
1.368 + SetDfcQ(((DDeviceResManUs*)(iDevice))->iSharedDfcQue);
1.369 + TDfc tempDfc(RegistrationDfcFunc, this, iDfcQ, KResManUsRegistrationPriority);
1.370 +
1.371 + // Block this thread until the DFC has executed
1.372 + tempDfc.Enque();
1.373 + NKern::FSWait(iFastSem);
1.374 + // Have finished with iFastSem
1.375 + delete iFastSem;
1.376 +
1.377 + // Registration complete - check success
1.378 + if(!(USER_SIDE_CLIENT_BIT_MASK & ClientHandle()))
1.379 + {
1.380 + // Registration failed
1.381 + r = KErrCouldNotConnect;
1.382 + }
1.383 + // Start receiving messages ...
1.384 + iMsgQ.Receive();
1.385 + }
1.386 + return r;
1.387 + }
1.388 +
1.389 +TInt DChannelResManUs::DoCreate(TInt /*aUnit*/,
1.390 + const TDesC8* aInfo,
1.391 + const TVersion &aVer)
1.392 +// Create the channel from the passed info.
1.393 + {
1.394 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer)"));
1.395 +
1.396 + TInt r = KErrNone;
1.397 + iPddPtr = ((DUserSideProxyInterface*)iPdd)->iController;
1.398 + // Check client has appropriate capabilities
1.399 + if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by DDevicePowerRsrc::Create")))
1.400 + return KErrPermissionDenied;
1.401 +
1.402 + // Check software version
1.403 + if (!Kern::QueryVersionSupported(TVersion(KResManUsMajorVersionNumber,
1.404 + KResManUsMinorVersionNumber,
1.405 + KResManUsBuildVersionNumber),
1.406 + aVer))
1.407 + return KErrNotSupported;
1.408 +
1.409 + // Implementation note: if this method fails, the destructor will be invoked
1.410 + // as part of which all successfully-allocated memory will be freed. Therefore,
1.411 + // no memory will be explicitly freed in the event of failure in the code which follows.
1.412 +
1.413 + // Allocate the arrays used for acquiring client, resource and dependency information
1.414 + if((iClientNamesResCtrl = HBuf8::New(KNumClientNamesResCtrl * sizeof(TPowerClientInfoV01)))==NULL)
1.415 + return KErrNoMemory;
1.416 + if((iResourceInfoResCtrl = HBuf8::New(KNumResourceInfoResCtrl * sizeof(TPowerResourceInfoV01)))==NULL)
1.417 + return KErrNoMemory;
1.418 + if((iResourceDependencyIds = HBuf8::New(KNumResourceDependencies * sizeof(SResourceDependencyInfo)))==NULL)
1.419 + return KErrNoMemory;
1.420 + // Obtain the channel name to use
1.421 + if((r=GetValidName(aInfo))!=KErrNone)
1.422 + return r;
1.423 +#ifdef PRM_ENABLE_EXTENDED_VERSION
1.424 + iResDepsValid = 0;
1.425 +#endif
1.426 +
1.427 +#ifdef PRM_US_INSTRUMENTATION_MACRO
1.428 + PRM_US_OPEN_CHANNEL_START_TRACE;
1.429 +#endif
1.430 +
1.431 + // Set up the request tracking support
1.432 + iGetStateTracker = new TTrackingControl();
1.433 + iSetStateTracker = new TTrackingControl();;
1.434 + iListenableTracker = new TTrackingControl();
1.435 + if((iGetStateTracker==NULL) || (iSetStateTracker==NULL) || (iListenableTracker==NULL))
1.436 + return KErrNoMemory;
1.437 +
1.438 + // Register with the Resource Controller
1.439 + r = RegisterWithResCtrlr();
1.440 +
1.441 +#ifdef PRM_US_INSTRUMENTATION_MACRO
1.442 + PRM_US_OPEN_CHANNEL_END_TRACE;
1.443 +#endif
1.444 +
1.445 + return r;
1.446 + }
1.447 +
1.448 +//Override sendMsg to allow data copy in the context of client thread for WDP.
1.449 +TInt DChannelResManUs::SendMsg(TMessageBase* aMsg)
1.450 + {
1.451 + TThreadMessage& m = *(TThreadMessage*)aMsg;
1.452 + TInt id = m.iValue;
1.453 + TInt r = KErrNone;
1.454 + if (id != (TInt)ECloseMsg && id != KMaxTInt)
1.455 + {
1.456 + if (id<0)
1.457 + {
1.458 + TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
1.459 + r = SendRequest(aMsg);
1.460 + if (r != KErrNone)
1.461 + Kern::RequestComplete(pS,r);
1.462 + }
1.463 + else
1.464 + r = SendControl(aMsg);
1.465 + }
1.466 + else
1.467 + r = DLogicalChannel::SendMsg(aMsg);
1.468 + return r;
1.469 + }
1.470 +
1.471 +TInt DChannelResManUs::SendRequest(TMessageBase* aMsg)
1.472 + {
1.473 + TThreadMessage& m = *(TThreadMessage*)aMsg;
1.474 + TInt id = ~m.iValue;
1.475 + TRequestStatus* pS = (TRequestStatus*)m.Ptr0();
1.476 + TInt r = KErrNone;
1.477 + TTrackingBuffer *trackBuf = NULL;
1.478 + TUint parms[4];
1.479 + TPowerResourceCb *callBack;
1.480 + DPowerResourceNotification *prn;
1.481 +
1.482 + switch(id)
1.483 + {
1.484 + case RBusDevResManUs::EChangeResourceState:
1.485 + {
1.486 + __ASSERT_ALWAYS(m.Ptr2() != NULL, RESMANUS_FAULT());
1.487 +#ifdef _DUMP_TRACKERS
1.488 + if((r=DumpTracker(iSetStateTracker))!=KErrNone)
1.489 + break;
1.490 +#endif
1.491 + r = GetAndInitTrackingBuffer(iSetStateTracker, trackBuf, (TUint)m.Ptr1(), pS);
1.492 + if( r != KErrNone)
1.493 + return r;
1.494 + callBack = &(((TTrackSetStateBuf*)trackBuf)->iCtrlBlock);
1.495 + new (callBack) TPowerResourceCb(&AsyncCallBackFn, (TAny*)trackBuf, iDfcQ, KResManCallBackPriority);
1.496 + parms[0] = (TUint)m.Ptr2();
1.497 + parms[1] = (TUint)callBack;
1.498 + m.iArg[2] = &(parms[0]);
1.499 + break;
1.500 + }
1.501 + case RBusDevResManUs::EGetResourceState:
1.502 + {
1.503 + __ASSERT_ALWAYS(m.Ptr2() != NULL, RESMANUS_FAULT());
1.504 + umemget32(&(parms[0]), m.Ptr2(), 3*sizeof(TInt));
1.505 +#ifdef _DUMP_TRACKERS
1.506 + if((r=DumpTracker(iGetStateTracker))!=KErrNone)
1.507 + break;
1.508 +#endif
1.509 + r = GetStateBuffer(iGetStateTracker, trackBuf, (TUint)m.Ptr1(), (TInt*)parms[1], (TInt*)parms[2], callBack, pS);
1.510 + if(r != KErrNone)
1.511 + return r;
1.512 + parms[3] = (TUint)callBack;
1.513 + m.iArg[2] = &(parms[0]);
1.514 + break;
1.515 + }
1.516 + case RBusDevResManUs::ERequestChangeNotification:
1.517 + {
1.518 + __ASSERT_ALWAYS(m.Ptr1() != NULL, RESMANUS_FAULT());
1.519 + r = GetAndInitTrackingBuffer(iListenableTracker, trackBuf, (TUint)m.Ptr1(), pS);
1.520 + if(r != KErrNone)
1.521 + return r;
1.522 + prn = &(((TTrackNotifyBuf*)trackBuf)->iNotifyBlock);
1.523 + new (prn) DPowerResourceNotification(&AsyncCallBackFn, (TAny*)trackBuf, iDfcQ, KResManCallBackPriority);
1.524 + m.iArg[2] = (TAny*)prn;
1.525 + break;
1.526 + }
1.527 + case RBusDevResManUs::ERequestQualifiedChangeNotification:
1.528 + {
1.529 + __ASSERT_ALWAYS(m.Ptr1() != NULL, RESMANUS_FAULT());
1.530 + __ASSERT_ALWAYS(m.Ptr2() != NULL, RESMANUS_FAULT());
1.531 + umemget32(&(parms[0]), m.Ptr2(), 2*sizeof(TUint));
1.532 + m.iArg[2] = &parms[0];
1.533 + r = GetAndInitTrackingBuffer(iListenableTracker, trackBuf, (TUint)parms[0], pS);
1.534 + if(r != KErrNone)
1.535 + return r;
1.536 + prn = &(((TTrackNotifyBuf*)trackBuf)->iNotifyBlock);
1.537 + new (prn) DPowerResourceNotification(&AsyncCallBackFn, (TAny*)trackBuf, iDfcQ, KResManCallBackPriority);
1.538 + parms[2] = (TUint)prn;
1.539 + break;
1.540 + }
1.541 + default:
1.542 + {
1.543 + return KErrNotSupported;
1.544 + }
1.545 + }
1.546 +
1.547 + if(r == KErrNone)
1.548 + r = DLogicalChannel::SendMsg(aMsg);
1.549 + if(r != KErrNone)
1.550 + FreeTrackingBuffer(trackBuf);
1.551 + return r;
1.552 + }
1.553 +
1.554 +
1.555 +TInt DChannelResManUs::SendControl(TMessageBase* aMsg)
1.556 + {
1.557 + TThreadMessage& m = *(TThreadMessage*)aMsg;
1.558 + TInt id = m.iValue;
1.559 + TInt param1 = 0;
1.560 + TUint parms[4];
1.561 + TAny* a1 = m.Ptr0();
1.562 + TAny* a2 = m.Ptr1();
1.563 + TAny* ptr1 = NULL;
1.564 + switch(id)
1.565 + {
1.566 + case RBusDevResManUs::EInitialise:
1.567 + {
1.568 + __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
1.569 + TUint8 stateRes[3];
1.570 + umemget(&(stateRes[0]), a1, 3*sizeof(TUint8));
1.571 + m.iArg[0] = &(stateRes[0]);
1.572 + break;
1.573 + }
1.574 + case RBusDevResManUs::EGetNoOfResources:
1.575 + case RBusDevResManUs::EGetResourceControllerVersion:
1.576 + {
1.577 + __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
1.578 + m.iArg[0] = ¶m1;
1.579 + break;
1.580 + }
1.581 + case RBusDevResManUs::EGetNoOfClients:
1.582 + case RBusDevResManUs::EGetNumClientsUsingResource:
1.583 + {
1.584 + __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
1.585 + __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
1.586 + umemget32(&(parms[0]), a2, 3*sizeof(TUint));
1.587 + m.iArg[1] = &(parms[0]);
1.588 + m.iArg[0] = ¶m1;
1.589 + break;
1.590 + }
1.591 + case RBusDevResManUs::EGetNumResourcesInUseByClient:
1.592 + {
1.593 + __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
1.594 + __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
1.595 + TBuf8 <MAX_NAME_LENGTH_IN_RESMAN> clientName;
1.596 + Kern::KUDesGet(clientName, *(TDesC8*)m.Ptr0());
1.597 + m.iArg[0] = (TAny*)&clientName;
1.598 + umemget32(&(parms[0]), m.Ptr1(), 2*sizeof(TUint));
1.599 + param1 = parms[1];
1.600 + m.iArg[1] = ¶m1;
1.601 + break;
1.602 + }
1.603 + case RBusDevResManUs::EGetResourceIdByName:
1.604 + {
1.605 + __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
1.606 + __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
1.607 + TBuf8 <MAX_NAME_LENGTH_IN_RESMAN> resourceName;
1.608 + Kern::KUDesGet(resourceName, *(TDesC8*)m.Ptr0());
1.609 + m.iArg[0] = (TAny*)&resourceName;
1.610 + m.iArg[1] = ¶m1;
1.611 + break;
1.612 + }
1.613 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
1.614 + case RBusDevResManUs::EGetNumCandidateAsyncResources:
1.615 + case RBusDevResManUs::EGetNumCandidateSharedResources:
1.616 + {
1.617 + __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
1.618 + m.iArg[0] = ¶m1;
1.619 + break;
1.620 + }
1.621 + case RBusDevResManUs::EGetCandidateAsyncResourceId:
1.622 + case RBusDevResManUs::EGetCandidateSharedResourceId:
1.623 + {
1.624 + __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
1.625 + m.iArg[1] = ¶m1;
1.626 + break;
1.627 + }
1.628 +#endif
1.629 + case RBusDevResManUs::EGetNumDependentsForResource:
1.630 + {
1.631 + __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
1.632 + __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
1.633 + umemget32(&(parms[0]), m.Ptr1(), 2*sizeof(TUint));
1.634 + m.iArg[1] = &(parms[0]);
1.635 + m.iArg[0] = ¶m1;
1.636 + break;
1.637 + }
1.638 + case RBusDevResManUs::EGetDependentsIdForResource:
1.639 + {
1.640 + __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
1.641 + __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
1.642 + umemget32(&(parms[0]), m.Ptr1(), 3*sizeof(TUint));
1.643 + TInt len, maxLen;
1.644 + ptr1 = (TAny*)parms[1];
1.645 + Kern::KUDesInfo(*(const TDesC8*)parms[1], len, maxLen);
1.646 + umemget32(¶m1, m.Ptr0(), sizeof(TUint));
1.647 + if((maxLen - len) < (TInt)(param1 * sizeof(SResourceDependencyInfo)))
1.648 + {
1.649 + return KErrArgument;
1.650 + }
1.651 + m.iArg[0] = ¶m1;
1.652 + m.iArg[1] = &(parms[0]);
1.653 + break;
1.654 + }
1.655 + case RBusDevResManUs::EGetResourceInfo:
1.656 + {
1.657 + __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
1.658 + __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
1.659 + TResourceInfoBuf buf;
1.660 + m.iArg[1] = &buf;
1.661 + break;
1.662 + }
1.663 + case RBusDevResManUs::EGetAllResourcesInfo:
1.664 + {
1.665 + __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
1.666 + __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
1.667 + umemget32(&(parms[0]), m.Ptr1(), 2*sizeof(TUint));
1.668 + ptr1 = (TAny*)parms[0];
1.669 + umemget32(¶m1, (TAny*)parms[0], sizeof(TUint));
1.670 + parms[0] =(TUint)¶m1;
1.671 + RSimplePointerArray<TResourceInfoBuf> infoPtrs;
1.672 + umemget(&infoPtrs, m.Ptr0(), sizeof(RSimplePointerArray<TResourceInfoBuf>));
1.673 + if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
1.674 + return KErrArgument;
1.675 + m.iArg[1] = &(parms[0]);
1.676 + break;
1.677 + }
1.678 + case RBusDevResManUs::EGetInfoOnClientsUsingResource:
1.679 + {
1.680 + __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
1.681 + __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
1.682 + umemget32(&parms[0], m.Ptr1(), 4*sizeof(TUint));
1.683 + ptr1 = (TAny*)parms[0];
1.684 + umemget32(¶m1, (TAny*)parms[0], sizeof(TUint));
1.685 + parms[0] = (TUint)¶m1;
1.686 + RSimplePointerArray<TClientInfoBuf>infoPtrs;
1.687 + umemget(&infoPtrs, m.Ptr0(), sizeof(RSimplePointerArray<TClientInfoBuf>));
1.688 + if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
1.689 + return KErrArgument;
1.690 + m.iArg[1] = &(parms[0]);
1.691 + break;
1.692 + }
1.693 + case RBusDevResManUs::EGetNamesAllClients:
1.694 + {
1.695 + __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
1.696 + __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
1.697 + umemget32(&parms[0], m.Ptr1(), 4*sizeof(TUint));
1.698 + ptr1 = (TAny*)parms[0];
1.699 + umemget32(¶m1, (TAny*)parms[0], sizeof(TUint));
1.700 + parms[0] = (TUint)¶m1;
1.701 + RSimplePointerArray<TClientName> infoPtrs;
1.702 + umemget(&infoPtrs, m.Ptr0(), sizeof(RSimplePointerArray<TClientName>));
1.703 + if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
1.704 + return KErrArgument;
1.705 + m.iArg[1] = &(parms[0]);
1.706 + break;
1.707 + }
1.708 + case RBusDevResManUs::EGetInfoOnResourcesInUseByClient:
1.709 + {
1.710 + __ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
1.711 + __ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
1.712 + TBuf8 <MAX_NAME_LENGTH_IN_RESMAN> clientName;
1.713 + Kern::KUDesGet(clientName, *(TDesC8*)m.Ptr0());
1.714 + m.iArg[0] = (TAny*)&clientName;
1.715 + umemget32(&parms[0], m.Ptr1(), 3*sizeof(TUint));
1.716 + ptr1 = (TAny*)parms[0];
1.717 + umemget32(¶m1, (TAny*)parms[0], sizeof(TUint));
1.718 + parms[0] = (TUint)¶m1;
1.719 + RSimplePointerArray<TResourceInfoBuf> infoPtrs;
1.720 + umemget(&infoPtrs, (TAny*)parms[1], sizeof(RSimplePointerArray<TResourceInfoBuf>));
1.721 + if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
1.722 + return KErrArgument;
1.723 + m.iArg[1] = &(parms[0]);
1.724 + break;
1.725 + }
1.726 + }
1.727 +
1.728 + TInt r = DLogicalChannel::SendMsg(aMsg);
1.729 + if(r != KErrNone)
1.730 + return r;
1.731 +
1.732 + switch(id)
1.733 + {
1.734 + case RBusDevResManUs::EGetNoOfResources:
1.735 + case RBusDevResManUs::EGetNoOfClients:
1.736 + case RBusDevResManUs::EGetNumClientsUsingResource:
1.737 + case RBusDevResManUs::EGetResourceControllerVersion:
1.738 + case RBusDevResManUs::EGetNumDependentsForResource:
1.739 + {
1.740 + umemput32(a1, (TAny*)¶m1, sizeof(TUint));
1.741 + break;
1.742 + }
1.743 + case RBusDevResManUs::EGetNumResourcesInUseByClient:
1.744 + {
1.745 + umemput32((TAny*)parms[0], (TAny*)¶m1, sizeof(TUint));
1.746 + break;
1.747 + }
1.748 + case RBusDevResManUs::EGetResourceIdByName:
1.749 + {
1.750 + umemput32(a2, (TAny*)¶m1, sizeof(TUint));
1.751 + break;
1.752 + }
1.753 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
1.754 + case RBusDevResManUs::EGetNumCandidateAsyncResources:
1.755 + case RBusDevResManUs::EGetNumCandidateSharedResources:
1.756 + {
1.757 + umemput32(a1, (TAny*)¶m1, sizeof(TUint));
1.758 + break;
1.759 + }
1.760 + case RBusDevResManUs::EGetCandidateAsyncResourceId:
1.761 + case RBusDevResManUs::EGetCandidateSharedResourceId:
1.762 + {
1.763 + umemput32(a2, (TAny*)¶m1, sizeof(TUint));
1.764 + break;
1.765 + }
1.766 +#endif
1.767 + case RBusDevResManUs::EGetDependentsIdForResource:
1.768 + {
1.769 + r = Kern::ThreadDesWrite(iClient,(TAny*)ptr1, (const TDesC8&)*(SResourceDependencyInfo*)parms[1], 0);
1.770 + if(r == KErrOverflow) //This is done to retain the error as per API spec
1.771 + r = KErrArgument;
1.772 + break;
1.773 + }
1.774 + case RBusDevResManUs::EGetResourceInfo:
1.775 + {
1.776 + Kern::KUDesPut(*(TDes8*)a2, (const TDesC8&)*(TResourceInfoBuf*)m.Ptr1());
1.777 + break;
1.778 + }
1.779 + case RBusDevResManUs::EGetAllResourcesInfo:
1.780 + {
1.781 + TUint numToCopy;
1.782 + RSimplePointerArray<TResourceInfoBuf> infoPtrs;
1.783 + umemget(&infoPtrs, a1, sizeof(RSimplePointerArray<TResourceInfoBuf>));
1.784 + numToCopy = (infoPtrs.Count() < param1) ? infoPtrs.Count() : param1;
1.785 + umemput32(ptr1, (TAny*)¶m1, sizeof(TUint));
1.786 + TResourceInfoBuf** entriesAddr = infoPtrs.Entries();
1.787 + TInt* entryPtr = (TInt*)entriesAddr;
1.788 + TPowerResourceInfoV01 *currRes = (TPowerResourceInfoV01*)iResourceInfoResCtrl->Ptr();
1.789 + TResourceInfoBuf* clientAddr;
1.790 + TResourceInfoBuf tempInfo;
1.791 + for(TUint index = 0; index < numToCopy; index++)
1.792 + {
1.793 + umemget32(&clientAddr, entryPtr, sizeof(TResourceInfoBuf*));
1.794 + entryPtr++;
1.795 + r = ExtractResourceInfo(currRes, tempInfo);
1.796 + if(r != KErrNone)
1.797 + return r;
1.798 + umemput((TAny*)clientAddr, (TAny*)&(tempInfo), tempInfo.Length());
1.799 + currRes++;
1.800 + }
1.801 + break;
1.802 + }
1.803 + case RBusDevResManUs::EGetInfoOnClientsUsingResource:
1.804 + {
1.805 + TUint numToCopy;
1.806 + RSimplePointerArray<TClientInfoBuf> infoPtrs;
1.807 + umemget(&infoPtrs, a1, sizeof(RSimplePointerArray<TClientName>));
1.808 + numToCopy = infoPtrs.Count();
1.809 + TClientInfoBuf** entriesAddr = infoPtrs.Entries();
1.810 + TInt* entryPtr = (TInt*)entriesAddr;
1.811 + TPowerClientInfoV01* rcDataPtr = (TPowerClientInfoV01*)iClientNamesResCtrl->Ptr();
1.812 + TClientInfoBuf* clientAddr;
1.813 + TUint userSideClients = 0;
1.814 + TClientInfoBuf tempInfo;
1.815 + for(TInt index = 0; index < param1; index++)
1.816 + {
1.817 + if((!parms[1]) && !(rcDataPtr->iClientId & USER_SIDE_CLIENT_BIT_MASK))
1.818 + {
1.819 + rcDataPtr++;
1.820 + continue;
1.821 + }
1.822 + if(numToCopy == 0)
1.823 + {
1.824 + userSideClients++;
1.825 + continue;
1.826 + }
1.827 + umemget32(&clientAddr, entryPtr, sizeof(TClientName*));
1.828 + entryPtr++;
1.829 + tempInfo().iId = rcDataPtr->iClientId;
1.830 + tempInfo().iName = *rcDataPtr->iClientName;
1.831 + Kern::InfoCopy(*clientAddr, tempInfo);
1.832 + rcDataPtr++;
1.833 + numToCopy--;
1.834 + userSideClients++;
1.835 + }
1.836 + if(parms[1])
1.837 + umemput32(ptr1, (TAny*)¶m1, sizeof(TUint));
1.838 + else
1.839 + umemput32(ptr1, (TAny*)&userSideClients, sizeof(TUint));
1.840 + break;
1.841 + }
1.842 + case RBusDevResManUs::EGetNamesAllClients:
1.843 + {
1.844 + TUint numToCopy;
1.845 + RSimplePointerArray<TClientName> infoPtrs;
1.846 + umemget(&infoPtrs, a1, sizeof(RSimplePointerArray<TClientName>));
1.847 + numToCopy = infoPtrs.Count();
1.848 + TClientName** entriesAddr = infoPtrs.Entries();
1.849 + TInt* entryPtr = (TInt*)entriesAddr;
1.850 + TPowerClientInfoV01* rcDataPtr = (TPowerClientInfoV01*)iClientNamesResCtrl->Ptr();
1.851 + TClientName* clientAddr;
1.852 + TUint userSideClients = 0;
1.853 + for(TInt index = 0; index < param1; index++)
1.854 + {
1.855 + if((!parms[1]) && !(rcDataPtr->iClientId & USER_SIDE_CLIENT_BIT_MASK))
1.856 + {
1.857 + rcDataPtr++;
1.858 + continue;
1.859 + }
1.860 + if(numToCopy == 0)
1.861 + {
1.862 + userSideClients++;
1.863 + continue;
1.864 + }
1.865 + umemget32(&clientAddr, entryPtr, sizeof(TClientName*));
1.866 + entryPtr++;
1.867 + Kern::KUDesPut(*((TDes8*)clientAddr), *(const TDesC8*)rcDataPtr->iClientName);
1.868 + rcDataPtr++;
1.869 + numToCopy--;
1.870 + userSideClients++;
1.871 + }
1.872 + if(parms[1])
1.873 + umemput32(ptr1, (TAny*)¶m1, sizeof(TUint));
1.874 + else
1.875 + umemput32(ptr1, (TAny*)&userSideClients, sizeof(TUint));
1.876 + break;
1.877 + }
1.878 + case RBusDevResManUs::EGetInfoOnResourcesInUseByClient:
1.879 + {
1.880 + TUint numToCopy;
1.881 + RSimplePointerArray<TResourceInfoBuf> infoPtrs;
1.882 + umemget(&infoPtrs, (TAny*)parms[1], sizeof(RSimplePointerArray<TResourceInfoBuf>));
1.883 + numToCopy = (infoPtrs.Count() < param1) ? infoPtrs.Count() : param1;
1.884 + umemput32(ptr1, (TAny*)¶m1, sizeof(TUint));
1.885 + TResourceInfoBuf** entriesAddr = infoPtrs.Entries();
1.886 + TInt* entryPtr = (TInt*)entriesAddr;
1.887 + TPowerResourceInfoV01* currRes = (TPowerResourceInfoV01*)iResourceInfoResCtrl->Ptr();
1.888 + TResourceInfoBuf* clientAddr;
1.889 + TResourceInfoBuf tempInfo;
1.890 + for(TUint index = 0; index < numToCopy; index++)
1.891 + {
1.892 + umemget32(&clientAddr, entryPtr, sizeof(TResourceInfoBuf*));
1.893 + entryPtr++;
1.894 + r = ExtractResourceInfo(currRes, tempInfo);
1.895 + if(r != KErrNone)
1.896 + return r;
1.897 + umemput((TAny*)clientAddr, (TAny*)&(tempInfo), tempInfo.Length());
1.898 + currRes++;
1.899 + }
1.900 + break;
1.901 + }
1.902 + }
1.903 + return r;
1.904 + }
1.905 +
1.906 +void DChannelResManUs::HandleMsg(TMessageBase* aMsg)
1.907 + {
1.908 + TThreadMessage& m=*(TThreadMessage*)aMsg;
1.909 + TInt id=m.iValue;
1.910 +
1.911 + __KTRACE_OPT(KRESMANAGER, Kern::Printf(" >ldd: DChannelResManUs::HandleMsg(TMessageBase* aMsg) id=%d\n", id));
1.912 +
1.913 + if (id==(TInt)ECloseMsg)
1.914 + {
1.915 + // Deregister here to ensure the correct thread ID is read
1.916 + if(ClientHandle() != 0)
1.917 + {
1.918 + // Must de-register from Resource Controller before closing down
1.919 + // Not checking return value - still need to delete allocated buffers
1.920 +#ifdef PRM_US_INSTRUMENTATION_MACRO
1.921 + PRM_US_DEREGISTER_CLIENT_START_TRACE;
1.922 +#endif
1.923 + ((DPowerResourceController*)iPddPtr)->DeregisterProxyClient(ClientHandle());
1.924 +
1.925 +#ifdef PRM_US_INSTRUMENTATION_MACRO
1.926 + PRM_US_DEREGISTER_CLIENT_END_TRACE;
1.927 +#endif
1.928 + SetClientHandle(0);
1.929 + }
1.930 + iMsgQ.iMessage->Complete(KErrNone,EFalse);
1.931 + return;
1.932 + }
1.933 + else if (id==KMaxTInt)
1.934 + {
1.935 + // DoCancel
1.936 + DoCancel(m.Int0());
1.937 + m.Complete(KErrNone,ETrue);
1.938 + return;
1.939 + }
1.940 +
1.941 + if (id<0)
1.942 + {
1.943 + // DoRequest
1.944 + TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
1.945 + TInt r=DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
1.946 + m.Complete(r,ETrue);
1.947 + }
1.948 + else
1.949 + {
1.950 + // DoControl
1.951 + __KTRACE_OPT(KRESMANAGER, Kern::Printf(" >ldd: do control id=%d...\n", id));
1.952 + TInt r=DoControl(id,m.Ptr0(),m.Ptr1());
1.953 + m.Complete(r,ETrue);
1.954 + }
1.955 + }
1.956 +
1.957 +TInt DChannelResManUs::CancelTrackerRequests(TTrackingControl* aTracker, TBool aSingleRsrc, TUint aResourceId, TRequestStatus* aStatus)
1.958 + {
1.959 + // Cancel all outstanding requests from this client for a specified operation on
1.960 + // a specified resource
1.961 +
1.962 + // Loop all entries in the iBusyQue of requests to locate a match for the
1.963 + // operation type and resource ID
1.964 + //
1.965 + // For each match, remove the buffer from the busy queue and return to the free queue
1.966 + // If the request is already being processed, and so the callback function will be called
1.967 + // later, then the callback will exit gracefully.
1.968 + //
1.969 + __KTRACE_OPT(KRESMANAGER, Kern::Printf(" > DChannelResManUs::CancelTrackerRequests"));
1.970 + TInt returnVal = KErrNone;
1.971 + TBool statusMatched=EFalse;
1.972 + TTrackingBuffer* firstLink = NULL;
1.973 + TTrackingBuffer* lastLink = NULL;
1.974 + TInt type = aTracker->iType;
1.975 +
1.976 +#ifdef PRM_US_INSTRUMENTATION_MACRO
1.977 + if(type==EGetState)
1.978 + {
1.979 + PRM_US_CANCEL_GET_RESOURCE_STATE_START_TRACE;
1.980 + }
1.981 + else if(type==ESetState)
1.982 + {
1.983 + PRM_US_CANCEL_SET_RESOURCE_STATE_START_TRACE;
1.984 + }
1.985 +#endif
1.986 +
1.987 + if(aTracker->iBusyQue != NULL)
1.988 + {
1.989 + firstLink = (TTrackingBuffer*)(aTracker->iBusyQue->iA.iNext);
1.990 + lastLink = (TTrackingBuffer*)(&(aTracker->iBusyQue->iA));
1.991 + }
1.992 + while(( firstLink!=lastLink )&&(!statusMatched))
1.993 + {
1.994 + TTrackingBuffer* buffer = firstLink;
1.995 + TUint resourceId = buffer->GetResourceId();
1.996 + if(aSingleRsrc)
1.997 + if(resourceId != aResourceId) // Required resource?
1.998 + {
1.999 + firstLink=(TTrackingBuffer*)(firstLink->iNext);
1.1000 + continue;
1.1001 + }
1.1002 + if(aStatus!=NULL)
1.1003 + {
1.1004 + TClientRequest *request;
1.1005 + GET_USER_REQUEST(request, buffer, type)
1.1006 + if(request->StatusPtr() == aStatus)
1.1007 + {
1.1008 + statusMatched = ETrue;
1.1009 + }
1.1010 + else
1.1011 + {
1.1012 + firstLink=(TTrackingBuffer*)(firstLink->iNext);
1.1013 + continue;
1.1014 + }
1.1015 + }
1.1016 + TInt r = KErrNone;
1.1017 + if(type==EGetState)
1.1018 + {
1.1019 + TTrackGetStateBuf* stateBuf = (TTrackGetStateBuf*)firstLink;
1.1020 + r=((DPowerResourceController*)iPddPtr)->CancelAsyncRequestCallBack(ClientHandle(),
1.1021 + resourceId, (stateBuf->iCtrlBlock));
1.1022 + }
1.1023 + else if(type==ESetState)
1.1024 + {
1.1025 + TTrackSetStateBuf* stateBuf = (TTrackSetStateBuf*)firstLink;
1.1026 + r = ((DPowerResourceController*)iPddPtr)->CancelAsyncRequestCallBack(ClientHandle(),
1.1027 + resourceId, (stateBuf->iCtrlBlock));
1.1028 + }
1.1029 + else if(type==ENotify)
1.1030 + {
1.1031 + TTrackNotifyBuf* notifyBuf = (TTrackNotifyBuf*)firstLink;
1.1032 + r=((DPowerResourceController*)iPddPtr)->CancelNotification(ClientHandle(), resourceId,
1.1033 + notifyBuf->iNotifyBlock);
1.1034 + }
1.1035 +
1.1036 + // Process the accumulated return value
1.1037 + if((r==KErrCompletion)&&((returnVal==KErrNone)||(returnVal==KErrCancel)))
1.1038 + {
1.1039 + returnVal=KErrCompletion;
1.1040 + }
1.1041 + else if((r==KErrInUse)&&
1.1042 + ((returnVal==KErrNone)||(returnVal==KErrCompletion)||(returnVal==KErrCancel)))
1.1043 + {
1.1044 + returnVal=KErrInUse;
1.1045 + }
1.1046 + else if(r!=KErrCancel)
1.1047 + {
1.1048 + returnVal=r;
1.1049 + }
1.1050 +
1.1051 + // Return the tracking buffer to the free queue
1.1052 + TTrackingBuffer* tempLink = (TTrackingBuffer*)(firstLink->iNext);
1.1053 + FreeTrackingBuffer(firstLink);
1.1054 + firstLink = tempLink;
1.1055 +
1.1056 +#ifdef PRM_US_INSTRUMENTATION_MACRO
1.1057 + if(type==EGetState)
1.1058 + {
1.1059 + PRM_US_CANCEL_GET_RESOURCE_STATE_END_TRACE;
1.1060 + }
1.1061 + else if(type==ESetState)
1.1062 + {
1.1063 + PRM_US_CANCEL_SET_RESOURCE_STATE_END_TRACE;
1.1064 + }
1.1065 +#endif
1.1066 + // Complete the TRequestStatus object
1.1067 + if((r!=KErrCompletion)&&(r!=KErrInUse))
1.1068 + {
1.1069 + TClientRequest* request;
1.1070 + GET_USER_REQUEST(request, buffer, type)
1.1071 + Kern::QueueRequestComplete(iClient, request, r);
1.1072 + }
1.1073 +
1.1074 + } // while
1.1075 + return returnVal;
1.1076 + }
1.1077 +
1.1078 +
1.1079 +TTrackingControl* DChannelResManUs::MapRequestToTracker(TInt aRequestType)
1.1080 +// Utility function to map identifiers for cancel commands to request types.
1.1081 + {
1.1082 + TTrackingControl *tracker=NULL;
1.1083 + switch(aRequestType)
1.1084 + {
1.1085 + case RBusDevResManUs::ECancelChangeResourceStateRequests:
1.1086 + case RBusDevResManUs::ECancelChangeResourceState:
1.1087 + {
1.1088 + tracker=iSetStateTracker;
1.1089 + break;
1.1090 + }
1.1091 + case RBusDevResManUs::ECancelGetResourceStateRequests:
1.1092 + case RBusDevResManUs::ECancelGetResourceState:
1.1093 + {
1.1094 + tracker=iGetStateTracker;
1.1095 + break;
1.1096 + }
1.1097 + case RBusDevResManUs::ECancelChangeNotificationRequests:
1.1098 + case RBusDevResManUs::ECancelRequestChangeNotification:
1.1099 + {
1.1100 + tracker=iListenableTracker;
1.1101 + break;
1.1102 + }
1.1103 + default:
1.1104 + {
1.1105 + __ASSERT_ALWAYS(0,RESMANUS_FAULT());
1.1106 + }
1.1107 + }
1.1108 + return tracker;
1.1109 + }
1.1110 +
1.1111 +
1.1112 +TInt DChannelResManUs::CancelRequestsOfType(TInt aRequestType, TRequestStatus* aStatus)
1.1113 +// Cancel a particular request. This may be qualified by the type of operation
1.1114 + {
1.1115 + __ASSERT_ALWAYS(((aRequestType==RBusDevResManUs::ECancelChangeResourceState)||
1.1116 + (aRequestType==RBusDevResManUs::ECancelGetResourceState)||
1.1117 + (aRequestType==RBusDevResManUs::ECancelRequestChangeNotification)||
1.1118 + (KMaxTInt)),
1.1119 + RESMANUS_FAULT());
1.1120 + // For the KMaxTInt case, the type of the request is not known and so all trackers
1.1121 + // must be considered before the request is found.
1.1122 + // For all other cases, only the relevant tracker is searched.
1.1123 + TInt r=KErrNone;
1.1124 + if(aRequestType!=KMaxTInt)
1.1125 + {
1.1126 + TTrackingControl*tracker=MapRequestToTracker(aRequestType);
1.1127 + r=CancelTrackerRequests(tracker, EFalse, 0, aStatus);
1.1128 + }
1.1129 + else
1.1130 + {
1.1131 + TTrackingControl* tracker[3] = {iGetStateTracker, iSetStateTracker, iListenableTracker};
1.1132 + TUint8 index=0;
1.1133 + while((index<3) && (r==KErrNone))
1.1134 + {
1.1135 + r=CancelTrackerRequests(tracker[index], EFalse, 0, aStatus);
1.1136 + ++index;
1.1137 + }
1.1138 + }
1.1139 + if(r==KErrCancel)
1.1140 + r=KErrNone; // All cancellations were successful
1.1141 +
1.1142 + return r;
1.1143 + }
1.1144 +
1.1145 +
1.1146 +void DChannelResManUs::DoCancel(TInt aMask)
1.1147 +// Cancel an outstanding request.
1.1148 + {
1.1149 + TRequestStatus* status = (TRequestStatus*)aMask;
1.1150 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoCancel, TRequestStatus addr = 0x%x",(TInt)status));
1.1151 +
1.1152 + CancelRequestsOfType(KMaxTInt, status); // Ignore return value
1.1153 + return;
1.1154 + }
1.1155 +
1.1156 +TInt DChannelResManUs::DoRequest(TInt aReqNo, TRequestStatus* /*aStatus*/, TAny* a1, TAny* a2)
1.1157 +// Asynchronous requests.
1.1158 + {
1.1159 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)"));
1.1160 +
1.1161 + TInt r=KErrNone;
1.1162 + switch (aReqNo)
1.1163 + {
1.1164 + case RBusDevResManUs::EChangeResourceState:
1.1165 + {
1.1166 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case EChangeResourceState"));
1.1167 + // a1 specifies the identifier of the required resource
1.1168 + // a2 specifies the required state for the resource
1.1169 + //
1.1170 + TUint *param = (TUint*)a2;
1.1171 + TUint resourceId = (TUint)a1;
1.1172 + TInt newState = (TInt)param[0];
1.1173 +
1.1174 +#ifdef PRM_US_INSTRUMENTATION_MACRO
1.1175 + PRM_US_SET_RESOURCE_STATE_START_TRACE;
1.1176 +#endif
1.1177 + // Invoke the API
1.1178 + r=((DPowerResourceController*)iPddPtr)->ChangeResourceState(ClientHandle(),
1.1179 + resourceId, newState, (TPowerResourceCb*)param[1]);
1.1180 + break;
1.1181 + }
1.1182 +
1.1183 + case RBusDevResManUs::EGetResourceState:
1.1184 + {
1.1185 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case EGetResourceState"));
1.1186 + // a1 specifies the resource ID
1.1187 + // a2 specifies the container stating if a cached value is required, the address of the variable
1.1188 + // to be update with the state value and the address of the level owner ID
1.1189 + //
1.1190 + TUint resourceId = (TUint)a1;
1.1191 + TUint *parms = (TUint*)a2;
1.1192 + TBool cached = (TBool)(parms[0]);
1.1193 +
1.1194 +#ifdef PRM_US_INSTRUMENTATION_MACRO
1.1195 + PRM_US_GET_RESOURCE_STATE_START_TRACE;
1.1196 +#endif
1.1197 + // Always invoke the asynchronous version of the API
1.1198 + r=((DPowerResourceController*)iPddPtr)->GetResourceState(ClientHandle(),
1.1199 + resourceId, cached, *((TPowerResourceCb*)parms[3]));
1.1200 + break;
1.1201 + }
1.1202 +
1.1203 +
1.1204 + case RBusDevResManUs::ERequestChangeNotification:
1.1205 + {
1.1206 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case ERequestChangeNotification"));
1.1207 + // a1 specifies the resource ID
1.1208 + r=((DPowerResourceController*)iPddPtr)->RequestNotification(ClientHandle(),
1.1209 + (TUint)a1, *((DPowerResourceNotification*)a2));
1.1210 + break;
1.1211 + }
1.1212 +
1.1213 + case RBusDevResManUs::ERequestQualifiedChangeNotification:
1.1214 + {
1.1215 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case ERequestQualifiedChangeNotification"));
1.1216 + // a1 specifies the threshold value that the state is to change by
1.1217 + // a2 specifies the address of the container holding the resourceID and the required direction
1.1218 + TInt threshold = (TInt)a1;
1.1219 + TUint *parms = (TUint*)a2;
1.1220 + TUint resourceId = parms[0];
1.1221 + TBool direction = (TBool)(parms[1]);
1.1222 + r=((DPowerResourceController*)iPddPtr)->RequestNotification(ClientHandle(),
1.1223 + resourceId, *((DPowerResourceNotification*)parms[2]), threshold, direction);
1.1224 + break;
1.1225 + }
1.1226 +
1.1227 + default:
1.1228 + return KErrNotSupported;
1.1229 + }
1.1230 + return r;
1.1231 + }
1.1232 +
1.1233 +TInt DChannelResManUs::DoControl(TInt aFunction, TAny* a1, TAny* a2)
1.1234 +// Synchronous requests.
1.1235 + {
1.1236 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DoControl(TInt aFunction, TAny* a1, TAny* a2)") );
1.1237 +
1.1238 + TInt r=KErrNone;
1.1239 + switch (aFunction)
1.1240 + {
1.1241 + case RBusDevResManUs::EInitialise:
1.1242 + {
1.1243 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EInitialise"));
1.1244 + // a1 specifies the array describing the number of 'gettable' and 'settable' state resources
1.1245 + // and the number of 'listenable' resources
1.1246 + //
1.1247 + TUint8 *stateRes = (TUint8*)a1;
1.1248 +#ifdef PRM_US_INSTRUMENTATION_MACRO
1.1249 + PRM_US_REGISTER_CLIENT_START_TRACE;
1.1250 +#endif
1.1251 + // The call to the Resource Controller's AllocReserve method requires two parameters:
1.1252 + // the number of client level objects and the number of request message objects
1.1253 + // Each 'settable' state resource requires a client level object and a request message object
1.1254 + // Each 'gettable' state resource requires a request message object, only.
1.1255 + // Call Resource Control to make allocations
1.1256 + r=((DPowerResourceController*)iPddPtr)->AllocReserve(ClientHandle(),
1.1257 + stateRes[1], // Number of settable
1.1258 + (TUint8)(stateRes[1] + stateRes[0])); // Number of (settable + gettable)
1.1259 +#ifdef PRM_US_INSTRUMENTATION_MACRO
1.1260 + PRM_US_REGISTER_CLIENT_END_TRACE;
1.1261 +#endif
1.1262 + if(r==KErrNone)
1.1263 + {
1.1264 + // Require 1 TPowerResourceCb object per gettable resource state
1.1265 + // Require 1 TPowerResourceCb object per settable resource state
1.1266 + // Require 1 DPowerResourceNotification object per listenable resource
1.1267 + //
1.1268 + if(stateRes[0]>0)
1.1269 + r=InitTrackingControl(iGetStateTracker,EGetState,stateRes[0]);
1.1270 + if((r==KErrNone) && (stateRes[1]>0))
1.1271 + r=InitTrackingControl(iSetStateTracker,ESetState,stateRes[1]);
1.1272 + if((r==KErrNone) && (stateRes[2]>0))
1.1273 + r=InitTrackingControl(iListenableTracker,ENotify,stateRes[2]);
1.1274 +#ifdef _DUMP_TRACKERS
1.1275 + if((r=DumpTracker(iGetStateTracker))!=KErrNone)
1.1276 + break;
1.1277 + if((r=DumpTracker(iSetStateTracker))!=KErrNone)
1.1278 + break;
1.1279 +#endif
1.1280 + }
1.1281 + break;
1.1282 + }
1.1283 +
1.1284 + case RBusDevResManUs::EGetNoOfResources:
1.1285 + {
1.1286 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNoOfResources"));
1.1287 + TUint numResources;
1.1288 + r=((DPowerResourceController*)iPddPtr)->GetNumResourcesInUseByClient(ClientHandle(),0,numResources);
1.1289 + iResInfoValid = 0; // New numResources invalidates the iResInfoXXXX information
1.1290 + iResInfoStoredClientId = 0;
1.1291 + iResInfoStoredNum = 0;
1.1292 + if(r!=KErrNone)
1.1293 + return r;
1.1294 + // a2 specifies whether the resource information should be loaded
1.1295 + if((r==KErrNone)&&(a2!=NULL))
1.1296 + {
1.1297 + TUint prevNumRes = 0;
1.1298 + while((numResources != prevNumRes)&&(r==KErrNone))
1.1299 + {
1.1300 + // if the number of resources is greater than can be accommodated by the array,
1.1301 + // re-size it
1.1302 + if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
1.1303 + break;
1.1304 + prevNumRes = numResources;
1.1305 + // Get the resource info from the Resource Controller
1.1306 + // Specify 'aTargetClientId' as zero to access all resources
1.1307 + iResourceInfoResCtrl->SetLength(0);
1.1308 + r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
1.1309 + ClientHandle(),0,numResources,iResourceInfoResCtrl);
1.1310 + }
1.1311 + if(r==KErrNone)
1.1312 + {
1.1313 + iResInfoValid = 1;
1.1314 + iResInfoStoredClientId = KAllResInfoStored;
1.1315 + iResInfoStoredNum = numResources;
1.1316 + }
1.1317 + }
1.1318 + if(r==KErrNone)
1.1319 + *(TUint*)a1 = numResources;
1.1320 + break;
1.1321 + }
1.1322 +
1.1323 + case RBusDevResManUs::EGetAllResourcesInfo:
1.1324 + {
1.1325 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetAllResourcesInfo"));
1.1326 + // Parameters are passed in TUint* parms[2]
1.1327 + // The address of the number of resources is at element 0
1.1328 + // The flag to indicate if the resource info stored is to be refreshed is at element 1
1.1329 + TUint* parms = (TUint*)a2;
1.1330 + TUint numResources = *(TUint*)parms[0];
1.1331 + TBool refresh=(TBool)(parms[1]);
1.1332 +
1.1333 + // The results are to be written to an RSimplePointerArray, the address is in a1
1.1334 + // Check that the array has enough elements
1.1335 + if(refresh)
1.1336 + {
1.1337 + // For the refresh option, invoke Resource Controller API once, only (do not recurse)
1.1338 + // If the number of requested resources is greater than can be accommodated by the array,
1.1339 + // re-size it
1.1340 + if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
1.1341 + break;
1.1342 + // Get the resource info from the Resource Controller
1.1343 + // Specify 'aTargetClientId' as zero to access all resources
1.1344 + iResourceInfoResCtrl->SetLength(0);
1.1345 + r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
1.1346 + ClientHandle(),0,numResources,iResourceInfoResCtrl);
1.1347 + if(numResources != iResInfoStoredNum)
1.1348 + {
1.1349 + iResInfoValid = 0; // Assume cohesion is now lost
1.1350 + iResInfoStoredClientId = 0;
1.1351 + iResInfoStoredNum = 0;
1.1352 + }
1.1353 + }
1.1354 + else
1.1355 + {
1.1356 + // If the information stored is not valid or is not for all resources return KErrNotReady
1.1357 + if((iResInfoValid != 1)||(iResInfoStoredClientId != KAllResInfoStored))
1.1358 + {
1.1359 + r=KErrNotReady;
1.1360 + break;
1.1361 + }
1.1362 + // The number of resources for which information is available in this case is iResInfoStoredNum
1.1363 + numResources = iResInfoStoredNum;
1.1364 + }
1.1365 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
1.1366 + TPowerResourceInfoV01* currRes = (TPowerResourceInfoV01*)iResourceInfoResCtrl->Ptr();
1.1367 + for(TUint index = 0; index < numResources; index++)
1.1368 + {
1.1369 + CheckForCandidateAsyncResource(currRes);
1.1370 + CheckForCandidateSharedResource(currRes);
1.1371 + currRes++;
1.1372 + }
1.1373 +#endif
1.1374 + *(TUint*)(parms[0]) = numResources;
1.1375 +
1.1376 + break;
1.1377 + }
1.1378 +
1.1379 + case RBusDevResManUs::EGetNoOfClients:
1.1380 + case RBusDevResManUs::EGetNumClientsUsingResource:
1.1381 + {
1.1382 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNoOfClients"));
1.1383 + // Parameters are passed in TUint parms[3]
1.1384 + // The flag to indicate if kernel-side clients are to be included is at element 0
1.1385 + // The ID of the resource of interest (0 is expected for EGetNoOfClients)
1.1386 + // The flag to indicate if the client info is to be read now is at element 1
1.1387 + TUint *parms = (TUint*)a2;
1.1388 + TUint includeKern = parms[0];
1.1389 + TUint resourceId = parms[1];
1.1390 + TUint infoRead = parms[2];
1.1391 + TUint requiredId = resourceId;
1.1392 + if(aFunction == RBusDevResManUs::EGetNoOfClients)
1.1393 + {
1.1394 + __ASSERT_ALWAYS(resourceId==0,RESMANUS_FAULT());
1.1395 + requiredId = KAllClientInfoStored;
1.1396 + }
1.1397 + TUint numClients = 0;
1.1398 + if(includeKern==1)
1.1399 + {
1.1400 + // Client must exhibit PlatSec capability ReadDeviceData
1.1401 + if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNoOfClients")))
1.1402 + {
1.1403 + r = KErrPermissionDenied;
1.1404 + break;
1.1405 + }
1.1406 + if(r==KErrNone)
1.1407 + r=((DPowerResourceController*)iPddPtr)->GetNumClientsUsingResource(ClientHandle(),resourceId,numClients);
1.1408 + }
1.1409 + else
1.1410 + numClients = (TUint)(iDevice->iOpenChannels);
1.1411 +
1.1412 + // New numClients invalidates the iClientInfoXXXX information
1.1413 + iClientInfoValid = 0;
1.1414 + iClientInfoStoredResId = 0;
1.1415 + iClientInfoStoredNum= 0;
1.1416 +
1.1417 + if((r==KErrNone)&&(infoRead==1))
1.1418 + {
1.1419 + // Capability check already performed, so no need to repeat ...
1.1420 + TUint prevNumClients = 0;
1.1421 + while((numClients != prevNumClients)&&(r == KErrNone))
1.1422 + {
1.1423 + // Ensure buffer is large enough to store the information
1.1424 + if((r=EnsureSizeIsSufficient(iClientNamesResCtrl, (TInt)(numClients*sizeof(TPowerClientInfoV01))))!=KErrNone)
1.1425 + break;
1.1426 + prevNumClients = numClients;
1.1427 + // Invoke the API
1.1428 + r=((DPowerResourceController*)iPddPtr)->GetInfoOnClientsUsingResource(ClientHandle(),
1.1429 + resourceId,numClients,iClientNamesResCtrl);
1.1430 + };
1.1431 +
1.1432 + if(r==KErrNone)
1.1433 + {
1.1434 + iClientInfoValid = 1;
1.1435 + iClientInfoStoredResId = requiredId;
1.1436 + iClientInfoStoredNum = numClients;
1.1437 + if(includeKern!=1)
1.1438 + {
1.1439 + TUint numAllClients = numClients;
1.1440 + numClients = 0;
1.1441 + TPowerClientInfoV01* rcDataPtr = (TPowerClientInfoV01*)(iClientNamesResCtrl->Ptr());
1.1442 + for(TUint i=0; i<numAllClients; i++)
1.1443 + {
1.1444 + if( rcDataPtr->iClientId & USER_SIDE_CLIENT_BIT_MASK)
1.1445 + ++numClients;
1.1446 + ++rcDataPtr;
1.1447 + }
1.1448 + }
1.1449 + }
1.1450 + }
1.1451 + if(r==KErrNone)
1.1452 + *(TUint*)a1 = numClients;
1.1453 + break;
1.1454 + }
1.1455 +
1.1456 + case RBusDevResManUs::EGetNamesAllClients:
1.1457 + case RBusDevResManUs::EGetInfoOnClientsUsingResource:
1.1458 + {
1.1459 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNamesAllClients-EGetInfoOnClientsUsingResource"));
1.1460 + // Parameters are passed in TUint* parms[4]
1.1461 + // The address of the number of clients is at element 0
1.1462 + // The flag to indicate if kernel-side info is requested is at element 1
1.1463 + // The resource ID is at element 2
1.1464 + // The flag to indicate if the client information stored is to be refreshed is at element 3
1.1465 + TUint* parms = (TUint*)a2;
1.1466 + TUint numClients = *(TUint*)parms[0];
1.1467 + TBool includeKern=(TBool)(parms[1]);
1.1468 + TUint resourceId=(TUint)(parms[2]);
1.1469 + TBool refresh=(TBool)(parms[3]);
1.1470 +
1.1471 + TUint numClientsAvailable = 0;
1.1472 + iClientNamesResCtrl->SetLength(0);
1.1473 +
1.1474 + if(includeKern)
1.1475 + {
1.1476 + // Client must exhibit PlatSec capability ReadDeviceData
1.1477 + if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNamesAllClients-EGetInfoOnClientsUsingResource")))
1.1478 + {
1.1479 + r = KErrPermissionDenied;
1.1480 + break; // Early exit in event of error
1.1481 + }
1.1482 + TUint requiredId = (resourceId==0)?(TUint)KAllClientInfoStored:resourceId;
1.1483 + if(refresh)
1.1484 + {
1.1485 + // For the refresh option, invoke Resource Controller API once, only (do not recurse)
1.1486 + // If the number of clients is greater than can be accommodated by the array,
1.1487 + // re-size it
1.1488 + if((r=EnsureSizeIsSufficient(iClientNamesResCtrl, (TInt)(numClients*sizeof(TPowerClientInfoV01))))!=KErrNone)
1.1489 + break;
1.1490 + // Invoke the API
1.1491 + numClientsAvailable = numClients; // Arbitrary initialisation (to silence compiler warning)
1.1492 + r=((DPowerResourceController*)iPddPtr)->GetInfoOnClientsUsingResource(ClientHandle(),
1.1493 + resourceId,numClientsAvailable,iClientNamesResCtrl);
1.1494 + if((r!=KErrNone)||(numClientsAvailable != iClientInfoStoredNum)||(iClientInfoStoredResId != requiredId))
1.1495 + {
1.1496 + iClientInfoValid = 0; // Assume cohesion is now lost
1.1497 + iClientInfoStoredResId = 0;
1.1498 + iClientInfoStoredNum = 0;
1.1499 + }
1.1500 + }
1.1501 + else
1.1502 + {
1.1503 + // If the information stored is not valid, is not for the required resources return KErrNotReady
1.1504 + if((iClientInfoValid != 1)||(iClientInfoStoredResId != requiredId))
1.1505 + r=KErrNotReady;
1.1506 + // The number of clients for which information is available in this case is iClientInfoStoredNum
1.1507 + numClientsAvailable = iClientInfoStoredNum;
1.1508 + }
1.1509 + }
1.1510 + else
1.1511 + {
1.1512 + // Resource Controller will return information for the number of clients requested,
1.1513 + // taken in order from its internal storage - but this will be regardless of whether
1.1514 + // they are kernel-side or user-side; the USER_SIDE_CLIENT_BIT_MASK bit must be
1.1515 + // interrogated to determine this.
1.1516 + //
1.1517 + // Therefore, need to read all the clients - but to do this, must find out how many
1.1518 + // clients there are first.
1.1519 + TUint numAllClients;
1.1520 + r=((DPowerResourceController*)iPddPtr)->GetNumClientsUsingResource(ClientHandle(),resourceId,numAllClients);
1.1521 + if(r!=KErrNone)
1.1522 + break; // Early exit in event of error
1.1523 + if(numAllClients > 0)
1.1524 + {
1.1525 + if(refresh)
1.1526 + {
1.1527 + // For the refresh option, invoke Resource Controller API once, only (do not recurse)
1.1528 + // If the number of clients is greater than can be accommodated by the array,
1.1529 + // re-size it
1.1530 + if((r=EnsureSizeIsSufficient(iClientNamesResCtrl, (TInt)(numAllClients*sizeof(TPowerClientInfoV01))))!=KErrNone)
1.1531 + break;
1.1532 + // Invoke the API
1.1533 + r=((DPowerResourceController*)iPddPtr)->GetInfoOnClientsUsingResource(ClientHandle(),
1.1534 + resourceId,numAllClients,iClientNamesResCtrl);
1.1535 + TUint requiredId = (resourceId==0)?(TUint)KAllClientInfoStored:resourceId;
1.1536 + if((r!=KErrNone)||(numClientsAvailable != iClientInfoStoredNum)||(iClientInfoStoredResId != requiredId))
1.1537 + {
1.1538 + iClientInfoValid = 0; // Assume cohesion is now lost
1.1539 + iClientInfoStoredResId = 0;
1.1540 + iClientInfoStoredNum = 0;
1.1541 + break;
1.1542 + }
1.1543 + else
1.1544 + {
1.1545 + iClientInfoValid = 1;
1.1546 + iClientInfoStoredResId = requiredId;
1.1547 + iClientInfoStoredNum = numAllClients;
1.1548 + }
1.1549 + }
1.1550 + else
1.1551 + {
1.1552 + // If the information stored is not valid, is not for the required resources return KErrNotReady
1.1553 + TUint requiredId = (resourceId==0)?(TUint)KAllClientInfoStored:resourceId;
1.1554 + if((iClientInfoValid != 1)||(iClientInfoStoredResId != requiredId))
1.1555 + {
1.1556 + r=KErrNotReady;
1.1557 + break;
1.1558 + }
1.1559 + // The number of clients for which information is available in this case is iClientInfoStoredNum
1.1560 + numAllClients = iClientInfoStoredNum;
1.1561 + }
1.1562 + numClientsAvailable = numAllClients;
1.1563 + } // if(numAllClients > 0)
1.1564 + }
1.1565 + // Write the total number of user side cients available
1.1566 + *(TUint*)parms[0] = numClientsAvailable;
1.1567 + break;
1.1568 + }
1.1569 + case RBusDevResManUs::EGetNumResourcesInUseByClient:
1.1570 + {
1.1571 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumResourcesInUseByClient"));
1.1572 + // a1 specifies the container holding the client name
1.1573 + //
1.1574 +
1.1575 + // If client doesn't exist, return KErrNotFound
1.1576 + // If client has appropriate capabilities, or if the client for which the information is sought
1.1577 + // is user-side, invoke the Resource Controller API directly
1.1578 + // Otherwise, return KErrPermissionDenied
1.1579 + TUint clientId=0;
1.1580 + r=((DPowerResourceController*)iPddPtr)->GetClientId(ClientHandle(),
1.1581 + *(TDesC8*)a1,clientId);
1.1582 + if(r!=KErrNone)
1.1583 + return KErrNotFound;
1.1584 + // Perform capability check
1.1585 + if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNoOfClients")))
1.1586 + {
1.1587 + if(!(clientId & USER_SIDE_CLIENT_BIT_MASK))
1.1588 + return KErrPermissionDenied;
1.1589 + }
1.1590 + TUint numResources=0;
1.1591 + if(r==KErrNone)
1.1592 + r=((DPowerResourceController*)iPddPtr)->GetNumResourcesInUseByClient(ClientHandle(),
1.1593 + clientId,numResources);
1.1594 + // New numResources invalidates the iResXXXX information
1.1595 + iResInfoValid = 0;
1.1596 + iResInfoStoredClientId = 0;
1.1597 + iResInfoStoredNum= 0;
1.1598 +
1.1599 + // parms[1] specifies whether the resource information should be loaded
1.1600 + if((r==KErrNone)&&(*(TUint*)a2 != NULL))
1.1601 + {
1.1602 + TUint prevNumRes = 0;
1.1603 + while((numResources != prevNumRes)&&(r==KErrNone))
1.1604 + {
1.1605 + // if the number of resources is greater than can be accommodated by the array,
1.1606 + // re-size it
1.1607 + if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
1.1608 + break;
1.1609 + prevNumRes = numResources;
1.1610 + // Get the resource info from the Resource Controller
1.1611 + // Specify 'aTargetClientId' as zero to access all resources
1.1612 + iResourceInfoResCtrl->SetLength(0);
1.1613 + r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
1.1614 + ClientHandle(),clientId,numResources,iResourceInfoResCtrl);
1.1615 + }
1.1616 + if(r==KErrNone)
1.1617 + {
1.1618 + iResInfoValid = 1;
1.1619 + iResInfoStoredClientId = clientId;
1.1620 + iResInfoStoredNum = numResources;
1.1621 + }
1.1622 + }
1.1623 + if(r==KErrNone)
1.1624 + *(TUint*)a2 = numResources;
1.1625 + break;
1.1626 + }
1.1627 +
1.1628 + case RBusDevResManUs::EGetInfoOnResourcesInUseByClient:
1.1629 + {
1.1630 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetInfoOnResourcesInUseByClient"));
1.1631 + // a1 specifies the container holding the client name
1.1632 + // a2 specifies an array TUint* parms[3] which contains:
1.1633 + // - the address of the variable to write the number of reasources to
1.1634 + // - a pointer to the container to hold the resources' information
1.1635 + // - the flag to indicate whether the resource info should be (re-)read here
1.1636 +
1.1637 + TUint clientId=0;
1.1638 + TUint *parms = (TUint*)a2;
1.1639 + TUint numResources = *(TUint*)parms[0];
1.1640 + // The results are to be written to an RSimplePointerArray, the address is in parms[1]
1.1641 + // Check that the array has enough elements
1.1642 + // If client doesn't exist, return KErrNotFound
1.1643 + // If client has appropriate capabilities, or if the client for which the information is sought
1.1644 + // is user-side, invoke the Resource Controller API directly
1.1645 + // Otherwise, return KErrPermissionDenied
1.1646 + r=((DPowerResourceController*)iPddPtr)->GetClientId(ClientHandle(),
1.1647 + *(TDesC8*)a1,clientId);
1.1648 + if(r!=KErrNone)
1.1649 + return KErrNotFound;
1.1650 + // Perform capability check
1.1651 + if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNoOfClients")))
1.1652 + {
1.1653 + if(!(clientId & USER_SIDE_CLIENT_BIT_MASK))
1.1654 + return KErrPermissionDenied;
1.1655 + }
1.1656 +
1.1657 + TUint updatedNumResources = numResources;
1.1658 + r=((DPowerResourceController*)iPddPtr)->GetNumResourcesInUseByClient(ClientHandle(),clientId,updatedNumResources);
1.1659 + if(r!=KErrNone)
1.1660 + break;
1.1661 +
1.1662 + if(updatedNumResources>0)
1.1663 + {
1.1664 + if((TUint)(parms[2] != 0))
1.1665 + {
1.1666 + // For the refresh option, invoke Resource Controller API once, only (do not recurse)
1.1667 + // If the number of requested resources is greater than can be accommodated by the array,
1.1668 + // re-size it
1.1669 + if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
1.1670 + break;
1.1671 + // Get the resource info from the Resource Controller
1.1672 + // Specify 'aTargetClientId' as zero to access all resources
1.1673 + iResourceInfoResCtrl->SetLength(0);
1.1674 + r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
1.1675 + ClientHandle(),clientId,numResources,iResourceInfoResCtrl);
1.1676 + if((numResources != iResInfoStoredNum)||(iResInfoStoredClientId != clientId))
1.1677 + {
1.1678 + iResInfoValid = 0; // Assume cohesion is now lost
1.1679 + iResInfoStoredClientId = 0;
1.1680 + iResInfoStoredNum = 0;
1.1681 + }
1.1682 + }
1.1683 + else
1.1684 + {
1.1685 + // If the information stored is not valid or is not for the required clientId return KErrNotReady
1.1686 + if((iResInfoValid != 1)||(iResInfoStoredClientId != clientId))
1.1687 + r=KErrNotReady;
1.1688 + // The number of resources for which information is available in this case is iResInfoStoredNum
1.1689 + numResources = iResInfoStoredNum;
1.1690 + }
1.1691 + }
1.1692 + if(r==KErrNone)
1.1693 + *(TUint*)parms[0] = updatedNumResources;
1.1694 +
1.1695 + break;
1.1696 + }
1.1697 +
1.1698 + case RBusDevResManUs::EGetResourceIdByName:
1.1699 + {
1.1700 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetResourceIdByName"));
1.1701 + // a1 specifies the container holding the resource name
1.1702 + // a2 specifies the variable to be update with the ID
1.1703 + TUint resourceId;
1.1704 + r=((DPowerResourceController*)iPddPtr)->GetResourceId(ClientHandle(), *(TDesC8*)a1, resourceId);
1.1705 + if(r==KErrNone)
1.1706 + *(TUint *)a2 = resourceId;
1.1707 + break;
1.1708 + }
1.1709 +
1.1710 + case RBusDevResManUs::EGetResourceInfo:
1.1711 + {
1.1712 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetResourceInfo"));
1.1713 + // a1 specifies the container holding the resource ID
1.1714 + // a2 specifies the address of the container to be written to
1.1715 +
1.1716 + TUint resourceId= (TUint)a1;
1.1717 + TPowerResourceInfoBuf01 resCtrlInfo;
1.1718 + resCtrlInfo.SetLength(0);
1.1719 + TResourceInfoBuf tempInfo;
1.1720 + r=((DPowerResourceController*)iPddPtr)->GetResourceInfo(ClientHandle(),resourceId,&resCtrlInfo);
1.1721 + if(r==KErrNone)
1.1722 + {
1.1723 + // Copy the client buffer to tempInfo so that its size can be determined
1.1724 + // by ExtractResourceInfo
1.1725 + r=ExtractResourceInfo(&(resCtrlInfo()), tempInfo);
1.1726 + }
1.1727 + if(r==KErrNone)
1.1728 + {
1.1729 + // Write the resources' info to the client thread
1.1730 + *(TResourceInfoBuf*)a2 = tempInfo;
1.1731 + }
1.1732 + break;
1.1733 + }
1.1734 +
1.1735 +
1.1736 + case RBusDevResManUs::ECancelChangeResourceStateRequests:
1.1737 + case RBusDevResManUs::ECancelGetResourceStateRequests:
1.1738 + case RBusDevResManUs::ECancelChangeNotificationRequests:
1.1739 + {
1.1740 + TUint resourceId = (TUint)a1;
1.1741 + TTrackingControl*tracker=MapRequestToTracker(aFunction);
1.1742 + r=CancelTrackerRequests(tracker, ETrue, resourceId, NULL);
1.1743 + if(r==KErrCancel)
1.1744 + r=KErrNone; // All cancellations were successful
1.1745 + break;
1.1746 + }
1.1747 +
1.1748 + case RBusDevResManUs::ECancelChangeResourceState:
1.1749 + case RBusDevResManUs::ECancelGetResourceState:
1.1750 + case RBusDevResManUs::ECancelRequestChangeNotification:
1.1751 + {
1.1752 + TRequestStatus* status = (TRequestStatus*)a1;
1.1753 + r=CancelRequestsOfType(aFunction, status);
1.1754 + break;
1.1755 + }
1.1756 +
1.1757 +
1.1758 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
1.1759 + case RBusDevResManUs::EGetNumCandidateAsyncResources:
1.1760 + {
1.1761 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumCandidateAsyncResources"));
1.1762 + TUint numResources;
1.1763 + GetNumCandidateAsyncResources(numResources);
1.1764 + // Write the result to the client thread
1.1765 + *(TUint*)a1 = numResources;
1.1766 + break;
1.1767 + }
1.1768 + case RBusDevResManUs::EGetCandidateAsyncResourceId:
1.1769 + {
1.1770 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetCandidateAsyncResourceId"));
1.1771 + // Get the index to use
1.1772 + TUint index = (TUint)a1;
1.1773 + TUint resourceId = 0;
1.1774 + r=GetCandidateAsyncResourceId(index, resourceId);
1.1775 + if(r==KErrNone) // Write the result to the client thread
1.1776 + *(TUint*)a2 = resourceId;
1.1777 + break;
1.1778 + }
1.1779 +
1.1780 + case RBusDevResManUs::EGetNumCandidateSharedResources:
1.1781 + {
1.1782 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumCandidateSharedResources"));
1.1783 + TUint numResources;
1.1784 + GetNumCandidateSharedResources(numResources);
1.1785 + // Write the result to the client thread
1.1786 + *(TUint*)a1 = numResources;
1.1787 + break;
1.1788 + }
1.1789 + case RBusDevResManUs::EGetCandidateSharedResourceId:
1.1790 + {
1.1791 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetCandidateSharedResourceId"));
1.1792 + // Get the index to use
1.1793 + TUint index = (TUint)a1;
1.1794 + TUint resourceId = 0;
1.1795 + r=GetCandidateSharedResourceId(index, resourceId);
1.1796 + if(r==KErrNone) // Write the result to the client thread
1.1797 + *(TUint*)a2 = resourceId;
1.1798 + break;
1.1799 + }
1.1800 +#endif
1.1801 +
1.1802 + case RBusDevResManUs::EGetResourceControllerVersion:
1.1803 + {
1.1804 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetResourceControllerVersion"));
1.1805 + // a1 specifies the address of the TVersion variable to be written to
1.1806 + // a2 is not used
1.1807 + TUint version;
1.1808 + if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(),
1.1809 + KResManControlIoGetVersion,
1.1810 + (TAny*)&version,
1.1811 + NULL,
1.1812 + NULL))!=KErrNone)
1.1813 + return r;
1.1814 + // Write the required information
1.1815 + *(TUint*)a1 = version;
1.1816 + break;
1.1817 + }
1.1818 +
1.1819 + case RBusDevResManUs::EGetNumDependentsForResource:
1.1820 + {
1.1821 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumDependentsForResource"));
1.1822 + // a1 specifies a pointer to the variable to be written to
1.1823 + // a2 specifies an array TUint parms[2] which contains:
1.1824 + // - the resource ID
1.1825 + // - flag to indicate if dependency information is to be loaded as part of this call
1.1826 + TUint *parms = (TUint*)a2;
1.1827 + TUint numDependents = 0;
1.1828 + r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(),
1.1829 + KResManControlIoGetNumDependents,
1.1830 + (TAny*)(parms[0]), // Resource ID
1.1831 + &numDependents,
1.1832 + NULL);
1.1833 + iResDepsValid=EFalse; // The number of dependents may differ from the dependency information stored
1.1834 + if(r!=KErrNone)
1.1835 + return r;
1.1836 +
1.1837 + // Load the dependency information, if required.
1.1838 + if(parms[1])
1.1839 + {
1.1840 + // The dependency information may be updated subsequent to the request for the number of dependents. In order
1.1841 + // to provide a coherent number and array of dependents, the requests for dependency information will be
1.1842 + // re-issued if the (new) number of dependents differs from that previously read.
1.1843 + TUint prevNumDeps = 0;
1.1844 + TUint newNumDeps = numDependents;
1.1845 + while((newNumDeps != prevNumDeps)&&(r == KErrNone))
1.1846 + {
1.1847 + if((r=EnsureSizeIsSufficient(iResourceDependencyIds, (TInt)(newNumDeps*sizeof(SResourceDependencyInfo))))!=KErrNone)
1.1848 + return r;
1.1849 + prevNumDeps = newNumDeps;
1.1850 + if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(),
1.1851 + KResManControlIoGetDependentsId,
1.1852 + (TAny*)(parms[0]), // Resource ID
1.1853 + (TAny*)(iResourceDependencyIds),
1.1854 + (TAny*)&newNumDeps))!=KErrNone)
1.1855 + return r;
1.1856 + };
1.1857 + // Dependency information now in synch with number reported
1.1858 + numDependents = newNumDeps;
1.1859 + iNumResDepsStored = newNumDeps;
1.1860 + iResDepsValid = ETrue;
1.1861 + }
1.1862 + // Write the number of dependents to the client thread
1.1863 + *(TUint*)a1 = numDependents;
1.1864 + break;
1.1865 + }
1.1866 +
1.1867 +
1.1868 + case RBusDevResManUs::EGetDependentsIdForResource:
1.1869 + {
1.1870 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetDependentsIdForResource"));
1.1871 + // a1 specifies a pointer to the variable to hold the number of dependencies
1.1872 + // a2 specifies an array TUint parms[4] which contains:
1.1873 + // - the resource ID
1.1874 + // - the address of the array to write the required IDs to
1.1875 + // - flag to indicate if dependency information is to be (re-)loaded as part of this call
1.1876 + TUint *parms = (TUint*)a2;
1.1877 + TUint numDependents = 0;
1.1878 +
1.1879 + // (Re-)Load the dependency information, if required.
1.1880 + if(parms[2])
1.1881 + {
1.1882 + if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(),
1.1883 + KResManControlIoGetNumDependents,
1.1884 + (TAny*)(parms[0]),
1.1885 + (TAny*)&numDependents,
1.1886 + NULL))!=KErrNone)
1.1887 + return r;
1.1888 +
1.1889 + iResDepsValid=EFalse; // The number of dependents may differ from the dependency information stored
1.1890 + // In order to provide a coherent number and array of dependents, the requests for dependency information
1.1891 + // will be re-issued if the (new) number of dependents differs from that previously read.
1.1892 + TUint prevNumDeps = 0;
1.1893 + TUint newNumDeps = numDependents;
1.1894 + while(newNumDeps != prevNumDeps)
1.1895 + {
1.1896 + if((r=EnsureSizeIsSufficient(iResourceDependencyIds, (TInt)(newNumDeps*sizeof(SResourceDependencyInfo))))!=KErrNone)
1.1897 + return r;
1.1898 + prevNumDeps = newNumDeps;
1.1899 + if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(),
1.1900 + KResManControlIoGetDependentsId,
1.1901 + (TAny*)(parms[0]), // Resource ID
1.1902 + (TAny*)(iResourceDependencyIds),
1.1903 + (TAny*)&newNumDeps))!=KErrNone)
1.1904 + return r;
1.1905 + };
1.1906 +
1.1907 + // Dependency information now in synch with number reported
1.1908 + numDependents = newNumDeps;
1.1909 + iNumResDepsStored = newNumDeps;
1.1910 + iResDepsValid = ETrue;
1.1911 + }
1.1912 +
1.1913 + // If iResDepsValid equals zero, the results are invalid - so return KErrNotReady.
1.1914 + if(iResDepsValid==0)
1.1915 + return KErrNotReady;
1.1916 +
1.1917 + // Write the number of dependencies available to the client
1.1918 + *(TUint*)a1 = iNumResDepsStored;
1.1919 + // Write the dependencies to the client array if it is of sufficient size
1.1920 + // Copy the required dependency information to the user-supplied container.
1.1921 + parms[1] = (TUint)iResourceDependencyIds;
1.1922 + break;
1.1923 + }
1.1924 +
1.1925 + default:
1.1926 + {
1.1927 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl default 0x%x", aFunction));
1.1928 + r=KErrNotSupported;
1.1929 + }
1.1930 + }
1.1931 + return(r);
1.1932 + }
1.1933 +
1.1934 +
1.1935 +TInt DChannelResManUs::EnsureSizeIsSufficient(HBuf*& aBuffer, TInt aMinSize)
1.1936 + {
1.1937 +// Utility function to ensure a buffer is of at least the minimum required size
1.1938 +// If the buffer is to small, an attempt is made to increase its size.
1.1939 +// If the re-sizing fails, KErrNoMemory is returned; otherwise KErrNone.
1.1940 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::EnsureSizeIsSufficient"));
1.1941 +
1.1942 + if(aBuffer->MaxLength() < aMinSize)
1.1943 + {
1.1944 + aBuffer = aBuffer->ReAlloc(aMinSize);
1.1945 + if(aBuffer->MaxLength() < aMinSize)
1.1946 + return KErrNoMemory; // ReAlloc failed - aBuffer is unchanged
1.1947 + }
1.1948 + aBuffer->SetLength(0);
1.1949 + return KErrNone;
1.1950 + }
1.1951 +
1.1952 +void DChannelResManUs::FreeTrackingBuffer(TTrackingBuffer*& aBuffer)
1.1953 + {
1.1954 + __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::FreeTrackingBuffer"));
1.1955 + // Function invoked for to free tracking buffers from the busy to free queue of a tracking control
1.1956 + __ASSERT_ALWAYS((aBuffer!=NULL),RESMANUS_FAULT());
1.1957 + NKern::FMWait(&iBufferFastMutex);
1.1958 + TTrackingControl* tracker = aBuffer->GetTrackingControl();
1.1959 + SDblQue* bufQue = aBuffer->GetQue();
1.1960 +
1.1961 + __ASSERT_ALWAYS(((tracker!=NULL)&&(bufQue!=NULL)),RESMANUS_FAULT());
1.1962 +
1.1963 + // Check that the buffer is still in the busy queue of the tracker - exit if not
1.1964 + if(bufQue == tracker->iBusyQue)
1.1965 + {
1.1966 + aBuffer->Deque();
1.1967 + tracker->iFreeQue->Add(aBuffer);
1.1968 + aBuffer->SetQue(tracker->iFreeQue);
1.1969 + }
1.1970 + NKern::FMSignal(&iBufferFastMutex);
1.1971 + }
1.1972 +
1.1973 +
1.1974 +TInt DChannelResManUs::GetAndInitTrackingBuffer(TTrackingControl*& aTracker, TTrackingBuffer*& aBuffer, TUint aResourceId, TRequestStatus* aStatus)
1.1975 + {
1.1976 +// Utility function - perform the necessary processing to get a buffer to support
1.1977 +// asynchronous requests to change the state of a resource
1.1978 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetAndInitTrackingBuffer"));
1.1979 + TInt r=KErrNone;
1.1980 + NKern::FMWait(&iBufferFastMutex);
1.1981 + if(aTracker->iFreeQue->IsEmpty())
1.1982 + r = KErrUnderflow;
1.1983 + else
1.1984 + {
1.1985 + // Need intermediate cast from SDblQueLink* to TAny* before TTrackingBuffer*
1.1986 + TAny* ptr = (TAny*)(aTracker->iFreeQue->GetFirst());
1.1987 + aBuffer = (TTrackingBuffer*)ptr;
1.1988 + aTracker->iBusyQue->Add((SDblQueLink*)ptr);
1.1989 + aBuffer->SetQue(aTracker->iBusyQue);
1.1990 + aBuffer->SetResourceId(aResourceId);
1.1991 + TClientRequest* request;
1.1992 + TTrackingControl* tracker = aBuffer->GetTrackingControl();
1.1993 + GET_USER_REQUEST(request, aBuffer, tracker->iType);
1.1994 + request->Reset();
1.1995 + request->SetStatus(aStatus);
1.1996 + }
1.1997 + NKern::FMSignal(&iBufferFastMutex);
1.1998 + return r;
1.1999 + }
1.2000 +
1.2001 +TInt DChannelResManUs::GetStateBuffer(TTrackingControl*& aTracker, TTrackingBuffer*& aBuffer, TUint aResourceId, TInt* aState, TInt* aLevelOwnerPtr, TPowerResourceCb*& aCb, TRequestStatus* aStatus)
1.2002 + {
1.2003 +// Utility function - perform the necessary processing to get a buffer and control block
1.2004 +// to support asynchronous requests to change the state of a resource
1.2005 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetStateBuffer"));
1.2006 +
1.2007 + TInt r=GetAndInitTrackingBuffer(aTracker, aBuffer, aResourceId, aStatus);
1.2008 + if(r==KErrNone)
1.2009 + {
1.2010 + TTrackGetStateBuf* stateBuf = (TTrackGetStateBuf*)aBuffer;
1.2011 + stateBuf->iRequest->SetDestPtr1(aState);
1.2012 + stateBuf->iRequest->SetDestPtr2(aLevelOwnerPtr);
1.2013 + // Use placement new to update the content of the TPowerResourceCb
1.2014 + aCb = &(stateBuf->iCtrlBlock);
1.2015 + new (aCb) TPowerResourceCb(&AsyncCallBackFn,(TAny*)aBuffer,iDfcQ,KResManCallBackPriority);
1.2016 + }
1.2017 + return r;
1.2018 + }
1.2019 +
1.2020 +
1.2021 +#ifdef _DUMP_TRACKERS
1.2022 +TInt DChannelResManUs::DumpTracker(TTrackingControl* aTracker)
1.2023 + {
1.2024 + Kern::Printf("\nDChannelResManUs::DumpTracker");
1.2025 + Kern::Printf("Tracker at 0x%x\n",aTracker);
1.2026 + if(NULL==aTracker)
1.2027 + return KErrGeneral;
1.2028 + Kern::Printf("iType=%d",aTracker->iType);
1.2029 + switch(aTracker->iType)
1.2030 + {
1.2031 + case 0:
1.2032 + Kern::Printf("= GetState tracker\n");
1.2033 + break;
1.2034 + case 1:
1.2035 + Kern::Printf("= SetState tracker\n");
1.2036 + break;
1.2037 + case 2:
1.2038 + Kern::Printf("= Notify tracker\n");
1.2039 + break;
1.2040 + }
1.2041 + Kern::Printf("iOwningChannel at 0x%x\n",aTracker->iOwningChannel);
1.2042 + Kern::Printf("iFreeQue at 0x%x\n",aTracker->iFreeQue);
1.2043 + SDblQueLink* buf;
1.2044 + if(aTracker->iFreeQue!=NULL)
1.2045 + {
1.2046 + buf=aTracker->iFreeQue->First();
1.2047 + while(buf!=aTracker->iFreeQue->Last())
1.2048 + {
1.2049 + Kern::Printf("iFreeQue buffer at 0x%x\n",buf);
1.2050 + TAny* intermediatePtr = (TAny*)buf;
1.2051 + if((aTracker->iType == EGetState)||(aTracker->iType == ESetState))
1.2052 + {
1.2053 + TTrackStateBuf* tempBuf =(TTrackStateBuf*)intermediatePtr;
1.2054 + Kern::Printf("buffer control block at 0x%x\n",tempBuf->iCtrlBlock);
1.2055 + }
1.2056 + buf= buf->iNext;
1.2057 + };
1.2058 + }
1.2059 + Kern::Printf("iBusyQue at 0x%x\n",aTracker->iBusyQue);
1.2060 + if(aTracker->iBusyQue!=NULL)
1.2061 + {
1.2062 + buf=aTracker->iBusyQue->First();
1.2063 + while(buf!=aTracker->iBusyQue->Last())
1.2064 + {
1.2065 + Kern::Printf("iBusyQue buffer at 0x%x\n",buf);
1.2066 + TAny* intermediatePtr = (TAny*)buf;
1.2067 + if((aTracker->iType == EGetState)||(aTracker->iType == ESetState))
1.2068 + {
1.2069 + TTrackStateBuf* tempBuf =(TTrackStateBuf*)intermediatePtr;
1.2070 + Kern::Printf("buffer control block at 0x%x\n",tempBuf->iCtrlBlock);
1.2071 + }
1.2072 + buf= buf->iNext;
1.2073 + };
1.2074 + }
1.2075 +
1.2076 + return KErrNone;
1.2077 + }
1.2078 +#endif
1.2079 +
1.2080 +TInt DChannelResManUs::InitTrackingControl(TTrackingControl*& aTracker, TUint8 aType, TUint8 aNumBuffers)
1.2081 + {
1.2082 +// Set the tracker type, create the tracking queues and required tracking buffers.
1.2083 +// Assign all the tracking buffers to the free queue.
1.2084 +//
1.2085 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::InitTrackingControl()"));
1.2086 +
1.2087 + TInt r = KErrNone;
1.2088 + aTracker->iType = (TAsyncOpType)aType;
1.2089 + aTracker->iOwningChannel = this;
1.2090 + aTracker->iFreeQue = new SDblQue();
1.2091 + __ASSERT_DEBUG(aTracker->iFreeQue != NULL, RESMANUS_FAULT());
1.2092 + if(aTracker->iFreeQue == NULL)
1.2093 + r = KErrNoMemory;
1.2094 + if(r==KErrNone)
1.2095 + {
1.2096 + aTracker->iBusyQue = new SDblQue();
1.2097 + __ASSERT_DEBUG(aTracker->iBusyQue != NULL, RESMANUS_FAULT());
1.2098 + if(aTracker->iBusyQue == NULL)
1.2099 + {
1.2100 + delete aTracker->iFreeQue;
1.2101 + r = KErrNoMemory;
1.2102 + }
1.2103 + }
1.2104 + if(r==KErrNone)
1.2105 + {
1.2106 + for(TUint8 i=0; (i<aNumBuffers) && (r==KErrNone) ;i++)
1.2107 + {
1.2108 + TAny* buf = NULL;
1.2109 + TAny* ptr=NULL; // To be assigned to non-NULL value later
1.2110 + switch(aTracker->iType)
1.2111 + {
1.2112 + case EGetState:
1.2113 + {
1.2114 + buf = (TAny*)(new TTrackGetStateBuf(&AsyncCallBackFn,ptr,iDfcQ,KResManCallBackPriority));
1.2115 + r = Kern::CreateClientDataRequest2(((TTrackGetStateBuf*)buf)->iRequest);
1.2116 + break;
1.2117 + }
1.2118 + case ESetState:
1.2119 + {
1.2120 + buf = (TAny*)(new TTrackSetStateBuf(&AsyncCallBackFn, ptr, iDfcQ, KResManCallBackPriority));
1.2121 + r = Kern::CreateClientRequest(((TTrackSetStateBuf*)buf)->iRequest);
1.2122 + break;
1.2123 + }
1.2124 + case ENotify:
1.2125 + {
1.2126 + buf = (TAny*)(new TTrackNotifyBuf(&AsyncCallBackFn,ptr,iDfcQ,KResManCallBackPriority));
1.2127 + r = Kern::CreateClientRequest(((TTrackNotifyBuf*)buf)->iRequest);
1.2128 + break;
1.2129 + }
1.2130 + default:
1.2131 + __ASSERT_ALWAYS(0,RESMANUS_FAULT());
1.2132 + }
1.2133 + __ASSERT_DEBUG(buf!=NULL, RESMANUS_FAULT());
1.2134 + if((buf == NULL) || (r == KErrNoMemory))
1.2135 + {
1.2136 + r = KErrNoMemory;
1.2137 + break;
1.2138 + }
1.2139 + else
1.2140 + {
1.2141 + ((TTrackingBuffer*)buf)->SetTrackingControl(aTracker);
1.2142 + (aTracker->iFreeQue)->Add((SDblQueLink*)buf);
1.2143 + ((TTrackingBuffer*)buf)->SetQue(aTracker->iFreeQue);
1.2144 + }
1.2145 + }
1.2146 + // If buffer allocation failed, need to remove all previously-allocated buffers and the queues
1.2147 + if(r!=KErrNone)
1.2148 + {
1.2149 + SDblQueLink* ptr = (aTracker->iFreeQue)->First();
1.2150 + do
1.2151 + {
1.2152 + SDblQueLink* next = NULL;
1.2153 + if(ptr !=NULL)
1.2154 + next = ptr->iNext;
1.2155 + delete ptr;
1.2156 + ptr = next;
1.2157 + } while ((ptr!=NULL)&&(ptr!=(aTracker->iFreeQue)->Last()));
1.2158 + delete aTracker->iFreeQue;
1.2159 + delete aTracker->iBusyQue;
1.2160 + }
1.2161 + }
1.2162 + return r;
1.2163 + }
1.2164 +
1.2165 +
1.2166 +void DChannelResManUs::RemoveTrackingControl(TTrackingControl*& aTracker)
1.2167 + {
1.2168 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::RemoveTrackingControl()"));
1.2169 +
1.2170 + // Free the resource-tracking links and their respective queues
1.2171 + TAny* buf;
1.2172 + if(aTracker->iFreeQue!=NULL)
1.2173 + {
1.2174 + while(!aTracker->iFreeQue->IsEmpty())
1.2175 + {
1.2176 + buf = (TAny*)(aTracker->iFreeQue->GetFirst()); // Dequeues the element
1.2177 + delete buf;
1.2178 + }
1.2179 + delete aTracker->iFreeQue;
1.2180 + }
1.2181 +
1.2182 + if(aTracker->iBusyQue!=NULL)
1.2183 + {
1.2184 + while(!aTracker->iBusyQue->IsEmpty())
1.2185 + {
1.2186 + buf = (TAny*)(aTracker->iBusyQue->GetFirst()); // Dequeues the element
1.2187 + delete buf;
1.2188 + }
1.2189 + delete aTracker->iBusyQue;
1.2190 + }
1.2191 + delete aTracker;
1.2192 + }
1.2193 +
1.2194 +
1.2195 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
1.2196 +void DChannelResManUs::CheckForCandidateAsyncResource(TPowerResourceInfoV01* aResource)
1.2197 + {
1.2198 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::CheckForCandidateAsyncResource"));
1.2199 + // Proceed only if we already have less that the maximum number of candidate resources
1.2200 + if(iNoCandidateAsyncRes >= MAX_NUM_CANDIDATE_RESOURCES)
1.2201 + return;
1.2202 + // For the purposes of asynchronous testing, we need a long latency resource
1.2203 + if(((TInt)(aResource->iLatencyGet)==(TInt)(EResLongLatency)) &&
1.2204 + ((TInt)(aResource->iLatencySet)==(TInt)(EResLongLatency)))
1.2205 + {
1.2206 + // An additional requirement is that the level of the resource can be
1.2207 + // updated a sufficient amount of times to support the required testing.
1.2208 + if(((aResource->iMaxLevel - aResource->iMinLevel) > LEVEL_GAP_REQUIRED_FOR_ASYNC_TESTING) &&
1.2209 + ((TInt)(aResource->iSense) == (TInt)(EResPositive)) )
1.2210 + {
1.2211 + TInt r=((DPowerResourceController*)iPddPtr)->GetResourceId(ClientHandle(), *(aResource->iResourceName), iCandidateAsyncResIds[iNoCandidateAsyncRes]);
1.2212 + if(r!=KErrNone)
1.2213 + {
1.2214 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("Failed to identify long latency resource\n"));
1.2215 + }
1.2216 + else
1.2217 + {
1.2218 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("Potential async resource ID = %d\n",iCandidateAsyncResIds[iNoCandidateAsyncRes]));
1.2219 + iHaveLongLatencyResource = ETrue;
1.2220 + ++iNoCandidateAsyncRes;
1.2221 + }
1.2222 + }
1.2223 + }
1.2224 + }
1.2225 +
1.2226 +
1.2227 +void DChannelResManUs::GetNumCandidateAsyncResources(TUint& aNumResources)
1.2228 + {
1.2229 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetNumCandidateAsyncResources"));
1.2230 +
1.2231 + aNumResources = iNoCandidateAsyncRes;
1.2232 + }
1.2233 +
1.2234 +TInt DChannelResManUs::GetCandidateAsyncResourceId(TUint aIndex, TUint& aResourceId)
1.2235 + {
1.2236 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetCandidateAsyncResourceId"));
1.2237 + TInt r = KErrNone;
1.2238 + if(aIndex>=iNoCandidateAsyncRes)
1.2239 + r = KErrNotFound;
1.2240 + else
1.2241 + aResourceId = iCandidateAsyncResIds[aIndex];
1.2242 + return r;
1.2243 + }
1.2244 +
1.2245 +void DChannelResManUs::CheckForCandidateSharedResource(TPowerResourceInfoV01* aResource)
1.2246 + {
1.2247 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::CheckForCandidateSharedResource"));
1.2248 +
1.2249 + // Proceed only if we already have less that the maximum number of candidate resources
1.2250 + if(iNoCandidateSharedRes >= MAX_NUM_CANDIDATE_RESOURCES)
1.2251 + return;
1.2252 +
1.2253 + // For the purposes of testing shared usgae of resources, we need a shareable resource
1.2254 + if((TInt)(aResource->iUsage)==(TInt)(EResShared))
1.2255 + {
1.2256 + // An additional requirement is that the level of the resource can be
1.2257 + // updated a sufficient amount of times to support the required testing.
1.2258 + if(((aResource->iMaxLevel - aResource->iMinLevel) > LEVEL_GAP_REQUIRED_FOR_SHARED_TESTING) &&
1.2259 + ((TInt)(aResource->iSense) == (TInt)(EResPositive)) )
1.2260 + {
1.2261 + TInt r=((DPowerResourceController*)iPddPtr)->GetResourceId(ClientHandle(), *(aResource->iResourceName), iCandidateSharedResIds[iNoCandidateSharedRes]);
1.2262 + if(r!=KErrNone)
1.2263 + {
1.2264 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("Failed to identify shared resource\n"));
1.2265 + }
1.2266 + else
1.2267 + {
1.2268 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("Potential shared resource ID = %d\n",iCandidateSharedResIds[iNoCandidateAsyncRes]));
1.2269 + iHaveLongLatencyResource = ETrue;
1.2270 + ++iNoCandidateSharedRes;
1.2271 + }
1.2272 + }
1.2273 + }
1.2274 + }
1.2275 +
1.2276 +void DChannelResManUs::GetNumCandidateSharedResources(TUint& aNumResources)
1.2277 + {
1.2278 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetNumCandidateSharedResources"));
1.2279 +
1.2280 + aNumResources = iNoCandidateSharedRes;
1.2281 + }
1.2282 +
1.2283 +TInt DChannelResManUs::GetCandidateSharedResourceId(TUint aIndex, TUint& aResourceId)
1.2284 + {
1.2285 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetCandidateSharedResourceId"));
1.2286 + TInt r = KErrNone;
1.2287 + if(aIndex>=iNoCandidateSharedRes)
1.2288 + r = KErrNotFound;
1.2289 + else
1.2290 + aResourceId = iCandidateSharedResIds[aIndex];
1.2291 + return r;
1.2292 + }
1.2293 +
1.2294 +#endif
1.2295 +
1.2296 +TInt DChannelResManUs::ExtractResourceInfo(const TPowerResourceInfoV01* aPwrResInfo, TResourceInfoBuf& aInfo)
1.2297 + {
1.2298 +// Extract data from a TPowerResourceInfoV01 object to a TResourceInfo instance
1.2299 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::ExtractResourceInfo"));
1.2300 +
1.2301 + TInt r=KErrNone;
1.2302 + TInt copyLength=(((aInfo().iName).MaxLength())<((aPwrResInfo->iResourceName)->Length()))?
1.2303 + (aInfo().iName).MaxLength():
1.2304 + (aPwrResInfo->iResourceName)->Length();
1.2305 + (aInfo().iName).Copy((aPwrResInfo->iResourceName)->Ptr(),copyLength);
1.2306 + aInfo().iId = aPwrResInfo->iResourceId;
1.2307 + aInfo().iClass = (TResourceClass)aPwrResInfo->iClass;
1.2308 + aInfo().iType = (TResourceType)aPwrResInfo->iType;
1.2309 + aInfo().iUsage = (TResourceUsage)aPwrResInfo->iUsage;
1.2310 + aInfo().iSense = (TResourceSense)aPwrResInfo->iSense;
1.2311 + aInfo().iMinLevel = aPwrResInfo->iMinLevel;
1.2312 + aInfo().iMaxLevel = aPwrResInfo->iMaxLevel;
1.2313 +
1.2314 +#ifdef _DUMP_TRACKERS
1.2315 + r=DumpResource(aPwrResInfo);
1.2316 +#endif
1.2317 + return r;
1.2318 + }
1.2319 +
1.2320 +#ifdef _DUMP_TRACKERS
1.2321 +TInt DChannelResManUs::DumpResource(const TPowerResourceInfoV01* aResource)
1.2322 + {
1.2323 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DumpResource"));
1.2324 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("Resource name = %S \n",aResource->iResourceName));
1.2325 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("Resource ID = 0x%d \n",aResource->iResourceId));
1.2326 + switch(aResource->iClass)
1.2327 + {
1.2328 + case DStaticPowerResource::EPhysical:
1.2329 + {
1.2330 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("class = EPhysical\n"));
1.2331 + break;
1.2332 + }
1.2333 + case DStaticPowerResource::ELogical:
1.2334 + {
1.2335 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("class = ELogical\n"));
1.2336 + break;
1.2337 + }
1.2338 + default:
1.2339 + {
1.2340 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("class = % is UNKNOWN!\n"));
1.2341 + return KErrGeneral;
1.2342 + }
1.2343 + }
1.2344 + switch(aResource->iType)
1.2345 + {
1.2346 + case DStaticPowerResource::EBinary:
1.2347 + {
1.2348 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("type = EBinary\n"));
1.2349 + break;
1.2350 + }
1.2351 + case DStaticPowerResource::EMultilevel:
1.2352 + {
1.2353 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("type = EMultilevel\n"));
1.2354 + break;
1.2355 + }
1.2356 + case DStaticPowerResource::EMultiProperty:
1.2357 + {
1.2358 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("type = EMultiProperty\n"));
1.2359 + break;
1.2360 + }
1.2361 + default:
1.2362 + {
1.2363 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("type = % is UNKNOWN!\n"));
1.2364 + return KErrGeneral;
1.2365 + }
1.2366 + }
1.2367 + switch(aResource->iUsage)
1.2368 + {
1.2369 + case DStaticPowerResource::ESingleUse:
1.2370 + {
1.2371 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("usage = ESingleUse\n"));
1.2372 + break;
1.2373 + }
1.2374 + case DStaticPowerResource::EShared:
1.2375 + {
1.2376 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("usage = EShared\n"));
1.2377 + break;
1.2378 + }
1.2379 + default:
1.2380 + {
1.2381 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("usage = % is UNKNOWN!\n"));
1.2382 + return KErrGeneral;
1.2383 + }
1.2384 + }
1.2385 + switch(aResource->iSense)
1.2386 + {
1.2387 + case DStaticPowerResource::EPositive:
1.2388 + {
1.2389 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = EPositive\n"));
1.2390 + break;
1.2391 + }
1.2392 + case DStaticPowerResource::ENegative:
1.2393 + {
1.2394 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = ENegative\n"));
1.2395 + break;
1.2396 + }
1.2397 + case DStaticPowerResource::ECustom:
1.2398 + {
1.2399 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = ECustom\n"));
1.2400 + break;
1.2401 + }
1.2402 + default:
1.2403 + {
1.2404 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = % is UNKNOWN!\n"));
1.2405 + return KErrGeneral;
1.2406 + }
1.2407 + }
1.2408 + switch(aResource->iLatencyGet)
1.2409 + {
1.2410 + case DStaticPowerResource::EInstantaneous:
1.2411 + {
1.2412 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("latency get = EInstantaneous\n"));
1.2413 + break;
1.2414 + }
1.2415 + case DStaticPowerResource::ENegative:
1.2416 + {
1.2417 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("latency get = ELongLatency\n"));
1.2418 + break;
1.2419 + }
1.2420 + default:
1.2421 + {
1.2422 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("latency get = % is UNKNOWN!\n"));
1.2423 + return KErrGeneral;
1.2424 + }
1.2425 + }
1.2426 + switch(aResource->iLatencySet)
1.2427 + {
1.2428 + case DStaticPowerResource::EInstantaneous:
1.2429 + {
1.2430 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("latency set = EInstantaneous\n"));
1.2431 + break;
1.2432 + }
1.2433 + case DStaticPowerResource::ENegative:
1.2434 + {
1.2435 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("latency set = ELongLatency\n"));
1.2436 + break;
1.2437 + }
1.2438 + default:
1.2439 + {
1.2440 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("latency set = % is UNKNOWN!\n"));
1.2441 + return KErrGeneral;
1.2442 + }
1.2443 + }
1.2444 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DefaultLevel = %d\n",aResource->iDefaultLevel));
1.2445 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("MinLevel = %d\n",aResource->iMinLevel));
1.2446 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("MaxLevel = %d\n",aResource->iMaxLevel));
1.2447 +
1.2448 + return KErrNone;
1.2449 + }
1.2450 +#endif
1.2451 +
1.2452 +#ifndef RESOURCE_MANAGER_SIMULATED_PSL
1.2453 +DECLARE_EXTENSION_LDD()
1.2454 + {
1.2455 + return new DDeviceResManUs;
1.2456 + }
1.2457 +
1.2458 +
1.2459 +DECLARE_STANDARD_EXTENSION()
1.2460 + {
1.2461 + DDeviceResManUs* device = new DDeviceResManUs;
1.2462 + __KTRACE_OPT(KBOOT, Kern::Printf("DECLARE_STANDARD_EXTENSION, device = 0x%x\n",device));
1.2463 +
1.2464 + if(device == NULL)
1.2465 + return KErrNoMemory;
1.2466 + else
1.2467 + {
1.2468 + device->iSharedDfcQue = new TDfcQue();
1.2469 + if(device->iSharedDfcQue==NULL)
1.2470 + return KErrNoMemory;
1.2471 +
1.2472 + return (Kern::InstallLogicalDevice(device));
1.2473 + }
1.2474 + }
1.2475 +#else
1.2476 +DECLARE_STANDARD_LDD()
1.2477 + {
1.2478 + TInt r = DSimulatedPowerResourceController::CompleteResourceControllerInitialisation();
1.2479 + if(r != KErrNone)
1.2480 + {
1.2481 + // Unconditionally print message
1.2482 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DECLARE_STANDARD_LDD: initialise Resource Controller failed with %d\n",r));
1.2483 + return NULL;
1.2484 + }
1.2485 + DDeviceResManUs* device = new DDeviceResManUs;
1.2486 + return device;
1.2487 + }
1.2488 +#endif