kernel/eka/drivers/resmanus/d_resmanus.cpp
author Tom Cosgrove <tom.cosgrove@nokia.com>
Fri, 28 May 2010 16:29:07 +0100
changeset 30 8aab599e3476
parent 0 a41df078684a
child 43 c1f20ce4abcf
permissions -rw-r--r--
Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h) Have multiple extension sections in the bld.inf, one for each version of the compiler. The RVCT version building the tools will build the runtime libraries for its version, but make sure we extract all the other versions from zip archives. Also add the archive for RVCT4.

// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// e32\drivers\resmanus\d_resmanus.cpp
// 
//

// LDD for Resource Manager user side API
#include "resmanus.h"
#include <kernel/kern_priv.h>
#include <kernel/kernel.h>
#include <e32hal.h>
#include <e32uid.h>
#include <e32cmn.h>
#include <e32cmn_private.h>
#include <e32def_private.h>
#include <drivers/resource_extend.h>

#ifdef RESOURCE_MANAGER_SIMULATED_PSL
#include "rescontrol_psl.h"
#endif

#ifdef PRM_US_INSTRUMENTATION_MACRO
#include <drivers/resmanus_trace.h>
#endif

#ifdef PRM_ENABLE_EXTENDED_VERSION2
_LIT(KResManUsThreadName,"ResManUsExtendedCoreLddThread");
#elif defined (PRM_ENABLE_EXTENDED_VERSION)
_LIT(KResManUsThreadName,"ResManUsExtendedLddThread");
#else
_LIT(KResManUsThreadName,"ResManUsLddThread");
#endif

#define RESMANUS_FAULT()	Kern::Fault("RESMANUS",__LINE__)

const TInt KResManUsThreadPriority = 24;
const TInt KResManUsRegistrationPriority = 5; // Arbitrary! Can be 0-7, 7 is highest
const TInt KResManCallBackPriority = 5; // Arbitrary! Can be 0-7, 7 is highest

//Macro to return appropriate request type.
#define GET_USER_REQUEST(request, buffer, type)						\
	{																\
	if(type == EGetState)											\
		request = ((TTrackGetStateBuf*)buffer)->iRequest;			\
	else if(type == ESetState)										\
		request = ((TTrackSetStateBuf*)buffer)->iRequest;			\
	else															\
		request = ((TTrackNotifyBuf*)buffer)->iRequest;				\
	}

/***************************************************************************************
	class TTrackGetStateBuf
 ***************************************************************************************/
TTrackGetStateBuf::TTrackGetStateBuf(TPowerResourceCbFn aFn, TAny* aPtr,
						       TDfcQue* aQue, TInt aPriority)
							   :	iCtrlBlock(aFn, aPtr, aQue, aPriority)
	{
	iRequest = NULL;
	}

/***************************************************************************************
	class TTrackSetStateBuf
 ***************************************************************************************/
TTrackSetStateBuf::TTrackSetStateBuf(TPowerResourceCbFn aFn, TAny* aPtr,
						       TDfcQue* aQue, TInt aPriority)
							   :	iCtrlBlock(aFn, aPtr, aQue, aPriority)
	{
	iRequest = NULL;
	}

/***************************************************************************************
	class TTrackNotifyBuf
 ***************************************************************************************/
TTrackNotifyBuf::TTrackNotifyBuf(TPowerResourceCbFn aFn, TAny* aPtr,
								 TDfcQue* aQue, TInt aPriority)
							   :	iNotifyBlock(aFn, aPtr, aQue, aPriority)
	{
	iRequest = NULL;
	}

TTrackNotifyBuf::~TTrackNotifyBuf()
	{
	if(iRequest)
		Kern::DestroyClientRequest(iRequest);
	}

TTrackSetStateBuf::~TTrackSetStateBuf()
	{
	if(iRequest)
		Kern::DestroyClientRequest(iRequest);
	}

TTrackGetStateBuf::~TTrackGetStateBuf()
	{
	if(iRequest)
		Kern::DestroyClientRequest(iRequest);
	}
	
/***************************************************************************************
	class DDeviceResManUs
 ***************************************************************************************/
DDeviceResManUs::DDeviceResManUs()
// Constructor
    {
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::DDeviceResManUs()"));
    iParseMask=KDeviceAllowAll&~KDeviceAllowUnit; // Allow info and pdd, but not units
    iUnitsMask=0;
    iVersion=TVersion(KResManUsMajorVersionNumber,
		      KResManUsMinorVersionNumber,
		      KResManUsBuildVersionNumber);
    }

DDeviceResManUs::~DDeviceResManUs()
// Destructor
    {
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::~DDeviceResManUs()"));
#ifdef RESOURCE_MANAGER_SIMULATED_PSL
	iSharedDfcQue->Destroy();
#else
	delete iSharedDfcQue;
#endif
	}

TInt DDeviceResManUs::Install()
// Install the device driver.
    {
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::Install()"));
	// Create the message queue and initialise the DFC queue pointer
#ifndef RESOURCE_MANAGER_SIMULATED_PSL
	TInt r=Kern::DfcQInit(iSharedDfcQue,KResManUsThreadPriority,&KResManUsThreadName);
#else
	TInt r = Kern::DynamicDfcQCreate(iSharedDfcQue,KResManUsThreadPriority,KResManUsThreadName);
#endif
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DfcQCreate r  = %d", r));
	if(r!=KErrNone)
		return r;

#ifdef CPU_AFFINITY_ANY
        NKern::ThreadSetCpuAffinity((NThread*)(iSharedDfcQue->iThread), KCpuAffinityAny);
#endif
	r = SetName(&KLddRootName);
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> SetName, r  = %d", r));
	return r;
    }


void DDeviceResManUs::GetCaps(TDes8& aDes) const
// Return the ResManUs capabilities.
    {
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::GetCaps(TDes8& aDes) const"));
    TPckgBuf<TCapsDevResManUs> b;
    b().version=TVersion(KResManUsMajorVersionNumber,
			 KResManUsMinorVersionNumber,
			 KResManUsBuildVersionNumber);
    Kern::InfoCopy(aDes,b);
    }


TInt DDeviceResManUs::Create(DLogicalChannelBase*& aChannel)
// Create a channel on the device.
    {
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::Create(DLogicalChannelBase*& aChannel)"));
	if(iOpenChannels>=KMaxNumChannels)
		return KErrOverflow;
    aChannel=new DChannelResManUs;
    return aChannel?KErrNone:KErrNoMemory;
    }


/***************************************************************************************
	class DChannelResManUs
 ***************************************************************************************/
DChannelResManUs::DChannelResManUs() 
// Constructor
    {
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DChannelResManUs()"));
    iClient=&Kern::CurrentThread();
	// Increase the DThread's ref count so that it does not close without us
	iClient->Open();
    }


DChannelResManUs::~DChannelResManUs()
// Destructor
    {
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::~DChannelResManUs()"));

	// Cancel any outstanding requests
	//
	// For each tracker (Get, Set and notify)
	// 
	if(iGetStateTracker != NULL)
		{
		CancelTrackerRequests(iGetStateTracker,EFalse,0,NULL); // EFalse,0, to ignore resource IDs
		RemoveTrackingControl(iGetStateTracker);
		}
	if(iSetStateTracker != NULL)
		{
		CancelTrackerRequests(iSetStateTracker,EFalse,0,NULL); // EFalse,0, to ignore resource IDs
		RemoveTrackingControl(iSetStateTracker);
		}
	if(iListenableTracker != NULL)
		{
		CancelTrackerRequests(iListenableTracker,EFalse,0,NULL); // EFalse,0, to ignore resource IDs
		RemoveTrackingControl(iListenableTracker);
		}

	delete iUserNameUsed;
	delete iResourceDependencyIds;
	delete iClientNamesResCtrl;
	delete iResourceInfoResCtrl;

	// decrement the DThread's reference count
	Kern::SafeClose((DObject*&)iClient, NULL);
    }


static void AsyncCallBackFn(TUint aClient, TUint aResourceId, TInt aLevel, TInt aLevelOwnerId, TInt aResult, TAny* aTrackingBuffer)
	{
// Callback function for asynchronous requests
    __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));
	TTrackingBuffer* buffer = ((TTrackingBuffer*)aTrackingBuffer);
	TTrackingControl* tracker = buffer->GetTrackingControl();
	__ASSERT_ALWAYS((tracker!=NULL),RESMANUS_FAULT());
	DChannelResManUs* channel = tracker->iOwningChannel;

#ifdef PRM_US_INSTRUMENTATION_MACRO
	if(tracker->iType==EGetState)
		{
		PRM_US_GET_RESOURCE_STATE_END_TRACE;
		}
	else if(tracker->iType==ESetState)
		{
		PRM_US_SET_RESOURCE_STATE_END_TRACE;
		}
#endif
	if(tracker->iType == EGetState)
		{
		TTrackGetStateBuf* stateBuf = (TTrackGetStateBuf*)aTrackingBuffer;
		if(aResult==KErrNone)
			{
			// Write the state value to the user-supplied variable
			stateBuf->iRequest->Data1() = aLevel;
			stateBuf->iRequest->Data2() = aLevelOwnerId;
			}
		Kern::QueueRequestComplete(channel->iClient, ((TTrackGetStateBuf*)buffer)->iRequest, aResult);
		}
	else if(tracker->iType == ESetState)
		{
		Kern::QueueRequestComplete(channel->iClient, ((TTrackSetStateBuf*)buffer)->iRequest, aResult);
		}
	// Once notified of a change in a resource state, must cancel the notification
	// request in the Resource Controller to give the client the appearance of a 
	// 'one'shot' type of operation.
	else if(tracker->iType==ENotify)
		{
#ifdef PRM_ENABLE_EXTENDED_VERSION
		if(((TInt)aClient==KDynamicResourceDeRegistering)&&(aResourceId&KIdMaskDynamic))  
			{
			// Resource has de-registered from Resource Controller, so can't expect any more notifications
			// of this type. Cancellation of notifications (i.e. invoke Resource Controller) and transfer of
			// buffers to free queue (for both conditional and unconditional notifications) is already done.
			// To distinguish removal of a dynamic resource, hijack aResult (the value used when completing
			// the user-side TRequestStatus object) and set it to KErrDisconnected.
			aResult = KErrDisconnected;
			}

#endif
		TInt r = (channel->iPddPtr)->CancelNotification(channel->ClientHandle(),aResourceId,
										((TTrackNotifyBuf*)buffer)->iNotifyBlock);
		__ASSERT_ALWAYS((r == KErrCancel),RESMANUS_FAULT());
		Kern::QueueRequestComplete(channel->iClient, ((TTrackNotifyBuf*)buffer)->iRequest, aResult);
		}

	// Return the tracking buffer to the free queue
	channel->FreeTrackingBuffer(buffer);
	}

TInt DChannelResManUs::GetValidName(const TDesC8* aInfo)
	{
// Extract a usable name from that supplied by the client
	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::GetValidName"));
	TInt err=KErrNone;
	if(aInfo)
		{
		DThread* thread = &Kern::CurrentThread();
		TInt nameLen = Kern::ThreadGetDesLength(thread, aInfo);
		if(nameLen<0)
			return nameLen; // return error code
		iNameProvidedLength = nameLen;
		if(nameLen > MAX_CLIENT_NAME_LENGTH)
			err=KErrBadName;
		else
			{
			nameLen = (nameLen<=MAX_NAME_LENGTH_IN_RESMAN) ? nameLen : MAX_NAME_LENGTH_IN_RESMAN;
			if((iUserNameUsed = HBuf8::New(nameLen))==NULL)
				return KErrNoMemory;
			err = Kern::ThreadDesRead(thread,aInfo,*iUserNameUsed,0);
			if(err!=KErrNone)
				return err;
			}
		}
	else
		err=KErrBadName;
	return err;
	}

