kerneltest/f32test/smassstorage/src/scsicmdbuilder.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2004-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 // Provides utilities to build SCSI commands
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalTechnology
       
    21 */
       
    22 
       
    23 #include <e32std.h>
       
    24 #include <e32std_private.h>
       
    25 #include <testusbc.h>
       
    26 #include "scsicmdbuilder.h"
       
    27 
       
    28 #define SCSI_READ_WRITE_LEN       10
       
    29 #define SCSI_UNIT_READY_LEN        6
       
    30 #define SCSI_MED_RMVL_LEN          6
       
    31 #define SCSI_START_STOP_LEN        6
       
    32 
       
    33 GLDEF_D TBuf8<KScsiCmdMaxLen> scsiCmdBuf;
       
    34 GLREF_D RDevTestUsbcClient usbcClient;
       
    35 
       
    36 void BuildReadWrite(TInt aFlag, TInt aLogicalBlkAddr, TInt aTotalBlks)
       
    37     // 
       
    38     // Builds SCSI read(10) / write(10) command
       
    39     //
       
    40     {
       
    41     // Zero out the whole buffer
       
    42     scsiCmdBuf.FillZ(SCSI_READ_WRITE_LEN);
       
    43     scsiCmdBuf[0] = TUint8(aFlag);     // opcode for read (0x28)/write (0x2A)
       
    44 
       
    45     // Fill in logical block address. Big endian
       
    46     scsiCmdBuf[2] = TUint8((aLogicalBlkAddr >> 24) & 0xFF);
       
    47     scsiCmdBuf[3] = TUint8((aLogicalBlkAddr >> 16) & 0xFF);
       
    48     scsiCmdBuf[4] = TUint8((aLogicalBlkAddr >> 8) & 0xFF);
       
    49     scsiCmdBuf[5] = TUint8(aLogicalBlkAddr & 0xFF);
       
    50     
       
    51     // Data transfer length (# of sectors). Big endian
       
    52     scsiCmdBuf[7] = TUint8((aTotalBlks >> 8) & 0xFF);
       
    53     scsiCmdBuf[8] = TUint8((aTotalBlks & 0xFF));
       
    54 
       
    55     scsiCmdBuf.SetLength(SCSI_READ_WRITE_LEN);
       
    56     }
       
    57 
       
    58 void BuildMediumRemoval(TInt aFlag)
       
    59     //
       
    60     // Builds prevent/allow medium removal command
       
    61     // 
       
    62     {
       
    63     // Zero out the buf
       
    64     scsiCmdBuf.SetLength(SCSI_MED_RMVL_LEN);
       
    65     scsiCmdBuf.FillZ(SCSI_MED_RMVL_LEN);
       
    66     scsiCmdBuf[0] = 0x1E;             // opcode for medium removal
       
    67     scsiCmdBuf[4] = TUint8(aFlag);    // prevent(1)/allow(0) medium removal 
       
    68     }
       
    69 
       
    70 void BuildTestUnitReady()
       
    71     //
       
    72     // Builds test unit ready command
       
    73     // 
       
    74     {
       
    75     // Zero out the buf
       
    76     scsiCmdBuf.FillZ(SCSI_UNIT_READY_LEN);
       
    77     scsiCmdBuf[0] = 0;                // opcode for test unit ready
       
    78 
       
    79     scsiCmdBuf.SetLength(SCSI_UNIT_READY_LEN);
       
    80     }
       
    81 
       
    82 void BuildStartStopUnit(TInt aFlag)
       
    83     //
       
    84     // Builds start/stop unit command
       
    85     // 
       
    86     {
       
    87     const TUint8 KStartMask = 0x01;
       
    88     const TUint8 KLoejMask = 0x02;
       
    89     // Zero out the buf
       
    90     scsiCmdBuf.FillZ(SCSI_START_STOP_LEN);
       
    91     scsiCmdBuf[0] = 0x1B;             // opcode for test unit ready
       
    92     scsiCmdBuf[1] = 0x01;			  // set immed bit to true
       
    93     scsiCmdBuf[4] = TUint8((aFlag == 1) ? KLoejMask & KStartMask : KLoejMask);  // LOEJ + START or STOP
       
    94 
       
    95     scsiCmdBuf.SetLength(SCSI_START_STOP_LEN);
       
    96     }
       
    97 
       
    98 void fillInt(TUint8* dest, TInt source)
       
    99     // 
       
   100     // Copy an int. Little endian
       
   101     //
       
   102     {
       
   103     for (TInt i = 0; i < 4; i++)
       
   104         {
       
   105         *dest++ = TUint8((source >> i*8) & 0xFF);
       
   106         }
       
   107     }
       
   108 
       
   109 TInt extractInt(const TUint8* aBuf)
       
   110     //
       
   111     // Extract an integer from a buffer. Assume little endian
       
   112     //
       
   113     {
       
   114     return aBuf[0] + (aBuf[1] << 8) + (aBuf[2] << 16) + (aBuf[3] << 24);
       
   115     }
       
   116 
       
   117 void createCBW(TDes8& aCbw, TInt aDCBWTag, TInt aDataTransferLen, TUint8 aInOutFlag, TDes8& aCBWCB, TUint8 aTestLun)
       
   118     // 
       
   119     // aCbw:            stores CBW
       
   120     // aDCBWTag:        a command block tag sent by the host. Used to associates a CSW
       
   121     //                  with corresponding CBW
       
   122     // aDataTranferLen: the number of bytes the host expects to transfer
       
   123     // aInOutFlag:      value for bmCBWFlags field, indicating the direction of transfer
       
   124     // aCBWCB			the actual command to be wrapped
       
   125     // aTestLun			local unit number
       
   126     {
       
   127     // Zero out aCbw
       
   128     aCbw.SetLength(KCbwLength);
       
   129     aCbw.FillZ();
       
   130 
       
   131     // dCBWSignature field, the value comes from spec
       
   132     TInt dCBWSignature = 0x43425355;
       
   133     fillInt(&aCbw[0], dCBWSignature);
       
   134     // dCBWTag field
       
   135     fillInt(&aCbw[4], aDCBWTag);
       
   136     // dCBWDataTransferLength field
       
   137     fillInt(&aCbw[8], aDataTransferLen);
       
   138     // bmCBWFlags field
       
   139     aCbw[12] = aInOutFlag;
       
   140 	aCbw[13] = aTestLun;
       
   141     // bCBWCBLength field
       
   142     aCbw[14] = TUint8(aCBWCB.Length());          
       
   143 	
       
   144     // CBWCB field
       
   145     for (TInt i = 0; i < aCbw[14]; ++i)
       
   146     	{
       
   147     	aCbw[15 + i] = aCBWCB[i];
       
   148     	}
       
   149     }
       
   150