os/kernelhwsrv/kernel/eka/drivers/resmanus/d_resmanus.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// e32\drivers\resmanus\d_resmanus.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
// LDD for Resource Manager user side API
sl@0
    19
#include "resmanus.h"
sl@0
    20
#include <kernel/kern_priv.h>
sl@0
    21
#include <kernel/kernel.h>
sl@0
    22
#include <e32hal.h>
sl@0
    23
#include <e32uid.h>
sl@0
    24
#include <e32cmn.h>
sl@0
    25
#include <e32cmn_private.h>
sl@0
    26
#include <e32def_private.h>
sl@0
    27
#include <drivers/resource_extend.h>
sl@0
    28
sl@0
    29
#ifdef RESOURCE_MANAGER_SIMULATED_PSL
sl@0
    30
#include "rescontrol_psl.h"
sl@0
    31
#endif
sl@0
    32
sl@0
    33
#ifdef PRM_US_INSTRUMENTATION_MACRO
sl@0
    34
#include <drivers/resmanus_trace.h>
sl@0
    35
#endif
sl@0
    36
sl@0
    37
#ifdef PRM_ENABLE_EXTENDED_VERSION2
sl@0
    38
_LIT(KResManUsThreadName,"ResManUsExtendedCoreLddThread");
sl@0
    39
#elif defined (PRM_ENABLE_EXTENDED_VERSION)
sl@0
    40
_LIT(KResManUsThreadName,"ResManUsExtendedLddThread");
sl@0
    41
#else
sl@0
    42
_LIT(KResManUsThreadName,"ResManUsLddThread");
sl@0
    43
#endif
sl@0
    44
sl@0
    45
#define RESMANUS_FAULT()	Kern::Fault("RESMANUS",__LINE__)
sl@0
    46
sl@0
    47
const TInt KResManUsThreadPriority = 24;
sl@0
    48
const TInt KResManUsRegistrationPriority = 5; // Arbitrary! Can be 0-7, 7 is highest
sl@0
    49
const TInt KResManCallBackPriority = 5; // Arbitrary! Can be 0-7, 7 is highest
sl@0
    50
sl@0
    51
//Macro to return appropriate request type.
sl@0
    52
#define GET_USER_REQUEST(request, buffer, type)						\
sl@0
    53
	{																\
sl@0
    54
	if(type == EGetState)											\
sl@0
    55
		request = ((TTrackGetStateBuf*)buffer)->iRequest;			\
sl@0
    56
	else if(type == ESetState)										\
sl@0
    57
		request = ((TTrackSetStateBuf*)buffer)->iRequest;			\
sl@0
    58
	else															\
sl@0
    59
		request = ((TTrackNotifyBuf*)buffer)->iRequest;				\
sl@0
    60
	}
sl@0
    61
sl@0
    62
/***************************************************************************************
sl@0
    63
	class TTrackGetStateBuf
sl@0
    64
 ***************************************************************************************/
sl@0
    65
TTrackGetStateBuf::TTrackGetStateBuf(TPowerResourceCbFn aFn, TAny* aPtr,
sl@0
    66
						       TDfcQue* aQue, TInt aPriority)
sl@0
    67
							   :	iCtrlBlock(aFn, aPtr, aQue, aPriority)
sl@0
    68
	{
sl@0
    69
	iRequest = NULL;
sl@0
    70
	}
sl@0
    71
sl@0
    72
/***************************************************************************************
sl@0
    73
	class TTrackSetStateBuf
sl@0
    74
 ***************************************************************************************/
sl@0
    75
TTrackSetStateBuf::TTrackSetStateBuf(TPowerResourceCbFn aFn, TAny* aPtr,
sl@0
    76
						       TDfcQue* aQue, TInt aPriority)
sl@0
    77
							   :	iCtrlBlock(aFn, aPtr, aQue, aPriority)
sl@0
    78
	{
sl@0
    79
	iRequest = NULL;
sl@0
    80
	}
sl@0
    81
sl@0
    82
/***************************************************************************************
sl@0
    83
	class TTrackNotifyBuf
sl@0
    84
 ***************************************************************************************/
sl@0
    85
TTrackNotifyBuf::TTrackNotifyBuf(TPowerResourceCbFn aFn, TAny* aPtr,
sl@0
    86
								 TDfcQue* aQue, TInt aPriority)
sl@0
    87
							   :	iNotifyBlock(aFn, aPtr, aQue, aPriority)
sl@0
    88
	{
sl@0
    89
	iRequest = NULL;
sl@0
    90
	}
sl@0
    91
sl@0
    92
TTrackNotifyBuf::~TTrackNotifyBuf()
sl@0
    93
	{
sl@0
    94
	if(iRequest)
sl@0
    95
		Kern::DestroyClientRequest(iRequest);
sl@0
    96
	}
sl@0
    97
sl@0
    98
TTrackSetStateBuf::~TTrackSetStateBuf()
sl@0
    99
	{
sl@0
   100
	if(iRequest)
sl@0
   101
		Kern::DestroyClientRequest(iRequest);
sl@0
   102
	}
sl@0
   103
sl@0
   104
TTrackGetStateBuf::~TTrackGetStateBuf()
sl@0
   105
	{
sl@0
   106
	if(iRequest)
sl@0
   107
		Kern::DestroyClientRequest(iRequest);
sl@0
   108
	}
sl@0
   109
	
sl@0
   110
/***************************************************************************************
sl@0
   111
	class DDeviceResManUs
sl@0
   112
 ***************************************************************************************/
sl@0
   113
DDeviceResManUs::DDeviceResManUs()
sl@0
   114
// Constructor
sl@0
   115
    {
sl@0
   116
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::DDeviceResManUs()"));
sl@0
   117
    iParseMask=KDeviceAllowAll&~KDeviceAllowUnit; // Allow info and pdd, but not units
sl@0
   118
    iUnitsMask=0;
sl@0
   119
    iVersion=TVersion(KResManUsMajorVersionNumber,
sl@0
   120
		      KResManUsMinorVersionNumber,
sl@0
   121
		      KResManUsBuildVersionNumber);
sl@0
   122
    }
sl@0
   123
sl@0
   124
DDeviceResManUs::~DDeviceResManUs()
sl@0
   125
// Destructor
sl@0
   126
    {
sl@0
   127
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::~DDeviceResManUs()"));
sl@0
   128
#ifdef RESOURCE_MANAGER_SIMULATED_PSL
sl@0
   129
	iSharedDfcQue->Destroy();
sl@0
   130
#else
sl@0
   131
	delete iSharedDfcQue;
sl@0
   132
#endif
sl@0
   133
	}
sl@0
   134
sl@0
   135
TInt DDeviceResManUs::Install()
sl@0
   136
// Install the device driver.
sl@0
   137
    {
sl@0
   138
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::Install()"));
sl@0
   139
	// Create the message queue and initialise the DFC queue pointer
sl@0
   140
#ifndef RESOURCE_MANAGER_SIMULATED_PSL
sl@0
   141
	TInt r=Kern::DfcQInit(iSharedDfcQue,KResManUsThreadPriority,&KResManUsThreadName);
sl@0
   142
#else
sl@0
   143
	TInt r = Kern::DynamicDfcQCreate(iSharedDfcQue,KResManUsThreadPriority,KResManUsThreadName);
sl@0
   144
#endif
sl@0
   145
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DfcQCreate r  = %d", r));
sl@0
   146
	if(r!=KErrNone)
sl@0
   147
		return r;
sl@0
   148
sl@0
   149
#ifdef CPU_AFFINITY_ANY
sl@0
   150
        NKern::ThreadSetCpuAffinity((NThread*)(iSharedDfcQue->iThread), KCpuAffinityAny);
sl@0
   151
#endif
sl@0
   152
	r = SetName(&KLddRootName);
sl@0
   153
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> SetName, r  = %d", r));
sl@0
   154
	return r;
sl@0
   155
    }
sl@0
   156
sl@0
   157
sl@0
   158
void DDeviceResManUs::GetCaps(TDes8& aDes) const
sl@0
   159
// Return the ResManUs capabilities.
sl@0
   160
    {
sl@0
   161
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::GetCaps(TDes8& aDes) const"));
sl@0
   162
    TPckgBuf<TCapsDevResManUs> b;
sl@0
   163
    b().version=TVersion(KResManUsMajorVersionNumber,
sl@0
   164
			 KResManUsMinorVersionNumber,
sl@0
   165
			 KResManUsBuildVersionNumber);
sl@0
   166
    Kern::InfoCopy(aDes,b);
sl@0
   167
    }
sl@0
   168
sl@0
   169
sl@0
   170
TInt DDeviceResManUs::Create(DLogicalChannelBase*& aChannel)
sl@0
   171
// Create a channel on the device.
sl@0
   172
    {
sl@0
   173
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceResManUs::Create(DLogicalChannelBase*& aChannel)"));
sl@0
   174
	if(iOpenChannels>=KMaxNumChannels)
sl@0
   175
		return KErrOverflow;
sl@0
   176
    aChannel=new DChannelResManUs;
sl@0
   177
    return aChannel?KErrNone:KErrNoMemory;
sl@0
   178
    }
sl@0
   179
sl@0
   180
sl@0
   181
/***************************************************************************************
sl@0
   182
	class DChannelResManUs
sl@0
   183
 ***************************************************************************************/
sl@0
   184
DChannelResManUs::DChannelResManUs() 
sl@0
   185
// Constructor
sl@0
   186
    {
sl@0
   187
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DChannelResManUs()"));
sl@0
   188
    iClient=&Kern::CurrentThread();
sl@0
   189
	// Increase the DThread's ref count so that it does not close without us
sl@0
   190
	iClient->Open();
sl@0
   191
    }
sl@0
   192
sl@0
   193
sl@0
   194
DChannelResManUs::~DChannelResManUs()
sl@0
   195
// Destructor
sl@0
   196
    {
sl@0
   197
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::~DChannelResManUs()"));
sl@0
   198
sl@0
   199
	// Cancel any outstanding requests
sl@0
   200
	//
sl@0
   201
	// For each tracker (Get, Set and notify)
sl@0
   202
	// 
sl@0
   203
	if(iGetStateTracker != NULL)
sl@0
   204
		{
sl@0
   205
		CancelTrackerRequests(iGetStateTracker,EFalse,0,NULL); // EFalse,0, to ignore resource IDs
sl@0
   206
		RemoveTrackingControl(iGetStateTracker);
sl@0
   207
		}
sl@0
   208
	if(iSetStateTracker != NULL)
sl@0
   209
		{
sl@0
   210
		CancelTrackerRequests(iSetStateTracker,EFalse,0,NULL); // EFalse,0, to ignore resource IDs
sl@0
   211
		RemoveTrackingControl(iSetStateTracker);
sl@0
   212
		}
sl@0
   213
	if(iListenableTracker != NULL)
sl@0
   214
		{
sl@0
   215
		CancelTrackerRequests(iListenableTracker,EFalse,0,NULL); // EFalse,0, to ignore resource IDs
sl@0
   216
		RemoveTrackingControl(iListenableTracker);
sl@0
   217
		}
sl@0
   218
sl@0
   219
	delete iUserNameUsed;
sl@0
   220
	delete iResourceDependencyIds;
sl@0
   221
	delete iClientNamesResCtrl;
sl@0
   222
	delete iResourceInfoResCtrl;
sl@0
   223
sl@0
   224
	// decrement the DThread's reference count
sl@0
   225
	Kern::SafeClose((DObject*&)iClient, NULL);
sl@0
   226
    }
sl@0
   227
sl@0
   228
sl@0
   229
static void AsyncCallBackFn(TUint aClient, TUint aResourceId, TInt aLevel, TInt aLevelOwnerId, TInt aResult, TAny* aTrackingBuffer)
sl@0
   230
	{
sl@0
   231
// Callback function for asynchronous requests
sl@0
   232
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> AsyncCallBackFn aClient=0x%x aResourceId=0x%x, aLevel=0x%x, aResult=0x%x, aTrackingBuffer=0x%x\n",aClient, aResourceId, aLevel, aResult, aTrackingBuffer));
sl@0
   233
	TTrackingBuffer* buffer = ((TTrackingBuffer*)aTrackingBuffer);
sl@0
   234
	TTrackingControl* tracker = buffer->GetTrackingControl();
sl@0
   235
	__ASSERT_ALWAYS((tracker!=NULL),RESMANUS_FAULT());
sl@0
   236
	DChannelResManUs* channel = tracker->iOwningChannel;
sl@0
   237
sl@0
   238
#ifdef PRM_US_INSTRUMENTATION_MACRO
sl@0
   239
	if(tracker->iType==EGetState)
sl@0
   240
		{
sl@0
   241
		PRM_US_GET_RESOURCE_STATE_END_TRACE;
sl@0
   242
		}
sl@0
   243
	else if(tracker->iType==ESetState)
sl@0
   244
		{
sl@0
   245
		PRM_US_SET_RESOURCE_STATE_END_TRACE;
sl@0
   246
		}
sl@0
   247
#endif
sl@0
   248
	if(tracker->iType == EGetState)
sl@0
   249
		{
sl@0
   250
		TTrackGetStateBuf* stateBuf = (TTrackGetStateBuf*)aTrackingBuffer;
sl@0
   251
		if(aResult==KErrNone)
sl@0
   252
			{
sl@0
   253
			// Write the state value to the user-supplied variable
sl@0
   254
			stateBuf->iRequest->Data1() = aLevel;
sl@0
   255
			stateBuf->iRequest->Data2() = aLevelOwnerId;
sl@0
   256
			}
sl@0
   257
		Kern::QueueRequestComplete(channel->iClient, ((TTrackGetStateBuf*)buffer)->iRequest, aResult);
sl@0
   258
		}
sl@0
   259
	else if(tracker->iType == ESetState)
sl@0
   260
		{
sl@0
   261
		Kern::QueueRequestComplete(channel->iClient, ((TTrackSetStateBuf*)buffer)->iRequest, aResult);
sl@0
   262
		}
sl@0
   263
	// Once notified of a change in a resource state, must cancel the notification
sl@0
   264
	// request in the Resource Controller to give the client the appearance of a 
sl@0
   265
	// 'one'shot' type of operation.
sl@0
   266
	else if(tracker->iType==ENotify)
sl@0
   267
		{
sl@0
   268
#ifdef PRM_ENABLE_EXTENDED_VERSION
sl@0
   269
		if(((TInt)aClient==KDynamicResourceDeRegistering)&&(aResourceId&KIdMaskDynamic))  
sl@0
   270
			{
sl@0
   271
			// Resource has de-registered from Resource Controller, so can't expect any more notifications
sl@0
   272
			// of this type. Cancellation of notifications (i.e. invoke Resource Controller) and transfer of
sl@0
   273
			// buffers to free queue (for both conditional and unconditional notifications) is already done.
sl@0
   274
			// To distinguish removal of a dynamic resource, hijack aResult (the value used when completing
sl@0
   275
			// the user-side TRequestStatus object) and set it to KErrDisconnected.
sl@0
   276
			aResult = KErrDisconnected;
sl@0
   277
			}
sl@0
   278
sl@0
   279
#endif
sl@0
   280
		TInt r = (channel->iPddPtr)->CancelNotification(channel->ClientHandle(),aResourceId,
sl@0
   281
										((TTrackNotifyBuf*)buffer)->iNotifyBlock);
sl@0
   282
		__ASSERT_ALWAYS((r == KErrCancel),RESMANUS_FAULT());
sl@0
   283
		Kern::QueueRequestComplete(channel->iClient, ((TTrackNotifyBuf*)buffer)->iRequest, aResult);
sl@0
   284
		}
sl@0
   285
sl@0
   286
	// Return the tracking buffer to the free queue
sl@0
   287
	channel->FreeTrackingBuffer(buffer);
sl@0
   288
	}
sl@0
   289
sl@0
   290
TInt DChannelResManUs::GetValidName(const TDesC8* aInfo)
sl@0
   291
	{
sl@0
   292
// Extract a usable name from that supplied by the client
sl@0
   293
	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::GetValidName"));
sl@0
   294
	TInt err=KErrNone;
sl@0
   295
	if(aInfo)
sl@0
   296
		{
sl@0
   297
		DThread* thread = &Kern::CurrentThread();
sl@0
   298
		TInt nameLen = Kern::ThreadGetDesLength(thread, aInfo);
sl@0
   299
		if(nameLen<0)
sl@0
   300
			return nameLen; // return error code
sl@0
   301
		iNameProvidedLength = nameLen;
sl@0
   302
		if(nameLen > MAX_CLIENT_NAME_LENGTH)
sl@0
   303
			err=KErrBadName;
sl@0
   304
		else
sl@0
   305
			{
sl@0
   306
			nameLen = (nameLen<=MAX_NAME_LENGTH_IN_RESMAN) ? nameLen : MAX_NAME_LENGTH_IN_RESMAN;
sl@0
   307
			if((iUserNameUsed = HBuf8::New(nameLen))==NULL)
sl@0
   308
				return KErrNoMemory;
sl@0
   309
			err = Kern::ThreadDesRead(thread,aInfo,*iUserNameUsed,0);
sl@0
   310
			if(err!=KErrNone)
sl@0
   311
				return err;
sl@0
   312
			}
sl@0
   313
		}
sl@0
   314
	else
sl@0
   315
		err=KErrBadName;
sl@0
   316
	return err;
sl@0
   317
	}
sl@0
   318
sl@0
   319
TInt DChannelResManUs::RequestUserHandle(DThread* aThread, TOwnerType aType)
sl@0
   320
// Called when a user thread requests a handle to this channel
sl@0
   321
    {
sl@0
   322
    // Make sure that only our client can get a handle
sl@0
   323
	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::RequestUserHandle"));
sl@0
   324
    if (aType!=EOwnerThread || aThread!=iClient)
sl@0
   325
        return KErrAccessDenied;
sl@0
   326
    return KErrNone;
sl@0
   327
    }
sl@0
   328
sl@0
   329