TInt DChannelResManUs::RequestUserHandle(DThread* aThread, TOwnerType aType)
// Called when a user thread requests a handle to this channel
    {
    // Make sure that only our client can get a handle
	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::RequestUserHandle"));
    if (aType!=EOwnerThread || aThread!=iClient)
        return KErrAccessDenied;
    return KErrNone;
    }

void DChannelResManUs::RegistrationDfcFunc(TAny* aChannel)
	{
	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::RegistrationDfcFunc"));
	// DFC function invoked for registration with Resource Controller
	DChannelResManUs* channel = (DChannelResManUs*)aChannel;
	// RegisterProxyClient(TUint& aProxyId, const TDesC& aName);
	TUint uintVal=0;
	TInt r = KErrNone;
	__ASSERT_ALWAYS((r==KErrNone),RESMANUS_FAULT());

	r=(channel->iPddPtr)->RegisterProxyClient(uintVal,*((TDesC8*)(channel->iUserNameUsed)));
	if(r!=KErrNone)
		{
		// Registration failed
		// Ensure that the client-side flag is cleared in uintVal
		// so the failure can be detected in DoCreate
		uintVal &= ~USER_SIDE_CLIENT_BIT_MASK; // Copied from rescontrol_export
		}
	channel->SetClientHandle((TInt)uintVal);
	NKern::FSSignal(channel->iFastSem);
	}


TInt DChannelResManUs::RegisterWithResCtrlr()
	{
	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::RegisterWithResCtrlr"));
	TInt r = KErrNone;
	// Initialise the channel's fast semaphore
	iFastSem = new NFastSemaphore();
	if(iFastSem == NULL)
		r = KErrNoMemory;
	else
		{
		iFastSem->iOwningThread = (NThreadBase*)NKern::CurrentThread();

		// Attempt to perform registration with the Resource Controller on behalf of the client.
		SetDfcQ(((DDeviceResManUs*)(iDevice))->iSharedDfcQue);
		TDfc tempDfc(RegistrationDfcFunc, this, iDfcQ, KResManUsRegistrationPriority);

		// Block this thread until the DFC has executed
		tempDfc.Enque();
		NKern::FSWait(iFastSem);
		// Have finished with iFastSem
		delete iFastSem;

		// Registration complete - check success
		if(!(USER_SIDE_CLIENT_BIT_MASK & ClientHandle()))
			{
			// Registration failed
			r = KErrCouldNotConnect;	
			}
		// Start receiving messages ...
		iMsgQ.Receive();
		}
	return r;
	}

TInt DChannelResManUs::DoCreate(TInt /*aUnit*/,
                                const TDesC8* aInfo, 
                                const TVersion &aVer)
// Create the channel from the passed info.
    {
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer)"));

	TInt r = KErrNone;
	iPddPtr = ((DUserSideProxyInterface*)iPdd)->iController;
	// Check client has appropriate capabilities
	if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by DDevicePowerRsrc::Create")))
		return KErrPermissionDenied;

	// Check software version
	if (!Kern::QueryVersionSupported(TVersion(KResManUsMajorVersionNumber,
			 KResManUsMinorVersionNumber,
			 KResManUsBuildVersionNumber),
				     aVer))
		return KErrNotSupported;

	// Implementation note: if this method fails, the destructor will be invoked
	// as part of which all successfully-allocated memory will be freed. Therefore,
	// no memory will be explicitly freed in the event of failure in the code which follows.
	
	// Allocate the arrays used for acquiring client, resource and dependency information
	if((iClientNamesResCtrl = HBuf8::New(KNumClientNamesResCtrl * sizeof(TPowerClientInfoV01)))==NULL)
		return KErrNoMemory;
	if((iResourceInfoResCtrl = HBuf8::New(KNumResourceInfoResCtrl * sizeof(TPowerResourceInfoV01)))==NULL)
		return KErrNoMemory;
	if((iResourceDependencyIds = HBuf8::New(KNumResourceDependencies * sizeof(SResourceDependencyInfo)))==NULL)
		return KErrNoMemory;
	// Obtain the channel name to use
	if((r=GetValidName(aInfo))!=KErrNone)
		return r;
#ifdef PRM_ENABLE_EXTENDED_VERSION
	iResDepsValid = 0;
#endif

#ifdef PRM_US_INSTRUMENTATION_MACRO
	PRM_US_OPEN_CHANNEL_START_TRACE;	 
#endif

	// Set up the request tracking support
	iGetStateTracker = new TTrackingControl();
	iSetStateTracker = new TTrackingControl();;
	iListenableTracker = new TTrackingControl();
	if((iGetStateTracker==NULL) || (iSetStateTracker==NULL) || (iListenableTracker==NULL))
		return KErrNoMemory;

	// Register with the Resource Controller
	r = RegisterWithResCtrlr();

#ifdef PRM_US_INSTRUMENTATION_MACRO
	PRM_US_OPEN_CHANNEL_END_TRACE;
#endif

    return r;
    }

//Override sendMsg to allow data copy in the context of client thread for WDP.
TInt DChannelResManUs::SendMsg(TMessageBase* aMsg)
	{
	TThreadMessage& m = *(TThreadMessage*)aMsg;
	TInt id = m.iValue;
	TInt r = KErrNone;
	if (id != (TInt)ECloseMsg && id != KMaxTInt)
		{
		if (id<0)
			{
			TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
			r = SendRequest(aMsg);
			if (r != KErrNone)
				Kern::RequestComplete(pS,r);
			}
		else
			r = SendControl(aMsg);
		}
	else
		r = DLogicalChannel::SendMsg(aMsg);
	return r;
	}

TInt DChannelResManUs::SendRequest(TMessageBase* aMsg)
	{
	TThreadMessage& m = *(TThreadMessage*)aMsg;
	TInt id = ~m.iValue;
	TRequestStatus* pS = (TRequestStatus*)m.Ptr0();
	TInt r = KErrNone;
	TTrackingBuffer *trackBuf = NULL;
	TUint parms[4];
	TPowerResourceCb *callBack;
	DPowerResourceNotification *prn;

	switch(id)
		{
		case RBusDevResManUs::EChangeResourceState:
			{
			__ASSERT_ALWAYS(m.Ptr2() != NULL, RESMANUS_FAULT());
#ifdef _DUMP_TRACKERS
			if((r=DumpTracker(iSetStateTracker))!=KErrNone)
				break;
#endif
			r = GetAndInitTrackingBuffer(iSetStateTracker, trackBuf, (TUint)m.Ptr1(), pS);
			if( r != KErrNone)
				return r;
			callBack = &(((TTrackSetStateBuf*)trackBuf)->iCtrlBlock);
			new (callBack) TPowerResourceCb(&AsyncCallBackFn, (TAny*)trackBuf, iDfcQ, KResManCallBackPriority);
			parms[0] = (TUint)m.Ptr2();
			parms[1] = (TUint)callBack;
			m.iArg[2] = &(parms[0]);
			break;
			}
		case RBusDevResManUs::EGetResourceState:
			{
			__ASSERT_ALWAYS(m.Ptr2() != NULL, RESMANUS_FAULT());
			umemget32(&(parms[0]), m.Ptr2(), 3*sizeof(TInt));
#ifdef _DUMP_TRACKERS
			if((r=DumpTracker(iGetStateTracker))!=KErrNone)
				break;
#endif
			r = GetStateBuffer(iGetStateTracker, trackBuf, (TUint)m.Ptr1(), (TInt*)parms[1], (TInt*)parms[2], callBack, pS);
			if(r != KErrNone)
				return r;
			parms[3] = (TUint)callBack;
			m.iArg[2] = &(parms[0]);
			break;
			}
		case RBusDevResManUs::ERequestChangeNotification:
			{
			__ASSERT_ALWAYS(m.Ptr1() != NULL, RESMANUS_FAULT());
			r = GetAndInitTrackingBuffer(iListenableTracker, trackBuf, (TUint)m.Ptr1(), pS);
			if(r != KErrNone)
				return r;
			prn = &(((TTrackNotifyBuf*)trackBuf)->iNotifyBlock);
			new (prn) DPowerResourceNotification(&AsyncCallBackFn, (TAny*)trackBuf, iDfcQ, KResManCallBackPriority);
			m.iArg[2] = (TAny*)prn;
			break;
			}
		case RBusDevResManUs::ERequestQualifiedChangeNotification:
			{
			__ASSERT_ALWAYS(m.Ptr1() != NULL, RESMANUS_FAULT());
			__ASSERT_ALWAYS(m.Ptr2() != NULL, RESMANUS_FAULT());
			umemget32(&(parms[0]), m.Ptr2(), 2*sizeof(TUint));
			m.iArg[2] = &parms[0];
			r = GetAndInitTrackingBuffer(iListenableTracker, trackBuf, (TUint)parms[0], pS);
			if(r != KErrNone)
				return r;
			prn = &(((TTrackNotifyBuf*)trackBuf)->iNotifyBlock);
			new (prn) DPowerResourceNotification(&AsyncCallBackFn, (TAny*)trackBuf, iDfcQ, KResManCallBackPriority);
			parms[2] = (TUint)prn;
			break;
			}
		default:
			{
			return KErrNotSupported;
			}
		}

	if(r == KErrNone)
		r = DLogicalChannel::SendMsg(aMsg);
	if(r != KErrNone)
		FreeTrackingBuffer(trackBuf);
	return r;
	}


