sl@0: // Copyright (c) 2008-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\e32test\demandpaging\d_pagingexample_1_post.cpp sl@0: // Demand paging migration example device driver d_pagingexample_1_post: a DLogicalChannel-dervied sl@0: // driver, post-migration sl@0: // sl@0: // sl@0: sl@0: #include "d_pagingexample.h" sl@0: #include sl@0: #include sl@0: sl@0: const TInt KDfcQThreadPriority = 25; sl@0: const TInt KBufferSize = KMaxTransferSize; sl@0: sl@0: // sl@0: // Logical channel sl@0: // sl@0: sl@0: class DExampleChannel : public DLogicalChannel sl@0: { sl@0: public: sl@0: typedef RPagingExample::TConfigData TConfigData; sl@0: typedef RPagingExample::TValueStruct TValueStruct; sl@0: public: sl@0: DExampleChannel(); sl@0: ~DExampleChannel(); sl@0: virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); sl@0: virtual TInt SendMsg(TMessageBase* aMsg); sl@0: TInt SendControl(TMessageBase* aMsg); sl@0: TInt SendRequest(TMessageBase* aMsg); sl@0: virtual void HandleMsg(TMessageBase* aMsg); sl@0: TInt DoControl(TInt aFunction, TAny* a1, TAny* a2); sl@0: void DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* a1, TAny* a2); sl@0: TInt DoCancel(TUint aMask); sl@0: private: sl@0: TDfcQue* DfcQ(); sl@0: void Shutdown(); sl@0: void SetConfig(const TConfigData&); sl@0: TInt PreNotify(TRequestStatus* aStatus); sl@0: void StartNotify(); sl@0: TInt PreAsyncGetValue(TInt* aValue, TRequestStatus* aStatus); sl@0: void StartAsyncGetValue(); sl@0: TInt PreAsyncGetValue2(TInt* aValue1, TInt* aValue2, TRequestStatus* aStatus); sl@0: void StartAsyncGetValue2(); sl@0: TInt PreRead(TAny* aBuffer, TInt aLength, TRequestStatus* aStatus); sl@0: void StartRead(); sl@0: TInt PreReadDes(TDes8* aDesOut, TRequestStatus* aStatus); sl@0: void StartReadDes(); sl@0: TInt PreWrite(TAny* aBuffer, TInt aLength, TRequestStatus* aStatus); sl@0: void StartWrite(); sl@0: TInt PreWriteDes(const TDesC8* aDesIn, TRequestStatus* aStatus); sl@0: void StartWriteDes(); sl@0: void ReceiveToReadBuffer(); sl@0: void SendFromWriteBuffer(); sl@0: static void AsyncGetValueCompleteDfcFunc(TAny* aPtr); sl@0: static void AsyncGetValue2CompleteDfcFunc(TAny* aPtr); sl@0: static void ReceiveCompleteDfcFunc(TAny* aPtr); sl@0: static void SendCompleteDfcFunc(TAny* aPtr); sl@0: void CompleteNotify(); sl@0: void CompleteAsyncGetValue(); sl@0: void CompleteAsyncGetValue2(); sl@0: void CompleteRead(); sl@0: void CompleteWrite(); sl@0: private: sl@0: TDynamicDfcQue* iDynamicDfcQ; sl@0: TConfigData iConfig; sl@0: DThread* iClient; sl@0: sl@0: // Notify sl@0: TClientRequest* iNotifyRequest; sl@0: sl@0: // Async get value sl@0: TClientDataRequest* iAsyncGetValueRequest; sl@0: NTimer iAsyncGetValueTimer; sl@0: TDfc iAsyncGetValueDfc; sl@0: sl@0: // Async get value 2 sl@0: TClientDataRequest2* iAsyncGetValue2Request; sl@0: NTimer iAsyncGetValue2Timer; sl@0: TDfc iAsyncGetValue2Dfc; sl@0: sl@0: // Read sl@0: TClientBufferRequest* iReadRequest; sl@0: NTimer iReadTimer; sl@0: TClientBuffer* iClientReadBuffer; sl@0: TDfc iCompleteReadDfc; sl@0: sl@0: // Write sl@0: TClientBufferRequest* iWriteRequest; sl@0: NTimer iWriteTimer; sl@0: TClientBuffer* iClientWriteBuffer; sl@0: TDfc iCompleteWriteDfc; sl@0: TUint8 iBuffer[KBufferSize]; sl@0: }; sl@0: sl@0: DExampleChannel::DExampleChannel() : sl@0: iAsyncGetValueTimer(NULL, this), sl@0: iAsyncGetValueDfc(AsyncGetValueCompleteDfcFunc, this, 0), sl@0: iAsyncGetValue2Timer(NULL, this), sl@0: iAsyncGetValue2Dfc(AsyncGetValue2CompleteDfcFunc, this, 0), sl@0: iReadTimer(NULL, this), sl@0: iCompleteReadDfc(ReceiveCompleteDfcFunc, this, 0), sl@0: iWriteTimer(NULL, this), sl@0: iCompleteWriteDfc(SendCompleteDfcFunc, this, 0) sl@0: { sl@0: iClient = &Kern::CurrentThread(); sl@0: iClient->Open(); sl@0: } sl@0: sl@0: DExampleChannel::~DExampleChannel() sl@0: { sl@0: Kern::SafeClose((DObject*&)iClient, NULL); sl@0: if (iDynamicDfcQ) sl@0: iDynamicDfcQ->Destroy(); sl@0: Kern::DestroyClientRequest(iNotifyRequest); sl@0: Kern::DestroyClientRequest(iAsyncGetValueRequest); sl@0: Kern::DestroyClientRequest(iAsyncGetValue2Request); sl@0: Kern::DestroyClientBufferRequest(iReadRequest); sl@0: Kern::DestroyClientBufferRequest(iWriteRequest); sl@0: } sl@0: sl@0: TDfcQue* DExampleChannel::DfcQ() sl@0: { sl@0: return iDynamicDfcQ; sl@0: } sl@0: sl@0: TInt DExampleChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/) sl@0: { sl@0: TInt r; sl@0: sl@0: r = Kern::CreateClientRequest(iNotifyRequest); sl@0: if (r != KErrNone) sl@0: return r; sl@0: r = Kern::CreateClientDataRequest(iAsyncGetValueRequest); sl@0: if (r != KErrNone) sl@0: return r; sl@0: r = Kern::CreateClientDataRequest2(iAsyncGetValue2Request); sl@0: if (r != KErrNone) sl@0: return r; sl@0: r = Kern::CreateClientBufferRequest(iReadRequest, 1, TClientBufferRequest::EPinVirtual); sl@0: if (r != KErrNone) sl@0: return r; sl@0: r = Kern::CreateClientBufferRequest(iWriteRequest, 1, TClientBufferRequest::EPinVirtual); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // create a dynamic DFC queue, which is used for handling client messages and for our own DFCs sl@0: r = Kern::DynamicDfcQCreate(iDynamicDfcQ, KDfcQThreadPriority, KPagingExample1PostLdd); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // todo: this will be the default anyway sl@0: iDynamicDfcQ->SetRealtimeState(ERealtimeStateOn); sl@0: sl@0: SetDfcQ(DfcQ()); sl@0: iAsyncGetValueDfc.SetDfcQ(DfcQ()); sl@0: iAsyncGetValue2Dfc.SetDfcQ(DfcQ()); sl@0: iCompleteReadDfc.SetDfcQ(DfcQ()); sl@0: iCompleteWriteDfc.SetDfcQ(DfcQ()); sl@0: iMsgQ.Receive(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: // override SendMsg method to allow pinning data in the context of the client thread sl@0: TInt DExampleChannel::SendMsg(TMessageBase* aMsg) sl@0: { sl@0: TThreadMessage& m=*(TThreadMessage*)aMsg; sl@0: TInt id = m.iValue; sl@0: sl@0: // we only support one client sl@0: if (id != (TInt)ECloseMsg && m.Client() != iClient) sl@0: return KErrAccessDenied; sl@0: sl@0: TInt r = KErrNone; sl@0: if (id != (TInt)ECloseMsg && id != KMaxTInt) sl@0: { sl@0: if (id<0) sl@0: { sl@0: TRequestStatus* pS=(TRequestStatus*)m.Ptr0(); sl@0: r = SendRequest(aMsg); sl@0: if (r != KErrNone) sl@0: Kern::RequestComplete(pS,r); sl@0: } sl@0: else sl@0: r = SendControl(aMsg); sl@0: } sl@0: else sl@0: r = DLogicalChannel::SendMsg(aMsg); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: void DExampleChannel::HandleMsg(TMessageBase* aMsg) sl@0: { sl@0: TThreadMessage& m=*(TThreadMessage*)aMsg; sl@0: TInt id=m.iValue; sl@0: sl@0: if (id==(TInt)ECloseMsg) sl@0: { sl@0: Shutdown(); sl@0: m.Complete(KErrNone,EFalse); sl@0: return; sl@0: } sl@0: else if (id==KMaxTInt) sl@0: { sl@0: // DoCancel sl@0: DoCancel(m.Int0()); sl@0: m.Complete(KErrNone,ETrue); sl@0: return; sl@0: } sl@0: else if (id<0) sl@0: { sl@0: // DoRequest sl@0: TRequestStatus* pS=(TRequestStatus*)m.Ptr0(); sl@0: DoRequest(~id,pS,m.Ptr1(),m.Ptr2()); sl@0: m.Complete(KErrNone,ETrue); sl@0: } sl@0: else sl@0: { sl@0: // DoControl sl@0: TInt r=DoControl(id,m.Ptr0(),m.Ptr1()); sl@0: m.Complete(r,ETrue); sl@0: } sl@0: } sl@0: sl@0: TInt DExampleChannel::SendControl(TMessageBase* aMsg) sl@0: { sl@0: TThreadMessage& m=*(TThreadMessage*)aMsg; sl@0: TInt id=m.iValue; sl@0: sl@0: // thread-local copy of configuration data sl@0: TConfigData kernelConfigBuffer; sl@0: TAny* userConfigPtr = m.Ptr0(); sl@0: sl@0: switch (id) sl@0: { sl@0: case RPagingExample::ESetConfig: sl@0: // copy config from client to local buffer in context of client thread sl@0: umemget32(&kernelConfigBuffer, userConfigPtr, sizeof(TConfigData)); sl@0: // update message to point to kernel-side buffer sl@0: m.iArg[0] = &kernelConfigBuffer; sl@0: break; sl@0: sl@0: case RPagingExample::EGetConfig: sl@0: // update message to point to kernel-side buffer sl@0: m.iArg[0] = &kernelConfigBuffer; sl@0: break; sl@0: } sl@0: sl@0: TInt r = DLogicalChannel::SendMsg(aMsg); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: switch (id) sl@0: { sl@0: case RPagingExample::EGetConfig: sl@0: // copy config from local bufferto client in context of client thread sl@0: umemput32(userConfigPtr, &kernelConfigBuffer, sizeof(TConfigData)); sl@0: break; sl@0: } sl@0: sl@0: return r; sl@0: } sl@0: sl@0: TInt DExampleChannel::DoControl(TInt aFunction,TAny* a1,TAny* /*a2*/) sl@0: { sl@0: TInt r = KErrNone; sl@0: TConfigData* configBuffer = (TConfigData*)a1; sl@0: switch (aFunction) sl@0: { sl@0: case RPagingExample::EGetConfig: sl@0: // copy current config into local buffer in context of DFC thread to avoid potential race conditions sl@0: *configBuffer = iConfig; sl@0: break; sl@0: sl@0: case RPagingExample::ESetConfig: sl@0: // set config from copy in local buffer in context of DFC thread to avoid potential race conditions sl@0: SetConfig(*configBuffer); sl@0: break; sl@0: sl@0: default: sl@0: r = KErrNotSupported; sl@0: } sl@0: return r; sl@0: } sl@0: sl@0: TInt DExampleChannel::SendRequest(TMessageBase* aMsg) sl@0: { sl@0: TThreadMessage& m=*(TThreadMessage*)aMsg; sl@0: TInt function = ~m.iValue; sl@0: TRequestStatus* pS=(TRequestStatus*)m.Ptr0(); sl@0: TAny* a1 = m.Ptr1(); sl@0: TAny* a2 = m.Ptr2(); sl@0: sl@0: TInt r = KErrNotSupported; sl@0: switch (function) sl@0: { sl@0: case RPagingExample::ERequestNotify: sl@0: r = PreNotify(pS); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestAsyncGetValue: sl@0: r = PreAsyncGetValue((TInt*)a1, pS); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestAsyncGetValue2: sl@0: r = PreAsyncGetValue2((TInt*)a1, (TInt*)a2, pS); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestRead: sl@0: r = PreRead(a1, (TInt)a2, pS); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestReadDes: sl@0: r = PreReadDes((TDes8*)a1, pS); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestWrite: sl@0: r = PreWrite(a1, (TInt)a2, pS); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestWriteDes: sl@0: r = PreWriteDes((TDes8*)a1, pS); sl@0: break; sl@0: } sl@0: sl@0: if (r == KErrNone) sl@0: r = DLogicalChannel::SendMsg(aMsg); sl@0: return r; sl@0: } sl@0: sl@0: void DExampleChannel::DoRequest(TInt aFunction, TRequestStatus* /*aStatus*/, TAny* /*a1*/, TAny* /*a2*/) sl@0: { sl@0: switch (aFunction) sl@0: { sl@0: case RPagingExample::ERequestNotify: sl@0: StartNotify(); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestAsyncGetValue: sl@0: StartAsyncGetValue(); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestAsyncGetValue2: sl@0: StartAsyncGetValue2(); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestRead: sl@0: StartRead(); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestReadDes: sl@0: StartReadDes(); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestWrite: sl@0: StartWrite(); sl@0: break; sl@0: sl@0: case RPagingExample::ERequestWriteDes: sl@0: StartWriteDes(); sl@0: break; sl@0: sl@0: default: sl@0: __NK_ASSERT_ALWAYS(EFalse); // we already validated the request number sl@0: } sl@0: } sl@0: sl@0: TInt DExampleChannel::DoCancel(TUint /*aMask*/) sl@0: { sl@0: if (iAsyncGetValueRequest->IsReady()) sl@0: { sl@0: iAsyncGetValueTimer.Cancel(); sl@0: iAsyncGetValueDfc.Cancel(); sl@0: Kern::QueueRequestComplete(iClient, iAsyncGetValueRequest, KErrCancel); sl@0: } sl@0: sl@0: if (iAsyncGetValue2Request->IsReady()) sl@0: { sl@0: iAsyncGetValue2Timer.Cancel(); sl@0: iAsyncGetValue2Dfc.Cancel(); sl@0: Kern::QueueRequestComplete(iClient, iAsyncGetValue2Request, KErrCancel); sl@0: } sl@0: sl@0: if (iReadRequest->IsReady()) sl@0: { sl@0: iReadTimer.Cancel(); sl@0: iCompleteReadDfc.Cancel(); sl@0: Kern::QueueBufferRequestComplete(iClient, iReadRequest, KErrCancel); sl@0: } sl@0: sl@0: if (iWriteRequest->IsReady()) sl@0: { sl@0: iWriteTimer.Cancel(); sl@0: iCompleteWriteDfc.Cancel(); sl@0: Kern::QueueBufferRequestComplete(iClient, iWriteRequest, KErrCancel); sl@0: } sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: void DExampleChannel::Shutdown() sl@0: { sl@0: } sl@0: sl@0: void DExampleChannel::SetConfig(const TConfigData& aNewConfig) sl@0: { sl@0: iConfig = aNewConfig; sl@0: } sl@0: sl@0: TInt DExampleChannel::PreNotify(TRequestStatus* aStatus) sl@0: { sl@0: return iNotifyRequest->SetStatus(aStatus); sl@0: } sl@0: sl@0: void DExampleChannel::StartNotify() sl@0: { sl@0: CompleteNotify(); // example implementation completes the request immediately sl@0: } sl@0: sl@0: void DExampleChannel::CompleteNotify() sl@0: { sl@0: Kern::QueueRequestComplete(iClient, iNotifyRequest, KErrNone); sl@0: } sl@0: sl@0: TInt DExampleChannel::PreAsyncGetValue(TInt* aValue, TRequestStatus* aStatus) sl@0: { sl@0: TInt r = iAsyncGetValueRequest->SetStatus(aStatus); sl@0: if (r != KErrNone) sl@0: return r; sl@0: iAsyncGetValueRequest->SetDestPtr(aValue); sl@0: return KErrNone; sl@0: } sl@0: sl@0: void DExampleChannel::StartAsyncGetValue() sl@0: { sl@0: // queue a timer to simulate an asynchronous operation sl@0: iAsyncGetValueTimer.OneShot(KAsyncDelay, iAsyncGetValueDfc); sl@0: } sl@0: sl@0: void DExampleChannel::AsyncGetValueCompleteDfcFunc(TAny* aPtr) sl@0: { sl@0: DExampleChannel* self = (DExampleChannel*)aPtr; sl@0: self->CompleteAsyncGetValue(); sl@0: } sl@0: sl@0: void DExampleChannel::CompleteAsyncGetValue() sl@0: { sl@0: iAsyncGetValueRequest->Data().iValue1 = 1; sl@0: iAsyncGetValueRequest->Data().iValue2 = _L8("shrt"); sl@0: Kern::QueueRequestComplete(iClient, iAsyncGetValueRequest, KErrNone); sl@0: } sl@0: sl@0: TInt DExampleChannel::PreAsyncGetValue2(TInt* aValue1, TInt* aValue2, TRequestStatus* aStatus) sl@0: { sl@0: TInt r = iAsyncGetValue2Request->SetStatus(aStatus); sl@0: if (r != KErrNone) sl@0: return r; sl@0: iAsyncGetValue2Request->SetDestPtr1(aValue1); sl@0: iAsyncGetValue2Request->SetDestPtr2(aValue2); sl@0: return KErrNone; sl@0: } sl@0: sl@0: void DExampleChannel::StartAsyncGetValue2() sl@0: { sl@0: // queue a timer to simulate an asynchronous operation sl@0: iAsyncGetValue2Timer.OneShot(KAsyncDelay, iAsyncGetValue2Dfc); sl@0: } sl@0: sl@0: void DExampleChannel::AsyncGetValue2CompleteDfcFunc(TAny* aPtr) sl@0: { sl@0: DExampleChannel* self = (DExampleChannel*)aPtr; sl@0: self->CompleteAsyncGetValue2(); sl@0: } sl@0: sl@0: void DExampleChannel::CompleteAsyncGetValue2() sl@0: { sl@0: iAsyncGetValue2Request->Data1() = 1; sl@0: iAsyncGetValue2Request->Data2() = 2; sl@0: Kern::QueueRequestComplete(iClient, iAsyncGetValue2Request, KErrNone); sl@0: } sl@0: sl@0: TInt DExampleChannel::PreRead(TAny* aBuffer, TInt aLength, TRequestStatus* aStatus) sl@0: { sl@0: // check length argument first sl@0: if (aLength < 1 || aLength > KBufferSize) sl@0: return KErrArgument; sl@0: sl@0: // start request setup sl@0: TInt r = iReadRequest->StartSetup(aStatus); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // add client buffer, this does pinning in context of client thread sl@0: r = iReadRequest->AddBuffer(iClientReadBuffer, (TLinAddr)aBuffer, aLength, ETrue); sl@0: if (r != KErrNone) sl@0: return KErrNoMemory; sl@0: sl@0: iReadRequest->EndSetup(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: void DExampleChannel::StartRead() sl@0: { sl@0: ReceiveToReadBuffer(); // called in DFC thread as may require serialised access to hardware sl@0: } sl@0: sl@0: TInt DExampleChannel::PreReadDes(TDes8* aDesOut, TRequestStatus* aStatus) sl@0: { sl@0: // start request setup sl@0: TInt r = iReadRequest->StartSetup(aStatus); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // add client descriptor, this does pinning in context of client thread sl@0: r = iReadRequest->AddBuffer(iClientReadBuffer, aDesOut); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // can check length argument here sl@0: TInt length = iClientReadBuffer->MaxLength(); sl@0: if (length < 1 || length > KBufferSize) sl@0: { sl@0: // need to reset object so it can be reused sl@0: iReadRequest->Reset(); sl@0: return KErrArgument; sl@0: } sl@0: sl@0: iReadRequest->EndSetup(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: void DExampleChannel::StartReadDes() sl@0: { sl@0: ReceiveToReadBuffer(); // called in DFC thread as may require serialised access to hardware sl@0: } sl@0: sl@0: TInt DExampleChannel::PreWrite(TAny* aBuffer, TInt aLength, TRequestStatus* aStatus) sl@0: { sl@0: // check length argument first sl@0: if (aLength < 1 || aLength > KBufferSize) sl@0: return KErrArgument; sl@0: sl@0: // demonstrate use the single-buffer version of Setup sl@0: return iWriteRequest->Setup(iClientWriteBuffer, aStatus, (TLinAddr)aBuffer, aLength); sl@0: } sl@0: sl@0: void DExampleChannel::StartWrite() sl@0: { sl@0: SendFromWriteBuffer(); // called in DFC thread as may require serialised access to hardware sl@0: } sl@0: sl@0: TInt DExampleChannel::PreWriteDes(const TDesC8* aDesIn, TRequestStatus* aStatus) sl@0: { sl@0: // demonstrate use the single-buffer version of Setup sl@0: TInt r = iWriteRequest->Setup(iClientWriteBuffer, aStatus, (TAny*)aDesIn); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: // can check length argument here sl@0: TInt length = iClientWriteBuffer->Length(); sl@0: if (length < 1 || length > KBufferSize) sl@0: { sl@0: // need to reset object so it can be reused sl@0: iWriteRequest->Reset(); sl@0: return KErrArgument; sl@0: } sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: void DExampleChannel::StartWriteDes() sl@0: { sl@0: SendFromWriteBuffer(); // called in DFC thread as may require serialised access to hardware sl@0: } sl@0: sl@0: void DExampleChannel::ReceiveToReadBuffer() sl@0: { sl@0: // just queue a timer to simulate an asynchronous receive operation sl@0: // actually will return the previous contents of the buffer sl@0: iReadTimer.OneShot(KAsyncDelay, iCompleteReadDfc); sl@0: } sl@0: sl@0: void DExampleChannel::SendFromWriteBuffer() sl@0: { sl@0: // just queue a timer to simulate an asynchronous send operation sl@0: iWriteTimer.OneShot(KAsyncDelay, iCompleteWriteDfc); sl@0: } sl@0: sl@0: void DExampleChannel::ReceiveCompleteDfcFunc(TAny* aPtr) sl@0: { sl@0: DExampleChannel* self = (DExampleChannel*)aPtr; sl@0: self->CompleteRead(); sl@0: } sl@0: sl@0: void DExampleChannel::SendCompleteDfcFunc(TAny* aPtr) sl@0: { sl@0: DExampleChannel* self = (DExampleChannel*)aPtr; sl@0: self->CompleteWrite(); sl@0: } sl@0: sl@0: void DExampleChannel::CompleteRead() sl@0: { sl@0: TPtrC8 des(iBuffer, iClientReadBuffer->MaxLength()); sl@0: TInt r = Kern::ThreadBufWrite(iClient, iClientReadBuffer, des, 0, KChunkShiftBy0, iClient); sl@0: Kern::QueueBufferRequestComplete(iClient, iReadRequest, r); sl@0: } sl@0: sl@0: void DExampleChannel::CompleteWrite() sl@0: { sl@0: TPtr8 des(iBuffer, iClientWriteBuffer->Length()); sl@0: TInt r = Kern::ThreadBufRead(iClient, iClientWriteBuffer, des, 0, KChunkShiftBy0); sl@0: Kern::QueueBufferRequestComplete(iClient, iWriteRequest, r); sl@0: } sl@0: sl@0: // sl@0: // Logical device sl@0: // sl@0: sl@0: class DExampleFactory : public DLogicalDevice sl@0: { sl@0: public: sl@0: DExampleFactory(); sl@0: virtual TInt Install(); sl@0: virtual void GetCaps(TDes8& aDes) const; sl@0: virtual TInt Create(DLogicalChannelBase*& aChannel); sl@0: }; sl@0: sl@0: DExampleFactory::DExampleFactory() sl@0: { sl@0: iParseMask = 0; sl@0: iVersion = TVersion(1, 0, 0); sl@0: } sl@0: sl@0: TInt DExampleFactory::Install() sl@0: { sl@0: return SetName(&KPagingExample1PostLdd); sl@0: } sl@0: sl@0: void DExampleFactory::GetCaps(TDes8& /*aDes*/) const sl@0: { sl@0: // not used but required as DLogicalDevice::GetCaps is pure virtual sl@0: } sl@0: sl@0: TInt DExampleFactory::Create(DLogicalChannelBase*& aChannel) sl@0: { sl@0: aChannel = new DExampleChannel; sl@0: return aChannel ? KErrNone : KErrNoMemory; sl@0: } sl@0: sl@0: DECLARE_STANDARD_LDD() sl@0: { sl@0: return new DExampleFactory; sl@0: }