sl@0: // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: sl@0: #include <e32def.h> sl@0: #include <e32cmn.h> sl@0: #include <e32des8.h> sl@0: #include <e32std.h> sl@0: sl@0: #include "mstypes.h" sl@0: #include "msctypes.h" sl@0: #include "mscutils.h" sl@0: #include "scsimsctypes.h" sl@0: sl@0: #include "tscsiserverreq.h" sl@0: #include "tscsiservercmds.h" sl@0: #include "debug.h" sl@0: #include "msdebug.h" sl@0: sl@0: /** sl@0: Default constructor for TSenseInfo sl@0: */ sl@0: TSrvSenseInfo::TSrvSenseInfo() sl@0: { sl@0: __MSFNLOG sl@0: iSenseCode = ENoSense; sl@0: iAdditional = 0; sl@0: iQualifier = 0; sl@0: } sl@0: sl@0: /** sl@0: Set sense with no additional info. sl@0: sl@0: @param aSenseCode sense key sl@0: */ sl@0: void TSrvSenseInfo::SetSense(TSenseCode aSenseCode) sl@0: { sl@0: __MSFNLOG sl@0: iSenseCode = static_cast<TUint8>(aSenseCode); sl@0: iAdditional = 0; sl@0: iQualifier = 0; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Set sense with additional info. sl@0: sl@0: @param aSenseCode sense key sl@0: @param aAdditional additional sense code (ASC) sl@0: */ sl@0: void TSrvSenseInfo::SetSense(TSenseCode aSenseCode, sl@0: TAdditionalCode aAdditional) sl@0: sl@0: { sl@0: __MSFNLOG sl@0: iSenseCode = static_cast<TUint8>(aSenseCode); sl@0: iAdditional = static_cast<TUint8>(aAdditional); sl@0: iQualifier = 0; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Set sense with additional info and qualifier. sl@0: sl@0: @param aSenseCode sense key sl@0: @param aAdditional additional sense code (ASC) sl@0: @param aQualifier additional sense code qualifier (ASCQ) sl@0: */ sl@0: void TSrvSenseInfo::SetSense(TSenseCode aSenseCode, sl@0: TAdditionalCode aAdditional, sl@0: TUint8 aQualifier) sl@0: { sl@0: __MSFNLOG sl@0: iSenseCode = static_cast<TUint8>(aSenseCode); sl@0: iAdditional = static_cast<TUint8>(aAdditional); sl@0: iQualifier = aQualifier; sl@0: } sl@0: sl@0: sl@0: // **** TEST UNIT READY **** sl@0: // **** REQUEST SENSE **** sl@0: void TScsiServerRequestSenseResp::Encode(TDes8& aBuffer) const sl@0: { sl@0: __MSFNSLOG sl@0: aBuffer.FillZ(KCommandLength); sl@0: __PRINT(_L("->PROTOCOL(SCSI) REQUEST SENSE\n")); sl@0: //additional sense length sl@0: aBuffer[07] = static_cast<TUint8>(KCommandLength - 8); sl@0: sl@0: aBuffer[0] = iResponseCode; sl@0: aBuffer[02] = static_cast<TUint8>(iSensePtr->iSenseCode); sl@0: aBuffer[12] = iSensePtr->iAdditional; sl@0: aBuffer[13] = iSensePtr->iQualifier; sl@0: sl@0: //truncate to Allocation Length of the Request sl@0: TUint length = iAllocationLength < KCommandLength ? sl@0: iAllocationLength : KCommandLength; sl@0: aBuffer.SetLength(length); sl@0: } sl@0: sl@0: // **** INQUIRY **** sl@0: void TScsiServerInquiryReq::DecodeL(const TDesC8& aPtr) sl@0: { sl@0: __MSFNLOG sl@0: TScsiServerReq::DecodeL(aPtr); sl@0: iCmdDt = aPtr[1] & 0x2; sl@0: iEvpd = aPtr[1] & 0x1; sl@0: iPage = aPtr[2]; sl@0: iAllocationLength = aPtr[4]; sl@0: __PRINT(_L("<-PROTOCOL(SCSI) INQUIRY\n")); sl@0: } sl@0: sl@0: sl@0: void TScsiServerInquiryResp::Encode(TDes8& aBuffer) const sl@0: { sl@0: __MSFNSLOG sl@0: __PRINT(_L("->PROTOCOL(SCSI) INQUIRY\n")); sl@0: sl@0: aBuffer.FillZ(KResponseLength); sl@0: sl@0: // MSB: RMB : Removable sl@0: if (iRemovable) sl@0: { sl@0: aBuffer[1] |= 0x80; sl@0: } sl@0: sl@0: // AERC, TrmTsk, NormACA, Response Data Format sl@0: aBuffer[3] |= (iResponseDataFormat & 0x0F); sl@0: sl@0: // Additional Length sl@0: aBuffer[4] = 0x1F; sl@0: sl@0: // Vendor ID (Vendor Specific/Logged by T10) sl@0: TPtr8 vendorId(&aBuffer[8], 8, 8); sl@0: vendorId.Fill(' ', 8); sl@0: vendorId.Copy(iConfig.iVendorId); sl@0: sl@0: // Product ID (Vendor Specific) sl@0: TPtr8 productId(&aBuffer[16], 16, 16); sl@0: productId.Fill(' ', 16); sl@0: productId.Copy(iConfig.iProductId); sl@0: sl@0: // Product Revision Level (Vendor Specific) sl@0: TPtr8 productRev(&aBuffer[32], 4, 4); sl@0: productRev.Fill(' ', 4); sl@0: productRev.Copy(iConfig.iProductRev); sl@0: sl@0: // Truncate to Allocation Length of the Request sl@0: TUint length = iAllocationLength < KResponseLength ? sl@0: iAllocationLength : KResponseLength; sl@0: aBuffer.SetLength(length); sl@0: } sl@0: sl@0: sl@0: // **** MODE SENSE (6) **** sl@0: void TScsiServerModeSense6Req::DecodeL(const TDesC8& aPtr) sl@0: { sl@0: __MSFNLOG sl@0: TScsiServerReq::DecodeL(aPtr); sl@0: iPageCode = aPtr[2] & 0x3F; sl@0: iPageControl = static_cast<TPageControl>(aPtr[2] >> 6); sl@0: iAllocationLength = aPtr[4]; sl@0: __PRINT(_L("<-PROTOCOL(SCSI) MODE SENSE (6)\n")); sl@0: } sl@0: sl@0: sl@0: void TScsiServerModeSense6Resp::Encode(TDes8& aBuffer) const sl@0: { sl@0: __MSFNSLOG sl@0: __PRINT(_L("->PROTOCOL(SCSI) MODE SENSE (6)\n")); sl@0: // reserve 4 bytes for Length, Media type, Device-specific parameter and sl@0: // Block descriptor length sl@0: aBuffer.FillZ(KCommandLength); sl@0: sl@0: // Mode Parameter List sl@0: // SPC-3 7.4.2 sl@0: // - Mode Parameter Header sl@0: // - Block Descriptor(s) sl@0: // - Mode Page(s) sl@0: sl@0: // Mode Parameter Header sl@0: // SPC-3 7.4.3 sl@0: // [0] Mode Data Length sl@0: // [1] Medium Type sl@0: // [2] Device-Specific Paramater sl@0: // [3] Block Descriptor Length sl@0: sl@0: // [0] Mode Date Length sl@0: // Sending only Mode parameter header sl@0: aBuffer[0] = 3; sl@0: sl@0: // [1] Medium Type sl@0: // 0x00 for SBC sl@0: sl@0: // [2] Device specific parameter sl@0: // SBC-3 6.3.1 sl@0: // set SWP bit at the Device Specific parameters sl@0: if (iWp) sl@0: { sl@0: aBuffer[2] |= 0x80; sl@0: } sl@0: sl@0: // [3] Block Descriptor Length sl@0: // 0x00 for no descriptors sl@0: sl@0: // No Block Descriptors sl@0: sl@0: // No Mode Pages sl@0: sl@0: // Truncate to Allocation Length of the Request sl@0: TUint length = iAllocationLength < KCommandLength ? sl@0: iAllocationLength : KCommandLength; sl@0: aBuffer.SetLength(length); sl@0: } sl@0: sl@0: // **** START STOP UNIT **** sl@0: void TScsiServerStartStopUnitReq::DecodeL(const TDesC8& aPtr) sl@0: { sl@0: __MSFNLOG sl@0: TScsiServerReq::DecodeL(aPtr); sl@0: sl@0: const TUint8 KStartMask = 0x01; sl@0: const TUint8 KImmedMask = 0x01; sl@0: const TUint8 KLoejMask = 0x02; sl@0: sl@0: iImmed = aPtr[1] & KImmedMask ? ETrue : EFalse; sl@0: iStart = aPtr[4] & KStartMask ? ETrue : EFalse; sl@0: iLoej = aPtr[4] & KLoejMask ? ETrue : EFalse; sl@0: sl@0: __PRINT2(_L("<-PROTOCOL(SCSI) START STOP UNIT Data %X %X\n"), aPtr[1], aPtr[4]); sl@0: __PRINT1(_L("IMMED = %d\n"), iImmed); sl@0: __PRINT1(_L("START = %d\n"), iStart); sl@0: __PRINT1(_L("LOEJ = %d\n"), iLoej); sl@0: } sl@0: sl@0: sl@0: // **** PREVENT MEDIA REMOVAL **** sl@0: void TScsiServerPreventMediaRemovalReq::DecodeL(const TDesC8& aPtr) sl@0: { sl@0: __MSFNLOG sl@0: TScsiServerReq::DecodeL(aPtr); sl@0: iPrevent = aPtr[4] & 0x01; sl@0: __PRINT1(_L("<-PROTOCOL(SCSI) PREVENT MEDIA REMOVAL prevent = %d\n"), iPrevent); sl@0: } sl@0: sl@0: sl@0: // **** READ FORMAT CAPACITIES **** sl@0: void TScsiServerReadFormatCapacitiesReq::DecodeL(const TDesC8& aPtr) sl@0: { sl@0: __MSFNLOG sl@0: TScsiServerReq::DecodeL(aPtr); sl@0: const TUint8* ptr = aPtr.Ptr(); sl@0: iAllocationLength = BigEndian::Get32(ptr+7); sl@0: __PRINT(_L("<-PROTOCOL(SCSI) READ FORMAT CAPACITIES\n")); sl@0: } sl@0: sl@0: sl@0: void TScsiServerReadFormatCapacitiesResp::Encode(TDes8& aBuffer) const sl@0: { sl@0: __MSFNSLOG sl@0: __PRINT(_L("->PROTOCOL(SCSI) READ FORMAT CAPACITIES\n")); sl@0: aBuffer.FillZ(KResponseLength); sl@0: aBuffer[3] = 0x08; // Capacity List Length sl@0: sl@0: aBuffer[4] = static_cast<TUint8>(iNumberBlocks >> 24); // Number of blocks sl@0: aBuffer[5] = static_cast<TUint8>(iNumberBlocks >> 16); // sl@0: aBuffer[6] = static_cast<TUint8>(iNumberBlocks >> 8); // sl@0: aBuffer[7] = static_cast<TUint8>(iNumberBlocks); // sl@0: sl@0: aBuffer[8] = 0x02; // Formatted size sl@0: sl@0: aBuffer[9] = 0x00; // 512 Byte Blocks sl@0: aBuffer[10] = 0x02; // sl@0: aBuffer[11] = 0x00; // sl@0: sl@0: // Truncate to Allocation Length of the Request sl@0: // Truncate to Allocation Length of the Request sl@0: TUint length = iAllocationLength < KResponseLength ? sl@0: iAllocationLength : KResponseLength; sl@0: aBuffer.SetLength(length); sl@0: } sl@0: sl@0: sl@0: // **** READ CAPACITY (10) **** sl@0: void TScsiServerReadCapacity10Req::DecodeL(const TDesC8& aPtr) sl@0: { sl@0: __MSFNLOG sl@0: TScsiServerReq::DecodeL(aPtr); sl@0: iPmi = aPtr[8] & 0x01; sl@0: const TUint8* ptr = aPtr.Ptr(); sl@0: iLogicalBlockAddress = BigEndian::Get32(ptr+2); sl@0: __PRINT(_L("<-PROTOCOL(SCSI) READ CAPACITY (10)\n")); sl@0: } sl@0: sl@0: sl@0: void TScsiServerReadCapacity10Resp::Encode(TDes8& aBuffer) const sl@0: { sl@0: __MSFNSLOG sl@0: aBuffer.FillZ(KCommandLength); sl@0: sl@0: __PRINT3(_L("->PROTOCOL(SCSI) READ CAPACITY (10) Block size=0x%X, NumBlocks=0x%08X%08X\n"), sl@0: iBlockSize, sl@0: I64HIGH(iNumberBlocks), sl@0: I64LOW(iNumberBlocks)); sl@0: sl@0: if (I64HIGH(iNumberBlocks) == 0) sl@0: { sl@0: TUint32 numBlocks = I64LOW(iNumberBlocks); sl@0: sl@0: // Number of blocks sl@0: aBuffer[0] = static_cast<TUint8>(numBlocks >> 24); sl@0: aBuffer[1] = static_cast<TUint8>(numBlocks >> 16); sl@0: aBuffer[2] = static_cast<TUint8>(numBlocks >> 8); sl@0: aBuffer[3] = static_cast<TUint8>(numBlocks); sl@0: } sl@0: else sl@0: { sl@0: // indicate that size more then )0xFFFFFFFF sl@0: aBuffer[0] = aBuffer[1] = aBuffer[2] = aBuffer[3] = 0xFF; sl@0: } sl@0: sl@0: // Block Size sl@0: aBuffer[4] = static_cast<TUint8>(iBlockSize >> 24); sl@0: aBuffer[5] = static_cast<TUint8>(iBlockSize >> 16); sl@0: aBuffer[6] = static_cast<TUint8>(iBlockSize >> 8); sl@0: aBuffer[7] = static_cast<TUint8>(iBlockSize); sl@0: } sl@0: sl@0: sl@0: // **** RdWr10 **** sl@0: void TScsiServerRdWr10Req::DecodeL(const TDesC8& aDes) sl@0: { sl@0: __MSFNLOG sl@0: TScsiServerReq::DecodeL(aDes); sl@0: sl@0: // PROTECT sl@0: iProtect = aDes[1] >> 5; sl@0: sl@0: const TUint8* ptr = aDes.Ptr(); sl@0: // LOGICAL BLOCK ADDRESS sl@0: iLogicalBlockAddress = BigEndian::Get32(ptr+2); sl@0: // TRANSFER LENGTH sl@0: iTransferLength = BigEndian::Get16(ptr+7); sl@0: sl@0: __PRINT2(_L("<-PROTOCOL(SCSI) RD/WR (10) : LBA = %x, Length = %x (blocks)\n"), sl@0: iLogicalBlockAddress, iTransferLength); sl@0: } sl@0: sl@0: sl@0: // **** READ (10) **** sl@0: // **** WRITE (10) **** sl@0: // **** VERIFY (10) **** sl@0: void TScsiServerVerify10Req::DecodeL(const TDesC8& aPtr) sl@0: { sl@0: __MSFNLOG sl@0: TScsiServerRdWr10Req::DecodeL(aPtr); sl@0: iBytchk = aPtr[1] & 0x02 ? ETrue : EFalse; sl@0: }