changeset 287 | ddfd5aa0d58f |
parent 271 | dc268b18d709 |
child 293 | 0659d0e1a03c |
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 |