kerneltest/e32test/dmav2/d_dma2.cpp
changeset 130 c30940f6d922
parent 36 538db54a451d
child 199 189ece41fa29
child 247 d8d70de2bd36
equal deleted inserted replaced
129:a990138eda40 130:c30940f6d922
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    53 			{
    53 			{
    54 			diff = iStop - iStart;
    54 			diff = iStop - iStart;
    55 			}
    55 			}
    56 		return FastCountToMicroSecs(diff);
    56 		return FastCountToMicroSecs(diff);
    57 #else
    57 #else
    58 		//TODO On SMP it is possible for the value returned from
    58 		//On SMP it is possible for the value returned from
    59 		//NKern::FastCounter to depend on the current CPU (ie.
    59 		//NKern::FastCounter to depend on the current CPU (ie.
    60 		//NaviEngine)
    60 		//NaviEngine)
    61 		//
    61 		//
    62 		//One solution would be to tie DFC's and ISR's to the same
    62 		//One solution would be to tie DFC's and ISR's to the same
    63 		//core as the client, but this would reduce the usefulness of
    63 		//core as the client, but this would reduce the usefulness of
    98 	virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType);
    98 	virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType);
    99 private:
    99 private:
   100 	TInt DoGetInfo(TAny* aInfo);
   100 	TInt DoGetInfo(TAny* aInfo);
   101 
   101 
   102 	TInt OpenDmaChannel(TUint aPslCookie, TUint& aDriverCookie);
   102 	TInt OpenDmaChannel(TUint aPslCookie, TUint& aDriverCookie);
       
   103 	TInt OpenDmaChannel(TUint& aDriverCookie, TDmaChannel::SCreateInfo& aInfo);
   103 	TInt CloseDmaChannelByCookie(TUint aDriverCookie);
   104 	TInt CloseDmaChannelByCookie(TUint aDriverCookie);
   104 	TInt PauseDmaChannelByCookie(TUint aDriverCookie);
   105 	TInt PauseDmaChannelByCookie(TUint aDriverCookie);
   105 	TInt ResumeDmaChannelByCookie(TUint aDriverCookie);
   106 	TInt ResumeDmaChannelByCookie(TUint aDriverCookie);
   106 	TInt GetChannelCapsByCookie(TUint aDriverCookie, SDmacCaps& aChannelCaps);
   107 	TInt GetChannelCapsByCookie(TUint aDriverCookie, SDmacCaps& aChannelCaps);
   107 	TInt GetChannelCapsByCookie(TUint aDriverCookie, TDmacTestCaps& aChannelCaps);
   108 	TInt GetChannelCapsByCookie(TUint aDriverCookie, TDmacTestCaps& aChannelCaps);
   125 	@param aRequestCookie - On success will be a cookie by which the dma request can be referred to
   126 	@param aRequestCookie - On success will be a cookie by which the dma request can be referred to
   126 	@param aNewCallback - If true, then a new style DMA callback will be used
   127 	@param aNewCallback - If true, then a new style DMA callback will be used
   127 	*/
   128 	*/
   128 	TInt CreateDmaRequest(TUint aChannelCookie, TUint& aRequestCookie, TBool aNewCallback = EFalse, TInt aMaxFragmentSizeBytes=0);
   129 	TInt CreateDmaRequest(TUint aChannelCookie, TUint& aRequestCookie, TBool aNewCallback = EFalse, TInt aMaxFragmentSizeBytes=0);
   129 
   130 
   130 	//TODO what happens if a client closes a channel that
       
   131 	//it still has dma requests associated with?
       
   132 	
       
   133 	/**
   131 	/**
   134 	Destroys a previously created dma request object
   132 	Destroys a previously created dma request object
   135 	*/
   133 	*/
   136 	TInt DestroyDmaRequestByCookie(TUint aRequestCookie);
   134 	TInt DestroyDmaRequestByCookie(TUint aRequestCookie);
   137 
   135 
   139 
   137 
   140 
   138 
   141 	TInt CookieToChannelIndex(TUint aDriverCookie) const;
   139 	TInt CookieToChannelIndex(TUint aDriverCookie) const;
   142 	TInt CookieToRequestIndex(TUint aRequestCookie) const;
   140 	TInt CookieToRequestIndex(TUint aRequestCookie) const;
   143 
   141 
   144 	void FixupTransferArgs(TDmaTransferArgs& aTransferArgs) const;
   142 	void MakeAddressesAbsoulute(TDmaTransferArgs& aTransferArgs) const;
   145 	TInt FragmentRequest(TUint aRequestCookie, const TDmaTransferArgs& aTransferArgs, TBool aLegacy=ETrue);
   143 	TInt FragmentRequest(TUint aRequestCookie, const TDmaTransferArgs& aTransferArgs, TBool aLegacy=ETrue);
   146 
   144 
   147 	TInt QueueRequest(TUint aRequestCookie, TRequestStatus* aStatus, TCallbackRecord* aRecord, TUint64* aDurationMicroSecs);
   145 	TInt QueueRequest(TUint aRequestCookie, TRequestStatus* aStatus, TCallbackRecord* aRecord, TUint64* aDurationMicroSecs);
   148 	DClientDmaRequest* RequestFromCookie(TUint aRequestCookie) const;
   146 	DClientDmaRequest* RequestFromCookie(TUint aRequestCookie) const;
   149 	TInt RequestFragmentCount(TUint aRequestCookie);
   147 	TInt RequestFragmentCount(TUint aRequestCookie);
   175 	void AddRequeArgs(const TIsrRequeArgsSet& aRequeArgSet);
   173 	void AddRequeArgs(const TIsrRequeArgsSet& aRequeArgSet);
   176 
   174 
   177 	TUint64 GetDuration()
   175 	TUint64 GetDuration()
   178 		{return iStopwatch.ReadMicroSecs();}
   176 		{return iStopwatch.ReadMicroSecs();}
   179 
   177 
       
   178 	/**
       
   179 	Store a copy of the TDmaTransferArgs which was used for fragmentation
       
   180 	for argument checking
       
   181 	*/
       
   182 	void SetAddressParms(const TDmaTransferArgs& aAddressParms)
       
   183 		{iFragmentedTransfer = aAddressParms;}
       
   184 
       
   185 	/**
       
   186 	Retrieve stored TDmaTransferArgs
       
   187 	*/
       
   188 	const TDmaTransferArgs& GetAddressParms() const
       
   189 		{return iFragmentedTransfer;}
       
   190 
   180 protected:
   191 protected:
   181 	TInt Create();
   192 	TInt Create();
   182 	/** Construct with old style callback */
   193 	/** Construct with old style callback */
   183 	DClientDmaRequest(DThread* aClient, TDfcQue* const aDfcQ, TDmaChannel& aChannel, TInt aMaxTransferSize);
   194 	DClientDmaRequest(DThread* aClient, TDfcQue* const aDfcQ, TDmaChannel& aChannel, TInt aMaxTransferSize);
   184 
   195 
   200 	TDfcQue* const iDfcQ; //!< Use the DDmaTestSession's dfc queue
   211 	TDfcQue* const iDfcQ; //!< Use the DDmaTestSession's dfc queue
   201 	TDfc iDfc;
   212 	TDfc iDfc;
   202 
   213 
   203 	TStopwatch iStopwatch;
   214 	TStopwatch iStopwatch;
   204 	TIsrRequeArgsSet iIsrRequeArgSet;
   215 	TIsrRequeArgsSet iIsrRequeArgSet;
       
   216 
       
   217 	/**
       
   218 	This will be updated each time fragment is called.
       
   219 	It is required so that, at queue time, if ISR re-queue
       
   220 	arguments are added, they can be checked for sanity
       
   221 	*/
       
   222 	TDmaTransferArgs iFragmentedTransfer;
   205 	};
   223 	};
   206 
   224 
   207 DClientDmaRequest* DClientDmaRequest::Construct(DThread* aClient, TDfcQue* const aDfcQ, TDmaChannel& aChannel, TBool aNewStyle, TInt aMaxTransferSize)
   225 DClientDmaRequest* DClientDmaRequest::Construct(DThread* aClient, TDfcQue* const aDfcQ, TDmaChannel& aChannel, TBool aNewStyle, TInt aMaxTransferSize)
   208 	{
   226 	{
   209 	DClientDmaRequest* dmaRequest = NULL;
   227 	DClientDmaRequest* dmaRequest = NULL;
   339 	TEST_FAULT;
   357 	TEST_FAULT;
   340 	return KErrNotSupported;
   358 	return KErrNotSupported;
   341 #endif
   359 #endif
   342 	}
   360 	}
   343 
   361 
   344 /**
   362 /** Translate an old style dma callback to a new-style one
   345 Check that both source and destination of ISR reque args will
       
   346 lie within the range specified by aStart and aSize.
       
   347 
       
   348 @param aStart The linear base address of the region
       
   349 @param aSize The size of the region
       
   350 */
       
   351 TBool TIsrRequeArgs::CheckRange(TLinAddr aStart, TUint aSize) const
       
   352 	{
       
   353 	TUint physStart = Epoc::LinearToPhysical(aStart);
       
   354 	TEST_ASSERT(physStart != KPhysAddrInvalid);
       
   355 
       
   356 	TAddrRange chunk(physStart, aSize);
       
   357 	TBool sourceOk = (iSrcAddr == KPhysAddrInvalid) ? ETrue : chunk.Contains(SourceRange());
       
   358 
       
   359 	TBool destOk = (iDstAddr == KPhysAddrInvalid) ? ETrue : chunk.Contains(DestRange());
       
   360 
       
   361 	return sourceOk && destOk;
       
   362 	}
       
   363 
       
   364 TBool TIsrRequeArgsSet::CheckRange(TLinAddr aAddr, TUint aSize) const
       
   365 	{
       
   366 	for(TInt i=0; i<iCount; i++)
       
   367 		{
       
   368 		if(!iRequeArgs[i].CheckRange(aAddr, aSize))
       
   369 			return EFalse;
       
   370 		}
       
   371 	return ETrue;
       
   372 	}
       
   373 
       
   374 /**
       
   375 Translate an old style dma callback to a new-style one
       
   376 */
   363 */
   377 void DClientDmaRequest::CallbackOldStyle(TResult aResult, TAny* aArg)
   364 void DClientDmaRequest::CallbackOldStyle(TResult aResult, TAny* aArg)
   378 	{
   365 	{
   379 	__KTRACE_OPT(KDMA, Kern::Printf(">DClientDmaRequest::CallBackOldStyle: TResult result=%d", aResult));
   366 	__KTRACE_OPT(KDMA, Kern::Printf(">DClientDmaRequest::CallBackOldStyle: TResult result=%d", aResult));
   380 	TEST_ASSERT(aResult != EBadResult);
   367 	TEST_ASSERT(aResult != EBadResult);
   429 		{
   416 		{
   430 		self.iDfc.iPtr = aArg;
   417 		self.iDfc.iPtr = aArg;
   431 		self.iDfc.Add();
   418 		self.iDfc.Add();
   432 		break;
   419 		break;
   433 		}
   420 		}
   434 	case NKern::EIDFC: //fall-through
   421 	//Fall-through: If context is IDFC or the EEscaped marker occur
       
   422 	//it is an error
       
   423 	case NKern::EIDFC:
   435 	case NKern::EEscaped:
   424 	case NKern::EEscaped:
   436 	default:
   425 	default:
   437 		TEST_FAULT;
   426 		TEST_FAULT;
   438 		}
   427 		}
   439 	}
   428 	}
   591 		{
   580 		{
   592 	case RDmaSession::EOpenChannel:
   581 	case RDmaSession::EOpenChannel:
   593 			{
   582 			{
   594 			TUint pslCookie = (TUint)a1;
   583 			TUint pslCookie = (TUint)a1;
   595 			TUint driverCookie = 0;
   584 			TUint driverCookie = 0;
   596 			TInt r = OpenDmaChannel(pslCookie, driverCookie);	
   585 			TInt r = OpenDmaChannel(pslCookie, driverCookie);
   597 			umemput32(a2, &driverCookie, sizeof(TAny*));
   586 			umemput32(a2, &driverCookie, sizeof(TAny*));
       
   587 			return r;
       
   588 			}
       
   589 	case RDmaSession::EOpenChannelExposed:
       
   590 			{
       
   591 			TDmaChannel::SCreateInfo openInfo;
       
   592 			TUint driverCookie = 0;
       
   593 
       
   594 			TPckgBuf<SCreateInfoTest> openArgsBuf;
       
   595 			Kern::KUDesGet(openArgsBuf, *reinterpret_cast<TDes8*>(a2));
       
   596 
       
   597 			SCreateInfoTest& openTestInfo = openArgsBuf();
       
   598 			openInfo.iCookie = openTestInfo.iCookie;
       
   599 			openInfo.iDesCount = openTestInfo.iDesCount;
       
   600 			openInfo.iDfcQ = iDfcQ;
       
   601 			openInfo.iDfcPriority = openTestInfo.iDfcPriority;
       
   602 
       
   603 			#ifdef DMA_APIV2
       
   604 				openInfo.iPriority = openTestInfo.iPriority;
       
   605 				openInfo.iDynChannel = openTestInfo.iDynChannel;
       
   606 			#endif
       
   607 
       
   608 			TInt r = OpenDmaChannel(driverCookie, openInfo);
       
   609 			umemput32(a1, &driverCookie, sizeof(TAny*));
       
   610 			Kern::KUDesPut(*reinterpret_cast<TDes8*>(a2), openArgsBuf);
   598 			return r;
   611 			return r;
   599 			}
   612 			}
   600 	case RDmaSession::ECloseChannel:
   613 	case RDmaSession::ECloseChannel:
   601 			{
   614 			{
   602 			TUint driverCookie = reinterpret_cast<TUint>(a1);
   615 			TUint driverCookie = reinterpret_cast<TUint>(a1);
   658 			//must remove constness as we actually need to
   671 			//must remove constness as we actually need to
   659 			//convert the src and dst offsets to addresses
   672 			//convert the src and dst offsets to addresses
   660 			TDmaTransferArgs& transferArgs = const_cast<TDmaTransferArgs&>(argsBuff().iTransferArgs);
   673 			TDmaTransferArgs& transferArgs = const_cast<TDmaTransferArgs&>(argsBuff().iTransferArgs);
   661 
   674 
   662 			//convert address offsets in to kernel virtual addresses
   675 			//convert address offsets in to kernel virtual addresses
   663 			FixupTransferArgs(transferArgs);
   676 			MakeAddressesAbsoulute(transferArgs);
   664 
       
   665 			TEST_ASSERT((TAddressParms(transferArgs).CheckRange(iChunkBase, iChunk->Size())));
       
   666 
   677 
   667 			TInt r = KErrGeneral;
   678 			TInt r = KErrGeneral;
       
   679 			if (!TAddressParms(transferArgs).CheckRange(iChunkBase, iChunk->Size()))
       
   680 			{
       
   681 				// Return error code for invalid src and destination arguments used in tranferArgs
       
   682 				r=KErrArgument;
       
   683 				return r;
       
   684 			}
   668 
   685 
   669 			TStopwatch clock;
   686 			TStopwatch clock;
   670 			clock.Start();
   687 			clock.Start();
   671 			switch (aFunction)
   688 			switch (aFunction)
   672 				{
   689 				{
   706 				}
   723 				}
   707 			return r;
   724 			return r;
   708 			}	
   725 			}	
   709 	case RDmaSession::EQueueRequestWithReque:
   726 	case RDmaSession::EQueueRequestWithReque:
   710 			{
   727 			{
   711 			//TODO can common code with EQueueRequest be extracted?
       
   712 			TPckgBuf<RDmaSession::TQueueArgsWithReque> argsBuff;
   728 			TPckgBuf<RDmaSession::TQueueArgsWithReque> argsBuff;
   713 			Kern::KUDesGet(argsBuff, *reinterpret_cast<TDes8*>(a1));
   729 			Kern::KUDesGet(argsBuff, *reinterpret_cast<TDes8*>(a1));
   714 
   730 
   715 			//this is an Asynchronous request
   731 			//this is an Asynchronous request
   716 			const TUint requestCookie = argsBuff().iRequestCookie;
   732 			const TUint requestCookie = argsBuff().iRequestCookie;
   721 			TInt r = KErrNotFound;
   737 			TInt r = KErrNotFound;
   722 
   738 
   723 			DClientDmaRequest* const request = RequestFromCookie(requestCookie);
   739 			DClientDmaRequest* const request = RequestFromCookie(requestCookie);
   724 			if(request != NULL)
   740 			if(request != NULL)
   725 				{
   741 				{
   726 				argsBuff().iRequeSet.Fixup(iChunkBase);
   742 				TIsrRequeArgsSet& requeArgs = argsBuff().iRequeSet;
   727 				//TODO reque args must be substituted in order to
   743 				requeArgs.Fixup(iChunkBase);
   728 				//check the range. The original transfer args are not
   744 
   729 				//available when queue is called, they could
   745 				TEST_ASSERT(requeArgs.CheckRange(iChunkBase, iChunk->Size(), request->GetAddressParms() ));
   730 				//however be stored within DClientDmaRequest
   746 				request->AddRequeArgs(requeArgs);
   731 				//TEST_ASSERT((argsBuff().iRequeSet.CheckRange(iChunkBase, iChunk->Size())));
       
   732 				request->AddRequeArgs(argsBuff().iRequeSet);
       
   733 
   747 
   734 				r = QueueRequest(requestCookie, requestStatus, callbackRec, duration);
   748 				r = QueueRequest(requestCookie, requestStatus, callbackRec, duration);
   735 				}
   749 				}
   736 
   750 
   737 			if(r != KErrNone)
   751 			if(r != KErrNone)
   738 				{
   752 				{
   739 				Kern::RequestComplete(requestStatus, r);
   753 				Kern::RequestComplete(requestStatus, r);
   740 				}
   754 				}
   741 			return r;
       
   742 			}
       
   743 	case RDmaSession::EIsrRedoRequest:
       
   744 			{
       
   745 			TPckgBuf<RDmaSession::TIsrRedoReqArgs> argsBuff;
       
   746 			Kern::KUDesGet(argsBuff, *reinterpret_cast<TDes8*>(a1));
       
   747 
       
   748 			const TUint driverCookie = argsBuff().iDriverCookie;
       
   749 			const TUint32 srcAddr = argsBuff().iSrcAddr;
       
   750 			const TUint32 dstAddr = argsBuff().iDstAddr;
       
   751 			const TInt transferCount = argsBuff().iTransferCount;
       
   752 			const TUint32 pslRequestInfo = argsBuff().iPslRequestInfo;
       
   753 			const TBool isrCb = argsBuff().iIsrCb;
       
   754 
       
   755 			TInt r = IsrRedoRequestByCookie(driverCookie,srcAddr,dstAddr,transferCount,pslRequestInfo,isrCb);
       
   756 			return r;
   755 			return r;
   757 			}
   756 			}
   758 	case RDmaSession::EIsOpened:
   757 	case RDmaSession::EIsOpened:
   759 			{
   758 			{
   760 			TUint driverCookie = (TUint)a1;
   759 			TUint driverCookie = (TUint)a1;
   795 		Kern::PanicCurrentThread(KClientPanicCat, __LINE__);
   794 		Kern::PanicCurrentThread(KClientPanicCat, __LINE__);
   796 		return KErrGeneral;
   795 		return KErrGeneral;
   797 		}
   796 		}
   798 	}
   797 	}
   799 
   798 
       
   799 TInt DDmaTestSession::OpenDmaChannel(TUint& aDriverCookie, TDmaChannel::SCreateInfo& aInfo)
       
   800 	{
       
   801 	//cs so thread can't be killed between
       
   802 	//opening channel and adding to array
       
   803 	NKern::ThreadEnterCS();
       
   804 	TDmaChannel* channel = NULL;
       
   805 	TInt r = TDmaChannel::Open(aInfo, channel);
       
   806 	if(KErrNone == r)
       
   807 		{
       
   808 		__NK_ASSERT_ALWAYS(channel);
       
   809 
       
   810 		__KTRACE_OPT(KDMA, Kern::Printf("OpenDmaChannel: channel@ 0x%08x", channel));
       
   811 
       
   812 		r = iChannels.Append(channel);
       
   813 		if(KErrNone == r)
       
   814 			{
       
   815 			aDriverCookie = reinterpret_cast<TUint>(channel);
       
   816 			}
       
   817 		else
       
   818 			{
       
   819 			channel->Close();
       
   820 			r = KErrNoMemory;
       
   821 			}
       
   822 		}
       
   823 	NKern::ThreadLeaveCS();
       
   824 
       
   825 	return r;
       
   826 	}
       
   827 
       
   828 /**
       
   829 Open a DMA channel with arbitrary default parameters
       
   830 */
   800 TInt DDmaTestSession::OpenDmaChannel(TUint aPslCookie, TUint& aDriverCookie )
   831 TInt DDmaTestSession::OpenDmaChannel(TUint aPslCookie, TUint& aDriverCookie )
   801 	{
   832 	{
   802 	TDmaChannel::SCreateInfo info;
   833 	TDmaChannel::SCreateInfo info;
   803 	info.iCookie = aPslCookie;
   834 	info.iCookie = aPslCookie;
   804 	info.iDfcQ = iDfcQ;
   835 	info.iDfcQ = iDfcQ;
   805 	info.iDfcPriority = 3;
   836 	info.iDfcPriority = 3;
   806 	info.iDesCount = 128;
   837 	info.iDesCount = 128;
   807 
   838 
   808 	TDmaChannel* channel = NULL;
   839 	return OpenDmaChannel(aDriverCookie, info);
   809 
       
   810 	//cs so thread can't be killed between
       
   811 	//opening channel and adding to array
       
   812 	NKern::ThreadEnterCS();
       
   813 	TInt r = TDmaChannel::Open(info, channel);
       
   814 	if(KErrNone == r)
       
   815 		{
       
   816 		__NK_ASSERT_ALWAYS(channel);
       
   817 		
       
   818 		__KTRACE_OPT(KDMA, Kern::Printf("OpenDmaChannel: channel@ 0x%08x", channel)); 
       
   819 
       
   820 
       
   821 		TInt err = iChannels.Append(channel);
       
   822 		if(KErrNone == err)
       
   823 			{
       
   824 			aDriverCookie = reinterpret_cast<TUint>(channel);
       
   825 			}
       
   826 		else
       
   827 			{
       
   828 			channel->Close();
       
   829 			r = KErrNoMemory;
       
   830 			}
       
   831 		}
       
   832 	NKern::ThreadLeaveCS();
       
   833 
       
   834 	return r;
       
   835 	}
   840 	}
   836 
   841 
   837 TInt DDmaTestSession::CookieToChannelIndex(TUint aDriverCookie) const
   842 TInt DDmaTestSession::CookieToChannelIndex(TUint aDriverCookie) const
   838 	{
   843 	{
   839 	const TInt r = iChannels.Find(reinterpret_cast<TDmaChannel*>(aDriverCookie));
   844 	const TInt r = iChannels.Find(reinterpret_cast<TDmaChannel*>(aDriverCookie));
   904 void DDmaTestSession::CancelAllByIndex(TInt aIndex)
   909 void DDmaTestSession::CancelAllByIndex(TInt aIndex)
   905 	{
   910 	{
   906 	__KTRACE_OPT(KDMA, Kern::Printf("CancelAllByIndex: %d", aIndex)); 
   911 	__KTRACE_OPT(KDMA, Kern::Printf("CancelAllByIndex: %d", aIndex)); 
   907 	__NK_ASSERT_DEBUG(aIndex < iChannels.Count()); 
   912 	__NK_ASSERT_DEBUG(aIndex < iChannels.Count()); 
   908 	
   913 	
   909 	TDmaChannel* channel = iChannels[aIndex];
   914 	TDmaChannel* channel = iChannels[aIndex];	
   910 	iChannels.Remove(aIndex);
       
   911 	channel->CancelAll();
   915 	channel->CancelAll();
   912 	}
   916 	}
   913 
   917 
   914 TInt DDmaTestSession::PauseDmaChannelByIndex(TInt aIndex)
   918 TInt DDmaTestSession::PauseDmaChannelByIndex(TInt aIndex)
   915 	{
   919 	{
  1186 	const TInt r = Kern::MakeHandleAndOpen(NULL, iChunk);
  1190 	const TInt r = Kern::MakeHandleAndOpen(NULL, iChunk);
  1187 	NKern::ThreadLeaveCS();
  1191 	NKern::ThreadLeaveCS();
  1188 	return r;
  1192 	return r;
  1189 	}
  1193 	}
  1190 
  1194 
  1191 void DDmaTestSession::FixupTransferArgs(TDmaTransferArgs& aTransferArgs) const
  1195 /**
       
  1196 Replace addresses specified as an offset from the chunk base with absolute
       
  1197 virtual addresses.
       
  1198 */
       
  1199 void DDmaTestSession::MakeAddressesAbsoulute(TDmaTransferArgs& aTransferArgs) const
  1192 	{
  1200 	{
  1193 	aTransferArgs.iSrcConfig.iAddr += iChunkBase;
  1201 	aTransferArgs.iSrcConfig.iAddr += iChunkBase;
  1194 	aTransferArgs.iDstConfig.iAddr += iChunkBase;
  1202 	aTransferArgs.iDstConfig.iAddr += iChunkBase;
  1195 	}
  1203 	}
  1196 
  1204 
  1223 	__KTRACE_OPT(KDMA, Kern::Printf(">FragmentRequest: cookie=0x%08x, legacy=%d", aRequestCookie, aLegacy)); 
  1231 	__KTRACE_OPT(KDMA, Kern::Printf(">FragmentRequest: cookie=0x%08x, legacy=%d", aRequestCookie, aLegacy)); 
  1224 	TInt requestIndex = CookieToRequestIndex(aRequestCookie);
  1232 	TInt requestIndex = CookieToRequestIndex(aRequestCookie);
  1225 	if(requestIndex < 0)
  1233 	if(requestIndex < 0)
  1226 		return requestIndex;
  1234 		return requestIndex;
  1227 
  1235 
       
  1236 	DClientDmaRequest& request = *iClientDmaReqs[requestIndex];
       
  1237 	request.SetAddressParms(aTransferArgs);
       
  1238 
  1228 	TInt r = KErrNotSupported;
  1239 	TInt r = KErrNotSupported;
       
  1240 
       
  1241 	if (aTransferArgs.iTransferCount < 1)
       
  1242 		{
       
  1243 		// Return error code for invalid transfer size used in tranferArgs
       
  1244 		r=KErrArgument;
       
  1245 		return r;
       
  1246 		}
       
  1247 
  1229 	if(aLegacy)
  1248 	if(aLegacy)
  1230 		{
  1249 		{
  1231 		// TODO we can extract the required info from the struct to
       
  1232 		// set flags
       
  1233 		TUint flags = KDmaMemSrc | KDmaIncSrc | KDmaMemDest | KDmaIncDest;
  1250 		TUint flags = KDmaMemSrc | KDmaIncSrc | KDmaMemDest | KDmaIncDest;
  1234 
       
  1235 		const TUint src = aTransferArgs.iSrcConfig.iAddr;
  1251 		const TUint src = aTransferArgs.iSrcConfig.iAddr;
  1236 		const TUint dst = aTransferArgs.iDstConfig.iAddr;
  1252 		const TUint dst = aTransferArgs.iDstConfig.iAddr;
  1237 		r = iClientDmaReqs[requestIndex]->Fragment(src, dst, aTransferArgs.iTransferCount, flags, NULL);
  1253 		r = request.Fragment(src, dst, aTransferArgs.iTransferCount, flags, NULL);
  1238 		}
  1254 		}
  1239 	else
  1255 	else
  1240 		{
  1256 		{
  1241 #ifdef DMA_APIV2
  1257 #ifdef DMA_APIV2
  1242 		r = iClientDmaReqs[requestIndex]->Fragment(aTransferArgs);
  1258 		r = request.Fragment(aTransferArgs);
  1243 #else
       
  1244 		r = KErrNotSupported;
       
  1245 #endif
  1259 #endif
  1246 		}
  1260 		}
  1247 	return r;
  1261 	return r;
  1248 	}
  1262 	}
  1249 
  1263 
  1294 
  1308 
  1295 	newInfo.iMaxSgChannels = aOldInfo.iMaxSgChannels;
  1309 	newInfo.iMaxSgChannels = aOldInfo.iMaxSgChannels;
  1296 	for(TInt i=0; i<aOldInfo.iMaxSgChannels; i++)
  1310 	for(TInt i=0; i<aOldInfo.iMaxSgChannels; i++)
  1297 		newInfo.iSgChannels[i] = aOldInfo.iSgChannels[i];
  1311 		newInfo.iSgChannels[i] = aOldInfo.iSgChannels[i];
  1298 
  1312 
  1299 	//TODO will want to add initialisation for Asym channels
       
  1300 	//when these are available
       
  1301 
       
  1302 	return newInfo;
  1313 	return newInfo;
  1303 	}
  1314 	}
  1304 //////////////////////////////////////////////////////////////////////////////
  1315 //////////////////////////////////////////////////////////////////////////////
  1305 
  1316 
  1306 class DDmaTestFactory : public DLogicalDevice
  1317 class DDmaTestFactory : public DLogicalDevice
  1319 
  1330 
  1320 
  1331 
  1321 DDmaTestFactory::DDmaTestFactory()
  1332 DDmaTestFactory::DDmaTestFactory()
  1322     {
  1333     {
  1323     iVersion = TestDmaLddVersion();
  1334     iVersion = TestDmaLddVersion();
  1324     iParseMask = KDeviceAllowUnit;							// no info, no PDD
  1335     iParseMask = KDeviceAllowUnit;							// no info, no PDD    
  1325     // iUnitsMask = 0;										// Only one thing
       
  1326     }
  1336     }
  1327 
  1337 
  1328 
  1338 
  1329 TInt DDmaTestFactory::Create(DLogicalChannelBase*& aChannel)
  1339 TInt DDmaTestFactory::Create(DLogicalChannelBase*& aChannel)
  1330     {
  1340     {