kernel/eka/drivers/locmedia/dmasupport.cpp
branchRCL_3
changeset 28 5b5d147c7838
parent 14 5d2844f35677
child 43 c1f20ce4abcf
--- a/kernel/eka/drivers/locmedia/dmasupport.cpp	Tue May 11 17:28:22 2010 +0300
+++ b/kernel/eka/drivers/locmedia/dmasupport.cpp	Tue May 25 14:09:55 2010 +0300
@@ -743,43 +743,79 @@
 	{
 	OstTraceFunctionEntry0( DDMAHELPER_GETPHYSICALADDRESS_ENTRY );
 	__ASSERT_DEBUG( (aReq.Flags() & TLocDrvRequest::ETClientBuffer) == 0,  PHYSADDR_FAULT());
-	TLinAddr linAddr = (TLinAddr) aReq.RemoteDes();
-	TInt& offset = aReq.RemoteDesOffset();
-	TLinAddr currLinAddr = linAddr + offset;
-	TInt reqLen = I64LOW(aReq.Length());
-	__ASSERT_DEBUG(I64HIGH(aReq.Length()) == 0,  PHYSADDR_FAULT());
-
-	aAddr = Epoc::LinearToPhysical(currLinAddr);
 
-	// Set the initial length to be the length remaining in this page or the request length (whichever is shorter).
-	// If there are subsequent pages, we then need to determine whether they are contiguous
-	aLen = Min( (TInt) (PageAlign(currLinAddr+iPageSize) - currLinAddr), reqLen - offset);
+	TInt reqLen = I64LOW(aReq.Length());
+    __ASSERT_DEBUG(I64HIGH(aReq.Length()) == 0,  PHYSADDR_FAULT());
+    
+    TInt& offset = aReq.RemoteDesOffset();    
+	if (aReq.Flags() & TLocDrvRequest::EPhysAddrOnly)
+        {        
+        __KTRACE_DMA(Kern::Printf("-Physical Address Only"));
+        __ASSERT_DEBUG(IsPageAligned((TLinAddr)reqLen), PHYSADDR_FAULT());
+        
+        TPhysAddr* physArray = (TPhysAddr*)aReq.RemoteDes();        
+        
+        // Adjust start to the next element to be issued                 
+        TUint pageNo = offset>>iPageSizeLog2;
+        TPhysAddr currPhysPageAddr = aAddr = physArray[pageNo];
+        __ASSERT_DEBUG(IsPageAligned((TLinAddr)currPhysPageAddr), PHYSADDR_FAULT());
+        offset+=iPageSize; 
+        aLen=iPageSize;
 
-	__ASSERT_DEBUG(aLen > 0,  PHYSADDR_FAULT());
-	
-	TPhysAddr currPhysPageAddr = PageAlign((TLinAddr) aAddr);
-
-	offset+= aLen;
-
+        //Determine how many pages are contiguous
+        TPhysAddr nextPhysPageAddr;        
+        while (offset < reqLen)
+            {
+            pageNo++;
+            nextPhysPageAddr = physArray[pageNo];            
+            __ASSERT_DEBUG(PageOffset((TLinAddr) nextPhysPageAddr) == 0,  PHYSADDR_FAULT());
 
-	while (offset < reqLen)
-		{
-		TPhysAddr nextPhysPageAddr = Epoc::LinearToPhysical(linAddr + offset);
-		__ASSERT_DEBUG(PageOffset((TLinAddr) nextPhysPageAddr) == 0,  PHYSADDR_FAULT());
+            if (nextPhysPageAddr != currPhysPageAddr + iPageSize)
+                break;
+            
+            currPhysPageAddr = nextPhysPageAddr;            
+            offset+= iPageSize;
+            aLen+= iPageSize;
+            }
+        
+        __KTRACE_DMA(Kern::Printf(">PHYSADDR:DP:GetPhysS(PhysAddrOnly), physAddr %08X, len %x reqLen %x", aAddr, aLen, reqLen));
+        }
+	else
+	    {	
+        TLinAddr linAddr = (TLinAddr) aReq.RemoteDes();
+        TLinAddr currLinAddr = linAddr + offset;	
+    
+        aAddr = Epoc::LinearToPhysical(currLinAddr);
+    
+        // Set the initial length to be the length remaining in this page or the request length (whichever is shorter).
+        // If there are subsequent pages, we then need to determine whether they are contiguous
+        aLen = Min( (TInt) (PageAlign(currLinAddr+iPageSize) - currLinAddr), reqLen - offset);
+    
+        __ASSERT_DEBUG(aLen > 0,  PHYSADDR_FAULT());
+        
+        TPhysAddr currPhysPageAddr = PageAlign((TLinAddr) aAddr);
+    
+        offset+= aLen;
+    
+        while (offset < reqLen)
+            {
+            TPhysAddr nextPhysPageAddr = Epoc::LinearToPhysical(linAddr + offset);
+            __ASSERT_DEBUG(PageOffset((TLinAddr) nextPhysPageAddr) == 0,  PHYSADDR_FAULT());
+    
+            if (nextPhysPageAddr != currPhysPageAddr + iPageSize)
+                break;
+            
+            currPhysPageAddr = nextPhysPageAddr;
+    
+            TInt len = Min(iPageSize, reqLen - offset);
+            offset+= len;
+            aLen+= len;
+            }
 
-		if (nextPhysPageAddr != currPhysPageAddr + iPageSize)
-			break;
-		
-		currPhysPageAddr = nextPhysPageAddr;
-
-		TInt len = Min(iPageSize, reqLen - offset);
-		offset+= len;
-		aLen+= len;
-		}
-
-
-	__KTRACE_DMA(Kern::Printf(">PHYSADDR:DP:GetPhysS(), linAddr %08X, physAddr %08X, len %x reqLen %x", linAddr + offset, aAddr, aLen, reqLen));
-	OstTraceExt4(TRACE_DEMANDPAGING, DDMAHELPER_GETPHYSICALADDRESS_DP, "linAddr=0x%x; physAddr=0x%x; length=0x%x; reqLen=0x%x", linAddr + offset, aAddr, aLen, reqLen);
+        __KTRACE_DMA(Kern::Printf(">PHYSADDR:DP:GetPhysS(), linAddr %08X, physAddr %08X, len %x reqLen %x", linAddr + offset, aAddr, aLen, reqLen));
+        OstTraceExt4(TRACE_DEMANDPAGING, DDMAHELPER_GETPHYSICALADDRESS_DP, "linAddr=0x%x; physAddr=0x%x; length=0x%x; reqLen=0x%x", linAddr + offset, aAddr, aLen, reqLen);
+	    }
+	
 	OstTraceFunctionExit0( DDMAHELPER_GETPHYSICALADDRESS_EXIT );
 	return KErrNone;
 	}