os/kernelhwsrv/userlibandfileserver/fileserver/shostmassstorage/server/protocol/tsbcclientinterface.cpp
Update contrib.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
27 #include "mtransport.h"
28 #include "mprotocol.h"
29 #include "tscsiclientreq.h"
31 #include "tblocktransfer.h"
33 #include "usbmshostpanic.h"
34 #include "tscsiblockcmds.h"
35 #include "tsbcclientinterface.h"
40 @param aTransport The Transport interface to be used
42 TSbcClientInterface::TSbcClientInterface(MTransport& aTransport)
43 : iTransport(aTransport)
49 TSbcClientInterface::~TSbcClientInterface()
56 Constructor to create and send SCSI MODE SENSE (6) request to obtain the
57 medium's Write Protect status. The function leaves if the device response is not
58 compliant with the protocol standard.
60 @param aPageCode The SCSI PAGE CODE value
61 @param aWriteProtected The SCSI WP value
63 @return TInt KErrNone if successful, KErrCommandFailed to indicate a
64 device status error, KErrCommandStalled to indicate device stall
66 TInt TSbcClientInterface::ModeSense6L(TUint aPageCode, TBool& aWriteProtected)
69 TScsiClientModeSense6Req modeSense6Req(TScsiClientModeSense6Req::ECurrentValues,
71 TScsiClientModeSense6Resp modeSense6Resp;
72 TInt err = iTransport.SendControlCmdL(&modeSense6Req, &modeSense6Resp);
75 __SCSIPRINT1(_L("SCSI MODE SENSE (6) INFO WrProtect=%d"),
76 modeSense6Resp.iWriteProtected);
77 aWriteProtected = modeSense6Resp.iWriteProtected;
81 aWriteProtected = EFalse;
88 Create and send SCSI MODE SENSE (10) request to obtain the mediums Write Protect
89 status. The function leaves if the device response is not compliant with the
92 @param aPageCode The SCSI PAGE CODE value
93 @param aWriteProtected The SCSI WP value
95 @return TInt KErrNone if successful, KErrCommandFailed to indicate a
96 device status error, KErrCommandStalled to indicate a device stall
98 TInt TSbcClientInterface::ModeSense10L(TUint aPageCode, TBool& aWriteProtected)
101 TScsiClientModeSense10Req modeSense10Req(TScsiClientModeSense10Req::ECurrentValues,
103 TScsiClientModeSense10Resp modeSense10Resp;
104 TInt err = iTransport.SendControlCmdL(&modeSense10Req, &modeSense10Resp);
108 __SCSIPRINT1(_L("SCSI MODE SENSE (10) INFO WrProtect=%d"),
109 modeSense10Resp.iWriteProtected);
110 aWriteProtected = modeSense10Resp.iWriteProtected;
114 aWriteProtected = EFalse;
121 Constructor to create SCSI MODE SENSE (10) request.
123 @param aPageControl The SCSI PAGE CODE value
124 @param aPageCode The SCSI WP value
125 @param aSubPageCode The SCSI SUB PAGE CODE value
127 TScsiClientModeSense10Req::TScsiClientModeSense10Req(TPageControl aPageControl,
131 TScsiClientReq(EModeSense10),
132 iPageControl(aPageControl),
133 iPageCode(aPageCode),
134 iSubPageCode(aSubPageCode),
135 iAllocationLength(KResponseLength)
141 TInt TScsiClientModeSense10Req::EncodeRequestL(TDes8& aBuffer) const
144 __SCSIPRINT(_L("<-- SCSI MODE SENSE (10)"));
145 TInt length = TScsiClientReq::EncodeRequestL(aBuffer);
148 aBuffer[2] = iPageCode;
149 aBuffer[2] |= iPageControl << 6;
150 aBuffer[3] = iSubPageCode;
152 BigEndian::Put16(&aBuffer[7], iAllocationLength);
157 Create READ (10) request and send to the transport layer. This performs a
158 logical block read of the device server. The received data is appended into the
159 copy buffer. The function leaves if the device response is not compliant with
160 the protocol standard.
161 Note that TBlockTransfer must be initialised beforehand.
163 @param aLba The Logical Block address to read from
164 @param aBuffer The buffer to copy data to
165 @param aLen The number of bytes to be read (IN) and returns the number of bytes
168 @return TInt KErrNone if successful otherwise KErrCommandFailed to indicate a
169 device status error or KErrArgument to indicate that aLen is too large for the
172 TInt TSbcClientInterface::Read10L(TLba aLba, TDes8& aBuffer, TInt& aLen)
175 __ASSERT_DEBUG(iBlockTransfer.BlockLength(), User::Panic(KUsbMsHostPanicCat, EBlockLengthNotSet));
176 __ASSERT_DEBUG(aLen % iBlockTransfer.BlockLength() == 0, User::Panic(KUsbMsHostPanicCat, EBlockDevice));
178 TScsiClientRead10Req read10Req;
180 read10Req.iLogicalBlockAddress = aLba;
182 TInt blockTransferLength = aLen / iBlockTransfer.BlockLength();
183 if (blockTransferLength > static_cast<TInt>(KMaxTUint16))
185 User::Leave(KErrArgument);
187 read10Req.iBlockTransferLength = static_cast<TUint16>(blockTransferLength);
188 TInt err = iTransport.SendDataRxCmdL(&read10Req, aBuffer, aLen);
193 Create READ CAPACITY (10) request and send to the transport layer. The request
194 returns the device servers capacity information. The device server's response
195 values are also used here to initialise the TBlockTransfer values. The function
196 leaves if the device response is not compliant with the protocol standard.
198 @param aLba The Logical Block Address returned by the LU
199 @param aBlockSize The Block Size returned by the LU
201 @return TInt KErrNone if successful, KErrCommandFailed to indicate a
202 device status error, KErrCommandStalled to indicate a device stall
204 TInt TSbcClientInterface::ReadCapacity10L(TLba& aLba, TUint32& aBlockSize)
207 TScsiClientReadCapacity10Req capacity10Req;
208 TScsiClientReadCapacity10Resp capacity10Resp;
210 TInt err = iTransport.SendControlCmdL(&capacity10Req, &capacity10Resp);
213 aLba = capacity10Resp.iLba;
214 aBlockSize = capacity10Resp.iBlockSize;
216 __SCSIPRINT2(_L("Capacity LBA=0x%08x SIZE=0x%08x"),
219 iBlockTransfer.SetCapacityL(aBlockSize, aLba);
226 Create START STOP UNIT request. The function leaves if the device response is
227 not compliant with the protocol standard.
229 @param aStart SCSI START value
231 @return TInt KErrNone if successful otherwise KErrCommandFailed to indicate a
234 TInt TSbcClientInterface::StartStopUnitL(TBool aStart)
237 TScsiClientStartStopUnitReq startStopUnitReq;
239 startStopUnitReq.iImmed = ETrue;
240 startStopUnitReq.iLoej = EFalse;
241 startStopUnitReq.iStart = aStart;
243 TInt err = iTransport.SendControlCmdL(&startStopUnitReq);
250 Create WRITE (10) request and send to the transport layer. This performs a
251 logical block write of the device server. Note that TBlockTransfer must be
252 initialised beforehand. The function leaves if the device response is not
253 compliant with the protocol standard.
255 @param aLba Logical Block Address to write the data to
256 @param aBuffer Buffer containing the data
257 @param aPos Offset into the buffer to the data
258 @param aLen The number of bytes to be written (IN) and returns the bytes
259 actually transferred (OUT)
261 @return TInt KErrNone if successful otherwise KErrCommandFailed to indicate a
262 device status error or KErrArgument to indicate that aLen is too large for the
265 TInt TSbcClientInterface::Write10L(TLba aLba, TDesC8& aBuffer, TUint aPos, TInt& aLen)
268 __ASSERT_DEBUG(iBlockTransfer.BlockLength(), User::Panic(KUsbMsHostPanicCat, EBlockLengthNotSet));
269 __ASSERT_DEBUG(aLen % iBlockTransfer.BlockLength() == 0, User::Panic(KUsbMsHostPanicCat, EBlockDevice));
271 // check that buffer size is large enough
272 if (aBuffer.Length() < (aPos + aLen))
274 User::Leave(KErrArgument);
277 TScsiClientWrite10Req write10Req;
278 write10Req.iLogicalBlockAddress = aLba;
280 TInt blockTransferLength = aLen / iBlockTransfer.BlockLength();
281 if (blockTransferLength > static_cast<TInt>(KMaxTUint16))
283 User::Leave(KErrArgument);
285 write10Req.iBlockTransferLength = static_cast<TUint16>(blockTransferLength);
287 TInt err = iTransport.SendDataTxCmdL(&write10Req, aBuffer, aPos, aLen);