sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32\include\drivers\resourcecontrol.h sl@0: // sl@0: // WARNING: This file contains some APIs which are internal and are subject sl@0: // to change without notice. Such APIs should therefore not be used sl@0: // outside the Kernel and Hardware Services package. sl@0: // sl@0: sl@0: #ifndef __RESOURCECONTROL_H__ sl@0: #define __RESOURCECONTROL_H__ sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #define PRM_CONTROLLER sl@0: #ifndef PRM_ENABLE_EXTENDED_VERSION sl@0: #include sl@0: #else sl@0: #include sl@0: #endif sl@0: #include sl@0: sl@0: /** #defines for client bit masks */ sl@0: #define ID_INDEX_BIT_MASK 0x3FFF /* bit 0 -13 */ sl@0: #define USER_SIDE_CLIENT_BIT_MASK 0x4000 //Bit 14 sl@0: #define CLIENT_THREAD_RELATIVE_BIT_MASK 0x80000000 //Bit 31 sl@0: #define INSTANCE_COUNT_BIT_MASK 0x1FFF //13 Bits sl@0: #define INSTANCE_COUNT_POS 18 sl@0: #define CLIENT_POWER_CONTROLLER_BIT_MASK 0x8000 //Bit 15 sl@0: /** Bit to indicate valid post boot level in resource */ sl@0: #define SET_VALID_POST_BOOT_LEVEL 0x8000 //Bit 15 sl@0: sl@0: #define RESOURCE_NOT_IN_OPERATION 0x1 sl@0: #define PRM_DYNAMIC_RESOURCE_INITIAL_SIZE 2 sl@0: sl@0: #define PRM_STATIC_RESOURCE 0x0 sl@0: #define PRM_STATIC_DEPENDENCY_RESOURCE 0x1 sl@0: #define PRM_DYNAMIC_RESOURCE 0x2 sl@0: #define PRM_DYNAMIC_DEPENDENCY_RESOURCE 0x3 sl@0: #define RESOURCE_BIT_IN_ID_CHECK 16 sl@0: sl@0: sl@0: static const TInt KMaxResourceNameLength=0x20; //Maximum allowable resource length is 32 characters. sl@0: static const TInt KMaxClientNameLength=0x20; //Maximum allowable client length is 32 characters. sl@0: sl@0: sl@0: _LIT8(KPowerController, "PowerController"); sl@0: _LIT8(KDfcThread1Name, "DfcThread1"); sl@0: _LIT8(KDfcThread0Name, "DfcThread0"); sl@0: _LIT8(KNullThreadName, "Null"); sl@0: _LIT8(KNoClient, "NoClient"); sl@0: _LIT8(KParentResource, "ParentResource"); sl@0: /** Macro to check the context of client calling RM API. sl@0: Panics if it is called from ISR, IDFC, NULL thread or DFC thread1 */ sl@0: #ifdef DEBUG_VERSION sl@0: #define CHECK_CONTEXT(t) \ sl@0: __ASSERT_ALWAYS(NKern::CurrentContext() == NKern::EThread, Panic(ECalledFromIsr)); \ sl@0: const TDesC8* pDfc1 = &KDfcThread1Name; \ sl@0: if(!pDfc1->Compare(*(TDesC8*)t.iName)) \ sl@0: Panic(ECalledFromDfcThread1); \ sl@0: const TDesC8* pNull = &KNullThreadName; \ sl@0: if(!pNull->Compare(*(TDesC8*)t.iName)) \ sl@0: Panic(ECalledFromNullThread); sl@0: #else sl@0: #define CHECK_CONTEXT(t) sl@0: #endif sl@0: sl@0: /** Macro to unlock and return */ sl@0: #define UNLOCK_RETURN(retval) \ sl@0: { \ sl@0: UnLock(); \ sl@0: return(retval); \ sl@0: } sl@0: sl@0: /** Macro to push the item into the specified list. Item are pushed to the head of the list. */ sl@0: #define LIST_PUSH(list,item,link) \ sl@0: { \ sl@0: (item)->link = (list); \ sl@0: (list) = (item); \ sl@0: } sl@0: sl@0: /** Macro to pop the item from the specified list. Item are poped from the head of the list. */ sl@0: #define LIST_POP(list,item,link) \ sl@0: { \ sl@0: (item) = (list); \ sl@0: if ((item)) \ sl@0: { \ sl@0: (list) = (item)->link; \ sl@0: (item)->link = NULL; \ sl@0: } \ sl@0: } sl@0: sl@0: /** Macro to remove the item from the list. */ sl@0: #define LIST_REMOVE(list,item,link,className) \ sl@0: if (list) \ sl@0: { \ sl@0: className* current = (list); \ sl@0: if (current==(item)) \ sl@0: { \ sl@0: (list) = (item)->link; \ sl@0: (item)->link = NULL; \ sl@0: } \ sl@0: else \ sl@0: { \ sl@0: className* next = current->link; \ sl@0: while (next) \ sl@0: { \ sl@0: if ((item)==next) \ sl@0: { \ sl@0: current->link=next->link; \ sl@0: next->link = NULL; \ sl@0: break; \ sl@0: } \ sl@0: current = next; \ sl@0: next = next->link; \ sl@0: } \ sl@0: } \ sl@0: } sl@0: sl@0: sl@0: /* Macro to add dynamic resource to appropriate containers. Used only in extended version */ sl@0: #define ADD_TO_RESOURCE_CONTAINER(list, res, resId, resIdCount) \ sl@0: { \ sl@0: TUint16 growBy = (list).GrowBy(); \ sl@0: if(!growBy) \ sl@0: (list).Initialise((TUint16)PRM_DYNAMIC_RESOURCE_INITIAL_SIZE); \ sl@0: if((list).Add(res, resId) == KErrNoMemory) \ sl@0: { \ sl@0: TInt r = (list).ReSize(growBy); \ sl@0: if(r != KErrNone) \ sl@0: return r; \ sl@0: (list).Add(res, resId); \ sl@0: } \ sl@0: res->iResourceId |= resId; \ sl@0: resId = res->iResourceId; \ sl@0: resIdCount++; \ sl@0: } sl@0: sl@0: /* Macro to get the resource from appropriate list. Used only in extended version */ sl@0: #define GET_RESOURCE_FROM_LIST(resId, res) \ sl@0: { \ sl@0: switch((resId >> RESOURCE_BIT_IN_ID_CHECK) & 0x3) \ sl@0: { \ sl@0: case PRM_STATIC_RESOURCE: \ sl@0: if(resId > iStaticResourceArrayEntries) \ sl@0: UNLOCK_RETURN(KErrNotFound); \ sl@0: res = iStaticResourceArray[resId - 1]; \ sl@0: if(!res) \ sl@0: UNLOCK_RETURN(KErrNotFound); \ sl@0: break; \ sl@0: case PRM_STATIC_DEPENDENCY_RESOURCE: \ sl@0: if((TUint16)(resId & ID_INDEX_BIT_MASK) > iStaticResDependencyCount) \ sl@0: UNLOCK_RETURN(KErrNotFound); \ sl@0: res = iStaticResDependencyArray[(TUint16)(resId & ID_INDEX_BIT_MASK) - 1]; \ sl@0: break; \ sl@0: case PRM_DYNAMIC_RESOURCE: \ sl@0: res = iDynamicResourceList[(TUint16)(resId & ID_INDEX_BIT_MASK)]; \ sl@0: if(!res) \ sl@0: UNLOCK_RETURN(KErrNotFound); \ sl@0: break; \ sl@0: case PRM_DYNAMIC_DEPENDENCY_RESOURCE: \ sl@0: res = iDynamicResDependencyList[(TUint16)(resId & ID_INDEX_BIT_MASK)]; \ sl@0: if(!res) \ sl@0: UNLOCK_RETURN(KErrNotFound); \ sl@0: break; \ sl@0: default: \ sl@0: UNLOCK_RETURN(KErrArgument); \ sl@0: } \ sl@0: } sl@0: sl@0: /**Macro to get the client from appropriate client list based on bit 14 of client ID. sl@0: If the client is registered as thread relative, then check is made to make sure sl@0: it is called from the same thread. */ sl@0: #define VALIDATE_CLIENT(t) \ sl@0: if(aClientId & USER_SIDE_CLIENT_BIT_MASK) \ sl@0: pC = iUserSideClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)]; \ sl@0: else \ sl@0: pC = iClientList[(TUint16)(aClientId & ID_INDEX_BIT_MASK)]; \ sl@0: if(!pC) \ sl@0: { \ sl@0: __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID not Found")); \ sl@0: UNLOCK_RETURN(KErrAccessDenied); \ sl@0: } \ sl@0: if(pC->iClientId != aClientId) \ sl@0: { \ sl@0: __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID does not match")); \ sl@0: UNLOCK_RETURN(KErrAccessDenied); \ sl@0: } \ sl@0: if(pC->iClientId & CLIENT_THREAD_RELATIVE_BIT_MASK) \ sl@0: { \ sl@0: if(pC->iThreadId != t.iId) \ sl@0: { \ sl@0: __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client not called from thread context(Thread Relative)")); \ sl@0: UNLOCK_RETURN(KErrAccessDenied); \ sl@0: } \ sl@0: } sl@0: sl@0: /** Macro to get the target client from appropriate client list based on bit 14 of client ID. */ sl@0: #define GET_TARGET_CLIENT() \ sl@0: if(aTargetClientId & USER_SIDE_CLIENT_BIT_MASK) \ sl@0: pC = iUserSideClientList[(TUint16)(aTargetClientId & ID_INDEX_BIT_MASK)]; \ sl@0: else \ sl@0: pC = iClientList[(TUint16)(aTargetClientId & ID_INDEX_BIT_MASK)]; \ sl@0: if(!pC) \ sl@0: { \ sl@0: __KTRACE_OPT(KRESMANAGER, Kern::Printf("Target Client ID not found")); \ sl@0: UNLOCK_RETURN(KErrNotFound); \ sl@0: } \ sl@0: if(pC->iClientId != aTargetClientId) \ sl@0: { \ sl@0: __KTRACE_OPT(KRESMANAGER, Kern::Printf("Client ID does not match")); \ sl@0: UNLOCK_RETURN(KErrNotFound); \ sl@0: } sl@0: sl@0: /* Macro definition for entry point of Power Resource Controller */ sl@0: #define DECLARE_RESOURCE_MANAGER_EXTENSION(TheController) \ sl@0: TDfc* resourceInitDfc = NULL; \ sl@0: static void ResourceInit(TAny* aController) \ sl@0: { \ sl@0: TInt aReason = NKern::EThread; \ sl@0: PRM_BOOTING_TRACE \ sl@0: ((DPowerResourceController*)aController)->InitResources(); \ sl@0: delete resourceInitDfc; \ sl@0: return; \ sl@0: } \ sl@0: void CreateController(); \ sl@0: GLDEF_C TInt KernelModuleEntry(TInt aReason) \ sl@0: { \ sl@0: if(aReason==KModuleEntryReasonVariantInit0) \ sl@0: { \ sl@0: __KTRACE_OPT(KBOOT, Kern::Printf("Create Resource Controller")); \ sl@0: CreateController(); \ sl@0: return KErrNone; \ sl@0: } \ sl@0: if (aReason==KModuleEntryReasonExtensionInit0) \ sl@0: return KExtensionMaximumPriority; \ sl@0: if (aReason!=KModuleEntryReasonExtensionInit1) \ sl@0: return KErrArgument; \ sl@0: PRM_BOOTING_TRACE \ sl@0: __KTRACE_OPT(KBOOT, Kern::Printf("Initialise Resource Controller")); \ sl@0: TInt r = KErrNone; \ sl@0: r = DPowerResourceController::InitController(); \ sl@0: if(r != KErrNone) \ sl@0: return r; \ sl@0: __KTRACE_OPT(KBOOT, Kern::Printf("Create PDD and queue ResourceInit DFC")); \ sl@0: DResConPddFactory* device = new DResConPddFactory; \ sl@0: if(!device) \ sl@0: return KErrNoMemory; \ sl@0: r = Kern::InstallPhysicalDevice(device); \ sl@0: if(r != KErrNone) \ sl@0: return r; \ sl@0: resourceInitDfc = new TDfc(&ResourceInit,(TAny*)&TheController,Kern::SvMsgQue(),KMaxDfcPriority-1); \ sl@0: if(!resourceInitDfc) \ sl@0: return KErrNoMemory; \ sl@0: resourceInitDfc->Enque(); \ sl@0: return KErrNone; \ sl@0: } \ sl@0: GLDEF_C void CreateController() sl@0: sl@0: struct SPowerResourceClient; sl@0: struct TPowerRequest; sl@0: struct SPowerRequest; sl@0: struct SPowerResourceClientLevel; sl@0: struct SIdleResourceInfo; sl@0: class DPowerResourceController; sl@0: sl@0: /** sl@0: @internalComponent sl@0: @prototype 9.5 sl@0: Interface class for Resource Manager sl@0: Functions from PowerResourceManager calls corresponding functions of this sl@0: class which in turn calls Powercontroller functions. sl@0: */ sl@0: class TInterface sl@0: { sl@0: public: sl@0: static TInt RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType=EOwnerProcess); sl@0: static TInt DeRegisterClient(TUint aClientId); sl@0: static TInt GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName); sl@0: static TInt GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId); sl@0: static TInt GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId); sl@0: static TInt GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo); sl@0: static TInt GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources); sl@0: static TInt GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources, TAny* aInfo); sl@0: static TInt GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients); sl@0: static TInt GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients, TAny* aInfo); sl@0: static TInt AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm); sl@0: static TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL); sl@0: static TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId); sl@0: static TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb); sl@0: static TInt CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb); sl@0: static TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN); sl@0: static TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, TInt aThreshold, TBool aDirection); sl@0: static TInt CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN); sl@0: static TInt DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId); sl@0: static DPowerResourceController* GetPowerResourceController(void); sl@0: static TInt ControlIO(TUint aClientId, TUint aFunction, TAny* aParam1, TAny* aParam2, TAny* aParam3); sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: @prototype 9.5 sl@0: Container class to create containers of pointers to clients. sl@0: */ sl@0: template sl@0: class DResourceCon : public DBase sl@0: { sl@0: public: sl@0: inline TInt Initialise(TUint16 aInitialSize); sl@0: inline void Delete(); sl@0: inline T* operator[](TUint16 aIndex); sl@0: inline TInt Remove(T* aObj, TUint16 aIndex); sl@0: inline TInt Add(T* aObj, TUint &aId); sl@0: inline TInt Find(T*& anEntry, TDesC& aName); sl@0: inline TInt ReSize(TUint16 aGrowBy); sl@0: inline TUint16 Count() {return iCount;} sl@0: inline TUint16 Allocd() {return iAllocated;} sl@0: inline TUint16 GrowBy() {return iGrowBy;} sl@0: private: sl@0: TUint16 iGrowBy; //Size to grow the size of the array. sl@0: TUint16 iAllocated; //Size of the array sl@0: TUint16 iCount; //Valid entries in the array sl@0: TUint16 iInstanceCount; //FreeCounter incremented whenever an entry is added. sl@0: TUint16 iFreeLoc; //Cached free location in the array sl@0: TUint16 iSpare; sl@0: T** iArray; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: @prototype 9.5 sl@0: Factory class for physical device sl@0: */ sl@0: NONSHARABLE_CLASS(DResConPddFactory) : public DPhysicalDevice sl@0: { sl@0: public: sl@0: /** sl@0: Structure for holding PDD capabilities information sl@0: */ sl@0: class TCaps sl@0: { sl@0: public: sl@0: TVersion iVersion; sl@0: }; sl@0: public: sl@0: DResConPddFactory(); sl@0: virtual TInt Install(); sl@0: virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); sl@0: virtual TInt Validate(TInt aUint, const TDesC8* anInfo, const TVersion& aVer); sl@0: virtual void GetCaps(TDes8& aDes) const; sl@0: inline static TVersion VersionRequired(); sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: @prototype 9.5 sl@0: Interface class for user side resource controller proxy. For each user side channel opened an object of sl@0: this class is created in heap and pointer to resource controller is stored in iController member variable. sl@0: User side resource controller proxy calls the resource controller API's by deferencing the pointer. sl@0: This class is required as when the channel is closed the device driver framework tries to delete sl@0: the object stored in ipdd, because of which it is not possible to pass the controller pointer directly. sl@0: */ sl@0: class DUserSideProxyInterface: public DBase sl@0: { sl@0: public: sl@0: DPowerResourceController *iController; sl@0: }; sl@0: sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @prototype 9.5 sl@0: resource manager implementation base class sl@0: */ sl@0: NONSHARABLE_CLASS (DPowerResourceController) : public DBase sl@0: { sl@0: public: sl@0: TInt RegisterClient(TUint& aClientId, const TDesC8& aName, TOwnerType aType=EOwnerProcess); sl@0: TInt DeRegisterClient(TUint aClientId); sl@0: virtual TInt GetClientName(TUint aClientId, TUint aTargetClientId, TDes8& aName); sl@0: virtual TInt GetClientId(TUint aClientId, TDesC8& aClientName, TUint& aTargetClientId); sl@0: virtual TInt GetResourceId(TUint aClientId, TDesC8& aResourceName, TUint& aResourceId); sl@0: virtual TInt GetResourceInfo(TUint aClientId, TUint aResourceId, TAny* aInfo); sl@0: virtual TInt GetNumResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources); sl@0: virtual TInt GetInfoOnResourcesInUseByClient(TUint aClientId, TUint aTargetClientId, TUint& aNumResources, TAny* aInfo); sl@0: virtual TInt GetNumClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients); sl@0: virtual TInt GetInfoOnClientsUsingResource(TUint aClientId, TUint aResourceId, TUint& aNumClients, TAny* aInfo); sl@0: virtual TInt AllocReserve(TUint aClientId, TUint8 aNumCl, TUint8 aNumRm); sl@0: virtual TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL); sl@0: virtual TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId); sl@0: virtual TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb); sl@0: virtual TInt CancelAsyncRequestCallBack(TUint aClientId, TUint aResourceId, TPowerResourceCb& aCb); sl@0: virtual TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN); sl@0: virtual TInt RequestNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN, TInt aThreshold, TBool aDirection); sl@0: virtual TInt CancelNotification(TUint aClientId, TUint aResourceId, DPowerResourceNotification& aN); sl@0: virtual TInt DeRegisterClientLevelFromResource(TUint aClientId, TUint aResourceId); sl@0: public: sl@0: enum TResConPanic sl@0: { sl@0: ECalledFromDfcThread0 = 0, sl@0: ECalledFromIsr = 1, sl@0: ECalledFromNullThread = 2, sl@0: ECalledFromDfcThread1 = 3, sl@0: EClientHasPendingAsyncRequest = 4, sl@0: EClientHasNotificationObject = 5, sl@0: EControllerAlreadyExists = 6, sl@0: ECustomFunctionNotSet = 7, sl@0: EClientIdNotInClientLevelList = 8, sl@0: ENoMemToCreatePowerControllerClient = 9, sl@0: EResourceNameExceedsLimit = 10, sl@0: EObjectNotFoundInList = 11 sl@0: }; sl@0: #ifdef PRM_ENABLE_EXTENDED_VERSION sl@0: enum TExtendedResConPanic sl@0: { sl@0: EClosedLoopDependencies = EObjectNotFoundInList + 2, //13 sl@0: ERegisteringNonDependentStaticResource = 14, sl@0: EClientHasDynamicResourceRegistered = 15, sl@0: EDynamicResourceStillRegistered = 16, sl@0: ERegisteringDependentStaticResourceWithHoles = 17 sl@0: }; sl@0: #endif sl@0: enum TResConStartSequence sl@0: { sl@0: EResConCreated, sl@0: EResConInitialised, sl@0: EResConStartupCompleted sl@0: }; sl@0: //early initialization sl@0: IMPORT_C static TInt InitController(); sl@0: TInt InitResources(); sl@0: //request a post-boot level for the resource sl@0: IMPORT_C static TInt PostBootLevel(TUint aResId, TInt aLevel); sl@0: //request registration of static resource sl@0: IMPORT_C static TInt RegisterStaticResource(TUint aClientId, DStaticPowerResource* pR); sl@0: //request registration of group/array of static resources sl@0: IMPORT_C static TInt RegisterArrayOfStaticResources(TUint aClientId, DStaticPowerResource**& aStaticResourceArray, TUint aResCount); sl@0: //registration for proxy client sl@0: virtual TInt RegisterProxyClient(TUint& aProxyId, const TDesC8& aName); sl@0: virtual TInt DeregisterProxyClient(TUint aClientId); sl@0: //register list of resources whose state matter to Idle sl@0: virtual TInt RegisterResourcesForIdle(TInt aPowerControllerId, TUint aNumResources, TPtr* aBuf); sl@0: static void Panic(TUint8 aPanic); sl@0: virtual TInt GetInterface(TUint aClientId, TUint aInterfaceId, TAny* aParam1, TAny* aParam2, TAny* aParam3); sl@0: virtual ~DPowerResourceController(); sl@0: /**@internalComponent*/ sl@0: void CompleteNotifications(TInt aClientId, DStaticPowerResource* aResource, TInt aState, TInt aReturnCode, TInt aLevelOwnerId, TBool aLock = ETrue); sl@0: #ifdef PRM_ENABLE_EXTENDED_VERSION sl@0: /**@internalComponent*/ sl@0: TInt ReserveClientLevelPoolCount(TUint16 aCount); sl@0: /**@internalComponent*/ sl@0: void RemoveClientLevelFromPool(SPowerResourceClientLevel *&aLevelPtr); sl@0: /**@internalComponent*/ sl@0: TInt HandleResourceChange(TPowerRequest &aRequest, TPropagation aProp, TUint aOriginatorId, sl@0: const TDesC8& aOriginatorName, DStaticPowerResourceD* aResource); sl@0: #endif sl@0: protected: sl@0: //generic layer function to be called by the PSL sl@0: DPowerResourceController(); sl@0: void SetDfcQ(TDfcQue* aDfcQ); sl@0: #ifdef PRM_ENABLE_EXTENDED_VERSION sl@0: void SetDfcQDependency(TDfcQue* aDfcQ); sl@0: #endif sl@0: TInt InitPools(TUint16 aKClients, TUint16 aUClients, TUint16 aNClientLevels, TUint16 aNRequests); sl@0: /* Lock the resource controller mutex */ sl@0: inline void Lock() { NKern::ThreadEnterCS(); sl@0: Kern::MutexWait(*iResourceMutex); } sl@0: inline void UnLock() { Kern::MutexSignal(*iResourceMutex); sl@0: NKern::ThreadLeaveCS();} sl@0: #ifdef PRM_ENABLE_EXTENDED_VERSION sl@0: //Default implementation, PSL re-implements these if features supported sl@0: virtual TInt DoRegisterStaticResourcesDependency(DStaticPowerResourceD**& aStaticResourceDArray, TUint16& aStaticResourceDCount); sl@0: #endif sl@0: private: sl@0: // pure virtual implemented by PSL - to be called by PIL sl@0: virtual TInt DoInitController()=0; sl@0: virtual TInt DoRegisterStaticResources(DStaticPowerResource**& aStaticResourceArray, TUint16& aStaticResourceCount)=0; sl@0: /**@internalComponent*/ sl@0: TInt CheckLevelAndAddClient(SPowerResourceClient* pC, TPowerRequest* Request); sl@0: static void MsgQFunc(TAny* aPtr); sl@0: #ifdef PRM_ENABLE_EXTENDED_VERSION sl@0: static void MsgQDependencyFunc(TAny* aPtr); sl@0: #endif sl@0: sl@0: /**@internalComponent*/ sl@0: void ResourceStateChangeOfClientLevels(SPowerResourceClient* pC); sl@0: /**@internalComponent*/ sl@0: void HandleMsg(TPowerRequest& aRequest); sl@0: #ifdef PRM_ENABLE_EXTENDED_VERSION sl@0: /**@internalComponent*/ sl@0: void HandleDependencyMsg(TPowerRequest& aRequest); sl@0: #endif sl@0: /**@internalComponent*/ sl@0: void CompleteRequest(TPowerRequest& aRequest); sl@0: /**@internalComponent*/ sl@0: void MoveRequestToFreePool(TPowerRequest *aReq); sl@0: /**@internalComponent*/ sl@0: TInt HandleReservationOfObjects(TPowerRequest& aRequest); sl@0: /**@internalComponent*/ sl@0: TInt HandleClientRegistration(TPowerRequest& aRequest); sl@0: #ifdef PRM_ENABLE_EXTENDED_VERSION sl@0: TInt RegisterDynamicResource(SPowerResourceClient* aClientPtr, DDynamicPowerResource* aPDRes, TUint* aDynamicResourceId); sl@0: TInt DeregisterDynamicResource(SPowerResourceClient* aClientPtr, TUint aDynamicResourceId, TInt* aPDefLevel); sl@0: TInt RegisterResourceDependency(SPowerResourceClient* aClientPtr, SResourceDependencyInfo* aInfo1, SResourceDependencyInfo* aInfo2); sl@0: /**@internalComponent*/ sl@0: void CheckForDependencyLoop(DStaticPowerResourceD* pR, TUint aParentResId, TUint aTargetResId); sl@0: TInt DeregisterResourceDependency(SPowerResourceClient* aClientPtr, TUint aResId1, TUint aResId2); sl@0: /**@internalComponent*/ sl@0: TInt HandleDependencyResourceStateChange(SPowerResourceClient* pC, TPowerRequest& aRequest); sl@0: TInt GetNumDependentsForResource(TUint aResourceId, TUint* aNumResources); sl@0: TInt GetDependentsIdForResource(TUint aResourceId, TAny* aInfo, TUint* aNumDepResources); sl@0: TInt HandleResourceRegistration(TPowerRequest& aReq); sl@0: #endif sl@0: public: sl@0: DMutex* iResourceMutex; sl@0: protected: sl@0: TDfcQue* iDfcQ; sl@0: TMessageQue *iMsgQ; sl@0: #ifdef PRM_ENABLE_EXTENDED_VERSION sl@0: TDfcQue* iDfcQDependency; sl@0: TMessageQue* iMsgQDependency; sl@0: TBool iDfcQDependencyLock; sl@0: #endif sl@0: private: sl@0: DStaticPowerResource** iStaticResourceArray; sl@0: DResourceCon iClientList; sl@0: DResourceCon iUserSideClientList; sl@0: #ifdef RESOURCE_MANAGER_SIMULATED_PSL sl@0: RPointerArray iCleanList; sl@0: #endif sl@0: SPowerResourceClient* iClientPool; sl@0: SPowerRequest* iRequestPool; sl@0: SPowerResourceClientLevel* iClientLevelPool; sl@0: TUint iPowerControllerId; //Stores the ID allocated to PowerController sl@0: SIdleResourceInfo* iListForIdle; sl@0: TUint iInitialised; sl@0: TUint16 iClientCount; sl@0: TUint16 iUserSideClientCount; sl@0: TUint16 iClientLevelPoolCount; sl@0: TUint16 iClientLevelPoolGrowBy; sl@0: TUint16 iRequestPoolCount; sl@0: TUint16 iRequestPoolGrowBy; sl@0: TUint16 iStaticResourceArrayEntries; //Number of entries in the array including holes if any. sl@0: TUint16 iStaticResourceCount; //Actual number of static resources registered (valid entries). sl@0: TUint iReserved2; //Reserved for future use sl@0: #ifdef PRM_ENABLE_EXTENDED_VERSION sl@0: DResourceCon iDynamicResourceList; sl@0: DResourceCon iDynamicResDependencyList; sl@0: DStaticPowerResourceD** iStaticResDependencyArray; sl@0: SPowerResourceClientLevel* iResourceLevelPool; sl@0: TUint16 iResourceLevelPoolCount; sl@0: TUint16 iStaticResDependencyCount; sl@0: TUint16 iDynamicResourceCount; sl@0: TUint8 iDynamicResDependencyCount; sl@0: TUint8 iSpare2; sl@0: TUint iReserved3; //Reserved for future use. sl@0: #endif sl@0: }; sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @prototype 9.5 sl@0: power level of client in a shared resource sl@0: */ sl@0: struct SPowerResourceClientLevel : public SDblQueLink sl@0: { sl@0: TUint iClientId; sl@0: TUint iResourceId; sl@0: TInt iLevel; sl@0: SPowerResourceClientLevel* iNextInList; sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: @prototype 9.5 sl@0: respresent client in resource manager sl@0: */ sl@0: struct SPowerResourceClient sl@0: { sl@0: TUint iClientId; sl@0: const TDesC8* iName; sl@0: SPowerResourceClient* iNextInList; sl@0: SPowerResourceClientLevel* iLevelList; sl@0: DPowerResourceNotification* iNotificationList; sl@0: TUint8 iReservedCl; sl@0: TUint8 iReservedRm; sl@0: TUint8 iPendingReqCount; sl@0: TUint8 iUnderFlowRmCount; sl@0: TUint8 iUnderFlowClCount; sl@0: TUint8 iDynamicResCount; //Counter for dynamic resource registered by the client. Used only in extended version sl@0: TUint8 iSpare1; sl@0: TUint8 iSpare2; sl@0: union sl@0: { sl@0: TUint iThreadId; sl@0: TAny* iSpare3; sl@0: }; sl@0: }; sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @prototype 9.5 sl@0: represents a request inside the resource manager sl@0: */ sl@0: struct TPowerRequest : public TThreadMessage sl@0: { sl@0: /** requests can either be to get the resource value or to change the resource value*/ sl@0: enum TReqType {EGet, EChange, ESetDefaultLevel, ERegisterKernelClient, ERegisterUsersideClient, EAllocReserve, sl@0: ERegisterDynamicResource }; sl@0: /** @return thread's own message and turn into a power request. Used for sync/instant calls*/ sl@0: inline static TPowerRequest& Get() sl@0: {return (TPowerRequest&)Kern::Message();} sl@0: /** @return type of request get or set */ sl@0: inline TReqType& ReqType() // one of TReqType sl@0: {return *(TReqType*)&iValue;} sl@0: /** @return resource id which is being requested*/ sl@0: inline TUint& ResourceId() sl@0: {return *(TUint*)&iArg[0];} sl@0: /** @return id of client making request (only valid on change requests)*/ sl@0: inline TInt& ClientId() sl@0: {return *(TInt*)&iArg[1];} sl@0: /** sl@0: On resource state change operations the PIL sets this field with the required level before sl@0: invoking the DoRequest(..) function; on return from DoRequest(..) function the PSL sets this field sl@0: with the real state of the resource to be cached by the PIL.On resource state read operations PSL sl@0: sets it with the level read. sl@0: */ sl@0: inline TInt& Level() sl@0: {return *(TInt*)&iArg[2];} sl@0: /** @return pointer the resource being requested */ sl@0: inline DStaticPowerResource*& Resource() sl@0: {return *(DStaticPowerResource**)&iArg[3];} sl@0: /** @return pointer to resource callback structure, used for async requests */ sl@0: inline TPowerResourceCb*& ResourceCb() sl@0: {return *(TPowerResourceCb**)&iArg[4];} sl@0: /** @return return code of resource's DoRequest function when request has been processed */ sl@0: inline TInt& ReturnCode() sl@0: {return *(TInt*)&iArg[5];} sl@0: /** @return return ETrue if a change is required on a shared resource */ sl@0: inline TBool& RequiresChange() sl@0: {return *(TInt*)&iArg[6];} sl@0: /** @return number of client level objects requested by a client to reserve */ sl@0: inline TInt& ClientLevelCount() sl@0: {return *(TInt*)&iArg[7];} sl@0: /** @return number of request objects requested by a client to reserve */ sl@0: inline TInt& RequestCount() sl@0: {return *(TInt*)&iArg[8];} sl@0: }; sl@0: sl@0: /** sl@0: @internalComponent sl@0: @prototype 9.5 sl@0: */ sl@0: struct SPowerRequest sl@0: { sl@0: TPowerRequest iRequest; sl@0: SPowerRequest* iNext; sl@0: }; sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @prototype 9.5 sl@0: Structure representing resource information used for Idle power management sl@0: */ sl@0: struct SIdleResourceInfo sl@0: { sl@0: TUint iResourceId; sl@0: TInt iLevelOwnerId; //Owner of the resource. sl@0: TInt iCurrentLevel; //Cached resource state sl@0: TInt iReserved1; //Reserved for future use. sl@0: TInt iReserved2; //Reserved for future use. sl@0: TInt iReserved3; //Reserved for future use. sl@0: }; sl@0: sl@0: #include sl@0: sl@0: #endif //__RESOURCECONTROL_H__ sl@0: sl@0: