kernel/eka/drivers/medmmc/medmmc.h
changeset 287 ddfd5aa0d58f
child 293 0659d0e1a03c
equal deleted inserted replaced
286:48e57fb1237e 287:ddfd5aa0d58f
       
     1 // Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // drivers/medmmc/medmmc.h
       
    15 //
       
    16 //
       
    17 
       
    18 #ifndef MEDMMC_H
       
    19 #define MEDMMC_H
       
    20 
       
    21 #include <drivers/locmedia.h>
       
    22 #include <e32const.h>
       
    23 
       
    24 #if defined(__DEMAND_PAGING__)
       
    25 	// If in debug mode, enable paging stats and their retrieval using DLocalDrive::EControlIO
       
    26 	#if defined( _DEBUG)
       
    27 		#define __TEST_PAGING_MEDIA_DRIVER__
       
    28 	#endif
       
    29 	#include "mmcdp.h"
       
    30 #endif
       
    31 
       
    32 // Enable this macro to debug cache: 
       
    33 // NB The greater the number of blocks, the slower this is...
       
    34 //#define _DEBUG_CACHE
       
    35 #ifdef _DEBUG_CACHE
       
    36 #define __ASSERT_CACHE(c,p) (void)((c)||(p,0))
       
    37 #else
       
    38 #define __ASSERT_CACHE(c,p)
       
    39 #endif
       
    40 
       
    41 const TInt KDiskSectorSize  = 512;
       
    42 const TInt KDiskSectorShift =   9;
       
    43 
       
    44 
       
    45 class DMmcMediaDriverFlash : public DMediaDriver
       
    46 	{
       
    47 public:
       
    48 	DMmcMediaDriverFlash(TInt aMediaId);
       
    49 	~DMmcMediaDriverFlash();
       
    50 	// ...from DMediaDriver
       
    51 	virtual void Close();
       
    52 	// replacing pure virtual
       
    53 	virtual void Disconnect(DLocalDrive* aLocalDrive, TThreadMessage*);
       
    54 	virtual TInt Request(TLocDrvRequest& aRequest);
       
    55 	virtual TInt PartitionInfo(TPartitionInfo& anInfo);
       
    56 	virtual void NotifyPowerDown();
       
    57 	virtual void NotifyEmergencyPowerDown();
       
    58 	// For creation by DPhysicalDeviceMediaMmcFlash
       
    59 	TInt DoCreate(TInt aMediaId);
       
    60 	
       
    61 		
       
    62 private:
       
    63 	enum TPanic
       
    64 		{
       
    65 		EDRInUse		= 0x0000,	EDRStart, EDRNotPositive, EDREnd,
       
    66 		ELRRequest		= 0x0010,	ELRStart, ELRNotPositive, ELREnd, ELRCached,
       
    67 		EDWInUse		= 0x0020,	EDWStart, EDWNotPositive, EDWEnd,
       
    68 		EDFInUse		= 0x0030,	EDFStart, EDFNotPositive, EDFEnd, ENotMmcSocket,
       
    69 		ELWRequest		= 0x0040,	ELWStart, ELWFmtStAlign, ELWNotPositive, ELWEnd, ELWFmtEndAlign, 
       
    70 									ELWLength, ELFStart, ELFEnd, ELFNotPositive,
       
    71 		ERPIInUse		= 0x0050,
       
    72 		EPCInUse		= 0x0060,	EPCFunc,
       
    73 		ESECBQueued		= 0x0070,
       
    74 		EDSEDRequest	= 0x0080,	EDSEDNotErrComplete,
       
    75 		ECRReqIdle		= 0x0090,	ECRRequest,
       
    76 		ERRBStAlign		= 0x00a0,	ERRBStPos, ERRBNotPositive, ERRBEndAlign, ERRBEndPos,
       
    77 									ERRBOverflow, ERRBCchInv, ERRBExist,
       
    78 		ERWBStPos		= 0x00b0,	ERWBNotPositive, ERWBEndPos, ERWBOverflow, ERWBCchInv,
       
    79 		EMBStPos		= 0x00c0,	EMBStAlign, EMBNotPositive, EMBEndPos, EMBEndAlign,
       
    80 									EMBOverflow, EMBCchInvPre, EMBCchInvPost,
       
    81 		EBGAStPos		= 0x00d0,	EBGAStAlign, EBGANotPositive, EBGAEndPos, EBGAEndAlign,
       
    82 									EBGAOverflow, EBGACchInv,
       
    83 		EICMNegative	= 0x00e0,	EICMOverflow, ECMIOverflow,
       
    84 		EGCBAlign		= 0x00f0,	EGCBPos, EGCBCchInv,
       
    85 		
       
    86 		ECFSessPtrNull	= 0x0100,	// Code Fault - session pointer NULL
       
    87 
       
    88 		EDBNotEven		= 0x0110,	// Not and even number of blocks in the buffer cache
       
    89 		EDBCBQueued		= 0x0111,	// The data transfer callback is already queued
       
    90 		EDBLength		= 0x0112,	// The length of data to transfer in data transfer callback is not positive
       
    91 		EDBLengthTooBig	= 0x0113,	// The length of data to transfer in data transfer callback is too big
       
    92 		EDBOffsetTooBig = 0x0114,	// The Offset into the user data buffer is too big
       
    93 		EDBCacheInvalid	= 0x0115,	// The cache is invalid at the end of data transfer
       
    94 		EDBNotOptimal	= 0x0116,	// Due to Cache size DB functionality will never be utilised
       
    95 		ENoDBSupport	= 0x0120,	// DMA request arrived but PSL does not support double buffering
       
    96 		ENotDMAAligned  = 0x0121,
       
    97 		EArrayBoundsExc = 0x0122	// Array bounds exceeded (either too small or too large)
       
    98 		};
       
    99 	static void Panic(TPanic aPnc);
       
   100 
       
   101 	enum TMediaRequest
       
   102 		{
       
   103 		EMReqRead = 0,
       
   104 		EMReqWrite = 1,
       
   105 		EMReqFormat = 2,
       
   106 		EMReqPtnInfo,
       
   107 		EMReqPswdCtrl,
       
   108 		EMReqForceErase,
       
   109 		EMReqUpdatePtnInfo,
       
   110 		EMReqWritePasswordData,
       
   111 		EMReqIdle,
       
   112 		EMReqEMMCPtnInfo,
       
   113 		};
       
   114 	enum TMediaReqType {EMReqTypeNormalRd,EMReqTypeNormalWr,EMReqTypeUnlockPswd,EMReqTypeChangePswd};
       
   115 
       
   116 	enum {KWtRBMFst = 0x00000001, 	// iWtRBM - Read First Block only
       
   117 		  KWtRBMLst = 0x00000002,	// iWtRBM - Read Last Block only
       
   118 		  KWtMinFst = 0x00000004,	// iWtRBM - Write First Block only
       
   119 		  KWtMinLst = 0x00000008,	// iWtRBM - Write Last Block only
       
   120 		  KIPCSetup = 0x00000010,	// iRdROB - IPC Setup Next Iteration
       
   121 		  KIPCWrite = 0x00000020};	// iRdROB - IPC Write Next Iteration
       
   122 
       
   123 public:
       
   124 	inline void SetEMmcPartitionMapping(TInt aLocalPtn, TInt aEMmcPtn) 
       
   125 		{
       
   126 		__ASSERT_DEBUG((aLocalPtn >= 0) && (aLocalPtn < KMaxLocalDrives), Kern::Fault("Mmc: Array bounds exception", __LINE__));
       
   127 		iEMmcPartitionMappings[aLocalPtn] = aEMmcPtn;
       
   128 		};
       
   129 	
       
   130 	inline TInt GetEMmcPartitionMapping(TInt aLocalPtn) const
       
   131 		{
       
   132 		__ASSERT_DEBUG((aLocalPtn >= 0) && (aLocalPtn < KMaxLocalDrives), Kern::Fault("Mmc: Array bounds exception", __LINE__));
       
   133 		return iEMmcPartitionMappings[aLocalPtn];
       
   134 		};
       
   135 
       
   136 
       
   137 private:
       
   138 	// MMC device specific stuff
       
   139 	TInt DoRead();
       
   140 	TInt DoWrite();
       
   141 	TInt DoFormat();
       
   142 	TInt Caps(TLocDrv& aDrive, TLocalDriveCapsV6& aInfo);
       
   143 
       
   144 	inline DMMCStack& Stack() const;
       
   145 	inline TInt CardNum() const;
       
   146 	inline TMediaRequest CurrentRequest() const;
       
   147 
       
   148 	TInt LaunchRead(TInt64 aStart, TUint32 aLength);
       
   149 	TInt LaunchDBRead();
       
   150 	TInt LaunchPhysRead(TInt64 aStart, TUint32 aLength);
       
   151 	
       
   152 	TInt LaunchWrite(TInt64 aStart, TUint32 aLength, TMediaRequest aMedReq);
       
   153 	TInt LaunchFormat(TInt64 aStart, TUint32 aLength);
       
   154 
       
   155 	TInt LaunchRPIUnlock(TLocalDrivePasswordData& aData);
       
   156 	TInt LaunchRPIRead();
       
   157 	TInt LaunchRPIErase();
       
   158 	TInt DecodePartitionInfo();
       
   159 	TInt WritePartitionInfo();
       
   160 	TInt GetDefaultPartitionInfo(TMBRPartitionEntry& aPartitionEntry);
       
   161 	TInt CreateDefaultPartition();
       
   162 
       
   163 
       
   164 #if defined __TEST_PAGING_MEDIA_DRIVER__
       
   165 	TInt HandleControlIORequest();
       
   166 #endif
       
   167 
       
   168 	static void SetPartitionEntry(TPartitionEntry* aEntry, TUint aFirstSector, TUint aNumSectors);
       
   169 
       
   170 	TInt CheckDevice(TMediaReqType aReqType);
       
   171 
       
   172 	static void SessionEndCallBack(TAny* aMediaDriver);
       
   173 	static void SessionEndDfc(TAny* aMediaDriver);
       
   174 	void DoSessionEndDfc();
       
   175 
       
   176 	static void DataTransferCallBack(TAny* aMediaDriver);
       
   177 	static void DataTransferCallBackDfc(TAny* aMediaDriver);
       
   178 
       
   179 	void DoReadDataTransferCallBack();
       
   180 	void DoWriteDataTransferCallBack();
       
   181 	void DoPhysReadDataTransferCallBack();
       
   182 	void DoPhysWriteDataTransferCallBack();
       
   183 	
       
   184 	TInt AdjustPhysicalFragment(TPhysAddr &physAddr, TInt &physLength);
       
   185 	TInt PrepareFirstPhysicalFragment(TPhysAddr &aPhysAddr, TInt &aPhysLength, TUint32 aLength);
       
   186 	void PrepareNextPhysicalFragment();
       
   187 
       
   188 	TInt EngageAndSetReadRequest(TMediaRequest aRequest);
       
   189 	TInt EngageAndSetWriteRequest(TMediaRequest aRequest);
       
   190 	TInt EngageAndSetRequest(TMediaRequest aRequest, TInt aCurrent);
       
   191 	void CompleteRequest(TInt aReason);
       
   192 
       
   193 	TInt ReadDataUntilCacheExhausted(TBool* aAllDone);
       
   194 	TInt WriteDataToUser(TUint8* aBufPtr);
       
   195 	TInt ReadDataFromUser(TDes8& aDes, TInt aOffset);
       
   196 	TUint8* ReserveReadBlocks(TInt64 aStart, TInt64 aEnd, TUint32* aLength);
       
   197 	TUint8* ReserveWriteBlocks(TInt64 aMedStart, TInt64 aMedEnd, TUint* aRBM);
       
   198 	void MarkBlocks(TInt64 aStart, TInt64 aEnd, TInt aStartIndex);
       
   199 	void BuildGammaArray(TInt64 aStart, TInt64 aEnd);
       
   200 	void InvalidateCache();
       
   201 	void InvalidateCache(TInt64 aStart, TInt64 aEnd);
       
   202 	TUint8* IdxToCchMem(TInt aIdx) const;
       
   203 	TInt CchMemToIdx(TUint8* aMemP) const;
       
   204 
       
   205 	TInt DoPasswordOp();
       
   206 	void PasswordControl(TInt aFunc, TLocalDrivePasswordData& aData);
       
   207 	void Reset();
       
   208 	TInt AllocateSession();  
       
   209 
       
   210 #ifdef _DEBUG_CACHE
       
   211 	TBool CacheInvariant();
       
   212 	TUint8* GetCachedBlock(TInt64 aAddr);
       
   213 #endif
       
   214 private:
       
   215 	DMMCStack* iStack;			 				// controller objects
       
   216 	TMMCard* iCard;
       
   217 	DMMCSession* iSession;
       
   218 	DMMCSocket* iSocket;
       
   219 
       
   220 	TInt iCardNumber;
       
   221 
       
   222 	TUint iBlkLenLog2;							// cached CSD data
       
   223 	TUint32 iBlkLen;
       
   224 	TInt64 iBlkMsk;
       
   225 	TBool iReadBlPartial;
       
   226 	TUint32 iPrWtGpLen;							// preferred write group size in bytes,
       
   227 	TInt64 iPrWtGpMsk;
       
   228 
       
   229 	TInt iReadCurrentInMilliAmps;				// power management
       
   230 	TInt iWriteCurrentInMilliAmps;
       
   231 
       
   232 	TUint8* iMinorBuf;							// MBR, CMD42, partial read
       
   233 	TUint8* iCacheBuf;							// cached buffer
       
   234 	TUint32 iMaxBufSize;
       
   235 	TInt iBlocksInBuffer;
       
   236 	TInt64* iCachedBlocks;
       
   237 	TInt* iGamma;								// B lookup, ReserveReadBlocks()
       
   238 	TUint8* iIntBuf;							// start of current buffer region
       
   239 	TInt iLstUsdCchEnt;							// index of last used cache entry
       
   240 
       
   241 	TLocDrvRequest* iCurrentReq;				// Current Request
       
   242 	TMediaRequest iMedReq;
       
   243 	
       
   244 	TInt64 iReqStart;							// user-requested start region
       
   245 	TInt64 iReqCur;								// Currently requested start region
       
   246 	TInt64 iReqEnd;							    // user-requested end region
       
   247 	TInt64 iPhysStart;							// physical region for one operation
       
   248 	TInt64 iPhysEnd;						    // physical end point for one operation
       
   249 	TInt64 iDbEnd;								// Double buffer end point for one operation
       
   250 
       
   251 	TUint64 iEraseUnitMsk;
       
   252 
       
   253 	TUint iWtRBM;								// Write - Read Before Modify Flags
       
   254 	TUint iRdROB;								// Read  - Read Odd Blocks Flags
       
   255 	
       
   256 	TInt iFragOfset;			
       
   257 	TUint32 iIPCLen;
       
   258 	TUint32 iNxtIPCLen;
       
   259 	TUint32 iBufOfset;
       
   260 	
       
   261 	TUint iHiddenSectors;						// bootup / password
       
   262 
       
   263 	TMMCCallBack iSessionEndCallBack;
       
   264 	TDfc iSessionEndDfc;
       
   265 
       
   266 	TPartitionInfo* iPartitionInfo;
       
   267 	TMMCMediaTypeEnum iMediaType;
       
   268 	TMMCEraseInfo iEraseInfo;
       
   269 	TBool iMbrMissing;
       
   270 	TInt iMediaId;
       
   271 
       
   272 	DMMCStack::TDemandPagingInfo iDemandPagingInfo;
       
   273 
       
   274 #if defined(__TEST_PAGING_MEDIA_DRIVER__)
       
   275 	SMmcStats iMmcStats;
       
   276 #endif // __TEST_PAGING_MEDIA_DRIVER__
       
   277 
       
   278 	TMMCCallBack iDataTransferCallBack;	// Callback registered with the MMC stack to perform double-buffering
       
   279 	TDfc iDataTransferCallBackDfc;		// ...and the associated DFC queue.
       
   280 
       
   281 	TBool iSecondBuffer;				// Specified the currently active buffer
       
   282 	TBool iDoLastRMW;					// ETrue if the last double-buffer transfer requires RMW modification
       
   283 	TBool iDoDoubleBuffer;				// ETrue if double-buffering is currently active
       
   284 	TBool iDoPhysicalAddress;			// ETrue if Physical Addressing is currently active
       
   285 	TBool iCreateMbr;
       
   286 	TBool iReadToEndOfCard;				// {Read Only} ETrue if Reading to end of Card
       
   287 
       
   288 	TBool iInternalSlot;
       
   289 
       
   290 	DEMMCPartitionInfo* iMmcPartitionInfo;  // Responsible for decoding partitions for embedded devices
       
   291 	TInt iEMmcPartitionMappings[KMaxLocalDrives]; // holds the mapping of emmc partitions
       
   292 	};
       
   293 	
       
   294 #endif
       
   295