void DChannelResManUs::RegistrationDfcFunc(TAny* aChannel)
sl@0
   330
	{
sl@0
   331
	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::RegistrationDfcFunc"));
sl@0
   332
	// DFC function invoked for registration with Resource Controller
sl@0
   333
	DChannelResManUs* channel = (DChannelResManUs*)aChannel;
sl@0
   334
	// RegisterProxyClient(TUint& aProxyId, const TDesC& aName);
sl@0
   335
	TUint uintVal=0;
sl@0
   336
	TInt r = KErrNone;
sl@0
   337
	__ASSERT_ALWAYS((r==KErrNone),RESMANUS_FAULT());
sl@0
   338
sl@0
   339
	r=(channel->iPddPtr)->RegisterProxyClient(uintVal,*((TDesC8*)(channel->iUserNameUsed)));
sl@0
   340
	if(r!=KErrNone)
sl@0
   341
		{
sl@0
   342
		// Registration failed
sl@0
   343
		// Ensure that the client-side flag is cleared in uintVal
sl@0
   344
		// so the failure can be detected in DoCreate
sl@0
   345
		uintVal &= ~USER_SIDE_CLIENT_BIT_MASK; // Copied from rescontrol_export
sl@0
   346
		}
sl@0
   347
	channel->SetClientHandle((TInt)uintVal);
sl@0
   348
	NKern::FSSignal(channel->iFastSem);
sl@0
   349
	}
sl@0
   350
sl@0
   351
sl@0
   352
TInt DChannelResManUs::RegisterWithResCtrlr()
sl@0
   353
	{
sl@0
   354
	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::RegisterWithResCtrlr"));
sl@0
   355
	TInt r = KErrNone;
sl@0
   356
	// Initialise the channel's fast semaphore
sl@0
   357
	iFastSem = new NFastSemaphore();
sl@0
   358
	if(iFastSem == NULL)
sl@0
   359
		r = KErrNoMemory;
sl@0
   360
	else
sl@0
   361
		{
sl@0
   362
		iFastSem->iOwningThread = (NThreadBase*)NKern::CurrentThread();
sl@0
   363
sl@0
   364
		// Attempt to perform registration with the Resource Controller on behalf of the client.
sl@0
   365
		SetDfcQ(((DDeviceResManUs*)(iDevice))->iSharedDfcQue);
sl@0
   366
		TDfc tempDfc(RegistrationDfcFunc, this, iDfcQ, KResManUsRegistrationPriority);
sl@0
   367
sl@0
   368
		// Block this thread until the DFC has executed
sl@0
   369
		tempDfc.Enque();
sl@0
   370
		NKern::FSWait(iFastSem);
sl@0
   371
		// Have finished with iFastSem
sl@0
   372
		delete iFastSem;
sl@0
   373
sl@0
   374
		// Registration complete - check success
sl@0
   375
		if(!(USER_SIDE_CLIENT_BIT_MASK & ClientHandle()))
sl@0
   376
			{
sl@0
   377
			// Registration failed
sl@0
   378
			r = KErrCouldNotConnect;	
sl@0
   379
			}
sl@0
   380
		// Start receiving messages ...
sl@0
   381
		iMsgQ.Receive();
sl@0
   382
		}
sl@0
   383
	return r;
sl@0
   384
	}
sl@0
   385
sl@0
   386
TInt DChannelResManUs::DoCreate(TInt /*aUnit*/,
sl@0
   387
                                const TDesC8* aInfo, 
sl@0
   388
                                const TVersion &aVer)
sl@0
   389
// Create the channel from the passed info.
sl@0
   390
    {
sl@0
   391
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer)"));
sl@0
   392
sl@0
   393
	TInt r = KErrNone;
sl@0
   394
	iPddPtr = ((DUserSideProxyInterface*)iPdd)->iController;
sl@0
   395
	// Check client has appropriate capabilities
sl@0
   396
	if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by DDevicePowerRsrc::Create")))
sl@0
   397
		return KErrPermissionDenied;
sl@0
   398
sl@0
   399
	// Check software version
sl@0
   400
	if (!Kern::QueryVersionSupported(TVersion(KResManUsMajorVersionNumber,
sl@0
   401
			 KResManUsMinorVersionNumber,
sl@0
   402
			 KResManUsBuildVersionNumber),
sl@0
   403
				     aVer))
sl@0
   404
		return KErrNotSupported;
sl@0
   405
sl@0
   406
	// Implementation note: if this method fails, the destructor will be invoked
sl@0
   407
	// as part of which all successfully-allocated memory will be freed. Therefore,
sl@0
   408
	// no memory will be explicitly freed in the event of failure in the code which follows.
sl@0
   409
	
sl@0
   410
	// Allocate the arrays used for acquiring client, resource and dependency information
sl@0
   411
	if((iClientNamesResCtrl = HBuf8::New(KNumClientNamesResCtrl * sizeof(TPowerClientInfoV01)))==NULL)
sl@0
   412
		return KErrNoMemory;
sl@0
   413
	if((iResourceInfoResCtrl = HBuf8::New(KNumResourceInfoResCtrl * sizeof(TPowerResourceInfoV01)))==NULL)
sl@0
   414
		return KErrNoMemory;
sl@0
   415
	if((iResourceDependencyIds = HBuf8::New(KNumResourceDependencies * sizeof(SResourceDependencyInfo)))==NULL)
sl@0
   416
		return KErrNoMemory;
sl@0
   417
	// Obtain the channel name to use
sl@0
   418
	if((r=GetValidName(aInfo))!=KErrNone)
sl@0
   419
		return r;
sl@0
   420
#ifdef PRM_ENABLE_EXTENDED_VERSION
sl@0
   421
	iResDepsValid = 0;
sl@0
   422
#endif
sl@0
   423
sl@0
   424
#ifdef PRM_US_INSTRUMENTATION_MACRO
sl@0
   425
	PRM_US_OPEN_CHANNEL_START_TRACE;	 
sl@0
   426
#endif
sl@0
   427
sl@0
   428
	// Set up the request tracking support
sl@0
   429
	iGetStateTracker = new TTrackingControl();
sl@0
   430
	iSetStateTracker = new TTrackingControl();;
sl@0
   431
	iListenableTracker = new TTrackingControl();
sl@0
   432
	if((iGetStateTracker==NULL) || (iSetStateTracker==NULL) || (iListenableTracker==NULL))
sl@0
   433
		return KErrNoMemory;
sl@0
   434
sl@0
   435
	// Register with the Resource Controller
sl@0
   436
	r = RegisterWithResCtrlr();
sl@0
   437
sl@0
   438
#ifdef PRM_US_INSTRUMENTATION_MACRO
sl@0
   439
	PRM_US_OPEN_CHANNEL_END_TRACE;
sl@0
   440
#endif
sl@0
   441
sl@0
   442
    return r;
sl@0
   443
    }
sl@0
   444
sl@0
   445
//Override sendMsg to allow data copy in the context of client thread for WDP.
sl@0
   446
TInt DChannelResManUs::SendMsg(TMessageBase* aMsg)
sl@0
   447
	{
sl@0
   448
	TThreadMessage& m = *(TThreadMessage*)aMsg;
sl@0
   449
	TInt id = m.iValue;
sl@0
   450
	TInt r = KErrNone;
sl@0
   451
	if (id != (TInt)ECloseMsg && id != KMaxTInt)
sl@0
   452
		{
sl@0
   453
		if (id<0)
sl@0
   454
			{
sl@0
   455
			TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
sl@0
   456
			r = SendRequest(aMsg);
sl@0
   457
			if (r != KErrNone)
sl@0
   458
				Kern::RequestComplete(pS,r);
sl@0
   459
			}
sl@0
   460
		else
sl@0
   461
			r = SendControl(aMsg);
sl@0
   462
		}
sl@0
   463
	else
sl@0
   464
		r = DLogicalChannel::SendMsg(aMsg);
sl@0
   465
	return r;
sl@0
   466
	}
sl@0
   467
sl@0
   468
TInt DChannelResManUs::SendRequest(TMessageBase* aMsg)
sl@0
   469
	{
sl@0
   470
	TThreadMessage& m = *(TThreadMessage*)aMsg;
sl@0
   471
	TInt id = ~m.iValue;
sl@0
   472
	TRequestStatus* pS = (TRequestStatus*)m.Ptr0();
sl@0
   473
	TInt r = KErrNone;
sl@0
   474
	TTrackingBuffer *trackBuf = NULL;
sl@0
   475
	TUint parms[4];
sl@0
   476
	TPowerResourceCb *callBack;
sl@0
   477
	DPowerResourceNotification *prn;
sl@0
   478
sl@0
   479
	switch(id)
sl@0
   480
		{
sl@0
   481
		case RBusDevResManUs::EChangeResourceState:
sl@0
   482
			{
sl@0
   483
			__ASSERT_ALWAYS(m.Ptr2() != NULL, RESMANUS_FAULT());
sl@0
   484
#ifdef _DUMP_TRACKERS
sl@0
   485
			if((r=DumpTracker(iSetStateTracker))!=KErrNone)
sl@0
   486
				break;
sl@0
   487
#endif
sl@0
   488
			r = GetAndInitTrackingBuffer(iSetStateTracker, trackBuf, (TUint)m.Ptr1(), pS);
sl@0
   489
			if( r != KErrNone)
sl@0
   490
				return r;
sl@0
   491
			callBack = &(((TTrackSetStateBuf*)trackBuf)->iCtrlBlock);
sl@0
   492
			new (callBack) TPowerResourceCb(&AsyncCallBackFn, (TAny*)trackBuf, iDfcQ, KResManCallBackPriority);
sl@0
   493
			parms[0] = (TUint)m.Ptr2();
sl@0
   494
			parms[1] = (TUint)callBack;
sl@0
   495
			m.iArg[2] = &(parms[0]);
sl@0
   496
			break;
sl@0
   497
			}
sl@0
   498
		case RBusDevResManUs::EGetResourceState:
sl@0
   499
			{
sl@0
   500
			__ASSERT_ALWAYS(m.Ptr2() != NULL, RESMANUS_FAULT());
sl@0
   501
			umemget32(&(parms[0]), m.Ptr2(), 3*sizeof(TInt));
sl@0
   502
#ifdef _DUMP_TRACKERS
sl@0
   503
			if((r=DumpTracker(iGetStateTracker))!=KErrNone)
sl@0
   504
				break;
sl@0
   505
#endif
sl@0
   506
			r = GetStateBuffer(iGetStateTracker, trackBuf, (TUint)m.Ptr1(), (TInt*)parms[1], (TInt*)parms[2], callBack, pS);
sl@0
   507
			if(r != KErrNone)
sl@0
   508
				return r;
sl@0
   509
			parms[3] = (TUint)callBack;
sl@0
   510
			m.iArg[2] = &(parms[0]);
sl@0
   511
			break;
sl@0
   512
			}
sl@0
   513
		case RBusDevResManUs::ERequestChangeNotification:
sl@0
   514
			{
sl@0
   515
			__ASSERT_ALWAYS(m.Ptr1() != NULL, RESMANUS_FAULT());
sl@0
   516
			r = GetAndInitTrackingBuffer(iListenableTracker, trackBuf, (TUint)m.Ptr1(), pS);
sl@0
   517
			if(r != KErrNone)
sl@0
   518
				return r;
sl@0
   519
			prn = &(((TTrackNotifyBuf*)trackBuf)->iNotifyBlock);
sl@0
   520
			new (prn) DPowerResourceNotification(&AsyncCallBackFn, (TAny*)trackBuf, iDfcQ, KResManCallBackPriority);
sl@0
   521
			m.iArg[2] = (TAny*)prn;
sl@0
   522
			break;
sl@0
   523
			}
sl@0
   524
		case RBusDevResManUs::ERequestQualifiedChangeNotification:
sl@0
   525
			{
sl@0
   526
			__ASSERT_ALWAYS(m.Ptr1() != NULL, RESMANUS_FAULT());
sl@0
   527
			__ASSERT_ALWAYS(m.Ptr2() != NULL, RESMANUS_FAULT());
sl@0
   528
			umemget32(&(parms[0]), m.Ptr2(), 2*sizeof(TUint));
sl@0
   529
			m.iArg[2] = &parms[0];
sl@0
   530
			r = GetAndInitTrackingBuffer(iListenableTracker, trackBuf, (TUint)parms[0], pS);
sl@0
   531
			if(r != KErrNone)
sl@0
   532
				return r;
sl@0
   533
			prn = &(((TTrackNotifyBuf*)trackBuf)->iNotifyBlock);
sl@0
   534
			new (prn) DPowerResourceNotification(&AsyncCallBackFn, (TAny*)trackBuf, iDfcQ, KResManCallBackPriority);
sl@0
   535
			parms[2] = (TUint)prn;
sl@0
   536
			break;
sl@0
   537
			}
sl@0
   538
		default:
sl@0
   539
			{
sl@0
   540
			return KErrNotSupported;
sl@0
   541
			}
sl@0
   542
		}
sl@0
   543
sl@0
   544
	if(r == KErrNone)
sl@0
   545
		r = DLogicalChannel::SendMsg(aMsg);
sl@0
   546
	if(r != KErrNone)
sl@0
   547
		FreeTrackingBuffer(trackBuf);
sl@0
   548
	return r;
sl@0
   549
	}
sl@0
   550
sl@0
   551
sl@0
   552
TInt DChannelResManUs::SendControl(TMessageBase* aMsg)
sl@0
   553
	{
sl@0
   554
	TThreadMessage& m = *(TThreadMessage*)aMsg;
sl@0
   555
	TInt id = m.iValue;
sl@0
   556
	TInt param1 = 0;
sl@0
   557
	TUint parms[4];
sl@0
   558
	TAny* a1 = m.Ptr0();
sl@0
   559
	TAny* a2 = m.Ptr1();
sl@0
   560
	TAny* ptr1 = NULL;
sl@0
   561
	switch(id)
sl@0
   562
		{
sl@0
   563
		case RBusDevResManUs::EInitialise:
sl@0
   564
			{
sl@0
   565
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
sl@0
   566
			TUint8 stateRes[3];
sl@0
   567
			umemget(&(stateRes[0]), a1, 3*sizeof(TUint8));
sl@0
   568
			m.iArg[0] = &(stateRes[0]);
sl@0
   569
			break;
sl@0
   570
			}
sl@0
   571
		case RBusDevResManUs::EGetNoOfResources:
sl@0
   572
		case RBusDevResManUs::EGetResourceControllerVersion:
sl@0
   573
			{
sl@0
   574
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
sl@0
   575
			m.iArg[0] = &param1;
sl@0
   576
			break;
sl@0
   577
			}
sl@0
   578
		case RBusDevResManUs::EGetNoOfClients:
sl@0
   579
		case RBusDevResManUs::EGetNumClientsUsingResource:
sl@0
   580
			{
sl@0
   581
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
sl@0
   582
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
sl@0
   583
			umemget32(&(parms[0]), a2, 3*sizeof(TUint));
sl@0
   584
			m.iArg[1]  = &(parms[0]);
sl@0
   585
			m.iArg[0] = &param1;
sl@0
   586
			break;
sl@0
   587
			}
sl@0
   588
		case RBusDevResManUs::EGetNumResourcesInUseByClient:
sl@0
   589
			{
sl@0
   590
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
sl@0
   591
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
sl@0
   592
			TBuf8 <MAX_NAME_LENGTH_IN_RESMAN> clientName;
sl@0
   593
			Kern::KUDesGet(clientName, *(TDesC8*)m.Ptr0());
sl@0
   594
			m.iArg[0] = (TAny*)&clientName;
sl@0
   595
			umemget32(&(parms[0]), m.Ptr1(), 2*sizeof(TUint));
sl@0
   596
			param1 = parms[1];
sl@0
   597
			m.iArg[1] = &param1;
sl@0
   598
			break;
sl@0
   599
			}
sl@0
   600
		case RBusDevResManUs::EGetResourceIdByName:
sl@0
   601
			{
sl@0
   602
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
sl@0
   603
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
sl@0
   604
			TBuf8 <MAX_NAME_LENGTH_IN_RESMAN> resourceName;
sl@0
   605
			Kern::KUDesGet(resourceName, *(TDesC8*)m.Ptr0());
sl@0
   606
			m.iArg[0] = (TAny*)&resourceName;
sl@0
   607
			m.iArg[1] = &param1;
sl@0
   608
			break;
sl@0
   609
			}
sl@0
   610
#ifdef RESOURCE_MANAGER_SIMULATED_PSL
sl@0
   611
		case RBusDevResManUs::EGetNumCandidateAsyncResources:
sl@0
   612
		case RBusDevResManUs::EGetNumCandidateSharedResources:
sl@0
   613
			{
sl@0
   614
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
sl@0
   615
			m.iArg[0] = &param1;
sl@0
   616
			break;
sl@0
   617
			}
sl@0
   618
		case RBusDevResManUs::EGetCandidateAsyncResourceId:
sl@0
   619
		case RBusDevResManUs::EGetCandidateSharedResourceId:
sl@0
   620
			{
sl@0
   621
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
sl@0
   622
			m.iArg[1] = &param1;
sl@0
   623
			break;
sl@0
   624
			}
sl@0
   625
#endif
sl@0
   626
		case RBusDevResManUs::EGetNumDependentsForResource:
sl@0
   627
			{
sl@0
   628
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
sl@0
   629
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
sl@0
   630
			umemget32(&(parms[0]), m.Ptr1(), 2*sizeof(TUint));
sl@0
   631
			m.iArg[1] = &(parms[0]);
sl@0
   632
			m.iArg[0] = &param1;
sl@0
   633
			break;
sl@0
   634
			}
sl@0
   635
		case RBusDevResManUs::EGetDependentsIdForResource:
sl@0
   636
			{
sl@0
   637
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
sl@0
   638
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
sl@0
   639
			umemget32(&(parms[0]), m.Ptr1(), 3*sizeof(TUint));
sl@0
   640
			TInt len, maxLen;
sl@0
   641
			ptr1 = (TAny*)parms[1];
sl@0
   642
			Kern::KUDesInfo(*(const TDesC8*)parms[1], len, maxLen);
sl@0
   643
			umemget32(&param1, m.Ptr0(), sizeof(TUint));
sl@0
   644
			if((maxLen - len) < (TInt)(param1 * sizeof(SResourceDependencyInfo)))
sl@0
   645
				{
sl@0
   646
				return KErrArgument;
sl@0
   647
				}
sl@0
   648
			m.iArg[0] = &param1;
sl@0
   649
			m.iArg[1] = &(parms[0]);
sl@0
   650
			break;
sl@0
   651
			}
sl@0
   652
		case RBusDevResManUs::EGetResourceInfo:
sl@0
   653
			{
sl@0
   654
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
sl@0
   655
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
sl@0
   656
			TResourceInfoBuf buf;
sl@0
   657
			m.iArg[1] = &buf;
sl@0
   658
			break;
sl@0
   659
			}
sl@0
   660
		case RBusDevResManUs::EGetAllResourcesInfo:
sl@0
   661
			{
sl@0
   662
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
sl@0
   663
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
sl@0
   664
			umemget32(&(parms[0]), m.Ptr1(), 2*sizeof(TUint));
sl@0
   665
			ptr1 = (TAny*)parms[0];
sl@0
   666
			umemget32(&param1, (TAny*)parms[0], sizeof(TUint));
sl@0
   667
			parms[0]  =(TUint)&param1;
sl@0
   668
			RSimplePointerArray<TResourceInfoBuf> infoPtrs;
sl@0
   669
			umemget(&infoPtrs, m.Ptr0(), sizeof(RSimplePointerArray<TResourceInfoBuf>));
sl@0
   670
			if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
sl@0
   671
				return KErrArgument;
sl@0
   672
			m.iArg[1] = &(parms[0]);
sl@0
   673
			break;
sl@0
   674
			}
sl@0
   675
		case RBusDevResManUs::EGetInfoOnClientsUsingResource:
sl@0
   676
			{
sl@0
   677
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
sl@0
   678
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
sl@0
   679
			umemget32(&parms[0], m.Ptr1(), 4*sizeof(TUint));
sl@0
   680
			ptr1 = (TAny*)parms[0];
sl@0
   681
			umemget32(&param1, (TAny*)parms[0], sizeof(TUint));
sl@0
   682
			parms[0] = (TUint)&param1;
sl@0
   683
			RSimplePointerArray<TClientInfoBuf>infoPtrs;
sl@0
   684
			umemget(&infoPtrs, m.Ptr0(), sizeof(RSimplePointerArray<TClientInfoBuf>));
sl@0
   685
			if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
sl@0
   686
				return KErrArgument;
sl@0
   687
			m.iArg[1] = &(parms[0]);
sl@0
   688
			break;
sl@0
   689
			}
sl@0
   690
		case RBusDevResManUs::EGetNamesAllClients:
sl@0
   691
			{
sl@0
   692
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
sl@0
   693
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
sl@0
   694
			umemget32(&parms[0], m.Ptr1(), 4*sizeof(TUint));
sl@0
   695
			ptr1 = (TAny*)parms[0];
sl@0
   696
			umemget32(&param1, (TAny*)parms[0], sizeof(TUint));
sl@0
   697
			parms[0] = (TUint)&param1;
sl@0
   698
			RSimplePointerArray<TClientName> infoPtrs;
sl@0
   699
			umemget(&infoPtrs, m.Ptr0(), sizeof(RSimplePointerArray<TClientName>));
sl@0
   700
			if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
sl@0
   701
				return KErrArgument;
sl@0
   702
			m.iArg[1] = &(parms[0]);
sl@0
   703
			break;
sl@0
   704
			}
sl@0
   705
		case RBusDevResManUs::EGetInfoOnResourcesInUseByClient:
sl@0
   706
			{
sl@0
   707
			__ASSERT_ALWAYS(a1 != NULL, RESMANUS_FAULT());
sl@0
   708
			__ASSERT_ALWAYS(a2 != NULL, RESMANUS_FAULT());
sl@0
   709
			TBuf8 <MAX_NAME_LENGTH_IN_RESMAN> clientName;
sl@0
   710
			Kern::KUDesGet(clientName, *(TDesC8*)m.Ptr0());
sl@0
   711
			m.iArg[0] = (TAny*)&clientName;
sl@0
   712
			umemget32(&parms[0], m.Ptr1(), 3*sizeof(TUint));
sl@0
   713
			ptr1 = (TAny*)parms[0];
sl@0
   714
			umemget32(&param1, (TAny*)parms[0], sizeof(TUint));
sl@0
   715
			parms[0] = (TUint)&param1;
sl@0
   716
			RSimplePointerArray<TResourceInfoBuf> infoPtrs;
sl@0
   717
			umemget(&infoPtrs, (TAny*)parms[1], sizeof(RSimplePointerArray<TResourceInfoBuf>));
sl@0
   718
			if((infoPtrs.Count() < 0) || (infoPtrs.Count() < param1))
sl@0
   719
				return KErrArgument;
sl@0
   720
			m.iArg[1] = &(parms[0]);
sl@0
   721
			break;
sl@0
   722
			}
sl@0
   723
		}
sl@0
   724
sl@0
   725
	TInt r = DLogicalChannel::SendMsg(aMsg);
sl@0
   726
	if(r != KErrNone)
sl@0
   727
		return r;
sl@0
   728
sl@0
   729
	switch(id)
sl@0
   730
		{
sl@0
   731
		case RBusDevResManUs::EGetNoOfResources:
sl@0
   732
		case RBusDevResManUs::EGetNoOfClients:
sl@0
   733
		case RBusDevResManUs::EGetNumClientsUsingResource:
sl@0
   734
		case RBusDevResManUs::EGetResourceControllerVersion:
sl@0
   735
		case RBusDevResManUs::EGetNumDependentsForResource:
sl@0
   736
			{
sl@0
   737
			umemput32(a1, (TAny*)&param1, sizeof(TUint));
sl@0
   738
			break;
sl@0
   739
			}
sl@0
   740
		case RBusDevResManUs::EGetNumResourcesInUseByClient:
sl@0
   741
			{
sl@0
   742
			umemput32((TAny*)parms[0], (TAny*)&param1, sizeof(TUint));
sl@0
   743
			break;
sl@0
   744
			}
sl@0
   745
		case RBusDevResManUs::EGetResourceIdByName:
sl@0
   746
			{
sl@0
   747
			umemput32(a2, (TAny*)&param1, sizeof(TUint));
sl@0
   748
			break;
sl@0
   749
			}
sl@0
   750
#ifdef RESOURCE_MANAGER_SIMULATED_PSL
sl@0
   751
		case RBusDevResManUs::EGetNumCandidateAsyncResources:
sl@0
   752
		case RBusDevResManUs::EGetNumCandidateSharedResources:
sl@0
   753
			{
sl@0
   754
			umemput32(a1, (TAny*)&param1, sizeof(TUint));
sl@0
   755
			break;
sl@0
   756
			}
sl@0
   757
		case RBusDevResManUs::EGetCandidateAsyncResourceId:
sl@0
   758
		case RBusDevResManUs::EGetCandidateSharedResourceId:
sl@0
   759
			{
sl@0
   760
			umemput32(a2, (TAny*)&param1, sizeof(TUint));
sl@0
   761
			break;
sl@0
   762
			}
sl@0
   763
#endif
sl@0
   764
		case RBusDevResManUs::EGetDependentsIdForResource:
sl@0
   765
			{
sl@0
   766
			r = Kern::ThreadDesWrite(iClient,(TAny*)ptr1, (const TDesC8&)*(SResourceDependencyInfo*)parms[1], 0);
sl@0
   767
			if(r == KErrOverflow) //This is done to retain the error as per API spec
sl@0
   768
				r = KErrArgument;
sl@0
   769
			break;
sl@0
   770
			}
sl@0
   771
		case RBusDevResManUs::EGetResourceInfo:
sl@0
   772
			{
sl@0
   773
			Kern::KUDesPut(*(TDes8*)a2, (const TDesC8&)*(TResourceInfoBuf*)m.Ptr1());
sl@0
   774
			break;
sl@0
   775
			}
sl@0
   776
		case RBusDevResManUs::EGetAllResourcesInfo:
sl@0
   777
			{
sl@0
   778
			TUint numToCopy;
sl@0
   779
			RSimplePointerArray<TResourceInfoBuf> infoPtrs;
sl@0
   780
			umemget(&infoPtrs, a1, sizeof(RSimplePointerArray<TResourceInfoBuf>));
sl@0
   781
			numToCopy = (infoPtrs.Count() < param1) ? infoPtrs.Count() : param1;
sl@0
   782
			umemput32(ptr1, (TAny*)&param1, sizeof(TUint));
sl@0
   783
			TResourceInfoBuf** entriesAddr = infoPtrs.Entries();
sl@0
   784
			TInt* entryPtr = (TInt*)entriesAddr;
sl@0
   785
			TPowerResourceInfoV01 *currRes = (TPowerResourceInfoV01*)iResourceInfoResCtrl->Ptr();
sl@0
   786
			TResourceInfoBuf* clientAddr;
sl@0
   787
			TResourceInfoBuf tempInfo;
sl@0
   788
			for(TUint index = 0; index < numToCopy; index++)
sl@0
   789
				{
sl@0
   790
				umemget32(&clientAddr, entryPtr, sizeof(TResourceInfoBuf*));
sl@0
   791
				entryPtr++;
sl@0
   792
				r = ExtractResourceInfo(currRes, tempInfo);
sl@0
   793
				if(r != KErrNone)
sl@0
   794
					return r;
sl@0
   795
				umemput((TAny*)clientAddr, (TAny*)&(tempInfo), tempInfo.Length());
sl@0
   796
				currRes++;
sl@0
   797
				}
sl@0
   798
			break;
sl@0
   799
			}
sl@0
   800
		case RBusDevResManUs::EGetInfoOnClientsUsingResource:
sl@0
   801
			{
sl@0
   802
			TUint numToCopy;
sl@0
   803
			RSimplePointerArray<TClientInfoBuf> infoPtrs;
sl@0
   804
			umemget(&infoPtrs, a1, sizeof(RSimplePointerArray<TClientName>));
sl@0
   805
			numToCopy = infoPtrs.Count();
sl@0
   806
			TClientInfoBuf** entriesAddr = infoPtrs.Entries();
sl@0
   807
			TInt* entryPtr = (TInt*)entriesAddr;
sl@0
   808
			TPowerClientInfoV01* rcDataPtr = (TPowerClientInfoV01*)iClientNamesResCtrl->Ptr();
sl@0
   809
			TClientInfoBuf* clientAddr;
sl@0
   810
			TUint userSideClients = 0;
sl@0
   811
			TClientInfoBuf tempInfo;
sl@0
   812
			for(TInt index = 0; index < param1; index++)
sl@0
   813
				{
sl@0
   814
				if((!parms[1]) && !(rcDataPtr->iClientId & USER_SIDE_CLIENT_BIT_MASK))
sl@0
   815
					{
sl@0
   816
					rcDataPtr++;
sl@0
   817
					continue;
sl@0
   818
					}
sl@0
   819
				if(numToCopy == 0)
sl@0
   820
					{
sl@0
   821
					userSideClients++;
sl@0
   822
					continue;
sl@0
   823
					}
sl@0
   824
				umemget32(&clientAddr, entryPtr, sizeof(TClientName*));
sl@0
   825
				entryPtr++;
sl@0
   826
				tempInfo().iId = rcDataPtr->iClientId;
sl@0
   827
				tempInfo().iName = *rcDataPtr->iClientName;
sl@0
   828
				Kern::InfoCopy(*clientAddr, tempInfo);
sl@0
   829
				rcDataPtr++;
sl@0
   830
				numToCopy--;
sl@0
   831
				userSideClients++;
sl@0
   832
				}
sl@0
   833
			if(parms[1])
sl@0
   834
				umemput32(ptr1, (TAny*)&param1, sizeof(TUint));
sl@0
   835
			else
sl@0
   836
				umemput32(ptr1, (TAny*)&userSideClients, sizeof(TUint));
sl@0
   837
			break;
sl@0
   838
			}
sl@0
   839
		case RBusDevResManUs::EGetNamesAllClients:
sl@0
   840
			{
sl@0
   841
			TUint numToCopy;
sl@0
   842
			RSimplePointerArray<TClientName> infoPtrs;
sl@0
   843
			umemget(&infoPtrs, a1, sizeof(RSimplePointerArray<TClientName>));
sl@0
   844
			numToCopy = infoPtrs.Count();
sl@0
   845
			TClientName** entriesAddr = infoPtrs.Entries();
sl@0
   846
			TInt* entryPtr = (TInt*)entriesAddr;
sl@0
   847
			TPowerClientInfoV01* rcDataPtr = (TPowerClientInfoV01*)iClientNamesResCtrl->Ptr();
sl@0
   848
			TClientName* clientAddr;
sl@0
   849
			TUint userSideClients = 0;
sl@0
   850
			for(TInt index = 0; index < param1; index++)
sl@0
   851
				{
sl@0
   852
				if((!parms[1]) && !(rcDataPtr->iClientId & USER_SIDE_CLIENT_BIT_MASK))
sl@0
   853
					{
sl@0
   854
					rcDataPtr++;
sl@0
   855
					continue;
sl@0
   856
					}
sl@0
   857
				if(numToCopy == 0)
sl@0
   858
					{
sl@0
   859
					userSideClients++;
sl@0
   860
					continue;
sl@0
   861
					}
sl@0
   862
				umemget32(&clientAddr, entryPtr, sizeof(TClientName*));
sl@0
   863
				entryPtr++;
sl@0
   864
				Kern::KUDesPut(*((TDes8*)clientAddr), *(const TDesC8*)rcDataPtr->iClientName);
sl@0
   865
				rcDataPtr++;
sl@0
   866
				numToCopy--;
sl@0
   867
				userSideClients++;
sl@0
   868
				}
sl@0
   869
			if(parms[1])
sl@0
   870
				umemput32(ptr1, (TAny*)&param1, sizeof(TUint));
sl@0
   871
			else
sl@0
   872
				umemput32(ptr1, (TAny*)&userSideClients, sizeof(TUint));
sl@0
   873
			break;
sl@0
   874
			}
sl@0
   875
		case RBusDevResManUs::EGetInfoOnResourcesInUseByClient:
sl@0
   876
			{
sl@0
   877
			TUint numToCopy;
sl@0
   878
			RSimplePointerArray<TResourceInfoBuf> infoPtrs;
sl@0
   879
			umemget(&infoPtrs, (TAny*)parms[1], sizeof(RSimplePointerArray<TResourceInfoBuf>));
sl@0
   880
			numToCopy = (infoPtrs.Count() < param1) ? infoPtrs.Count() : param1;
sl@0
   881
			umemput32(ptr1, (TAny*)&param1, sizeof(TUint));
sl@0
   882
			TResourceInfoBuf** entriesAddr = infoPtrs.Entries();
sl@0
   883
			TInt* entryPtr = (TInt*)entriesAddr;
sl@0
   884
			TPowerResourceInfoV01* currRes = (TPowerResourceInfoV01*)iResourceInfoResCtrl->Ptr();
sl@0
   885
			TResourceInfoBuf* clientAddr;
sl@0
   886
			TResourceInfoBuf tempInfo;
sl@0
   887
			for(TUint index = 0; index < numToCopy; index++)
sl@0
   888
				{
sl@0
   889
				umemget32(&clientAddr, entryPtr, sizeof(TResourceInfoBuf*));
sl@0
   890
				entryPtr++;
sl@0
   891
				r = ExtractResourceInfo(currRes, tempInfo);
sl@0
   892
				if(r != KErrNone)
sl@0
   893
					return r;
sl@0
   894
				umemput((TAny*)clientAddr, (TAny*)&(tempInfo), tempInfo.Length());
sl@0
   895
				currRes++;
sl@0
   896
				}
sl@0
   897
			break;
sl@0
   898
			}
sl@0
   899
		}
sl@0
   900
	return r;
sl@0
   901
	}
sl@0
   902
sl@0
   903
void DChannelResManUs::HandleMsg(TMessageBase* aMsg)
sl@0
   904
    {
sl@0
   905
    TThreadMessage& m=*(TThreadMessage*)aMsg;
sl@0
   906
    TInt id=m.iValue;
sl@0
   907
    
sl@0
   908
    __KTRACE_OPT(KRESMANAGER, Kern::Printf(" >ldd: DChannelResManUs::HandleMsg(TMessageBase* aMsg) id=%d\n", id));
sl@0
   909
	
sl@0
   910
	if (id==(TInt)ECloseMsg)
sl@0
   911
		{
sl@0
   912
		// Deregister here to ensure the correct thread ID is read
sl@0
   913
		if(ClientHandle() != 0)
sl@0
   914
			{
sl@0
   915
			// Must de-register from Resource Controller before closing down
sl@0
   916
			// Not checking return value - still need to delete allocated buffers
sl@0
   917
#ifdef PRM_US_INSTRUMENTATION_MACRO
sl@0
   918
	PRM_US_DEREGISTER_CLIENT_START_TRACE;
sl@0
   919
#endif
sl@0
   920
			((DPowerResourceController*)iPddPtr)->DeregisterProxyClient(ClientHandle());
sl@0
   921
sl@0
   922
#ifdef PRM_US_INSTRUMENTATION_MACRO
sl@0
   923
	PRM_US_DEREGISTER_CLIENT_END_TRACE;
sl@0
   924
#endif
sl@0
   925
			SetClientHandle(0);
sl@0
   926
			}
sl@0
   927
	    iMsgQ.iMessage->Complete(KErrNone,EFalse);
sl@0
   928
		return;
sl@0
   929
		}
sl@0
   930
    else if (id==KMaxTInt)
sl@0
   931
		{
sl@0
   932
		// DoCancel
sl@0
   933
		DoCancel(m.Int0());
sl@0
   934
		m.Complete(KErrNone,ETrue);
sl@0
   935
		return;
sl@0
   936
		}
sl@0
   937
sl@0
   938
    if (id<0)
sl@0
   939
		{
sl@0
   940
		// DoRequest
sl@0
   941
		TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
sl@0
   942
		TInt r=DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
sl@0
   943
		m.Complete(r,ETrue);
sl@0
   944
		}
sl@0
   945
    else
sl@0
   946
		{
sl@0
   947
		// DoControl
sl@0
   948
		__KTRACE_OPT(KRESMANAGER, Kern::Printf(" >ldd: do control id=%d...\n", id));
sl@0
   949
		TInt r=DoControl(id,m.Ptr0(),m.Ptr1());
sl@0
   950
		m.Complete(r,ETrue);
sl@0
   951
		}
sl@0
   952
	}