TInt DChannelResManUs::SendControl(TMessageBase* aMsg)
	{
	TThreadMessage& m = *(TThreadMessage*)aMsg;
	TInt id = m.iValue;
	TInt param1 = 0;
	TUint parms[4];
	TAny* a1 = m.Ptr0();
	TAny* a2 = m.Ptr1();
	TAny* ptr1 = NULL;
	switch(id)
		{
		case RBusDevResManUs::EInitialise:
			{
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
			TUint8 stateRes[3];
			umemget(&(stateRes[0]), a1, 3*sizeof(TUint8));
			m.iArg[0] = &(stateRes[0]);
			break;
			}
		case RBusDevResManUs::EGetNoOfResources:
		case RBusDevResManUs::EGetResourceControllerVersion:
			{
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
			m.iArg[0] = &param1;
			break;
			}
		case RBusDevResManUs::EGetNoOfClients:
		case RBusDevResManUs::EGetNumClientsUsingResource:
			{
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
			umemget32(&(parms[0]), a2, 3*sizeof(TUint));
			m.iArg[1]  = &(parms[0]);
			m.iArg[0] = &param1;
			break;
			}
		case RBusDevResManUs::EGetNumResourcesInUseByClient:
			{
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
			TBuf8 <MAX_NAME_LENGTH_IN_RESMAN> clientName;
			Kern::KUDesGet(clientName, *(TDesC8*)m.Ptr0());
			m.iArg[0] = (TAny*)&clientName;
			umemget32(&(parms[0]), m.Ptr1(), 2*sizeof(TUint));
			param1 = parms[1];
			m.iArg[1] = &param1;
			break;
			}
		case RBusDevResManUs::EGetResourceIdByName:
			{
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
			TBuf8 <MAX_NAME_LENGTH_IN_RESMAN> resourceName;
			Kern::KUDesGet(resourceName, *(TDesC8*)m.Ptr0());
			m.iArg[0] = (TAny*)&resourceName;
			m.iArg[1] = &param1;
			break;
			}
#ifdef RESOURCE_MANAGER_SIMULATED_PSL
		case RBusDevResManUs::EGetNumCandidateAsyncResources:
		case RBusDevResManUs::EGetNumCandidateSharedResources:
			{
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
			m.iArg[0] = &param1;
			break;
			}
		case RBusDevResManUs::EGetCandidateAsyncResourceId:
		case RBusDevResManUs::EGetCandidateSharedResourceId:
			{
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
			m.iArg[1] = &param1;
			break;
			}
#endif
		case RBusDevResManUs::EGetNumDependentsForResource:
			{
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
			umemget32(&(parms[0]), m.Ptr1(), 2*sizeof(TUint));
			m.iArg[1] = &(parms[0]);
			m.iArg[0] = &param1;
			break;
			}
		case RBusDevResManUs::EGetDependentsIdForResource:
			{
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
			umemget32(&(parms[0]), m.Ptr1(), 3*sizeof(TUint));
			TInt len, maxLen;
			ptr1 = (TAny*)parms[1];
			Kern::KUDesInfo(*(const TDesC8*)parms[1], len, maxLen);
			umemget32(&param1, m.Ptr0(), sizeof(TUint));
			if((maxLen - len) < (TInt)(param1 * sizeof(SResourceDependencyInfo)))
				{
				return KErrArgument;
				}
			m.iArg[0] = &param1;
			m.iArg[1] = &(parms[0]);
			break;
			}
		case RBusDevResManUs::EGetResourceInfo:
			{
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
			TResourceInfoBuf buf;
			m.iArg[1] = &buf;
			break;
			}
		case RBusDevResManUs::EGetAllResourcesInfo:
			{
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
			umemget32(&(parms[0]), m.Ptr1(), 2*sizeof(TUint));
			ptr1 = (TAny*)parms[0];
			umemget32(&param1, (TAny*)parms[0], sizeof(TUint));
			parms[0]  =(TUint)&param1;
			RSimplePointerArray<TResourceInfoBuf> infoPtrs;
			umemget(&infoPtrs, m.Ptr0(), sizeof(RSimplePointerArray<TResourceInfoBuf>));
			if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
				return KErrArgument;
			m.iArg[1] = &(parms[0]);
			break;
			}
		case RBusDevResManUs::EGetInfoOnClientsUsingResource:
			{
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
			umemget32(&parms[0], m.Ptr1(), 4*sizeof(TUint));
			ptr1 = (TAny*)parms[0];
			umemget32(&param1, (TAny*)parms[0], sizeof(TUint));
			parms[0] = (TUint)&param1;
			RSimplePointerArray<TClientInfoBuf>infoPtrs;
			umemget(&infoPtrs, m.Ptr0(), sizeof(RSimplePointerArray<TClientInfoBuf>));
			if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
				return KErrArgument;
			m.iArg[1] = &(parms[0]);
			break;
			}
		case RBusDevResManUs::EGetNamesAllClients:
			{
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
			umemget32(&parms[0], m.Ptr1(), 4*sizeof(TUint));
			ptr1 = (TAny*)parms[0];
			umemget32(&param1, (TAny*)parms[0], sizeof(TUint));
			parms[0] = (TUint)&param1;
			RSimplePointerArray<TClientName> infoPtrs;
			umemget(&infoPtrs, m.Ptr0(), sizeof(RSimplePointerArray<TClientName>));
			if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
				return KErrArgument;
			m.iArg[1] = &(parms[0]);
			break;
			}
		case RBusDevResManUs::EGetInfoOnResourcesInUseByClient:
			{
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
			TBuf8 <MAX_NAME_LENGTH_IN_RESMAN> clientName;
			Kern::KUDesGet(clientName, *(TDesC8*)m.Ptr0());
			m.iArg[0] = (TAny*)&clientName;
			umemget32(&parms[0], m.Ptr1(), 3*sizeof(TUint));
			ptr1 = (TAny*)parms[0];
			umemget32(&param1, (TAny*)parms[0], sizeof(TUint));
			parms[0] = (TUint)&param1;
			RSimplePointerArray<TResourceInfoBuf> infoPtrs;
			umemget(&infoPtrs, (TAny*)parms[1], sizeof(RSimplePointerArray<TResourceInfoBuf>));
			if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
				return KErrArgument;
			m.iArg[1] = &(parms[0]);
			break;
			}
		}

	TInt r = DLogicalChannel::SendMsg(aMsg);
	if(r != KErrNone)
		return r;

	switch(id)
		{
		case RBusDevResManUs::EGetNoOfResources:
		case RBusDevResManUs::EGetNoOfClients:
		case RBusDevResManUs::EGetNumClientsUsingResource:
		case RBusDevResManUs::EGetResourceControllerVersion:
		case RBusDevResManUs::EGetNumDependentsForResource:
			{
			umemput32(a1, (TAny*)&param1, sizeof(TUint));
			break;
			}
		case RBusDevResManUs::EGetNumResourcesInUseByClient:
			{
			umemput32((TAny*)parms[0], (TAny*)&param1, sizeof(TUint));
			break;
			}
		case RBusDevResManUs::EGetResourceIdByName:
			{
			umemput32(a2, (TAny*)&param1, sizeof(TUint));
			break;
			}
#ifdef RESOURCE_MANAGER_SIMULATED_PSL
		case RBusDevResManUs::EGetNumCandidateAsyncResources:
		case RBusDevResManUs::EGetNumCandidateSharedResources:
			{
			umemput32(a1, (TAny*)&param1, sizeof(TUint));
			break;
			}
		case RBusDevResManUs::EGetCandidateAsyncResourceId:
		case RBusDevResManUs::EGetCandidateSharedResourceId:
			{
			umemput32(a2, (TAny*)&param1, sizeof(TUint));
			break;
			}
#endif
		case RBusDevResManUs::EGetDependentsIdForResource:
			{
			r = Kern::ThreadDesWrite(iClient,(TAny*)ptr1, (const TDesC8&)*(SResourceDependencyInfo*)parms[1], 0);
			if(r == KErrOverflow) //This is done to retain the error as per API spec
				r = KErrArgument;
			break;
			}
		case RBusDevResManUs::EGetResourceInfo:
			{
			Kern::KUDesPut(*(TDes8*)a2, (const TDesC8&)*(TResourceInfoBuf*)m.Ptr1());
			break;
			}
		case RBusDevResManUs::EGetAllResourcesInfo:
			{
			TUint numToCopy;
			RSimplePointerArray<TResourceInfoBuf> infoPtrs;
			umemget(&infoPtrs, a1, sizeof(RSimplePointerArray<TResourceInfoBuf>));
			numToCopy = (infoPtrs.Count() < param1) ? infoPtrs.Count() : param1;
			umemput32(ptr1, (TAny*)&param1, sizeof(TUint));
			TResourceInfoBuf** entriesAddr = infoPtrs.Entries();
			TInt* entryPtr = (TInt*)entriesAddr;
			TPowerResourceInfoV01 *currRes = (TPowerResourceInfoV01*)iResourceInfoResCtrl->Ptr();
			TResourceInfoBuf* clientAddr;
			TResourceInfoBuf tempInfo;
			for(TUint index = 0; index < numToCopy; index++)
				{
				umemget32(&clientAddr, entryPtr, sizeof(TResourceInfoBuf*));
				entryPtr++;
				r = ExtractResourceInfo(currRes, tempInfo);
				if(r != KErrNone)
					return r;
				umemput((TAny*)clientAddr, (TAny*)&(tempInfo), tempInfo.Length());
				currRes++;
				}
			break;
			}
		case RBusDevResManUs::EGetInfoOnClientsUsingResource:
			{
			TUint numToCopy;
			RSimplePointerArray<TClientInfoBuf> infoPtrs;
			umemget(&infoPtrs, a1, sizeof(RSimplePointerArray<TClientName>));
			numToCopy = infoPtrs.Count();
			TClientInfoBuf** entriesAddr = infoPtrs.Entries();
			TInt* entryPtr = (TInt*)entriesAddr;
			TPowerClientInfoV01* rcDataPtr = (TPowerClientInfoV01*)iClientNamesResCtrl->Ptr();
			TClientInfoBuf* clientAddr;
			TUint userSideClients = 0;
			TClientInfoBuf tempInfo;
			for(TInt index = 0; index < param1; index++)
				{
				if((!parms[1]) && !(rcDataPtr->iClientId & USER_SIDE_CLIENT_BIT_MASK))
					{
					rcDataPtr++;
					continue;
					}
				if(numToCopy == 0)
					{
					userSideClients++;
					continue;
					}
				umemget32(&clientAddr, entryPtr, sizeof(TClientName*));
				entryPtr++;
				tempInfo().iId = rcDataPtr->iClientId;
				tempInfo().iName = *rcDataPtr->iClientName;
				Kern::InfoCopy(*clientAddr, tempInfo);
				rcDataPtr++;
				numToCopy--;
				userSideClients++;
				}
			if(parms[1])
				umemput32(ptr1, (TAny*)&param1, sizeof(TUint));
			else
				umemput32(ptr1, (TAny*)&userSideClients, sizeof(TUint));
			break;
			}
		case RBusDevResManUs::EGetNamesAllClients:
			{
			TUint numToCopy;
			RSimplePointerArray<TClientName> infoPtrs;
			umemget(&infoPtrs, a1, sizeof(RSimplePointerArray<TClientName>));
			numToCopy = infoPtrs.Count();
			TClientName** entriesAddr = infoPtrs.Entries();
			TInt* entryPtr = (TInt*)entriesAddr;
			TPowerClientInfoV01* rcDataPtr = (TPowerClientInfoV01*)iClientNamesResCtrl->Ptr();
			TClientName* clientAddr;
			TUint userSideClients = 0;
			for(TInt index = 0; index < param1; index++)
				{
				if((!parms[1]) && !(rcDataPtr->iClientId & USER_SIDE_CLIENT_BIT_MASK))
					{
					rcDataPtr++;
					continue;
					}
				if(numToCopy == 0)
					{
					userSideClients++;
					continue;
					}
				umemget32(&clientAddr, entryPtr, sizeof(TClientName*));
				entryPtr++;
				Kern::KUDesPut(*((TDes8*)clientAddr), *(const TDesC8*)rcDataPtr->iClientName);
				rcDataPtr++;
				numToCopy--;
				userSideClients++;
				}
			if(parms[1])
				umemput32(ptr1, (TAny*)&param1, sizeof(TUint));
			else
				umemput32(ptr1, (TAny*)&userSideClients, sizeof(TUint));
			break;
			}
		case RBusDevResManUs::EGetInfoOnResourcesInUseByClient:
			{
			TUint numToCopy;
			RSimplePointerArray<TResourceInfoBuf> infoPtrs;
			umemget(&infoPtrs, (TAny*)parms[1], sizeof(RSimplePointerArray<TResourceInfoBuf>));
			numToCopy = (infoPtrs.Count() < param1) ? infoPtrs.Count() : param1;
			umemput32(ptr1, (TAny*)&param1, sizeof(TUint));
			TResourceInfoBuf** entriesAddr = infoPtrs.Entries();
			TInt* entryPtr = (TInt*)entriesAddr;
			TPowerResourceInfoV01* currRes = (TPowerResourceInfoV01*)iResourceInfoResCtrl->Ptr();
			TResourceInfoBuf* clientAddr;
			TResourceInfoBuf tempInfo;
			for(TUint index = 0; index < numToCopy; index++)
				{
				umemget32(&clientAddr, entryPtr, sizeof(TResourceInfoBuf*));
				entryPtr++;
				r = ExtractResourceInfo(currRes, tempInfo);
				if(r != KErrNone)
					return r;
				umemput((TAny*)clientAddr, (TAny*)&(tempInfo), tempInfo.Length());
				currRes++;
				}
			break;
			}
		}
	return r;
	}

