userlibandfileserver/fileserver/smassstorage/inc/scsiprot.h
changeset 0 a41df078684a
child 20 597aaf25e343
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/fileserver/smassstorage/inc/scsiprot.h	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,272 @@
+// 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:
+// SCSI Protocol layer for USB Mass Storage
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#ifndef __SCSIPROT_H__
+#define __SCSIPROT_H__
+
+
+// Header files
+#include "drivemanager.h"
+#include "protocol.h"
+
+// Define MSDC_MULTITHREADED to use Mass Storage multi-threaded (Double-buffering) disk read/writes.
+// smassstorage_db.mmp defines this macro.
+
+#if defined MSDC_MULTITHREADED 
+class CWriteDriveThread;
+class CReadDriveThread;
+#endif
+
+
+// Display time taken to write data to disk
+//#define MEASURE_AND_DISPLAY_WRITE_TIME
+// Display time taken to read data from disk
+//#define MEASURE_AND_DISPLAY_READ_TIME
+
+
+// Maximum size for SCSI Read10 Write10 and Verify10 commands
+// Windows requests size of 64K whereas MAC requests size of 128K
+static const TUint32 KMaxBufSize = 128 * 1024;
+
+// Write to media when data is available
+static const TUint32 KDefaultMediaWriteSize = 4 * 1024;
+
+// Use in the HS case a write size of 64KB
+static const TUint32 KHsMediaWriteSize = 64 * 1024;
+
+
+/**
+Sense Info
+*/
+class TSenseInfo
+	{
+public:
+	// Spec: SCSI Primary Commands 3 (SPC-3)
+	// Section 4.5.6 Sense key and sense code defintions
+	// Table 27 - Sense key descriptions
+	enum TSenseCode
+		{
+		ENoSense        = 0,
+		ERecoveredError = 1,
+		ENotReady       = 2,
+		EMediumError    = 3,
+		EHardwareError  = 4,
+		EIllegalRequest = 5,
+		EUnitAttention  = 6,
+		EDataProtection = 7,
+		EBlankCheck     = 8,
+		EVendorSpecific = 9,
+		ECopyAborted    = 10,
+		EAbortedCommand = 11,
+		EDataOverflow   = 13,
+		EMisCompare     = 14
+		};
+
+	// Table 28 - ASC and ASQ assignments
+	enum TAdditionalCode
+		{
+		EAscNull								 = 0x00,
+		EAscLogicalUnitNotReady					 = 0x04,
+		EAscLogicalUnitDoesNotRespondToSelection = 0x05,
+		EInvalidCmdCode							 = 0x20,
+		ELbaOutOfRange							 = 0x21,
+		EInvalidFieldInCdb						 = 0x24,
+		ELuNotSupported							 = 0x25,
+		EWriteProtected							 = 0x27,
+		ENotReadyToReadyChange					 = 0x28,
+		EMediaNotPresent						 = 0x3A,
+		EInsufficientRes						 = 0x55
+		};
+
+	enum TAdditionalSenseCodeQualifier
+		{
+		EAscqNull								   = 0x00,
+		EAscqLogicalUnitIsInProcessOfBecomingReady = 0x01
+		};
+
+public:
+	TSenseInfo();
+
+	void SetSense(TSenseCode aSenseCode);
+
+	void SetSense(TSenseCode aSenseCode,
+				  TAdditionalCode aAdditional);
+
+	void SetSense(TSenseCode aSenseCode,
+				  TAdditionalCode aAdditional,
+				  TAdditionalSenseCodeQualifier aQualifier);
+
+	TBool SenseOk();
+
+public:
+	TUint8 iSenseCode;
+	TUint8 iAdditional;
+	TUint8 iQualifier;
+	};
+
+
+/**
+Returns EFalse if a sense code has been set. 
+Note that ENoSense indicates that there is no specific sense key infotmation
+to be reported and the command was successful. 
+*/
+inline TBool TSenseInfo::SenseOk()
+	{
+	return (iSenseCode == ENoSense);
+	}
+
+
+const TUint KModeSenseCommandLength = 4;
+const TUint KReadCapacityCommandLength = 8;
+const TUint KReadFormatCapacitiesCommandLength = 12;
+const TUint KRequestSenseCommandLength = 18;
+const TUint KInquiryCommandLength = 36;
+
+
+/**
+The CScsiProtocol is responsible for interpreting the data received from the Transpor layer
+and where appropriate routing specific requests through to the appropriate drive unit.
+
+@internalTechnology
+*/
+class CScsiProtocol : public CBase, public MProtocolBase
+	{
+public:
+	enum TCommand
+	{
+	ETestUnitReady			= 0x00,
+	ERequestSense			= 0x03,
+	EInquiry 				= 0x12,
+	EModeSense				= 0x1A,
+	EStartStopUnit			= 0x1B,
+	EPreventMediaRemoval	= 0x1E,
+	EReadFormatCapacities	= 0x23,
+	EReadCapacity			= 0x25,
+	ERead10 				= 0x28,
+	EWrite10				= 0x2A,
+	EVerify10				= 0x2f,
+	EUndefinedCommand		= 0xFF
+	};
+
+
+public:
+
+	static CScsiProtocol* NewL(CDriveManager& aDriveManager);
+	void RegisterTransport(MTransportBase* aTransport);
+	void ReportHighSpeedDevice();
+	TBool DecodePacket(TPtrC8& aData, TUint aLun);
+	TInt ReadComplete(TInt aError);
+	TInt SetScsiParameters(TMassStorageConfig aConfig);
+	TInt Cancel();
+	~CScsiProtocol();
+
+#ifdef MSDC_MULTITHREADED
+	void InitializeBufferPointers(TPtr8& aDes1, TPtr8& aDes2);
+	static void ProcessWriteComplete (TUint8* aAddress, TAny* aPtr); //todo const
+#endif
+
+private:
+	CScsiProtocol(CDriveManager& aDriveManager);
+	void  ConstructL();
+	CMassStorageDrive* GetCheckDrive(TUint aLun);
+	TBool HandleUnitReady(TUint aLun);
+	TBool HandleRequestSense(TPtrC8& aData);
+	TBool HandleInquiry(TPtrC8& aData, TUint aLun);
+	TBool HandleStartStopUnit(TPtrC8& aData, TUint aLun);
+	TBool HandlePreventMediaRemoval(TPtrC8& aData, TUint aLun);
+	TBool HandleReadCapacity(TPtrC8& aData, TUint aLun);
+	TBool HandleRead10(TPtrC8& aData, TUint aLun);
+	TBool HandleWrite10(TPtrC8& aData, TUint aLun);
+	TBool HandleVerify10(TPtrC8& aData, TUint aLun);
+	TBool HandleModeSense(TPtrC8& aData, TUint aLun);
+	TBool HandleReadFormatCapacities(TUint aLun);
+
+private:
+	/** Configuration data for INQUIRY command*/
+	TMassStorageConfig iConfig;
+
+	/** reference to the Drive Manager */
+	CDriveManager& iDriveManager;
+	
+	/** pointer to the transport level */
+	MTransportBase* iTransport; 
+
+	/** Sense Info */
+	TSenseInfo iSenseInfo;
+
+#ifdef MSDC_MULTITHREADED
+	/** Sense Info */
+	TSenseInfo iDeferredSenseInfo;
+#endif
+
+	/** Start offset (in bytes) for Write/Verify */
+	TInt64 iOffset;
+
+	/** Last command for SetupRead (Write or Verify) */
+	TUint8 iLastCommand;
+
+	/** LUN for SetupRead */
+	TUint iLastLun;
+
+#ifdef SIMDISK
+	CArrayFixFlat<TUint8>* iSimDisk;
+#endif
+
+	/** The number of bytes remaining to be read from the host for write operations */
+	TUint32 iBytesRemain;
+
+	/** Write to the media when this amount of data is available */
+	TUint32 iMediaWriteSize;
+
+#ifdef MSDC_MULTITHREADED
+	/** Ptr to Write Thread instance */
+	CWriteDriveThread* iWriteDriveThread;
+
+	/** Ptr to Read Thread instance */
+	CReadDriveThread* iReadDriveThread;
+#endif // MSDC_MULTITHREADED
+
+#ifdef USB_TRANSFER_PUBLISHER
+	/**
+	Publish and subscribe properties for tracking data transfer volume
+	*/
+	CUsbWriteTransferPublisher* iWriteTransferPublisher;
+	CUsbReadTransferPublisher* iReadTransferPublisher;
+
+	/**
+	Cumulative bytes read
+	*/
+	TFixedArray<TInt64, KUsbMsMaxDrives> iBytesRead;
+	/**
+	Cumulative bytes written
+	*/
+	TFixedArray<TInt64, KUsbMsMaxDrives> iBytesWritten;
+#else
+	/**
+	Publish and subscribe properties for tracking data transfer volume
+	*/
+	CDriveWriteTransferPublisher* iWriteTransferPublisher;
+	CDriveReadTransferPublisher* iReadTransferPublisher;
+#endif
+	};
+
+#endif // __SCSIPROT_H__