sl@0
   953
sl@0
   954
TInt DChannelResManUs::CancelTrackerRequests(TTrackingControl* aTracker, TBool aSingleRsrc, TUint aResourceId, TRequestStatus* aStatus)
sl@0
   955
	{
sl@0
   956
	// Cancel all outstanding requests from this client for a specified operation on 
sl@0
   957
	// a specified resource
sl@0
   958
sl@0
   959
	// Loop all entries in the iBusyQue of requests to locate a match for the 
sl@0
   960
	// operation type and resource ID
sl@0
   961
	//
sl@0
   962
	// For each match, remove the buffer from the busy queue and return to the free queue
sl@0
   963
	// If the request is already being processed, and so the callback function will be called
sl@0
   964
	// later, then the callback will exit gracefully.
sl@0
   965
	//
sl@0
   966
    __KTRACE_OPT(KRESMANAGER, Kern::Printf(" > DChannelResManUs::CancelTrackerRequests"));
sl@0
   967
	TInt returnVal = KErrNone;
sl@0
   968
	TBool statusMatched=EFalse;
sl@0
   969
	TTrackingBuffer* firstLink = NULL;
sl@0
   970
	TTrackingBuffer* lastLink = NULL;
sl@0
   971
	TInt type = aTracker->iType;
sl@0
   972
sl@0
   973
#ifdef PRM_US_INSTRUMENTATION_MACRO
sl@0
   974
	if(type==EGetState)
sl@0
   975
		{
sl@0
   976
		PRM_US_CANCEL_GET_RESOURCE_STATE_START_TRACE;
sl@0
   977
		}
sl@0
   978
	else if(type==ESetState)
sl@0
   979
		{
sl@0
   980
		PRM_US_CANCEL_SET_RESOURCE_STATE_START_TRACE;
sl@0
   981
		}
sl@0
   982
#endif
sl@0
   983
sl@0
   984
	if(aTracker->iBusyQue != NULL)
sl@0
   985
		{
sl@0
   986
		firstLink = (TTrackingBuffer*)(aTracker->iBusyQue->iA.iNext);
sl@0
   987
		lastLink = (TTrackingBuffer*)(&(aTracker->iBusyQue->iA));
sl@0
   988
		}
sl@0
   989
	while(( firstLink!=lastLink )&&(!statusMatched))
sl@0
   990
		{
sl@0
   991
		TTrackingBuffer* buffer = firstLink;
sl@0
   992
		TUint resourceId = buffer->GetResourceId();
sl@0
   993
		if(aSingleRsrc)
sl@0
   994
			if(resourceId != aResourceId)	// Required resource?
sl@0
   995
				{
sl@0
   996
				firstLink=(TTrackingBuffer*)(firstLink->iNext);
sl@0
   997
				continue;
sl@0
   998
				}
sl@0
   999
		if(aStatus!=NULL)
sl@0
  1000
			{
sl@0
  1001
			TClientRequest *request;
sl@0
  1002
			GET_USER_REQUEST(request, buffer, type)
sl@0
  1003
			if(request->StatusPtr() == aStatus)
sl@0
  1004
				{
sl@0
  1005
				statusMatched = ETrue;
sl@0
  1006
				}
sl@0
  1007
			else
sl@0
  1008
				{
sl@0
  1009
				firstLink=(TTrackingBuffer*)(firstLink->iNext);
sl@0
  1010
				continue;
sl@0
  1011
				}
sl@0
  1012
			}
sl@0
  1013
		TInt r = KErrNone;
sl@0
  1014
		if(type==EGetState)
sl@0
  1015
			{
sl@0
  1016
			TTrackGetStateBuf* stateBuf = (TTrackGetStateBuf*)firstLink;
sl@0
  1017
			r=((DPowerResourceController*)iPddPtr)->CancelAsyncRequestCallBack(ClientHandle(),
sl@0
  1018
															resourceId, (stateBuf->iCtrlBlock));
sl@0
  1019
			}
sl@0
  1020
		else if(type==ESetState)
sl@0
  1021
			{
sl@0
  1022
			TTrackSetStateBuf* stateBuf = (TTrackSetStateBuf*)firstLink;
sl@0
  1023
			r = ((DPowerResourceController*)iPddPtr)->CancelAsyncRequestCallBack(ClientHandle(), 
sl@0
  1024
															resourceId, (stateBuf->iCtrlBlock));
sl@0
  1025
			}
sl@0
  1026
		else if(type==ENotify)
sl@0
  1027
			{
sl@0
  1028
			TTrackNotifyBuf* notifyBuf = (TTrackNotifyBuf*)firstLink;
sl@0
  1029
			r=((DPowerResourceController*)iPddPtr)->CancelNotification(ClientHandle(), resourceId,
sl@0
  1030
															notifyBuf->iNotifyBlock);
sl@0
  1031
			}
sl@0
  1032
sl@0
  1033
		// Process the accumulated return value
sl@0
  1034
		if((r==KErrCompletion)&&((returnVal==KErrNone)||(returnVal==KErrCancel)))
sl@0
  1035
			{
sl@0
  1036
			returnVal=KErrCompletion;	
sl@0
  1037
			}
sl@0
  1038
		else if((r==KErrInUse)&&
sl@0
  1039
			((returnVal==KErrNone)||(returnVal==KErrCompletion)||(returnVal==KErrCancel)))
sl@0
  1040
			{
sl@0
  1041
			returnVal=KErrInUse;
sl@0
  1042
			}
sl@0
  1043
		else if(r!=KErrCancel)
sl@0
  1044
			{
sl@0
  1045
			returnVal=r;
sl@0
  1046
			}
sl@0
  1047
sl@0
  1048
		// Return the tracking buffer to the free queue
sl@0
  1049
		TTrackingBuffer* tempLink = (TTrackingBuffer*)(firstLink->iNext);
sl@0
  1050
		FreeTrackingBuffer(firstLink);
sl@0
  1051
		firstLink = tempLink;
sl@0
  1052
sl@0
  1053
#ifdef PRM_US_INSTRUMENTATION_MACRO
sl@0
  1054
	if(type==EGetState)
sl@0
  1055
		{
sl@0
  1056
		PRM_US_CANCEL_GET_RESOURCE_STATE_END_TRACE;
sl@0
  1057
		}
sl@0
  1058
	else if(type==ESetState)
sl@0
  1059
		{
sl@0
  1060
		PRM_US_CANCEL_SET_RESOURCE_STATE_END_TRACE;
sl@0
  1061
		}
sl@0
  1062
#endif
sl@0
  1063
		// Complete the TRequestStatus object
sl@0
  1064
		if((r!=KErrCompletion)&&(r!=KErrInUse))
sl@0
  1065
			{
sl@0
  1066
			TClientRequest* request;
sl@0
  1067
			GET_USER_REQUEST(request, buffer, type)
sl@0
  1068
			Kern::QueueRequestComplete(iClient, request, r);
sl@0
  1069
			}
sl@0
  1070
sl@0
  1071
		} //  while
sl@0
  1072
	return returnVal;
sl@0
  1073
	}
sl@0
  1074
sl@0
  1075
sl@0
  1076
TTrackingControl* DChannelResManUs::MapRequestToTracker(TInt aRequestType)
sl@0
  1077
// Utility function to map identifiers for cancel commands to request types.
sl@0
  1078
	{
sl@0
  1079
	TTrackingControl *tracker=NULL;
sl@0
  1080
	switch(aRequestType)
sl@0
  1081
		{
sl@0
  1082
		case RBusDevResManUs::ECancelChangeResourceStateRequests:
sl@0
  1083
		case RBusDevResManUs::ECancelChangeResourceState:
sl@0
  1084
			{
sl@0
  1085
			tracker=iSetStateTracker;
sl@0
  1086
			break;
sl@0
  1087
			}
sl@0
  1088
		case RBusDevResManUs::ECancelGetResourceStateRequests:
sl@0
  1089
		case RBusDevResManUs::ECancelGetResourceState:
sl@0
  1090
			{
sl@0
  1091
			tracker=iGetStateTracker;
sl@0
  1092
			break;
sl@0
  1093
			}
sl@0
  1094
		case RBusDevResManUs::ECancelChangeNotificationRequests:
sl@0
  1095
		case RBusDevResManUs::ECancelRequestChangeNotification:
sl@0
  1096
			{
sl@0
  1097
			tracker=iListenableTracker;
sl@0
  1098
			break;
sl@0
  1099
			}
sl@0
  1100
		default:
sl@0
  1101
			{
sl@0
  1102
			__ASSERT_ALWAYS(0,RESMANUS_FAULT());
sl@0
  1103
			}
sl@0
  1104
		}
sl@0
  1105
	return tracker;
sl@0
  1106
	}
sl@0
  1107
sl@0
  1108
sl@0
  1109
TInt DChannelResManUs::CancelRequestsOfType(TInt aRequestType, TRequestStatus* aStatus)
sl@0
  1110
// Cancel a particular request. This may be qualified by the type of operation
sl@0
  1111
    {
sl@0
  1112
	__ASSERT_ALWAYS(((aRequestType==RBusDevResManUs::ECancelChangeResourceState)||
sl@0
  1113
					(aRequestType==RBusDevResManUs::ECancelGetResourceState)||
sl@0
  1114
					(aRequestType==RBusDevResManUs::ECancelRequestChangeNotification)||
sl@0
  1115
					(KMaxTInt)),
sl@0
  1116
					RESMANUS_FAULT());
sl@0
  1117
	// For the KMaxTInt case, the type of the request is not known and so all trackers
sl@0
  1118
	// must be considered before the request is found.
sl@0
  1119
	// For all other cases, only the relevant tracker is searched.
sl@0
  1120
	TInt r=KErrNone;
sl@0
  1121
	if(aRequestType!=KMaxTInt)
sl@0
  1122
		{
sl@0
  1123
		TTrackingControl*tracker=MapRequestToTracker(aRequestType);
sl@0
  1124
		r=CancelTrackerRequests(tracker, EFalse, 0, aStatus);
sl@0
  1125
		}
sl@0
  1126
	else
sl@0
  1127
		{
sl@0
  1128
		TTrackingControl* tracker[3] = {iGetStateTracker, iSetStateTracker, iListenableTracker};
sl@0
  1129
		TUint8 index=0;
sl@0
  1130
		while((index<3) && (r==KErrNone))
sl@0
  1131
			{
sl@0
  1132
			r=CancelTrackerRequests(tracker[index], EFalse, 0, aStatus);
sl@0
  1133
			++index;
sl@0
  1134
			}
sl@0
  1135
		}
sl@0
  1136
	if(r==KErrCancel) 
sl@0
  1137
		r=KErrNone;	// All cancellations were successful
sl@0
  1138
sl@0
  1139
	return r;
sl@0
  1140
	}
sl@0
  1141
sl@0
  1142
sl@0
  1143
void DChannelResManUs::DoCancel(TInt aMask)
sl@0
  1144
// Cancel an outstanding request.
sl@0
  1145
    {
sl@0
  1146
	TRequestStatus* status = (TRequestStatus*)aMask;
sl@0
  1147
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoCancel, TRequestStatus addr = 0x%x",(TInt)status));
sl@0
  1148
sl@0
  1149
	CancelRequestsOfType(KMaxTInt, status); // Ignore return value
sl@0
  1150
	return;
sl@0
  1151
	}
sl@0
  1152
sl@0
  1153
TInt DChannelResManUs::DoRequest(TInt aReqNo, TRequestStatus* /*aStatus*/, TAny* a1, TAny* a2)
sl@0
  1154
// Asynchronous requests.
sl@0
  1155
    {
sl@0
  1156
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)"));
sl@0
  1157
sl@0
  1158
    TInt r=KErrNone;
sl@0
  1159
    switch (aReqNo)
sl@0
  1160
		{
sl@0
  1161
		case RBusDevResManUs::EChangeResourceState:
sl@0
  1162
			{
sl@0
  1163
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case EChangeResourceState"));
sl@0
  1164
			// a1 specifies the identifier of the required resource
sl@0
  1165
			// a2 specifies the required state for the resource
sl@0
  1166
			//
sl@0
  1167
			TUint *param = (TUint*)a2;
sl@0
  1168
			TUint resourceId = (TUint)a1;
sl@0
  1169
			TInt newState = (TInt)param[0];
sl@0
  1170
sl@0
  1171
#ifdef PRM_US_INSTRUMENTATION_MACRO
sl@0
  1172
	PRM_US_SET_RESOURCE_STATE_START_TRACE;
sl@0
  1173
#endif
sl@0
  1174
				// Invoke the API
sl@0
  1175
				r=((DPowerResourceController*)iPddPtr)->ChangeResourceState(ClientHandle(),
sl@0
  1176
														resourceId, newState, (TPowerResourceCb*)param[1]);
sl@0
  1177
			break;
sl@0
  1178
			}
sl@0
  1179
sl@0
  1180
		case RBusDevResManUs::EGetResourceState:
sl@0
  1181
			{
sl@0
  1182
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case EGetResourceState"));
sl@0
  1183
			// a1 specifies the resource ID
sl@0
  1184
			// a2 specifies the container stating if a cached value is required, the address of the variable
sl@0
  1185
			// to be update with the state value and the address of the level owner ID
sl@0
  1186
			//
sl@0
  1187
			TUint resourceId = (TUint)a1;
sl@0
  1188
			TUint *parms = (TUint*)a2;
sl@0
  1189
			TBool cached = (TBool)(parms[0]);
sl@0
  1190
sl@0
  1191
#ifdef PRM_US_INSTRUMENTATION_MACRO
sl@0
  1192
	PRM_US_GET_RESOURCE_STATE_START_TRACE;
sl@0
  1193
#endif
sl@0
  1194
				// Always invoke the asynchronous version of the API
sl@0
  1195
				r=((DPowerResourceController*)iPddPtr)->GetResourceState(ClientHandle(),
sl@0
  1196
																		resourceId, cached, *((TPowerResourceCb*)parms[3]));
sl@0
  1197
			break;
sl@0
  1198
			}
sl@0
  1199
sl@0
  1200
sl@0
  1201
		case RBusDevResManUs::ERequestChangeNotification:
sl@0
  1202
			{
sl@0
  1203
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case ERequestChangeNotification"));
sl@0
  1204
			// a1 specifies the resource ID
sl@0
  1205
			r=((DPowerResourceController*)iPddPtr)->RequestNotification(ClientHandle(),
sl@0
  1206
														(TUint)a1, *((DPowerResourceNotification*)a2));
sl@0
  1207
			break;
sl@0
  1208
			}
sl@0
  1209
sl@0
  1210
		case RBusDevResManUs::ERequestQualifiedChangeNotification:
sl@0
  1211
			{
sl@0
  1212
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoRequest case ERequestQualifiedChangeNotification"));
sl@0
  1213
			// a1 specifies the threshold value that the state is to change by
sl@0
  1214
			// a2 specifies the address of the container holding the resourceID and the required direction
sl@0
  1215
			TInt threshold = (TInt)a1;
sl@0
  1216
			TUint *parms = (TUint*)a2;
sl@0
  1217
			TUint resourceId = parms[0];
sl@0
  1218
			TBool direction = (TBool)(parms[1]);			
sl@0
  1219
			r=((DPowerResourceController*)iPddPtr)->RequestNotification(ClientHandle(),
sl@0
  1220
														resourceId, *((DPowerResourceNotification*)parms[2]), threshold, direction);
sl@0
  1221
			break;
sl@0
  1222
			}
sl@0
  1223
sl@0
  1224
		default:
sl@0
  1225
	    	return KErrNotSupported;
sl@0
  1226
		}
sl@0
  1227
	    return r;
sl@0
  1228
    }
sl@0
  1229
sl@0
  1230
TInt DChannelResManUs::DoControl(TInt aFunction, TAny* a1, TAny* a2)
sl@0
  1231