void DChannelResManUs::HandleMsg(TMessageBase* aMsg)
    {
    TThreadMessage& m=*(TThreadMessage*)aMsg;
    TInt id=m.iValue;
    
    __KTRACE_OPT(KRESMANAGER, Kern::Printf(" >ldd: DChannelResManUs::HandleMsg(TMessageBase* aMsg) id=%d\n", id));
	
	if (id==(TInt)ECloseMsg)
		{
		// Deregister here to ensure the correct thread ID is read
		if(ClientHandle() != 0)
			{
			// Must de-register from Resource Controller before closing down
			// Not checking return value - still need to delete allocated buffers
#ifdef PRM_US_INSTRUMENTATION_MACRO
	PRM_US_DEREGISTER_CLIENT_START_TRACE;
#endif
			((DPowerResourceController*)iPddPtr)->DeregisterProxyClient(ClientHandle());

#ifdef PRM_US_INSTRUMENTATION_MACRO
	PRM_US_DEREGISTER_CLIENT_END_TRACE;
#endif
			SetClientHandle(0);
			}
	    iMsgQ.iMessage->Complete(KErrNone,EFalse);
		return;
		}
    else if (id==KMaxTInt)
		{
		// DoCancel
		DoCancel(m.Int0());
		m.Complete(KErrNone,ETrue);
		return;
		}

    if (id<0)
		{
		// DoRequest
		TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
		TInt r=DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
		m.Complete(r,ETrue);
		}
    else
		{
		// DoControl
		__KTRACE_OPT(KRESMANAGER, Kern::Printf(" >ldd: do control id=%d...\n", id));
		TInt r=DoControl(id,m.Ptr0(),m.Ptr1());
		m.Complete(r,ETrue);
		}
	}

TInt DChannelResManUs::CancelTrackerRequests(TTrackingControl* aTracker, TBool aSingleRsrc, TUint aResourceId, TRequestStatus* aStatus)
	{
	// Cancel all outstanding requests from this client for a specified operation on 
	// a specified resource

	// Loop all entries in the iBusyQue of requests to locate a match for the 
	// operation type and resource ID
	//
	// For each match, remove the buffer from the busy queue and return to the free queue
	// If the request is already being processed, and so the callback function will be called
	// later, then the callback will exit gracefully.
	//
    __KTRACE_OPT(KRESMANAGER, Kern::Printf(" > DChannelResManUs::CancelTrackerRequests"));
	TInt returnVal = KErrNone;
	TBool statusMatched=EFalse;
	TTrackingBuffer* firstLink = NULL;
	TTrackingBuffer* lastLink = NULL;
	TInt type = aTracker->iType;

#ifdef PRM_US_INSTRUMENTATION_MACRO
	if(type==EGetState)
		{
		PRM_US_CANCEL_GET_RESOURCE_STATE_START_TRACE;
		}
	else if(type==ESetState)
		{
		PRM_US_CANCEL_SET_RESOURCE_STATE_START_TRACE;
		}
#endif

	if(aTracker->iBusyQue != NULL)
		{
		firstLink = (TTrackingBuffer*)(aTracker->iBusyQue->iA.iNext);
		lastLink = (TTrackingBuffer*)(&(aTracker->iBusyQue->iA));
		}
	while(( firstLink!=lastLink )&&(!statusMatched))
		{
		TTrackingBuffer* buffer = firstLink;
		TUint resourceId = buffer->GetResourceId();
		if(aSingleRsrc)
			if(resourceId != aResourceId)	// Required resource?
				{
				firstLink=(TTrackingBuffer*)(firstLink->iNext);
				continue;
				}
		if(aStatus!=NULL)
			{
			TClientRequest *request;
			GET_USER_REQUEST(request, buffer, type)
			if(request->StatusPtr() == aStatus)
				{
				statusMatched = ETrue;
				}
			else
				{
				firstLink=(TTrackingBuffer*)(firstLink->iNext);
				continue;
				}
			}
		TInt r = KErrNone;
		if(type==EGetState)
			{
			TTrackGetStateBuf* stateBuf = (TTrackGetStateBuf*)firstLink;
			r=((DPowerResourceController*)iPddPtr)->CancelAsyncRequestCallBack(ClientHandle(),
															resourceId, (stateBuf->iCtrlBlock));
			}
		else if(type==ESetState)
			{
			TTrackSetStateBuf* stateBuf = (TTrackSetStateBuf*)firstLink;
			r = ((DPowerResourceController*)iPddPtr)->CancelAsyncRequestCallBack(ClientHandle(), 
															resourceId, (stateBuf->iCtrlBlock));
			}
		else if(type==ENotify)
			{
			TTrackNotifyBuf* notifyBuf = (TTrackNotifyBuf*)firstLink;
			r=((DPowerResourceController*)iPddPtr)->CancelNotification(ClientHandle(), resourceId,
															notifyBuf->iNotifyBlock);
			}

		// Process the accumulated return value
		if((r==KErrCompletion)&&((returnVal==KErrNone)||(returnVal==KErrCancel)))
			{
			returnVal=KErrCompletion;	
			}
		else if((r==KErrInUse)&&
			((returnVal==KErrNone)||(returnVal==KErrCompletion)||(returnVal==KErrCancel)))
			{
			returnVal=KErrInUse;
			}
		else if(r!=KErrCancel)
			{
			returnVal=r;
			}

		// Return the tracking buffer to the free queue
		TTrackingBuffer* tempLink = (TTrackingBuffer*)(firstLink->iNext);
		FreeTrackingBuffer(firstLink);
		firstLink = tempLink;

#ifdef PRM_US_INSTRUMENTATION_MACRO
	if(type==EGetState)
		{
		PRM_US_CANCEL_GET_RESOURCE_STATE_END_TRACE;
		}
	else if(type==ESetState)
		{
		PRM_US_CANCEL_SET_RESOURCE_STATE_END_TRACE;
		}
#endif
		// Complete the TRequestStatus object
		if((r!=KErrCompletion)&&(r!=KErrInUse))
			{
			TClientRequest* request;
			GET_USER_REQUEST(request, buffer, type)
			Kern::QueueRequestComplete(iClient, request, r);
			}

		} //  while
	return returnVal;
	}


TTrackingControl* DChannelResManUs::MapRequestToTracker(TInt aRequestType)
// Utility function to map identifiers for cancel commands to request types.
	{
	TTrackingControl *tracker=NULL;
	switch(aRequestType)
		{
		case RBusDevResManUs::ECancelChangeResourceStateRequests:
		case RBusDevResManUs::ECancelChangeResourceState:
			{
			tracker=iSetStateTracker;
			break;
			}
		case RBusDevResManUs::ECancelGetResourceStateRequests:
		case RBusDevResManUs::ECancelGetResourceState:
			{
			tracker=iGetStateTracker;
			break;
			}
		case RBusDevResManUs::ECancelChangeNotificationRequests:
		case RBusDevResManUs::ECancelRequestChangeNotification:
			{
			tracker=iListenableTracker;
			break;
			}
		default:
			{
			__ASSERT_ALWAYS(0,RESMANUS_FAULT());
			}
		}
	return tracker;
	}


TInt DChannelResManUs::CancelRequestsOfType(TInt aRequestType, TRequestStatus* aStatus)
// Cancel a particular request. This may be qualified by the type of operation
    {
	__ASSERT_ALWAYS(((aRequestType==RBusDevResManUs::ECancelChangeResourceState)||
					(aRequestType==RBusDevResManUs::ECancelGetResourceState)||
					(aRequestType==RBusDevResManUs::ECancelRequestChangeNotification)||
					(KMaxTInt)),
					RESMANUS_FAULT());
	// For the KMaxTInt case, the type of the request is not known and so all trackers
	// must be considered before the request is found.
	// For all other cases, only the relevant tracker is searched.
	TInt r=KErrNone;
	if(aRequestType!=KMaxTInt)
		{
		TTrackingControl*tracker=MapRequestToTracker(aRequestType);
		r=CancelTrackerRequests(tracker, EFalse, 0, aStatus);
		}
	else
		{
		TTrackingControl* tracker[3] = {iGetStateTracker, iSetStateTracker, iListenableTracker};
		TUint8 index=0;
		while((index<3) && (r==KErrNone))
			{
			r=CancelTrackerRequests(tracker[index], EFalse, 0, aStatus);
			++index;
			}
		}
	if(r==KErrCancel) 
		r=KErrNone;	// All cancellations were successful

	return r;
	}


void DChannelResManUs::DoCancel(TInt aMask)
// Cancel an outstanding request.
    {
	TRequestStatus* status = (TRequestStatus*)aMask;
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoCancel, TRequestStatus addr = 0x%x",(TInt)status));

	CancelRequestsOfType(KMaxTInt, status); // Ignore return value
	return;
	}

TInt DChannelResManUs::DoRequest(TInt aReqNo, TRequestStatus* /*aStatus*/, TAny* a1, TAny* a2)
// Asynchronous requests.
    {
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)"));

    TInt r=KErrNone;
    switch (aReqNo)
		{
		case RBusDevResManUs::EChangeResourceState:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case EChangeResourceState"));
			// a1 specifies the identifier of the required resource
			// a2 specifies the required state for the resource
			//
			TUint *param = (TUint*)a2;
			TUint resourceId = (TUint)a1;
			TInt newState = (TInt)param[0];

#ifdef PRM_US_INSTRUMENTATION_MACRO
	PRM_US_SET_RESOURCE_STATE_START_TRACE;
#endif
				// Invoke the API
				r=((DPowerResourceController*)iPddPtr)->ChangeResourceState(ClientHandle(),
														resourceId, newState, (TPowerResourceCb*)param[1]);
			break;
			}

		case RBusDevResManUs::EGetResourceState:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case EGetResourceState"));
			// a1 specifies the resource ID
			// a2 specifies the container stating if a cached value is required, the address of the variable
			// to be update with the state value and the address of the level owner ID
			//
			TUint resourceId = (TUint)a1;
			TUint *parms = (TUint*)a2;
			TBool cached = (TBool)(parms[0]);

#ifdef PRM_US_INSTRUMENTATION_MACRO
	PRM_US_GET_RESOURCE_STATE_START_TRACE;
#endif
				// Always invoke the asynchronous version of the API
				r=((DPowerResourceController*)iPddPtr)->GetResourceState(ClientHandle(),
																		resourceId, cached, *((TPowerResourceCb*)parms[3]));
			break;
			}


		case RBusDevResManUs::ERequestChangeNotification:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case ERequestChangeNotification"));
			// a1 specifies the resource ID
			r=((DPowerResourceController*)iPddPtr)->RequestNotification(ClientHandle(),
														(TUint)a1, *((DPowerResourceNotification*)a2));
			break;
			}

		case RBusDevResManUs::ERequestQualifiedChangeNotification:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case ERequestQualifiedChangeNotification"));
			// a1 specifies the threshold value that the state is to change by
			// a2 specifies the address of the container holding the resourceID and the required direction
			TInt threshold = (TInt)a1;
			TUint *parms = (TUint*)a2;
			TUint resourceId = parms[0];
			TBool direction = (TBool)(parms[1]);			
			r=((DPowerResourceController*)iPddPtr)->RequestNotification(ClientHandle(),
														resourceId, *((DPowerResourceNotification*)parms[2]), threshold, direction);
			break;
			}

		default:
	    	return KErrNotSupported;
		}
	    return r;
    }

