--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/f32test/smassstorage/src/scsicmdbuilder.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,150 @@
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Provides utilities to build SCSI commands
+//
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#include <e32std.h>
+#include <e32std_private.h>
+#include <testusbc.h>
+#include "scsicmdbuilder.h"
+
+#define SCSI_READ_WRITE_LEN 10
+#define SCSI_UNIT_READY_LEN 6
+#define SCSI_MED_RMVL_LEN 6
+#define SCSI_START_STOP_LEN 6
+
+GLDEF_D TBuf8<KScsiCmdMaxLen> scsiCmdBuf;
+GLREF_D RDevTestUsbcClient usbcClient;
+
+void BuildReadWrite(TInt aFlag, TInt aLogicalBlkAddr, TInt aTotalBlks)
+ //
+ // Builds SCSI read(10) / write(10) command
+ //
+ {
+ // Zero out the whole buffer
+ scsiCmdBuf.FillZ(SCSI_READ_WRITE_LEN);
+ scsiCmdBuf[0] = TUint8(aFlag); // opcode for read (0x28)/write (0x2A)
+
+ // Fill in logical block address. Big endian
+ scsiCmdBuf[2] = TUint8((aLogicalBlkAddr >> 24) & 0xFF);
+ scsiCmdBuf[3] = TUint8((aLogicalBlkAddr >> 16) & 0xFF);
+ scsiCmdBuf[4] = TUint8((aLogicalBlkAddr >> 8) & 0xFF);
+ scsiCmdBuf[5] = TUint8(aLogicalBlkAddr & 0xFF);
+
+ // Data transfer length (# of sectors). Big endian
+ scsiCmdBuf[7] = TUint8((aTotalBlks >> 8) & 0xFF);
+ scsiCmdBuf[8] = TUint8((aTotalBlks & 0xFF));
+
+ scsiCmdBuf.SetLength(SCSI_READ_WRITE_LEN);
+ }
+
+void BuildMediumRemoval(TInt aFlag)
+ //
+ // Builds prevent/allow medium removal command
+ //
+ {
+ // Zero out the buf
+ scsiCmdBuf.SetLength(SCSI_MED_RMVL_LEN);
+ scsiCmdBuf.FillZ(SCSI_MED_RMVL_LEN);
+ scsiCmdBuf[0] = 0x1E; // opcode for medium removal
+ scsiCmdBuf[4] = TUint8(aFlag); // prevent(1)/allow(0) medium removal
+ }
+
+void BuildTestUnitReady()
+ //
+ // Builds test unit ready command
+ //
+ {
+ // Zero out the buf
+ scsiCmdBuf.FillZ(SCSI_UNIT_READY_LEN);
+ scsiCmdBuf[0] = 0; // opcode for test unit ready
+
+ scsiCmdBuf.SetLength(SCSI_UNIT_READY_LEN);
+ }
+
+void BuildStartStopUnit(TInt aFlag)
+ //
+ // Builds start/stop unit command
+ //
+ {
+ const TUint8 KStartMask = 0x01;
+ const TUint8 KLoejMask = 0x02;
+ // Zero out the buf
+ scsiCmdBuf.FillZ(SCSI_START_STOP_LEN);
+ scsiCmdBuf[0] = 0x1B; // opcode for test unit ready
+ scsiCmdBuf[1] = 0x01; // set immed bit to true
+ scsiCmdBuf[4] = TUint8((aFlag == 1) ? KLoejMask & KStartMask : KLoejMask); // LOEJ + START or STOP
+
+ scsiCmdBuf.SetLength(SCSI_START_STOP_LEN);
+ }
+
+void fillInt(TUint8* dest, TInt source)
+ //
+ // Copy an int. Little endian
+ //
+ {
+ for (TInt i = 0; i < 4; i++)
+ {
+ *dest++ = TUint8((source >> i*8) & 0xFF);
+ }
+ }
+
+TInt extractInt(const TUint8* aBuf)
+ //
+ // Extract an integer from a buffer. Assume little endian
+ //
+ {
+ return aBuf[0] + (aBuf[1] << 8) + (aBuf[2] << 16) + (aBuf[3] << 24);
+ }
+
+void createCBW(TDes8& aCbw, TInt aDCBWTag, TInt aDataTransferLen, TUint8 aInOutFlag, TDes8& aCBWCB, TUint8 aTestLun)
+ //
+ // aCbw: stores CBW
+ // aDCBWTag: a command block tag sent by the host. Used to associates a CSW
+ // with corresponding CBW
+ // aDataTranferLen: the number of bytes the host expects to transfer
+ // aInOutFlag: value for bmCBWFlags field, indicating the direction of transfer
+ // aCBWCB the actual command to be wrapped
+ // aTestLun local unit number
+ {
+ // Zero out aCbw
+ aCbw.SetLength(KCbwLength);
+ aCbw.FillZ();
+
+ // dCBWSignature field, the value comes from spec
+ TInt dCBWSignature = 0x43425355;
+ fillInt(&aCbw[0], dCBWSignature);
+ // dCBWTag field
+ fillInt(&aCbw[4], aDCBWTag);
+ // dCBWDataTransferLength field
+ fillInt(&aCbw[8], aDataTransferLen);
+ // bmCBWFlags field
+ aCbw[12] = aInOutFlag;
+ aCbw[13] = aTestLun;
+ // bCBWCBLength field
+ aCbw[14] = TUint8(aCBWCB.Length());
+
+ // CBWCB field
+ for (TInt i = 0; i < aCbw[14]; ++i)
+ {
+ aCbw[15 + i] = aCBWCB[i];
+ }
+ }
+