// Synchronous requests.
sl@0
  1232
    {
sl@0
  1233
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DoControl(TInt aFunction, TAny* a1, TAny* a2)") );
sl@0
  1234
sl@0
  1235
    TInt r=KErrNone;
sl@0
  1236
    switch (aFunction)
sl@0
  1237
		{
sl@0
  1238
		case RBusDevResManUs::EInitialise:
sl@0
  1239
			{
sl@0
  1240
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EInitialise"));
sl@0
  1241
			// a1 specifies the array describing the number of 'gettable' and 'settable' state resources
sl@0
  1242
			// and the number of 'listenable' resources
sl@0
  1243
			//
sl@0
  1244
			TUint8 *stateRes = (TUint8*)a1;
sl@0
  1245
#ifdef PRM_US_INSTRUMENTATION_MACRO
sl@0
  1246
	PRM_US_REGISTER_CLIENT_START_TRACE;
sl@0
  1247
#endif
sl@0
  1248
			// The call to the Resource Controller's AllocReserve method requires two parameters:
sl@0
  1249
			// the number of client level objects and the number of request message objects
sl@0
  1250
			// Each 'settable' state resource requires a client level object and a request message object
sl@0
  1251
			// Each 'gettable' state resource requires a request message object, only.
sl@0
  1252
			// Call Resource Control to make allocations
sl@0
  1253
			r=((DPowerResourceController*)iPddPtr)->AllocReserve(ClientHandle(),
sl@0
  1254
															stateRes[1],							// Number of settable
sl@0
  1255
															(TUint8)(stateRes[1] + stateRes[0]));	// Number of (settable + gettable)
sl@0
  1256
#ifdef PRM_US_INSTRUMENTATION_MACRO
sl@0
  1257
	PRM_US_REGISTER_CLIENT_END_TRACE;
sl@0
  1258
#endif
sl@0
  1259
			if(r==KErrNone)
sl@0
  1260
				{
sl@0
  1261
				// Require 1 TPowerResourceCb object per gettable resource state
sl@0
  1262
				// Require 1 TPowerResourceCb object per settable resource state
sl@0
  1263
				// Require 1 DPowerResourceNotification object per listenable resource
sl@0
  1264
				//
sl@0
  1265
				if(stateRes[0]>0)
sl@0
  1266
					r=InitTrackingControl(iGetStateTracker,EGetState,stateRes[0]);
sl@0
  1267
				if((r==KErrNone) && (stateRes[1]>0))
sl@0
  1268
					r=InitTrackingControl(iSetStateTracker,ESetState,stateRes[1]);
sl@0
  1269
				if((r==KErrNone) && (stateRes[2]>0))
sl@0
  1270
					r=InitTrackingControl(iListenableTracker,ENotify,stateRes[2]);
sl@0
  1271
#ifdef _DUMP_TRACKERS
sl@0
  1272
			if((r=DumpTracker(iGetStateTracker))!=KErrNone)
sl@0
  1273
				break;
sl@0
  1274
			if((r=DumpTracker(iSetStateTracker))!=KErrNone)
sl@0
  1275
				break;
sl@0
  1276
#endif
sl@0
  1277
				}
sl@0
  1278
			break;
sl@0
  1279
			}
sl@0
  1280
sl@0
  1281
		case RBusDevResManUs::EGetNoOfResources:
sl@0
  1282
			{
sl@0
  1283
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNoOfResources"));
sl@0
  1284
			TUint numResources;
sl@0
  1285
			r=((DPowerResourceController*)iPddPtr)->GetNumResourcesInUseByClient(ClientHandle(),0,numResources);
sl@0
  1286
			iResInfoValid = 0;			// New numResources invalidates the iResInfoXXXX information
sl@0
  1287
			iResInfoStoredClientId = 0;
sl@0
  1288
			iResInfoStoredNum = 0;
sl@0
  1289
			if(r!=KErrNone)
sl@0
  1290
				return r;
sl@0
  1291
			// a2 specifies whether the resource information should be loaded
sl@0
  1292
			if((r==KErrNone)&&(a2!=NULL))
sl@0
  1293
				{
sl@0
  1294
				TUint prevNumRes = 0;
sl@0
  1295
				while((numResources != prevNumRes)&&(r==KErrNone))
sl@0
  1296
					{
sl@0
  1297
					// if the number of resources is greater than can be accommodated by the array,
sl@0
  1298
					// re-size it
sl@0
  1299
					if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
sl@0
  1300
						break;
sl@0
  1301
					prevNumRes = numResources;
sl@0
  1302
					// Get the resource info from the Resource Controller
sl@0
  1303
					// Specify 'aTargetClientId' as zero to access all resources
sl@0
  1304
					iResourceInfoResCtrl->SetLength(0);
sl@0
  1305
					r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
sl@0
  1306
															ClientHandle(),0,numResources,iResourceInfoResCtrl);
sl@0
  1307
					}
sl@0
  1308
				if(r==KErrNone)
sl@0
  1309
					{
sl@0
  1310
					iResInfoValid = 1;
sl@0
  1311
					iResInfoStoredClientId = KAllResInfoStored;
sl@0
  1312
					iResInfoStoredNum = numResources;
sl@0
  1313
					}
sl@0
  1314
				}
sl@0
  1315
			if(r==KErrNone)
sl@0
  1316
				*(TUint*)a1 = numResources;
sl@0
  1317
			break;
sl@0
  1318
			}
sl@0
  1319
sl@0
  1320
		case RBusDevResManUs::EGetAllResourcesInfo:
sl@0
  1321
			{
sl@0
  1322
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetAllResourcesInfo"));
sl@0
  1323
			// Parameters are passed in TUint* parms[2]
sl@0
  1324
			// The address of the number of resources is at element 0
sl@0
  1325
			// The flag to indicate if the resource info stored is to be refreshed is at element 1
sl@0
  1326
			TUint* parms = (TUint*)a2;
sl@0
  1327
			TUint numResources = *(TUint*)parms[0];
sl@0
  1328
			TBool refresh=(TBool)(parms[1]);
sl@0
  1329
			
sl@0
  1330
			// The results are to be written to an RSimplePointerArray, the address is in a1
sl@0
  1331
			// Check that the array has enough elements
sl@0
  1332
			if(refresh)
sl@0
  1333
				{
sl@0
  1334
				// For the refresh option, invoke Resource Controller API once, only (do not recurse)
sl@0
  1335
				// If the number of requested resources is greater than can be accommodated by the array,
sl@0
  1336
				// re-size it
sl@0
  1337
				if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
sl@0
  1338
					break;
sl@0
  1339
				// Get the resource info from the Resource Controller
sl@0
  1340
				// Specify 'aTargetClientId' as zero to access all resources
sl@0
  1341
				iResourceInfoResCtrl->SetLength(0);
sl@0
  1342
				r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
sl@0
  1343
														ClientHandle(),0,numResources,iResourceInfoResCtrl);
sl@0
  1344
				if(numResources != iResInfoStoredNum)
sl@0
  1345
					{
sl@0
  1346
					iResInfoValid = 0;		// Assume cohesion is now lost 
sl@0
  1347
					iResInfoStoredClientId = 0;
sl@0
  1348
					iResInfoStoredNum = 0;
sl@0
  1349
					}
sl@0
  1350
				}
sl@0
  1351
			else
sl@0
  1352
				{
sl@0
  1353
				// If the information stored is not valid or is not for all resources return KErrNotReady 
sl@0
  1354
				if((iResInfoValid != 1)||(iResInfoStoredClientId != KAllResInfoStored))
sl@0
  1355
					{
sl@0
  1356
					r=KErrNotReady;
sl@0
  1357
					break;
sl@0
  1358
					}
sl@0
  1359
				// The number of resources for which information is available in this case is iResInfoStoredNum
sl@0
  1360
				numResources = iResInfoStoredNum;
sl@0
  1361
				}
sl@0
  1362
#ifdef RESOURCE_MANAGER_SIMULATED_PSL
sl@0
  1363
			TPowerResourceInfoV01* currRes = (TPowerResourceInfoV01*)iResourceInfoResCtrl->Ptr();
sl@0
  1364
			for(TUint index = 0; index < numResources; index++)
sl@0
  1365
				{
sl@0
  1366
				CheckForCandidateAsyncResource(currRes);
sl@0
  1367
				CheckForCandidateSharedResource(currRes);
sl@0
  1368
				currRes++;
sl@0
  1369
				}
sl@0
  1370
#endif
sl@0
  1371
			*(TUint*)(parms[0]) = numResources;
sl@0
  1372
sl@0
  1373
			break;
sl@0
  1374
			}
sl@0
  1375
sl@0
  1376
		case RBusDevResManUs::EGetNoOfClients:
sl@0
  1377
		case RBusDevResManUs::EGetNumClientsUsingResource:
sl@0
  1378
			{
sl@0
  1379
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNoOfClients"));
sl@0
  1380
			// Parameters are passed in TUint parms[3]
sl@0
  1381
			// The flag to indicate if kernel-side clients are to be included is at element 0
sl@0
  1382
			// The ID of the resource of interest (0 is expected for EGetNoOfClients)
sl@0
  1383
			// The flag to indicate if the client info is to be read now is at element 1
sl@0
  1384
			TUint *parms = (TUint*)a2;
sl@0
  1385
			TUint includeKern = parms[0];
sl@0
  1386
			TUint resourceId = parms[1];
sl@0
  1387
			TUint infoRead = parms[2];
sl@0
  1388
			TUint requiredId = resourceId;
sl@0
  1389
			if(aFunction == RBusDevResManUs::EGetNoOfClients)
sl@0
  1390
				{
sl@0
  1391
				__ASSERT_ALWAYS(resourceId==0,RESMANUS_FAULT());
sl@0
  1392
				requiredId = KAllClientInfoStored;
sl@0
  1393
				}
sl@0
  1394
			TUint numClients = 0;
sl@0
  1395
			if(includeKern==1)
sl@0
  1396
				{
sl@0
  1397
				// Client must exhibit PlatSec capability ReadDeviceData
sl@0
  1398
				if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNoOfClients")))
sl@0
  1399
					{
sl@0
  1400
					r =  KErrPermissionDenied;
sl@0
  1401
					break;
sl@0
  1402
					}
sl@0
  1403
				if(r==KErrNone)
sl@0
  1404
					r=((DPowerResourceController*)iPddPtr)->GetNumClientsUsingResource(ClientHandle(),resourceId,numClients);
sl@0
  1405
				}
sl@0
  1406
			else
sl@0
  1407
				numClients = (TUint)(iDevice->iOpenChannels);
sl@0
  1408
sl@0
  1409
			// New numClients invalidates the iClientInfoXXXX information
sl@0
  1410
			iClientInfoValid = 0;
sl@0
  1411
			iClientInfoStoredResId = 0;
sl@0
  1412
			iClientInfoStoredNum= 0;
sl@0
  1413
sl@0
  1414
			if((r==KErrNone)&&(infoRead==1))
sl@0
  1415
				{
sl@0
  1416
				// Capability check already performed, so no need to repeat ...
sl@0
  1417
				TUint prevNumClients = 0;
sl@0
  1418
				while((numClients != prevNumClients)&&(r == KErrNone))
sl@0
  1419
					{
sl@0
  1420
					// Ensure buffer is large enough to store the information
sl@0
  1421
					if((r=EnsureSizeIsSufficient(iClientNamesResCtrl, (TInt)(numClients*sizeof(TPowerClientInfoV01))))!=KErrNone)
sl@0
  1422
						break;
sl@0
  1423
					prevNumClients = numClients;
sl@0
  1424
					// Invoke the API
sl@0
  1425
					r=((DPowerResourceController*)iPddPtr)->GetInfoOnClientsUsingResource(ClientHandle(),
sl@0
  1426
																					resourceId,numClients,iClientNamesResCtrl);
sl@0
  1427
					};
sl@0
  1428
sl@0
  1429
				if(r==KErrNone)
sl@0
  1430
					{
sl@0
  1431
					iClientInfoValid = 1;
sl@0
  1432
					iClientInfoStoredResId = requiredId;
sl@0
  1433
					iClientInfoStoredNum = numClients;
sl@0
  1434
					if(includeKern!=1)
sl@0
  1435
						{
sl@0
  1436
						TUint numAllClients = numClients;
sl@0
  1437
						numClients = 0;
sl@0
  1438
						TPowerClientInfoV01* rcDataPtr = (TPowerClientInfoV01*)(iClientNamesResCtrl->Ptr());
sl@0
  1439
						for(TUint i=0; i<numAllClients; i++)
sl@0
  1440
							{
sl@0
  1441
							if( rcDataPtr->iClientId & USER_SIDE_CLIENT_BIT_MASK)
sl@0
  1442
								++numClients;
sl@0
  1443
							++rcDataPtr;
sl@0
  1444
							}
sl@0
  1445
						}
sl@0
  1446
					}
sl@0
  1447
				}
sl@0
  1448
			if(r==KErrNone)
sl@0
  1449
				*(TUint*)a1 = numClients;
sl@0
  1450
			break;
sl@0
  1451
			}
sl@0
  1452
sl@0
  1453
		case RBusDevResManUs::EGetNamesAllClients:
sl@0
  1454
		case RBusDevResManUs::EGetInfoOnClientsUsingResource:
sl@0
  1455
			{
sl@0
  1456
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNamesAllClients-EGetInfoOnClientsUsingResource"));
sl@0
  1457
			// Parameters are passed in TUint* parms[4]
sl@0
  1458
			// The address of the number of clients is at element 0
sl@0
  1459
			// The flag to indicate if kernel-side info is requested is at element 1
sl@0
  1460
			// The resource ID is at element 2
sl@0
  1461
			// The flag to indicate if the client information stored is to be refreshed is at element 3
sl@0
  1462
			TUint* parms = (TUint*)a2;
sl@0
  1463
			TUint numClients = *(TUint*)parms[0];
sl@0
  1464
			TBool includeKern=(TBool)(parms[1]);
sl@0
  1465
			TUint resourceId=(TUint)(parms[2]);
sl@0
  1466
			TBool refresh=(TBool)(parms[3]);
sl@0
  1467
		
sl@0
  1468
			TUint numClientsAvailable = 0; 
sl@0
  1469
			iClientNamesResCtrl->SetLength(0);
sl@0
  1470
			
sl@0
  1471
			if(includeKern)
sl@0
  1472
				{
sl@0
  1473
				// Client must exhibit PlatSec capability ReadDeviceData
sl@0
  1474
				if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNamesAllClients-EGetInfoOnClientsUsingResource")))
sl@0
  1475
					{
sl@0
  1476
					r = KErrPermissionDenied;
sl@0
  1477
					break;  // Early exit in event of error
sl@0
  1478
					}
sl@0
  1479
				TUint requiredId = (resourceId==0)?(TUint)KAllClientInfoStored:resourceId;
sl@0
  1480
				if(refresh)
sl@0
  1481
					{
sl@0
  1482
					// For the refresh option, invoke Resource Controller API once, only (do not recurse)
sl@0
  1483
					// If the number of clients is greater than can be accommodated by the array,
sl@0
  1484
					// re-size it
sl@0
  1485
					if((r=EnsureSizeIsSufficient(iClientNamesResCtrl, (TInt)(numClients*sizeof(TPowerClientInfoV01))))!=KErrNone)
sl@0
  1486
						break;
sl@0
  1487
					// Invoke the API
sl@0
  1488
					numClientsAvailable = numClients; // Arbitrary initialisation (to silence compiler warning)
sl@0
  1489
					r=((DPowerResourceController*)iPddPtr)->GetInfoOnClientsUsingResource(ClientHandle(),
sl@0
  1490
																					resourceId,numClientsAvailable,iClientNamesResCtrl);
sl@0
  1491
					if((r!=KErrNone)||(numClientsAvailable != iClientInfoStoredNum)||(iClientInfoStoredResId != requiredId))
sl@0
  1492
						{
sl@0
  1493
						iClientInfoValid = 0;	// Assume cohesion is now lost	
sl@0
  1494
						iClientInfoStoredResId = 0;
sl@0
  1495
						iClientInfoStoredNum = 0;
sl@0
  1496
						}
sl@0
  1497
					}
sl@0
  1498
				else
sl@0
  1499
					{
sl@0
  1500
					// If the information stored is not valid, is not for the required resources return KErrNotReady 
sl@0
  1501
					if((iClientInfoValid != 1)||(iClientInfoStoredResId != requiredId))
sl@0
  1502
						r=KErrNotReady;
sl@0
  1503
					// The number of clients for which information is available in this case is iClientInfoStoredNum
sl@0
  1504
					numClientsAvailable = iClientInfoStoredNum;
sl@0
  1505
					}
sl@0
  1506
				}
sl@0
  1507
			else
sl@0
  1508
				{
sl@0
  1509
				// Resource Controller will return information for the number of clients requested,
sl@0
  1510
				// taken in order from its internal storage - but this will be regardless of whether
sl@0
  1511
				// they are kernel-side or user-side; the USER_SIDE_CLIENT_BIT_MASK bit must be 
sl@0
  1512
				// interrogated to determine this.
sl@0
  1513
				//
sl@0
  1514
				// Therefore, need to read all the clients - but to do this, must find out how many 
sl@0
  1515
				// clients there are first.
sl@0
  1516
				TUint numAllClients;
sl@0
  1517
				r=((DPowerResourceController*)iPddPtr)->GetNumClientsUsingResource(ClientHandle(),resourceId,numAllClients);
sl@0
  1518
				if(r!=KErrNone)
sl@0
  1519
					break;  // Early exit in event of error
sl@0
  1520
				if(numAllClients > 0)
sl@0
  1521
					{
sl@0
  1522
					if(refresh)
sl@0
  1523
						{
sl@0
  1524
						// For the refresh option, invoke Resource Controller API once, only (do not recurse)
sl@0
  1525
						// If the number of clients is greater than can be accommodated by the array,
sl@0
  1526
						// re-size it
sl@0
  1527
						if((r=EnsureSizeIsSufficient(iClientNamesResCtrl, (TInt)(numAllClients*sizeof(TPowerClientInfoV01))))!=KErrNone)
sl@0
  1528
							break;
sl@0
  1529
						// Invoke the API
sl@0
  1530
						r=((DPowerResourceController*)iPddPtr)->GetInfoOnClientsUsingResource(ClientHandle(),
sl@0
  1531
																						resourceId,numAllClients,iClientNamesResCtrl);
sl@0
  1532
						TUint requiredId = (resourceId==0)?(TUint)KAllClientInfoStored:resourceId;
sl@0
  1533
						if((r!=KErrNone)||(numClientsAvailable != iClientInfoStoredNum)||(iClientInfoStoredResId != requiredId))
sl@0
  1534
							{
sl@0
  1535
							iClientInfoValid = 0;	// Assume cohesion is now lost	
sl@0
  1536
							iClientInfoStoredResId = 0;
sl@0
  1537
							iClientInfoStoredNum = 0;
sl@0
  1538
							break;
sl@0
  1539
							}
sl@0
  1540
						else
sl@0
  1541
							{
sl@0
  1542
							iClientInfoValid = 1;
sl@0
  1543
							iClientInfoStoredResId = requiredId;
sl@0
  1544
							iClientInfoStoredNum = numAllClients;
sl@0
  1545
							}
sl@0
  1546
						}
sl@0
  1547
					else
sl@0
  1548
						{
sl@0
  1549
						// If the information stored is not valid, is not for the required resources return KErrNotReady 
sl@0
  1550
						TUint requiredId = (resourceId==0)?(TUint)KAllClientInfoStored:resourceId;
sl@0
  1551
						if((iClientInfoValid != 1)||(iClientInfoStoredResId != requiredId))
sl@0
  1552
							{
sl@0
  1553
							r=KErrNotReady;
sl@0
  1554
							break;
sl@0
  1555
							}
sl@0
  1556
						// The number of clients for which information is available in this case is iClientInfoStoredNum
sl@0
  1557
						numAllClients = iClientInfoStoredNum;
sl@0
  1558
						}
sl@0
  1559
					numClientsAvailable = numAllClients;
sl@0
  1560
					} // if(numAllClients > 0)
sl@0
  1561
				}
sl@0
  1562
			// Write the total number of user side cients available
sl@0
  1563
			*(TUint*)parms[0] = numClientsAvailable;
sl@0
  1564
			break;
sl@0
  1565
			}