TInt DChannelResManUs::DoControl(TInt aFunction, TAny* a1, TAny* a2)
// Synchronous requests.
    {
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DoControl(TInt aFunction, TAny* a1, TAny* a2)") );

    TInt r=KErrNone;
    switch (aFunction)
		{
		case RBusDevResManUs::EInitialise:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EInitialise"));
			// a1 specifies the array describing the number of 'gettable' and 'settable' state resources
			// and the number of 'listenable' resources
			//
			TUint8 *stateRes = (TUint8*)a1;
#ifdef PRM_US_INSTRUMENTATION_MACRO
	PRM_US_REGISTER_CLIENT_START_TRACE;
#endif
			// The call to the Resource Controller's AllocReserve method requires two parameters:
			// the number of client level objects and the number of request message objects
			// Each 'settable' state resource requires a client level object and a request message object
			// Each 'gettable' state resource requires a request message object, only.
			// Call Resource Control to make allocations
			r=((DPowerResourceController*)iPddPtr)->AllocReserve(ClientHandle(),
															stateRes[1],							// Number of settable
															(TUint8)(stateRes[1] + stateRes[0]));	// Number of (settable + gettable)
#ifdef PRM_US_INSTRUMENTATION_MACRO
	PRM_US_REGISTER_CLIENT_END_TRACE;
#endif
			if(r==KErrNone)
				{
				// Require 1 TPowerResourceCb object per gettable resource state
				// Require 1 TPowerResourceCb object per settable resource state
				// Require 1 DPowerResourceNotification object per listenable resource
				//
				if(stateRes[0]>0)
					r=InitTrackingControl(iGetStateTracker,EGetState,stateRes[0]);
				if((r==KErrNone) && (stateRes[1]>0))
					r=InitTrackingControl(iSetStateTracker,ESetState,stateRes[1]);
				if((r==KErrNone) && (stateRes[2]>0))
					r=InitTrackingControl(iListenableTracker,ENotify,stateRes[2]);
#ifdef _DUMP_TRACKERS
			if((r=DumpTracker(iGetStateTracker))!=KErrNone)
				break;
			if((r=DumpTracker(iSetStateTracker))!=KErrNone)
				break;
#endif
				}
			break;
			}

		case RBusDevResManUs::EGetNoOfResources:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNoOfResources"));
			TUint numResources;
			r=((DPowerResourceController*)iPddPtr)->GetNumResourcesInUseByClient(ClientHandle(),0,numResources);
			iResInfoValid = 0;			// New numResources invalidates the iResInfoXXXX information
			iResInfoStoredClientId = 0;
			iResInfoStoredNum = 0;
			if(r!=KErrNone)
				return r;
			// a2 specifies whether the resource information should be loaded
			if((r==KErrNone)&&(a2!=NULL))
				{
				TUint prevNumRes = 0;
				while((numResources != prevNumRes)&&(r==KErrNone))
					{
					// if the number of resources is greater than can be accommodated by the array,
					// re-size it
					if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
						break;
					prevNumRes = numResources;
					// Get the resource info from the Resource Controller
					// Specify 'aTargetClientId' as zero to access all resources
					iResourceInfoResCtrl->SetLength(0);
					r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
															ClientHandle(),0,numResources,iResourceInfoResCtrl);
					}
				if(r==KErrNone)
					{
					iResInfoValid = 1;
					iResInfoStoredClientId = KAllResInfoStored;
					iResInfoStoredNum = numResources;
					}
				}
			if(r==KErrNone)
				*(TUint*)a1 = numResources;
			break;
			}

		case RBusDevResManUs::EGetAllResourcesInfo:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetAllResourcesInfo"));
			// Parameters are passed in TUint* parms[2]
			// The address of the number of resources is at element 0
			// The flag to indicate if the resource info stored is to be refreshed is at element 1
			TUint* parms = (TUint*)a2;
			TUint numResources = *(TUint*)parms[0];
			TBool refresh=(TBool)(parms[1]);
			
			// The results are to be written to an RSimplePointerArray, the address is in a1
			// Check that the array has enough elements
			if(refresh)
				{
				// For the refresh option, invoke Resource Controller API once, only (do not recurse)
				// If the number of requested resources is greater than can be accommodated by the array,
				// re-size it
				if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
					break;
				// Get the resource info from the Resource Controller
				// Specify 'aTargetClientId' as zero to access all resources
				iResourceInfoResCtrl->SetLength(0);
				r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
														ClientHandle(),0,numResources,iResourceInfoResCtrl);
				if(numResources != iResInfoStoredNum)
					{
					iResInfoValid = 0;		// Assume cohesion is now lost 
					iResInfoStoredClientId = 0;
					iResInfoStoredNum = 0;
					}
				}
			else
				{
				// If the information stored is not valid or is not for all resources return KErrNotReady 
				if((iResInfoValid != 1)||(iResInfoStoredClientId != KAllResInfoStored))
					{
					r=KErrNotReady;
					break;
					}
				// The number of resources for which information is available in this case is iResInfoStoredNum
				numResources = iResInfoStoredNum;
				}
#ifdef RESOURCE_MANAGER_SIMULATED_PSL
			TPowerResourceInfoV01* currRes = (TPowerResourceInfoV01*)iResourceInfoResCtrl->Ptr();
			for(TUint index = 0; index < numResources; index++)
				{
				CheckForCandidateAsyncResource(currRes);
				CheckForCandidateSharedResource(currRes);
				currRes++;
				}
