os/kernelhwsrv/userlibandfileserver/fileserver/shostmassstorage/server/protocol/tblocktransfer.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 /**
    17  @file
    18  @internalTechnology
    19 */
    20 
    21 #include <e32def.h>
    22 #include <e32std.h>
    23 #include <e32base.h>
    24 #include "msctypes.h"
    25 
    26 #include "mblocktransferprotocol.h"
    27 #include "tblocktransfer.h"
    28 #include "debug.h"
    29 #include "msdebug.h"
    30 
    31 
    32 /**
    33 Manage a read from a block device.
    34 
    35 @param aProtocol A reference to object providing protocol read method
    36 @param aPosition The position to start reading from
    37 @param aLength The length of data to read
    38 @param aBuf Buffer to copy the data to
    39 */
    40 void TBlockTransfer::ReadL(MBlockTransferProtocol& aProtocol,
    41                            TPos aPosition,
    42                            TInt aLength,
    43                            TDes8& aBuf)
    44     {
    45     __MSFNLOG
    46 	__HOSTPRINT1(_L("blocklen = 0%lx"), iBlockLength);
    47 
    48 	TInt copylen = 0;
    49     TInt headlen = 0;
    50 
    51 	aBuf.SetLength(0);
    52     TPos headOffset = GetHeadBlockOffset(aPosition);
    53 	/**** READ10 HEAD ****/
    54 	if (headOffset)
    55         {
    56 		TPos headpos = aPosition - headOffset;
    57         iHeadbuf->Zero();
    58 		headlen = ((headOffset + aLength - 1) / iBlockLength) == 0 ? aLength : (iBlockLength - headOffset);
    59 
    60 		__HOSTPRINT2(_L("\tRead head pos = 0%lx length = 0%lx"),
    61                      headpos, iBlockLength);
    62 		aProtocol.BlockReadL(headpos, *iHeadbuf, iBlockLength);
    63 		aBuf.Append(iHeadbuf->Ptr() + headOffset, headlen);		
    64         }
    65 
    66 	/**** READ10 BODY ****/
    67     TInt blocksInMain = (aLength - headlen)/iBlockLength;
    68 	if (blocksInMain)
    69         {
    70 		copylen = blocksInMain * iBlockLength;
    71 		__HOSTPRINT2(_L("\tRead main pos = 0%lx length = 0x%x"),
    72                      aPosition+headlen, copylen);
    73 		aProtocol.BlockReadL(aPosition+headlen, (TDes8 &)aBuf, copylen);
    74         }
    75 
    76 	copylen += headlen;
    77 
    78 	/**** READ10 TAIL ****/
    79     TInt tailLen = aLength - copylen;
    80 	if ((tailLen) != 0)
    81         {
    82 		__HOSTPRINT2(_L("\tRead tail pos = 0%lx length = 0%lx"),
    83                      aPosition+copylen, iBlockLength);
    84         iTailbuf->Zero();    
    85 		aProtocol.BlockReadL(aPosition+copylen, *iTailbuf, iBlockLength);
    86 		aBuf.Append(iTailbuf->Ptr(), tailLen);
    87         }
    88     }
    89 
    90 
    91 /**
    92 Manage a write to a block device
    93 
    94 @param aProtocol A reference to object providing protocol read method
    95 @param aPosition The position to start reading from
    96 @param aLength The length of data to read
    97 @param aBuf Buffer containing the data to write
    98 */
    99 void TBlockTransfer::WriteL(MBlockTransferProtocol& aProtocol,
   100                             TPos aPosition,
   101                             TInt aLength,
   102                             TDesC8& aBuf)
   103     {
   104     __MSFNLOG
   105 	TInt copylen = 0;
   106     TInt headlen = 0;
   107 
   108     TPos headOffset = GetHeadBlockOffset(aPosition);
   109 	/**** WRITE10 HEAD ****/
   110 	if (headOffset)
   111         {
   112 		TPos headpos = aPosition - headOffset;
   113 
   114         iHeadbuf->Zero();
   115 
   116         RBuf8& buf = *iTailbuf;
   117         buf.Zero();
   118 
   119 		headlen = ((headOffset + aLength - 1) / iBlockLength) == 0 ? aLength : (iBlockLength - headOffset);
   120 
   121 		__HOSTPRINT2(_L("\tWrite-Read head pos = 0%lx length = 0%lx"),
   122                      headpos, iBlockLength);
   123 
   124 		aProtocol.BlockReadL(headpos, *iHeadbuf, iBlockLength);
   125 		/* get head */
   126 		__HOSTPRINT2(_L("\tcopying read data pos = 0%lx offset = 0%lx"),
   127                      headpos, headOffset);
   128 		buf.Append(iHeadbuf->Ptr(), headOffset);
   129 
   130 		/* get body */
   131 		buf.Append(aBuf.Ptr(), headlen);
   132 
   133 		/* Is it a short write and tail exist? */
   134         TInt headEndOffset = headOffset + headlen;
   135 		if (headEndOffset != iBlockLength)
   136             {
   137             TInt len = iBlockLength - headEndOffset;
   138 
   139 			__HOSTPRINT2(_L("\t(short write) copying read data pos = 0%lx length = %08x"),
   140                          (headpos + headEndOffset), len);
   141 			buf.Append(iHeadbuf->Ptr() + headEndOffset, len);
   142             }
   143 
   144 		__HOSTPRINT2(_L("\tWrite head pos = 0%lx length = %08x"),
   145                      headpos, headlen);
   146 
   147 		aProtocol.BlockWriteL(headpos, (TDes8 &)buf, 0, iBlockLength);
   148         }
   149 
   150 	/**** WRITE10 BODY ****/
   151     TPos blocksInMain = (aLength - headlen)/iBlockLength;
   152 	if (blocksInMain)
   153         {
   154 		copylen = blocksInMain * iBlockLength;
   155 
   156         const TUint64 pos = aPosition + headlen;
   157 		__HOSTPRINT2(_L("\tWrite main pos = 0%lx length = %08x"),
   158                      pos, copylen);
   159 
   160 		/* form the body */
   161 		aProtocol.BlockWriteL(pos, (TDes8 &)aBuf, headlen, copylen);
   162         }
   163 
   164 	copylen += headlen;
   165 
   166 	/**** WRITE10 TAIL ****/
   167     TInt tailLen = aLength - copylen;;
   168 	if (tailLen != 0)
   169         {
   170         RBuf8& buf = *iHeadbuf;
   171         buf.Zero();
   172 
   173         iTailbuf->Zero();
   174 
   175         const TUint64 pos = aPosition + copylen;
   176 
   177 		__HOSTPRINT2(_L("\tWrite-Read tail pos = 0%lx length = %08x"),
   178                      pos, iBlockLength);
   179 
   180 		aProtocol.BlockReadL(pos, *iTailbuf, iBlockLength);
   181 		/* get head */
   182 		buf.Append(aBuf.Ptr() + copylen, tailLen);
   183 		/* get tail */
   184 		buf.Append(iTailbuf->Ptr() + tailLen, iBlockLength - tailLen);
   185 
   186 		aProtocol.BlockWriteL(pos, (TDes8 &)buf, 0, iBlockLength);
   187         }
   188     }
   189 
   190 
   191 void TBlockTransfer::SetCapacityL(TUint32 aBlockLength, TLba aLastLba)
   192     {
   193     __MSFNLOG
   194     iBlockLength = static_cast<TInt64>(aBlockLength);
   195     iLastLba = aLastLba;
   196 
   197     __ASSERT_DEBUG(iHeadbuf, User::Invariant());
   198     __ASSERT_DEBUG(iTailbuf, User::Invariant());
   199 
   200     if (iHeadbuf->Length() < iBlockLength)
   201         {
   202         iHeadbuf->ReAllocL(aBlockLength);
   203         iTailbuf->ReAllocL(aBlockLength);
   204         }    
   205     }
   206 
   207 
   208 TPos TBlockTransfer::GetHeadBlockOffset(TPos aPos)
   209     {
   210     __MSFNLOG
   211 	return (aPos % iBlockLength);
   212     }
   213 
   214 TLba TBlockTransfer::GetHeadBlockLbaL(TPos aPos)
   215     {
   216     __MSFNLOG
   217     TLba lba = I64LOW(aPos / iBlockLength);
   218     if (lba > iLastLba)
   219         User::Leave(KErrArgument);
   220     return lba;
   221     }
   222 
   223 TPos TBlockTransfer::GetTailBlockOffset(TPos aPos, TInt aLen)
   224     {
   225     __MSFNLOG
   226     return ((aPos + aLen) % iBlockLength);
   227     }
   228 
   229 TLba TBlockTransfer::GetTailBlockLbaL(TPos aPos, TInt aLen)
   230     {
   231     __MSFNLOG
   232     TLba lba = I64LOW((aPos + aLen) / iBlockLength);
   233     if (lba > iLastLba)
   234         User::Leave(KErrArgument);
   235     return lba;
   236     }
   237 
   238 
   239