sl@0
  1566
		case RBusDevResManUs::EGetNumResourcesInUseByClient:
sl@0
  1567
			{
sl@0
  1568
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumResourcesInUseByClient"));
sl@0
  1569
			// a1 specifies the container holding the client name
sl@0
  1570
			//
sl@0
  1571
			
sl@0
  1572
			// If client doesn't exist, return KErrNotFound
sl@0
  1573
			// If client has appropriate capabilities, or if the client for which the information is sought
sl@0
  1574
			// is user-side, invoke the Resource Controller API directly
sl@0
  1575
			// Otherwise, return KErrPermissionDenied
sl@0
  1576
			TUint clientId=0;
sl@0
  1577
			r=((DPowerResourceController*)iPddPtr)->GetClientId(ClientHandle(),
sl@0
  1578
															*(TDesC8*)a1,clientId);
sl@0
  1579
			if(r!=KErrNone)
sl@0
  1580
				return KErrNotFound;
sl@0
  1581
			// Perform capability check
sl@0
  1582
			if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNoOfClients")))
sl@0
  1583
				{
sl@0
  1584
				if(!(clientId & USER_SIDE_CLIENT_BIT_MASK))
sl@0
  1585
					return KErrPermissionDenied;
sl@0
  1586
				}
sl@0
  1587
			TUint numResources=0;
sl@0
  1588
			if(r==KErrNone)
sl@0
  1589
				r=((DPowerResourceController*)iPddPtr)->GetNumResourcesInUseByClient(ClientHandle(),
sl@0
  1590
																			clientId,numResources);
sl@0
  1591
			// New numResources invalidates the iResXXXX information
sl@0
  1592
			iResInfoValid = 0;
sl@0
  1593
			iResInfoStoredClientId = 0;
sl@0
  1594
			iResInfoStoredNum= 0;
sl@0
  1595
sl@0
  1596
			// parms[1] specifies whether the resource information should be loaded
sl@0
  1597
			if((r==KErrNone)&&(*(TUint*)a2 != NULL))
sl@0
  1598
				{
sl@0
  1599
				TUint prevNumRes = 0;
sl@0
  1600
				while((numResources != prevNumRes)&&(r==KErrNone))
sl@0
  1601
					{
sl@0
  1602
					// if the number of resources is greater than can be accommodated by the array,
sl@0
  1603
					// re-size it
sl@0
  1604
					if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
sl@0
  1605
						break;
sl@0
  1606
					prevNumRes = numResources;
sl@0
  1607
					// Get the resource info from the Resource Controller
sl@0
  1608
					// Specify 'aTargetClientId' as zero to access all resources
sl@0
  1609
					iResourceInfoResCtrl->SetLength(0);
sl@0
  1610
					r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
sl@0
  1611
															ClientHandle(),clientId,numResources,iResourceInfoResCtrl);
sl@0
  1612
					}
sl@0
  1613
				if(r==KErrNone)
sl@0
  1614
					{
sl@0
  1615
					iResInfoValid = 1;
sl@0
  1616
					iResInfoStoredClientId = clientId;
sl@0
  1617
					iResInfoStoredNum = numResources;
sl@0
  1618
					}
sl@0
  1619
				}
sl@0
  1620
			if(r==KErrNone)
sl@0
  1621
				*(TUint*)a2 = numResources;
sl@0
  1622
			break;
sl@0
  1623
			}
sl@0
  1624
sl@0
  1625
		case RBusDevResManUs::EGetInfoOnResourcesInUseByClient:
sl@0
  1626
			{
sl@0
  1627
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetInfoOnResourcesInUseByClient"));
sl@0
  1628
			// a1 specifies the container holding the client name
sl@0
  1629
			// a2 specifies an array TUint* parms[3] which contains:
sl@0
  1630
			//   - the address of the variable to write the number of reasources to
sl@0
  1631
			//   - a pointer to the container to hold the resources' information
sl@0
  1632
			//   - the flag to indicate whether the resource info should be (re-)read here
sl@0
  1633
sl@0
  1634
			TUint clientId=0;
sl@0
  1635
			TUint *parms = (TUint*)a2;
sl@0
  1636
			TUint numResources = *(TUint*)parms[0];
sl@0
  1637
			// The results are to be written to an RSimplePointerArray, the address is in parms[1]
sl@0
  1638
			// Check that the array has enough elements
sl@0
  1639
			// If client doesn't exist, return KErrNotFound
sl@0
  1640
			// If client has appropriate capabilities, or if the client for which the information is sought
sl@0
  1641
			// is user-side, invoke the Resource Controller API directly
sl@0
  1642
			// Otherwise, return KErrPermissionDenied
sl@0
  1643
			r=((DPowerResourceController*)iPddPtr)->GetClientId(ClientHandle(),
sl@0
  1644
															*(TDesC8*)a1,clientId);
sl@0
  1645
			if(r!=KErrNone)
sl@0
  1646
				return KErrNotFound;
sl@0
  1647
			// Perform capability check
sl@0
  1648
			if(!iClient->HasCapability(ECapabilityReadDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Resource Manager user-side API function EGetNoOfClients")))
sl@0
  1649
				{
sl@0
  1650
				if(!(clientId & USER_SIDE_CLIENT_BIT_MASK))
sl@0
  1651
					return KErrPermissionDenied;
sl@0
  1652
				}
sl@0
  1653
sl@0
  1654
			TUint updatedNumResources = numResources;
sl@0
  1655
			r=((DPowerResourceController*)iPddPtr)->GetNumResourcesInUseByClient(ClientHandle(),clientId,updatedNumResources);
sl@0
  1656
			if(r!=KErrNone)
sl@0
  1657
				break;
sl@0
  1658
sl@0
  1659
			if(updatedNumResources>0)
sl@0
  1660
				{
sl@0
  1661
				if((TUint)(parms[2] != 0))
sl@0
  1662
					{
sl@0
  1663
					// For the refresh option, invoke Resource Controller API once, only (do not recurse)
sl@0
  1664
					// If the number of requested resources is greater than can be accommodated by the array,
sl@0
  1665
					// re-size it
sl@0
  1666
					if((r=EnsureSizeIsSufficient(iResourceInfoResCtrl, (TInt)(numResources*sizeof(TPowerResourceInfoV01))))!=KErrNone)
sl@0
  1667
						break;
sl@0
  1668
					// Get the resource info from the Resource Controller
sl@0
  1669
					// Specify 'aTargetClientId' as zero to access all resources
sl@0
  1670
					iResourceInfoResCtrl->SetLength(0);
sl@0
  1671
					r=((DPowerResourceController*)iPddPtr)->GetInfoOnResourcesInUseByClient(
sl@0
  1672
															ClientHandle(),clientId,numResources,iResourceInfoResCtrl);
sl@0
  1673
					if((numResources != iResInfoStoredNum)||(iResInfoStoredClientId != clientId))
sl@0
  1674
						{
sl@0
  1675
						iResInfoValid = 0;		// Assume cohesion is now lost 
sl@0
  1676
						iResInfoStoredClientId = 0;
sl@0
  1677
						iResInfoStoredNum = 0;
sl@0
  1678
						}
sl@0
  1679
					}
sl@0
  1680
				else
sl@0
  1681
					{
sl@0
  1682
					// If the information stored is not valid or is not for the required clientId return KErrNotReady 
sl@0
  1683
					if((iResInfoValid != 1)||(iResInfoStoredClientId != clientId))
sl@0
  1684
						r=KErrNotReady;
sl@0
  1685
					// The number of resources for which information is available in this case is iResInfoStoredNum
sl@0
  1686
					numResources = iResInfoStoredNum;
sl@0
  1687
					}
sl@0
  1688
				}
sl@0
  1689
			if(r==KErrNone)
sl@0
  1690
				*(TUint*)parms[0] = updatedNumResources;
sl@0
  1691
sl@0
  1692
			break;
sl@0
  1693
			}
sl@0
  1694
sl@0
  1695
		case RBusDevResManUs::EGetResourceIdByName:
sl@0
  1696
			{
sl@0
  1697
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetResourceIdByName"));
sl@0
  1698
			// a1 specifies the container holding the resource name
sl@0
  1699
			// a2 specifies the variable to be update with the ID
sl@0
  1700
			TUint resourceId;
sl@0
  1701
			r=((DPowerResourceController*)iPddPtr)->GetResourceId(ClientHandle(), *(TDesC8*)a1, resourceId);
sl@0
  1702
			if(r==KErrNone)
sl@0
  1703
				*(TUint *)a2 = resourceId;
sl@0
  1704
			break;
sl@0
  1705
			}
sl@0
  1706
sl@0
  1707
		case RBusDevResManUs::EGetResourceInfo:
sl@0
  1708
			{
sl@0
  1709
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetResourceInfo"));
sl@0
  1710
			// a1 specifies the container holding the resource ID
sl@0
  1711
			// a2 specifies the address of the container to be written to
sl@0
  1712
sl@0
  1713
			TUint resourceId= (TUint)a1;
sl@0
  1714
			TPowerResourceInfoBuf01 resCtrlInfo;
sl@0
  1715
			resCtrlInfo.SetLength(0);
sl@0
  1716
			TResourceInfoBuf tempInfo;
sl@0
  1717
			r=((DPowerResourceController*)iPddPtr)->GetResourceInfo(ClientHandle(),resourceId,&resCtrlInfo);
sl@0
  1718
			if(r==KErrNone)
sl@0
  1719
				{
sl@0
  1720
				// Copy the client buffer to tempInfo so that its size can be determined
sl@0
  1721
				// by ExtractResourceInfo
sl@0
  1722
				r=ExtractResourceInfo(&(resCtrlInfo()), tempInfo);
sl@0
  1723
				}			
sl@0
  1724
			if(r==KErrNone)
sl@0
  1725
				{
sl@0
  1726
				// Write the resources' info to the client thread
sl@0
  1727
				*(TResourceInfoBuf*)a2 = tempInfo;
sl@0
  1728
				}
sl@0
  1729
			break;
sl@0
  1730
			}
sl@0
  1731
sl@0
  1732
sl@0
  1733
		case RBusDevResManUs::ECancelChangeResourceStateRequests:
sl@0
  1734
		case RBusDevResManUs::ECancelGetResourceStateRequests:
sl@0
  1735
		case RBusDevResManUs::ECancelChangeNotificationRequests:
sl@0
  1736
			{
sl@0
  1737
			TUint resourceId = (TUint)a1;
sl@0
  1738
			TTrackingControl*tracker=MapRequestToTracker(aFunction);
sl@0
  1739
			r=CancelTrackerRequests(tracker, ETrue, resourceId, NULL);
sl@0
  1740
			if(r==KErrCancel)
sl@0
  1741
				r=KErrNone;	// All cancellations were successful
sl@0
  1742
			break;
sl@0
  1743
			}
sl@0
  1744
sl@0
  1745
		case RBusDevResManUs::ECancelChangeResourceState:
sl@0
  1746
		case RBusDevResManUs::ECancelGetResourceState:
sl@0
  1747
		case RBusDevResManUs::ECancelRequestChangeNotification:
sl@0
  1748
			{
sl@0
  1749
			TRequestStatus* status = (TRequestStatus*)a1;
sl@0
  1750
			r=CancelRequestsOfType(aFunction, status);
sl@0
  1751
			break;
sl@0
  1752
			}
sl@0
  1753
sl@0
  1754
sl@0
  1755
#ifdef RESOURCE_MANAGER_SIMULATED_PSL
sl@0
  1756
		case RBusDevResManUs::EGetNumCandidateAsyncResources:
sl@0
  1757
			{
sl@0
  1758
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumCandidateAsyncResources"));
sl@0
  1759
			TUint numResources;
sl@0
  1760
			GetNumCandidateAsyncResources(numResources);
sl@0
  1761
			// Write the result to the client thread
sl@0
  1762
			*(TUint*)a1 = numResources;
sl@0
  1763
			break;
sl@0
  1764
			}
sl@0
  1765
		case RBusDevResManUs::EGetCandidateAsyncResourceId:
sl@0
  1766
			{
sl@0
  1767
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetCandidateAsyncResourceId"));
sl@0
  1768
			// Get the index to use
sl@0
  1769
			TUint index = (TUint)a1;
sl@0
  1770
			TUint resourceId = 0;
sl@0
  1771
			r=GetCandidateAsyncResourceId(index, resourceId);
sl@0
  1772
			if(r==KErrNone)				// Write the result to the client thread
sl@0
  1773
				*(TUint*)a2 = resourceId;
sl@0
  1774
			break;
sl@0
  1775
			}
sl@0
  1776
sl@0
  1777
		case RBusDevResManUs::EGetNumCandidateSharedResources:
sl@0
  1778
			{
sl@0
  1779
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumCandidateSharedResources"));
sl@0
  1780
			TUint numResources;
sl@0
  1781
			GetNumCandidateSharedResources(numResources);
sl@0
  1782
			// Write the result to the client thread
sl@0
  1783
			*(TUint*)a1 = numResources;
sl@0
  1784
			break;
sl@0
  1785
			}
sl@0
  1786
		case RBusDevResManUs::EGetCandidateSharedResourceId:
sl@0
  1787
			{
sl@0
  1788
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetCandidateSharedResourceId"));
sl@0
  1789
			// Get the index to use
sl@0
  1790
			TUint index = (TUint)a1;
sl@0
  1791
			TUint resourceId = 0;
sl@0
  1792
			r=GetCandidateSharedResourceId(index, resourceId);
sl@0
  1793
			if(r==KErrNone)				// Write the result to the client thread
sl@0
  1794
				*(TUint*)a2 = resourceId;
sl@0
  1795
			break;
sl@0
  1796
			}
sl@0
  1797
#endif
sl@0
  1798
sl@0
  1799
		case RBusDevResManUs::EGetResourceControllerVersion:
sl@0
  1800
			{
sl@0
  1801
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetResourceControllerVersion"));
sl@0
  1802
			// a1 specifies the address of the TVersion variable to be written to
sl@0
  1803
			// a2 is not used
sl@0
  1804
			TUint version;
sl@0
  1805
			if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(), 
sl@0
  1806
																	KResManControlIoGetVersion, 
sl@0
  1807
																	(TAny*)&version,
sl@0
  1808
																	NULL, 
sl@0
  1809
																	NULL))!=KErrNone)
sl@0
  1810
				return r;
sl@0
  1811
			// Write the required information
sl@0
  1812
			*(TUint*)a1 = version;
sl@0
  1813
			break;
sl@0
  1814
			}
sl@0
  1815
		
sl@0
  1816
		case RBusDevResManUs::EGetNumDependentsForResource:
sl@0
  1817
			{
sl@0
  1818
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetNumDependentsForResource"));
sl@0
  1819
			// a1 specifies a pointer to the variable to be written to
sl@0
  1820
			// a2 specifies an array TUint parms[2] which contains:
sl@0
  1821
			//   - the resource ID
sl@0
  1822
			//   - flag to indicate if dependency information is to be loaded as part of this call
sl@0
  1823
			TUint *parms = (TUint*)a2;
sl@0
  1824
			TUint numDependents = 0;
sl@0
  1825
			r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(), 
sl@0
  1826
																	KResManControlIoGetNumDependents,
sl@0
  1827
																	(TAny*)(parms[0]),	// Resource ID
sl@0
  1828
																	&numDependents,
sl@0
  1829
																	NULL);
sl@0
  1830
			iResDepsValid=EFalse; // The number of dependents may differ from the dependency information stored
sl@0
  1831
			if(r!=KErrNone)
sl@0
  1832
				return r;
sl@0
  1833
sl@0
  1834
			// Load the dependency information, if required.
sl@0
  1835
			if(parms[1])
sl@0
  1836
				{
sl@0
  1837
				// The dependency information may be updated subsequent to the request for the number of dependents. In order
sl@0
  1838
				// to provide a coherent number and array of dependents, the requests for dependency information will be
sl@0
  1839
				// re-issued if the (new) number of dependents differs from that previously read.
sl@0
  1840
				TUint prevNumDeps = 0;
sl@0
  1841
				TUint newNumDeps = numDependents;
sl@0
  1842
				while((newNumDeps != prevNumDeps)&&(r == KErrNone))
sl@0
  1843
					{
sl@0
  1844
					if((r=EnsureSizeIsSufficient(iResourceDependencyIds, (TInt)(newNumDeps*sizeof(SResourceDependencyInfo))))!=KErrNone)
sl@0
  1845
						return r;
sl@0
  1846
					prevNumDeps = newNumDeps;
sl@0
  1847
					if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(), 
sl@0
  1848
																			KResManControlIoGetDependentsId,
sl@0
  1849
																			(TAny*)(parms[0]),	// Resource ID
sl@0
  1850
																			(TAny*)(iResourceDependencyIds),
sl@0
  1851
																			(TAny*)&newNumDeps))!=KErrNone)
sl@0
  1852
						return r;
sl@0
  1853
					};
sl@0
  1854
				// Dependency information now in synch with number reported
sl@0
  1855
				numDependents = newNumDeps;
sl@0
  1856
				iNumResDepsStored = newNumDeps;
sl@0
  1857
				iResDepsValid = ETrue;
sl@0
  1858
				}
sl@0
  1859
			// Write the number of dependents to the client thread
sl@0
  1860
			*(TUint*)a1 = numDependents;
sl@0
  1861
			break;
sl@0
  1862
			}
sl@0
  1863