#endif
			*(TUint*)(parms[0]) = numResources;

			break;
			}

		case RBusDevResManUs::EGetNoOfClients:
		case RBusDevResManUs::EGetNumClientsUsingResource:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNoOfClients"));
			// Parameters are passed in TUint parms[3]
			// The flag to indicate if kernel-side clients are to be included is at element 0
			// The ID of the resource of interest (0 is expected for EGetNoOfClients)
			// The flag to indicate if the client info is to be read now is at element 1
			TUint *parms = (TUint*)a2;
			TUint includeKern = parms[0];
			TUint resourceId = parms[1];
			TUint infoRead = parms[2];
			TUint requiredId = resourceId;
			if(aFunction == RBusDevResManUs::EGetNoOfClients)
				{
				__ASSERT_ALWAYS(resourceId==0,RESMANUS_FAULT());
				requiredId = KAllClientInfoStored;
				}
			TUint numClients = 0;
			if(includeKern==1)
				{
				// Client must exhibit PlatSec capability ReadDeviceData
				if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNoOfClients")))
					{
					r =  KErrPermissionDenied;
					break;
					}
				if(r==KErrNone)
					r=((DPowerResourceController*)iPddPtr)->GetNumClientsUsingResource(ClientHandle(),resourceId,numClients);
				}
			else
				numClients = (TUint)(iDevice->iOpenChannels);

			// New numClients invalidates the iClientInfoXXXX information
			iClientInfoValid = 0;
			iClientInfoStoredResId = 0;
			iClientInfoStoredNum= 0;

			if((r==KErrNone)&&(infoRead==1))
				{
				// Capability check already performed, so no need to repeat ...
				TUint prevNumClients = 0;
				while((numClients != prevNumClients)&&(r == KErrNone))
					{
					// Ensure buffer is large enough to store the information
					if((r=EnsureSizeIsSufficient(iClientNamesResCtrl, (TInt)(numClients*sizeof(TPowerClientInfoV01))))!=KErrNone)
						break;
					prevNumClients = numClients;
					// Invoke the API
					r=((DPowerResourceController*)iPddPtr)->GetInfoOnClientsUsingResource(ClientHandle(),
																					resourceId,numClients,iClientNamesResCtrl);
					};

				if(r==KErrNone)
					{
					iClientInfoValid = 1;
					iClientInfoStoredResId = requiredId;
					iClientInfoStoredNum = numClients;
					if(includeKern!=1)
						{
						TUint numAllClients = numClients;
						numClients = 0;
						TPowerClientInfoV01* rcDataPtr = (TPowerClientInfoV01*)(iClientNamesResCtrl->Ptr());
						for(TUint i=0; i<numAllClients; i++)
							{
							if( rcDataPtr->iClientId & USER_SIDE_CLIENT_BIT_MASK)
								++numClients;
							++rcDataPtr;
							}
						}
					}
				}
			if(r==KErrNone)
				*(TUint*)a1 = numClients;
			break;
			}

		case RBusDevResManUs::EGetNamesAllClients:
		case RBusDevResManUs::EGetInfoOnClientsUsingResource:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNamesAllClients-EGetInfoOnClientsUsingResource"));
			// Parameters are passed in TUint* parms[4]
			// The address of the number of clients is at element 0
			// The flag to indicate if kernel-side info is requested is at element 1
			// The resource ID is at element 2
			// The flag to indicate if the client information stored is to be refreshed is at element 3
			TUint* parms = (TUint*)a2;
			TUint numClients = *(TUint*)parms[0];
			TBool includeKern=(TBool)(parms[1]);
			TUint resourceId=(TUint)(parms[2]);
			TBool refresh=(TBool)(parms[3]);
		
			TUint numClientsAvailable = 0; 
			iClientNamesResCtrl->SetLength(0);
			
			if(includeKern)
				{
				// Client must exhibit PlatSec capability ReadDeviceData
				if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNamesAllClients-EGetInfoOnClientsUsingResource")))
					{
					r = KErrPermissionDenied;
					break;  // Early exit in event of error
					}
				TUint requiredId = (resourceId==0)?(TUint)KAllClientInfoStored:resourceId;
				if(refresh)
					{
					// For the refresh option, invoke Resource Controller API once, only (do not recurse)
					// If the number of clients is greater than can be accommodated by the array,
					// re-size it
					if((r=EnsureSizeIsSufficient(iClientNamesResCtrl, (TInt)(numClients*sizeof(TPowerClientInfoV01))))!=KErrNone)
						break;
					// Invoke the API
					numClientsAvailable = numClients; // Arbitrary initialisation (to silence compiler warning)
					r=((DPowerResourceController*)iPddPtr)->GetInfoOnClientsUsingResource(ClientHandle(),
																					resourceId,numClientsAvailable,iClientNamesResCtrl);
					if((r!=KErrNone)||(numClientsAvailable != iClientInfoStoredNum)||(iClientInfoStoredResId != requiredId))
						{
						iClientInfoValid = 0;	// Assume cohesion is now lost	
						iClientInfoStoredResId = 0;
						iClientInfoStoredNum = 0;
						}
					}
				else
					{
					// If the information stored is not valid, is not for the required resources return KErrNotReady 
					if((iClientInfoValid != 1)||(iClientInfoStoredResId != requiredId))
						r=KErrNotReady;
					// The number of clients for which information is available in this case is iClientInfoStoredNum
					numClientsAvailable = iClientInfoStoredNum;
					}
				}
			else
				{
				// Resource Controller will return information for the number of clients requested,
				// taken in order from its internal storage - but this will be regardless of whether
				// they are kernel-side or user-side; the USER_SIDE_CLIENT_BIT_MASK bit must be 
				// interrogated to determine this.
				//
				// Therefore, need to read all the clients - but to do this, must find out how many 
				// clients there are first.
				TUint numAllClients;
				r=((DPowerResourceController*)iPddPtr)->GetNumClientsUsingResource(ClientHandle(),resourceId,numAllClients);
				if(r!=KErrNone)
					break;  // Early exit in event of error
				if(numAllClients > 0)
					{
					if(refresh)
						{
						// For the refresh option, invoke Resource Controller API once, only (do not recurse)
						// If the number of clients is greater than can be accommodated by the array,
						// re-size it
						if((r=EnsureSizeIsSufficient(iClientNamesResCtrl, (TInt)(numAllClients*sizeof(TPowerClientInfoV01))))!=KErrNone)
							break;
						// Invoke the API
						r=((DPowerResourceController*)iPddPtr)->GetInfoOnClientsUsingResource(ClientHandle(),
																						resourceId,numAllClients,iClientNamesResCtrl);
						TUint requiredId = (resourceId==0)?(TUint)KAllClientInfoStored:resourceId;
						if((r!=KErrNone)||(numClientsAvailable != iClientInfoStoredNum)||(iClientInfoStoredResId != requiredId))
							{
							iClientInfoValid = 0;	// Assume cohesion is now lost	
							iClientInfoStoredResId = 0;
							iClientInfoStoredNum = 0;
							break;
							}
						else
							{
							iClientInfoValid = 1;
							iClientInfoStoredResId = requiredId;
							iClientInfoStoredNum = numAllClients;
							}
						}
					else
						{
						// If the information stored is not valid, is not for the required resources return KErrNotReady 
						TUint requiredId = (resourceId==0)?(TUint)KAllClientInfoStored:resourceId;
						if((iClientInfoValid != 1)||(iClientInfoStoredResId != requiredId))
							{
							r=KErrNotReady;
							break;
							}
						// The number of clients for which information is available in this case is iClientInfoStoredNum
						numAllClients = iClientInfoStoredNum;
						}
					numClientsAvailable = numAllClients;
					} // if(numAllClients > 0)
				}
			// Write the total number of user side cients available
			*(TUint*)parms[0] = numClientsAvailable;
			break;
			}
		case RBusDevResManUs::EGetNumResourcesInUseByClient:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumResourcesInUseByClient"));
			// a1 specifies the container holding the client name
			//
			
			// If client doesn't exist, return KErrNotFound
			// If client has appropriate capabilities, or if the client for which the information is sought
			// is user-side, invoke the Resource Controller API directly
			// Otherwise, return KErrPermissionDenied
			TUint clientId=0;
			r=((DPowerResourceController*)iPddPtr)->GetClientId(ClientHandle(),
															*(TDesC8*)a1,clientId);
			if(r!=KErrNone)
				return KErrNotFound;
			// Perform capability check
			if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNoOfClients")))
				{
				if(!(clientId & USER_SIDE_CLIENT_BIT_MASK))
					return KErrPermissionDenied;
				}
			TUint numResources=0;
			if(r==KErrNone)
				r=((DPowerResourceController*)iPddPtr)->GetNumResourcesInUseByClient(ClientHandle(),
																			clientId,numResources);
			// New numResources invalidates the iResXXXX information
			iResInfoValid = 0;
			iResInfoStoredClientId = 0;
			iResInfoStoredNum= 0;

			// parms[1] specifies whether the resource information should be loaded
			if((r==KErrNone)&&(*(TUint*)a2 != NULL))
				{
				TUint prevNumRes = 0;
				while((numResources != prevNumRes)&&(r==KErrNone))
					{
					// if the number of resources is greater than can be accommodated by the array,
					// re-size it
					if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
						break;
					prevNumRes = numResources;
					// Get the resource info from the Resource Controller
					// Specify 'aTargetClientId' as zero to access all resources
					iResourceInfoResCtrl->SetLength(0);
					r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
															ClientHandle(),clientId,numResources,iResourceInfoResCtrl);
					}
				if(r==KErrNone)
					{
					iResInfoValid = 1;
					iResInfoStoredClientId = clientId;
					iResInfoStoredNum = numResources;
					}
				}
			if(r==KErrNone)
				*(TUint*)a2 = numResources;
			break;
			}

		case RBusDevResManUs::EGetInfoOnResourcesInUseByClient:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetInfoOnResourcesInUseByClient"));
			// a1 specifies the container holding the client name
			// a2 specifies an array TUint* parms[3] which contains:
			//   - the address of the variable to write the number of reasources to
			//   - a pointer to the container to hold the resources' information
			//   - the flag to indicate whether the resource info should be (re-)read here

			TUint clientId=0;
			TUint *parms = (TUint*)a2;
			TUint numResources = *(TUint*)parms[0];
			// The results are to be written to an RSimplePointerArray, the address is in parms[1]
			// Check that the array has enough elements
			// If client doesn't exist, return KErrNotFound
			// If client has appropriate capabilities, or if the client for which the information is sought
			// is user-side, invoke the Resource Controller API directly
			// Otherwise, return KErrPermissionDenied
			r=((DPowerResourceController*)iPddPtr)->GetClientId(ClientHandle(),
															*(TDesC8*)a1,clientId);
			if(r!=KErrNone)
				return KErrNotFound;
			// Perform capability check
			if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNoOfClients")))
				{
				if(!(clientId & USER_SIDE_CLIENT_BIT_MASK))
					return KErrPermissionDenied;
				}

			TUint updatedNumResources = numResources;
			r=((DPowerResourceController*)iPddPtr)->GetNumResourcesInUseByClient(ClientHandle(),clientId,updatedNumResources);
			if(r!=KErrNone)
				break;

			if(updatedNumResources>0)
				{
				if((TUint)(parms[2] != 0))
					{
					// For the refresh option, invoke Resource Controller API once, only (do not recurse)
					// If the number of requested resources is greater than can be accommodated by the array,
					// re-size it
					if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
						break;
					// Get the resource info from the Resource Controller
					// Specify 'aTargetClientId' as zero to access all resources
					iResourceInfoResCtrl->SetLength(0);
					r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
															ClientHandle(),clientId,numResources,iResourceInfoResCtrl);
					if((numResources != iResInfoStoredNum)||(iResInfoStoredClientId != clientId))
						{
						iResInfoValid = 0;		// Assume cohesion is now lost 
						iResInfoStoredClientId = 0;
						iResInfoStoredNum = 0;
						}
					}
				else
					{
					// If the information stored is not valid or is not for the required clientId return KErrNotReady 
					if((iResInfoValid != 1)||(iResInfoStoredClientId != clientId))
						r=KErrNotReady;
					// The number of resources for which information is available in this case is iResInfoStoredNum
					numResources = iResInfoStoredNum;
					}
				}
			if(r==KErrNone)
				*(TUint*)parms[0] = updatedNumResources;

			break;
			}

		case RBusDevResManUs::EGetResourceIdByName:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetResourceIdByName"));
			// a1 specifies the container holding the resource name
			// a2 specifies the variable to be update with the ID
			TUint resourceId;
			r=((DPowerResourceController*)iPddPtr)->GetResourceId(ClientHandle(), *(TDesC8*)a1, resourceId);
			if(r==KErrNone)
				*(TUint *)a2 = resourceId;
			break;
			}

		case RBusDevResManUs::EGetResourceInfo:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetResourceInfo"));
			// a1 specifies the container holding the resource ID
			// a2 specifies the address of the container to be written to

			TUint resourceId= (TUint)a1;
			TPowerResourceInfoBuf01 resCtrlInfo;
			resCtrlInfo.SetLength(0);
			TResourceInfoBuf tempInfo;
			r=((DPowerResourceController*)iPddPtr)->GetResourceInfo(ClientHandle(),resourceId,&resCtrlInfo);
			if(r==KErrNone)
				{
				// Copy the client buffer to tempInfo so that its size can be determined
				// by ExtractResourceInfo
				r=ExtractResourceInfo(&(resCtrlInfo()), tempInfo);
				}			
			if(r==KErrNone)
				{
				// Write the resources' info to the client thread
				*(TResourceInfoBuf*)a2 = tempInfo;
				}
			break;
			}


		case RBusDevResManUs::ECancelChangeResourceStateRequests:
		case RBusDevResManUs::ECancelGetResourceStateRequests:
		case RBusDevResManUs::ECancelChangeNotificationRequests:
			{
			TUint resourceId = (TUint)a1;
			TTrackingControl*tracker=MapRequestToTracker(aFunction);
			r=CancelTrackerRequests(tracker, ETrue, resourceId, NULL);
			if(r==KErrCancel)
				r=KErrNone;	// All cancellations were successful
			break;
			}

		case RBusDevResManUs::ECancelChangeResourceState:
		case RBusDevResManUs::ECancelGetResourceState:
		case RBusDevResManUs::ECancelRequestChangeNotification:
			{
			TRequestStatus* status = (TRequestStatus*)a1;
			r=CancelRequestsOfType(aFunction, status);
			break;
			}


#ifdef RESOURCE_MANAGER_SIMULATED_PSL
		case RBusDevResManUs::EGetNumCandidateAsyncResources:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumCandidateAsyncResources"));
			TUint numResources;
			GetNumCandidateAsyncResources(numResources);
			// Write the result to the client thread
			*(TUint*)a1 = numResources;
			break;
			}
		case RBusDevResManUs::EGetCandidateAsyncResourceId:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetCandidateAsyncResourceId"));
			// Get the index to use
			TUint index = (TUint)a1;
			TUint resourceId = 0;
			r=GetCandidateAsyncResourceId(index, resourceId);
			if(r==KErrNone)				// Write the result to the client thread
				*(TUint*)a2 = resourceId;
			break;
			}

		case RBusDevResManUs::EGetNumCandidateSharedResources:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumCandidateSharedResources"));
			TUint numResources;
			GetNumCandidateSharedResources(numResources);
			// Write the result to the client thread
			*(TUint*)a1 = numResources;
			break;
			}
		case RBusDevResManUs::EGetCandidateSharedResourceId:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetCandidateSharedResourceId"));
			// Get the index to use
			TUint index = (TUint)a1;
			TUint resourceId = 0;
			r=GetCandidateSharedResourceId(index, resourceId);
			if(r==KErrNone)				// Write the result to the client thread
				*(TUint*)a2 = resourceId;
			break;
			}
