os/kernelhwsrv/userlibandfileserver/fileserver/shostmassstorage/server/protocol/tblocktransfer.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/userlibandfileserver/fileserver/shostmassstorage/server/protocol/tblocktransfer.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,239 @@
1.4 +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +/**
1.20 + @file
1.21 + @internalTechnology
1.22 +*/
1.23 +
1.24 +#include <e32def.h>
1.25 +#include <e32std.h>
1.26 +#include <e32base.h>
1.27 +#include "msctypes.h"
1.28 +
1.29 +#include "mblocktransferprotocol.h"
1.30 +#include "tblocktransfer.h"
1.31 +#include "debug.h"
1.32 +#include "msdebug.h"
1.33 +
1.34 +
1.35 +/**
1.36 +Manage a read from a block device.
1.37 +
1.38 +@param aProtocol A reference to object providing protocol read method
1.39 +@param aPosition The position to start reading from
1.40 +@param aLength The length of data to read
1.41 +@param aBuf Buffer to copy the data to
1.42 +*/
1.43 +void TBlockTransfer::ReadL(MBlockTransferProtocol& aProtocol,
1.44 + TPos aPosition,
1.45 + TInt aLength,
1.46 + TDes8& aBuf)
1.47 + {
1.48 + __MSFNLOG
1.49 + __HOSTPRINT1(_L("blocklen = 0%lx"), iBlockLength);
1.50 +
1.51 + TInt copylen = 0;
1.52 + TInt headlen = 0;
1.53 +
1.54 + aBuf.SetLength(0);
1.55 + TPos headOffset = GetHeadBlockOffset(aPosition);
1.56 + /**** READ10 HEAD ****/
1.57 + if (headOffset)
1.58 + {
1.59 + TPos headpos = aPosition - headOffset;
1.60 + iHeadbuf->Zero();
1.61 + headlen = ((headOffset + aLength - 1) / iBlockLength) == 0 ? aLength : (iBlockLength - headOffset);
1.62 +
1.63 + __HOSTPRINT2(_L("\tRead head pos = 0%lx length = 0%lx"),
1.64 + headpos, iBlockLength);
1.65 + aProtocol.BlockReadL(headpos, *iHeadbuf, iBlockLength);
1.66 + aBuf.Append(iHeadbuf->Ptr() + headOffset, headlen);
1.67 + }
1.68 +
1.69 + /**** READ10 BODY ****/
1.70 + TInt blocksInMain = (aLength - headlen)/iBlockLength;
1.71 + if (blocksInMain)
1.72 + {
1.73 + copylen = blocksInMain * iBlockLength;
1.74 + __HOSTPRINT2(_L("\tRead main pos = 0%lx length = 0x%x"),
1.75 + aPosition+headlen, copylen);
1.76 + aProtocol.BlockReadL(aPosition+headlen, (TDes8 &)aBuf, copylen);
1.77 + }
1.78 +
1.79 + copylen += headlen;
1.80 +
1.81 + /**** READ10 TAIL ****/
1.82 + TInt tailLen = aLength - copylen;
1.83 + if ((tailLen) != 0)
1.84 + {
1.85 + __HOSTPRINT2(_L("\tRead tail pos = 0%lx length = 0%lx"),
1.86 + aPosition+copylen, iBlockLength);
1.87 + iTailbuf->Zero();
1.88 + aProtocol.BlockReadL(aPosition+copylen, *iTailbuf, iBlockLength);
1.89 + aBuf.Append(iTailbuf->Ptr(), tailLen);
1.90 + }
1.91 + }
1.92 +
1.93 +
1.94 +/**
1.95 +Manage a write to a block device
1.96 +
1.97 +@param aProtocol A reference to object providing protocol read method
1.98 +@param aPosition The position to start reading from
1.99 +@param aLength The length of data to read
1.100 +@param aBuf Buffer containing the data to write
1.101 +*/
1.102 +void TBlockTransfer::WriteL(MBlockTransferProtocol& aProtocol,
1.103 + TPos aPosition,
1.104 + TInt aLength,
1.105 + TDesC8& aBuf)
1.106 + {
1.107 + __MSFNLOG
1.108 + TInt copylen = 0;
1.109 + TInt headlen = 0;
1.110 +
1.111 + TPos headOffset = GetHeadBlockOffset(aPosition);
1.112 + /**** WRITE10 HEAD ****/
1.113 + if (headOffset)
1.114 + {
1.115 + TPos headpos = aPosition - headOffset;
1.116 +
1.117 + iHeadbuf->Zero();
1.118 +
1.119 + RBuf8& buf = *iTailbuf;
1.120 + buf.Zero();
1.121 +
1.122 + headlen = ((headOffset + aLength - 1) / iBlockLength) == 0 ? aLength : (iBlockLength - headOffset);
1.123 +
1.124 + __HOSTPRINT2(_L("\tWrite-Read head pos = 0%lx length = 0%lx"),
1.125 + headpos, iBlockLength);
1.126 +
1.127 + aProtocol.BlockReadL(headpos, *iHeadbuf, iBlockLength);
1.128 + /* get head */
1.129 + __HOSTPRINT2(_L("\tcopying read data pos = 0%lx offset = 0%lx"),
1.130 + headpos, headOffset);
1.131 + buf.Append(iHeadbuf->Ptr(), headOffset);
1.132 +
1.133 + /* get body */
1.134 + buf.Append(aBuf.Ptr(), headlen);
1.135 +
1.136 + /* Is it a short write and tail exist? */
1.137 + TInt headEndOffset = headOffset + headlen;
1.138 + if (headEndOffset != iBlockLength)
1.139 + {
1.140 + TInt len = iBlockLength - headEndOffset;
1.141 +
1.142 + __HOSTPRINT2(_L("\t(short write) copying read data pos = 0%lx length = %08x"),
1.143 + (headpos + headEndOffset), len);
1.144 + buf.Append(iHeadbuf->Ptr() + headEndOffset, len);
1.145 + }
1.146 +
1.147 + __HOSTPRINT2(_L("\tWrite head pos = 0%lx length = %08x"),
1.148 + headpos, headlen);
1.149 +
1.150 + aProtocol.BlockWriteL(headpos, (TDes8 &)buf, 0, iBlockLength);
1.151 + }
1.152 +
1.153 + /**** WRITE10 BODY ****/
1.154 + TPos blocksInMain = (aLength - headlen)/iBlockLength;
1.155 + if (blocksInMain)
1.156 + {
1.157 + copylen = blocksInMain * iBlockLength;
1.158 +
1.159 + const TUint64 pos = aPosition + headlen;
1.160 + __HOSTPRINT2(_L("\tWrite main pos = 0%lx length = %08x"),
1.161 + pos, copylen);
1.162 +
1.163 + /* form the body */
1.164 + aProtocol.BlockWriteL(pos, (TDes8 &)aBuf, headlen, copylen);
1.165 + }
1.166 +
1.167 + copylen += headlen;
1.168 +
1.169 + /**** WRITE10 TAIL ****/
1.170 + TInt tailLen = aLength - copylen;;
1.171 + if (tailLen != 0)
1.172 + {
1.173 + RBuf8& buf = *iHeadbuf;
1.174 + buf.Zero();
1.175 +
1.176 + iTailbuf->Zero();
1.177 +
1.178 + const TUint64 pos = aPosition + copylen;
1.179 +
1.180 + __HOSTPRINT2(_L("\tWrite-Read tail pos = 0%lx length = %08x"),
1.181 + pos, iBlockLength);
1.182 +
1.183 + aProtocol.BlockReadL(pos, *iTailbuf, iBlockLength);
1.184 + /* get head */
1.185 + buf.Append(aBuf.Ptr() + copylen, tailLen);
1.186 + /* get tail */
1.187 + buf.Append(iTailbuf->Ptr() + tailLen, iBlockLength - tailLen);
1.188 +
1.189 + aProtocol.BlockWriteL(pos, (TDes8 &)buf, 0, iBlockLength);
1.190 + }
1.191 + }
1.192 +
1.193 +
1.194 +void TBlockTransfer::SetCapacityL(TUint32 aBlockLength, TLba aLastLba)
1.195 + {
1.196 + __MSFNLOG
1.197 + iBlockLength = static_cast<TInt64>(aBlockLength);
1.198 + iLastLba = aLastLba;
1.199 +
1.200 + __ASSERT_DEBUG(iHeadbuf, User::Invariant());
1.201 + __ASSERT_DEBUG(iTailbuf, User::Invariant());
1.202 +
1.203 + if (iHeadbuf->Length() < iBlockLength)
1.204 + {
1.205 + iHeadbuf->ReAllocL(aBlockLength);
1.206 + iTailbuf->ReAllocL(aBlockLength);
1.207 + }
1.208 + }
1.209 +
1.210 +
1.211 +TPos TBlockTransfer::GetHeadBlockOffset(TPos aPos)
1.212 + {
1.213 + __MSFNLOG
1.214 + return (aPos % iBlockLength);
1.215 + }
1.216 +
1.217 +TLba TBlockTransfer::GetHeadBlockLbaL(TPos aPos)
1.218 + {
1.219 + __MSFNLOG
1.220 + TLba lba = I64LOW(aPos / iBlockLength);
1.221 + if (lba > iLastLba)
1.222 + User::Leave(KErrArgument);
1.223 + return lba;
1.224 + }
1.225 +
1.226 +TPos TBlockTransfer::GetTailBlockOffset(TPos aPos, TInt aLen)
1.227 + {
1.228 + __MSFNLOG
1.229 + return ((aPos + aLen) % iBlockLength);
1.230 + }
1.231 +
1.232 +TLba TBlockTransfer::GetTailBlockLbaL(TPos aPos, TInt aLen)
1.233 + {
1.234 + __MSFNLOG
1.235 + TLba lba = I64LOW((aPos + aLen) / iBlockLength);
1.236 + if (lba > iLastLba)
1.237 + User::Leave(KErrArgument);
1.238 + return lba;
1.239 + }
1.240 +
1.241 +
1.242 +