sl@0
  1864
sl@0
  1865
		case RBusDevResManUs::EGetDependentsIdForResource:
sl@0
  1866
			{
sl@0
  1867
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl case EGetDependentsIdForResource"));
sl@0
  1868
			// a1 specifies a pointer to the variable to hold the number of dependencies
sl@0
  1869
			// a2 specifies an array TUint parms[4] which contains:
sl@0
  1870
			//   - the resource ID
sl@0
  1871
			//   - the address of the array to write the required IDs to
sl@0
  1872
			//   - flag to indicate if dependency information is to be (re-)loaded as part of this call
sl@0
  1873
			TUint *parms = (TUint*)a2;
sl@0
  1874
			TUint numDependents = 0;
sl@0
  1875
sl@0
  1876
			// (Re-)Load the dependency information, if required.
sl@0
  1877
			if(parms[2])
sl@0
  1878
				{
sl@0
  1879
				if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(), 
sl@0
  1880
															KResManControlIoGetNumDependents, 
sl@0
  1881
															(TAny*)(parms[0]), 
sl@0
  1882
															(TAny*)&numDependents, 
sl@0
  1883
															NULL))!=KErrNone)
sl@0
  1884
					return r;
sl@0
  1885
sl@0
  1886
				iResDepsValid=EFalse; // The number of dependents may differ from the dependency information stored
sl@0
  1887
				// In order to provide a coherent number and array of dependents, the requests for dependency information
sl@0
  1888
				// will be re-issued if the (new) number of dependents differs from that previously read.
sl@0
  1889
				TUint prevNumDeps = 0;
sl@0
  1890
				TUint newNumDeps = numDependents;
sl@0
  1891
				while(newNumDeps != prevNumDeps)
sl@0
  1892
					{
sl@0
  1893
					if((r=EnsureSizeIsSufficient(iResourceDependencyIds, (TInt)(newNumDeps*sizeof(SResourceDependencyInfo))))!=KErrNone)
sl@0
  1894
						return r;
sl@0
  1895
					prevNumDeps = newNumDeps;
sl@0
  1896
					if((r=((DPowerResourceController*)iPddPtr)->GetInterface(ClientHandle(), 
sl@0
  1897
																			KResManControlIoGetDependentsId,
sl@0
  1898
																			(TAny*)(parms[0]),	// Resource ID
sl@0
  1899
																			(TAny*)(iResourceDependencyIds),
sl@0
  1900
																			(TAny*)&newNumDeps))!=KErrNone)
sl@0
  1901
						return r;
sl@0
  1902
					};
sl@0
  1903
sl@0
  1904
				// Dependency information now in synch with number reported
sl@0
  1905
				numDependents = newNumDeps;
sl@0
  1906
				iNumResDepsStored = newNumDeps;
sl@0
  1907
				iResDepsValid = ETrue;
sl@0
  1908
				}
sl@0
  1909
sl@0
  1910
			// If iResDepsValid equals zero, the results are invalid - so return KErrNotReady.
sl@0
  1911
			if(iResDepsValid==0)
sl@0
  1912
				return KErrNotReady;
sl@0
  1913
sl@0
  1914
			// Write the number of dependencies available to the client
sl@0
  1915
			*(TUint*)a1 = iNumResDepsStored;
sl@0
  1916
			// Write the dependencies to the client array if it is of sufficient size
sl@0
  1917
			// Copy the required dependency information to the user-supplied container.
sl@0
  1918
			parms[1] = (TUint)iResourceDependencyIds;
sl@0
  1919
			break;
sl@0
  1920
			}
sl@0
  1921
		
sl@0
  1922
		default:
sl@0
  1923
			{
sl@0
  1924
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::DoControl default 0x%x", aFunction));
sl@0
  1925
			r=KErrNotSupported;
sl@0
  1926
			}
sl@0
  1927
		}
sl@0
  1928
	    return(r);
sl@0
  1929
    }
sl@0
  1930
sl@0
  1931
sl@0
  1932
TInt DChannelResManUs::EnsureSizeIsSufficient(HBuf*& aBuffer, TInt aMinSize)
sl@0
  1933
	{
sl@0
  1934
// Utility function to ensure a buffer is of at least the minimum required size
sl@0
  1935
// If the buffer is to small, an attempt is made to increase its size.
sl@0
  1936
// If the re-sizing fails, KErrNoMemory is returned; otherwise KErrNone.
sl@0
  1937
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::EnsureSizeIsSufficient"));
sl@0
  1938
sl@0
  1939
	if(aBuffer->MaxLength() < aMinSize)
sl@0
  1940
		{
sl@0
  1941
		aBuffer = aBuffer->ReAlloc(aMinSize);
sl@0
  1942
		if(aBuffer->MaxLength() < aMinSize)
sl@0
  1943
			return KErrNoMemory; // ReAlloc failed - aBuffer is unchanged
sl@0
  1944
		}
sl@0
  1945
	aBuffer->SetLength(0);
sl@0
  1946
	return KErrNone;
sl@0
  1947
	}
sl@0
  1948
sl@0
  1949
void DChannelResManUs::FreeTrackingBuffer(TTrackingBuffer*& aBuffer)
sl@0
  1950
	{
sl@0
  1951
	__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DChannelResManUs::FreeTrackingBuffer"));
sl@0
  1952
	// Function invoked for to free tracking buffers from the busy to free queue of a tracking control
sl@0
  1953
	__ASSERT_ALWAYS((aBuffer!=NULL),RESMANUS_FAULT());
sl@0
  1954
	NKern::FMWait(&iBufferFastMutex);
sl@0
  1955
	TTrackingControl* tracker = aBuffer->GetTrackingControl();
sl@0
  1956
	SDblQue* bufQue = aBuffer->GetQue();
sl@0
  1957
sl@0
  1958
	__ASSERT_ALWAYS(((tracker!=NULL)&&(bufQue!=NULL)),RESMANUS_FAULT());
sl@0
  1959
sl@0
  1960
	// Check that the buffer is still in the busy queue of the tracker - exit if not
sl@0
  1961
	if(bufQue == tracker->iBusyQue)
sl@0
  1962
		{
sl@0
  1963
		aBuffer->Deque();
sl@0
  1964
		tracker->iFreeQue->Add(aBuffer);
sl@0
  1965
		aBuffer->SetQue(tracker->iFreeQue);
sl@0
  1966
		}
sl@0
  1967
	NKern::FMSignal(&iBufferFastMutex);	
sl@0
  1968
	}
sl@0
  1969
sl@0
  1970
sl@0
  1971
TInt DChannelResManUs::GetAndInitTrackingBuffer(TTrackingControl*& aTracker, TTrackingBuffer*& aBuffer, TUint aResourceId, TRequestStatus* aStatus)
sl@0
  1972
	{
sl@0
  1973
// Utility function - perform the necessary processing to get a buffer to support
sl@0
  1974
// asynchronous requests to change the state of a resource
sl@0
  1975
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetAndInitTrackingBuffer"));
sl@0
  1976
	TInt r=KErrNone;
sl@0
  1977
	NKern::FMWait(&iBufferFastMutex);
sl@0
  1978
	if(aTracker->iFreeQue->IsEmpty())
sl@0
  1979
		r = KErrUnderflow;
sl@0
  1980
	else
sl@0
  1981
		{
sl@0
  1982
		// Need intermediate cast from SDblQueLink* to TAny* before TTrackingBuffer*
sl@0
  1983
		TAny* ptr = (TAny*)(aTracker->iFreeQue->GetFirst());
sl@0
  1984
		aBuffer = (TTrackingBuffer*)ptr;
sl@0
  1985
		aTracker->iBusyQue->Add((SDblQueLink*)ptr);
sl@0
  1986
		aBuffer->SetQue(aTracker->iBusyQue);
sl@0
  1987
		aBuffer->SetResourceId(aResourceId);
sl@0
  1988
		TClientRequest* request;
sl@0
  1989
		TTrackingControl* tracker = aBuffer->GetTrackingControl();
sl@0
  1990
		GET_USER_REQUEST(request, aBuffer, tracker->iType);
sl@0
  1991
		request->Reset();
sl@0
  1992
		request->SetStatus(aStatus);
sl@0
  1993
		}
sl@0
  1994
	NKern::FMSignal(&iBufferFastMutex);	
sl@0
  1995
	return r;
sl@0
  1996
	}
sl@0
  1997
sl@0
  1998
TInt DChannelResManUs::GetStateBuffer(TTrackingControl*& aTracker, TTrackingBuffer*& aBuffer, TUint aResourceId, TInt* aState, TInt* aLevelOwnerPtr, TPowerResourceCb*& aCb, TRequestStatus* aStatus)
sl@0
  1999
	{
sl@0
  2000
// Utility function - perform the necessary processing to get a buffer and control block
sl@0
  2001
// to support asynchronous requests to change the state of a resource
sl@0
  2002
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetStateBuffer"));
sl@0
  2003
sl@0
  2004
	TInt r=GetAndInitTrackingBuffer(aTracker, aBuffer, aResourceId, aStatus);
sl@0
  2005
	if(r==KErrNone)
sl@0
  2006
		{
sl@0
  2007
		TTrackGetStateBuf* stateBuf = (TTrackGetStateBuf*)aBuffer;
sl@0
  2008
		stateBuf->iRequest->SetDestPtr1(aState);
sl@0
  2009
		stateBuf->iRequest->SetDestPtr2(aLevelOwnerPtr);
sl@0
  2010
		// Use placement new to update the content of the TPowerResourceCb
sl@0
  2011
		aCb = &(stateBuf->iCtrlBlock);
sl@0
  2012
		new (aCb) TPowerResourceCb(&AsyncCallBackFn,(TAny*)aBuffer,iDfcQ,KResManCallBackPriority);
sl@0
  2013
		}
sl@0
  2014
	return r;
sl@0
  2015
	}
sl@0
  2016
sl@0
  2017
sl@0
  2018
#ifdef _DUMP_TRACKERS
sl@0
  2019
TInt DChannelResManUs::DumpTracker(TTrackingControl* aTracker)
sl@0
  2020
	{
sl@0
  2021
	Kern::Printf("\nDChannelResManUs::DumpTracker");
sl@0
  2022
	Kern::Printf("Tracker at 0x%x\n",aTracker);
sl@0
  2023
	if(NULL==aTracker)
sl@0
  2024
		return KErrGeneral;
sl@0
  2025
	Kern::Printf("iType=%d",aTracker->iType);
sl@0
  2026
	switch(aTracker->iType)
sl@0
  2027
		{
sl@0
  2028
		case 0:
sl@0
  2029
			Kern::Printf("= GetState tracker\n");
sl@0
  2030
		break;
sl@0
  2031
		case 1:
sl@0
  2032
			Kern::Printf("= SetState tracker\n");
sl@0
  2033
		break;
sl@0
  2034
		case 2:
sl@0
  2035
			Kern::Printf("= Notify tracker\n");
sl@0
  2036
		break;
sl@0
  2037
		}
sl@0
  2038
	Kern::Printf("iOwningChannel at 0x%x\n",aTracker->iOwningChannel);
sl@0
  2039
	Kern::Printf("iFreeQue at 0x%x\n",aTracker->iFreeQue);
sl@0
  2040
	SDblQueLink* buf;
sl@0
  2041
	if(aTracker->iFreeQue!=NULL)
sl@0
  2042
		{
sl@0
  2043
		buf=aTracker->iFreeQue->First();
sl@0
  2044
		while(buf!=aTracker->iFreeQue->Last())
sl@0
  2045
			{
sl@0
  2046
			Kern::Printf("iFreeQue buffer at 0x%x\n",buf);
sl@0
  2047
			TAny* intermediatePtr = (TAny*)buf;
sl@0
  2048
			if((aTracker->iType == EGetState)||(aTracker->iType == ESetState))
sl@0
  2049
				{
sl@0
  2050
				TTrackStateBuf* tempBuf =(TTrackStateBuf*)intermediatePtr;
sl@0
  2051
				Kern::Printf("buffer control block at 0x%x\n",tempBuf->iCtrlBlock);
sl@0
  2052
				}
sl@0
  2053
			buf= buf->iNext;
sl@0
  2054
			};
sl@0
  2055
		}
sl@0
  2056
	Kern::Printf("iBusyQue at 0x%x\n",aTracker->iBusyQue);
sl@0
  2057
	if(aTracker->iBusyQue!=NULL)
sl@0
  2058
		{
sl@0
  2059
		buf=aTracker->iBusyQue->First();
sl@0
  2060
		while(buf!=aTracker->iBusyQue->Last())
sl@0
  2061
			{
sl@0
  2062
			Kern::Printf("iBusyQue buffer at 0x%x\n",buf);
sl@0
  2063
			TAny* intermediatePtr = (TAny*)buf;
sl@0
  2064
			if((aTracker->iType == EGetState)||(aTracker->iType == ESetState))
sl@0
  2065
				{
sl@0
  2066
				TTrackStateBuf* tempBuf =(TTrackStateBuf*)intermediatePtr;
sl@0
  2067
				Kern::Printf("buffer control block at 0x%x\n",tempBuf->iCtrlBlock);
sl@0
  2068
				}
sl@0
  2069
			buf= buf->iNext;
sl@0
  2070
			};
sl@0
  2071
		}
sl@0
  2072
sl@0
  2073
	return KErrNone;
sl@0
  2074
	}
sl@0
  2075
#endif
sl@0
  2076
sl@0
  2077
TInt DChannelResManUs::InitTrackingControl(TTrackingControl*& aTracker, TUint8 aType, TUint8 aNumBuffers)
sl@0
  2078
	{
sl@0
  2079
// Set the tracker type, create the tracking queues and required tracking buffers.
sl@0
  2080
// Assign all the tracking buffers to the free queue.
sl@0
  2081
//
sl@0
  2082
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::InitTrackingControl()"));
sl@0
  2083
sl@0
  2084
	TInt r = KErrNone;
sl@0
  2085
	aTracker->iType = (TAsyncOpType)aType;
sl@0
  2086
	aTracker->iOwningChannel = this;
sl@0
  2087
	aTracker->iFreeQue = new SDblQue();
sl@0
  2088
	__ASSERT_DEBUG(aTracker->iFreeQue != NULL, RESMANUS_FAULT());
sl@0
  2089
	if(aTracker->iFreeQue == NULL)
sl@0
  2090
		r = KErrNoMemory;
sl@0
  2091
	if(r==KErrNone)
sl@0
  2092
		{
sl@0
  2093
		aTracker->iBusyQue = new SDblQue();
sl@0
  2094
		__ASSERT_DEBUG(aTracker->iBusyQue != NULL, RESMANUS_FAULT());
sl@0
  2095
		if(aTracker->iBusyQue == NULL)
sl@0
  2096
			{
sl@0
  2097
			delete aTracker->iFreeQue;
sl@0
  2098
			r = KErrNoMemory;
sl@0
  2099
			}
sl@0
  2100
		}
sl@0
  2101
	if(r==KErrNone)
sl@0
  2102
		{
sl@0
  2103
		for(TUint8 i=0; (i<aNumBuffers) && (r==KErrNone) ;i++)
sl@0
  2104
			{
sl@0
  2105
			TAny* buf = NULL;
sl@0
  2106
			TAny* ptr=NULL; // To be assigned to non-NULL value later
sl@0
  2107
			switch(aTracker->iType)
sl@0
  2108
				{
sl@0
  2109
				case EGetState:
sl@0
  2110
					{
sl@0
  2111
					buf = (TAny*)(new TTrackGetStateBuf(&AsyncCallBackFn,ptr,iDfcQ,KResManCallBackPriority));
sl@0
  2112
					r = Kern::CreateClientDataRequest2(((TTrackGetStateBuf*)buf)->iRequest);
sl@0
  2113
					break;
sl@0
  2114
					}
sl@0
  2115
				case ESetState:
sl@0
  2116
					{
sl@0
  2117
					buf = (TAny*)(new TTrackSetStateBuf(&AsyncCallBackFn, ptr, iDfcQ, KResManCallBackPriority));
sl@0
  2118
					r = Kern::CreateClientRequest(((TTrackSetStateBuf*)buf)->iRequest);
sl@0
  2119
					break;
sl@0
  2120
					}
sl@0
  2121
				case ENotify:
sl@0
  2122
					{
sl@0
  2123
					buf = (TAny*)(new TTrackNotifyBuf(&AsyncCallBackFn,ptr,iDfcQ,KResManCallBackPriority));
sl@0
  2124
					r = Kern::CreateClientRequest(((TTrackNotifyBuf*)buf)->iRequest);
sl@0
  2125
					break;
sl@0
  2126
					}
sl@0
  2127
				default:
sl@0
  2128
					__ASSERT_ALWAYS(0,RESMANUS_FAULT());
sl@0
  2129
				}
sl@0
  2130
			__ASSERT_DEBUG(buf!=NULL, RESMANUS_FAULT());
sl@0
  2131
			if((buf == NULL) || (r == KErrNoMemory))
sl@0
  2132
				{
sl@0
  2133
				r = KErrNoMemory;
sl@0
  2134
				break;
sl@0
  2135
				}
sl@0
  2136
			else
sl@0
  2137
				{
sl@0
  2138
				((TTrackingBuffer*)buf)->SetTrackingControl(aTracker);
sl@0
  2139
				(aTracker->iFreeQue)->Add((SDblQueLink*)buf);
sl@0
  2140
				((TTrackingBuffer*)buf)->SetQue(aTracker->iFreeQue);
sl@0
  2141
				}
sl@0
  2142
			}
sl@0
  2143
		// If buffer allocation failed, need to remove all previously-allocated buffers and the queues
sl@0
  2144
		if(r!=KErrNone)
sl@0
  2145
			{
sl@0
  2146
			SDblQueLink* ptr = (aTracker->iFreeQue)->First();
sl@0
  2147
			do
sl@0
  2148
				{
sl@0
  2149
				SDblQueLink* next = NULL;
sl@0
  2150
				if(ptr !=NULL)
sl@0
  2151
					next = ptr->iNext;
sl@0
  2152
				delete ptr;
sl@0
  2153
				ptr = next;
sl@0
  2154
				} while ((ptr!=NULL)&&(ptr!=(aTracker->iFreeQue)->Last()));
sl@0
  2155
			delete aTracker->iFreeQue;
sl@0
  2156
			delete aTracker->iBusyQue;
sl@0
  2157
			}
sl@0
  2158
		}
sl@0
  2159
	return r;
sl@0
  2160
	}