#endif

		case RBusDevResManUs::EGetResourceControllerVersion:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetResourceControllerVersion"));
			// a1 specifies the address of the TVersion variable to be written to
			// a2 is not used
			TUint version;
			if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(), 
																	KResManControlIoGetVersion, 
																	(TAny*)&version,
																	NULL, 
																	NULL))!=KErrNone)
				return r;
			// Write the required information
			*(TUint*)a1 = version;
			break;
			}
		
		case RBusDevResManUs::EGetNumDependentsForResource:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumDependentsForResource"));
			// a1 specifies a pointer to the variable to be written to
			// a2 specifies an array TUint parms[2] which contains:
			//   - the resource ID
			//   - flag to indicate if dependency information is to be loaded as part of this call
			TUint *parms = (TUint*)a2;
			TUint numDependents = 0;
			r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(), 
																	KResManControlIoGetNumDependents,
																	(TAny*)(parms[0]),	// Resource ID
																	&numDependents,
																	NULL);
			iResDepsValid=EFalse; // The number of dependents may differ from the dependency information stored
			if(r!=KErrNone)
				return r;

			// Load the dependency information, if required.
			if(parms[1])
				{
				// The dependency information may be updated subsequent to the request for the number of dependents. In order
				// to provide a coherent number and array of dependents, the requests for dependency information will be
				// re-issued if the (new) number of dependents differs from that previously read.
				TUint prevNumDeps = 0;
				TUint newNumDeps = numDependents;
				while((newNumDeps != prevNumDeps)&&(r == KErrNone))
					{
					if((r=EnsureSizeIsSufficient(iResourceDependencyIds, (TInt)(newNumDeps*sizeof(SResourceDependencyInfo))))!=KErrNone)
						return r;
					prevNumDeps = newNumDeps;
					if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(), 
																			KResManControlIoGetDependentsId,
																			(TAny*)(parms[0]),	// Resource ID
																			(TAny*)(iResourceDependencyIds),
																			(TAny*)&newNumDeps))!=KErrNone)
						return r;
					};
				// Dependency information now in synch with number reported
				numDependents = newNumDeps;
				iNumResDepsStored = newNumDeps;
				iResDepsValid = ETrue;
				}
			// Write the number of dependents to the client thread
			*(TUint*)a1 = numDependents;
			break;
			}


		case RBusDevResManUs::EGetDependentsIdForResource:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetDependentsIdForResource"));
			// a1 specifies a pointer to the variable to hold the number of dependencies
			// a2 specifies an array TUint parms[4] which contains:
			//   - the resource ID
			//   - the address of the array to write the required IDs to
			//   - flag to indicate if dependency information is to be (re-)loaded as part of this call
			TUint *parms = (TUint*)a2;
			TUint numDependents = 0;

			// (Re-)Load the dependency information, if required.
			if(parms[2])
				{
				if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(), 
															KResManControlIoGetNumDependents, 
															(TAny*)(parms[0]), 
															(TAny*)&numDependents, 
															NULL))!=KErrNone)
					return r;

				iResDepsValid=EFalse; // The number of dependents may differ from the dependency information stored
				// In order to provide a coherent number and array of dependents, the requests for dependency information
				// will be re-issued if the (new) number of dependents differs from that previously read.
				TUint prevNumDeps = 0;
				TUint newNumDeps = numDependents;
				while(newNumDeps != prevNumDeps)
					{
					if((r=EnsureSizeIsSufficient(iResourceDependencyIds, (TInt)(newNumDeps*sizeof(SResourceDependencyInfo))))!=KErrNone)
						return r;
					prevNumDeps = newNumDeps;
					if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(), 
																			KResManControlIoGetDependentsId,
																			(TAny*)(parms[0]),	// Resource ID
																			(TAny*)(iResourceDependencyIds),
																			(TAny*)&newNumDeps))!=KErrNone)
						return r;
					};

				// Dependency information now in synch with number reported
				numDependents = newNumDeps;
				iNumResDepsStored = newNumDeps;
				iResDepsValid = ETrue;
				}

			// If iResDepsValid equals zero, the results are invalid - so return KErrNotReady.
			if(iResDepsValid==0)
				return KErrNotReady;

			// Write the number of dependencies available to the client
			*(TUint*)a1 = iNumResDepsStored;
			// Write the dependencies to the client array if it is of sufficient size
			// Copy the required dependency information to the user-supplied container.
			parms[1] = (TUint)iResourceDependencyIds;
			break;
			}
		
		default:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl default 0x%x", aFunction));
			r=KErrNotSupported;
			}
		}
	    return(r);
    }


TInt DChannelResManUs::EnsureSizeIsSufficient(HBuf*& aBuffer, TInt aMinSize)
	{
// Utility function to ensure a buffer is of at least the minimum required size
// If the buffer is to small, an attempt is made to increase its size.
// If the re-sizing fails, KErrNoMemory is returned; otherwise KErrNone.
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::EnsureSizeIsSufficient"));

	if(aBuffer->MaxLength() < aMinSize)
		{
		aBuffer = aBuffer->ReAlloc(aMinSize);
		if(aBuffer->MaxLength() < aMinSize)
			return KErrNoMemory; // ReAlloc failed - aBuffer is unchanged
		}
	aBuffer->SetLength(0);
	return KErrNone;
	}

void DChannelResManUs::FreeTrackingBuffer(TTrackingBuffer*& aBuffer)
	{
	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::FreeTrackingBuffer"));
	// Function invoked for to free tracking buffers from the busy to free queue of a tracking control
	__ASSERT_ALWAYS((aBuffer!=NULL),RESMANUS_FAULT());
	NKern::FMWait(&iBufferFastMutex);
	TTrackingControl* tracker = aBuffer->GetTrackingControl();
	SDblQue* bufQue = aBuffer->GetQue();

	__ASSERT_ALWAYS(((tracker!=NULL)&&(bufQue!=NULL)),RESMANUS_FAULT());

	// Check that the buffer is still in the busy queue of the tracker - exit if not
	if(bufQue == tracker->iBusyQue)
		{
		aBuffer->Deque();
		tracker->iFreeQue->Add(aBuffer);
		aBuffer->SetQue(tracker->iFreeQue);
		}
	NKern::FMSignal(&iBufferFastMutex);	
	}


TInt DChannelResManUs::GetAndInitTrackingBuffer(TTrackingControl*& aTracker, TTrackingBuffer*& aBuffer, TUint aResourceId, TRequestStatus* aStatus)
	{
// Utility function - perform the necessary processing to get a buffer to support
// asynchronous requests to change the state of a resource
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetAndInitTrackingBuffer"));
	TInt r=KErrNone;
	NKern::FMWait(&iBufferFastMutex);
	if(aTracker->iFreeQue->IsEmpty())
		r = KErrUnderflow;
	else
		{
		// Need intermediate cast from SDblQueLink* to TAny* before TTrackingBuffer*
		TAny* ptr = (TAny*)(aTracker->iFreeQue->GetFirst());
		aBuffer = (TTrackingBuffer*)ptr;
		aTracker->iBusyQue->Add((SDblQueLink*)ptr);
		aBuffer->SetQue(aTracker->iBusyQue);
		aBuffer->SetResourceId(aResourceId);
		TClientRequest* request;
		TTrackingControl* tracker = aBuffer->GetTrackingControl();
		GET_USER_REQUEST(request, aBuffer, tracker->iType);
		request->Reset();
		request->SetStatus(aStatus);
		}
	NKern::FMSignal(&iBufferFastMutex);	
	return r;
	}

TInt DChannelResManUs::GetStateBuffer(TTrackingControl*& aTracker, TTrackingBuffer*& aBuffer, TUint aResourceId, TInt* aState, TInt* aLevelOwnerPtr, TPowerResourceCb*& aCb, TRequestStatus* aStatus)
	{
// Utility function - perform the necessary processing to get a buffer and control block
// to support asynchronous requests to change the state of a resource
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetStateBuffer"));

	TInt r=GetAndInitTrackingBuffer(aTracker, aBuffer, aResourceId, aStatus);
	if(r==KErrNone)
		{
		TTrackGetStateBuf* stateBuf = (TTrackGetStateBuf*)aBuffer;
		stateBuf->iRequest->SetDestPtr1(aState);
		stateBuf->iRequest->SetDestPtr2(aLevelOwnerPtr);
		// Use placement new to update the content of the TPowerResourceCb
		aCb = &(stateBuf->iCtrlBlock);
		new (aCb) TPowerResourceCb(&AsyncCallBackFn,(TAny*)aBuffer,iDfcQ,KResManCallBackPriority);
		}
	return r;
	}


#ifdef _DUMP_TRACKERS
TInt DChannelResManUs::DumpTracker(TTrackingControl* aTracker)
	{
	Kern::Printf("\nDChannelResManUs::DumpTracker");
	Kern::Printf("Tracker at 0x%x\n",aTracker);
	if(NULL==aTracker)
		return KErrGeneral;
	Kern::Printf("iType=%d",aTracker->iType);
	switch(aTracker->iType)
		{
		case 0:
			Kern::Printf("= GetState tracker\n");
		break;
		case 1:
			Kern::Printf("= SetState tracker\n");
		break;
		case 2:
			Kern::Printf("= Notify tracker\n");
		break;
		}
	Kern::Printf("iOwningChannel at 0x%x\n",aTracker->iOwningChannel);
	Kern::Printf("iFreeQue at 0x%x\n",aTracker->iFreeQue);
	SDblQueLink* buf;
	if(aTracker->iFreeQue!=NULL)
		{
		buf=aTracker->iFreeQue->First();
		while(buf!=aTracker->iFreeQue->Last())
			{
			Kern::Printf("iFreeQue buffer at 0x%x\n",buf);
			TAny* intermediatePtr = (TAny*)buf;
			if((aTracker->iType == EGetState)||(aTracker->iType == ESetState))
				{
				TTrackStateBuf* tempBuf =(TTrackStateBuf*)intermediatePtr;
				Kern::Printf("buffer control block at 0x%x\n",tempBuf->iCtrlBlock);
				}
			buf= buf->iNext;
			};
		}
	Kern::Printf("iBusyQue at 0x%x\n",aTracker->iBusyQue);
	if(aTracker->iBusyQue!=NULL)
		{
		buf=aTracker->iBusyQue->First();
		while(buf!=aTracker->iBusyQue->Last())
			{
			Kern::Printf("iBusyQue buffer at 0x%x\n",buf);
			TAny* intermediatePtr = (TAny*)buf;
			if((aTracker->iType == EGetState)||(aTracker->iType == ESetState))
				{
				TTrackStateBuf* tempBuf =(TTrackStateBuf*)intermediatePtr;
				Kern::Printf("buffer control block at 0x%x\n",tempBuf->iCtrlBlock);
				}
			buf= buf->iNext;
			};
		}

	return KErrNone;
	}
#endif

TInt DChannelResManUs::InitTrackingControl(TTrackingControl*& aTracker, TUint8 aType, TUint8 aNumBuffers)
	{
// Set the tracker type, create the tracking queues and required tracking buffers.
// Assign all the tracking buffers to the free queue.
//
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::InitTrackingControl()"));

	TInt r = KErrNone;
	aTracker->iType = (TAsyncOpType)aType;
	aTracker->iOwningChannel = this;
	aTracker->iFreeQue = new SDblQue();
	__ASSERT_DEBUG(aTracker->iFreeQue != NULL, RESMANUS_FAULT());
	if(aTracker->iFreeQue == NULL)
		r = KErrNoMemory;
	if(r==KErrNone)
		{
		aTracker->iBusyQue = new SDblQue();
		__ASSERT_DEBUG(aTracker->iBusyQue != NULL, RESMANUS_FAULT());
		if(aTracker->iBusyQue == NULL)
			{
			delete aTracker->iFreeQue;
			r = KErrNoMemory;
			}
		}
	if(r==KErrNone)
		{
		for(TUint8 i=0; (i<aNumBuffers) && (r==KErrNone) ;i++)
			{
			TAny* buf = NULL;
			TAny* ptr=NULL; // To be assigned to non-NULL value later
			switch(aTracker->iType)
				{
				case EGetState:
					{
					buf = (TAny*)(new TTrackGetStateBuf(&AsyncCallBackFn,ptr,iDfcQ,KResManCallBackPriority));
					r = Kern::CreateClientDataRequest2(((TTrackGetStateBuf*)buf)->iRequest);
					break;
					}
				case ESetState:
					{
					buf = (TAny*)(new TTrackSetStateBuf(&AsyncCallBackFn, ptr, iDfcQ, KResManCallBackPriority));
					r = Kern::CreateClientRequest(((TTrackSetStateBuf*)buf)->iRequest);
					break;
					}
				case ENotify:
					{
					buf = (TAny*)(new TTrackNotifyBuf(&AsyncCallBackFn,ptr,iDfcQ,KResManCallBackPriority));
					r = Kern::CreateClientRequest(((TTrackNotifyBuf*)buf)->iRequest);
					break;
					}
				default:
					__ASSERT_ALWAYS(0,RESMANUS_FAULT());
				}
			__ASSERT_DEBUG(buf!=NULL, RESMANUS_FAULT());
			if((buf == NULL) || (r == KErrNoMemory))
				{
				r = KErrNoMemory;
				break;
				}
			else
				{
				((TTrackingBuffer*)buf)->SetTrackingControl(aTracker);
				(aTracker->iFreeQue)->Add((SDblQueLink*)buf);
				((TTrackingBuffer*)buf)->SetQue(aTracker->iFreeQue);
				}
			}
		// If buffer allocation failed, need to remove all previously-allocated buffers and the queues
		if(r!=KErrNone)
			{
			SDblQueLink* ptr = (aTracker->iFreeQue)->First();
			do
				{
				SDblQueLink* next = NULL;
				if(ptr !=NULL)
					next = ptr->iNext;
				delete ptr;
				ptr = next;
				} while ((ptr!=NULL)&&(ptr!=(aTracker->iFreeQue)->Last()));
			delete aTracker->iFreeQue;
			delete aTracker->iBusyQue;
			}
		}
	return r;
	}


