kernel/eka/include/drivers/mmc.h
changeset 0 a41df078684a
child 110 c734af59ce98
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/include/drivers/mmc.h	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,4129 @@
+// Copyright (c) 1999-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:
+// Generic MMC controller types and standard classes for MMC manipulation
+// This controller follows MMC spec V2.1
+// 
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#if !defined(__MMC_H__)
+#define __MMC_H__
+
+#include <drivers/pbus.h>
+#include <d32locd.h>
+
+// MMC Card maximum system settings
+
+const TInt KMaxMmcSockets = KMaxPBusSockets;
+
+// Forward type declarations
+
+class TMMC;
+class TCID;
+class TCSD;
+class TExtendedCSD;
+class TRCA;
+class TDSR;
+class TMMCStatus;
+class TMMCArgument;
+class TMMCard;
+class TMMCCommandDesc;
+class TMMCBusConfig;
+class TMMCStackConfig;
+class TMMCRCAPool;
+class TMMCSessRing;
+class TMMCStateMachine;
+class DMMCSocket;
+class DMMCSession;
+class DMMCStack;
+class TMMCMachineInfo;
+class TMapping;
+class TMMCPasswordStore;
+class TMMCEraseInfo;
+class TMMCMachineInfoV4;
+typedef TPckg<TMMCMachineInfoV4> TMMCMachineInfoV4Pckg;
+
+enum TMMCAppCommand {EMMCNormalCmd,EMMCApplicationCmd};
+
+// Typedefs
+
+/**
+@publishedPartner
+@released
+
+Represents the MultiMediaCard error code bit set.
+
+MultiMediaCard error codes are defined as bit masks, mainly for use with
+the state machine where the error trap mask may be used. 
+The function DMMCSession::EpocErrorCode() converts these error bit values
+into standard Symbian OS error values.
+
+@see KMMCErrNone
+@see KMMCErrResponseTimeOut
+@see KMMCErrDataTimeOut
+@see KMMCErrBusyTimeOut
+@see KMMCErrBusTimeOut
+@see KMMCErrTooManyCards
+@see KMMCErrResponseCRC
+@see KMMCErrDataCRC
+@see KMMCErrCommandCRC
+@see KMMCErrStatus
+@see KMMCErrNoCard
+@see KMMCErrBrokenLock
+@see KMMCErrPowerDown
+@see KMMCErrAbort
+@see KMMCErrStackNotReady
+@see KMMCErrNotSupported
+@see KMMCErrHardware
+@see KMMCErrBusInconsistent
+@see KMMCErrBypass
+@see KMMCErrInitContext
+@see KMMCErrArgument
+@see KMMCErrSingleBlock
+@see KMMCErrLocked
+@see KMMCErrNotFound
+@see KMMCErrAlreadyExists
+@see KMMCErrGeneral
+@see KMMCErrAll
+@see KMMCErrBasic
+*/
+typedef TUint32 TMMCErr;
+
+//		MMC Enums and inline functions
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Defines a set of symbols corresponding to the MultiMediaCard bus commands.
+
+A command is one of the parameter values inserted into a TMMCCommandDesc object.
+The commands themselves are defined by the MultiMediaCard specification.
+
+@see TMMCCommandDesc
+*/
+enum TMMCCommandEnum
+	{
+	/**
+	CMD0; reset all cards to idle state.
+	*/
+	ECmdGoIdleState			=0,
+
+	
+	/**
+	CMD1; all cards in the idle state send their operating conditions.
+	*/
+	ECmdSendOpCond			=1,
+
+	
+	/**
+	CMD2; all cards send their CID number.
+	*/
+	ECmdAllSendCID			=2,
+
+
+	/**
+	CMD3; assign relative address to a card.
+	*/
+	ECmdSetRelativeAddr		=3,
+
+
+	/**
+	CMD4; program the DSR register of all cards.
+	*/
+	ECmdSetDSR				=4,
+
+	
+	/**
+	CMD5; toggle device between Sleep and Awake states.
+	*/
+	ECmd5					=5,
+	ECmdSleepAwake			=5,
+
+	
+	/**
+	CMD6; Switch
+	*/
+	ECmd6					=6,
+	ECmdSwitch				=6,
+
+	
+	/**
+	CMD7; toggle a card between standby and transfer state, or between
+	programming and disconnected state.
+
+    The card is selected by its RCA and deselected by any other address.
+	*/
+	ECmdSelectCard			=7,
+
+	
+	/**
+	CMD8; addressed card sends its extended CSD.
+	*/
+	ECmd8					=8,
+	ECmdSendExtendedCSD		=8,
+
+	
+	/**
+	CMD9; addressed card sends its CSD.
+	*/
+	ECmdSendCSD				=9,
+
+	
+	/**
+	CMD10; addressed card sends its CID.
+	*/
+	ECmdSendCID				=10,
+
+	
+	/**
+	CMD11; read data stream from the card starting at the given address until
+	an ECmdStopTransmission follows.
+	
+	@see ECmdStopTransmission
+	*/
+	ECmdReadDatUntilStop	=11,
+
+	
+	/**
+	CMD12; force the card to stop transmission.
+	*/
+	ECmdStopTransmission	=12,
+
+	
+	/**
+	CMD13; addressed card sends its status register.
+	*/
+	ECmdSendStatus			=13,
+
+	
+	/**
+	CMD14; BUSTEST_R - Reads the reversed bus testing data pattern from the card.
+	
+	@see ECmdBustest_W
+	*/
+	ECmd14					=14,
+	ECmdBustest_R			=14,
+
+	
+	/**
+	CMD15; set the card to the inactive state.
+	*/
+	ECmdGoInactiveState		=15,
+
+	
+	/**
+	CMD16; set the block length for all following block commands.
+	*/
+	ECmdSetBlockLen			=16,
+
+	
+	/**
+	CMD17; read a single data block from the card.
+	*/
+	ECmdReadSingleBlock		=17,
+
+	
+	/**
+	CMD18; continuously transfer data blocks from the card until interrupted
+	by ECmdStopTransmission.
+
+	@see ECmdStopTransmission
+	*/
+	ECmdReadMultipleBlock	=18,
+
+	
+	/**
+	CMD19; BUSTEST_W - Sends a test data pattern to the card to determine the bus characteristics
+
+	@see ECmdBustest_R
+	*/
+	ECmd19					=19,
+	ECmdBustest_W			=19,
+
+	
+	/**
+	CMD20; write data stream from the host starting at the given address
+	until interrupted by ECmdStopTransmission.
+
+	@see ECmdStopTransmission
+	*/
+	ECmdWriteDatUntilStop	=20,
+
+	
+	/**
+	CMD21; reserved for future use.	
+	*/
+	ECmd21					=21,
+
+	
+	/**
+	CMD22; reserved for future use.	
+	*/
+	ECmd22					=22,
+
+	
+	/**
+	CMD23; define the number of blocks to be transferred in the following
+	multiple block read or write command.
+	*/
+	ECmdSetBlockCount		=23,
+
+	
+	/**
+	CMD24; write a single block to the card.
+	*/
+	ECmdWriteBlock			=24,
+
+	
+	/**
+	CMD25; continuously transfer data blocks to the card until interrupted
+	by ECmdStopTransmission.
+
+	@see ECmdStopTransmission
+	*/
+	ECmdWriteMultipleBlock	=25,
+	
+
+	/**
+	CMD26; programming of the CID.
+	
+	This is issued once per card, and is normally reserved for
+	the manufacturer.
+	*/
+	ECmdProgramCID			=26,
+
+	
+	/**
+	CMD27; programming of the programmable bits of the CSD.
+	*/
+	ECmdProgramCSD			=27,
+
+	
+	/**
+	CMD28; set the write protect bit of the addressed group, if the card has
+	write protection features.
+	*/
+	ECmdSetWriteProt		=28,
+
+	
+	/**
+	CMD29; clear the write protect bit of the addressed group, if the card has
+	write protection features.
+	*/
+	ECmdClearWriteProt		=29,
+	
+
+	/**
+	CMD30; ask the card to send the status of the write protect bit, if
+	the card has write protection features.
+	*/
+	ECmdSendWriteProt		=30,
+
+	
+	/**
+	CMD31; reserved for future use.	
+	*/
+	ECmd31					=31,
+
+	
+	/**
+	CMD32; set the address of the first sector of the erase group.
+	*/
+	ECmdTagSectorStart		=32,
+
+	
+	/**
+	CMD33; set the address of the last sector in a continuous range within
+	the selected erase group, or the address of a single sector to be
+	selected for erase.
+	*/
+	ECmdTagSectorEnd		=33,
+
+	
+	/**
+	CMD34; remove one previously selected sector from the erase selection.
+	*/
+	ECmdUntagSector			=34,
+
+	
+	/**
+	CMD35; set the the address of the first erase group within a continuous
+	range to be selected for erase.
+	*/
+	ECmdTagEraseGroupStart	=35,
+
+	
+	/**
+	CMD36; set the address of the last erase group within a continuous range
+	to be selected for erase.
+	*/
+	ECmdTagEraseGroupEnd	=36,
+
+	
+	/**
+	CMD37; removes one previously selected erase group from the erase selection.
+	*/
+	ECmdUntagEraseGroup		=37,
+
+	
+	/**
+	CMD38; erase all previously selected sectors.
+	*/
+	ECmdErase				=38,
+
+	
+	/**
+	CMD39; read and write 8 bit (register) data fields.
+	*/
+	ECmdFastIO				=39,
+
+	
+	/**
+	CMD40; set the system into interrupt mode.
+	*/
+	ECmdGoIRQState			=40,
+
+	
+	/**
+	CMD41; reserved for future use.	
+	*/
+	ECmd41					=41,
+
+	
+	/**
+	CMD42; set/reset the password or lock/unlock the card.
+	*/
+	ECmdLockUnlock			=42,
+
+	
+	/**
+	CMD43; reserved for future use.	
+	*/
+	ECmd43					=43,
+
+	
+	/**
+	CMD44; reserved for future use.	
+	*/
+	ECmd44					=44,
+
+	
+	/**
+	CMD45; reserved for future use.	
+	*/
+	ECmd45					=45,
+
+	
+	/**
+	CMD46; reserved for future use.	
+	*/
+	ECmd46					=46,
+
+	
+	/**
+	CMD47; reserved for future use.	
+	*/
+	ECmd47					=47,
+
+	
+	/**
+	CMD48; reserved for future use.	
+	*/
+	ECmd48					=48,
+
+	
+	/**
+	CMD49; reserved for future use.
+	*/
+	ECmd49					=49,
+
+	
+	/**
+	CMD50; reserved for future use.	
+	*/
+	ECmd50					=50,
+
+	
+	/**
+	CMD51; reserved for future use.	
+	*/
+	ECmd51					=51,
+
+	
+	/**
+	CMD52; reserved for future use.	
+	*/
+	ECmd52					=52,
+
+	
+	/**
+	CMD53; reserved for future use.	
+	*/
+	ECmd53					=53,
+
+	
+	/**
+	CMD54; reserved for future use.	
+	*/
+	ECmd54					=54,
+
+	
+	/**
+	CMD55; indicate to the card that the next command is an application
+	specific command rather than a standard command.
+	*/
+	ECmdAppCmd				=55,
+
+	
+	/**
+	CMD56; transfer a data block to the card, or get a data block from the card,
+	for general purpose/application specific commands.
+	*/
+	ECmdGenCmd				=56,
+
+	
+	/**
+	CMD57; reserved for future use.	
+	*/
+	ECmd57					=57,
+
+	
+	/**
+	CMD58; reserved for future use.	
+	*/
+	ECmd58					=58,
+
+	
+	/**
+	CMD59; reserved for future use.
+	*/
+	ECmd59					=59,
+
+	
+	/**
+	CMD60; reserved for future use.
+	*/
+	ECmd60					=60,
+
+	
+	/**
+	CMD61; reserved for future use.
+	*/
+	ECmd61					=61,
+
+	
+	/**
+	CMD62; reserved for future use.
+	*/
+	ECmd62					=62,
+
+	
+	/**
+	CMD63; reserved for future use.
+	*/
+	ECmd63					=63
+	};
+
+enum TMMCCommandTypeEnum
+	{
+	ECmdTypeUK,				// UnKnown command type
+	ECmdTypeBC,				// Broadcast Command
+	ECmdTypeBCR,			// Broadcast Command with Response
+	ECmdTypeAC,				// Addressed Command
+	ECmdTypeACS,			// Addressed Command to a Selected card
+	ECmdTypeADTCS,			// Addressed Data Transfer Command to a Selected card
+	ECmdTypeADC				// Addressed Direct Command to a Selected card
+	};
+
+enum TMMCResponseTypeEnum
+	{
+	ERespTypeNone,
+	ERespTypeUnknown,
+	ERespTypeR1,			// 32 bits Status
+	ERespTypeR1B,			// 32 bits Status with possible busy signal
+	ERespTypeR2,			// 128 bits CID or CSD register
+	ERespTypeR3,			// 32 bits OCR register
+	ERespTypeR4,			// 32 bits Fast I/O
+	ERespTypeR5,			// 32 bits IRQ
+	ERespTypeR6,
+	ERespTypeR7				// not currently defined for MMC
+	};
+
+
+/**
+@publishedPartner
+@released
+
+Defines the set of media types for a MultiMediaCard.
+*/
+enum TMMCMediaTypeEnum
+	{
+	/**
+	A read only card.
+	*/
+	EMultiMediaROM,
+	
+	
+	/**
+	A writable card.
+	*/
+	EMultiMediaFlash,
+	
+	
+	/**
+	An I/O card.
+	*/
+	EMultiMediaIO,
+	
+	
+	/**
+	A card type that is neither read only, writable nor I/O.
+	*/
+	EMultiMediaOther,
+	
+	
+	/**
+	A card type that is not supported.
+	*/
+	EMultiMediaNotSupported
+	};
+
+enum TMMCSessionTypeEnum
+	{
+	ECIMNakedSession		 =0,
+	ECIMUpdateAcq			 =1,
+	ECIMInitStack			 =2,
+	ECIMCheckStack			 =3,
+	ECIMSetupCard			 =4,
+	ECIMReadBlock			 =5,
+	ECIMWriteBlock			 =6,
+	ECIMReadMBlock			 =7,
+	ECIMWriteMBlock			 =8,
+	ECIMEraseSector			 =9,
+	ECIMEraseGroup			 =10,
+	ECIMReadIO				 =11,
+	ECIMWriteIO				 =12,
+	ECIMLockUnlock			 =13,
+	ECIMLockStack			 =14,
+	ECIMInitStackAfterUnlock =15,
+	ECIMAutoUnlock			 =16,
+	ECIMSleep				 =17
+	};
+
+const TUint KMMCMaxSessionTypeNumber  = 18;
+const TUint KMMCMinCustomSession	  = 1024;
+
+const TUint KMMCCmdDirDirBitPosition=	KBit0;			//fixed - dont change it
+const TUint KMMCCmdDirIndBitPosition=	(KBit5-KBit0);	//fixed - dont change it
+const TUint KMMCCmdDirWBitArgument=		KBit5;
+const TUint KMMCCmdDirNegate=			KBit6;
+const TUint KMMCCmdDirWBitDirect=		KBit7;
+
+const TUint KMMCCmdReliableWrite	=	KBit31;
+
+
+/**
+@publishedPartner
+@released
+
+An enum whose values specify the data transfer direction.
+
+@see TMMCCommandSpec
+*/
+enum TMMCCmdDirEnum
+	{
+	EDirNone = 0,
+	EDirRead = KMMCCmdDirWBitDirect,
+	EDirWrite = KMMCCmdDirWBitDirect|KMMCCmdDirDirBitPosition,
+	EDirWBit0 = KMMCCmdDirWBitArgument + 0,
+	EDirRBit0 = (KMMCCmdDirWBitArgument|KMMCCmdDirNegate) + 0
+	};
+
+
+
+
+/**
+@publishedPartner
+@released
+
+An enum whose values specify the width of the data bus
+
+This enum is used by the DMMCStack::SetBusWidth() and TMMCMachineInfo.iMaxBusWidth.
+*/
+enum TBusWidth
+	{
+	EBusWidth1 = 0x00,
+	EBusWidth4 = 0x02,
+	EBusWidth8 = 0x03,
+	EBusWidthInvalid = KMaxTUint32
+	};
+
+/**
+@publishedPartner
+@released
+*/
+const TUint8 KMMCLockUnlockErase =		KBit3;	// In first byte of CMD42 data block
+
+/**
+@publishedPartner
+@released
+*/
+const TUint8 KMMCLockUnlockLockUnlock =	KBit2;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint8 KMMCLockUnlockClrPwd =		KBit1;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint8 KMMCLockUnlockSetPwd =		KBit0;
+
+
+
+
+/**
+@publishedPartner
+@released
+	
+A utility class that contains convenience functions to handle conversion
+to and from big-endian format.
+*/
+class TMMC
+	{
+public:
+	static inline TUint32 BigEndian32(const TUint8*);
+	static inline void BigEndian4Bytes(TUint8* aPtr, TUint32 aVal);
+	};
+
+
+//		Generic MMC layer constants
+
+const TInt  KMaxMMCStacks=1;					// Number of separate MMC buses
+const TUint KMaxMMCardsPerStack=4;				// Limits the number of cards in each stack
+
+const TUint KBroadcastToAllCards=0xFFFFFFFF;
+
+//		MMC Spec related constants
+
+const TUint KMMCMaxResponseLength=16;			// in bytes
+const TUint KMMCCIDLength=16;
+const TUint KMMCCSDLength=16;
+const TUint KMMCExtendedCSDLength=512;
+const TUint KMMCBusClockFOD=400;				// Identification clock in kiloherz
+const TUint KMMCCommandMask = 63;				// Size of TMMCCommandEnum enumerator
+
+// Command Classes Bit Set
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCCmdClassNone=			  0;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCCmdClassBasic=		  KBit0;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCCmdClassStreamRead=	  KBit1;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCCmdClassBlockRead=	  KBit2;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCCmdClassStreamWrite=	  KBit3;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCCmdClassBlockWrite=	  KBit4;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCCmdClassErase=		  KBit5;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCCmdClassWriteProtection=KBit6;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCCmdClassLockCard=		  KBit7;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCCmdClassApplication=	  KBit8;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCCmdClassIOMode=		  KBit9;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCCmdClassReserved10=	  KBit10;
+const TUint32 KMMCCmdClassSwitch=		  KBit10;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCCmdClassReserved11=	  KBit11;
+
+//		Specific MMC implementation constants
+
+const TUint KMaxMMCMachineStackDepth=20;		// TMMCStateMachine stack depth
+const TUint KMaxMMCCommandStackDepth=9;			// Session TMMCCommandDesc stack depth
+const TUint KMMCIdleCommandsAtRestart=2;		// Number of CMD0s to be issued at initialisation
+const TUint KMMCMaxJobsInStackWorkSet=8;		// Number of sessions simultaneously served
+const TUint KMMCPollGapInMilliseconds=40;
+const TUint KMMCMaxPollAttempts=5;				// 40*5 = 200ms
+const TUint KMMCRetryGapInMilliseconds=10;
+const TUint KMMCMaxTimeOutRetries=1;
+const TUint KMMCMaxCRCRetries=1;
+const TUint16 KMMCMaxUnlockRetries=4;
+const TUint16 KMMCMaxAutoUnlockRetries=25;
+const TUint KMMCMaxGlobalRetries=1;
+const TUint16 KMMCSpecOpCondBusyTimeout=100 ;     //MMC/SD Standard OCR timeout 1 second
+const TUint16 KMMCMaxOpCondBusyTimeout=150;		// 10*150 = 1500ms
+const TUint KMMCLowVoltagePowerUpTimeoutInMilliseconds=2;	// 1ms + 74 400KHz clock cycles
+const TUint KMMCUnlockRetryGapInMilliseconds = 200;			// Unlock retry gap
+
+// DMMCStack Modes Bit Set
+const TUint32 KMMCModeEnableClientConfig =	KBit0;	// Merge with session iConfig
+const TUint32 KMMCModeEnableTimeOutRetry =	KBit1;	// Auto retry on response time-outs
+const TUint32 KMMCModeTimeOutRetryGap =		KBit2;	// Force timer delay between retries
+const TUint32 KMMCModeEnableCRCRetry =		KBit3;	// Command or response CRC errors
+const TUint32 KMMCModeCRCRetryGap =			KBit4;
+const TUint32 KMMCModeDataCRCRetry =		KBit5;	// Repeat data transaction from the last valid position
+const TUint32 KMMCModeEnableUnlockRetry =	KBit6;	// Resend CMD42 for unreliable cards
+const TUint32 KMMCModeEnablePreemption =	KBit7;	// Allow sessions to share the MMC bus
+const TUint32 KMMCModePreemptOnBusy =		KBit8;	// Release bus control if busy
+const TUint32 KMMCModePreemptOnRetry =		KBit9;	// Release bus control before timeout/crc retries
+const TUint32 KMMCModePreemptInGaps =		KBit10;	// Preempt whenever gap timer is invoked
+const TUint32 KMMCModeEnqueIfLocked =		KBit11;	// Enque session if DMMCStack is locked
+const TUint32 KMMCModeCardControlled =		KBit12;	// Use Session CardP to get RCAs etc.
+const TUint32 KMMCModeCompleteInStackDFC =	KBit13;	// Run DMMCStack in DFC when completing
+const TUint32 KMMCModeEnableBusyPoll =		KBit14;	// Enables mechanism recovering from busy timeouts
+const TUint32 KMMCModeBusyPollGap =			KBit15;
+const TUint32 KMMCModeEnableRetries =		KBit16;	// This mode removed disables all retries/polls
+const TUint32 KMMCModeMask =				KBit17 - KBit0;
+
+// The following modes are effective for MasterConfig only
+const TUint32 KMMCModeClientPollAttempts =		KBit20;
+const TUint32 KMMCModeClientTimeOutRetries =	KBit21;
+const TUint32 KMMCModeClientCRCRetries =		KBit22;
+const TUint32 KMMCModeClientUnlockRetries =		KBit23;
+const TUint32 KMMCModeClientBusClock =			KBit24;
+const TUint32 KMMCModeClientClockIn =			KBit25;
+const TUint32 KMMCModeClientClockOut =			KBit26;
+const TUint32 KMMCModeClientResponseTimeOut =	KBit27;
+const TUint32 KMMCModeClientDataTimeOut =		KBit28;
+const TUint32 KMMCModeClientBusyTimeOut =		KBit29;
+const TUint32 KMMCModeClientiOpCondBusyTimeout = KBit30;
+const TUint32 KMMCModeClientMask =	KBit31 - KBit20;
+
+// The following modes cannot be enabled by a client if disabled in MasterConfig
+const TUint32 KMMCModeMasterOverrides=
+								KMMCModeEnableClientConfig	|
+								KMMCModeEnablePreemption	|
+								KMMCModeEnqueIfLocked		|
+								KMMCModeClientMask;
+
+// The following modes are always effective, even if the ClientConfig is disabled
+const TUint32 KMMCModeClientOverrides=
+								KMMCModeEnableClientConfig	|
+								KMMCModeCardControlled;
+
+
+// The default MasterConfig modes
+const TUint32 KMMCModeDefault=	KMMCModeEnableClientConfig	|
+								KMMCModeEnableRetries		|
+								KMMCModeEnableTimeOutRetry	|
+								KMMCModeTimeOutRetryGap		|
+								KMMCModeEnableCRCRetry		|
+								KMMCModeCRCRetryGap			|
+								KMMCModeDataCRCRetry		|
+								KMMCModeEnableUnlockRetry	|
+								KMMCModeEnablePreemption	|
+								KMMCModePreemptInGaps		|
+								KMMCModeEnqueIfLocked		|
+								KMMCModeCardControlled		|
+								KMMCModeClientMask;
+
+
+// MMC Error Code Bit Set
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+Indicates no error.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrNone=0;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+Timed out waiting for a response from the card after issuing a command.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrResponseTimeOut=KBit0;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+Timed out waiting for a data block to be received during a data read command.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrDataTimeOut=	 KBit1;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+Timed out waiting for a data block to be requested during a data write command.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrBusyTimeOut=	 KBit2;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+Timed out during the CIM_UPDATE_ACQ macro waiting for a card to power up.
+Cards that are still powering up return busy in response to a SEND_OP_COND command. 
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrBusTimeOut=	 KBit3;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+The host has detected more cards in a stack that it can handle, or it has
+detected more cards than it was expecting, for example, more cards than physical slots.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrTooManyCards=	 KBit4;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+The host has detected a CRC error in a response received from a card.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrResponseCRC=	 KBit5;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+The host has detected a CRC error in a data block received from a card.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrDataCRC=		 KBit6;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+The card has detected a CRC error in a command received from the host.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrCommandCRC=	 KBit7;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+An R1 response was received from the card with one or more of the error flags
+set in the card status field.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrStatus=		 KBit8;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+A session was submitted without first being set-up with a card object,
+or was set-up with a card object that is no longer present.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrNoCard=		 KBit9;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+The session had the stack locked but the MultiMediaCard controller had
+to override the lock to perform some other bus activity. 
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrBrokenLock=	 KBit10;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+The card was powered down.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrPowerDown=		 KBit11;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+The session was stopped.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrAbort=			 KBit12;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+The stack has not yet been initialised.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrStackNotReady=	 KBit13;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+The session requested a service or feature that is not supported.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrNotSupported=	 KBit14;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+Indicates a general hardware related error.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrHardware=		 KBit15;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+An unexpected or inconsistent bus state has been detected.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrBusInconsistent=KBit16;
+
+
+
+
+// SM control error codes
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+This is used interally by the MultiMediaCard controller.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrBypass=		 KBit17;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+This is used internally by the MultiMediaCard controller in the process
+of re-initialising a card to recover from an inconsistent bus state.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrInitContext=	 KBit18;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+Indicates a bad argument.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrArgument=		 KBit19;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+A multiple block operation was requested, but the length specified was
+less than that of a block.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrSingleBlock=	 KBit20;
+
+
+
+/**
+@internalComponent
+*/
+const TUint32 KMMCErrUpdPswd=		 KBit21;
+
+
+
+
+// General error codes
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+The card is locked.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrLocked=			KBit22;
+
+
+/**
+@publishedPartner
+@released
+
+A MultiMediaCard error code.
+
+Indicates a general 'not found' type  error.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrNotFound=			KBit23;
+
+
+/**
+@publishedPartner
+@released
+
+An MultiMediaCard error code:
+
+Indicates a general already 'exists type' error.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrAlreadyExists=		KBit24;
+
+
+/**
+@publishedPartner
+@released
+
+An MultiMediaCard error code:
+
+Indicates an unspecified error.
+
+@see TMMCErr
+*/
+const TUint32 KMMCErrGeneral=			KBit25;
+
+
+/**
+@publishedPartner
+@released
+
+A bitmask of all MultiMediaCard error codes.
+*/
+const TUint32 KMMCErrAll = (KBit26 - KBit0);
+
+/**
+@publishedPartner
+@released
+
+A subset of MultiMediaCard error codes.
+*/
+const TUint32 KMMCErrBasic = (KMMCErrAll & ~(
+								KMMCErrBypass		|
+								KMMCErrUpdPswd		|
+								KMMCErrInitContext	|
+								KMMCErrArgument		|
+								KMMCErrSingleBlock	|
+								KMMCErrLocked		|
+								KMMCErrNotFound		|
+								KMMCErrAlreadyExists|
+								KMMCErrGeneral));
+
+// DMMC Stack and Session control bits
+
+// Stack State bits
+const TUint32 KMMCStackStateRunning=		KBit0;	// Stack scheduler active
+const TUint32 KMMCStackStateWaitingToLock=	KBit1;	//
+const TUint32 KMMCStackStateLocked=			KBit2;	//
+const TUint32 KMMCStackStateWaitingDFC=		KBit3;
+const TUint32 KMMCStackStateInitInProgress=	KBit4;
+const TUint32 KMMCStackStateReScheduled=	KBit5;
+const TUint32 KMMCStackStateJobChooser=		KBit6;
+const TUint32 KMMCStackStateDoDeselect=		KBit7;
+const TUint32 KMMCStackStateBusInconsistent=KBit8;
+const TUint32 KMMCStackStateInitPending=	KBit9;
+const TUint32 KMMCStackStateCardRemoved=    KBit10;
+const TUint32 KMMCStackStateSleepinProgress=KBit11;
+const TUint32 KMMCStackStateSleep=    		KBit12;
+const TUint32 KMMCStackStateYielding=		KBit13;
+
+// Session Blocking bits definition
+
+/**
+@publishedPartner
+@released
+
+A bit, which when set in a call to DMMCStack::BlockCurrentSession(), indicates
+that the current session is to be blocked, awaiting an event that is to
+be handled at the platform specific level.
+
+For example, the session may be waiting for:
+
+- a response following a command
+- an interrupt indicating that data transfer is required
+- a platform specific layer specific timer.
+
+@see DMMCStack::BlockCurrentSession()
+*/
+const TUint32 KMMCBlockOnASSPFunction=	KBit0;
+
+const TUint32 KMMCBlockOnPollTimer     = KBit1;
+const TUint32 KMMCBlockOnRetryTimer    = KBit2;
+const TUint32 KMMCBlockOnNoRun         = KBit3;
+const TUint32 KMMCBlockOnDoor          = KBit4;
+const TUint32 KMMCBlockOnWaitToLock    = KBit5;
+const TUint32 KMMCBlockOnCardInUse     = KBit6;
+const TUint32 KMMCBlockOnPgmTimer      = KBit7;
+const TUint32 KMMCBlockOnInterrupt     = KBit8;
+const TUint32 KMMCBlockOnDataTransfer  = KBit9;
+const TUint32 KMMCBlockOnMoreData      = KBit10;
+const TUint32 KMMCBlockOnYielding      = KBit11;  // Yielding to other commands
+
+const TUint32 KMMCBlockOnAsynchMask    = KMMCBlockOnASSPFunction |
+										 KMMCBlockOnPollTimer    |
+										 KMMCBlockOnRetryTimer   |
+										 KMMCBlockOnPgmTimer     |
+										 KMMCBlockOnInterrupt    |
+										 KMMCBlockOnDataTransfer |
+										 KMMCBlockOnMoreData;
+
+const TUint32 KMMCBlockOnGapTimersMask = KMMCBlockOnPollTimer  |
+										 KMMCBlockOnRetryTimer |
+										 KMMCBlockOnPgmTimer;
+
+// Session State bits definition
+const TUint32 KMMCSessStateEngaged     = KBit0;	// Processed by DMMCStack
+const TUint32 KMMCSessStateInProgress  = KBit1;	// No longer safe to restart
+const TUint32 KMMCSessStateCritical    = KBit2;	// Re-initialise the stack if aborted
+const TUint32 KMMCSessStateSafeInGaps  = KBit3;
+const TUint32 KMMCSessStateDoReSchedule= KBit4;
+
+/**
+@publishedPartner
+@released
+
+A bit that when set into DMMCSession::iState before calling 
+DMMCStack::UnBlockCurrentSession(), causes a DFC to be queued in order
+to resume the state machine at some later stage.
+*/
+const TUint32 KMMCSessStateDoDFC				  = KBit5;
+const TUint32 KMMCSessStateBlockOnDoor			  = KBit6;
+const TUint32 KMMCSessStateCardIsGone			  = KBit7;
+const TUint32 KMMCSessStateASSPEngaged			  = KBit8;
+const TUint32 KMMCSessStateAllowDirectCommands    = KBit9;  // Allow Direct Commands (Using CMD) during Data Transfer
+
+class TCID
+/**
+	CID class
+
+	@publishedPartner
+	@released
+*/
+	{
+public:
+	inline TCID() {}					// Default constructor
+	inline TCID(const TUint8*);
+	inline TCID& operator=(const TCID&);
+	inline TCID& operator=(const TUint8*);
+	inline TBool operator==(const TCID&) const;
+	inline TBool operator==(const TUint8*) const;
+	inline void Copy(TUint8*) const;		// Copies big endian 16 bytes CID
+	inline TUint8 At(TUint anIndex) const;	// Byte from CID at anIndex
+private:
+	TUint8 iData[KMMCCIDLength];		// Big endian 128 bit bitfield representing CID
+	};
+
+
+class TCSD
+/**
+	CSD class
+
+	@publishedPartner
+	@released
+*/
+	{
+public:
+	inline TCSD() {memclr(this, sizeof(*this));}	// Default constructor
+	inline TCSD(const TUint8*);
+	inline TCSD& operator=(const TCSD&);
+	inline TCSD& operator=(const TUint8*);
+	inline void Copy(TUint8*) const;		// Copies big endian 16 bytes CSD
+	inline TUint8 At(TUint anIndex) const;	// Byte from CSD at anIndex
+public:
+	inline TUint CSDStructure() const;
+	inline TUint SpecVers() const;
+	inline TUint Reserved120() const;
+	inline TUint TAAC() const;
+	inline TUint NSAC() const;
+	inline TUint TranSpeed() const;
+	inline TUint CCC() const;
+	inline TUint ReadBlLen() const;
+	inline TBool ReadBlPartial() const;
+	inline TBool WriteBlkMisalign() const;
+	inline TBool ReadBlkMisalign() const;
+	inline TBool DSRImp() const;
+	inline TUint Reserved74() const;
+	inline TUint CSize() const;
+	inline TUint VDDRCurrMin() const;
+	inline TUint VDDRCurrMax() const;
+	inline TUint VDDWCurrMin() const;
+	inline TUint VDDWCurrMax() const;
+	inline TUint CSizeMult() const;
+	inline TUint EraseGrpSize() const;
+	inline TUint EraseGrpMult() const;
+	inline TUint WPGrpSize() const;
+	inline TBool WPGrpEnable() const;
+	inline TUint DefaultECC() const;
+	inline TUint R2WFactor() const;
+	inline TUint WriteBlLen() const;
+	inline TBool WriteBlPartial() const;
+	inline TUint Reserved16() const;
+	inline TBool FileFormatGrp() const;
+	inline TBool Copy() const;
+	inline TBool PermWriteProtect() const;
+	inline TBool TmpWriteProtect() const;
+	inline TUint FileFormat() const;
+	inline TUint ECC() const;
+	inline TUint CRC() const;
+public:
+	IMPORT_C TUint DeviceSize() const;		// Uses functions above to calculate device capacity
+	IMPORT_C TMMCMediaTypeEnum MediaType() const;
+	IMPORT_C TUint ReadBlockLength() const;	// Read Block Length in bytes
+	IMPORT_C TUint WriteBlockLength() const;// Write Block Length in bytes
+	IMPORT_C TUint EraseSectorSize() const;	// Erase sector size (default 512 bytes)
+	IMPORT_C TUint EraseGroupSize() const;	// Erase group size (default 16*<sector size> bytes)
+	IMPORT_C TUint MinReadCurrentInMilliamps() const;
+	IMPORT_C TUint MinWriteCurrentInMilliamps() const;
+	IMPORT_C TUint MaxReadCurrentInMilliamps() const;
+	IMPORT_C TUint MaxWriteCurrentInMilliamps() const;
+	IMPORT_C TUint MaxTranSpeedInKilohertz() const;
+public:
+	IMPORT_C TUint CSDField(const TUint& aTopBit, const TUint& aBottomBit) const;	/**< @internalComponent */
+	TUint8 iData[KMMCCSDLength];												/**< @internalComponent */ // Big endian 128 bit bitfield representing CSD	
+	};
+
+
+class TExtendedCSD
+/**
+	Extended CSD register class.
+	For more information about this register, see the MultimediaCard System 
+	Specification, Version 4.1+
+
+	@publishedPartner
+	@released
+*/
+	{
+public:
+	/** 
+	An enum used by TExtendedCSD::GetWriteArg() to construct a TMMCArgument object.
+	The value chosen defines how the register or command set is to be modified.
+	*/
+	enum TExtCSDAccessBits 
+		{
+		/** Change the card's command set */
+		ECmdSet, 
+		/** Set the specified bits */
+		ESetBits, 
+		/** Clear the specified bits */
+		EClearBits, 
+		/** Write the specified byte */
+		EWriteByte
+		};
+	/** 
+	This enum defines various field offsets into the Modes Segment (i.e.
+	the writable part) of the Extended CSD register.
+	*/
+	enum TExtCSDModesFieldIndex 
+		{
+		/** Offset of the CMD_SET field */
+		ECmdSetIndex = 191, 
+		/** Offset of the CMD_SET_REV field */
+		ECmdSetRevIndex = 189, 
+		/** Offset of the POWER_CLASS field */
+		EPowerClassIndex = 187,
+		/** Offset of the HS_TIMING field */
+		EHighSpeedInterfaceTimingIndex = 185,
+		/** Offset of the BUS_WIDTH field */
+		EBusWidthModeIndex = 183,
+		/** Offset of the BOOT_CONFIG field */
+		EBootConfigIndex = 179,
+		/** Offset of the BOOT_BUS_WIDTH field */
+		EBootBusWidthIndex = 177,
+		/** Offset of the ERASE_GROUP_DEF field */
+		EEraseGroupDefIndex = 175
+		};
+
+	/** 
+	This enum defines various field offsets into the Properties Segment (i.e.
+	the read-only part) of the Extended CSD register.
+	*/
+	enum TExtCSDPropertiesFieldIndex
+		{
+		/** Offset of the EXT_CSD_REV field */
+		EExtendedCSDRevIndex = 192,
+		/** Offset of the CARD_TYPE field */
+		ECardTypeIndex = 196,
+		/** Offset of the ACC_SIZE field */
+		EAccessSizeIndex = 225,
+		/** Offset of the HC_ERASE_GRP_SIZE field */
+		EHighCapacityEraseGroupSizeIndex = 224
+		};
+
+	/** This enum defines the bus width encoding used by the BUS_WIDTH field */
+	enum TExtCSDBusWidths
+		{
+		EExtCsdBusWidth1 = 0x00,
+		EExtCsdBusWidth4 = 0x01,
+		EExtCsdBusWidth8 = 0x02
+		};
+
+	/** 
+	This enum defines the different MMCV4.x card types available as defined 
+	in the CARD_TYPE field 
+	*/
+	enum TCardTypes
+		{
+		EHighSpeedCard26Mhz = 0x01,
+		EHighSpeedCard52Mhz = 0x02
+		};
+	
+	/**
+	This enum defines the boot config encoding used by the BOOT_CONFIG field
+	*/
+	enum TExtCSDBootConfig
+		{
+		ESelectUserArea	 				= 0x00,
+		ESelectBootPartition1 			= 0x01,
+		ESelectBootPartition2 			= 0x02,
+		EEnableBootPartition1forBoot 	= 0x08,
+		EEnableBootPartition2forBoot 	= 0x10,
+		EEnableUserAreaforBoot			= 0x38,
+		EEnableBootAck  				= 0x40
+		};
+
+	/**
+	This enum defines the Boot Bus Width encoding used by the BOOT_BUS_WIDTH field
+	*/
+	enum TExtCSDBootBusWidth
+		{
+		EBootBusWidth1Bit			= 0x00,
+		EBootBusWidth4Bit			= 0x01,
+		EBootBusWidth8Bit			= 0x02,
+		EResetBusWidthafterBoot		= 0x08
+		};
+
+	/**
+	This enum defines the Erase Group Definition encoding 
+	used by the ERASE_GROUP_DEF field
+	*/
+	enum TExtCSDEraseGroupDef
+		{
+		
+		EEraseGrpDefEnableOldSizes		= 0x00,
+		EEraseGrpDefEnableHighCapSizes	= 0x01
+		};
+	
+public:
+	/** Default constructor */
+	inline TExtendedCSD();				
+	/** 
+	Constructor
+	@param aPtr a byte buffer containing the contents of the register
+	*/
+	inline TExtendedCSD(const TUint8* aPtr);
+	/** 
+	Copy constructor
+	@param aCSD a reference to another instance of the same class
+	*/
+	inline TExtendedCSD& operator=(const TExtendedCSD& aCSD);
+	/** 
+	Copy constructor
+	@param aPtr a byte buffer containing the contents of the register
+	*/
+	inline TExtendedCSD& operator=(const TUint8* aPtr);
+
+	/** Returns the byte at a particular offset into the register
+	@param anIndex the offset into the register
+	*/
+	inline TUint8 At(TUint anIndex) const;
+	
+	/** returns a pointer to the raw data */
+	inline TUint8* Ptr();
+	
+	/** 
+	Constructs and then returns a TMMCArgument which can be used to 
+	write to the register using the SWITCH command (CMD6)
+	@param aAccess specifies how the register or command set is to be modified.
+	@param aIndex the offset into the register
+	@param aValue the value to write to the field in the register
+	@param aCmdSet The command set to write. Valid if aAccess = ECmdSet
+	*/
+	inline static TMMCArgument GetWriteArg(TExtCSDAccessBits aAccess, TExtCSDModesFieldIndex aIndex, TUint aValue, TUint aCmdSet);
+	
+	/** returns the contents of the CMD_SET field */
+	inline TUint SupportedCmdSet() const;
+	
+	/** returns the contents of the SEC_COUNT field */
+	inline TUint SectorCount() const;
+	
+	/** returns the contents of the MIN_PERF_W_8_52 field */
+	inline TUint MinPerfWrite8Bit52Mhz() const;
+	
+	/** returns the contents of the MIN_PERF_R_8_52 field */
+	inline TUint MinPerfRead8Bit52Mhz() const;
+	
+	/** returns the contents of the MIN_PERF_W_8_26_4_52 field */
+	inline TUint MinPerfWrite8Bit26Mhz_4Bit52Mhz() const;
+	
+	/** returns the contents of the MIN_PERF_R_8_26_4_52 field */
+	inline TUint MinPerfRead8Bit26Mhz_4Bit52Mhz() const;
+	
+	/** returns the contents of the MIN_PERF_W_4_26 field */
+	inline TUint MinPerfWrite4Bit26Mhz() const;
+	
+	/** returns the contents of the MIN_PERF_R_4_26 field */
+	inline TUint MinPerfRead4Bit26Mhz() const;
+	
+	/** returns the contents of the PWR_CL_26_360 field */
+	inline TUint PowerClass26Mhz360V() const;
+	
+	/** returns the contents of the PWR_CL_52_360 field */
+	inline TUint PowerClass52Mhz360V() const;
+	
+	/** returns the contents of the PWR_CL_26_195 field */
+	inline TUint PowerClass26Mhz195V() const;
+	
+	/** returns the contents of the PWR_CL_52_195 field */
+	inline TUint PowerClass52Mhz195V() const;
+	
+	/** returns the contents of the CARD_TYPE field */
+	inline TUint CardType() const;
+	
+	/** returns the contents of the CSD_STRUCTURE field */
+	inline TUint CSDStructureVer() const;
+	
+	/** returns the contents of the EXT_CSD_REV field */
+	inline TUint ExtendedCSDRev() const;
+	
+	/** returns the contents of the CMD_SET field */
+	inline TUint CmdSet() const;
+	
+	/** returns the contents of the CMD_SET_REV field */
+	inline TUint CmdSetRev() const;
+	
+	/** returns the contents of the POWER_CLASS field */
+	inline TUint PowerClass() const;
+	
+	/** returns the contents of the HS_TIMING field */
+	inline TUint HighSpeedTiming() const;
+	
+	/** returns the contents of the BUS_WIDTH field */
+	inline TUint BusWidthMode() const;
+	
+	/** returns the contents of the BOOT_CONFIG field */
+	inline TUint BootConfig() const;
+
+	/** returns the contents of the BOOT_BUS_WIDTH field */
+	inline TUint BootBusWidth() const;
+
+	/** returns the contents of the ERASE_GROUP_DEF field */
+	inline TUint EraseGroupDef() const;
+
+	/** returns the contents of the ACC_SIZE field */
+	inline TUint AccessSize() const;
+
+	/** returns the contents of the HC_ERASE_GRP_SIZE field */
+	inline TUint HighCapacityEraseGroupSize() const;
+	
+	/** returns the contents of the BOOT_INFO field */
+	inline TUint BootInfo() const;
+	
+	/** returns the contents of the BOOT_SIZE_MUTLI field */
+	inline TUint BootSizeMultiple() const;
+	
+	/** returns the contents of the ERASE_TIMEOUT_MULT field */
+	inline TUint EraseTimeoutMultiple() const;
+	
+	/** returns the contents of the REL_WR_SEC_C field */
+	inline TUint ReliableWriteSector() const;
+	
+	/** returns the contents of the HC_WP_GRP_SIZE field */
+	inline TUint HighCapacityWriteProtectGroupSize() const;
+	
+	/** returns the contents of the S_C_VCC field */
+	inline TUint SleepCurrentVcc() const;
+	
+	/** returns the contents of the S_C_VCCQ field */
+	inline TUint SleepCurrentVccQ() const;
+	
+	/** returns the contents of the S_A_TIMEOUT field */
+	inline TUint SleepAwakeTimeout() const;
+
+private:
+	/** 
+	@internalComponent little endian 512 byte field representing extended CSD	
+	*/
+	TUint8 iData[KMMCExtendedCSDLength];
+	};
+
+
+//	32 bit MMC card status field (response R1)
+
+const TUint32 KMMCStatAppCmd=			KBit5;
+const TUint32 KMMCStatSwitchError=		KBit7;
+const TUint32 KMMCStatReadyForData=		KBit8;
+const TUint32 KMMCStatCurrentStateMask=	(KBit13-KBit9);
+const TUint32 KMMCStatEraseReset=		KBit13;
+const TUint32 KMMCStatCardECCDisabled=	KBit14;
+const TUint32 KMMCStatWPEraseSkip=		KBit15;
+const TUint32 KMMCStatErrCSDOverwrite=	KBit16;
+const TUint32 KMMCStatErrOverrun=		KBit17;
+const TUint32 KMMCStatErrUnderrun=		KBit18;
+const TUint32 KMMCStatErrUnknown=		KBit19;
+const TUint32 KMMCStatErrCCError=		KBit20;
+const TUint32 KMMCStatErrCardECCFailed=	KBit21;
+const TUint32 KMMCStatErrIllegalCommand=KBit22;
+const TUint32 KMMCStatErrComCRCError=	KBit23;
+const TUint32 KMMCStatErrLockUnlock=	KBit24;
+const TUint32 KMMCStatCardIsLocked=		KBit25;
+const TUint32 KMMCStatErrWPViolation=	KBit26;
+const TUint32 KMMCStatErrEraseParam=	KBit27;
+const TUint32 KMMCStatErrEraseSeqError=	KBit28;
+const TUint32 KMMCStatErrBlockLenError=	KBit29;
+const TUint32 KMMCStatErrAddressError=	KBit30;
+const TUint32 KMMCStatErrOutOfRange=	KBit31;
+
+const TUint32 KMMCStatErrorMask=		KMMCStatErrOutOfRange	|
+										KMMCStatErrAddressError	|
+										KMMCStatErrBlockLenError|
+										KMMCStatErrEraseSeqError|
+										KMMCStatErrEraseParam	|
+										KMMCStatErrWPViolation	|
+										KMMCStatErrLockUnlock	|
+										KMMCStatErrCardECCFailed|
+										KMMCStatErrCCError		|
+										KMMCStatErrUnknown		|
+										KMMCStatErrUnderrun		|
+										KMMCStatErrOverrun		|
+										KMMCStatErrCSDOverwrite;
+
+
+const TUint32 KMMCStatClearByReadMask=	KMMCStatErrOutOfRange	|
+										KMMCStatErrAddressError	|
+										KMMCStatErrBlockLenError|
+										KMMCStatErrEraseSeqError|
+										KMMCStatErrEraseParam	|
+										KMMCStatErrWPViolation	|
+										KMMCStatErrLockUnlock	|
+										KMMCStatErrCardECCFailed|
+										KMMCStatErrCCError		|
+										KMMCStatErrUnknown		|
+										KMMCStatErrUnderrun		|
+										KMMCStatErrOverrun		|
+										KMMCStatErrCSDOverwrite	|
+										KMMCStatWPEraseSkip		|
+										KMMCStatEraseReset		|
+										KMMCStatAppCmd;
+
+enum TMMCardStateEnum
+	{
+	ECardStateIdle = 0,
+	ECardStateReady =	(1 << 9),
+	ECardStateIdent =	(2 << 9),
+	ECardStateStby =	(3 << 9),
+	ECardStateTran =	(4 << 9),
+	ECardStateData =	(5 << 9),
+	ECardStateRcv =		(6 << 9),
+	ECardStatePrg =		(7 << 9),
+	ECardStateDis =		(8 << 9),
+	ECardStateBtst = 	(9 << 9),
+	ECardStateSlp = 	(10 << 9)
+	};
+
+class TMMCStatus
+/**
+	MMC Status class. 
+	This class can be used to get the MMC card state machine and response status.
+	For the details of MMC card state machine and command response refer to MMC card specification.
+    
+	@see DMMCStack
+	@publishedPartner
+	@released
+*/
+	{
+public:
+	/**
+    * Default constructor.
+    */
+	inline TMMCStatus() {}
+	inline TMMCStatus(const TUint8*);
+	inline TMMCStatus(const TUint32&);
+	inline operator TUint32() const;
+	inline TUint32 Error() const;
+	inline TMMCardStateEnum State() const;
+	inline void UpdateState(TMMCardStateEnum aState);
+private:
+	TUint32 iData;				//	32 bit bitfield representing status register
+	};
+
+
+
+const TUint32 KMMCOCRBusy           = KBit31;			// OCR Busy Bit (Response R3)
+const TUint32 KMMCOCRAccessModeHCS	= KBit30;			// OCR Access Mode + SD HCS Bit  (Response R3)
+const TUint32 KMMCOCRLowVoltage     = KBit7;			// 1.65 - 1.95 volt support
+const TUint32 KMMCOCRAccessModeMask	= KBit30 | KBit29;	// OCR Access Mode : [00 : Byte], [10 : Block]
+
+
+
+/**
+	Defines the bit value that can be used in TPBusPsuInfo::iVoltageSupported
+	to indicate that the MultiMediaCard PSU supports voltage adjustment.
+
+	@publishedPartner
+	@released
+*/
+#define KMMCAdjustableOpVoltage KMMCOCRBusy // Use same bit to flag ASSP PSU supports voltage adjustment.
+
+
+class TMMCArgument
+/**
+	MMC Argument class
+
+	@publishedPartner
+	@released
+*/
+	{
+public:
+	inline TMMCArgument();
+	inline TMMCArgument(const TUint32&);
+	inline TMMCArgument(TRCA);
+	inline TMMCArgument(TDSR);
+	inline operator TUint32() const;
+	inline void SetRCA(TRCA);
+private:
+	TUint32 iData;				//	32 bit bitfield representing the argument
+	};
+
+
+class TRCA
+/**
+	MMC RCA (Relative Card Address) class
+*/
+	{
+public:
+	inline TRCA() {}
+	inline TRCA(TUint16);
+	inline TRCA(TInt);
+	inline TRCA(TMMCArgument);
+	inline operator TUint16() const;
+private:
+	TUint16	iData;	// 16 bit bitfield representing MultiMedia Card's RCA
+	};
+
+
+class TDSR
+/**
+	MMC DSR (Driver Stage Register) class
+*/
+	{
+public:
+	inline TDSR();
+	inline TDSR(TUint16);
+	inline operator TUint16() const;
+private:
+	TUint16	iData;	// 16 bit bitfield representing MultiMedia Card's DSR
+	};
+
+
+// Card specific information and context
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCardHasPassword=			KBit0;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCardIsWriteProtected=		KBit1;
+
+/**
+@publishedPartner
+@released
+*/
+const TUint32 KMMCardIsLockable=			KBit2;
+const TUint32 KMMCardIsHighCapacity=		KBit3;
+const TUint32 KMMCardIsHighSpeed=			KBit4;
+
+const TUint32 KMMCardMMCFlagMask=			0x0000ffff;
+
+const TUint32 KMMCardFirstCustomFlag=		KBit16;
+const TUint32 KMMCardCustomFlagMask=		0xffff0000;
+
+const TUint32 KMMCardHighCapBlockSize=		512;
+const TUint32 KMMCardHighCapBlockSizeLog2=	9;
+
+NONSHARABLE_CLASS(TMMCard)
+/**
+	MMC card class
+*/
+	{
+public:
+	inline TBool IsHighCapacity() const;
+
+	/**	@publishedPartner
+		@released */
+	TMMCard();
+
+	/**	@publishedPartner
+		@released */
+	inline TBool IsPresent() const;
+
+	/**	@publishedPartner
+		@released */
+	IMPORT_C TBool IsReady() const;
+
+	/**	@publishedPartner
+		@released */
+	IMPORT_C TBool IsLocked() const;
+
+	/**	@publishedPartner
+		@released */
+	inline TMMCMediaTypeEnum MediaType() const;
+
+	/**	@publishedPartner
+		@released */
+	inline TUint DeviceSize() const;
+
+	/**	@publishedPartner
+		@released */
+	inline const TCID& CID() const;
+
+	/**	@publishedPartner
+		@released */
+	inline const TCSD& CSD() const;
+
+	/**	@publishedPartner
+		@released */
+	inline const TExtendedCSD& ExtendedCSD() const;
+
+	/**	@publishedPartner
+		@released */
+	inline TRCA RCA() const;
+
+	/**	@publishedPartner
+		@released */
+	inline TBool HasPassword() const;
+
+	/**	@publishedPartner
+		@released */
+	inline TBool IsWriteProtected() const;	// Always EFalse in MMC build
+
+	/**	@publishedPartner
+		@released */
+	inline TInt BusWidth() const;
+
+	/**	@publishedPartner
+		@released */
+	inline void SetBusWidth(TInt aBusWidth);
+
+    /** @internalTechnology */
+	inline void SetHighSpeedClock(TUint32 aHighSpeedClock);
+
+    /** @internalTechnology */
+	inline TUint32 HighSpeedClock() const;
+
+	/**	@publishedPartner
+		@released */
+	virtual TUint32 PreferredWriteGroupLength() const;
+
+	/**	@publishedPartner
+		@released */
+	virtual TInt GetFormatInfo(TLDFormatInfo& aFormatInfo) const;
+
+	/**	@publishedPartner
+		@released */
+	virtual TUint32 MinEraseSectorSize() const;
+
+	/**	@publishedPartner
+		@released */
+	virtual TUint32 EraseSectorSize() const;
+
+	virtual TUint MaxTranSpeedInKilohertz() const;
+
+	virtual TInt GetEraseInfo(TMMCEraseInfo& anEraseInfo) const;
+
+	/**	@publishedPartner
+		@released 
+
+		Returns the maximum block length supported by the card encoded as a logarithm.
+		This may be less than the READ_BL_LEN field in the CSD 
+		register depending on the type of card and it's capacity.
+	*/
+	virtual TInt MaxReadBlLen() const;
+
+	/**	@publishedPartner
+		@released 
+
+		Returns the maximum write block length supported by the card encoded as a logarithm.
+		This may be less than the WRITE_BL_LEN field in the CSD 
+		register depending on the type of card and it's capacity.
+	*/
+	virtual TInt MaxWriteBlLen() const;
+
+	/**	@publishedPartner
+		@released */
+	virtual TInt64 DeviceSize64() const;
+
+private:
+	inline TInt Number() const;
+public:
+	TInt iIndex;
+	TMMCStatus iStatus;				// last card's status
+	TUint32 iSetBlockLen;			// current block length set for the card
+	TMMCCommandEnum iLastCommand;	// Last Command code issued for the card
+	TCID iCID;
+	TCSD iCSD;
+	TRCA iRCA;
+	DMMCSession* iUsingSessionP;	// session which has this card attached
+	TUint32 iFlags;					
+	TExtendedCSD iExtendedCSD;
+private:
+	TUint32 iHighSpeedClock;
+	TInt iSpare[4];
+	TInt iBusWidth;
+	friend class DMMCStack;
+	friend class TMMCardArray;
+	};
+
+class TMMCardArray
+/**
+	MMC card array class
+*/
+	{
+public:
+	inline TMMCardArray(DMMCStack* anOwningStack);
+	
+	/**	@publishedPartner
+		@released */
+	IMPORT_C virtual TInt AllocCards();
+
+	void InitNewCardScan();
+
+	/**	@publishedPartner
+		@released */
+	IMPORT_C void AddNewCard(const TUint8* aCID,TRCA* aNewRCA);
+
+	inline TUint NewCardCount();
+	inline TInt CardsPresent();
+	inline TMMCard* NewCardP(TUint aNewCardNumber);
+	inline TMMCard* CardP(TUint aCardNumber);
+	inline TMMCard& Card(TUint aCardNumber);
+	inline TMMCard& NewCard(TUint aCardNumber);
+	TInt MergeCards(TBool aFirstPass);
+	void UpdateAcquisitions(TUint* aMaxClock);
+
+    /** @internalTechnology */
+	TInt CardIndex(const TMMCard* aCard);
+	
+	/**	@publishedPartner
+		@released */
+	IMPORT_C virtual void DeclareCardAsGone(TUint aCardNumber);
+
+protected:										// initialized by AllocCards()
+	void MoveCardAndLockRCA(TMMCard& aSrc,TMMCard& aDest,TInt aDestIndex);
+	DMMCStack* iOwningStack;
+	TInt iCardsPresent;
+	TUint iNewCardsCount;
+	TMMCard* iCards[KMaxMMCardsPerStack];
+	TMMCard* iNewCards[KMaxMMCardsPerStack];
+	};
+
+// MMC Command descriptor
+
+const TUint32 KMMCCmdFlagBytesValid=	KBit0;	// iBytesDone has a valid data
+const TUint32 KMMCCmdFlagTransStopped=	KBit1;	// CMD12 has been successfully issued
+const TUint32 KMMCCmdFlagStatusReceived=KBit2;	// Raised by ASSP layer, cleared by ExecCommandSM()
+const TUint32 KMMCCmdFlagExecTopBusy=	KBit3;	// ExecCommandSM() flag
+const TUint32 KMMCCmdFlagExecSelBusy=	KBit4;	// ExecCommandSM() flag
+const TUint32 KMMCCmdFlagBlockAddress=	KBit5;	// Block addressing mode
+const TUint32 KMMCCmdFlagDMARamValid=   KBit6;  // Memory is DMA'able flag
+const TUint32 KMMCCmdFlagDoubleBuffer=  KBit7;  // The current DT command is double-buffered
+const TUint32 KMMCCmdFlagPhysAddr=		KBit8;  // Address is a physical address
+const TUint32 KMMCCmdFlagReliableWrite=	KBit9;  // Current command is Reliable Write
+
+const TUint32 KMMCCmdFlagASSPFlags=	KMMCCmdFlagBytesValid	|
+									KMMCCmdFlagTransStopped	|
+									KMMCCmdFlagStatusReceived;
+
+
+
+
+/**
+The MultiMediaCard command specification.
+
+@publishedPartner
+@released
+*/
+class TMMCCommandSpec
+	{
+public:
+    /**
+    The command class as defined by the MultiMediaCard System Specification.
+    */
+	TUint32 iCommandClass;
+	
+	/**
+	The command type as defined by the MultiMediaCard System Specification.
+	*/
+	TMMCCommandTypeEnum iCommandType;
+	
+	/**
+	The data transfer direction.
+	*/
+	TMMCCmdDirEnum iDirection;
+	
+	/**
+	ETrue indicates more than one data block is to be tranferred.
+	*/
+	TBool iMultipleBlocks;
+	
+	/**
+	ETrue indicates use standard stop transmission mode.
+	*/
+	TBool iUseStopTransmission;		// CMD12 has to be used in the end
+	
+	/**
+	The expected response type.
+	
+	Note:
+	
+	- if this is EResponseTypeNone, then no response is expected.
+	- if this is ERespTypeR2, then a long (128-bit) response is expected.
+	- for all other types, a standard (32-bit) response is expected.
+	*/
+	TMMCResponseTypeEnum iResponseType;
+	
+	/**
+	Expected response length (currently 4 or 16 bytes).
+	*/
+	TUint iResponseLength;
+	};
+
+class TMMCIdxCommandSpec
+/**
+	MMC Index command spec class
+*/
+	{
+public:
+	TInt iIdx;
+	TMMCCommandSpec iSpec;
+	};
+
+
+
+
+/**
+	MMC command description.
+	
+	When issuing an individual command over the bus, the MultiMediaCard
+	controller uses an object of this type to specify the parameters
+	for the command, and to receive back any response.
+	
+	Commands are issued by passing an object of this type to
+	the DMMCStack::IssueMMCCommandSM() function, which is implemented by
+	the platform specific layer.
+
+	@publishedPartner
+	@released
+*/
+class TMMCCommandDesc
+	{
+public:
+	IMPORT_C TInt Direction() const;			// returns -1/0/+1 for read/none/write
+ 
+	inline TBool IsBlockCmd() const;
+	inline TUint32 NumBlocks() const;
+	inline TInt64 Arg64() const;	
+	inline TBool IsDoubleBuffered() const;
+	inline TUint32 BufferLength() const;
+	inline TUint32 BlockLength() const;
+	inline TBool IsPhysicalAddress() const;
+	TBool AdjustForBlockOrByteAccess(const DMMCSession& aSession);
+
+	void Dump(TUint8* aResponseP, TMMCErr aErr);
+
+public:
+    /**
+    @internalComponent
+    */
+	TUint32 iFlags;
+	
+	/**
+	The command code.
+	
+	This can be written directly to the MMC controller hardware.
+	*/
+	TMMCCommandEnum iCommand;
+	
+	/**
+    The argument to be supplied with the command.
+    
+   	This can be written directly to the MMC controller hardware.
+	*/
+	TMMCArgument iArgument;
+	
+	/**
+	The total length of the data to be tranferred.
+	*/
+	TUint32 iTotalLength;
+	
+	/**
+	A pointer to the location from where the data is to be read, or written. 
+	*/
+	TUint8* iDataMemoryP;
+	
+	/**
+	The block length to be used in a data transaction.
+	*/
+	TUint32 iBlockLength;
+	
+	/**
+	The MultiMediaCard command specification.
+	*/
+	TMMCCommandSpec iSpec;
+	
+	/**
+	The number of bytes transferred since the last time the card was selected.
+	*/
+	TUint32 iBytesDone;
+	
+    /**
+    @internalComponent
+    */
+	TUint iPollAttempts;			// Retry counters
+	
+    /**
+    @internalComponent
+    */
+	TUint iTimeOutRetries;
+	
+    /**
+    @internalComponent
+    */
+	TUint iCRCRetries;
+	
+    /**
+    @internalComponent
+    */
+	TUint16 iUnlockRetries;
+	
+    /**
+    @internalComponent
+    */
+	TUint16 iOpCondBusyTimeout;		// Units of 10mS
+	
+    /**
+    @internalComponent
+    */
+	TUint iCustomRetries;
+	
+    /**
+    @internalComponent
+    */
+	TUint32 iExecNotHandle;			// error codes to not handle in ExecCommandSM()
+	
+	/**
+	The area into which the command response is put.
+	
+	This is in big-endian format.
+	*/
+	TUint8 iResponse[KMMCMaxResponseLength];
+	};
+
+
+
+
+/**
+	MMC bus configuration.
+
+    An object of this type is passed to the Variant implementation
+	of DMMCStack::SetBusConfigDefaults(), which should fill the public data
+	members with appropriate information and values.
+
+	@publishedPartner
+	@released
+*/
+class TMMCBusConfig
+	{
+public:
+    /**
+    The hardware interface clock, in KHz.
+    */
+	TUint iBusClock;
+	
+	
+	/**
+	The bus clock when clocking in data, in KHz.
+	*/
+	TUint iClockIn;
+	
+	
+	/**
+	The bus clock when clocking out data, in KHz.
+	*/
+	TUint iClockOut;
+	
+	
+	/**
+	The response timeout value, in uS.
+	*/
+	TUint iResponseTimeOut;
+	
+	
+	/**
+	The data timeout value, in uS.
+	*/
+	TUint iDataTimeOut;
+	
+	
+	/**
+	The busy timeout value, in uS.
+	*/
+	TUint iBusyTimeOut;
+	};
+
+
+class TMMCStackConfig
+/**
+   	@publishedPartner
+	@released
+
+	Holds the stack configuration settings on behalf of a session.
+
+	Each DMMCSession object contains the public member DMMCSession::iConfig - an instance of the TMMCStackConfig class.
+	By changing these settings, the client can override the master (i.e. default) stack configuration settings. 
+
+	However, these changes only remain in effect for the period that the session remains the current session.
+	In this way, the client is able to change the settings employed by the Controller (e.g. bus clock, enable retries, 
+	change time-out values, restore defaults etc) while it performs that client's request. 
+
+	The client would generally set-up the stack configuration it requires prior to submitting the session.
+*/
+	{
+public:
+	inline TMMCStackConfig();
+	inline void SetMode(TUint32 aMask);
+	inline void RemoveMode(TUint32 aMask);
+	inline void UseDefault(TUint32 aMask);
+	inline void SetPollAttempts(TUint aData);
+	inline void SetTimeOutRetries(TUint aData);
+	inline void SetCRCRetries(TUint aData);
+	inline void SetBusClockInKhz(TUint aParam);			// In kilohertz
+	inline void SetTicksClockIn(TUint aParam);			// Number of clock ticks in ClockIn phase
+	inline void SetTicksClockOut(TUint aParam);			// Number of clock ticks in ClockOut phase
+	inline void SetResponseTimeOutInTicks(TUint aParam);	// Timeout in bus clock ticks
+	inline void SetDataTimeOutInMcs(TUint aParam);		// in microseconds
+	inline void SetBusyTimeOutInMcs(TUint aParam);		// in microseconds
+	inline void SetOpCondBusyTimeout(TUint16 aData);	// Units of 10mS
+	inline TInt OpCondBusyTimeout();
+	TUint iPollAttempts;
+private:
+	TUint32 iModes;
+	TUint32 iUpdateMask;
+	TUint32 iClientMask;
+	TUint iTimeOutRetries;
+	TUint iCRCRetries;
+	TUint16 iUnlockRetries;
+	TUint16 iOpCondBusyTimeout;							// Units of 10mS
+	TMMCBusConfig iBusConfig;
+	friend class DMMCStack;
+	};
+
+
+class TMMCRCAPool
+/**
+	MMC RCA Pool
+*/
+	{
+public:
+	inline TMMCRCAPool();
+	TRCA GetFreeRCA();
+	inline void LockRCA(TRCA);
+	inline void UnlockRCA(TRCA);
+	inline void ReleaseUnlocked();
+private:
+	TUint32 iPool;
+	TUint32 iLocked;
+	};
+
+
+class TMMCSessRing
+/**
+	MMC session ring
+*/
+	{
+public:
+	TMMCSessRing();
+	inline TBool IsEmpty() const;
+	void Erase();
+	inline void SetMarker();				// Sets Marker into Point position
+	inline void AdvanceMarker();			// Moves Marker one position forward
+	inline void Point();					// Sets Point into Marker position
+	TBool Point(DMMCSession* aSessP);		// Finds aSessP and sets Point to it
+	void Add(DMMCSession* aSessP);			// Inserts aSessP before the Marker; Point moves to Marker
+	void Add(TMMCSessRing& aRing);
+	DMMCSession* Remove();					// Removes at Point; Point moves forward
+	void Remove(DMMCSession* aSessP);		// Points aSessP first, then remove()
+	inline TUint Size() const;
+	inline operator DMMCSession*() const;
+	DMMCSession* operator++(TInt);			// returns Point and moves it forward; stops at Marker
+private:
+	DMMCSession* iPMark;
+	DMMCSession* iPoint;
+	DMMCSession* iPrevP;
+	TUint iSize;
+	};
+
+
+//
+// DMMCStack State Machine Functions are supported by TMMCStateMachine class
+//
+// The structure of state machine functions is assumed to be as follows
+//
+// TMMCErr DMMCStack::FunctionNameSMST( TAny* aPtr )
+//	{ return( STATIC_CAST(DMMCStack*,aPtr)->FunctionNameSM() ); }
+//
+// TMMCErr DMMCStack::FunctionNameSM()
+//	{
+//		enum states {EStBegin=0, ..., EStEnd };
+//		DMMCSession& s = Session();
+//		TMMCStateMachine& m = Machine();
+//		const TMMCErr err = m.SetExitCode( 0 );
+//
+//		for(;;)
+//		{
+//			switch(m.State())
+//			{
+//			case EStBegin:
+//				{
+//					....
+//				}
+//			case EStNext:
+//				{
+//					.....
+//				}
+//			case EStEnd: break;
+//			default: Panic(...);
+//			}
+//			break;
+//		}
+//		return(m.Pop());
+//	}
+//
+// State Machine remembers the next state number and function name and goes there as soon
+// as the control is returned to the session. To release the control and wait for the next
+// re-entrance (which will happen immediately if the session is not blocked or, as soon as
+// an asynchronous event removes the blocking condition), a state machine function has to
+// return( 0 ); Returning non-zero exit code will result in the session being completed with
+// that error code unless a caller state machine function has explicitly intercepted such
+// an error with m.SetTraps( TMMCErr aMask ).
+//
+// To make a state machine function code more readable, the following macros are provided:
+//
+// SMF_NEXTS(nexts)				- set the next state to "nexts"
+// SMF_CALL(func)				- invoke SM function "func", then go to the next state
+// SMF_CALLWAIT(func)			- the same as above, but sleep at the entry point
+// SMF_CALLMYS(nexts,retst)		- invoke current SM function at "nexts" entry point
+// SMF_CALLMEWR(retst)			- invoke me right here with return state retst
+// SMF_INVOKES(func,nexts)		- invoke SM function "func", then go to the state "nexts"
+// SMF_INVOKEWAITS(func,nexts)	- the same as above, but sleep at the entry point
+// SMF_WAIT						- sleep at the next state
+// SMF_WAITS(nexts)				- set next state to "nexts", then sleep
+// SMF_RETURN(value)			- return an error to the caller SM function
+// SMF_EXIT						- return to the caller SM function
+// SMF_EXITWAIT					- the same as above, but sleep at the exit point
+// SMF_JUMP(func)				- transfer the control to SM function "func"
+// SMF_JUMPWAIT(func)			- the same as above, but sleep at the entry point
+// SMF_GOTONEXTS				- goto the next state
+// SMF_GOTOS(nexts)				- set the next state to "nexts", then go to it
+// SMF_STATE(sname)				- declare the state name "sname"
+// SMF_BPOINT(sname)			- declare the state "sname" and sleep here if blocked statically
+//
+
+/**
+@publishedPartner
+@released
+
+Declares the start of a state machine case switch statement.
+
+The macro assumes that the first state defined by the state machine
+function is EStBegin.
+
+NOTES:
+
+- the code generates an opening curly brace that must be matched by
+a closing curly brace. Typically, this is provided by the SMF_STATE or
+the SMF_END macros.
+
+@see SMF_STATE
+@see SMF_END
+*/
+#define SMF_BEGIN TMMCStateMachine& m=Machine();const TMMCErr err=m.SetExitCode(0);\
+				for(;;){switch(m.State()){case EStBegin:{if(err) (void)0;
+
+/**
+@publishedPartner
+@released
+
+Declares the end of a state machine case switch statement.
+
+The macro assumes that the last state defined by the state machine
+function is EStEnd.
+
+NOTES:
+
+- the code generated assumes that there are earlier calls to SMF_BEGIN, 
+and zero or more calls to SMF_STATE.
+
+@see SMF_BEGIN
+@see SMF_STATE
+*/
+#define SMF_END }case EStEnd:break;default:DMMCSocket::Panic(DMMCSocket::EMMCMachineState);}break;}\
+				return(m.Pop());
+
+
+/**
+@publishedPartner
+@released
+
+Sets the next state when the current state machine
+function is re-entered.
+
+@param nexts The next state to be entered in the current state machine.
+*/
+#define SMF_NEXTS(nexts) m.SetState(nexts);
+
+
+/**
+@publishedPartner
+@released
+
+Pushes a state machine entry onto the stack, specifying the child state machine
+function to be invoked.
+
+The child function will be entered at state 0 (EStBegin), when the state machine
+is next dispatched.
+
+Control returns from this state machine function after completion of
+all functions coded by this macro.
+
+@param func The child state machine function to be invoked.
+*/
+#define SMF_CALL(func) return(m.Push(func));
+
+
+/**
+@publishedPartner
+@released
+
+Pushes a state machine entry onto the stack, specifying the child state machine
+function to be invoked.
+
+The state machine is blocked before entry to the child function, but when
+it becomes unblocked, the child function will be entered at state 0 (EStBegin)
+when the state machine is next dispatched.
+
+Control returns from this state machine function after completion of
+all functions coded by this macro.
+
+@param func The child state machine function to be invoked.
+*/
+#define SMF_CALLWAIT(func) return(m.Push(func,ETrue));
+
+
+/**
+@publishedPartner
+@released
+
+Sets the next state for the current state machine function - control will
+flow to this state on completion of all functions coded by this macro.
+
+The macro also pushes a state machine entry onto the stack, specifying
+the CURRENT state machine function as the child state machine function to be
+invoked, and sets the state in which this child state machine function will
+be entered, when it gains control.
+
+NOTES:
+
+- the child function is the same as the parent function.
+- the state machine is blocked on return from the current state machine function.
+
+@param nexts The state in which the child state machine function will
+             gain control.
+@param retst The next state for the current state machine function.
+*/
+#define SMF_CALLMYS(nexts,retst) {m.SetState(retst);m.PushMe();m.SetState(nexts);continue;}
+
+
+/**
+@publishedPartner
+@released
+
+Sets the next state for the current state machine function - control flows to
+the next instruction on completion of all functions coded by this macro.
+
+The macro also pushes a state machine entry onto the stack, specifying
+the CURRENT state machine function as the child state machine function to be
+invoked. The child function will be entered at state 0 (EStBegin), when the state machine
+is next dispatched.
+
+NOTES:
+
+- the child function is the same as the parent function.
+- the state machine is blocked on return from the current state machine function.
+
+@param retst The next state for the current state machine function.
+*/
+#define SMF_CALLMEWR(retst) {m.SetState(retst);m.PushMe();}
+
+
+/**
+@publishedPartner
+@released
+
+Sets the next state for the current state machine function.
+
+The macro also pushes a state machine entry onto the stack, specifying
+the child state machine function to be
+invoked. The child function will be entered at state 0 (EStBegin), when the state machine
+is next dispatched.
+
+Control returns from the current state machine function after completion of
+all functions coded by this macro.
+
+@param func  The child state machine function to be invoked.
+@param nexts The next state for the current state machine function.
+*/
+#define SMF_INVOKES(func,nexts) {m.SetState(nexts);return(m.Push(func));}
+
+
+/**
+@publishedPartner
+@released
+
+Sets the next state for the current state machine function.
+
+The macro also pushes a state machine entry onto the stack, specifying
+the child state machine function to be
+invoked. The child function will be entered at state 0 (EStBegin), when the state machine
+is next dispatched.
+
+Control returns from the current state machine function after completion of
+all functions coded by this macro.
+
+NOTES:
+
+- the state machine is blocked on return from the current state machine function.
+
+@param func  The child state machine function to be invoked.
+@param nexts The next state for the current state machine function. 
+*/
+#define SMF_INVOKEWAITS(func,nexts) {m.SetState(nexts);return(m.Push(func,ETrue));}
+
+
+/**
+@publishedPartner
+@released
+
+Returns from the current state machine function, and the state machine then blocks (waits).
+*/
+#define SMF_WAIT return(0);
+
+
+/**
+@publishedPartner
+@released
+
+Sets the next state for the current state machine function; control then returns
+from the current state machine function, and the state machine blocks (waits).
+
+@param nexts The next state for the current state machine function. 
+*/
+#define SMF_WAITS(nexts) return(m.SetState(nexts));
+
+
+/**
+@publishedPartner
+@released
+
+Returns the specified error value to the calling (parent) state machine function.
+
+@param value The error value to be returned.
+*/
+#define SMF_RETURN(value) {m.Pop();return(value);}
+
+
+/**
+@publishedPartner
+@released
+
+Returns to the calling state machine function.
+*/
+#define SMF_EXIT break;
+
+
+/**
+@publishedPartner
+@released
+
+Returns to the calling state machine function, and the state machine blocks (waits).
+*/
+#define SMF_EXITWAIT return(m.Pop(ETrue));
+
+
+/**
+@publishedPartner
+@released
+
+Transfers control to the specified state machine function.
+
+NOTES:
+
+- this function is executed at the same stack entry level as the current state machine function.
+
+@param func The state machine function to which control is to be transferred.
+*/
+#define SMF_JUMP(func) return(m.Jump(func));
+
+
+/**
+@publishedPartner
+@released
+
+Transfers control to the specified state machine function, and waits
+at its entry point.
+
+@param func The state machine function to which control is to be transferred.
+*/
+#define SMF_JUMPWAIT(func) return(m.Jump(func,ETrue));
+
+
+/**
+@publishedPartner
+@released
+
+Goes to the next state.
+*/
+#define SMF_GOTONEXTS continue;
+
+
+/**
+@publishedPartner
+@released
+
+Sets the next state and then goes to that state.
+
+@param nexts The next state.
+*/
+#define SMF_GOTOS(nexts) {m.SetState(nexts);continue;}
+
+
+/**
+@publishedPartner
+@released
+
+Declares the name of a state.
+
+This is used to generate a case statement based on the state name.
+
+@param sname The state name.
+*/
+#define SMF_STATE(sname) }case sname:{
+
+
+/**
+@publishedPartner
+@released
+
+Declares the name of a state, and sleeps here
+if blocked statically.
+
+@param sname The state name.
+*/
+#define SMF_BPOINT(sname) }case sname: if(StaticBlocks()) return(m.SetState(sname));{
+
+
+
+
+class TMMCStateMachine
+/**
+	The MultiMediaCard state machine.
+
+	@publishedPartner
+	@released
+*/
+	{
+public:
+	inline void Setup(TMMCErr (*anEntry)(TAny*), TAny* aContextP);
+	IMPORT_C void Reset();
+	IMPORT_C TMMCErr Dispatch();
+	inline TMMCErr ExitCode();
+	inline TMMCErr SetExitCode(TMMCErr aCode);
+	inline TUint State();
+	inline TMMCErr SetState(TUint aState);
+	inline void SuppressSuspension();
+	inline void SetTraps(TMMCErr aMask);
+	inline void ResetTraps();
+	inline void Abort();
+	inline TMMCErr Pop(TBool aSuspend=EFalse);
+	inline TMMCErr PushMe();
+	IMPORT_C TMMCErr Push(TMMCErr (*anEntry)(TAny*), TBool aSuspend=EFalse);
+	IMPORT_C TMMCErr Jump(TMMCErr (*anEntry)(TAny*), TBool aSuspend=EFalse);
+private:
+	class TMMCMachineStackEntry
+		{
+	public:
+		TMMCErr (*iFunction)(TAny*);
+		TUint iState;
+		TMMCErr iTrapMask;
+		};
+	TBool iAbort;
+	TBool iSuspend;
+	TAny* iContextP;
+	TMMCErr iExitCode;
+	TInt iSP;
+	TMMCMachineStackEntry iStack[KMaxMMCMachineStackDepth];
+	};
+
+class TMMCCallBack
+/**
+	This class is used to notify the request completion as a callback function for the clients of DMMCSession.
+    The callback function will be called on session completion.
+	Callback function is used to indicate Asynchronous Completion.
+
+	@see DMMCSession
+	@publishedPartner
+	@released
+*/
+	{
+public:
+	inline TMMCCallBack();
+	inline TMMCCallBack(void (*aFunction)(TAny* aPtr));
+	inline TMMCCallBack(void (*aFunction)(TAny* aPtr), TAny* aPtr);
+	inline void CallBack() const;
+public:
+	/**
+	A pointer to the callback function.
+	*/
+	void (*iFunction)(TAny* aPtr);
+
+	/**
+	A pointer that is passed to the callback function when
+	the callback function is called.
+	*/
+	TAny* iPtr;
+	};
+
+// DMMCStack serves an incoming queue of session requests.
+// Each queue element is represented by an instance of the following class
+
+typedef TMMCErr (*TMMCSMSTFunc)(TAny*);
+
+class DMMCSession : public DBase
+/**
+	Provides the main interface between the client and the MMC Socket, allowing commands and responses
+	to be processed asynchronously on the stack.
+
+	Each client creates it own instance of this class.  It is then able to make MultiMediaCard requests 
+	on the selected stack by configuring the DMMCSession object with relevant information for the request 
+	and then submitting (or engaging) this session object.
+
+	The session is used to pass commands either to the entire stack (a broadcast command), or to individual
+	cards in the stack. The class contains functions for initiating  macro functions as laid down by the
+	MultiMediaCard Association (MMCA) as well as lower level functions allowing a client to control the
+	stack in a more explicit manner.
+
+	All requests on the MultiMediaCard stack which involve bus activity are inherently asynchronous.  When
+	creating a DMMCSession object, a client supplies a call-back function as part of the constructor.
+	Once a client has engaged a session on the stack, it is informed of the completion of the request by
+	the Controller calling this call-back function.
+
+	@publishedPartner
+	@released
+*/
+	{
+public:
+	IMPORT_C virtual ~DMMCSession();
+	IMPORT_C DMMCSession(const TMMCCallBack& aCallBack);
+
+	// Object initialisation
+	inline void SetStack(DMMCStack* aStackP);
+	IMPORT_C void SetCard(TMMCard* aCardP);
+
+	// Control macros setup
+	inline void SetupCIMUpdateAcq();
+	inline void SetupCIMInitStack();
+	inline void SetupCIMCheckStack();
+	inline void SetupCIMSetupCard();
+	inline void SetupCIMLockStack();
+	inline void SetupCIMInitStackAfterUnlock();
+	inline void SetupCIMAutoUnlock();
+
+	// Data transfer macros setup
+	IMPORT_C void SetupCIMReadBlock(TMMCArgument aDevAddr, TUint32 aLength, TUint8* aMemoryP);
+	IMPORT_C void SetupCIMWriteBlock(TMMCArgument aDevAddr, TUint32 aLength, TUint8* aMemoryP);
+	IMPORT_C void SetupCIMReadMBlock(TMMCArgument aDevAddr, TUint32 aLength, TUint8* aMemoryP, TUint32 aBlkLen);
+	IMPORT_C void SetupCIMWriteMBlock(TMMCArgument aDevAddr, TUint32 aLength, TUint8* aMemoryP, TUint32 aBlkLen);
+	IMPORT_C void SetupCIMEraseSector(TMMCArgument aDevAddr, TUint32 aLength);
+	IMPORT_C void SetupCIMEraseGroup(TMMCArgument aDevAddr, TUint32 aLength);
+	IMPORT_C void SetupCIMReadIO(TUint8 aRegAddr, TUint32 aLength, TUint8* aMemoryP);
+	IMPORT_C void SetupCIMWriteIO(TUint8 aRegAddr, TUint32 aLength, TUint8* aMemoryP);
+	IMPORT_C void SetupCIMLockUnlock(TUint32 aLength, TUint8* aMemoryP);
+
+	// Data transfer macros setup (block mode)
+	inline void SetupCIMReadBlock(TMMCArgument aBlockAddr, TUint8* aMemoryP, TUint32 aBlocks = 1);
+	inline void SetupCIMWriteBlock(TMMCArgument aBlockAddr, TUint8* aMemoryP, TUint32 aBlocks = 1);
+	inline void SetupCIMEraseMSector(TMMCArgument aBlockAddr, TUint32 aBlocks = 1);
+	inline void SetupCIMEraseMGroup(TMMCArgument aBlockAddr, TUint32 aBlocks = 1);
+		
+	// Raw commands (must be used in the locked bus state only)
+	// Known commands with or without (with a default) argument
+	IMPORT_C void SetupCommand(TMMCCommandEnum aCommand, TMMCArgument anArgument=0);
+
+	// Generic unknown command with unknown response type
+	IMPORT_C void SetupRSCommand(TMMCCommandEnum aCommand, TMMCArgument anArgument,
+								TUint32 aResponseLength, TMMCCommandTypeEnum aCommandType=ECmdTypeUK,
+								TMMCResponseTypeEnum aResponseType=ERespTypeUnknown,
+								TUint32 aCommandClass=KMMCCmdClassNone);
+
+	// Generic data transfer command
+	IMPORT_C void SetupDTCommand(TMMCCommandEnum aCommand, TMMCArgument anArgument,
+								TUint32 aTotalLength, TUint8* aMemoryAddress, TUint32 aBlockLength=0,
+								TBool aStopTransmission=EFalse, TMMCCmdDirEnum aDir=EDirNone,
+								TUint32 aCommandClass=KMMCCmdClassNone);
+	// Actions
+	IMPORT_C TInt Engage();					// Enque session for execution
+	inline void UnlockStack();				// Unlock the bus
+	inline void Stop();						// Signal session to complete (stop and complete)
+	inline void Abort();					// Abort only (no completion)
+
+	// Info retrieval
+	IMPORT_C TInt EpocErrorCode() const;	// Derived from MMCExitCode and LastStatus
+	inline TMMCSessionTypeEnum SessionID() const;
+	inline DMMCStack* StackP() const;		// DMMCStack serving this session
+	inline TMMCard* CardP() const;			// The current card pointer
+	inline TBool IsEngaged() const;			// Session is being served by DMMCStack
+	inline TMMCErr MMCExitCode() const;		// MMC specific error code returned by DMMCStack
+	inline TMMCStatus LastStatus() const;	// Last R1 response received from the card
+	inline TUint32 BytesTransferred() const;// The actual amount of data transferred in this session
+	inline TUint8* ResponseP();				// Current command response (&iCommand[iCmdSP].iResponse)
+	inline TUint32 EffectiveModes() const;	// Modes which DMMCStack will consider as effective
+	//
+	inline void ResetCommandStack();
+private:
+	void SetupCIMControl(TInt aSessNum);
+protected:
+	IMPORT_C virtual TMMCSMSTFunc GetMacro(TInt aSessNum) const;
+	inline void Block(TUint32 aFlag);
+	inline void UnBlock(TUint32 aFlag, TMMCErr anExitCode);
+private:
+#ifdef __EPOC32__
+	static void PollTimerCallBack(TAny* aSessP);
+	static void RetryTimerCallBack(TAny* aSessP);
+	static void ProgramTimerCallBack(TAny* aSessP);
+#endif
+	inline void SwapMe();
+	void SynchBlock(TUint32 aFlag);
+	void SynchUnBlock(TUint32 aFlag);
+public:
+	static const TMMCCommandSpec& FindCommandSpec(const TMMCIdxCommandSpec aSpecs[], TInt aIdx);
+	IMPORT_C void FillCommandDesc();
+	IMPORT_C void FillCommandDesc(TMMCCommandEnum aCommand);
+	IMPORT_C void FillCommandDesc(TMMCCommandEnum aCommand, TMMCArgument anArgument);
+	IMPORT_C void FillCommandArgs(TMMCArgument anArgument, TUint32 aLength, TUint8* aMemoryP, TUint32 aBlkLen);
+	inline TMMCCommandDesc& Command();	// The current command descriptor
+	
+	inline void PushCommandStack();
+	inline void PopCommandStack();
+
+	// Methods for double-buffered data transfer:
+	inline TBool RequestMoreData();
+	inline void EnableDoubleBuffering(TUint32 aNumBlocks);							  /**< @internalTechnology */
+	inline void SetDataTransferCallback(TMMCCallBack& aCallback);					  /**< @internalTechnology */
+	inline void MoreDataAvailable(TUint32 aNumBlocks, TUint8* aMemoryP, TInt aError); /**< @internalTechnology */
+public:
+	/**
+    The last R1 response.
+	*/
+	TMMCStatus iLastStatus;
+
+	/**
+	A pointer to the card object.
+	*/
+	TMMCard* iCardP;				// Pointer to Card Info object
+	IMPORT_C TRCA CardRCA();		// Checks that card is still ready - otherwise returns 0
+	TMMCSessionTypeEnum iSessionID;
+private:
+	DMMCSession* iLinkP;			//
+protected:
+	TMMCCallBack iCallBack;			// Where to report the completion
+private:
+	DMMCStack* iStackP;				// Pointer to Stack Controller
+	TCID iCID;						// Card ID to ensure we are still talking to the same card
+	TUint32 iBytesTransferred;		// The actual amount of data transferred in this session
+	TMMCErr iMMCExitCode;			// State Machine exit code (MMC specific)
+public:
+    /**
+    Session state flags (synchronous).
+    */
+	TUint32 iState;
+private:
+	TUint iInitContext;				// Stack Initialiser pass number
+	TUint iGlobalRetries;			// Global retry counter
+
+	// Asynchronous flags analysed by scheduler
+	TBool volatile iDoAbort;		// Marks the session for abort
+	TBool volatile iDoStop;			// Stop the session as soon as it's safe
+	TBool volatile iDoComplete;		// Completion callback is now to be invoked
+	TBool iBrokenLock;				// Stack lock is broken by force major
+	//
+	TUint32 iBlockOn;				// blocking reasons
+	TInt iCmdSP;					// Current Command stack index
+	
+	TMMCCommandDesc iCommand[KMaxMMCCommandStackDepth];	// Command stack
+	
+	TMMCCallBack iDataTransferCallback;	// A callback function, used to request more data when performing double-buffering
+
+	TUint32 iSpare[22];				// Spare data (stolen from iCommand)
+
+	TMMCStateMachine iMachine;		// State Machine context
+#ifdef __EPOC32__
+	NTimer iPollTimer;
+	NTimer iRetryTimer;
+	NTimer iProgramTimer;
+#endif
+public:
+	TMMCStackConfig iConfig;		// Client configuration parameters
+	friend class DMMCStack;
+	friend class TMMCSessRing;
+	friend class TMMCardArray;
+	};
+
+
+class DMMCStack : public DBase
+/**
+	This object controls access to the MultiMediaCard stack.
+	The DMMCSocket owns an instance of this class for the MultiMediaCard stack that it manages.
+
+	@publishedPartner
+	@released
+*/
+	{
+public:
+	/** extension interfaces Ids */
+	enum TInterfaceId
+		{
+		KInterfaceMachineInfo,
+		KInterfaceSwitchToLowVoltageSM,
+		KInterfaceSetBusWidth,
+		KInterfaceDemandPagingInfo,
+		KInterfaceCancelSession,
+		KInterfaceDoWakeUpSM
+		};
+
+	/** generic interface */
+	class MInterface
+		{
+	public:
+		virtual TInt Function() = 0;
+		};
+
+	/** 
+	Demand paging support 
+	@see KInterfaceDemandPagingInfo
+	*/
+	class TDemandPagingInfo
+		{
+	public:
+		const TInt* iPagingDriveList;
+		TInt iDriveCount;
+		TUint iPagingType;
+		TInt iReadShift;
+		TUint iNumPages;
+		TBool iWriteProtected;
+		TInt iSlotNumber;
+		TUint iSpare[2];
+		} ;
+	/**
+	 * An optional interface implemented by the PSL for returning demand-paging information.
+	 * @see KInterfaceDemandPagingInfo
+	 */
+	class MDemandPagingInfo
+		{
+	public:
+		virtual TInt DemandPagingInfo(TDemandPagingInfo& aInfo) = 0;
+		};
+	
+	/**
+	 * An optional interface State machine implemented by the PSL for handling asynchronous VccCore powerup
+	 * @see KInterfaceDoWakeUpSM
+	 */
+	class MDoWakeUp
+		{
+	public:
+		virtual TMMCErr DoWakeUpSM()=0;
+		};
+
+
+public:
+	IMPORT_C DMMCStack(TInt aBus, DMMCSocket* aSocket);
+	IMPORT_C virtual TInt Init();
+	//
+	// Actions
+	inline void ReportPowerUp();
+	inline void ReportPowerDown();
+	inline void Reset();					// Discard all requests and clear up
+	inline void CompleteAll(TMMCErr aCode);	// Complete all operations with an error
+	inline void CancelSession(DMMCSession* aSession);
+
+	IMPORT_C void PowerUpStack();
+	IMPORT_C void PowerDownStack();
+	void QSleepStack();
+	IMPORT_C TInt Stop(TMMCard* aCardP);
+	//
+	// Inquiries
+	inline TUint MaxCardsInStack() const;
+	inline TMMCard* CardP(TUint aCardNumber);
+	inline DMMCSocket* MMCSocket() const;
+	inline TMMCPasswordStore* PasswordStore() const;
+	inline TBool InitStackInProgress() const;
+	inline TBool HasSessionsQueued() const;
+	inline TBool HasCardsPresent();
+	inline void BufferInfo(TUint8*& aBuf, TInt& aBufLen, TInt& aMinorBufLen);
+	inline TInt DemandPagingInfo(TDemandPagingInfo& aInfo);
+	inline TBool StackRunning() const;
+
+
+#ifdef __EPOC32__
+
+    /**
+    Defines the period for the poll timer.
+    
+    The poll timer is used by the generic layer for platforms 
+    that do not provide an interrupt to indicate
+    when programming mode is finished.
+    
+    @return The poll timer period, in milliseconds.
+    */
+	virtual TInt ProgramPeriodInMilliSeconds()	const =0;
+#endif
+
+	/**
+	 * Calculates the minimum range that must be read off a card, an optimisation that takes advantage
+	 * of the partial read feature found on some cards.  It takes the logical range that the media driver
+	 * wants to read from the card, and increases it to take into account factors such as FIFO width and
+	 * minimum DMA transfer size.
+	 * @param aCard A pointer to the MMC Card
+	 * @param aStart The required start position
+	 * @param aEnd The required end position
+	 * @param aPhysStart The adjusted start position
+	 * @param aPhysEnd The adjusted end position
+	 */
+	virtual void AdjustPartialRead(const TMMCard* aCard, TUint32 aStart, TUint32 aEnd, TUint32* aPhysStart, TUint32* aPhysEnd) const =0;
+
+	/**
+	 * Returns the details of the buffer allocated by the socket for data transfer operations.  The buffer
+	 * is allocated and configured at the variant layer to allow , for example, contiguous pages to be
+	 * allocated for DMA transfers.
+	 * @param aMDBuf A pointer to the allocated buffer
+	 * @param aMDBufLen The length of the allocated buffer
+	 */
+	virtual void GetBufferInfo(TUint8** aMDBuf, TInt* aMDBufLen) =0;
+
+	/**
+	 * Gets the platform specific configuration information.
+	 * @see TMMCMachineInfo
+	 */
+	virtual void MachineInfo(TMMCMachineInfo& aMachineInfo) =0;
+
+	/**
+	 * Creates the session object
+	 */
+	IMPORT_C virtual DMMCSession* AllocSession(const TMMCCallBack& aCallBack) const;
+
+protected:
+	// Platform layer service
+	inline TMMCBusConfig& BusConfig();
+	inline TMMCBusConfig& MasterBusConfig();
+	inline DMMCSession& Session();				// Current session
+	inline TMMCCommandDesc& Command();			// Current command descriptor of current session
+	inline TMMCStateMachine& Machine();			// State machine of current session
+	inline void BlockCurrentSession(TUint32 aFlag);
+	inline void UnBlockCurrentSession(TUint32 aFlag, TMMCErr anExitCode);
+	inline void ReportInconsistentBusState();
+	inline void ReportASSPEngaged();
+	inline void ReportASSPDisengaged();
+	inline TRCA CurrentSessCardRCA();			// Checks that card is still ready - otherwise returns 0
+	inline void CurrentSessPushCmdStack();
+	inline void CurrentSessPopCmdStack();
+	inline void CurrentSessFillCmdDesc(TMMCCommandEnum aCommand);
+	inline void CurrentSessFillCmdDesc(TMMCCommandEnum aCommand,TMMCArgument anArgument);
+	inline void CurrentSessFillCmdArgs(TMMCArgument anArgument,TUint32 aLength,TUint8* aMemoryP,TUint32 aBlkLen);
+	inline TRCA SelectedCard() const;
+	inline void YieldStack(TMMCCommandTypeEnum aCommand);
+
+	void DoSetClock(TUint32 aClock);
+	void DoSetBusWidth(TUint32 aBusWidth);
+	TBusWidth BusWidthEncoding(TInt aBusWidth) const;
+	TUint MaxTranSpeedInKilohertz(const TMMCard& aCard) const;
+
+	// Stack service provided by platform/variant layer.
+
+	/** 
+	 * Returns the default master settings for the platform.
+	 * @param aConfig A TMMCBusConfig reference to be filled in with the default settings.
+	 * @param aClock The requested clock frequency (may be ignored if the hardware cannot support it).
+	 */
+	virtual void SetBusConfigDefaults(TMMCBusConfig& aConfig, TUint aClock)=0;
+
+	/** 
+	 * Switches from identification mode of operation to data transfer mode operation. 
+	 *
+	 * Note that at this point the clock information in iBusConfig will not have been updated 
+	 * to the new data transfer rate. This function should generally just switch from open drain 
+	 * to push-pull bus mode - with the clock rate being changed at the start of IssueMMCCommandSM, 
+	 * where iBusConfig will be valid.
+	 */
+	virtual void InitClockOff()=0;
+
+	/** 
+	 * Stop all activities on the host stack. 
+	 *
+	 * This will generally perform the same operations as for ASSPDisengage() but this will additionally 
+	 * turn off the clock to the hardware interface and release any requested power requirements made on 
+	 * the power model. (That is release any power requirements made as part of the InitClockOnSM() function).
+	 *
+	 * Called from the platform independent layer when it is required to immediately cancel any PSL asynchronous 
+	 * activity because the current session has been aborted.
+	 *
+	 * This function should normally include a call to ReportAsspDisengaged() at the end, to report to the PIL 
+	 * that the PSL level resources have been disengaged. 
+	 */
+	virtual void ASSPReset()=0;
+
+	/**
+	 * Called each time a session which has engaged PSL resources has completed or has been aborted. 
+	 *
+	 * This should disable any activities which were required to perform the session just completed/aborted.
+	 * It shouldn't however turn off the clock to the hardware interface (which will be turned off instead 
+	 * by the inactivity timer). This typically disables DMA and interface interrupts and forces the hardware 
+	 * interface into idle.
+	 *
+	 * This function should normally include a call to ReportAsspDisengaged() at the end, to report to the PIL 
+	 * that the PSL level resources have been disengaged. 
+	 */
+	virtual void ASSPDisengage()=0;
+
+	/**
+	 * Called as part of the bus power down sequence. It stops all activities on the host stack, turns off the clock 
+	 * to the hardware interface and releases any requested power requirements made on the power model 
+	 * (i.e. very often a straight call of ASSPReset()). 
+	 *
+	 * This shouldn't turn off the MMC PSU as this will be performed immediately afterwards by the PSU class.
+	 */
+	virtual void DoPowerDown()=0;
+
+	IMPORT_C virtual TBool CardDetect(TUint aCardNumber);
+	IMPORT_C virtual TBool WriteProtected(TUint aCardNumber);
+	//
+	// State Machine functions implemented in platform layer.
+
+	/**
+	 * Called as a child function at the start of the CIM_UPDATE_ACQ macro state machine. 
+	 *
+	 * It should perform the necessary PSL level actions associated with powering up the bus. This includes 
+	 * turning on the MMC PSU. However, the hardware interface clock should not be turned on as part of this function.
+	 *
+	 * If the Controller has to request power resources from the power model (e.g a fast system clock required all the 
+	 * time the bus is powered) then this state machine function can be used to asynchronously wait for this resource 
+	 * to become available.
+	 *
+	 * Upon completion, DMMCStack::ReportPowerUp() should be called.
+	 *
+	 * @return KMMCErrNone if completed successfully or standard TMMCErr code otherwise
+	 */
+	virtual TMMCErr DoPowerUpSM()=0;
+	
+	/**
+	 * Turns on the clock to the hardware interface. 
+	 *
+	 * This state machine function is called as a child function as part of the CIM_UPDATE_ACQ macro state machine. 
+	 *
+	 * It is implemented as a state machine function since it may be necessary to include a short delay after the 
+	 * clock has been turned on to allow it to stabilise, or in some cases it may be necessary to wait for a power 
+	 * resource to become available.
+	 *
+	 * This function should normally include a call to ReportAsspEngaged() at the start, to report to the PIL that the PSL 
+	 * level resources have been engaged.
+	 *
+	 * @return KMMCErrNone if completed successfully or standard TMMCErr code otherwise
+	 */
+	virtual TMMCErr InitClockOnSM()=0;
+	
+	/**
+	 * Executes a single command over the bus.
+	 *
+	 * The input parameters are passed via the current command descriptor on the session's command stack 
+	 * (TMMCCommandDesc class), which specifies the type of command, response type, arguments etc..
+	 *
+	 * @return KMMCErrNone if completed successfully or standard TMMCErr code otherwise
+	 */
+	IMPORT_C virtual TMMCErr IssueMMCCommandSM()=0;
+
+	TBool StaticBlocks();
+
+	/**
+	 * Indicates that the PSL should change the bus width.
+	 * Must be implemented by the Platform Specific Layer if MMCV4 4/8-bit bus mode is required
+	 */
+	IMPORT_C virtual void SetBusWidth(TUint32 aBusWidth);
+
+	/**
+	 * Retrieves a TMMCMachineInfoV4 from the PSL
+	 * Must be implemented by the Platform Specific Layer if MMCV4 support is required
+	 */
+public:
+	IMPORT_C virtual void MachineInfo(TDes8& aMachineInfo);
+
+protected:
+	/**
+	 * Switches the MMC bus to low voltage mode
+	 */
+	TMMCErr SwitchToLowVoltageSM();
+
+	
+private:
+	//
+	// Session service
+	void Add(DMMCSession* aSessP);
+	void Abort(DMMCSession* aSessP);
+	void Stop(DMMCSession* aSessP);
+	void UnlockStack(DMMCSession* aSessP);
+	void MarkComplete(DMMCSession* aSessP, TMMCErr anExitCode);
+	//
+	//	Stack control and operations support
+	// Scheduler and its supplementary functions
+	enum TMMCStackSchedStateEnum
+		{
+		ESchedContinue=0,
+		ESchedLoop=1,
+		ESchedExit,
+		ESchedChooseJob
+		};
+	void Scheduler(volatile TBool& aFlag);
+	void DoSchedule();
+	TMMCStackSchedStateEnum SchedGetOnDFC();
+	void SchedSetContext(DMMCSession* aSessP);
+	void SchedDoAbort(DMMCSession* aSessP);
+	TMMCStackSchedStateEnum SchedResolveStatBlocks(DMMCSession* aSessP);
+	TMMCStackSchedStateEnum SchedGroundDown(DMMCSession* aSessP, TMMCErr aReason);
+	TMMCStackSchedStateEnum SchedEnqueStackSession(TMMCSessionTypeEnum aSessID);
+	void SchedGrabEntries();
+	void SchedDisengage();
+	TBool SchedAllowDirectCommands(DMMCSession* aSessP);
+	TBool SchedYielding(DMMCSession* aSessP);
+	inline TMMCStackSchedStateEnum SchedAbortPass();
+	inline TMMCStackSchedStateEnum SchedCompletionPass();
+	inline TMMCStackSchedStateEnum SchedInitStack();
+	inline TMMCStackSchedStateEnum SchedSleepStack();
+	inline TBool SchedPreemptable();
+	inline TMMCStackSchedStateEnum SchedSession();
+	inline TMMCStackSchedStateEnum SchedChooseJob();
+	//
+	// Miscellaneous SM function service
+protected:	
+	void MergeConfig(DMMCSession* aSessP);
+private:
+	inline void DeselectsToIssue(TUint aNumber);
+
+	// Static Completion routines.
+	static void StackDFC(TAny* aStackP);
+	static void StackSessionCBST(TAny* aStackP);
+	TInt StackSessionCB();
+	static void AutoUnlockCBST(TAny *aStackP);
+	TInt AutoUnlockCB();
+	
+protected:
+	IMPORT_C void Block(DMMCSession* aSessP, TUint32 aFlag);
+	IMPORT_C void UnBlock(DMMCSession* aSessP, TUint32 aFlag, TMMCErr anExitCode);
+
+protected:
+	// State machines.  The adapter functions just call the non-static versions.
+	// Top-level state machines.
+	static   TMMCErr NakedSessionSMST(TAny* aStackP);				// ECIMNakedSession
+	inline   TMMCErr NakedSessionSM();
+	static   TMMCErr CIMUpdateAcqSMST(TAny* aStackP);				// ECIMUpdateAcq
+	         TMMCErr CIMUpdateAcqSM();
+	static   TMMCErr CIMInitStackSMST(TAny* aStackP);				// ECIMInitStack
+	inline   TMMCErr CIMInitStackSM();
+	static   TMMCErr CIMCheckStackSMST(TAny* aStackP);			// ECIMCheckStack
+	inline   TMMCErr CIMCheckStackSM();
+	static   TMMCErr CIMSetupCardSMST(TAny* aStackP);				// ECIMSetupCard
+	inline   TMMCErr CIMSetupCardSM();
+	IMPORT_C static  TMMCErr CIMReadWriteBlocksSMST(TAny* aStackP);		// ECIMReadBlock, ECIMWriteBlock, ECIMReadMBlock, ECIMWriteMBlock
+	IMPORT_C virtual TMMCErr CIMReadWriteBlocksSM();
+	static   TMMCErr CIMEraseSMST(TAny* aStackP);					// ECIMEraseSector, ECIMEraseGroup
+	inline   TMMCErr CIMEraseSM();
+	static   TMMCErr CIMReadWriteIOSMST(TAny* aStackP);			// ECIMReadIO, ECIMWriteIO
+	inline   TMMCErr CIMReadWriteIOSM();
+	static   TMMCErr CIMLockUnlockSMST(TAny *aStackP);			// ECIMLockUnlock
+	inline   TMMCErr CIMLockUnlockSM();
+	static   TMMCErr NoSessionSMST(TAny* aStackP);				// ECIMLockStack
+	inline   TMMCErr NoSessionSM();
+	static   TMMCErr AcquireStackSMST(TAny* aStackP);
+	IMPORT_C virtual TMMCErr AcquireStackSM();
+	static   TMMCErr CheckStackSMST(TAny* aStackP);			// ECIMCheckStack
+	inline   TMMCErr CheckStackSM();
+	static   TMMCErr CheckLockStatusSMST(TAny* aStackP);
+	inline   TMMCErr CheckLockStatusSM();
+    static	 TMMCErr ModifyCardCapabilitySMST(TAny* aStackP);
+    IMPORT_C virtual TMMCErr ModifyCardCapabilitySM();
+    static	 TMMCErr BaseModifyCardCapabilitySMST(TAny* aStackP);
+	static   TMMCErr DoPowerUpSMST(TAny* aStackP);
+	static   TMMCErr InitClockOnSMST(TAny* aStackP);
+	IMPORT_C static  TMMCErr IssueMMCCommandSMST(TAny* aStackP);
+
+	static   TMMCErr CIMAutoUnlockSMST(TAny* aStackP);
+	inline   TMMCErr CIMAutoUnlockSM();
+
+	static   TMMCErr InitStackAfterUnlockSMST(TAny* aStackP);				// ECIMInitStackAfterUnlock
+	IMPORT_C virtual TMMCErr InitStackAfterUnlockSM();
+	
+	static	 TMMCErr InitCurrentCardAfterUnlockSMST(TAny* aStackP);
+
+	static   TMMCErr AttachCardSMST(TAny* aStackP);
+	inline   TMMCErr AttachCardSM();
+	static   TMMCErr ExecCommandSMST(TAny* aStackP);
+	inline   TMMCErr ExecCommandSM();
+	static   TMMCErr IssueCommandCheckResponseSMST(TAny* aStackP);
+	inline   TMMCErr IssueCommandCheckResponseSM();
+	static   TMMCErr PollGapTimerSMST(TAny* aStackP);
+	inline   TMMCErr PollGapTimerSM();
+	static   TMMCErr RetryGapTimerSMST(TAny* aStackP);
+	inline   TMMCErr RetryGapTimerSM();
+	static   TMMCErr ProgramTimerSMST(TAny *aStackP);
+	inline   TMMCErr ProgramTimerSM();
+	static   TMMCErr GoIdleSMST(TAny* aStackP);
+	inline	 TMMCErr GoIdleSM();
+
+	static   TMMCErr SwitchToLowVoltageSMST(TAny* aStackP);
+	
+	static   TMMCErr DoWakeUpSMST(TAny* aStackP);
+	
+
+private:
+	static   TMMCErr ConfigureHighSpeedSMST(TAny* aStackP);
+	inline	 TMMCErr ConfigureHighSpeedSM();
+
+	static   TMMCErr DetermineBusWidthAndClockSMST(TAny* aStackP);
+	inline	 TMMCErr DetermineBusWidthAndClockSM();
+
+	static   TMMCErr ExecSwitchCommandST(TAny* aStackP);
+	inline	 TMMCErr ExecSwitchCommand();
+	
+	static   TMMCErr ExecSleepCommandSMST(TAny* aStackP);
+	inline	 TMMCErr ExecSleepCommandSM();
+	
+	static   TMMCErr ExecAwakeCommandSMST(TAny* aStackP);
+	inline	 TMMCErr ExecAwakeCommandSM();
+
+	static   TMMCErr LowVoltagePowerupTimerSMST(TAny *aStackP);
+	TMMCErr LowVoltagePowerupTimerSM();
+
+	static   TMMCErr ExecBusTestSMST(TAny* aStackP);
+	inline	 TMMCErr ExecBusTestSM();
+
+	enum TBusWidthAndClock
+		{
+		E1Bit20Mhz  = 0x0000,
+
+		E4Bits26Mhz = 0x0001,
+		E4Bits52Mhz = 0x0002,
+
+		E8Bits26Mhz = 0x0004,
+		E8Bits52Mhz = 0x0008,
+		};
+	enum TBusWidthAndClockMasks
+		{
+		E4BitMask = E4Bits26Mhz | E4Bits52Mhz,
+		E8BitMask = E8Bits26Mhz | E8Bits52Mhz,
+		E26MhzMask = E4Bits26Mhz | E8Bits26Mhz,
+		E52MhzMask = E4Bits52Mhz | E8Bits52Mhz
+		};
+
+	void DetermineBusWidthAndClock(const TMMCard& aCard, TBool aLowVoltage, TUint& aPowerClass, TBusWidthAndClock& aBusWidthAndClock);
+	TUint GetPowerClass(const TMMCard& aCard, TBusWidthAndClock aWidthAndClock, TBool aLowVoltage);
+
+
+    //	----------- Data Members -------------
+private:
+	//
+	// Synchronous status, data structures and control info.
+	TUint32 iStackState;
+	TUint iInitContext;				// Stack Initialiser pass number
+	DMMCSession* iLockingSessionP;
+	TMMCSessRing iWorkSet;
+	TMMCSessRing iReadyQueue;
+	TMMCSessRing iEntryQueue;
+	TDfc iStackDFC;
+	TRCA iSelectedCard;
+	DMMCSocket* iSocket;
+	DMMCSession* iStackSession;
+	DMMCSession iAutoUnlockSession;
+	TInt iAutoUnlockIndex;			// index into iCards
+protected:
+	TUint8* iPSLBuf;
+private:
+	TInt iPSLBufLen;
+	TInt iMinorBufLen;
+	TUint8 iSpare[2];
+	TBool volatile iSleep;
+	DThread* iNotifierThread;
+	TRequestStatus* iNotifierReqStat;
+	enum TInitState {EISPending, EISDone};
+	TInitState iInitState;
+	//
+	//	Stack and Scheduler control
+	// Asynchronous sheduler attention flags
+	TBool volatile iAttention;	// There are ready sessions
+	TBool volatile iAbortReq;	// There are sessions marked for abort
+	TBool volatile iCompReq;	// There are sessions to complete
+	TBool volatile iInitialise;	// Enforce InitStack (after enforced PowerDown)
+	TBool volatile iUpdate;		// Enque InitStack into iWorkSet
+	// Other asynchronous flags
+	TBool volatile iPoweredUp;
+	TBool volatile iDFCRunning;
+	TBool volatile iAbortAll;
+	TMMCErr volatile iCompleteAllExitCode;
+	//
+	// Session context
+protected:
+	DMMCSession* iSessionP;
+private:
+	//
+	// Bus control
+	TDSR iCurrentDSR;
+	//
+	// Stack data structures and Session/StateMachine miscellaneous
+	TUint iDeselectsToIssue;
+	TInt iCxDeselectCount;
+	TUint8 iCMD42CmdByte;
+	TMediaPassword iMPTgt;
+public:
+	IMPORT_C TUint32 EffectiveModes(const TMMCStackConfig& aClientConfig);
+	TUint32 iCurrentOpRange;
+	TInt iCxCardCount;
+	TInt iCxPollRetryCount;
+	TMMCStackConfig iConfig;
+	TUint iMaxCardsInStack;
+	TMMCRCAPool iRCAPool;
+	TMMCardArray* iCardArray;
+	TMMCStackConfig iMasterConfig;
+	friend class DMMCSocket;
+	friend class DMMCSession;
+	friend class TMMCardArray;
+
+private:
+    //
+    // Dummy functions to maintain binary compatibility
+    IMPORT_C virtual void Dummy1();
+
+protected:
+	/** 
+	Gets an interface from a derived class
+	replaces reserved virtual Dummy4()
+	*/
+	IMPORT_C virtual void GetInterface(TInterfaceId aInterfaceId, MInterface*& aInterfacePtr);
+
+private:
+	TBusWidthAndClock iBusWidthAndClock;
+	TInt iSelectedCardIndex;
+    //
+    // Reserved members to maintain binary compatibility
+protected:
+	TBool   iMultiplexedBus;			// ETrue if cards are individually selectable.  EFalse if stacked on a common bus.
+private:
+	TMMCCommandTypeEnum iYieldCommandType;
+	TInt    iReserved;
+
+protected:	
+	// Pointer to protected utility class which allows class to grow while maintining BC
+	// replaces fourth element of iReserved[]
+	class DBody;
+	friend class DBody;
+	DBody* iBody;
+	};
+
+
+
+
+class TMMCMachineInfo
+/**
+	Platform-specific configuration information for the 
+	MultiMediaCard stack.
+	
+	An object of this type is passed to the Variant implementation
+	of DMMCStack::MachineInfo(), which should fill the public data
+	members with appropriate information and values.
+
+	@publishedPartner
+	@released
+*/
+	{
+
+public:
+	enum THardwareConfig
+		{
+		/**
+		Set this bit in iFlags if hardware supports SPI mode (not currently supported - set this bit to zero)
+		*/
+		ESupportsSPIMode		 = 0x01,
+
+		/**
+		Set this bit in iFlags if the PSL is enabled for double-buffered data transfers
+		*/
+		ESupportsDoubleBuffering = 0x02,
+
+		/**
+		Set this bit in iFlags if the PSL supports response type R7
+		*/
+		ESupportsR7				 = 0x04,
+
+		/**
+		Set this bit in iFlags if the hardware DMA controller utilises 8-Bit Addressing
+		*/
+		EDma8BitAddressing		 = 0x08,
+
+		/**
+		Set this bit in iFlags if the hardware DMA controller utilises 16-Bit Addressing
+		*/
+		EDma16BitAddressing		 = 0x10,
+
+		/**
+		Set this bit in iFlags if the hardware DMA controller utilises 32-Bit Addressing
+		*/
+		EDma32BitAddressing		 = 0x20,
+
+		/**
+		Set this bit in iFlags if the hardware DMA controller utilises 64-Bit Addressing
+		*/
+		EDma64BitAddressing		 = 0x40,
+		
+		/**
+		Set this in iFlags if the hardware supports DMA and can cope with being given a physical address.
+		This also sets the ESupportsDoubleBuffering flag, physical addressing is dependent on
+		doublebuffering functionality.
+		@see ESupportsDoubleBuffering
+		@see KMMCCmdFlagPhysAddr flag 
+		*/
+		ESupportsDMA			 = 0x082,
+
+		/**
+		Set this in iFlags if the hardware is unable to perform data transfers of more than 256K
+			- Transfers greater than 256K will be split into multiple transactions.
+		*/
+		EMaxTransferLength_256K	 = 0x100,
+
+		/**
+		Set this in iFlags if the hardware is unable to perform data transfers of more than 512K
+			- Transfers greater than 512K will be split into multiple transactions.
+		*/
+		EMaxTransferLength_512K	 = 0x200,
+
+		/**
+		Set this in iFlags if the hardware is unable to perform data transfers of more than 1M
+			- Transfers greater than 1M will be split into multiple transactions.
+		*/
+		EMaxTransferLength_1M	 = 0x300,
+
+		/**
+		Set this in iFlags if the hardware is unable to perform data transfers of more than 2M
+			- Transfers greater than 2M will be split into multiple transactions.
+		*/
+		EMaxTransferLength_2M	 = 0x400,
+
+		/**
+		Set this in iFlags if the hardware is unable to perform data transfers of more than 4M
+			- Transfers greater than 4M will be split into multiple transactions.
+		*/
+		EMaxTransferLength_4M	 = 0x500,
+
+		/**
+		Set this in iFlags if the hardware is unable to perform data transfers of more than 8M
+			- Transfers greater than 8M will be split into multiple transactions.
+		*/
+		EMaxTransferLength_8M	 = 0x600,
+
+		/**
+		Set this in iFlags if the hardware is unable to perform data transfers of more than 16M
+			- Transfers greater than 16M will be split into multiple transactions.
+		*/
+		EMaxTransferLength_16M	 = 0x700,
+
+		/**
+		The card in slot 1 is internal, i.e. not removable
+		*/
+		ESlot1Internal			 = 0x0800,
+
+		/**
+		The card in slot 2 is internal, i.e. not removable
+		*/
+		ESlot2Internal			 = 0x1000,
+		};
+
+public:
+    /**
+    The total number of MultiMediaCard slots for this stack.
+    
+    Be aware that this refers to the stack, and NOT to the platform;
+    a platform can have multiple stacks.
+    */
+	TInt iTotalSockets;
+	
+	/**
+	Not currently used.
+	
+	Set this value to zero.
+	*/
+	TInt iTotalMediaChanges;
+	
+	/**
+	Not currently used.
+	
+	Set this value to zero.
+	*/
+	TInt iTotalPrimarySupplies;
+	
+	union
+		{
+		/**
+		Indicates whether the SPI protocol is being used or not.
+		
+		SPI not currently supported; set this to EFalse.
+		*/
+		TBool iSPIMode;						// SPI mode not yet supported
+		/**
+		Hardware configuration flags
+		*/
+		TUint32 iFlags;
+		};
+
+    /**
+    The number of the first peripheral bus slot claimed by the
+    MultiMediaCard controller.
+    
+    Symbian OS supports 4, so set this to a value in the range 0-3.
+    */
+    TInt iBaseBusNumber;
+	};
+
+
+
+
+typedef TPckg<TMMCMachineInfo> TMMCardMachineInfoPckg;
+
+/**
+	Platform-specific configuration information for the 
+	MultiMediaCard stack. Contains information pertinent to 
+	MMC specification version 4.0/4.1
+	
+	An object of this type is passed to the Variant implementation
+	of DMMCStack::MachineInfo(), which should fill the public data
+	members with appropriate information and values.
+
+@internalComponent
+*/
+class TMMCMachineInfoV4 : public TMMCMachineInfo
+	{
+public:
+	inline TMMCMachineInfoV4() {memclr(this, sizeof(*this));}
+
+	/**
+	The version of the structure returned by the PSL in a call to DMMStack::MachineInfo()
+	The fields defined in TMMCMachineInfoV4 are only valid if the version is EVersion4 or higher
+	*/
+	enum TVersion {EVersion3, EVersion4};
+	TVersion iVersion;
+
+    /**
+    The maximum bus width supported.
+    */
+	TBusWidth iMaxBusWidth;
+
+	/** 
+	Maximum clock frequency supported,
+	N.B. if the controller's maximum clock rate is only slightly less than one of the 
+	"high-speed" clock frequencies defined in MMC spec 4.0 (i.e 26 Mhz and 52 Mhz), then 
+	it can still report that it is supported and then run at the slightly lower clock rate.
+	*/
+	enum THighSpeedClocks {EClockSpeed26Mhz = 26, EClockSpeed52Mhz = 52};
+	TUint iMaxClockSpeedInMhz;
+
+    /**
+    The power class supported for 3.6V (high voltage).
+	This is a 4-bit value encoded in the same way as the POWER_CLASS field in the EXT_CSD 
+	register. i.e. 0=100mA, 1=120mA, ... 10=450mA.
+	See MMC sepcification version 4.1, EXT_CSD register.
+    */
+	enum THiVoltagePowerClasses {EHi100mA, EHi120mA, EHi150mA, EHi180mA, EHi200mA, EHi220mA, EHi250mA, EHi300mA, EHi350mA, EHi400mA, EHi450mA };
+	TUint iHighVoltagePowerClass;
+
+    /**
+    The power class supported for 1.95V (low voltage).
+	This is a 4-bit value encoded in the same way as the POWER_CLASS field in the EXT_CSD 
+	register. i.e. 0=65mA, 1=70mA, ... 10=250mA.
+	See MMC sepcification version 4.1, EXT_CSD register.
+    */
+	enum TLoVoltagePowerClasses {ELo065mA, ELo070mA, ELo080mA, ELo090mA, ELo100mA, ELo120mA, ELo140mA, ELo160mA, ELo180mA, ELo200mA, ELo250mA };
+	TUint iLowVoltagePowerClass;
+	};
+
+
+class DMMCPsu : public DPBusPsuBase 
+/**
+	DPBusPsuBase derived abstract class to control the MMC socket's power supply.
+
+	This class is intended for derivation at the variant layer, which handles the
+	variant specific functionality of the power supply.
+
+	@publishedPartner
+	@released
+*/
+    {
+public:
+	IMPORT_C DMMCPsu(TInt aPsuNum, TInt aMediaChangedNum);
+
+	// Re-declaring virtual and pure-virtual interface defined in DPBusPsuBase for clarity...
+    
+	IMPORT_C virtual TInt DoCreate();
+
+	/**
+	 * Controls the power supply.
+	 * Implemented by the variant, directly controls the power to the MMC stack.
+	 * @param aState A TPBusPsuState enumeration specifying the required state
+	 *				 (EPsuOnFull, EPsuOff, EPsuOnCurLimit)
+	 */
+	virtual void DoSetState(TPBusPsuState aState)=0;
+
+	/**
+	 * Checks the PSU's voltage.
+	 * Implemented by the variant, uses a mechanism such as a comparator to check
+	 * the PSU's voltage level.  Upon reciept of the voltage level (the process may
+	 * be asynchronous), the variant calls ReceiveVoltageCheckResult() with KErrNone
+	 * if the voltage is OK, KErrGeneral if there is a problem, or KErrNotReady if the
+	 * hardware has not yet powered up.
+	 */
+	virtual void DoCheckVoltage()=0;
+
+	/**
+	 * Fills in the supplied TPBusPsuInfo object with the characteristics of the platform.
+	 * Provided at the variant layer.
+	 * @param anInfo A reference to a TPBusPsuInfo to be filled in with the PSU characteristics.
+	 */
+    virtual void PsuInfo(TPBusPsuInfo &anInfo)=0;
+
+	inline void SetVoltage(TUint32 aVoltage);
+	
+	static void SleepCheck(TAny* aPtr);
+
+protected:		  
+    /**
+	 * The current voltage setting, in OCR register format
+	 */
+	TUint32 iVoltageSetting; 
+    };
+
+class DMMCMediaChange : public DMediaChangeBase
+/**
+	DMediaChangeBase derived abstract class to handle the isertion and removal of removable media.
+
+	This class is intended for derivation at the variant layer, which handles the variant specific
+	functionality such as interrupt detection, and calls functions of the DMediaChangeBase class 
+	to pass notifications of media change to the socket layers.
+
+	@publishedPartner
+	@released
+*/
+	{
+public:
+	IMPORT_C DMMCMediaChange(TInt aMediaChangeNum);	
+	
+	// Re-declaring virtual and pure-virtual interface defined in DMediaChangeBase for clarity...
+	
+	IMPORT_C virtual TInt Create();
+
+	/**
+	 * Forces a media change, executing the same actions as if a door open has occurred.
+	 * @see DoDoorOpen
+	 */
+	virtual void ForceMediaChange()=0;
+
+	/**
+	 * Called by DMediaChangeBase when the door is opened.
+	 * Implemented at the variant layer, DoDoorOpen is invoked in response to the variant
+	 * calling ::DoDoorOpenService upon detection of a door open event. 
+	 * DoDoorOpen may queue a debounce timer which masks further events until it expires.
+	 * @see DoDoorClosed
+	 */
+	virtual void DoDoorOpen()=0;
+	
+	/**
+	 * Called by DMediaChangeBase when the door is closed.
+	 * Implemented at the variant layer, DoDoorClosed is invoked in response to the variant
+	 * calling ::DoorOpenService upon detection of a door closed event.
+	 * Systems without a door should perform this sequence when the debounce timer has 
+	 * expired after a door open event has been detected.
+	 * @see DoDoorOpen
+	 */
+	virtual void DoDoorClosed()=0;
+	
+	/**
+	 * Returns the current state of the door.
+	 * Implemented at the variant layer to provide information as to the state of the door.
+	 * @return TMediaState enumeration descibing the state of door (EDoorOpen, EDoorClosed).
+	 */	
+	virtual TMediaState MediaState() = 0;
+	};
+
+
+/*===========================================================================*/
+/* CLASS : DMMCEmbeddedMediaChange                                               */
+/*===========================================================================*/
+NONSHARABLE_CLASS(DMMCEmbeddedMediaChange) : public DMMCMediaChange
+/**
+ * This class looks after the processing to be carried out when the media door
+ * is opened or closed.  It may be queried without the interrupt being enabled.
+ *
+ */
+    {
+public:
+	DMMCEmbeddedMediaChange(TInt aMediaChangeNum) : DMMCMediaChange(aMediaChangeNum){};
+	
+    /// Directly calls the media change event
+    virtual void        ForceMediaChange() {return;};
+
+    /// Handle media door open (called on media door open interrupt).
+    virtual void        DoDoorOpen() {return;};
+
+    /// Handle media door closing (called on media door open interrupt).
+    virtual void        DoDoorClosed() {return;};
+
+    /// Return status of media changed signal.
+    virtual TMediaState MediaState() {return EDoorClosed;};
+    };
+
+
+
+class TMapping
+/**
+	MMC Mapping
+*/
+	{
+public:
+	TBuf8<KMMCCIDLength> iCID;
+	TMediaPassword iPWD;
+	enum TState {EStPending, EStValid, EStInvalid};
+	TState iState;
+	};
+
+NONSHARABLE_CLASS(TMMCPasswordStore) : public TPasswordStore
+/**
+	MMC Password Store
+*/
+	{
+public:
+	TMMCPasswordStore();
+
+	// Pure virtual...
+	TInt Init();
+	TInt ReadPasswordData(TDes8 &aBuf);
+	TInt WritePasswordData(TDesC8 &aBuf);
+	TInt PasswordStoreLengthInBytes();
+
+public:
+	TMapping *FindMappingInStore(const TCID &aCID);
+	TInt InsertMapping(const TCID &aCID, const TMediaPassword &aPWD, TMapping::TState aState);
+	IMPORT_C TBool IsMappingIncorrect(const TCID& aCID, const TMediaPassword& aPWD);
+
+	static TInt CompareCID(const TMapping& aLeft, const TMapping& aRight);
+	TIdentityRelation<TMapping> iIdentityRelation;
+
+private:
+	RArray<TMapping> *iStore;
+
+	friend class DMMCSocket;
+	};
+
+class DMMCSocket : public DPBusSocket
+/**
+	This DPBusSocket derived object oversees the power supplies
+	and media change functionality of DMMCStack Objects.  A socket 
+	directly corresponds to a single stack, which may support multiple cards.
+
+	@publishedPartner
+	@released
+*/
+	{
+public:
+	IMPORT_C DMMCSocket(TInt aSocketNumber, TMMCPasswordStore* aPasswordStore);
+	
+	// Functions inherited from DPBusSocket
+	virtual TInt Init();
+	virtual void InitiatePowerUpSequence();
+	virtual TBool CardIsPresent();
+	virtual void Reset1();
+	virtual void Reset2();
+	
+	TInt TotalSupportedCards();
+
+	// MMC specific functions
+	inline DMMCStack* Stack(TInt aBus);
+    inline void ResetInactivity(TInt aBus);
+	inline const TMMCMachineInfo& MachineInfo() const;
+	
+	virtual void AdjustPartialRead(const TMMCard* aCard, TUint32 aStart, TUint32 aEnd, TUint32* aPhysStart, TUint32* aPhysEnd) const;
+	virtual void GetBufferInfo(TUint8** aMDBuf, TInt* aMDBufLen);
+	virtual TInt PrepareStore(TInt aBus, TInt aFunc, TLocalDrivePasswordData &aData);
+
+	inline TBool SupportsDoubleBuffering();
+	inline TUint32 MaxDataTransferLength();
+	inline TUint32 DmaAlignment();
+
+protected:
+	// MMC specific functions
+	virtual void GetMachineInfo();
+
+private:
+	// Password Store Control Functions
+	TInt PasswordControlStart(const TCID &aCID, const TMediaPassword *aPWD);
+	void PasswordControlEnd(DMMCSession *aSessP, TInt aResult);
+	TBool RefreshStore();
+
+protected:
+    TMMCMachineInfo iMachineInfo;
+	TMMCPasswordStore* iPasswordStore;
+
+public:
+	DMMCStack* iStack;
+	DMMCPsu* iVccCore;
+
+private:
+	TUint32 iReserved[4];
+	
+public:	
+	enum TMMCPanic
+		{
+		EMMCMachineStack				=0,
+		EMMCMachineState				=1,
+		EMMCSessRingNoSession			=2,
+		EMMCStackSessionEngaged			=3,
+		EMMCInitStackBlocked			=4,
+		EMMCNoFreeRCA					=5,
+		EMMCCommandStack				=6,
+		EMMCRWSessionID					=7,
+		EMMCEraseSessionID				=8,
+		EMMCIOSessionID					=9,
+		EMMCSessionNoPswdCard			=10,
+		EMMCSessionPswdCmd				=11,
+		EMMCSessionBadSessionID			=12,
+		EMMCSetBusWidthNotImplemented	=13,
+		EMMCInvalidNumberOfCardSlots	=14,
+		EMMCBadBusWidth					=15,
+		EMMCInvalidDBCommand			=16,
+		EMMCInvalidDBBlockLength		=17,
+		EMMCUnblockingInWrongContext	=18,
+		EMMCInvalidCardNumber			=19,
+		EMMCNotInDfcContext				=20,
+		};
+    IMPORT_C static void Panic(TMMCPanic aPanic);
+	friend class DMMCStack;
+	friend class DMMCSession;
+	friend class DMMCMediaChange;
+	};
+
+const TUint32 KMMCEraseClassCmdsSupported=	KBit0;
+const TUint32 KMMCEraseGroupCmdsSupported=	KBit1;
+NONSHARABLE_CLASS(TMMCEraseInfo)
+	{
+public:
+	inline TBool EraseClassCmdsSupported() const;	
+	inline TBool EraseGroupCmdsSupported() const;	
+public:
+	TUint32 iEraseFlags;
+	TUint32 iPreferredEraseUnitSize;
+	TUint32 iMinEraseSectorSize;
+	};
+	
+#include <drivers/mmc.inl>
+
+#endif	// __MMC_H__
+