sl@0
  2161
sl@0
  2162
sl@0
  2163
void DChannelResManUs::RemoveTrackingControl(TTrackingControl*& aTracker)
sl@0
  2164
    {
sl@0
  2165
    __KTRACE_OPT(KRESMANAGER, Kern::Printf("DChannelResManUs::RemoveTrackingControl()"));
sl@0
  2166
sl@0
  2167
	// Free the resource-tracking links and their respective queues
sl@0
  2168
	TAny* buf;
sl@0
  2169
	if(aTracker->iFreeQue!=NULL)
sl@0
  2170
		{
sl@0
  2171
		while(!aTracker->iFreeQue->IsEmpty())
sl@0
  2172
			{
sl@0
  2173
			buf = (TAny*)(aTracker->iFreeQue->GetFirst()); // Dequeues the element
sl@0
  2174
			delete buf;
sl@0
  2175
			}
sl@0
  2176
		delete aTracker->iFreeQue;
sl@0
  2177
		}
sl@0
  2178
sl@0
  2179
	if(aTracker->iBusyQue!=NULL)
sl@0
  2180
		{
sl@0
  2181
		while(!aTracker->iBusyQue->IsEmpty())
sl@0
  2182
			{
sl@0
  2183
			buf = (TAny*)(aTracker->iBusyQue->GetFirst()); // Dequeues the element
sl@0
  2184
			delete buf;
sl@0
  2185
			}
sl@0
  2186
		delete aTracker->iBusyQue;
sl@0
  2187
		}
sl@0
  2188
	delete aTracker;
sl@0
  2189
    }
sl@0
  2190
sl@0
  2191
sl@0
  2192
#ifdef RESOURCE_MANAGER_SIMULATED_PSL
sl@0
  2193
void DChannelResManUs::CheckForCandidateAsyncResource(TPowerResourceInfoV01* aResource)
sl@0
  2194
	{
sl@0
  2195
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::CheckForCandidateAsyncResource"));
sl@0
  2196
	// Proceed only if we already have less that the maximum number of candidate resources
sl@0
  2197
	if(iNoCandidateAsyncRes >= MAX_NUM_CANDIDATE_RESOURCES)
sl@0
  2198
		return;
sl@0
  2199
	// For the purposes of asynchronous testing, we need a long latency resource
sl@0
  2200
	if(((TInt)(aResource->iLatencyGet)==(TInt)(EResLongLatency)) && 
sl@0
  2201
		((TInt)(aResource->iLatencySet)==(TInt)(EResLongLatency)))
sl@0
  2202
		{
sl@0
  2203
		// An additional requirement is that the level of the resource can be 
sl@0
  2204
		// updated a sufficient amount of times to support the required testing.
sl@0
  2205
		if(((aResource->iMaxLevel - aResource->iMinLevel) > LEVEL_GAP_REQUIRED_FOR_ASYNC_TESTING) &&
sl@0
  2206
			((TInt)(aResource->iSense) == (TInt)(EResPositive)) )
sl@0
  2207
			{
sl@0
  2208
			TInt r=((DPowerResourceController*)iPddPtr)->GetResourceId(ClientHandle(), *(aResource->iResourceName), iCandidateAsyncResIds[iNoCandidateAsyncRes]);
sl@0
  2209
			if(r!=KErrNone)
sl@0
  2210
				{
sl@0
  2211
				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Failed to identify long latency resource\n"));
sl@0
  2212
				}
sl@0
  2213
			else
sl@0
  2214
				{
sl@0
  2215
				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Potential async resource ID = %d\n",iCandidateAsyncResIds[iNoCandidateAsyncRes]));
sl@0
  2216
				iHaveLongLatencyResource = ETrue;
sl@0
  2217
				++iNoCandidateAsyncRes;
sl@0
  2218
				}
sl@0
  2219
			}
sl@0
  2220
		}
sl@0
  2221
	}
sl@0
  2222
sl@0
  2223
sl@0
  2224
void DChannelResManUs::GetNumCandidateAsyncResources(TUint& aNumResources)
sl@0
  2225
	{
sl@0
  2226
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetNumCandidateAsyncResources"));
sl@0
  2227
sl@0
  2228
	aNumResources = iNoCandidateAsyncRes;
sl@0
  2229
	}
sl@0
  2230
sl@0
  2231
TInt DChannelResManUs::GetCandidateAsyncResourceId(TUint aIndex, TUint& aResourceId)
sl@0
  2232
	{
sl@0
  2233
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetCandidateAsyncResourceId"));
sl@0
  2234
	TInt r = KErrNone;
sl@0
  2235
	if(aIndex>=iNoCandidateAsyncRes)
sl@0
  2236
		r = KErrNotFound;
sl@0
  2237
	else
sl@0
  2238
		aResourceId = iCandidateAsyncResIds[aIndex];
sl@0
  2239
	return r;
sl@0
  2240
	}
sl@0
  2241
sl@0
  2242
void DChannelResManUs::CheckForCandidateSharedResource(TPowerResourceInfoV01* aResource)
sl@0
  2243
	{
sl@0
  2244
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::CheckForCandidateSharedResource"));
sl@0
  2245
sl@0
  2246
	// Proceed only if we already have less that the maximum number of candidate resources
sl@0
  2247
	if(iNoCandidateSharedRes >= MAX_NUM_CANDIDATE_RESOURCES)
sl@0
  2248
		return;
sl@0
  2249
sl@0
  2250
	// For the purposes of testing shared usgae of resources, we need a shareable resource
sl@0
  2251
	if((TInt)(aResource->iUsage)==(TInt)(EResShared))
sl@0
  2252
		{
sl@0
  2253
		// An additional requirement is that the level of the resource can be 
sl@0
  2254
		// updated a sufficient amount of times to support the required testing.
sl@0
  2255
		if(((aResource->iMaxLevel - aResource->iMinLevel) > LEVEL_GAP_REQUIRED_FOR_SHARED_TESTING) &&
sl@0
  2256
			((TInt)(aResource->iSense) == (TInt)(EResPositive)) )
sl@0
  2257
			{
sl@0
  2258
			TInt r=((DPowerResourceController*)iPddPtr)->GetResourceId(ClientHandle(), *(aResource->iResourceName), iCandidateSharedResIds[iNoCandidateSharedRes]);
sl@0
  2259
			if(r!=KErrNone)
sl@0
  2260
				{
sl@0
  2261
				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Failed to identify shared resource\n"));
sl@0
  2262
				}
sl@0
  2263
			else
sl@0
  2264
				{
sl@0
  2265
				__KTRACE_OPT(KRESMANAGER, Kern::Printf("Potential shared resource ID = %d\n",iCandidateSharedResIds[iNoCandidateAsyncRes]));
sl@0
  2266
				iHaveLongLatencyResource = ETrue;
sl@0
  2267
				++iNoCandidateSharedRes;
sl@0
  2268
				}
sl@0
  2269
			}
sl@0
  2270
		}
sl@0
  2271
	}
sl@0
  2272
sl@0
  2273
void DChannelResManUs::GetNumCandidateSharedResources(TUint& aNumResources)
sl@0
  2274
	{
sl@0
  2275
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetNumCandidateSharedResources"));
sl@0
  2276
sl@0
  2277
	aNumResources = iNoCandidateSharedRes;
sl@0
  2278
	}
sl@0
  2279
sl@0
  2280
TInt DChannelResManUs::GetCandidateSharedResourceId(TUint aIndex, TUint& aResourceId)
sl@0
  2281
	{
sl@0
  2282
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::GetCandidateSharedResourceId"));
sl@0
  2283
	TInt r = KErrNone;
sl@0
  2284
	if(aIndex>=iNoCandidateSharedRes)
sl@0
  2285
		r = KErrNotFound;
sl@0
  2286
	else
sl@0
  2287
		aResourceId = iCandidateSharedResIds[aIndex];
sl@0
  2288
	return r;
sl@0
  2289
	}
sl@0
  2290
sl@0
  2291
#endif
sl@0
  2292
sl@0
  2293
TInt DChannelResManUs::ExtractResourceInfo(const TPowerResourceInfoV01* aPwrResInfo, TResourceInfoBuf& aInfo)
sl@0
  2294
	{
sl@0
  2295
// Extract data from a TPowerResourceInfoV01 object to a TResourceInfo instance
sl@0
  2296
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::ExtractResourceInfo"));
sl@0
  2297
sl@0
  2298
	TInt r=KErrNone;
sl@0
  2299
	TInt copyLength=(((aInfo().iName).MaxLength())<((aPwrResInfo->iResourceName)->Length()))?
sl@0
  2300
					(aInfo().iName).MaxLength():
sl@0
  2301
					(aPwrResInfo->iResourceName)->Length();
sl@0
  2302
	(aInfo().iName).Copy((aPwrResInfo->iResourceName)->Ptr(),copyLength);
sl@0
  2303
	aInfo().iId = aPwrResInfo->iResourceId;
sl@0
  2304
	aInfo().iClass	= (TResourceClass)aPwrResInfo->iClass;
sl@0
  2305
	aInfo().iType	= (TResourceType)aPwrResInfo->iType;
sl@0
  2306
	aInfo().iUsage	= (TResourceUsage)aPwrResInfo->iUsage;
sl@0
  2307
	aInfo().iSense	= (TResourceSense)aPwrResInfo->iSense;
sl@0
  2308
	aInfo().iMinLevel = aPwrResInfo->iMinLevel;
sl@0
  2309
	aInfo().iMaxLevel = aPwrResInfo->iMaxLevel;
sl@0
  2310
sl@0
  2311
#ifdef _DUMP_TRACKERS
sl@0
  2312
	r=DumpResource(aPwrResInfo);
sl@0
  2313
#endif
sl@0
  2314
	return r;
sl@0
  2315
	}
sl@0
  2316
sl@0
  2317
#ifdef _DUMP_TRACKERS
sl@0
  2318
TInt DChannelResManUs::DumpResource(const TPowerResourceInfoV01* aResource)
sl@0
  2319
	{
sl@0
  2320
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelResManUs::DumpResource"));
sl@0
  2321
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("Resource name = %S \n",aResource->iResourceName));
sl@0
  2322
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("Resource ID = 0x%d \n",aResource->iResourceId));
sl@0
  2323
	switch(aResource->iClass)
sl@0
  2324
		{
sl@0
  2325
		case DStaticPowerResource::EPhysical:
sl@0
  2326
			{
sl@0
  2327
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("class = EPhysical\n"));
sl@0
  2328
			break;
sl@0
  2329
			}
sl@0
  2330
		case DStaticPowerResource::ELogical:
sl@0
  2331
			{
sl@0
  2332
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("class = ELogical\n"));
sl@0
  2333
			break;
sl@0
  2334
			}
sl@0
  2335
		default:
sl@0
  2336
			{
sl@0
  2337
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("class = % is UNKNOWN!\n"));
sl@0
  2338
			return KErrGeneral;
sl@0
  2339
			}
sl@0
  2340
		}
sl@0
  2341
	switch(aResource->iType)
sl@0
  2342
		{
sl@0
  2343
		case DStaticPowerResource::EBinary:
sl@0
  2344
			{
sl@0
  2345
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("type = EBinary\n"));
sl@0
  2346
			break;
sl@0
  2347
			}
sl@0
  2348
		case DStaticPowerResource::EMultilevel:
sl@0
  2349
			{
sl@0
  2350
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("type = EMultilevel\n"));
sl@0
  2351
			break;
sl@0
  2352
			}
sl@0
  2353
		case DStaticPowerResource::EMultiProperty:
sl@0
  2354
			{
sl@0
  2355
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("type = EMultiProperty\n"));
sl@0
  2356
			break;
sl@0
  2357
			}
sl@0
  2358
		default:
sl@0
  2359
			{
sl@0
  2360
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("type = % is UNKNOWN!\n"));
sl@0
  2361
			return KErrGeneral;
sl@0
  2362
			}
sl@0
  2363
		}
sl@0
  2364
	switch(aResource->iUsage)
sl@0
  2365
		{
sl@0
  2366
		case DStaticPowerResource::ESingleUse:
sl@0
  2367
			{
sl@0
  2368
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("usage = ESingleUse\n"));
sl@0
  2369
			break;
sl@0
  2370
			}
sl@0
  2371
		case DStaticPowerResource::EShared:
sl@0
  2372
			{
sl@0
  2373
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("usage = EShared\n"));
sl@0
  2374
			break;
sl@0
  2375
			}
sl@0
  2376
		default:
sl@0
  2377
			{
sl@0
  2378
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("usage = % is UNKNOWN!\n"));
sl@0
  2379
			return KErrGeneral;
sl@0
  2380
			}
sl@0
  2381
		}
sl@0
  2382
	switch(aResource->iSense)
sl@0
  2383
		{
sl@0
  2384
		case DStaticPowerResource::EPositive:
sl@0
  2385
			{
sl@0
  2386
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = EPositive\n"));
sl@0
  2387
			break;
sl@0
  2388
			}
sl@0
  2389
		case DStaticPowerResource::ENegative:
sl@0
  2390
			{
sl@0
  2391
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = ENegative\n"));
sl@0
  2392
			break;
sl@0
  2393
			}
sl@0
  2394
		case DStaticPowerResource::ECustom:
sl@0
  2395
			{
sl@0
  2396
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = ECustom\n"));
sl@0
  2397
			break;
sl@0
  2398
			}
sl@0
  2399
		default:
sl@0
  2400
			{
sl@0
  2401
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("sense = % is UNKNOWN!\n"));
sl@0
  2402
			return KErrGeneral;
sl@0
  2403
			}
sl@0
  2404
		}
sl@0
  2405
	switch(aResource->iLatencyGet)
sl@0
  2406
		{
sl@0
  2407
		case DStaticPowerResource::EInstantaneous:
sl@0
  2408
			{
sl@0
  2409
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency get = EInstantaneous\n"));
sl@0
  2410
			break;
sl@0
  2411
			}
sl@0
  2412
		case DStaticPowerResource::ENegative:
sl@0
  2413
			{
sl@0
  2414
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency get = ELongLatency\n"));
sl@0
  2415
			break;
sl@0
  2416
			}
sl@0
  2417
		default:
sl@0
  2418
			{
sl@0
  2419
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency get = % is UNKNOWN!\n"));
sl@0
  2420
			return KErrGeneral;
sl@0
  2421
			}
sl@0
  2422
		}
sl@0
  2423
	switch(aResource->iLatencySet)
sl@0
  2424
		{
sl@0
  2425
		case DStaticPowerResource::EInstantaneous:
sl@0
  2426
			{
sl@0
  2427
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency set = EInstantaneous\n"));
sl@0
  2428
			break;
sl@0
  2429
			}
sl@0
  2430
		case DStaticPowerResource::ENegative:
sl@0
  2431
			{
sl@0
  2432
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency set = ELongLatency\n"));
sl@0
  2433
			break;
sl@0
  2434
			}
sl@0
  2435
		default:
sl@0
  2436
			{
sl@0
  2437
			__KTRACE_OPT(KRESMANAGER, Kern::Printf("latency set = % is UNKNOWN!\n"));
sl@0
  2438
			return KErrGeneral;
sl@0
  2439
			}
sl@0
  2440
		}
sl@0
  2441
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("DefaultLevel = %d\n",aResource->iDefaultLevel));
sl@0
  2442
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("MinLevel = %d\n",aResource->iMinLevel));
sl@0
  2443
	__KTRACE_OPT(KRESMANAGER, Kern::Printf("MaxLevel = %d\n",aResource->iMaxLevel));
sl@0
  2444
sl@0
  2445
	return KErrNone;
sl@0
  2446
	}
sl@0
  2447
#endif
sl@0
  2448
sl@0
  2449
#ifndef RESOURCE_MANAGER_SIMULATED_PSL
sl@0
  2450
DECLARE_EXTENSION_LDD()
sl@0
  2451
	{
sl@0
  2452
	return new DDeviceResManUs;
sl@0
  2453
	}
sl@0
  2454
sl@0
  2455
sl@0
  2456
DECLARE_STANDARD_EXTENSION()
sl@0
  2457
	{
sl@0
  2458
	DDeviceResManUs* device = new DDeviceResManUs;
sl@0
  2459
	__KTRACE_OPT(KBOOT, Kern::Printf("DECLARE_STANDARD_EXTENSION, device = 0x%x\n",device));
sl@0
  2460
sl@0
  2461
	if(device == NULL)
sl@0
  2462
		return KErrNoMemory;
sl@0
  2463
	else
sl@0
  2464
		{
sl@0
  2465
		device->iSharedDfcQue = new TDfcQue();
sl@0
  2466
		if(device->iSharedDfcQue==NULL)
sl@0
  2467
			return KErrNoMemory;
sl@0
  2468
sl@0
  2469
		return (Kern::InstallLogicalDevice(device));
sl@0
  2470
		}
sl@0
  2471
	}
sl@0
  2472
#else
sl@0
  2473
DECLARE_STANDARD_LDD()
sl@0
  2474
	{
sl@0
  2475
	TInt r = DSimulatedPowerResourceController::CompleteResourceControllerInitialisation();
sl@0
  2476
	if(r != KErrNone)
sl@0
  2477
		{
sl@0
  2478
		// Unconditionally print message 
sl@0
  2479
		__KTRACE_OPT(KRESMANAGER, Kern::Printf("DECLARE_STANDARD_LDD: initialise Resource Controller failed with %d\n",r));
sl@0
  2480
		return NULL;
sl@0
  2481
		}
sl@0
  2482
	DDeviceResManUs* device = new DDeviceResManUs;
sl@0
  2483
	return device;
sl@0
  2484
	}
sl@0
  2485
#endif