kernel/eka/drivers/medmmc/medmmc.cpp
changeset 287 ddfd5aa0d58f
parent 271 dc268b18d709
child 293 0659d0e1a03c
equal deleted inserted replaced
286:48e57fb1237e 287:ddfd5aa0d58f
     1 // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 1999-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    48 #define __ASSERT_CACHE(c,p) (void)((c)||(p,0))
    48 #define __ASSERT_CACHE(c,p) (void)((c)||(p,0))
    49 #else
    49 #else
    50 #define __ASSERT_CACHE(c,p)
    50 #define __ASSERT_CACHE(c,p)
    51 #endif
    51 #endif
    52 
    52 
       
    53 #include "medmmc.h"
    53 
    54 
    54 GLREF_C TInt GetMediaDefaultPartitionInfo(TMBRPartitionEntry& aPartitionEntry, TUint16& aReservedSectors, const TMMCard* aCardP);
    55 GLREF_C TInt GetMediaDefaultPartitionInfo(TMBRPartitionEntry& aPartitionEntry, TUint16& aReservedSectors, const TMMCard* aCardP);
    55 GLREF_C TBool MBRMandatory(const TMMCard* aCardP);
    56 GLREF_C TBool MBRMandatory(const TMMCard* aCardP);
    56 GLREF_C TBool CreateMBRAfterFormat(const TMMCard* aCardP);
    57 GLREF_C TBool CreateMBRAfterFormat(const TMMCard* aCardP);
    57 GLREF_C TInt BlockSize(const TMMCard* aCardP);
    58 GLREF_C TInt BlockSize(const TMMCard* aCardP);
    58 GLREF_C TInt EraseBlockSize(const TMMCard* aCardP);
    59 GLREF_C TInt EraseBlockSize(const TMMCard* aCardP);
    59 extern  TInt GetCardFormatInfo(const TMMCard* aCardP, TLocalDriveCapsV5& aCaps);
    60 extern  TInt GetCardFormatInfo(const TMMCard* aCardP, TLocalDriveCapsV5& aCaps);
    60 
    61 
    61 
    62 
       
    63 IMPORT_C extern const TUint KTRIMEnabled;
       
    64 
    62 const TInt KStackNumber = 0;
    65 const TInt KStackNumber = 0;
    63 
       
    64 const TInt KDiskSectorSize=512;
       
    65 const TInt KDiskSectorShift=9;
       
    66 
    66 
    67 const TInt KIdleCurrentInMilliAmps = 1;
    67 const TInt KIdleCurrentInMilliAmps = 1;
    68 
    68 
    69 const TInt KMBRFirstPartitionEntry=0x1BE;
    69 const TInt KMBRFirstPartitionEntry=0x1BE;
    70 
    70 
    88 
    88 
    89 // these should be static const members of DMmcMediaDriverFlash, but VC doesn't support this
    89 // these should be static const members of DMmcMediaDriverFlash, but VC doesn't support this
    90 const TInt64 KInvalidBlock = -1;
    90 const TInt64 KInvalidBlock = -1;
    91 const TInt KNoCacheBlock = -1;
    91 const TInt KNoCacheBlock = -1;
    92 
    92 
    93 class DMmcMediaDriverFlash : public DMediaDriver
       
    94 	{
       
    95 public:
       
    96 	DMmcMediaDriverFlash(TInt aMediaId);
       
    97 	~DMmcMediaDriverFlash();
       
    98 	// ...from DMediaDriver
       
    99 	virtual void Close();
       
   100 	// replacing pure virtual
       
   101 	virtual void Disconnect(DLocalDrive* aLocalDrive, TThreadMessage*);
       
   102 	virtual TInt Request(TLocDrvRequest& aRequest);
       
   103 	virtual TInt PartitionInfo(TPartitionInfo& anInfo);
       
   104 	virtual void NotifyPowerDown();
       
   105 	virtual void NotifyEmergencyPowerDown();
       
   106 	// For creation by DPhysicalDeviceMediaMmcFlash
       
   107 	TInt DoCreate(TInt aMediaId);
       
   108 
       
   109 private:
       
   110 	enum TPanic
       
   111 		{
       
   112 		EDRInUse		= 0x0000,	EDRStart, EDRNotPositive, EDREnd,
       
   113 		ELRRequest		= 0x0010,	ELRStart, ELRNotPositive, ELREnd, ELRCached,
       
   114 		EDWInUse		= 0x0020,	EDWStart, EDWNotPositive, EDWEnd,
       
   115 		EDFInUse		= 0x0030,	EDFStart, EDFNotPositive, EDFEnd, ENotMmcSocket,
       
   116 		ELWRequest		= 0x0040,	ELWStart, ELWFmtStAlign, ELWNotPositive, ELWEnd, ELWFmtEndAlign, 
       
   117 									ELWLength, ELFStart, ELFEnd, ELFNotPositive,
       
   118 		ERPIInUse		= 0x0050,
       
   119 		EPCInUse		= 0x0060,	EPCFunc,
       
   120 		ESECBQueued		= 0x0070,
       
   121 		EDSEDRequest	= 0x0080,	EDSEDNotErrComplete,
       
   122 		ECRReqIdle		= 0x0090,	ECRRequest,
       
   123 		ERRBStAlign		= 0x00a0,	ERRBStPos, ERRBNotPositive, ERRBEndAlign, ERRBEndPos,
       
   124 									ERRBOverflow, ERRBCchInv, ERRBExist,
       
   125 		ERWBStPos		= 0x00b0,	ERWBNotPositive, ERWBEndPos, ERWBOverflow, ERWBCchInv,
       
   126 		EMBStPos		= 0x00c0,	EMBStAlign, EMBNotPositive, EMBEndPos, EMBEndAlign,
       
   127 									EMBOverflow, EMBCchInvPre, EMBCchInvPost,
       
   128 		EBGAStPos		= 0x00d0,	EBGAStAlign, EBGANotPositive, EBGAEndPos, EBGAEndAlign,
       
   129 									EBGAOverflow, EBGACchInv,
       
   130 		EICMNegative	= 0x00e0,	EICMOverflow, ECMIOverflow,
       
   131 		EGCBAlign		= 0x00f0,	EGCBPos, EGCBCchInv,
       
   132 		
       
   133 		ECFSessPtrNull	= 0x0100,	// Code Fault - session pointer NULL
       
   134 
       
   135 		EDBNotEven		= 0x0110,	// Not and even number of blocks in the buffer cache
       
   136 		EDBCBQueued		= 0x0111,	// The data transfer callback is already queued
       
   137 		EDBLength		= 0x0112,	// The length of data to transfer in data transfer callback is not positive
       
   138 		EDBLengthTooBig	= 0x0113,	// The length of data to transfer in data transfer callback is too big
       
   139 		EDBOffsetTooBig = 0x0114,	// The Offset into the user data buffer is too big
       
   140 		EDBCacheInvalid	= 0x0115,	// The cache is invalid at the end of data transfer
       
   141 		EDBNotOptimal	= 0x0116,	// Due to Cache size DB functionality will never be utilised
       
   142 		ENoDBSupport	= 0x0120,	// DMA request arrived but PSL does not support double buffering
       
   143 		ENotDMAAligned  = 0x0121,
       
   144 		};
       
   145 	static void Panic(TPanic aPnc);
       
   146 
       
   147 	enum TMediaRequest
       
   148 		{
       
   149 		EMReqRead = 0,
       
   150 		EMReqWrite = 1,
       
   151 		EMReqFormat = 2,
       
   152 		EMReqPtnInfo,
       
   153 		EMReqPswdCtrl,
       
   154 		EMReqForceErase,
       
   155 		EMReqUpdatePtnInfo,
       
   156 		EMReqWritePasswordData,
       
   157 		EMReqIdle,
       
   158 		EMReqEMMCPtnInfo,
       
   159 		};
       
   160 	enum TMediaReqType {EMReqTypeNormalRd,EMReqTypeNormalWr,EMReqTypeUnlockPswd,EMReqTypeChangePswd};
       
   161 
       
   162 	enum {KWtRBMFst = 0x00000001, 	// iWtRBM - Read First Block only
       
   163 		  KWtRBMLst = 0x00000002,	// iWtRBM - Read Last Block only
       
   164 		  KWtMinFst = 0x00000004,	// iWtRBM - Write First Block only
       
   165 		  KWtMinLst = 0x00000008,	// iWtRBM - Write Last Block only
       
   166 		  KIPCSetup = 0x00000010,	// iRdROB - IPC Setup Next Iteration
       
   167 		  KIPCWrite = 0x00000020};	// iRdROB - IPC Write Next Iteration
       
   168 
       
   169 private:
       
   170 	// MMC device specific stuff
       
   171 	TInt DoRead();
       
   172 	TInt DoWrite();
       
   173 	TInt DoFormat();
       
   174 	TInt Caps(TLocDrv& aDrive, TLocalDriveCapsV6& aInfo);
       
   175 
       
   176 	inline DMMCStack& Stack() const;
       
   177 	inline TInt CardNum() const;
       
   178 	inline TMediaRequest CurrentRequest() const;
       
   179 
       
   180 	TInt LaunchRead(TInt64 aStart, TUint32 aLength);
       
   181 	TInt LaunchDBRead();
       
   182 	TInt LaunchPhysRead(TInt64 aStart, TUint32 aLength);
       
   183 	
       
   184 	TInt LaunchWrite(TInt64 aStart, TUint32 aLength, TMediaRequest aMedReq);
       
   185 	TInt LaunchFormat(TInt64 aStart, TUint32 aLength);
       
   186 
       
   187 	TInt LaunchRPIUnlock(TLocalDrivePasswordData& aData);
       
   188 	TInt LaunchRPIRead();
       
   189 	TInt LaunchRPIErase();
       
   190 	TInt DecodePartitionInfo();
       
   191 	TInt WritePartitionInfo();
       
   192 	TInt GetDefaultPartitionInfo(TMBRPartitionEntry& aPartitionEntry);
       
   193 	TInt CreateDefaultPartition();
       
   194 
       
   195 
       
   196 #if defined __TEST_PAGING_MEDIA_DRIVER__
       
   197 	TInt HandleControlIORequest();
       
   198 #endif
       
   199 
       
   200 	static void SetPartitionEntry(TPartitionEntry* aEntry, TUint aFirstSector, TUint aNumSectors);
       
   201 
       
   202 	TInt CheckDevice(TMediaReqType aReqType);
       
   203 
       
   204 	static void SessionEndCallBack(TAny* aMediaDriver);
       
   205 	static void SessionEndDfc(TAny* aMediaDriver);
       
   206 	void DoSessionEndDfc();
       
   207 
       
   208 	static void DataTransferCallBack(TAny* aMediaDriver);
       
   209 	static void DataTransferCallBackDfc(TAny* aMediaDriver);
       
   210 
       
   211 	void DoReadDataTransferCallBack();
       
   212 	void DoWriteDataTransferCallBack();
       
   213 	void DoPhysReadDataTransferCallBack();
       
   214 	void DoPhysWriteDataTransferCallBack();
       
   215 	
       
   216 	TInt AdjustPhysicalFragment(TPhysAddr &physAddr, TInt &physLength);
       
   217 	TInt PrepareFirstPhysicalFragment(TPhysAddr &aPhysAddr, TInt &aPhysLength, TUint32 aLength);
       
   218 	void PrepareNextPhysicalFragment();
       
   219 
       
   220 	TInt EngageAndSetReadRequest(TMediaRequest aRequest);
       
   221 	TInt EngageAndSetWriteRequest(TMediaRequest aRequest);
       
   222 	TInt EngageAndSetRequest(TMediaRequest aRequest, TInt aCurrent);
       
   223 	void CompleteRequest(TInt aReason);
       
   224 
       
   225 	TInt ReadDataUntilCacheExhausted(TBool* aAllDone);
       
   226 	TInt WriteDataToUser(TUint8* aBufPtr);
       
   227 	TInt ReadDataFromUser(TDes8& aDes, TInt aOffset);
       
   228 	TUint8* ReserveReadBlocks(TInt64 aStart, TInt64 aEnd, TUint32* aLength);
       
   229 	TUint8* ReserveWriteBlocks(TInt64 aMedStart, TInt64 aMedEnd, TUint* aRBM);
       
   230 	void MarkBlocks(TInt64 aStart, TInt64 aEnd, TInt aStartIndex);
       
   231 	void BuildGammaArray(TInt64 aStart, TInt64 aEnd);
       
   232 	void InvalidateCache();
       
   233 	void InvalidateCache(TInt64 aStart, TInt64 aEnd);
       
   234 	TUint8* IdxToCchMem(TInt aIdx) const;
       
   235 	TInt CchMemToIdx(TUint8* aMemP) const;
       
   236 
       
   237 	TInt DoPasswordOp();
       
   238 	void PasswordControl(TInt aFunc, TLocalDrivePasswordData& aData);
       
   239 	void Reset();
       
   240 	TInt AllocateSession();  
       
   241 
       
   242 #ifdef _DEBUG_CACHE
       
   243 	TBool CacheInvariant();
       
   244 	TUint8* GetCachedBlock(TInt64 aAddr);
       
   245 #endif
       
   246 private:
       
   247 	DMMCStack* iStack;			 				// controller objects
       
   248 	TMMCard* iCard;
       
   249 	DMMCSession* iSession;
       
   250 	DMMCSocket* iSocket;
       
   251 
       
   252 	TInt iCardNumber;
       
   253 
       
   254 	TUint iBlkLenLog2;							// cached CSD data
       
   255 	TUint32 iBlkLen;
       
   256 	TInt64 iBlkMsk;
       
   257 	TBool iReadBlPartial;
       
   258 	TUint32 iPrWtGpLen;							// preferred write group size in bytes,
       
   259 	TInt64 iPrWtGpMsk;
       
   260 
       
   261 	TInt iReadCurrentInMilliAmps;				// power management
       
   262 	TInt iWriteCurrentInMilliAmps;
       
   263 
       
   264 	TUint8* iMinorBuf;							// MBR, CMD42, partial read
       
   265 	TUint8* iCacheBuf;							// cached buffer
       
   266 	TUint32 iMaxBufSize;
       
   267 	TInt iBlocksInBuffer;
       
   268 	TInt64* iCachedBlocks;
       
   269 	TInt* iGamma;								// B lookup, ReserveReadBlocks()
       
   270 	TUint8* iIntBuf;							// start of current buffer region
       
   271 	TInt iLstUsdCchEnt;							// index of last used cache entry
       
   272 
       
   273 	TLocDrvRequest* iCurrentReq;				// Current Request
       
   274 	TMediaRequest iMedReq;
       
   275 	
       
   276 	TInt64 iReqStart;							// user-requested start region
       
   277 	TInt64 iReqCur;								// Currently requested start region
       
   278 	TInt64 iReqEnd;							    // user-requested end region
       
   279 	TInt64 iPhysStart;							// physical region for one operation
       
   280 	TInt64 iPhysEnd;						    // physical end point for one operation
       
   281 	TInt64 iDbEnd;								// Double buffer end point for one operation
       
   282 
       
   283 	TUint64 iEraseUnitMsk;
       
   284 
       
   285 	TUint iWtRBM;								// Write - Read Before Modify Flags
       
   286 	TUint iRdROB;								// Read  - Read Odd Blocks Flags
       
   287 	
       
   288 	TInt iFragOfset;			
       
   289 	TUint32 iIPCLen;
       
   290 	TUint32 iNxtIPCLen;
       
   291 	TUint32 iBufOfset;
       
   292 	
       
   293 	TUint iHiddenSectors;						// bootup / password
       
   294 
       
   295 	TMMCCallBack iSessionEndCallBack;
       
   296 	TDfc iSessionEndDfc;
       
   297 
       
   298 	TPartitionInfo* iPartitionInfo;
       
   299 	TMMCMediaTypeEnum iMediaType;
       
   300 	TMMCEraseInfo iEraseInfo;
       
   301 	TBool iMbrMissing;
       
   302 	TInt iMediaId;
       
   303 
       
   304 	DMMCStack::TDemandPagingInfo iDemandPagingInfo;
       
   305 
       
   306 #if defined(__TEST_PAGING_MEDIA_DRIVER__)
       
   307 	SMmcStats iMmcStats;
       
   308 #endif // __TEST_PAGING_MEDIA_DRIVER__
       
   309 
       
   310 	TMMCCallBack iDataTransferCallBack;	// Callback registered with the MMC stack to perform double-buffering
       
   311 	TDfc iDataTransferCallBackDfc;		// ...and the associated DFC queue.
       
   312 
       
   313 	TBool iSecondBuffer;				// Specified the currently active buffer
       
   314 	TBool iDoLastRMW;					// ETrue if the last double-buffer transfer requires RMW modification
       
   315 	TBool iDoDoubleBuffer;				// ETrue if double-buffering is currently active
       
   316 	TBool iDoPhysicalAddress;			// ETrue if Physical Addressing is currently active
       
   317 	TBool iCreateMbr;
       
   318 	TBool iReadToEndOfCard;				// {Read Only} ETrue if Reading to end of Card
       
   319 
       
   320 	TBool iInternalSlot;
       
   321 
       
   322 	DEMMCPartitionInfo* iMmcPartitionInfo;  // Responsible for decoding partitions for embedded devices
       
   323 	};
       
   324 	
    93 	
   325 // ======== DPhysicalDeviceMediaMmcFlash ========
    94 // ======== DPhysicalDeviceMediaMmcFlash ========
   326 
    95 
   327 
    96 
   328 DPhysicalDeviceMediaMmcFlash::DPhysicalDeviceMediaMmcFlash()
    97 DPhysicalDeviceMediaMmcFlash::DPhysicalDeviceMediaMmcFlash()
   469 	{
   238 	{
   470 	__KTRACE_OPT(KPBUSDRV, Kern::Printf("=mmd:mmd"));
   239 	__KTRACE_OPT(KPBUSDRV, Kern::Printf("=mmd:mmd"));
   471 	// NB aMedia Id = the media ID of the primary media, iMediaId = the media ID of this media
   240 	// NB aMedia Id = the media ID of the primary media, iMediaId = the media ID of this media
   472 	__KTRACE_OPT(KPBUSDRV, Kern::Printf("DMmcMediaDriverFlash(), iMediaId %d, aMediaId %d\n", iMediaId, aMediaId));
   241 	__KTRACE_OPT(KPBUSDRV, Kern::Printf("DMmcMediaDriverFlash(), iMediaId %d, aMediaId %d\n", iMediaId, aMediaId));
   473 	OstTraceExt2( TRACE_FLOW, DMMCMEDIADRIVERFLASH_DMMCMEDIADRIVERFLASH, "> DMmcMediaDriverFlash::DMmcMediaDriverFlash;aMediaId=%d;iMediaId=%d", (TInt) aMediaId, (TInt) iMediaId );
   242 	OstTraceExt2( TRACE_FLOW, DMMCMEDIADRIVERFLASH_DMMCMEDIADRIVERFLASH, "> DMmcMediaDriverFlash::DMmcMediaDriverFlash;aMediaId=%d;iMediaId=%d", (TInt) aMediaId, (TInt) iMediaId );
       
   243 	for(TInt drv = 0; drv < KMaxLocalDrives; drv++)
       
   244 		{
       
   245 		SetEMmcPartitionMapping(drv, TExtendedCSD::ESelectUserArea);
       
   246 		}
   474 	
   247 	
   475 	}
   248 	}
   476 
   249 
   477 #pragma warning( default : 4355 )
   250 #pragma warning( default : 4355 )
   478 TInt DMmcMediaDriverFlash::DoCreate(TInt /*aMediaId*/)
   251 TInt DMmcMediaDriverFlash::DoCreate(TInt /*aMediaId*/)
   538 	TInt minorBufLen;
   311 	TInt minorBufLen;
   539 	Stack().BufferInfo(buf, bufLen, minorBufLen);
   312 	Stack().BufferInfo(buf, bufLen, minorBufLen);
   540 
   313 
   541 	iMinorBuf = buf;
   314 	iMinorBuf = buf;
   542 	
   315 	
       
   316 	// reserve KRpmbOneFramePacketLength bytes after the minor buffer for RPMB requests / responses
   543 	// cache buffer can use rest of blocks in buffer.  Does not have to be power of 2.
   317 	// cache buffer can use rest of blocks in buffer.  Does not have to be power of 2.
   544 	iCacheBuf = iMinorBuf + minorBufLen;
   318 	iCacheBuf = iMinorBuf + minorBufLen + KRpmbOneFramePacketLength;
   545 
   319 
   546 	// We need to devide up the buffer space between the media drivers.
   320 	// We need to devide up the buffer space between the media drivers.
   547 	// The number of buffer sub-areas = number of physical card slots * number of media
   321 	// The number of buffer sub-areas = number of physical card slots * number of media
   548 	bufLen-= minorBufLen;
   322 	bufLen-= (minorBufLen + KRpmbOneFramePacketLength);
   549 	DPBusPrimaryMedia* primaryMedia = (DPBusPrimaryMedia*) iPrimaryMedia;
   323 	DPBusPrimaryMedia* primaryMedia = (DPBusPrimaryMedia*) iPrimaryMedia;
   550 	TInt physicalCardSlots = iStack->iMaxCardsInStack;
   324 	TInt physicalCardSlots = iStack->iMaxCardsInStack;
   551 	TInt numMedia = primaryMedia->iLastMediaId - primaryMedia->iMediaId + 1;
   325 	TInt numMedia = primaryMedia->iLastMediaId - primaryMedia->iMediaId + 1;
   552 	TInt totalNumMedia = numMedia * physicalCardSlots;
   326 	TInt totalNumMedia = numMedia * physicalCardSlots;
   553 
   327 
  1158 				{
   932 				{
  1159 				iPhysEnd&=(~minEraseSecMsk);
   933 				iPhysEnd&=(~minEraseSecMsk);
  1160 				}
   934 				}
  1161 
   935 
  1162 			// Now, if the erase start/end points are aligned to a min. erase unit boundary, we can use an erase cmd.
   936 			// Now, if the erase start/end points are aligned to a min. erase unit boundary, we can use an erase cmd.
  1163 			if ((iPhysStart & minEraseSecMsk) == 0 && (iPhysEnd & minEraseSecMsk) == 0)
   937 			if ((iPhysStart & minEraseSecMsk) == 0 && (iPhysEnd & minEraseSecMsk) == 0 ||
       
   938 			      (iCurrentReq->Id() == DLocalDrive::EDeleteNotify && (iPhysStart - iPhysEnd) % KMMCardHighCapBlockSize == 0 )) // handle TRIM case where erase is aligned to 512 blocks
  1164 				{
   939 				{
  1165 				// Aligned erase
   940 				// Aligned erase
  1166 				//  Check that erase commands are supported prior to issuing an erase command
   941 				//  Check that erase commands are supported prior to issuing an erase command
  1167 				if(iEraseInfo.EraseGroupCmdsSupported())
   942 				if(iEraseInfo.EraseGroupCmdsSupported())
  1168 					{
   943 					{
  1172 				else
   947 				else
  1173 					{
   948 					{
  1174 					iSession->SetupCIMEraseMSector(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2),
   949 					iSession->SetupCIMEraseMSector(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2),
  1175 												   I64LOW((iPhysEnd - iPhysStart) >> KMMCardHighCapBlockSizeLog2)); // Use ACMD32/33/38 (Erase Sector)
   950 												   I64LOW((iPhysEnd - iPhysStart) >> KMMCardHighCapBlockSizeLog2)); // Use ACMD32/33/38 (Erase Sector)
  1176 					}
   951 					}
       
   952 		        if(iCurrentReq->Id() == DLocalDrive::EDeleteNotify)   
       
   953 		            {
       
   954 		            iSession->Command().iFlags|= KMMCCmdFlagDeleteNotify;  //set flags for Trim
       
   955 		            }
  1177 				}
   956 				}
  1178 			else
   957 			else
  1179 				{
   958 				{
  1180 				// Misaligned erase - use multi-block write. However, first - check write length doesn't exceed buffer size.
   959 				// Misaligned erase - use multi-block write. However, first - check write length doesn't exceed buffer size.
  1181 				if ((iPhysEnd-iPhysStart)>(TUint32)iMaxBufSize)
   960 				if ((iPhysEnd-iPhysStart)>(TUint32)iMaxBufSize)
  1198 			__ASSERT_DEBUG((iPhysEnd - iPhysStart) > 0, Panic(ELWLength));
   977 			__ASSERT_DEBUG((iPhysEnd - iPhysStart) > 0, Panic(ELWLength));
  1199 			const TUint32 writeLen = I64LOW(iPhysEnd - iPhysStart);
   978 			const TUint32 writeLen = I64LOW(iPhysEnd - iPhysStart);
  1200 			memset (iCacheBuf, 0x00, writeLen);
   979 			memset (iCacheBuf, 0x00, writeLen);
  1201 			iSession->SetupCIMWriteBlock(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2), iCacheBuf, writeLen >> KMMCardHighCapBlockSizeLog2);
   980 			iSession->SetupCIMWriteBlock(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2), iCacheBuf, writeLen >> KMMCardHighCapBlockSizeLog2);
  1202 			}
   981 			}
  1203 		
   982 			
  1204 		r = EngageAndSetWriteRequest(EMReqFormat);
   983 		r = EngageAndSetWriteRequest(EMReqFormat);
  1205 		}
   984 		}
  1206 		OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_LAUNCHFORMAT_EXIT, this, r );
   985 		OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_LAUNCHFORMAT_EXIT, this, r );
  1207 		return r;
   986 		return r;
  1208 	}
   987 	}
  2305 					(iPhysEnd == iReqEnd) ||			// finshed already ?
  2084 					(iPhysEnd == iReqEnd) ||			// finshed already ?
  2306 					((iPhysStart & iEraseUnitMsk) == 0 && (iPhysEnd & iEraseUnitMsk) == 0))
  2085 					((iPhysStart & iEraseUnitMsk) == 0 && (iPhysEnd & iEraseUnitMsk) == 0))
  2307 					{
  2086 					{
  2308 					iReqCur = iPhysEnd;
  2087 					iReqCur = iPhysEnd;
  2309 					}
  2088 					}
       
  2089 				else if(iCurrentReq->Id() == DLocalDrive::EDeleteNotify) //handle DeleteNotify case
       
  2090 				    {
       
  2091                     iReqCur = iPhysEnd;
       
  2092 				    }
  2310 				else
  2093 				else
  2311 					{
  2094 					{
  2312 					// Formating to a mis-aligned boundary, so we can't make best use of
  2095 					// Formating to a mis-aligned boundary, so we can't make best use of
  2313 					// multiple erase blocks.  We shall simply erase up to the next block
  2096 					// multiple erase blocks.  We shall simply erase up to the next block
  2314 					// boundary, and return the adjustment info to the file system
  2097 					// boundary, and return the adjustment info to the file system
  2725 	__ASSERT_DEBUG(iSession != NULL, Panic(ECFSessPtrNull));
  2508 	__ASSERT_DEBUG(iSession != NULL, Panic(ECFSessPtrNull));
  2726 
  2509 
  2727 	iMedReq = aRequest;
  2510 	iMedReq = aRequest;
  2728 	SetCurrentConsumption(aCurrent);
  2511 	SetCurrentConsumption(aCurrent);
  2729 
  2512 
       
  2513 #ifdef EMMC_PARTITION_TEST_MODE_ENABLED
       
  2514 	if((iSession->Partition() & TExtendedCSD::EPartitionTestMode) != 0)
       
  2515 		{
       
  2516 		// driver in test mode, target partition must be set by ControlIO() KMmcSwitchPartition
       
  2517 		}
       
  2518 	else
       
  2519 #endif // EMMC_PARTITION_TEST_MODE_ENABLED	
       
  2520 		if (iCurrentReq)
       
  2521 			// if iCurrentReq is NULL then  it is assuned to be a request for a removable drive 
       
  2522 			// multiple physical partitions are not supported on removable drives hence partition settting is not requied
       
  2523 			{
       
  2524 			TInt ptn = iCurrentReq->Drive()->iPartitionNumber;
       
  2525 			TInt eMmcPtn = GetEMmcPartitionMapping(ptn);
       
  2526 			iSession->SetPartition(eMmcPtn);
       
  2527 			}
       
  2528 	
  2730 	// Reset the card pointer just in case the stack has changed it.
  2529 	// Reset the card pointer just in case the stack has changed it.
  2731 	iSession->SetCard(iCard);
  2530 	iSession->SetCard(iCard);
  2732 
  2531 		
  2733 	TInt r = InCritical();
  2532 	TInt r = InCritical();
  2734 	if (r == KErrNone)
  2533 	if (r == KErrNone)
  2735 		{
  2534 		{
  2736 		r = iSession->Engage();
  2535 		r = iSession->Engage();
  2737 		}
  2536 		}
  2781 	// Fill buffer with current media caps.
  2580 	// Fill buffer with current media caps.
  2782 	aInfo.iType = EMediaHardDisk;
  2581 	aInfo.iType = EMediaHardDisk;
  2783 	aInfo.iConnectionBusType = EConnectionBusInternal;
  2582 	aInfo.iConnectionBusType = EConnectionBusInternal;
  2784 	aInfo.iDriveAtt = KDriveAttLocal;
  2583 	aInfo.iDriveAtt = KDriveAttLocal;
  2785 	aInfo.iMediaAtt	= KMediaAttFormattable;
  2584 	aInfo.iMediaAtt	= KMediaAttFormattable;
       
  2585 	   
       
  2586 	if(iCard->ExtendedCSD().ExtendedCSDRev() >= 5 && KTRIMEnabled)   //TRIM support for v4.4+
       
  2587 	   aInfo.iMediaAtt |= KMediaAttDeleteNotify;
  2786 
  2588 
  2787 	if(iCard->iFlags & KMMCardIsLockable)
  2589 	if(iCard->iFlags & KMMCardIsLockable)
  2788 		aInfo.iMediaAtt |= KMediaAttLockable;
  2590 		aInfo.iMediaAtt |= KMediaAttLockable;
  2789 
  2591 
  2790 	if (iCard->HasPassword())
  2592 	if (iCard->HasPassword())
  2897 	
  2699 	
  2898 	if ( (iCurrentReq->DriverFlags() & RLocalDrive::ELocDrvDirectIO) || iCurrentReq->IsPhysicalAddress()
  2700 	if ( (iCurrentReq->DriverFlags() & RLocalDrive::ELocDrvDirectIO) || iCurrentReq->IsPhysicalAddress()
  2899 #if defined(__DEMAND_PAGING__) && !defined(__WINS__)
  2701 #if defined(__DEMAND_PAGING__) && !defined(__WINS__)
  2900 	     || DMediaPagingDevice::PageInRequest(*iCurrentReq)
  2702 	     || DMediaPagingDevice::PageInRequest(*iCurrentReq)
  2901 #endif //DEMAND_PAGING 
  2703 #endif //DEMAND_PAGING 
       
  2704 		// partition switching
       
  2705 		|| (GetEMmcPartitionMapping(iCurrentReq->Drive()->iPartitionNumber) != iSession->Partition())
  2902         )
  2706         )
  2903 		{
  2707 		{
  2904 		*aAllDone = EFalse;
  2708 		*aAllDone = EFalse;
  2905 		OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_READDATAUNTILCACHEEXHAUSTED_EXIT1, this, KErrNone );
  2709 		OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_READDATAUNTILCACHEEXHAUSTED_EXIT1, this, KErrNone );
  2906 		return KErrNone;
  2710 		return KErrNone;
  3743 					OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_REQUEST_EXIT3, this, KErrNotSupported );
  3547 					OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_REQUEST_EXIT3, this, KErrNotSupported );
  3744 					return KErrNotSupported;
  3548 					return KErrNotSupported;
  3745 				    }
  3549 				    }
  3746 				r=DoWrite();
  3550 				r=DoWrite();
  3747 				break;
  3551 				break;
       
  3552 			case DLocalDrive::EDeleteNotify:
       
  3553 			  if(iCard->ExtendedCSD().ExtendedCSDRev() <5)
       
  3554 			      {
       
  3555 			      r=KErrNotSupported;
       
  3556 			      break;
       
  3557 			      }
  3748 			case DLocalDrive::EFormat:
  3558 			case DLocalDrive::EFormat:
  3749 				if (readOnly)
  3559 				if (readOnly)
  3750 				    {
  3560 				    {
  3751 					OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_REQUEST_EXIT4, this, KErrNotSupported );
  3561 					OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_REQUEST_EXIT4, this, KErrNotSupported );
  3752 					return KErrNotSupported;
  3562 					return KErrNotSupported;
  3906 			iMmcStats.iNormalFragmenting=0;
  3716 			iMmcStats.iNormalFragmenting=0;
  3907 			iMmcStats.iClashFragmenting=0;
  3717 			iMmcStats.iClashFragmenting=0;
  3908 				
  3718 				
  3909 			break; 
  3719 			break; 
  3910 			}
  3720 			}
       
  3721 #ifdef EMMC_PARTITION_TEST_MODE_ENABLED			
       
  3722 		case KMmcSwitchPartition:
       
  3723 			__ASSERT_DEBUG(iSession != NULL, Panic(ECFSessPtrNull));
       
  3724 			InvalidateCache();
       
  3725 			iSession->SetPartition((TInt) aParam1);
       
  3726 			break;
       
  3727 #endif // EMMC_PARTITION_TEST_MODE_ENABLED
  3911 		default:
  3728 		default:
  3912 			r=KErrNotSupported;
  3729 			r=KErrNotSupported;
  3913 			break;
  3730 			break;
  3914 		}
  3731 		}
  3915 
  3732