userlibandfileserver/fileserver/shostmassstorage/server/protocol/tsbcclientinterface.cpp
changeset 43 96e5fb8b040d
child 44 36bfc973b146
equal deleted inserted replaced
-1:000000000000 43:96e5fb8b040d
       
     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 <e32base.h>
       
    22 #include <e32base_private.h>
       
    23 #include "msdebug.h"
       
    24 #include "debug.h"
       
    25 #include "msctypes.h"
       
    26 
       
    27 #include "mtransport.h"
       
    28 #include "mprotocol.h"
       
    29 #include "tscsiclientreq.h"
       
    30 
       
    31 #include "tblocktransfer.h"
       
    32 #include "mscutils.h"
       
    33 #include "usbmshostpanic.h"
       
    34 #include "tscsiblockcmds.h"
       
    35 #include "tsbcclientinterface.h"
       
    36 
       
    37 /**
       
    38 Constructor.
       
    39 
       
    40 @param aTransport The Transport interface to be used
       
    41 */
       
    42 TSbcClientInterface::TSbcClientInterface(MTransport& aTransport)
       
    43 :   iTransport(aTransport)
       
    44     {
       
    45     __MSFNLOG
       
    46     }
       
    47 
       
    48 
       
    49 TSbcClientInterface::~TSbcClientInterface()
       
    50     {
       
    51     __MSFNLOG
       
    52     }
       
    53 
       
    54 
       
    55 /**
       
    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.
       
    59 
       
    60 @param aPageCode The SCSI PAGE CODE value
       
    61 @param aWriteProtected The SCSI WP value
       
    62 
       
    63 @return TInt KErrNone if successful, KErrCommandFailed to indicate a
       
    64 device status error, KErrCommandStalled to indicate device stall
       
    65 */
       
    66 TInt TSbcClientInterface::ModeSense6L(TUint aPageCode, TBool& aWriteProtected)
       
    67     {
       
    68     __MSFNLOG
       
    69     TScsiClientModeSense6Req modeSense6Req(TScsiClientModeSense6Req::ECurrentValues,
       
    70                                            aPageCode);
       
    71     TScsiClientModeSense6Resp modeSense6Resp;
       
    72     TInt err = iTransport.SendControlCmdL(&modeSense6Req, &modeSense6Resp);
       
    73     if (!err)
       
    74         {
       
    75         __SCSIPRINT1(_L("SCSI MODE SENSE (6) INFO WrProtect=%d"),
       
    76                      modeSense6Resp.iWriteProtected);
       
    77         aWriteProtected = modeSense6Resp.iWriteProtected;
       
    78         }
       
    79     else
       
    80         {
       
    81         aWriteProtected = EFalse;
       
    82         }
       
    83 	return err;
       
    84     }
       
    85 
       
    86 
       
    87 /**
       
    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
       
    90 protocol standard.
       
    91 
       
    92 @param aPageCode The SCSI PAGE CODE value
       
    93 @param aWriteProtected The SCSI WP value
       
    94 
       
    95 @return TInt KErrNone if successful, KErrCommandFailed to indicate a
       
    96 device status error, KErrCommandStalled to indicate a device stall
       
    97 */
       
    98 TInt TSbcClientInterface::ModeSense10L(TUint aPageCode, TBool& aWriteProtected)
       
    99     {
       
   100     __MSFNLOG
       
   101     TScsiClientModeSense10Req modeSense10Req(TScsiClientModeSense10Req::ECurrentValues,
       
   102                                              aPageCode);
       
   103     TScsiClientModeSense10Resp modeSense10Resp;
       
   104     TInt err = iTransport.SendControlCmdL(&modeSense10Req, &modeSense10Resp);
       
   105 
       
   106     if (!err)
       
   107         {
       
   108         __SCSIPRINT1(_L("SCSI MODE SENSE (10) INFO WrProtect=%d"),
       
   109                      modeSense10Resp.iWriteProtected);
       
   110         aWriteProtected = modeSense10Resp.iWriteProtected;
       
   111         }
       
   112     else
       
   113         {
       
   114         aWriteProtected = EFalse;
       
   115         }
       
   116 	return err;
       
   117     }
       
   118 
       
   119 
       
   120 /**
       
   121 Constructor to create SCSI MODE SENSE (10) request.
       
   122 
       
   123 @param aPageControl The SCSI PAGE CODE value
       
   124 @param aPageCode The SCSI WP value
       
   125 @param aSubPageCode The SCSI SUB PAGE CODE value
       
   126 */
       
   127 TScsiClientModeSense10Req::TScsiClientModeSense10Req(TPageControl aPageControl,
       
   128                                                      TUint aPageCode,
       
   129                                                      TUint aSubPageCode)
       
   130     :
       
   131     TScsiClientReq(EModeSense10),
       
   132     iPageControl(aPageControl),
       
   133     iPageCode(aPageCode),
       
   134     iSubPageCode(aSubPageCode),
       
   135     iAllocationLength(KResponseLength)
       
   136     {
       
   137     __MSFNLOG
       
   138     }
       
   139 
       
   140 
       
   141 TInt TScsiClientModeSense10Req::EncodeRequestL(TDes8& aBuffer) const
       
   142     {
       
   143     __MSFNSLOG
       
   144     __SCSIPRINT(_L("<-- SCSI MODE SENSE (10)"));
       
   145     TInt length = TScsiClientReq::EncodeRequestL(aBuffer);
       
   146 
       
   147     // PC
       
   148     aBuffer[2] = iPageCode;
       
   149     aBuffer[2] |= iPageControl << 6;
       
   150     aBuffer[3] = iSubPageCode;
       
   151 
       
   152     BigEndian::Put16(&aBuffer[7], iAllocationLength);
       
   153     return length;
       
   154     }
       
   155 
       
   156 /**
       
   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.
       
   162 
       
   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
       
   166 actually read (OUT)
       
   167 
       
   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
       
   170 protocol.
       
   171 */
       
   172 TInt TSbcClientInterface::Read10L(TLba aLba, TDes8& aBuffer, TInt& aLen)
       
   173     {
       
   174     __MSFNLOG
       
   175 	__ASSERT_DEBUG(iBlockTransfer.BlockLength(), User::Panic(KUsbMsHostPanicCat, EBlockLengthNotSet));
       
   176     __ASSERT_DEBUG(aLen % iBlockTransfer.BlockLength() == 0, User::Panic(KUsbMsHostPanicCat, EBlockDevice));
       
   177 
       
   178     TScsiClientRead10Req read10Req;
       
   179 
       
   180     read10Req.iLogicalBlockAddress = aLba;
       
   181 
       
   182     TInt blockTransferLength = aLen / iBlockTransfer.BlockLength();
       
   183     if (blockTransferLength > static_cast<TInt>(KMaxTUint16))
       
   184         {
       
   185         User::Leave(KErrArgument);
       
   186         }
       
   187     read10Req.iBlockTransferLength = static_cast<TUint16>(blockTransferLength);
       
   188     TInt err = iTransport.SendDataRxCmdL(&read10Req, aBuffer, aLen);
       
   189 	return err;
       
   190     }
       
   191 
       
   192 /**
       
   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.
       
   197 
       
   198 @param aLba The Logical Block Address returned by the LU
       
   199 @param aBlockSize The Block Size returned by the LU
       
   200 
       
   201 @return TInt KErrNone if successful, KErrCommandFailed to indicate a
       
   202 device status error, KErrCommandStalled to indicate a device stall
       
   203 */
       
   204 TInt TSbcClientInterface::ReadCapacity10L(TLba& aLba, TUint32& aBlockSize)
       
   205     {
       
   206     __MSFNLOG
       
   207     TScsiClientReadCapacity10Req capacity10Req;
       
   208     TScsiClientReadCapacity10Resp capacity10Resp;
       
   209 
       
   210     TInt err = iTransport.SendControlCmdL(&capacity10Req, &capacity10Resp);
       
   211     if (!err)
       
   212         {
       
   213         aLba = capacity10Resp.iLba;
       
   214         aBlockSize = capacity10Resp.iBlockSize;
       
   215 
       
   216         __SCSIPRINT2(_L("Capacity LBA=0x%08x SIZE=0x%08x"),
       
   217                      aLba, aBlockSize);
       
   218 
       
   219         iBlockTransfer.SetCapacityL(aBlockSize, aLba);
       
   220         }
       
   221 	return err;
       
   222     }
       
   223 
       
   224 
       
   225 /**
       
   226 Create START STOP UNIT request. The function leaves if the device response is
       
   227 not compliant with the protocol standard.
       
   228 
       
   229 @param aStart SCSI START value
       
   230 
       
   231 @return TInt KErrNone if successful otherwise KErrCommandFailed to indicate a
       
   232 device status error
       
   233 */
       
   234 TInt TSbcClientInterface::StartStopUnitL(TBool aStart)
       
   235     {
       
   236     __MSFNLOG
       
   237     TScsiClientStartStopUnitReq startStopUnitReq;
       
   238 
       
   239     startStopUnitReq.iImmed = ETrue;
       
   240     startStopUnitReq.iLoej = EFalse;
       
   241     startStopUnitReq.iStart = aStart;
       
   242 
       
   243     TInt err = iTransport.SendControlCmdL(&startStopUnitReq);
       
   244 
       
   245 	return err;
       
   246     }
       
   247 
       
   248 
       
   249 /**
       
   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.
       
   254 
       
   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)
       
   260 
       
   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
       
   263 protocol.
       
   264 */
       
   265 TInt TSbcClientInterface::Write10L(TLba aLba, TDesC8& aBuffer, TUint aPos, TInt& aLen)
       
   266     {
       
   267     __MSFNLOG
       
   268 	__ASSERT_DEBUG(iBlockTransfer.BlockLength(), User::Panic(KUsbMsHostPanicCat, EBlockLengthNotSet));
       
   269     __ASSERT_DEBUG(aLen % iBlockTransfer.BlockLength() == 0, User::Panic(KUsbMsHostPanicCat, EBlockDevice));
       
   270 
       
   271     // check that buffer size is large enough
       
   272 	if (aBuffer.Length() < (aPos + aLen))
       
   273 		{
       
   274         User::Leave(KErrArgument);
       
   275 		}
       
   276 
       
   277     TScsiClientWrite10Req write10Req;
       
   278     write10Req.iLogicalBlockAddress = aLba;
       
   279 
       
   280     TInt blockTransferLength = aLen / iBlockTransfer.BlockLength();
       
   281     if (blockTransferLength > static_cast<TInt>(KMaxTUint16))
       
   282         {
       
   283         User::Leave(KErrArgument);
       
   284         }
       
   285     write10Req.iBlockTransferLength = static_cast<TUint16>(blockTransferLength);
       
   286 
       
   287     TInt err = iTransport.SendDataTxCmdL(&write10Req, aBuffer, aPos, aLen);
       
   288 	return err;
       
   289     }
       
   290