First public contribution.
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include <kernel/kernel.h>
17 #include <drivers/resourceman.h>
18 #include "d_prmacctst.h"
19 #ifdef RESOURCE_MANAGER_SIMULATED_PSL
20 #include "../resourceman_psl/rescontrol_psl.h"
21 #endif // RESOURCE_MANAGER_SIMULATED_PSL
23 #define TEST_KERRNONE(x) { TInt _r = (x); if (_r != KErrNone) \
24 Kern::Printf("Test failed: %s line %d error %d", __FILE__, __LINE__, _r); }
25 #define TEST(x) { if (!(x)) Kern::Printf("Test failed: %s line %d", __FILE__, __LINE__); }
27 _LIT(KTestDfcQueBaseName, "PrmIfDfc");
28 const TInt KTestDfcQuePrority = KMaxDfcPriority - 1;
30 //---------------------------------------------------------------------------
32 class DPrmIfDevice : public DLogicalDevice
36 virtual TInt Install();
37 virtual void GetCaps(TDes8& aDes) const;
38 virtual TInt Create(DLogicalChannelBase*& aChannel);
41 //---------------------------------------------------------------------------
43 class DPrmIfChannel : public DLogicalChannel
49 virtual void HandleMsg(TMessageBase* aMsg);
50 virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
52 TInt DoControl(TInt aReqNo, TAny *a1, TAny *a2);
53 TInt DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny *a1, TAny *a2);
57 static TUint KernelExtensionClientId;
64 TUint DPrmIfChannel::KernelExtensionClientId = 0;
66 void TestCallbackFunction(TUint /* aClientId */,
67 TUint /* aResourceId */,
69 TInt /* aLevelOwnerId */,
73 //---------------------------------------------------------------------------
75 DPrmIfDevice::DPrmIfDevice()
79 TInt DPrmIfDevice::Install()
81 return SetName(&KPrmIfLddName);
84 void DPrmIfDevice::GetCaps(TDes8& /* aDes */) const
86 // Not used but required as DLogicalDevice::GetCaps is pure virtual
89 TInt DPrmIfDevice::Create(DLogicalChannelBase*& aChannel)
91 aChannel = new DPrmIfChannel;
92 return aChannel ? KErrNone : KErrNoMemory;
95 //---------------------------------------------------------------------------
97 DPrmIfChannel::DPrmIfChannel()
99 iUserThread = &Kern::CurrentThread();
100 ((DObject*) iUserThread)->Open();
103 DPrmIfChannel::~DPrmIfChannel()
106 ((TDynamicDfcQue*)iDfcQ)->Destroy();
107 // Close our reference on the client thread
108 Kern::SafeClose((DObject*&)iUserThread,NULL);
111 void DPrmIfChannel::HandleMsg(TMessageBase *aMsg)
113 TThreadMessage& m = *(TThreadMessage*) aMsg;
116 if (id == (TInt) ECloseMsg)
118 m.Complete(KErrNone, EFalse);
121 else if (id == KMaxTInt)
124 m.Complete(KErrNone, ETrue);
130 TRequestStatus* pS = (TRequestStatus*) m.Ptr0();
131 TInt r = DoRequest(~id, pS, m.Ptr1(), m.Ptr2());
134 Kern::RequestComplete(iUserThread, pS, r);
136 m.Complete(KErrNone, ETrue);
141 TInt r = DoControl(id, m.Ptr0(), m.Ptr1());
142 if(r != KErrCompletion)
144 m.Complete(r, ETrue);
149 TInt DPrmIfChannel::DoCreate(TInt /* aUnit */, const TDesC8* /* aInfo */, const TVersion& /* aVer */)
151 TDynamicDfcQue* dfcQ;
152 TInt r = Kern::DynamicDfcQCreate(dfcQ, KTestDfcQuePrority, KTestDfcQueBaseName);
164 TInt DPrmIfChannel::DoControl(TInt aReqNo, TAny *a1, TAny *a2)
166 TInt r = KErrNotSupported;
169 case RPrmIf::EControlOpenClient:
173 return KErrAlreadyExists;
175 TBuf8<80> clientName;
176 r = PowerResourceManager::GetClientName((TUint) a1, (TUint) a1, clientName);
179 iClientId = (TUint) a1;
183 case RPrmIf::EControlGetKernelExtClientId:
185 r = Kern::ThreadRawWrite(iUserThread, a1, &KernelExtensionClientId, sizeof(TUint));
190 case RPrmIf::EControlRegisterClient:
194 return KErrAlreadyExists;
196 iClientName = HBuf::New(KNameMaxLength);
197 r = Kern::ThreadDesRead(iUserThread, a1, *iClientName, 0);
203 r = PowerResourceManager::RegisterClient(iClientId, *iClientName);
208 case RPrmIf::EControlDeRegisterClient:
214 r = PowerResourceManager::DeRegisterClient(iClientId);
217 if (iClientId == KernelExtensionClientId)
219 // Set it to 0 so it cannot be re-opened
220 KernelExtensionClientId = 0;
228 case RPrmIf::EControlGetInfoOnResourcesInUseByClient:
235 r = PowerResourceManager::GetNumResourcesInUseByClient(iClientId, (TUint) a1, nores);
244 resinfo = HBuf::New(nores * sizeof(TResInfo));
245 TEST(resinfo != NULL);
250 r = PowerResourceManager::GetInfoOnResourcesInUseByClient(iClientId, (TUint) a1, nores, (TAny*) resinfo);
257 r = Kern::ThreadDesWrite(iUserThread, a2, *resinfo, 0);
264 case RPrmIf::EControlChangeResourceState:
270 r = PowerResourceManager::ChangeResourceState(iClientId, (TUint) a1, (TInt) a2);
274 case RPrmIf::EControlGetResourceState:
282 r = PowerResourceManager::GetResourceState(iClientId, (TUint) a1, EFalse, state, levelowner);
288 r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &state, sizeof(TInt));
293 case RPrmIf::EControlGetResourceStateCached:
301 r = PowerResourceManager::GetResourceState(iClientId, (TUint) a1, ETrue, state, levelowner);
307 r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &state, sizeof(TInt));
312 case RPrmIf::EControlGetLevelOwner:
320 r = PowerResourceManager::GetResourceState(iClientId, (TUint) a1, EFalse, state, levelowner);
326 r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &levelowner, sizeof(TInt));
331 case RPrmIf::EControlGetTotalNumberOfResources:
338 r = PowerResourceManager::GetNumResourcesInUseByClient(iClientId, 0, nores);
344 r = Kern::ThreadRawWrite(iUserThread, a1, (TAny*) &nores, sizeof(TUint));
349 #ifdef PRM_ENABLE_EXTENDED_VERSION
350 case RPrmIf::EControlGetResourceDependencies:
356 // Get the resource information from the PRM
358 r = PowerResourceManager::GetNumDependentsForResource(iClientId, (TUint) a1, numres);
365 // Create a descriptor with the list of dependencies
367 depdes = HBuf::New(sizeof(SResourceDependencyInfo) * numres);
368 TEST(depdes != NULL);
374 TUint numres2 = numres;
375 r = PowerResourceManager::GetDependentsIdForResource(iClientId, (TUint) a1, (TAny*) depdes, numres2);
377 TEST(numres == numres2);
379 // Copy the descriptor contents to the user-side descriptor
380 r = Kern::ThreadDesWrite(iUserThread, a2, *depdes, 0);
385 #endif // PRM_ENABLE_EXTENDED_VERSION
390 TInt DPrmIfChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny *a1, TAny *a2)
392 TInt r = KErrNotSupported;
395 case RPrmIf::ERequestChangeResourceStateAndGetState:
401 TTestResourceStateBuf args;
402 r = Kern::ThreadDesRead(iUserThread, a1, args, 0);
409 NKern::FSSetOwner(&sem, (NThreadBase*) NKern::CurrentThread());
410 TPowerResourceCb cbfn(&TestCallbackFunction, (TAny*) &sem, /*iDfcQ*/ Kern::DfcQue0(), KMaxDfcPriority - 2);
411 // Change the state of the resource (asynchronous call)
412 r = PowerResourceManager::ChangeResourceState(iClientId, args().iResourceId, args().iNewState, &cbfn);
418 // Retrieve the intermediate state of the resource
421 r = PowerResourceManager::GetResourceState(iClientId, args().iResourceId, EFalse, state, levelowner);
427 r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &state, sizeof(TInt));
433 // Wait for the callback function
435 Kern::RequestComplete(iUserThread, aStatus, r);
442 //---------------------------------------------------------------------------
445 // Callback function for Latency Tests
447 void TestCallbackFunction(TUint /* aClientId */,
448 TUint /* aResourceId */,
450 TInt /* aLevelOwnerId */,
458 NKern::FSSignal((NFastSemaphore*) aSem);
462 // This function is called during kernel initialisation. It registers a client
463 // on the PRM in order to take ownership of the Single-User resources before
466 static void InitExtension(TAny*)
470 // Get the overall number of resources
472 r = PowerResourceManager::GetNumResourcesInUseByClient(DPrmIfChannel::KernelExtensionClientId, 0, nores);
479 // Get hold of all of the resources by setting their state to the default level
481 for (i = 0; i < (TInt) nores; i++)
483 TPowerResourceInfoBuf01 res;
485 r = PowerResourceManager::GetResourceInfo(DPrmIfChannel::KernelExtensionClientId, i + 1, (TAny*) &res);
491 r = PowerResourceManager::ChangeResourceState(DPrmIfChannel::KernelExtensionClientId, i + 1, res().iDefaultLevel);
499 r = PowerResourceManager::GetNumResourcesInUseByClient(DPrmIfChannel::KernelExtensionClientId, DPrmIfChannel::KernelExtensionClientId, resinuse);
501 TEST(resinuse == nores);
504 static TDfc InitExtensionDfc(&InitExtension, NULL, Kern::SvMsgQue(), KMaxDfcPriority - 2); // Priority lower than the Resource Controller (KMaxDfcPriority - 1)
506 #ifndef RESOURCE_MANAGER_SIMULATED_PSL
507 _LIT8(KTestKExtClientName, "KEXTC");
508 DECLARE_STANDARD_EXTENSION()
510 // Register the initial PRM client (kernel will crash if this fails)
512 TInt r = PowerResourceManager::RegisterClient(clientid, KTestKExtClientName);
518 DPrmIfChannel::KernelExtensionClientId = clientid;
519 // Queue the DFC call to take control of all the resources
520 InitExtensionDfc.Enque();
524 DECLARE_EXTENSION_LDD()
526 return new DPrmIfDevice;
529 DECLARE_STANDARD_LDD()
531 TInt r = DSimulatedPowerResourceController::CompleteResourceControllerInitialisation();
536 return new DPrmIfDevice;