Update contrib.
1 // Copyright (c) 2008-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.
14 // e32\e32test\demandpaging\d_pagingexample_1_pre.cpp
15 // Demand paging migration example device driver d_pagingexample_1_pre: a DLogicalChannel-dervied
16 // driver, pre-migration
20 #include "d_pagingexample.h"
21 #include <kernel/kernel.h>
22 #include <kernel/kern_priv.h>
24 const TInt KDfcQThreadPriority = 25;
25 const TInt KBufferSize = KMaxTransferSize;
31 class DExampleChannel : public DLogicalChannel
34 typedef RPagingExample::TConfigData TConfigData;
35 typedef RPagingExample::TValueStruct TValueStruct;
39 virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
40 virtual void HandleMsg(TMessageBase* aMsg);
41 TInt DoControl(TInt aFunction, TAny* a1, TAny* a2);
42 TInt DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* a1, TAny* a2);
43 TInt DoCancel(TUint aMask);
47 void SetConfig(const TConfigData&);
48 TInt StartNotify(TRequestStatus* aStatus);
49 TInt StartAsyncGetValue(TInt* aValue, TRequestStatus* aStatus);
50 TInt StartAsyncGetValue2(TInt* aValue1, TInt* aValue2, TRequestStatus* aStatus);
51 TInt StartRead(TAny* aBuffer, TInt aLength, TRequestStatus* aStatus);
52 TInt StartReadDes(TDes8* aDesOut, TRequestStatus* aStatus);
53 TInt StartWrite(TAny* aBuffer, TInt aLength, TRequestStatus* aStatus);
54 TInt StartWriteDes(const TDesC8* aDesIn, TRequestStatus* aStatus);
55 void ReceiveToReadBuffer();
56 void SendFromWriteBuffer();
57 static void AsyncGetValueCompleteDfcFunc(TAny* aPtr);
58 static void AsyncGetValue2CompleteDfcFunc(TAny* aPtr);
59 static void ReceiveCompleteDfcFunc(TAny* aPtr);
60 static void SendCompleteDfcFunc(TAny* aPtr);
61 void CompleteNotify();
62 void CompleteAsyncGetValue();
63 void CompleteAsyncGetValue2();
67 TDynamicDfcQue* iDynamicDfcQ;
72 TRequestStatus* iNotifyStatus;
75 TRequestStatus* iAsyncGetValueStatus;
76 TInt* iAsyncGetValueDest;
77 NTimer iAsyncGetValueTimer;
78 TDfc iAsyncGetValueDfc;
81 TRequestStatus* iAsyncGetValue2Status;
82 TInt* iAsyncGetValue2Dest1;
83 TInt* iAsyncGetValue2Dest2;
84 NTimer iAsyncGetValue2Timer;
85 TDfc iAsyncGetValue2Dfc;
88 TRequestStatus* iReadStatus;
93 TDfc iCompleteReadDfc;
96 TRequestStatus* iWriteStatus;
100 const TDesC8* iWriteDes;
101 TDfc iCompleteWriteDfc;
102 TUint8 iBuffer[KBufferSize];
105 DExampleChannel::DExampleChannel() :
106 iAsyncGetValueTimer(NULL, this),
107 iAsyncGetValueDfc(AsyncGetValueCompleteDfcFunc, this, 0),
108 iAsyncGetValue2Timer(NULL, this),
109 iAsyncGetValue2Dfc(AsyncGetValue2CompleteDfcFunc, this, 0),
110 iReadTimer(NULL, this),
111 iCompleteReadDfc(ReceiveCompleteDfcFunc, this, 0),
112 iWriteTimer(NULL, this),
113 iCompleteWriteDfc(SendCompleteDfcFunc, this, 0)
115 iClient = &Kern::CurrentThread();
119 DExampleChannel::~DExampleChannel()
121 Kern::SafeClose((DObject*&)iClient, NULL);
123 iDynamicDfcQ->Destroy();
126 TDfcQue* DExampleChannel::DfcQ()
131 TInt DExampleChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
133 // Existing drivers may use the kernel global DFC queue, but for testing purposes we actually
134 // allocate our own so we can control its realtime state.
135 TInt r = Kern::DynamicDfcQCreate(iDynamicDfcQ, KDfcQThreadPriority, KPagingExample1PreLdd);
138 iDynamicDfcQ->SetRealtimeState(ERealtimeStateWarn);
141 iAsyncGetValueDfc.SetDfcQ(DfcQ());
142 iAsyncGetValue2Dfc.SetDfcQ(DfcQ());
143 iCompleteReadDfc.SetDfcQ(DfcQ());
144 iCompleteWriteDfc.SetDfcQ(DfcQ());
149 void DExampleChannel::HandleMsg(TMessageBase* aMsg)
151 TThreadMessage& m=*(TThreadMessage*)aMsg;
154 if (id==(TInt)ECloseMsg)
157 m.Complete(KErrNone,EFalse);
161 // we only support one client
162 if (m.Client() != iClient)
164 m.Complete(KErrAccessDenied,ETrue);
172 m.Complete(KErrNone,ETrue);
178 TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
179 TInt r=DoRequest(~id,pS,m.Ptr1(),m.Ptr2());
181 Kern::RequestComplete(m.Client(),pS,r);
182 m.Complete(KErrNone,ETrue);
187 TInt r=DoControl(id,m.Ptr0(),m.Ptr1());
192 TInt DExampleChannel::DoControl(TInt aFunction,TAny* a1,TAny* /*a2*/)
197 case RPagingExample::ESetRealtimeState:
198 iDynamicDfcQ->SetRealtimeState(a1 ? ERealtimeStateOn : ERealtimeStateWarn);
201 case RPagingExample::EGetConfig:
202 r = Kern::ThreadRawWrite(iClient, a1, (TAny*)&iConfig, sizeof(TConfigData), iClient);
205 case RPagingExample::ESetConfig:
207 TConfigData newConfig;
208 r = Kern::ThreadRawRead(iClient, a1, &newConfig, sizeof(TConfigData));
210 SetConfig(newConfig);
215 r = KErrNotSupported;
220 TInt DExampleChannel::DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* a1, TAny* a2)
222 TInt r = KErrNotSupported;
225 case RPagingExample::ERequestNotify:
226 r = StartNotify(aStatus);
229 case RPagingExample::ERequestAsyncGetValue:
230 r = StartAsyncGetValue((TInt*)a1, aStatus);
233 case RPagingExample::ERequestAsyncGetValue2:
234 r = StartAsyncGetValue2((TInt*)a1, (TInt*)a2, aStatus);
237 case RPagingExample::ERequestRead:
238 r = StartRead(a1, (TInt)a2, aStatus);
241 case RPagingExample::ERequestReadDes:
242 r = StartReadDes((TDes8*)a1, aStatus);
245 case RPagingExample::ERequestWrite:
246 r = StartWrite(a1, (TInt)a2, aStatus);
249 case RPagingExample::ERequestWriteDes:
250 r = StartWriteDes((TDes8*)a1, aStatus);
256 TInt DExampleChannel::DoCancel(TUint /*aMask*/)
258 if (iAsyncGetValueStatus)
260 iAsyncGetValueTimer.Cancel();
261 iAsyncGetValueDfc.Cancel();
262 Kern::RequestComplete(iClient, iAsyncGetValueStatus, KErrCancel);
265 if (iAsyncGetValue2Status)
267 iAsyncGetValue2Timer.Cancel();
268 iAsyncGetValue2Dfc.Cancel();
269 Kern::RequestComplete(iClient, iAsyncGetValue2Status, KErrCancel);
275 iCompleteReadDfc.Cancel();
276 Kern::RequestComplete(iClient, iReadStatus, KErrCancel);
281 iWriteTimer.Cancel();
282 iCompleteWriteDfc.Cancel();
283 Kern::RequestComplete(iClient, iWriteStatus, KErrCancel);
289 void DExampleChannel::Shutdown()
293 void DExampleChannel::SetConfig(const TConfigData& aNewConfig)
295 iConfig = aNewConfig;
298 TInt DExampleChannel::StartNotify(TRequestStatus* aStatus)
300 iNotifyStatus = aStatus;
301 CompleteNotify(); // example implementation completes the request immediately
305 void DExampleChannel::CompleteNotify()
307 Kern::RequestComplete(iClient, iNotifyStatus, KErrNone);
310 TInt DExampleChannel::StartAsyncGetValue(TInt* aValue, TRequestStatus* aStatus)
312 iAsyncGetValueDest = aValue;
313 iAsyncGetValueStatus = aStatus;
315 // queue a timer to simulate an asynchronous operation
316 iAsyncGetValueTimer.OneShot(KAsyncDelay, iAsyncGetValueDfc);
320 void DExampleChannel::AsyncGetValueCompleteDfcFunc(TAny* aPtr)
322 DExampleChannel* self = (DExampleChannel*)aPtr;
323 self->CompleteAsyncGetValue();
326 void DExampleChannel::CompleteAsyncGetValue()
330 value.iValue2 = _L8("shrt");
331 TInt r = Kern::ThreadRawWrite(iClient, iAsyncGetValueDest, (TAny*)&value, sizeof(TValueStruct), iClient);
332 Kern::RequestComplete(iClient, iAsyncGetValueStatus, r);
335 TInt DExampleChannel::StartAsyncGetValue2(TInt* aValue1, TInt* aValue2, TRequestStatus* aStatus)
337 iAsyncGetValue2Dest1 = aValue1;
338 iAsyncGetValue2Dest2 = aValue2;
339 iAsyncGetValue2Status = aStatus;
341 // queue a timer to simulate an asynchronous operation
342 iAsyncGetValue2Timer.OneShot(KAsyncDelay, iAsyncGetValue2Dfc);
346 void DExampleChannel::AsyncGetValue2CompleteDfcFunc(TAny* aPtr)
348 DExampleChannel* self = (DExampleChannel*)aPtr;
349 self->CompleteAsyncGetValue2();
352 void DExampleChannel::CompleteAsyncGetValue2()
356 TInt r = Kern::ThreadRawWrite(iClient, iAsyncGetValue2Dest1, (TAny*)&value1, sizeof(TInt), iClient);
358 r = Kern::ThreadRawWrite(iClient, iAsyncGetValue2Dest2, (TAny*)&value2, sizeof(TInt), iClient);
359 Kern::RequestComplete(iClient, iAsyncGetValue2Status, r);
362 TInt DExampleChannel::StartRead(TAny* aBuffer, TInt aLength, TRequestStatus* aStatus)
366 if (aLength < 1 || aLength > KBufferSize)
368 iReadStatus = aStatus;
370 iReadLength = aLength;
371 ReceiveToReadBuffer();
375 TInt DExampleChannel::StartReadDes(TDes8* aDesOut, TRequestStatus* aStatus)
379 TInt r = Kern::ThreadGetDesMaxLength(iClient, aDesOut);
383 if (length < 1 || length > KBufferSize)
385 iReadStatus = aStatus;
387 iReadLength = length;
388 ReceiveToReadBuffer();
392 TInt DExampleChannel::StartWrite(TAny* aBuffer, TInt aLength, TRequestStatus* aStatus)
396 if (aLength < 1 || aLength > KBufferSize)
398 iWriteStatus = aStatus;
400 iWriteLength = aLength;
401 SendFromWriteBuffer();
405 TInt DExampleChannel::StartWriteDes(const TDesC8* aDesIn, TRequestStatus* aStatus)
409 TInt r = Kern::ThreadGetDesLength(iClient, aDesIn);
413 if (length < 1 || length > KBufferSize)
415 iWriteStatus = aStatus;
416 iWriteLength = length;
418 SendFromWriteBuffer();
422 void DExampleChannel::ReceiveToReadBuffer()
424 // just queue a timer to simulate an asynchronous receive operation
425 // actually will return the previous contents of the buffer
426 iReadTimer.OneShot(KAsyncDelay, iCompleteReadDfc);
429 void DExampleChannel::SendFromWriteBuffer()
431 // just queue a timer to simulate an asynchronous send operation
432 iWriteTimer.OneShot(KAsyncDelay, iCompleteWriteDfc);
435 void DExampleChannel::ReceiveCompleteDfcFunc(TAny* aPtr)
437 DExampleChannel* self = (DExampleChannel*)aPtr;
438 self->CompleteRead();
441 void DExampleChannel::SendCompleteDfcFunc(TAny* aPtr)
443 DExampleChannel* self = (DExampleChannel*)aPtr;
444 self->CompleteWrite();
447 void DExampleChannel::CompleteRead()
452 r = Kern::ThreadRawWrite(iClient, iReadDest, iBuffer, iReadLength, iClient);
457 TPtrC8 des(iBuffer, iReadLength);
458 r = Kern::ThreadDesWrite(iClient, iReadDes, des, 0, KChunkShiftBy0, iClient);
463 Kern::RequestComplete(iClient, iReadStatus, r);
466 void DExampleChannel::CompleteWrite()
471 r = Kern::ThreadRawRead(iClient, iWriteSrc, iBuffer, iWriteLength);
476 TPtr8 des(iBuffer, iWriteLength);
477 r = Kern::ThreadDesRead(iClient, iWriteDes, des, 0);
482 Kern::RequestComplete(iClient, iWriteStatus, r);
489 class DExampleFactory : public DLogicalDevice
493 virtual TInt Install();
494 virtual void GetCaps(TDes8& aDes) const;
495 virtual TInt Create(DLogicalChannelBase*& aChannel);
498 DExampleFactory::DExampleFactory()
501 iVersion = TVersion(1, 0, 0);
504 TInt DExampleFactory::Install()
506 return SetName(&KPagingExample1PreLdd);
509 void DExampleFactory::GetCaps(TDes8& /*aDes*/) const
511 // not used but required as DLogicalDevice::GetCaps is pure virtual
514 TInt DExampleFactory::Create(DLogicalChannelBase*& aChannel)
516 aChannel = new DExampleChannel;
517 return aChannel ? KErrNone : KErrNoMemory;
520 DECLARE_STANDARD_LDD()
522 return new DExampleFactory;