os/kernelhwsrv/kernel/eka/drivers/resmanus/d_resmanus.cpp
changeset 0 bde4ae8d615e
     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] = &param1;
   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] = &param1;
   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] = &param1;
   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] = &param1;
   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] = &param1;
   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] = &param1;
   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] = &param1;
   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(&param1, 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] = &param1;
   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(&param1, (TAny*)parms[0], sizeof(TUint));
   1.670 +			parms[0]  =(TUint)&param1;
   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(&param1, (TAny*)parms[0], sizeof(TUint));
   1.685 +			parms[0] = (TUint)&param1;
   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(&param1, (TAny*)parms[0], sizeof(TUint));
   1.700 +			parms[0] = (TUint)&param1;
   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(&param1, (TAny*)parms[0], sizeof(TUint));
   1.718 +			parms[0] = (TUint)&param1;
   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*)&param1, sizeof(TUint));
   1.741 +			break;
   1.742 +			}
   1.743 +		case RBusDevResManUs::EGetNumResourcesInUseByClient:
   1.744 +			{
   1.745 +			umemput32((TAny*)parms[0], (TAny*)&param1, sizeof(TUint));
   1.746 +			break;
   1.747 +			}
   1.748 +		case RBusDevResManUs::EGetResourceIdByName:
   1.749 +			{
   1.750 +			umemput32(a2, (TAny*)&param1, 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*)&param1, sizeof(TUint));
   1.758 +			break;
   1.759 +			}
   1.760 +		case RBusDevResManUs::EGetCandidateAsyncResourceId:
   1.761 +		case RBusDevResManUs::EGetCandidateSharedResourceId:
   1.762 +			{
   1.763 +			umemput32(a2, (TAny*)&param1, 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*)&param1, 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*)&param1, 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*)&param1, 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*)&param1, 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