void DChannelResManUs::RemoveTrackingControl(TTrackingControl*& aTracker)
    {
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::RemoveTrackingControl()"));

	// Free the resource-tracking links and their respective queues
	TAny* buf;
	if(aTracker->iFreeQue!=NULL)
		{
		while(!aTracker->iFreeQue->IsEmpty())
			{
			buf = (TAny*)(aTracker->iFreeQue->GetFirst()); // Dequeues the element
			delete buf;
			}
		delete aTracker->iFreeQue;
		}

	if(aTracker->iBusyQue!=NULL)
		{
		while(!aTracker->iBusyQue->IsEmpty())
			{
			buf = (TAny*)(aTracker->iBusyQue->GetFirst()); // Dequeues the element
			delete buf;
			}
		delete aTracker->iBusyQue;
		}
	delete aTracker;
    }


#ifdef RESOURCE_MANAGER_SIMULATED_PSL
void DChannelResManUs::CheckForCandidateAsyncResource(TPowerResourceInfoV01* aResource)
	{
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::CheckForCandidateAsyncResource"));
	// Proceed only if we already have less that the maximum number of candidate resources
	if(iNoCandidateAsyncRes >= MAX_NUM_CANDIDATE_RESOURCES)
		return;
	// For the purposes of asynchronous testing, we need a long latency resource
	if(((TInt)(aResource->iLatencyGet)==(TInt)(EResLongLatency)) && 
		((TInt)(aResource->iLatencySet)==(TInt)(EResLongLatency)))
		{
		// An additional requirement is that the level of the resource can be 
		// updated a sufficient amount of times to support the required testing.
		if(((aResource->iMaxLevel - aResource->iMinLevel) > LEVEL_GAP_REQUIRED_FOR_ASYNC_TESTING) &&
			((TInt)(aResource->iSense) == (TInt)(EResPositive)) )
			{
			TInt r=((DPowerResourceController*)iPddPtr)->GetResourceId(ClientHandle(), *(aResource->iResourceName), iCandidateAsyncResIds[iNoCandidateAsyncRes]);
			if(r!=KErrNone)
				{
				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Failed to identify long latency resource\n"));
				}
			else
				{
				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Potential async resource ID = %d\n",iCandidateAsyncResIds[iNoCandidateAsyncRes]));
				iHaveLongLatencyResource = ETrue;
				++iNoCandidateAsyncRes;
				}
			}
		}
	}


void DChannelResManUs::GetNumCandidateAsyncResources(TUint& aNumResources)
	{
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetNumCandidateAsyncResources"));

	aNumResources = iNoCandidateAsyncRes;
	}

TInt DChannelResManUs::GetCandidateAsyncResourceId(TUint aIndex, TUint& aResourceId)
	{
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetCandidateAsyncResourceId"));
	TInt r = KErrNone;
	if(aIndex>=iNoCandidateAsyncRes)
		r = KErrNotFound;
	else
		aResourceId = iCandidateAsyncResIds[aIndex];
	return r;
	}

void DChannelResManUs::CheckForCandidateSharedResource(TPowerResourceInfoV01* aResource)
	{
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::CheckForCandidateSharedResource"));

	// Proceed only if we already have less that the maximum number of candidate resources
	if(iNoCandidateSharedRes >= MAX_NUM_CANDIDATE_RESOURCES)
		return;

	// For the purposes of testing shared usgae of resources, we need a shareable resource
	if((TInt)(aResource->iUsage)==(TInt)(EResShared))
		{
		// An additional requirement is that the level of the resource can be 
		// updated a sufficient amount of times to support the required testing.
		if(((aResource->iMaxLevel - aResource->iMinLevel) > LEVEL_GAP_REQUIRED_FOR_SHARED_TESTING) &&
			((TInt)(aResource->iSense) == (TInt)(EResPositive)) )
			{
			TInt r=((DPowerResourceController*)iPddPtr)->GetResourceId(ClientHandle(), *(aResource->iResourceName), iCandidateSharedResIds[iNoCandidateSharedRes]);
			if(r!=KErrNone)
				{
				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Failed to identify shared resource\n"));
				}
			else
				{
				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Potential shared resource ID = %d\n",iCandidateSharedResIds[iNoCandidateAsyncRes]));
				iHaveLongLatencyResource = ETrue;
				++iNoCandidateSharedRes;
				}
			}
		}
	}

void DChannelResManUs::GetNumCandidateSharedResources(TUint& aNumResources)
	{
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetNumCandidateSharedResources"));

	aNumResources = iNoCandidateSharedRes;
	}

TInt DChannelResManUs::GetCandidateSharedResourceId(TUint aIndex, TUint& aResourceId)
	{
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetCandidateSharedResourceId"));
	TInt r = KErrNone;
	if(aIndex>=iNoCandidateSharedRes)
		r = KErrNotFound;
	else
		aResourceId = iCandidateSharedResIds[aIndex];
	return r;
	}

#endif

TInt DChannelResManUs::ExtractResourceInfo(const TPowerResourceInfoV01* aPwrResInfo, TResourceInfoBuf& aInfo)
	{
// Extract data from a TPowerResourceInfoV01 object to a TResourceInfo instance
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::ExtractResourceInfo"));

	TInt r=KErrNone;
	TInt copyLength=(((aInfo().iName).MaxLength())<((aPwrResInfo->iResourceName)->Length()))?
					(aInfo().iName).MaxLength():
					(aPwrResInfo->iResourceName)->Length();
	(aInfo().iName).Copy((aPwrResInfo->iResourceName)->Ptr(),copyLength);
	aInfo().iId = aPwrResInfo->iResourceId;
	aInfo().iClass	= (TResourceClass)aPwrResInfo->iClass;
	aInfo().iType	= (TResourceType)aPwrResInfo->iType;
	aInfo().iUsage	= (TResourceUsage)aPwrResInfo->iUsage;
	aInfo().iSense	= (TResourceSense)aPwrResInfo->iSense;
	aInfo().iMinLevel = aPwrResInfo->iMinLevel;
	aInfo().iMaxLevel = aPwrResInfo->iMaxLevel;

#ifdef _DUMP_TRACKERS
	r=DumpResource(aPwrResInfo);
#endif
	return r;
	}

#ifdef _DUMP_TRACKERS
TInt DChannelResManUs::DumpResource(const TPowerResourceInfoV01* aResource)
	{
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DumpResource"));
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("Resource name = %S \n",aResource->iResourceName));
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("Resource ID = 0x%d \n",aResource->iResourceId));
	switch(aResource->iClass)
		{
		case DStaticPowerResource::EPhysical:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("class = EPhysical\n"));
			break;
			}
		case DStaticPowerResource::ELogical:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("class = ELogical\n"));
			break;
			}
		default:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("class = % is UNKNOWN!\n"));
			return KErrGeneral;
			}
		}
	switch(aResource->iType)
		{
		case DStaticPowerResource::EBinary:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("type = EBinary\n"));
			break;
			}
		case DStaticPowerResource::EMultilevel:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("type = EMultilevel\n"));
			break;
			}
		case DStaticPowerResource::EMultiProperty:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("type = EMultiProperty\n"));
			break;
			}
		default:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("type = % is UNKNOWN!\n"));
			return KErrGeneral;
			}
		}
	switch(aResource->iUsage)
		{
		case DStaticPowerResource::ESingleUse:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("usage = ESingleUse\n"));
			break;
			}
		case DStaticPowerResource::EShared:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("usage = EShared\n"));
			break;
			}
		default:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("usage = % is UNKNOWN!\n"));
			return KErrGeneral;
			}
		}
	switch(aResource->iSense)
		{
		case DStaticPowerResource::EPositive:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = EPositive\n"));
			break;
			}
		case DStaticPowerResource::ENegative:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = ENegative\n"));
			break;
			}
		case DStaticPowerResource::ECustom:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = ECustom\n"));
			break;
			}
		default:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = % is UNKNOWN!\n"));
			return KErrGeneral;
			}
		}
	switch(aResource->iLatencyGet)
		{
		case DStaticPowerResource::EInstantaneous:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency get = EInstantaneous\n"));
			break;
			}
		case DStaticPowerResource::ENegative:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency get = ELongLatency\n"));
			break;
			}
		default:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency get = % is UNKNOWN!\n"));
			return KErrGeneral;
			}
		}
	switch(aResource->iLatencySet)
		{
		case DStaticPowerResource::EInstantaneous:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency set = EInstantaneous\n"));
			break;
			}
		case DStaticPowerResource::ENegative:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency set = ELongLatency\n"));
			break;
			}
		default:
			{
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency set = % is UNKNOWN!\n"));
			return KErrGeneral;
			}
		}
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("DefaultLevel = %d\n",aResource->iDefaultLevel));
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("MinLevel = %d\n",aResource->iMinLevel));
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("MaxLevel = %d\n",aResource->iMaxLevel));

	return KErrNone;
	}
#endif

#ifndef RESOURCE_MANAGER_SIMULATED_PSL
DECLARE_EXTENSION_LDD()
	{
	return new DDeviceResManUs;
	}


DECLARE_STANDARD_EXTENSION()
	{
	DDeviceResManUs* device = new DDeviceResManUs;
	__KTRACE_OPT(KBOOT, Kern::Printf("DECLARE_STANDARD_EXTENSION, device = 0x%x\n",device));

	if(device == NULL)
		return KErrNoMemory;
	else
		{
		device->iSharedDfcQue = new TDfcQue();
		if(device->iSharedDfcQue==NULL)
			return KErrNoMemory;

		return (Kern::InstallLogicalDevice(device));
		}
	}
#else
DECLARE_STANDARD_LDD()
	{
	TInt r = DSimulatedPowerResourceController::CompleteResourceControllerInitialisation();
	if(r != KErrNone)
		{
		// Unconditionally print message 
		__KTRACE_OPT(KRESMANAGER, Kern::Printf("DECLARE_STANDARD_LDD: initialise Resource Controller failed with %d\n",r));
		return NULL;
		}
	DDeviceResManUs* device = new DDeviceResManUs;
	return device;
	}
#endif