userlibandfileserver/fileserver/shostmassstorage/server/protocol/tscsiblockcmds.cpp
// Copyright (c) 2008-2010 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:
//
/**
@file
@internalTechnology
*/
#include <e32base.h>
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
#include "tscsiblockcmdsTraces.h"
#endif
#include "msctypes.h"
#include "mscutils.h"
#include "mtransport.h"
#include "mprotocol.h"
#include "tscsiclientreq.h"
#include "tscsiblockcmds.h"
// **** MODE SENSE (6) ****
void TScsiClientModeSense6Resp::DecodeL(const TDesC8& aPtr)
{
OstTrace0(TRACE_SHOSTMASSSTORAGE_SCSI, TSCSIBLOCKCMDS_10,
"--> SCSI MODE SENSE (6)");
OstTrace1(TRACE_SHOSTMASSSTORAGE_SCSI, TSCSIBLOCKCMDS_11,
"len=%d", aPtr.Length());
// Mode Parameter List
// SPC-3 7.4.2
// - Mode Parameter Header
// - Block Descriptor(s)
// - Mode Page(s)
// Mode Parameter Header
// SPC-3 7.4.3
// [0] Mode Data Length
// [1] Medium Type
// [2] Device-Specific Paramater
// [3] Block Descriptor Length
// validate length
if (aPtr.Length() < KResponseLength)
{
User::Leave(KErrGeneral);
}
TInt modeDataLength = aPtr[0];
if (aPtr.Length() - 1 > modeDataLength)
{
User::Leave(KErrGeneral);
}
TInt mediumType = aPtr[1];
TUint8 deviceSpecificParameter = aPtr[2];
// TInt blockDescriptorLength = aPtr[3];
OstTraceExt2(TRACE_SHOSTMASSSTORAGE_SCSI, TSCSIBLOCKCMDS_20,
"Medium Type=%d DSP=0x%x", mediumType, deviceSpecificParameter);
// [1] Medium Type
// 0x00 for SBC
if (mediumType == 0)
{
// [2] Device specific parameter
// SBC-3 6.3.1
// get the WP bit from the Device Specific parameters
iWriteProtected = (deviceSpecificParameter & 0x80) ? ETrue : EFalse;
}
else
{
// unsupported medium type
iWriteProtected = EFalse;
}
// [3] Block Descriptor Length
// 0x00 for no descriptors
// No Block Descriptors
// No Mode Pages
}
// **** MODE SENSE (10) ****
void TScsiClientModeSense10Resp::DecodeL(const TDesC8& aPtr)
{
OstTrace0(TRACE_SHOSTMASSSTORAGE_SCSI, TSCSIBLOCKCMDS_30,
"--> SCSI MODE SENSE (10)");
OstTrace1(TRACE_SHOSTMASSSTORAGE_SCSI, TSCSIBLOCKCMDS_31,
"len=%d", aPtr.Length());
// Mode Parameter List
// SPC-3 7.4.2
// - Mode Parameter Header
// - Block Descriptor(s)
// - Mode Page(s)
// Mode Parameter Header
// SPC-3 7.4.3
// [0] Mode Data Length
// [1] Mode Data Length
// [2] Medium Type
// [3] Device-Specific Paramater
// [4] Reserved
// [5] Reserved
// [6] Block Descriptor Length
// [7] Block Descriptor Length
// validate length
if (aPtr.Length() < KResponseLength)
{
User::Leave(KErrGeneral);
}
TInt modeDataLength = BigEndian::Get16(&aPtr[0]);
if (aPtr.Length() - 2 > modeDataLength)
{
User::Leave(KErrGeneral);
}
TInt mediumType = aPtr[2];
TUint8 deviceSpecificParameter = aPtr[3];
// TInt blockDescriptorLength = BigEndian::Get32(&aPtr[6]);;
OstTraceExt2(TRACE_SHOSTMASSSTORAGE_SCSI, TSCSIBLOCKCMDS_40,
"Medium Type=%d DSP=0x%x", mediumType, deviceSpecificParameter);
// [1] Medium Type
// 0x00 for SBC
if (mediumType == 0)
{
// [2] Device specific parameter
// SBC-3 6.3.1
// get the WP bit from the Device Specific parameters
iWriteProtected = (deviceSpecificParameter & 0x80) ? ETrue : EFalse;
}
else
{
// unsupported medium type
iWriteProtected = EFalse;
}
// [3] Block Descriptor Length
// 0x00 for no descriptors
// No Block Descriptors
// No Mode Pages
}
// **** READ CAPACITY (10) ***
TInt TScsiClientReadCapacity10Req::EncodeRequestL(TDes8& aBuffer) const
{
OstTrace0(TRACE_SHOSTMASSSTORAGE_SCSI, TSCSIBLOCKCMDS_50,
"<-- READ CAPACITY 10");
TInt length = TScsiClientReq::EncodeRequestL(aBuffer);
if (iLba)
{
// PMI bit
aBuffer[8] = 0x01;
// LBA
BigEndian::Put32(&aBuffer[2], iLba);
}
return length;
}
void TScsiClientReadCapacity10Resp::DecodeL(const TDesC8& aPtr)
{
OstTrace0(TRACE_SHOSTMASSSTORAGE_SCSI, TSCSIBLOCKCMDS_60,
"--> SCSI READ CAPACITY (10)");
iLba = BigEndian::Get32(&aPtr[0]);
iBlockSize = BigEndian::Get32(&aPtr[4]);
}
// **** RdWr10 ****
TInt TScsiClientRdWr10Req::EncodeRequestL(TDes8& aBuffer) const
{
TInt length = TScsiClientReq::EncodeRequestL(aBuffer);
// PROTECT
if (iProtect)
aBuffer[1] = iProtect << 5;
OstTraceExt2(TRACE_SHOSTMASSSTORAGE_SCSI, TSCSIBLOCKCMDS_70,
"LBA=%08x LEN=%08x", iLogicalBlockAddress, iBlockTransferLength);
// LOGICAL BLOCK ADDRESS
BigEndian::Put32(&aBuffer[2], iLogicalBlockAddress);
// TRANSFER LENGTH
BigEndian::Put16(&aBuffer[7], iBlockTransferLength);
return length;
}
// **** READ (10) ****
TInt TScsiClientRead10Req::EncodeRequestL(TDes8& aBuffer) const
{
OstTrace0(TRACE_SHOSTMASSSTORAGE_SCSI, TSCSIBLOCKCMDS_80,
"<-- SCSI READ (10)");
TInt length = TScsiClientRdWr10Req::EncodeRequestL(aBuffer);
return length;
}
// **** START STOP UNIT ****
TInt TScsiClientStartStopUnitReq::EncodeRequestL(TDes8& aBuffer) const
{
OstTrace0(TRACE_SHOSTMASSSTORAGE_SCSI, TSCSIBLOCKCMDS_90,
"--> SCSI START STOP UNIT");
TInt length = TScsiClientReq::EncodeRequestL(aBuffer);
// byte 1 mask
const TUint8 KImmedMask = 0x01;
// byte 4 mask
const TUint8 KStartMask = 0x01;
const TUint8 KLoejMask = 0x02;
if (iImmed)
aBuffer[1] |= KImmedMask;
if (iStart)
aBuffer[4] |= KStartMask;
if (iLoej)
aBuffer[4] |= KLoejMask;
return length;
}
// **** WRITE (10) ****
TInt TScsiClientWrite10Req::EncodeRequestL(TDes8& aBuffer) const
{
OstTrace0(TRACE_SHOSTMASSSTORAGE_SCSI, TSCSIBLOCKCMDS_91,
"<-- SCSI WRITE 10");
TInt length = TScsiClientRdWr10Req::EncodeRequestL(aBuffer);
return length;
}