1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/include/drivers/resourcecontrol.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,691 @@
1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\include\drivers\resourcecontrol.h
1.18 +//
1.19 +// WARNING: This file contains some APIs which are internal and are subject
1.20 +// to change without notice. Such APIs should therefore not be used
1.21 +// outside the Kernel and Hardware Services package.
1.22 +//
1.23 +
1.24 +#ifndef __RESOURCECONTROL_H__
1.25 +#define __RESOURCECONTROL_H__
1.26 +#include <nklib.h>
1.27 +#include <kernel/kernel.h>
1.28 +#include <kernel/kern_priv.h>
1.29 +#include <e32ver.h>
1.30 +#define PRM_CONTROLLER
1.31 +#ifndef PRM_ENABLE_EXTENDED_VERSION
1.32 +#include <drivers/resource.h>
1.33 +#else
1.34 +#include <drivers/resource_extend.h>
1.35 +#endif
1.36 +#include <drivers/resourceman.h>
1.37 +
1.38 +/** #defines for client bit masks */
1.39 +#define ID_INDEX_BIT_MASK 0x3FFF /* bit 0 -13 */
1.40 +#define USER_SIDE_CLIENT_BIT_MASK 0x4000 //Bit 14
1.41 +#define CLIENT_THREAD_RELATIVE_BIT_MASK 0x80000000 //Bit 31
1.42 +#define INSTANCE_COUNT_BIT_MASK 0x1FFF //13 Bits
1.43 +#define INSTANCE_COUNT_POS 18
1.44 +#define CLIENT_POWER_CONTROLLER_BIT_MASK 0x8000 //Bit 15
1.45 +/** Bit to indicate valid post boot level in resource */
1.46 +#define SET_VALID_POST_BOOT_LEVEL 0x8000 //Bit 15
1.47 +
1.48 +#define RESOURCE_NOT_IN_OPERATION 0x1
1.49 +#define PRM_DYNAMIC_RESOURCE_INITIAL_SIZE 2
1.50 +
1.51 +#define PRM_STATIC_RESOURCE 0x0
1.52 +#define PRM_STATIC_DEPENDENCY_RESOURCE 0x1
1.53 +#define PRM_DYNAMIC_RESOURCE 0x2
1.54 +#define PRM_DYNAMIC_DEPENDENCY_RESOURCE 0x3
1.55 +#define RESOURCE_BIT_IN_ID_CHECK 16
1.56 +
1.57 +
1.58 +static const TInt KMaxResourceNameLength=0x20; //Maximum allowable resource length is 32 characters.
1.59 +static const TInt KMaxClientNameLength=0x20; //Maximum allowable client length is 32 characters.
1.60 +
1.61 +
1.62 +_LIT8(KPowerController, "PowerController");
1.63 +_LIT8(KDfcThread1Name, "DfcThread1");
1.64 +_LIT8(KDfcThread0Name, "DfcThread0");
1.65 +_LIT8(KNullThreadName, "Null");
1.66 +_LIT8(KNoClient, "NoClient");
1.67 +_LIT8(KParentResource, "ParentResource");
1.68 +/** Macro to check the context of client calling RM API.
1.69 + Panics if it is called from ISR, IDFC, NULL thread or DFC thread1 */
1.70 +#ifdef DEBUG_VERSION
1.71 +#define CHECK_CONTEXT(t) \
1.72 + __ASSERT_ALWAYS(NKern::CurrentContext() == NKern::EThread, Panic(ECalledFromIsr)); \
1.73 + const TDesC8* pDfc1 = &KDfcThread1Name; \
1.74 + if(!pDfc1->Compare(*(TDesC8*)t.iName)) \
1.75 + Panic(ECalledFromDfcThread1); \
1.76 + const TDesC8* pNull = &KNullThreadName; \
1.77 + if(!pNull->Compare(*(TDesC8*)t.iName)) \
1.78 + Panic(ECalledFromNullThread);
1.79 +#else
1.80 +#define CHECK_CONTEXT(t)
1.81 +#endif
1.82 +
1.83 +/** Macro to unlock and return */
1.84 +#define UNLOCK_RETURN(retval) \
1.85 + { \
1.86 + UnLock(); \
1.87 + return(retval); \
1.88 + }
1.89 +
1.90 +/** Macro to push the item into the specified list. Item are pushed to the head of the list. */
1.91 +#define LIST_PUSH(list,item,link) \
1.92 + { \
1.93 + (item)->link = (list); \
1.94 + (list) = (item); \
1.95 + }
1.96 +
1.97 +/** Macro to pop the item from the specified list. Item are poped from the head of the list. */
1.98 +#define LIST_POP(list,item,link) \
1.99 + { \
1.100 + (item) = (list); \
1.101 + if ((item)) \
1.102 + { \
1.103 + (list) = (item)->link; \
1.104 + (item)->link = NULL; \
1.105 + } \
1.106 + }
1.107 +
1.108 +/** Macro to remove the item from the list. */
1.109 +#define LIST_REMOVE(list,item,link,className) \
1.110 + if (list) \
1.111 + { \
1.112 + className* current = (list); \
1.113 + if (current==(item)) \
1.114 + { \
1.115 + (list) = (item)->link; \
1.116 + (item)->link = NULL; \
1.117 + } \
1.118 + else \
1.119 + { \
1.120 + className* next = current->link; \
1.121 + while (next) \
1.122 + { \
1.123 + if ((item)==next) \
1.124 + { \
1.125 + current->link=next->link; \
1.126 + next->link = NULL; \
1.127 + break; \
1.128 + } \
1.129 + current = next; \
1.130 + next = next->link; \
1.131 + } \
1.132 + } \
1.133 + }
1.134 +
1.135 +
1.136 +/* Macro to add dynamic resource to appropriate containers. Used only in extended version */
1.137 +#define ADD_TO_RESOURCE_CONTAINER(list, res, resId, resIdCount) \
1.138 + { \
1.139 + TUint16 growBy = (list).GrowBy(); \
1.140 + if(!growBy) \
1.141 + (list).Initialise((TUint16)PRM_DYNAMIC_RESOURCE_INITIAL_SIZE); \
1.142 + if((list).Add(res, resId) == KErrNoMemory) \
1.143 + { \
1.144 + TInt r = (list).ReSize(growBy); \
1.145 + if(r != KErrNone) \
1.146 + return r; \
1.147 + (list).Add(res, resId); \
1.148 + } \
1.149 + res->iResourceId |= resId; \
1.150 + resId = res->iResourceId; \
1.151 + resIdCount++; \
1.152 + }
1.153 +
1.154 +/* Macro to get the resource from appropriate list. Used only in extended version */
1.155 +#define GET_RESOURCE_FROM_LIST(resId, res) \
1.156 + { \
1.157 + switch((resId >> RESOURCE_BIT_IN_ID_CHECK) & 0x3) \
1.158 + { \
1.159 + case PRM_STATIC_RESOURCE: \
1.160 + if(resId > iStaticResourceArrayEntries) \
1.161 + UNLOCK_RETURN(KErrNotFound); \
1.162 + res = iStaticResourceArray[resId - 1]; \
1.163 + if(!res) \
1.164 + UNLOCK_RETURN(KErrNotFound); \
1.165 + break; \
1.166 + case PRM_STATIC_DEPENDENCY_RESOURCE: \
1.167 + if((TUint16)(resId & ID_INDEX_BIT_MASK) > iStaticResDependencyCount) \
1.168 + UNLOCK_RETURN(KErrNotFound); \
1.169 + res = iStaticResDependencyArray[(TUint16)(resId & ID_INDEX_BIT_MASK) - 1]; \
1.170 + break; \
1.171 + case PRM_DYNAMIC_RESOURCE: \
1.172 + res = iDynamicResourceList[(TUint16)(resId & ID_INDEX_BIT_MASK)]; \
1.173 + if(!res) \
1.174 + UNLOCK_RETURN(KErrNotFound); \
1.175 + break; \
1.176 + case PRM_DYNAMIC_DEPENDENCY_RESOURCE: \
1.177 + res = iDynamicResDependencyList[(TUint16)(resId & ID_INDEX_BIT_MASK)]; \
1.178 + if(!res) \
1.179 + UNLOCK_RETURN(KErrNotFound); \
1.180 + break; \
1.181 + default: \
1.182 + UNLOCK_RETURN(KErrArgument); \
1.183 + } \
1.184 + }
1.185 +
1.186 +/**Macro to get the client from appropriate client list based on bit 14 of client ID.
1.187 + If the client is registered as thread relative, then check is made to make sure
1.188 + it is called from the same thread. */
1.189 +#define VALIDATE_CLIENT(t) \
1.190 + if(aClientId & USER_SIDE_CLIENT_BIT_MASK) \
1.191 + pC = iUserSideClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)]; \
1.192 + else \
1.193 + pC = iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)]; \
1.194 + if(!pC) \
1.195 + { \
1.196 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found")); \
1.197 + UNLOCK_RETURN(KErrAccessDenied); \
1.198 + } \
1.199 + if(pC->iClientId != aClientId) \
1.200 + { \
1.201 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID does not match")); \
1.202 + UNLOCK_RETURN(KErrAccessDenied); \
1.203 + } \
1.204 + if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK) \
1.205 + { \
1.206 + if(pC->iThreadId != t.iId) \
1.207 + { \
1.208 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client not called from thread context(Thread Relative)")); \
1.209 + UNLOCK_RETURN(KErrAccessDenied); \
1.210 + } \
1.211 + }
1.212 +
1.213 +/** Macro to get the target client from appropriate client list based on bit 14 of client ID. */
1.214 +#define GET_TARGET_CLIENT() \
1.215 + if(aTargetClientId & USER_SIDE_CLIENT_BIT_MASK) \
1.216 + pC = iUserSideClientList[(TUint16)(aTargetClientId & ID_INDEX_BIT_MASK)]; \
1.217 + else \
1.218 + pC = iClientList[(TUint16)(aTargetClientId & ID_INDEX_BIT_MASK)]; \
1.219 + if(!pC) \
1.220 + { \
1.221 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("Target Client ID not found")); \
1.222 + UNLOCK_RETURN(KErrNotFound); \
1.223 + } \
1.224 + if(pC->iClientId != aTargetClientId) \
1.225 + { \
1.226 + __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID does not match")); \
1.227 + UNLOCK_RETURN(KErrNotFound); \
1.228 + }
1.229 +
1.230 +/* Macro definition for entry point of Power Resource Controller */
1.231 +#define DECLARE_RESOURCE_MANAGER_EXTENSION(TheController) \
1.232 + TDfc* resourceInitDfc = NULL; \
1.233 + static void ResourceInit(TAny* aController) \
1.234 + { \
1.235 + TInt aReason = NKern::EThread; \
1.236 + PRM_BOOTING_TRACE \
1.237 + ((DPowerResourceController*)aController)->InitResources(); \
1.238 + delete resourceInitDfc; \
1.239 + return; \
1.240 + } \
1.241 + void CreateController(); \
1.242 + GLDEF_C TInt KernelModuleEntry(TInt aReason) \
1.243 + { \
1.244 + if(aReason==KModuleEntryReasonVariantInit0) \
1.245 + { \
1.246 + __KTRACE_OPT(KBOOT, Kern::Printf("Create Resource Controller")); \
1.247 + CreateController(); \
1.248 + return KErrNone; \
1.249 + } \
1.250 + if (aReason==KModuleEntryReasonExtensionInit0) \
1.251 + return KExtensionMaximumPriority; \
1.252 + if (aReason!=KModuleEntryReasonExtensionInit1) \
1.253 + return KErrArgument; \
1.254 + PRM_BOOTING_TRACE \
1.255 + __KTRACE_OPT(KBOOT, Kern::Printf("Initialise Resource Controller")); \
1.256 + TInt r = KErrNone; \
1.257 + r = DPowerResourceController::InitController(); \
1.258 + if(r != KErrNone) \
1.259 + return r; \
1.260 + __KTRACE_OPT(KBOOT, Kern::Printf("Create PDD and queue ResourceInit DFC")); \
1.261 + DResConPddFactory* device = new DResConPddFactory; \
1.262 + if(!device) \
1.263 + return KErrNoMemory; \
1.264 + r = Kern::InstallPhysicalDevice(device); \
1.265 + if(r != KErrNone) \
1.266 + return r; \
1.267 + resourceInitDfc = new TDfc(&ResourceInit,(TAny*)&TheController,Kern::SvMsgQue(),KMaxDfcPriority-1); \
1.268 + if(!resourceInitDfc) \
1.269 + return KErrNoMemory; \
1.270 + resourceInitDfc->Enque(); \
1.271 + return KErrNone; \
1.272 + } \
1.273 + GLDEF_C void CreateController()
1.274 +
1.275 +struct SPowerResourceClient;
1.276 +struct TPowerRequest;
1.277 +struct SPowerRequest;
1.278 +struct SPowerResourceClientLevel;
1.279 +struct SIdleResourceInfo;
1.280 +class DPowerResourceController;
1.281 +
1.282 +/**
1.283 +@internalComponent
1.284 +@prototype 9.5
1.285 +Interface class for Resource Manager
1.286 +Functions from PowerResourceManager calls corresponding functions of this
1.287 +class which in turn calls Powercontroller functions.
1.288 +*/
1.289 +class TInterface
1.290 + {
1.291 +public:
1.292 + static TInt RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType=EOwnerProcess);
1.293 + static TInt DeRegisterClient(TUint aClientId);
1.294 + static TInt GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName);
1.295 + static TInt GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId);
1.296 + static TInt GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId);
1.297 + static TInt GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo);
1.298 + static TInt GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources);
1.299 + static TInt GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources, TAny* aInfo);
1.300 + static TInt GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients);
1.301 + static TInt GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients, TAny* aInfo);
1.302 + static TInt AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm);
1.303 + static TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL);
1.304 + static TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId);
1.305 + static TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb);
1.306 + static TInt CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb);
1.307 + static TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
1.308 + static TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, TInt aThreshold, TBool aDirection);
1.309 + static TInt CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
1.310 + static TInt DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId);
1.311 + static DPowerResourceController* GetPowerResourceController(void);
1.312 + static TInt ControlIO(TUint aClientId, TUint aFunction, TAny* aParam1, TAny* aParam2, TAny* aParam3);
1.313 + };
1.314 +
1.315 +/**
1.316 +@internalComponent
1.317 +@prototype 9.5
1.318 +Container class to create containers of pointers to clients.
1.319 +*/
1.320 +template <class T>
1.321 +class DResourceCon : public DBase
1.322 + {
1.323 +public:
1.324 + inline TInt Initialise(TUint16 aInitialSize);
1.325 + inline void Delete();
1.326 + inline T* operator[](TUint16 aIndex);
1.327 + inline TInt Remove(T* aObj, TUint16 aIndex);
1.328 + inline TInt Add(T* aObj, TUint &aId);
1.329 + inline TInt Find(T*& anEntry, TDesC& aName);
1.330 + inline TInt ReSize(TUint16 aGrowBy);
1.331 + inline TUint16 Count() {return iCount;}
1.332 + inline TUint16 Allocd() {return iAllocated;}
1.333 + inline TUint16 GrowBy() {return iGrowBy;}
1.334 +private:
1.335 + TUint16 iGrowBy; //Size to grow the size of the array.
1.336 + TUint16 iAllocated; //Size of the array
1.337 + TUint16 iCount; //Valid entries in the array
1.338 + TUint16 iInstanceCount; //FreeCounter incremented whenever an entry is added.
1.339 + TUint16 iFreeLoc; //Cached free location in the array
1.340 + TUint16 iSpare;
1.341 + T** iArray;
1.342 + };
1.343 +
1.344 +/**
1.345 +@internalComponent
1.346 +@prototype 9.5
1.347 +Factory class for physical device
1.348 +*/
1.349 +NONSHARABLE_CLASS(DResConPddFactory) : public DPhysicalDevice
1.350 + {
1.351 +public:
1.352 + /**
1.353 + Structure for holding PDD capabilities information
1.354 + */
1.355 + class TCaps
1.356 + {
1.357 + public:
1.358 + TVersion iVersion;
1.359 + };
1.360 +public:
1.361 + DResConPddFactory();
1.362 + virtual TInt Install();
1.363 + virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
1.364 + virtual TInt Validate(TInt aUint, const TDesC8* anInfo, const TVersion& aVer);
1.365 + virtual void GetCaps(TDes8& aDes) const;
1.366 + inline static TVersion VersionRequired();
1.367 + };
1.368 +
1.369 +/**
1.370 +@internalComponent
1.371 +@prototype 9.5
1.372 +Interface class for user side resource controller proxy. For each user side channel opened an object of
1.373 +this class is created in heap and pointer to resource controller is stored in iController member variable.
1.374 +User side resource controller proxy calls the resource controller API's by deferencing the pointer.
1.375 +This class is required as when the channel is closed the device driver framework tries to delete
1.376 +the object stored in ipdd, because of which it is not possible to pass the controller pointer directly.
1.377 +*/
1.378 +class DUserSideProxyInterface: public DBase
1.379 + {
1.380 + public:
1.381 + DPowerResourceController *iController;
1.382 + };
1.383 +
1.384 +
1.385 +/**
1.386 +@publishedPartner
1.387 +@prototype 9.5
1.388 +resource manager implementation base class
1.389 +*/
1.390 +NONSHARABLE_CLASS (DPowerResourceController) : public DBase
1.391 + {
1.392 +public:
1.393 + TInt RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType=EOwnerProcess);
1.394 + TInt DeRegisterClient(TUint aClientId);
1.395 + virtual TInt GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName);
1.396 + virtual TInt GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId);
1.397 + virtual TInt GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId);
1.398 + virtual TInt GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo);
1.399 + virtual TInt GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources);
1.400 + virtual TInt GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources, TAny* aInfo);
1.401 + virtual TInt GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients);
1.402 + virtual TInt GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients, TAny* aInfo);
1.403 + virtual TInt AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm);
1.404 + virtual TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL);
1.405 + virtual TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId);
1.406 + virtual TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb);
1.407 + virtual TInt CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb);
1.408 + virtual TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
1.409 + virtual TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, TInt aThreshold, TBool aDirection);
1.410 + virtual TInt CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN);
1.411 + virtual TInt DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId);
1.412 +public:
1.413 + enum TResConPanic
1.414 + {
1.415 + ECalledFromDfcThread0 = 0,
1.416 + ECalledFromIsr = 1,
1.417 + ECalledFromNullThread = 2,
1.418 + ECalledFromDfcThread1 = 3,
1.419 + EClientHasPendingAsyncRequest = 4,
1.420 + EClientHasNotificationObject = 5,
1.421 + EControllerAlreadyExists = 6,
1.422 + ECustomFunctionNotSet = 7,
1.423 + EClientIdNotInClientLevelList = 8,
1.424 + ENoMemToCreatePowerControllerClient = 9,
1.425 + EResourceNameExceedsLimit = 10,
1.426 + EObjectNotFoundInList = 11
1.427 + };
1.428 +#ifdef PRM_ENABLE_EXTENDED_VERSION
1.429 + enum TExtendedResConPanic
1.430 + {
1.431 + EClosedLoopDependencies = EObjectNotFoundInList + 2, //13
1.432 + ERegisteringNonDependentStaticResource = 14,
1.433 + EClientHasDynamicResourceRegistered = 15,
1.434 + EDynamicResourceStillRegistered = 16,
1.435 + ERegisteringDependentStaticResourceWithHoles = 17
1.436 + };
1.437 +#endif
1.438 + enum TResConStartSequence
1.439 + {
1.440 + EResConCreated,
1.441 + EResConInitialised,
1.442 + EResConStartupCompleted
1.443 + };
1.444 + //early initialization
1.445 + IMPORT_C static TInt InitController();
1.446 + TInt InitResources();
1.447 + //request a post-boot level for the resource
1.448 + IMPORT_C static TInt PostBootLevel(TUint aResId, TInt aLevel);
1.449 + //request registration of static resource
1.450 + IMPORT_C static TInt RegisterStaticResource(TUint aClientId, DStaticPowerResource* pR);
1.451 + //request registration of group/array of static resources
1.452 + IMPORT_C static TInt RegisterArrayOfStaticResources(TUint aClientId, DStaticPowerResource**& aStaticResourceArray, TUint aResCount);
1.453 + //registration for proxy client
1.454 + virtual TInt RegisterProxyClient(TUint& aProxyId, const TDesC8& aName);
1.455 + virtual TInt DeregisterProxyClient(TUint aClientId);
1.456 + //register list of resources whose state matter to Idle
1.457 + virtual TInt RegisterResourcesForIdle(TInt aPowerControllerId, TUint aNumResources, TPtr* aBuf);
1.458 + static void Panic(TUint8 aPanic);
1.459 + virtual TInt GetInterface(TUint aClientId, TUint aInterfaceId, TAny* aParam1, TAny* aParam2, TAny* aParam3);
1.460 + virtual ~DPowerResourceController();
1.461 + /**@internalComponent*/
1.462 + void CompleteNotifications(TInt aClientId, DStaticPowerResource* aResource, TInt aState, TInt aReturnCode, TInt aLevelOwnerId, TBool aLock = ETrue);
1.463 +#ifdef PRM_ENABLE_EXTENDED_VERSION
1.464 + /**@internalComponent*/
1.465 + TInt ReserveClientLevelPoolCount(TUint16 aCount);
1.466 + /**@internalComponent*/
1.467 + void RemoveClientLevelFromPool(SPowerResourceClientLevel *&aLevelPtr);
1.468 + /**@internalComponent*/
1.469 + TInt HandleResourceChange(TPowerRequest &aRequest, TPropagation aProp, TUint aOriginatorId,
1.470 + const TDesC8& aOriginatorName, DStaticPowerResourceD* aResource);
1.471 +#endif
1.472 +protected:
1.473 + //generic layer function to be called by the PSL
1.474 + DPowerResourceController();
1.475 + void SetDfcQ(TDfcQue* aDfcQ);
1.476 + #ifdef PRM_ENABLE_EXTENDED_VERSION
1.477 + void SetDfcQDependency(TDfcQue* aDfcQ);
1.478 + #endif
1.479 + TInt InitPools(TUint16 aKClients, TUint16 aUClients, TUint16 aNClientLevels, TUint16 aNRequests);
1.480 + /* Lock the resource controller mutex */
1.481 + inline void Lock() { NKern::ThreadEnterCS();
1.482 + Kern::MutexWait(*iResourceMutex); }
1.483 + inline void UnLock() { Kern::MutexSignal(*iResourceMutex);
1.484 + NKern::ThreadLeaveCS();}
1.485 +#ifdef PRM_ENABLE_EXTENDED_VERSION
1.486 + //Default implementation, PSL re-implements these if features supported
1.487 + virtual TInt DoRegisterStaticResourcesDependency(DStaticPowerResourceD**& aStaticResourceDArray, TUint16& aStaticResourceDCount);
1.488 +#endif
1.489 +private:
1.490 + // pure virtual implemented by PSL - to be called by PIL
1.491 + virtual TInt DoInitController()=0;
1.492 + virtual TInt DoRegisterStaticResources(DStaticPowerResource**& aStaticResourceArray, TUint16& aStaticResourceCount)=0;
1.493 + /**@internalComponent*/
1.494 + TInt CheckLevelAndAddClient(SPowerResourceClient* pC, TPowerRequest* Request);
1.495 + static void MsgQFunc(TAny* aPtr);
1.496 + #ifdef PRM_ENABLE_EXTENDED_VERSION
1.497 + static void MsgQDependencyFunc(TAny* aPtr);
1.498 + #endif
1.499 +
1.500 + /**@internalComponent*/
1.501 + void ResourceStateChangeOfClientLevels(SPowerResourceClient* pC);
1.502 + /**@internalComponent*/
1.503 + void HandleMsg(TPowerRequest& aRequest);
1.504 + #ifdef PRM_ENABLE_EXTENDED_VERSION
1.505 + /**@internalComponent*/
1.506 + void HandleDependencyMsg(TPowerRequest& aRequest);
1.507 + #endif
1.508 + /**@internalComponent*/
1.509 + void CompleteRequest(TPowerRequest& aRequest);
1.510 + /**@internalComponent*/
1.511 + void MoveRequestToFreePool(TPowerRequest *aReq);
1.512 + /**@internalComponent*/
1.513 + TInt HandleReservationOfObjects(TPowerRequest& aRequest);
1.514 + /**@internalComponent*/
1.515 + TInt HandleClientRegistration(TPowerRequest& aRequest);
1.516 +#ifdef PRM_ENABLE_EXTENDED_VERSION
1.517 + TInt RegisterDynamicResource(SPowerResourceClient* aClientPtr, DDynamicPowerResource* aPDRes, TUint* aDynamicResourceId);
1.518 + TInt DeregisterDynamicResource(SPowerResourceClient* aClientPtr, TUint aDynamicResourceId, TInt* aPDefLevel);
1.519 + TInt RegisterResourceDependency(SPowerResourceClient* aClientPtr, SResourceDependencyInfo* aInfo1, SResourceDependencyInfo* aInfo2);
1.520 + /**@internalComponent*/
1.521 + void CheckForDependencyLoop(DStaticPowerResourceD* pR, TUint aParentResId, TUint aTargetResId);
1.522 + TInt DeregisterResourceDependency(SPowerResourceClient* aClientPtr, TUint aResId1, TUint aResId2);
1.523 + /**@internalComponent*/
1.524 + TInt HandleDependencyResourceStateChange(SPowerResourceClient* pC, TPowerRequest& aRequest);
1.525 + TInt GetNumDependentsForResource(TUint aResourceId, TUint* aNumResources);
1.526 + TInt GetDependentsIdForResource(TUint aResourceId, TAny* aInfo, TUint* aNumDepResources);
1.527 + TInt HandleResourceRegistration(TPowerRequest& aReq);
1.528 +#endif
1.529 +public:
1.530 + DMutex* iResourceMutex;
1.531 +protected:
1.532 + TDfcQue* iDfcQ;
1.533 + TMessageQue *iMsgQ;
1.534 +#ifdef PRM_ENABLE_EXTENDED_VERSION
1.535 + TDfcQue* iDfcQDependency;
1.536 + TMessageQue* iMsgQDependency;
1.537 + TBool iDfcQDependencyLock;
1.538 +#endif
1.539 +private:
1.540 + DStaticPowerResource** iStaticResourceArray;
1.541 + DResourceCon<SPowerResourceClient> iClientList;
1.542 + DResourceCon<SPowerResourceClient> iUserSideClientList;
1.543 +#ifdef RESOURCE_MANAGER_SIMULATED_PSL
1.544 + RPointerArray<SPowerResourceClient> iCleanList;
1.545 +#endif
1.546 + SPowerResourceClient* iClientPool;
1.547 + SPowerRequest* iRequestPool;
1.548 + SPowerResourceClientLevel* iClientLevelPool;
1.549 + TUint iPowerControllerId; //Stores the ID allocated to PowerController
1.550 + SIdleResourceInfo* iListForIdle;
1.551 + TUint iInitialised;
1.552 + TUint16 iClientCount;
1.553 + TUint16 iUserSideClientCount;
1.554 + TUint16 iClientLevelPoolCount;
1.555 + TUint16 iClientLevelPoolGrowBy;
1.556 + TUint16 iRequestPoolCount;
1.557 + TUint16 iRequestPoolGrowBy;
1.558 + TUint16 iStaticResourceArrayEntries; //Number of entries in the array including holes if any.
1.559 + TUint16 iStaticResourceCount; //Actual number of static resources registered (valid entries).
1.560 + TUint iReserved2; //Reserved for future use
1.561 +#ifdef PRM_ENABLE_EXTENDED_VERSION
1.562 + DResourceCon<DDynamicPowerResource> iDynamicResourceList;
1.563 + DResourceCon<DDynamicPowerResourceD> iDynamicResDependencyList;
1.564 + DStaticPowerResourceD** iStaticResDependencyArray;
1.565 + SPowerResourceClientLevel* iResourceLevelPool;
1.566 + TUint16 iResourceLevelPoolCount;
1.567 + TUint16 iStaticResDependencyCount;
1.568 + TUint16 iDynamicResourceCount;
1.569 + TUint8 iDynamicResDependencyCount;
1.570 + TUint8 iSpare2;
1.571 + TUint iReserved3; //Reserved for future use.
1.572 +#endif
1.573 + };
1.574 +
1.575 +/**
1.576 +@publishedPartner
1.577 +@prototype 9.5
1.578 +power level of client in a shared resource
1.579 +*/
1.580 +struct SPowerResourceClientLevel : public SDblQueLink
1.581 + {
1.582 + TUint iClientId;
1.583 + TUint iResourceId;
1.584 + TInt iLevel;
1.585 + SPowerResourceClientLevel* iNextInList;
1.586 + };
1.587 +
1.588 +/**
1.589 +@internalComponent
1.590 +@prototype 9.5
1.591 +respresent client in resource manager
1.592 +*/
1.593 +struct SPowerResourceClient
1.594 + {
1.595 + TUint iClientId;
1.596 + const TDesC8* iName;
1.597 + SPowerResourceClient* iNextInList;
1.598 + SPowerResourceClientLevel* iLevelList;
1.599 + DPowerResourceNotification* iNotificationList;
1.600 + TUint8 iReservedCl;
1.601 + TUint8 iReservedRm;
1.602 + TUint8 iPendingReqCount;
1.603 + TUint8 iUnderFlowRmCount;
1.604 + TUint8 iUnderFlowClCount;
1.605 + TUint8 iDynamicResCount; //Counter for dynamic resource registered by the client. Used only in extended version
1.606 + TUint8 iSpare1;
1.607 + TUint8 iSpare2;
1.608 + union
1.609 + {
1.610 + TUint iThreadId;
1.611 + TAny* iSpare3;
1.612 + };
1.613 + };
1.614 +
1.615 +/**
1.616 +@publishedPartner
1.617 +@prototype 9.5
1.618 +represents a request inside the resource manager
1.619 +*/
1.620 +struct TPowerRequest : public TThreadMessage
1.621 + {
1.622 + /** requests can either be to get the resource value or to change the resource value*/
1.623 + enum TReqType {EGet, EChange, ESetDefaultLevel, ERegisterKernelClient, ERegisterUsersideClient, EAllocReserve,
1.624 + ERegisterDynamicResource };
1.625 + /** @return thread's own message and turn into a power request. Used for sync/instant calls*/
1.626 + inline static TPowerRequest& Get()
1.627 + {return (TPowerRequest&)Kern::Message();}
1.628 + /** @return type of request get or set */
1.629 + inline TReqType& ReqType() // one of TReqType
1.630 + {return *(TReqType*)&iValue;}
1.631 + /** @return resource id which is being requested*/
1.632 + inline TUint& ResourceId()
1.633 + {return *(TUint*)&iArg[0];}
1.634 + /** @return id of client making request (only valid on change requests)*/
1.635 + inline TInt& ClientId()
1.636 + {return *(TInt*)&iArg[1];}
1.637 + /**
1.638 + On resource state change operations the PIL sets this field with the required level before
1.639 + invoking the DoRequest(..) function; on return from DoRequest(..) function the PSL sets this field
1.640 + with the real state of the resource to be cached by the PIL.On resource state read operations PSL
1.641 + sets it with the level read.
1.642 + */
1.643 + inline TInt& Level()
1.644 + {return *(TInt*)&iArg[2];}
1.645 + /** @return pointer the resource being requested */
1.646 + inline DStaticPowerResource*& Resource()
1.647 + {return *(DStaticPowerResource**)&iArg[3];}
1.648 + /** @return pointer to resource callback structure, used for async requests */
1.649 + inline TPowerResourceCb*& ResourceCb()
1.650 + {return *(TPowerResourceCb**)&iArg[4];}
1.651 + /** @return return code of resource's DoRequest function when request has been processed */
1.652 + inline TInt& ReturnCode()
1.653 + {return *(TInt*)&iArg[5];}
1.654 + /** @return return ETrue if a change is required on a shared resource */
1.655 + inline TBool& RequiresChange()
1.656 + {return *(TInt*)&iArg[6];}
1.657 + /** @return number of client level objects requested by a client to reserve */
1.658 + inline TInt& ClientLevelCount()
1.659 + {return *(TInt*)&iArg[7];}
1.660 + /** @return number of request objects requested by a client to reserve */
1.661 + inline TInt& RequestCount()
1.662 + {return *(TInt*)&iArg[8];}
1.663 + };
1.664 +
1.665 +/**
1.666 +@internalComponent
1.667 +@prototype 9.5
1.668 +*/
1.669 +struct SPowerRequest
1.670 + {
1.671 + TPowerRequest iRequest;
1.672 + SPowerRequest* iNext;
1.673 + };
1.674 +
1.675 +/**
1.676 +@publishedPartner
1.677 +@prototype 9.5
1.678 +Structure representing resource information used for Idle power management
1.679 +*/
1.680 +struct SIdleResourceInfo
1.681 + {
1.682 + TUint iResourceId;
1.683 + TInt iLevelOwnerId; //Owner of the resource.
1.684 + TInt iCurrentLevel; //Cached resource state
1.685 + TInt iReserved1; //Reserved for future use.
1.686 + TInt iReserved2; //Reserved for future use.
1.687 + TInt iReserved3; //Reserved for future use.
1.688 + };
1.689 +
1.690 +#include <drivers/resourcecontrol.inl>
1.691 +
1.692 +#endif //__RESOURCECONTROL_H__
1.693 +
1.694 +