author | hgs |
Wed, 22 Sep 2010 10:53:45 +0100 | |
changeset 271 | dc268b18d709 |
parent 244 | a77889bee936 |
child 287 | ddfd5aa0d58f |
permissions | -rw-r--r-- |
0 | 1 |
// Copyright (c) 1999-2009 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 |
// Media driver for MultiMediaCard Flash device |
|
15 |
// |
|
16 |
// |
|
17 |
||
18 |
#include "mmc.h" |
|
19 |
#include "pbusmedia.h" |
|
20 |
#include <drivers/emmcptn.h> |
|
21 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
22 |
#include "OstTraceDefinitions.h" |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
23 |
#ifdef OST_TRACE_COMPILER_IN_USE |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
24 |
#include "locmedia_ost.h" |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
25 |
#ifdef __VC32__ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
26 |
#pragma warning(disable: 4127) // disabling warning "conditional expression is constant" |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
27 |
#endif |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
28 |
#include "medmmcTraces.h" |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
29 |
#endif |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
30 |
|
0 | 31 |
#if defined(__DEMAND_PAGING__) |
32 |
// If in debug mode, enable paging stats and their retrieval using DLocalDrive::EControlIO |
|
33 |
#if defined( _DEBUG) |
|
34 |
#define __TEST_PAGING_MEDIA_DRIVER__ |
|
35 |
#endif |
|
36 |
#include "mmcdp.h" |
|
37 |
#endif |
|
38 |
||
39 |
#ifndef BTRACE_PAGING_MEDIA |
|
40 |
#undef BTraceContext8 |
|
41 |
#define BTraceContext8(aCategory,aSubCategory,a1,a2) |
|
42 |
#endif // BTRACE_PAGING_MEDIA |
|
43 |
||
44 |
// Enable this macro to debug cache: |
|
45 |
// NB The greater the number of blocks, the slower this is... |
|
46 |
//#define _DEBUG_CACHE |
|
47 |
#ifdef _DEBUG_CACHE |
|
48 |
#define __ASSERT_CACHE(c,p) (void)((c)||(p,0)) |
|
49 |
#else |
|
50 |
#define __ASSERT_CACHE(c,p) |
|
51 |
#endif |
|
52 |
||
53 |
||
54 |
GLREF_C TInt GetMediaDefaultPartitionInfo(TMBRPartitionEntry& aPartitionEntry, TUint16& aReservedSectors, const TMMCard* aCardP); |
|
55 |
GLREF_C TBool MBRMandatory(const TMMCard* aCardP); |
|
56 |
GLREF_C TBool CreateMBRAfterFormat(const TMMCard* aCardP); |
|
57 |
GLREF_C TInt BlockSize(const TMMCard* aCardP); |
|
58 |
GLREF_C TInt EraseBlockSize(const TMMCard* aCardP); |
|
271 | 59 |
extern TInt GetCardFormatInfo(const TMMCard* aCardP, TLocalDriveCapsV5& aCaps); |
60 |
||
0 | 61 |
|
62 |
const TInt KStackNumber = 0; |
|
63 |
||
64 |
const TInt KDiskSectorSize=512; |
|
65 |
const TInt KDiskSectorShift=9; |
|
66 |
||
67 |
const TInt KIdleCurrentInMilliAmps = 1; |
|
68 |
||
69 |
const TInt KMBRFirstPartitionEntry=0x1BE; |
|
70 |
||
71 |
template <class T> |
|
72 |
inline T UMin(T aLeft,T aRight) |
|
73 |
{return(aLeft<aRight ? aLeft : aRight);} |
|
74 |
||
75 |
||
76 |
class DPhysicalDeviceMediaMmcFlash : public DPhysicalDevice |
|
77 |
{ |
|
78 |
public: |
|
79 |
DPhysicalDeviceMediaMmcFlash(); |
|
80 |
||
81 |
virtual TInt Install(); |
|
82 |
virtual void GetCaps(TDes8& aDes) const; |
|
83 |
virtual TInt Create(DBase*& aChannel, TInt aMediaId, const TDesC8* aInfo, const TVersion& aVer); |
|
84 |
virtual TInt Validate(TInt aDeviceType, const TDesC8* aInfo, const TVersion& aVer); |
|
85 |
virtual TInt Info(TInt aFunction, TAny* a1); |
|
86 |
}; |
|
87 |
||
88 |
||
89 |
// these should be static const members of DMmcMediaDriverFlash, but VC doesn't support this |
|
90 |
const TInt64 KInvalidBlock = -1; |
|
91 |
const TInt KNoCacheBlock = -1; |
|
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 |
||
325 |
// ======== DPhysicalDeviceMediaMmcFlash ======== |
|
326 |
||
327 |
||
328 |
DPhysicalDeviceMediaMmcFlash::DPhysicalDeviceMediaMmcFlash() |
|
329 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
330 |
OstTraceFunctionEntry1( DPHYSICALDEVICEMEDIAMMCFLASH_DPHYSICALDEVICEMEDIAMMCFLASH_ENTRY, this ); |
0 | 331 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("=mmd:ctr")); |
332 |
||
333 |
iUnitsMask = 0x01; |
|
334 |
iVersion = TVersion(KMediaDriverInterfaceMajorVersion,KMediaDriverInterfaceMinorVersion,KMediaDriverInterfaceBuildVersion); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
335 |
OstTraceFunctionExit1( DPHYSICALDEVICEMEDIAMMCFLASH_DPHYSICALDEVICEMEDIAMMCFLASH_EXIT, this ); |
0 | 336 |
} |
337 |
||
338 |
||
339 |
TInt DPhysicalDeviceMediaMmcFlash::Install() |
|
340 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
341 |
OstTraceFunctionEntry1( DPHYSICALDEVICEMEDIAMMCFLASH_INSTALL_ENTRY, this ); |
0 | 342 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("=mmd:ins")); |
343 |
||
344 |
_LIT(KDrvNm, "Media.MmcF"); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
345 |
TInt r = SetName(&KDrvNm); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
346 |
OstTraceFunctionExitExt( DPHYSICALDEVICEMEDIAMMCFLASH_INSTALL_EXIT, this, r ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
347 |
return r; |
0 | 348 |
} |
349 |
||
350 |
||
351 |
void DPhysicalDeviceMediaMmcFlash::GetCaps(TDes8& /* aDes */) const |
|
352 |
{ |
|
353 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("=mmd:cap")); |
|
354 |
} |
|
355 |
||
356 |
||
357 |
TInt DPhysicalDeviceMediaMmcFlash::Info(TInt aFunction, TAny* /*a1*/) |
|
358 |
// |
|
359 |
// Return the priority of this media driver |
|
360 |
// |
|
361 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
362 |
OstTraceExt2(TRACE_FLOW, DPHYSICALDEVICEMEDIAMMCFLASH_INFO_ENTRY ,"DPhysicalDeviceMediaMmcFlash::Info;aFunction=%d;this=%x", aFunction, (TUint) this); |
0 | 363 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("=mmd:info")); |
364 |
if (aFunction==EPriority) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
365 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
366 |
OstTraceFunctionExitExt( DPHYSICALDEVICEMEDIAMMCFLASH_INFO_EXIT1, this, KMediaDriverPriorityNormal ); |
0 | 367 |
return KMediaDriverPriorityNormal; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
368 |
} |
0 | 369 |
// Don't close media driver when peripheral bus powers down. This avoids the need for Caps() to power up the stack. |
370 |
if (aFunction==EMediaDriverPersistent) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
371 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
372 |
OstTraceFunctionExitExt( DPHYSICALDEVICEMEDIAMMCFLASH_INFO_EXIT2, this, KErrNone ); |
0 | 373 |
return KErrNone; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
374 |
} |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
375 |
|
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
376 |
OstTraceFunctionExitExt( DPHYSICALDEVICEMEDIAMMCFLASH_INFO_EXIT3, this, KErrNotSupported ); |
0 | 377 |
return KErrNotSupported; |
378 |
} |
|
379 |
||
380 |
TInt DPhysicalDeviceMediaMmcFlash::Validate(TInt aDeviceType, const TDesC8* /*aInfo*/, const TVersion& aVer) |
|
381 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
382 |
OstTraceExt2(TRACE_FLOW, DPHYSICALDEVICEMEDIAMMCFLASH_VALIDATE_ENTRY ,"DPhysicalDeviceMediaMmcFlash::Validate;aDeviceType=%d;this=%x", aDeviceType, (TUint) this); |
0 | 383 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("=mmd:validate aDeviceType %d", aDeviceType)); |
384 |
if (!Kern::QueryVersionSupported(iVersion,aVer)) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
385 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
386 |
OstTraceFunctionExitExt( DPHYSICALDEVICEMEDIAMMCFLASH_VALIDATE_EXIT1, this, KErrNotSupported ); |
0 | 387 |
return KErrNotSupported; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
388 |
} |
0 | 389 |
if (aDeviceType!=MEDIA_DEVICE_MMC) |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
390 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
391 |
OstTraceFunctionExitExt( DPHYSICALDEVICEMEDIAMMCFLASH_VALIDATE_EXIT2, this, KErrNotSupported ); |
0 | 392 |
return KErrNotSupported; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
393 |
} |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
394 |
|
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
395 |
OstTraceFunctionExitExt( DPHYSICALDEVICEMEDIAMMCFLASH_VALIDATE_EXIT3, this, KErrNone ); |
0 | 396 |
return KErrNone; |
397 |
} |
|
398 |
||
399 |
TInt DPhysicalDeviceMediaMmcFlash::Create(DBase*& aChannel, TInt aMediaId, const TDesC8* /*aInfo*/, const TVersion& aVer) |
|
400 |
// |
|
401 |
// Create an MMC Card media driver. |
|
402 |
// |
|
403 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
404 |
OstTraceExt2(TRACE_FLOW, DPHYSICALDEVICEMEDIAMMCFLASH_CREATE_ENTRY, "DPhysicalDeviceMediaMmcFlash::Create;aMediaId=%d;this=%x", aMediaId, (TUint) this); |
0 | 405 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:crt")); |
406 |
||
407 |
if (!Kern::QueryVersionSupported(iVersion,aVer)) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
408 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
409 |
OstTraceFunctionExitExt( DPHYSICALDEVICEMEDIAMMCFLASH_CREATE_EXIT1, this, KErrNotSupported ); |
0 | 410 |
return KErrNotSupported; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
411 |
} |
0 | 412 |
|
413 |
DMmcMediaDriverFlash* pD = new DMmcMediaDriverFlash(aMediaId); |
|
414 |
aChannel=pD; |
|
415 |
||
416 |
TInt r=KErrNoMemory; |
|
417 |
if (pD) |
|
418 |
r=pD->DoCreate(aMediaId); |
|
419 |
if (r==KErrNone) |
|
420 |
pD->OpenMediaDriverComplete(KErrNone); |
|
421 |
||
422 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:mdf")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
423 |
|
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
424 |
OstTraceFunctionExitExt( DPHYSICALDEVICEMEDIAMMCFLASH_CREATE_EXIT2, this, r ); |
0 | 425 |
return r; |
426 |
} |
|
427 |
||
428 |
||
429 |
// ======== DMmcMediaDriverFlash ======== |
|
430 |
||
431 |
||
432 |
void DMmcMediaDriverFlash::Panic(TPanic aPanic) |
|
433 |
{ |
|
434 |
_LIT(KPncNm, "MEDMMC"); |
|
435 |
Kern::PanicCurrentThread(KPncNm, aPanic); |
|
436 |
} |
|
437 |
||
438 |
||
439 |
// ---- accessor functions ----- |
|
440 |
||
441 |
inline DMMCStack& DMmcMediaDriverFlash::Stack() const |
|
442 |
{ return *static_cast<DMMCStack*>(iStack); } |
|
443 |
||
444 |
||
445 |
inline TInt DMmcMediaDriverFlash::CardNum() const |
|
446 |
{ return iCardNumber; } |
|
447 |
||
448 |
||
449 |
inline DMmcMediaDriverFlash::TMediaRequest DMmcMediaDriverFlash::CurrentRequest() const |
|
450 |
{ return iMedReq; } |
|
451 |
||
452 |
||
453 |
// Helper |
|
454 |
template <class T> |
|
455 |
inline T* KernAlloc(const TUint32 n) |
|
456 |
{ return static_cast<T*>(Kern::Alloc(n * sizeof(T))); } |
|
457 |
||
458 |
// ---- ctor, open, close, dtor ---- |
|
459 |
||
460 |
#pragma warning( disable : 4355 ) // this used in initializer list |
|
461 |
DMmcMediaDriverFlash::DMmcMediaDriverFlash(TInt aMediaId) |
|
462 |
:DMediaDriver(aMediaId), |
|
463 |
iMedReq(EMReqIdle), |
|
464 |
iSessionEndCallBack(DMmcMediaDriverFlash::SessionEndCallBack, this), |
|
465 |
iSessionEndDfc(DMmcMediaDriverFlash::SessionEndDfc, this, 1), |
|
466 |
iMediaId(iPrimaryMedia->iNextMediaId), |
|
467 |
iDataTransferCallBack(DMmcMediaDriverFlash::DataTransferCallBack, this), |
|
468 |
iDataTransferCallBackDfc(DMmcMediaDriverFlash::DataTransferCallBackDfc, this, 1) |
|
469 |
{ |
|
470 |
__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 |
|
472 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("DMmcMediaDriverFlash(), iMediaId %d, aMediaId %d\n", iMediaId, aMediaId)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
473 |
OstTraceExt2( TRACE_FLOW, DMMCMEDIADRIVERFLASH_DMMCMEDIADRIVERFLASH, "> DMmcMediaDriverFlash::DMmcMediaDriverFlash;aMediaId=%d;iMediaId=%d", (TInt) aMediaId, (TInt) iMediaId ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
474 |
|
0 | 475 |
} |
476 |
||
477 |
#pragma warning( default : 4355 ) |
|
478 |
TInt DMmcMediaDriverFlash::DoCreate(TInt /*aMediaId*/) |
|
479 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
480 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_DOCREATE_ENTRY, this ); |
0 | 481 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:opn")); |
482 |
||
483 |
iSocket = ((DMMCSocket*)((DPBusPrimaryMedia*)iPrimaryMedia)->iSocket); |
|
484 |
if(iSocket == NULL) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
485 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
486 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOCREATE_EXIT1, this, KErrNoMemory ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
487 |
return KErrNoMemory; |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
488 |
} |
0 | 489 |
|
490 |
iCardNumber = ((DPBusPrimaryMedia*)iPrimaryMedia)->iSlotNumber; |
|
491 |
||
492 |
iStack = iSocket->Stack(KStackNumber); |
|
493 |
iCard = iStack->CardP(CardNum()); |
|
494 |
||
495 |
TMMCMachineInfo machineInfo; |
|
496 |
Stack().MachineInfo(machineInfo); |
|
497 |
TInt slotFlag = iCardNumber == 0 ? TMMCMachineInfo::ESlot1Internal : TMMCMachineInfo::ESlot2Internal; |
|
498 |
iInternalSlot = machineInfo.iFlags & slotFlag; |
|
499 |
||
500 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("DMmcMediaDriverFlash::DoCreate() slotNumber %d iInternalSlot %d", iCardNumber, iInternalSlot)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
501 |
OstTraceExt2(TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DOCREATE_SLOT, "slotNumber=%d; iInternalSlot=%d", iCardNumber, iInternalSlot); |
0 | 502 |
|
503 |
iSessionEndDfc.SetDfcQ(&iSocket->iDfcQ); |
|
504 |
iDataTransferCallBackDfc.SetDfcQ(&iSocket->iDfcQ); |
|
505 |
||
506 |
// check right type of card |
|
507 |
if ((iMediaType=iCard->MediaType())==EMultiMediaNotSupported) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
508 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
509 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOCREATE_EXIT2, this, KErrNotReady ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
510 |
return KErrNotReady; |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
511 |
} |
0 | 512 |
|
513 |
// get card characteristics |
|
514 |
const TCSD& csd = iCard->CSD(); |
|
515 |
iBlkLenLog2 = iCard->MaxReadBlLen(); |
|
516 |
iBlkLen = 1 << iBlkLenLog2; |
|
517 |
iBlkMsk = (TInt64)(iBlkLen - 1); |
|
518 |
||
519 |
SetTotalSizeInBytes(iCard->DeviceSize64()); |
|
520 |
||
521 |
// |
|
522 |
// High capcity cards (block addressable, MMCV4.2, SD2.0) do not support partial reads |
|
523 |
// ...some cards incorrectly report that they do, so ensure that we don't |
|
524 |
// |
|
525 |
iReadBlPartial = iCard->IsHighCapacity() ? EFalse : csd.ReadBlPartial(); |
|
526 |
||
527 |
// allocate and initialize session object |
|
528 |
TInt r = AllocateSession(); |
|
529 |
if (r!= KErrNone) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
530 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
531 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOCREATE_EXIT3, this, r ); |
0 | 532 |
return r; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
533 |
} |
0 | 534 |
|
535 |
// get buffer memory from EPBUS |
|
536 |
TUint8* buf; |
|
537 |
TInt bufLen; |
|
538 |
TInt minorBufLen; |
|
539 |
Stack().BufferInfo(buf, bufLen, minorBufLen); |
|
540 |
||
541 |
iMinorBuf = buf; |
|
542 |
||
543 |
// cache buffer can use rest of blocks in buffer. Does not have to be power of 2. |
|
544 |
iCacheBuf = iMinorBuf + minorBufLen; |
|
545 |
||
546 |
// 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 |
|
548 |
bufLen-= minorBufLen; |
|
549 |
DPBusPrimaryMedia* primaryMedia = (DPBusPrimaryMedia*) iPrimaryMedia; |
|
550 |
TInt physicalCardSlots = iStack->iMaxCardsInStack; |
|
551 |
TInt numMedia = primaryMedia->iLastMediaId - primaryMedia->iMediaId + 1; |
|
552 |
TInt totalNumMedia = numMedia * physicalCardSlots; |
|
553 |
||
554 |
TInt mediaIndex = iMediaId - primaryMedia->iMediaId; |
|
555 |
TInt bufIndex = (iCardNumber * numMedia) + mediaIndex; |
|
556 |
||
557 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("physicalCardSlots %d, iCardNumber %d\n", physicalCardSlots, iCardNumber)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
558 |
OstTraceExt2(TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DOCREATE_VARS1, "physicalCardSlots=%d; iCardNumber=%d", physicalCardSlots, iCardNumber); |
0 | 559 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("iMediaId %d numMedia %d, mediaIndex %d, totalNumMedia %d, bufIndex %d\n", |
560 |
iMediaId, numMedia, mediaIndex, totalNumMedia, bufIndex)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
561 |
OstTraceExt5(TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DOCREATE_VARS2, "iMediaId=%d; numMedia=%d; mediaIndex=%d; totalNumMedia=%d; bufIndex=%d", iMediaId, numMedia, mediaIndex, totalNumMedia, bufIndex); |
0 | 562 |
|
563 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("bufLen1 %08X iCacheBuf1 %08X", bufLen, iCacheBuf)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
564 |
OstTraceExt2(TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DOCREATE_CACHEBUF1, "bufLen1=0x%08x; iCacheBuf1=0x%08x", (TUint) bufLen, (TUint) iCacheBuf); |
0 | 565 |
bufLen/= totalNumMedia; |
566 |
iCacheBuf+= bufIndex * bufLen; |
|
567 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("bufLen2 %08X iCacheBuf2 %08X", bufLen, iCacheBuf)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
568 |
OstTraceExt2(TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DOCREATE_CACHEBUF2, "bufLen2=0x%08x; iCacheBuf2=0x%08x", (TUint) bufLen, (TUint) iCacheBuf); |
0 | 569 |
|
570 |
iBlocksInBuffer = bufLen >> iBlkLenLog2; // may lose partial block |
|
571 |
if(iSocket->SupportsDoubleBuffering()) |
|
572 |
{ |
|
573 |
// Ensure that there's always an even number of buffered blocks when double-buffering |
|
574 |
iBlocksInBuffer &= ~1; |
|
575 |
__ASSERT_DEBUG(iBlocksInBuffer >= 2, Panic(EDBNotEven)); |
|
576 |
#if defined(_DEBUG) |
|
577 |
/** |
|
578 |
* If Double-Buffering is enabled then the cache should not be greater than the maximum addressable range of the DMA controller, |
|
579 |
* otherwise Double buffering will never be utilised because all transfers will fit into the cache. |
|
580 |
*/ |
|
581 |
const TUint32 maxDbBlocks = iSocket->MaxDataTransferLength() >> iBlkLenLog2; |
|
33
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
582 |
if (maxDbBlocks) |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
583 |
{ |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
584 |
__ASSERT_DEBUG(iBlocksInBuffer <= (TInt)maxDbBlocks, Panic(EDBNotOptimal)); |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
585 |
} |
0 | 586 |
#endif |
587 |
} |
|
588 |
||
589 |
iMaxBufSize = iBlocksInBuffer << iBlkLenLog2; |
|
590 |
||
591 |
iPrWtGpLen = iCard->PreferredWriteGroupLength(); |
|
592 |
||
593 |
// check the preferred write group length is a power of two |
|
594 |
if(iPrWtGpLen == 0 || (iPrWtGpLen & (~iPrWtGpLen + 1)) != iPrWtGpLen) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
595 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
596 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOCREATE_EXIT4, this, KErrNotReady ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
597 |
return KErrNotReady; |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
598 |
} |
0 | 599 |
|
600 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("iMaxBufSize %d iPrWtGpLen %d\n", iMaxBufSize, iPrWtGpLen)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
601 |
OstTraceExt2(TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DOCREATE_IPRWTGPLEN1, "iMaxBufSize=%d; iPrWtGpLen1=%d", iMaxBufSize, iPrWtGpLen); |
0 | 602 |
// ensure the preferred write group length is as large as possible |
603 |
// so we can write to more than one write group at once |
|
604 |
while (iPrWtGpLen < (TUint32) iMaxBufSize) |
|
605 |
iPrWtGpLen <<= 1; |
|
606 |
||
607 |
// ensure preferred write group length is no greater than internal cache buffer |
|
608 |
while (iPrWtGpLen > (TUint32) iMaxBufSize) |
|
609 |
iPrWtGpLen >>= 1; |
|
610 |
iPrWtGpMsk = TInt64(iPrWtGpLen - 1); |
|
611 |
||
612 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("iPrWtGpLen #2 %d\n", iPrWtGpLen)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
613 |
OstTrace1(TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DOCREATE_IPRWTGPLEN2, "iPrWtGpLen2=%d", iPrWtGpLen); |
0 | 614 |
|
615 |
// allocate index for cached blocks |
|
616 |
iCachedBlocks = KernAlloc<TInt64>(iBlocksInBuffer); |
|
617 |
if (iCachedBlocks == 0) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
618 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
619 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOCREATE_EXIT5, this, KErrNoMemory ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
620 |
return KErrNoMemory; |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
621 |
} |
0 | 622 |
|
623 |
InvalidateCache(); |
|
624 |
iLstUsdCchEnt = iBlocksInBuffer - 1; // use entry 0 first |
|
625 |
||
626 |
// allocate read lookup index |
|
627 |
iGamma = KernAlloc<TInt>(iBlocksInBuffer); |
|
628 |
if (iGamma == 0) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
629 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
630 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOCREATE_EXIT6, this, KErrNoMemory ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
631 |
return KErrNoMemory; |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
632 |
} |
0 | 633 |
|
634 |
// get current requirements |
|
635 |
iReadCurrentInMilliAmps = csd.MaxReadCurrentInMilliamps(); |
|
636 |
iWriteCurrentInMilliAmps = csd.MaxWriteCurrentInMilliamps(); |
|
637 |
||
638 |
// get preferred erase information for format operations |
|
639 |
const TInt err = iCard->GetEraseInfo(iEraseInfo); |
|
640 |
if(err != KErrNone) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
641 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
642 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOCREATE_EXIT7, this, err ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
643 |
return err; |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
644 |
} |
0 | 645 |
|
646 |
iEraseUnitMsk = TInt64(iEraseInfo.iPreferredEraseUnitSize) - 1; |
|
647 |
||
648 |
// Retrieve the demand paging info from the PSL of the stack |
|
649 |
Stack().DemandPagingInfo(iDemandPagingInfo); |
|
650 |
||
651 |
// if a password has been supplied then it is sent when the partition info is read |
|
652 |
||
653 |
// |
|
654 |
// If this is an internal slot, then use the eMMC partition function |
|
655 |
// |
|
656 |
if(iInternalSlot) |
|
657 |
{ |
|
658 |
iMmcPartitionInfo = CreateEmmcPartitionInfo(); |
|
659 |
if(iMmcPartitionInfo == NULL) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
660 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
661 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOCREATE_EXIT8, this, KErrNoMemory ); |
0 | 662 |
return KErrNoMemory; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
663 |
} |
0 | 664 |
TInt err = iMmcPartitionInfo->Initialise(this); |
665 |
if(err != KErrNone) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
666 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
667 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOCREATE_EXIT9, this, err ); |
0 | 668 |
return err; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
669 |
} |
0 | 670 |
} |
671 |
||
672 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:opn")); |
|
673 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
674 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOCREATE_EXIT10, this, KErrNone ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
675 |
return KErrNone; |
0 | 676 |
} |
677 |
||
678 |
void DMmcMediaDriverFlash::Close() |
|
679 |
// |
|
680 |
// Close the media driver - also called on media change |
|
681 |
// |
|
682 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
683 |
OstTraceFunctionEntry0( DMMCMEDIADRIVERFLASH_CLOSE_ENTRY ); |
0 | 684 |
__KTRACE_OPT(KPBUSDRV,Kern::Printf("=mmd:cls")); |
685 |
||
686 |
EndInCritical(); |
|
687 |
iSessionEndDfc.Cancel(); |
|
688 |
iDataTransferCallBackDfc.Cancel(); |
|
689 |
CompleteRequest(KErrNotReady); |
|
690 |
DMediaDriver::Close(); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
691 |
OstTraceFunctionExit0( DMMCMEDIADRIVERFLASH_CLOSE_EXIT ); |
0 | 692 |
} |
693 |
||
694 |
||
695 |
DMmcMediaDriverFlash::~DMmcMediaDriverFlash() |
|
696 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
697 |
OstTraceFunctionEntry0( DMMCMEDIADRIVERFLASH_DMMCMEDIADRIVERFLASH_ENTRY ); |
0 | 698 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:dtr")); |
699 |
||
700 |
iSessionEndDfc.Cancel(); |
|
701 |
iDataTransferCallBackDfc.Cancel(); |
|
702 |
||
703 |
delete iSession; |
|
704 |
Kern::Free(iCachedBlocks); |
|
705 |
Kern::Free(iGamma); |
|
706 |
||
707 |
delete iMmcPartitionInfo; |
|
708 |
||
709 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:dtr")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
710 |
OstTraceFunctionExit0( DMMCMEDIADRIVERFLASH_DMMCMEDIADRIVERFLASH_EXIT ); |
0 | 711 |
} |
712 |
||
713 |
||
714 |
TInt DMmcMediaDriverFlash::AllocateSession() |
|
715 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
716 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_ALLOCATESESSION_ENTRY, this ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
717 |
|
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
718 |
|
0 | 719 |
// already allocated ? |
720 |
if (iSession != NULL) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
721 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
722 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_ALLOCATESESSION_EXIT1, this, KErrNone ); |
0 | 723 |
return KErrNone; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
724 |
} |
0 | 725 |
|
726 |
iSession = iStack->AllocSession(iSessionEndCallBack); |
|
727 |
if (iSession == NULL) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
728 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
729 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_ALLOCATESESSION_EXIT2, this, KErrNoMemory ); |
0 | 730 |
return KErrNoMemory; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
731 |
} |
0 | 732 |
|
733 |
iSession->SetStack(iStack); |
|
734 |
iSession->SetCard(iCard); |
|
735 |
iSession->SetDataTransferCallback(iDataTransferCallBack); |
|
736 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
737 |
|
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
738 |
|
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
739 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_ALLOCATESESSION_EXIT3, this, KErrNone ); |
0 | 740 |
return KErrNone; |
741 |
} |
|
742 |
||
743 |
// ---- media access ---- |
|
744 |
||
745 |
TInt DMmcMediaDriverFlash::DoRead() |
|
746 |
// |
|
747 |
// set up iReqStart, iReqEnd and iReqCur and launch first read. Subsequent reads |
|
748 |
// will be launched from the callback DFC. |
|
749 |
// |
|
750 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
751 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_DOREAD_ENTRY, this ); |
0 | 752 |
TInt r = CheckDevice(EMReqTypeNormalRd); |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
753 |
if (r != KErrNone) |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
754 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
755 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOREAD_EXIT1, this, r ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
756 |
return r; |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
757 |
} |
0 | 758 |
|
759 |
const TInt64 pos(iCurrentReq->Pos()); |
|
760 |
TUint32 length(I64LOW(iCurrentReq->Length())); |
|
761 |
||
762 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:dr:0x%lx,0x%x", pos, length)); |
|
148 | 763 |
OstTraceExt3( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DO_READ, "Position=%x:%x; Length=0x%x", (TUint) I64HIGH(pos), (TUint) I64LOW(pos), (TUint) length); |
0 | 764 |
__ASSERT_DEBUG(CurrentRequest() == EMReqIdle, Panic(EDRInUse)); |
765 |
__ASSERT_DEBUG(pos < TotalSizeInBytes(), Panic(EDRStart)); |
|
766 |
__ASSERT_DEBUG(iCurrentReq->Length() >= 0, Panic(EDRNotPositive)); |
|
767 |
__ASSERT_DEBUG(TotalSizeInBytes() >= pos + length, Panic(EDREnd)); |
|
768 |
||
769 |
if(length > 0) |
|
770 |
{ |
|
771 |
iReqCur = iReqStart = pos; |
|
772 |
iReqEnd = iReqStart + length; |
|
773 |
||
774 |
TBool allDone(EFalse); |
|
775 |
if ( ((r = ReadDataUntilCacheExhausted(&allDone)) == KErrNone) && !allDone) |
|
776 |
{ |
|
777 |
iMedReq = EMReqRead; |
|
778 |
iPhysStart = iReqCur & ~iBlkMsk; |
|
779 |
__ASSERT_DEBUG(I64HIGH(iPhysStart >> KMMCardHighCapBlockSizeLog2) == 0, Panic(ELRStart)); |
|
780 |
||
781 |
iReadToEndOfCard = ( iReqEnd >= TotalSizeInBytes() ); |
|
782 |
// Re-calculate length as some data may have been recovered from cache |
|
783 |
length = I64LOW(iReqEnd - iReqCur); |
|
784 |
||
785 |
if (iCurrentReq->IsPhysicalAddress() && !iReadToEndOfCard && (length >= iBlkLen) ) |
|
786 |
r = LaunchPhysRead(iReqCur, length); |
|
787 |
else if ( (iReqEnd - iPhysStart) > iMaxBufSize && iSocket->SupportsDoubleBuffering() && !iReadToEndOfCard) |
|
788 |
r = LaunchDBRead(); |
|
789 |
else |
|
790 |
r = LaunchRead(iReqCur, length); |
|
791 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
792 |
if (r == KErrNone) |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
793 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
794 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOREAD_EXIT2, this, r ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
795 |
return r; |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
796 |
} |
0 | 797 |
} |
798 |
} |
|
799 |
else |
|
800 |
{ |
|
123 | 801 |
TPtrC8 zeroDes(NULL, 0); |
802 |
r = iCurrentReq->WriteRemote(&zeroDes,0); |
|
0 | 803 |
} |
804 |
||
805 |
// error occurred or read all from cache so complete immediately |
|
806 |
if(r == KErrNone) |
|
807 |
r = KErrCompletion; |
|
808 |
||
809 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:dr:%d", r)); |
|
810 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
811 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOREAD_EXIT3, this, r ); |
0 | 812 |
return r; |
813 |
} |
|
814 |
||
815 |
||
816 |
TInt DMmcMediaDriverFlash::LaunchRead(TInt64 aStart, TUint32 aLength) |
|
817 |
// |
|
818 |
// starts reads from DoRead() and the session end DFC. This function does not maintain the |
|
819 |
// iReq* instance variables. It sets iPhysStart and iPhysEnd to the region that was actually |
|
820 |
// read into iIntBuf. iIntBuf can be set to a cached entry or to the minor buffer. It is |
|
821 |
// assumed that before this function is called that ReadDataUntilCacheExhausted() has been used. |
|
822 |
// |
|
823 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
824 |
OstTraceFunctionEntryExt( DMMCMEDIADRIVERFLASH_LAUNCHREAD_ENTRY, this ); |
148 | 825 |
OstTraceExt3( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_LAUNCHREAD, "position=%x:%x; length=0x%x", (TUint) I64HIGH(iCurrentReq->Pos()), (TUint) I64LOW(iCurrentReq->Pos()) ,(TUint) I64LOW(iCurrentReq->Length())); |
0 | 826 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:lr:0x%lx,0x%x", aStart, aLength)); |
827 |
__ASSERT_DEBUG(TotalSizeInBytes() > aStart, Panic(ELRStart)); |
|
828 |
__ASSERT_DEBUG(aLength > 0, Panic(ELRNotPositive)); |
|
829 |
__ASSERT_DEBUG(TotalSizeInBytes() >= aStart + aLength, Panic(ELREnd)); |
|
830 |
__ASSERT_CACHE(GetCachedBlock(aStart & ~iBlkMsk) == 0, Panic(ELRCached)); |
|
831 |
__ASSERT_DEBUG(iSession != NULL, Panic(ECFSessPtrNull)); |
|
832 |
||
833 |
iDoPhysicalAddress = EFalse; |
|
834 |
iDoDoubleBuffer = EFalse; |
|
835 |
iSecondBuffer = EFalse; |
|
836 |
||
837 |
// |
|
838 |
// if this read goes up to the end of the card then use only |
|
839 |
// single sector reads to avoid CMD12 timing problems |
|
840 |
// |
|
841 |
const TUint32 bufSize(iReadToEndOfCard ? iBlkLen : iMaxBufSize); |
|
842 |
||
843 |
iPhysEnd = (UMin(iReqEnd, iPhysStart + bufSize) + iBlkMsk) & ~iBlkMsk; |
|
844 |
||
845 |
TUint32 physLen(I64LOW(iPhysEnd - iPhysStart)); |
|
846 |
||
847 |
__ASSERT_DEBUG(I64HIGH(iPhysEnd - iPhysStart) == 0, Panic(ELREnd)); |
|
848 |
||
849 |
// partial reads must be within a single physical block |
|
850 |
if (iReadBlPartial && physLen == iBlkLen && aLength <= (iBlkLen >> 1)) |
|
851 |
{ |
|
852 |
// |
|
853 |
// Note : Partial reads are not supported for large block devices |
|
854 |
// (MMCV4.2 and SD2.0 high capacity cards) |
|
855 |
// |
|
856 |
__ASSERT_DEBUG(I64HIGH(aStart) == 0, Panic(ELRStart)); |
|
857 |
__ASSERT_DEBUG(I64HIGH(aStart + aLength) == 0, Panic(ELREnd)); |
|
858 |
||
859 |
iIntBuf = iMinorBuf; |
|
860 |
Stack().AdjustPartialRead(iCard, I64LOW(aStart), I64LOW(aStart + aLength), (TUint32*)&iPhysStart, (TUint32*)&iPhysEnd); |
|
861 |
iSession->SetupCIMReadBlock(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2), iIntBuf, physLen >> KMMCardHighCapBlockSizeLog2); |
|
862 |
} |
|
863 |
else |
|
864 |
{ |
|
865 |
iIntBuf = ReserveReadBlocks(iPhysStart, iPhysEnd, &physLen); |
|
866 |
||
867 |
// EPBUSM automatically uses CMD17 instead of CMD18 for single block reads |
|
868 |
iSession->SetupCIMReadBlock(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2), iIntBuf, physLen >> KMMCardHighCapBlockSizeLog2); |
|
869 |
||
870 |
// Update Physical end point as less may have been required due to additional blocks found in cache during ReserveReadBlocks |
|
871 |
iPhysEnd = iPhysStart + physLen; |
|
872 |
} |
|
873 |
||
874 |
TInt r = EngageAndSetReadRequest(EMReqRead); |
|
875 |
||
876 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:lr:%d", r)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
877 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_LAUNCHREAD_EXIT, this, r ); |
0 | 878 |
return r; |
879 |
} |
|
880 |
||
881 |
TInt DMmcMediaDriverFlash::LaunchDBRead() |
|
882 |
// |
|
883 |
// starts reads from DoRead() and the session end DFC. This function does not maintain the |
|
884 |
// iReq* instance variables. It sets iPhysStart and iPhysEnd to the region that was actually |
|
885 |
// read into iIntBuf. iIntBuf can be set to a cached entry or to the minor buffer. It is |
|
886 |
// assumed that before this function is called that ReadDataUntilCacheExhausted() has been used. |
|
887 |
// |
|
888 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
889 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_LAUNCHDBREAD_ENTRY, this ); |
0 | 890 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:ldbr:0x%lx,0x%x", iReqCur, I64LOW(iReqEnd - iReqCur))); |
148 | 891 |
OstTraceExt3( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_LAUNCHDBREAD, "position=%x:%x; length=0x%x", (TInt) I64HIGH(iReqCur), (TInt) I64LOW(iReqCur), (TInt) I64LOW(iReqEnd - iReqCur)); |
0 | 892 |
__ASSERT_DEBUG(TotalSizeInBytes() > iReqCur, Panic(ELRStart)); |
893 |
__ASSERT_DEBUG(I64LOW(iReqEnd - iReqCur) > 0, Panic(ELRNotPositive)); |
|
894 |
__ASSERT_DEBUG(TotalSizeInBytes() >= iReqEnd, Panic(ELREnd)); |
|
895 |
__ASSERT_CACHE(GetCachedBlock(iReqCur & ~iBlkMsk) == 0, Panic(ELRCached)); |
|
896 |
__ASSERT_DEBUG(iSession != NULL, Panic(ECFSessPtrNull)); |
|
897 |
||
898 |
iDoDoubleBuffer = ETrue; |
|
899 |
iDoPhysicalAddress = EFalse; |
|
900 |
||
901 |
iDbEnd = iReqEnd; |
|
902 |
const TUint32 maxDbLength = iSocket->MaxDataTransferLength(); |
|
903 |
||
904 |
if(maxDbLength) |
|
905 |
{ |
|
906 |
// |
|
907 |
// If the PSL specifies a limit on the maximum size of a data transfer, then truncate the request... |
|
908 |
// |
|
909 |
iDbEnd = UMin(iDbEnd, iPhysStart + maxDbLength); |
|
910 |
} |
|
911 |
||
912 |
iDbEnd = (iDbEnd + iBlkMsk) & ~iBlkMsk; |
|
913 |
||
914 |
const TUint32 doubleBufferSize = iMaxBufSize >> 1; |
|
915 |
iPhysEnd = (iReqCur + doubleBufferSize) & ~iBlkMsk; // The end of the first double-buffered transfer |
|
916 |
||
917 |
// |
|
918 |
// If we're double-buffering, then the entire cache will be re-used |
|
919 |
// continuously. Rather than continually reserve blocks during each |
|
920 |
// transfer we calculate the blocks that will be present after all |
|
921 |
// transfers have completed. |
|
922 |
// @see DoSessionEndDfc() |
|
923 |
// |
|
924 |
InvalidateCache(); |
|
925 |
iIntBuf = iCacheBuf; |
|
926 |
||
927 |
iSession->SetupCIMReadBlock(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2), iIntBuf, I64LOW(iDbEnd - iPhysStart) >> KMMCardHighCapBlockSizeLog2); |
|
928 |
||
929 |
iSession->EnableDoubleBuffering(doubleBufferSize >> KDiskSectorShift); |
|
930 |
||
931 |
// ...and switch to the 'second' buffer, which will be populated in the |
|
932 |
// data transfer callback in parallel with hardware transfer of the first. |
|
933 |
iSecondBuffer = ETrue; |
|
934 |
||
935 |
TInt r = EngageAndSetReadRequest(EMReqRead); |
|
936 |
||
937 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:ldbr:%d", r)); |
|
938 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
939 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_LAUNCHDBREAD_EXIT, this, r ); |
0 | 940 |
return r; |
941 |
} |
|
942 |
||
943 |
||
944 |
TInt DMmcMediaDriverFlash::LaunchPhysRead(TInt64 aStart, TUint32 aLength) |
|
945 |
// |
|
946 |
// This function does not maintain the iReq* instance variables. |
|
947 |
// It is assumed that before this function is called that |
|
948 |
// ReadDataUntilCacheExhausted() has been used. |
|
949 |
// |
|
950 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
951 |
OstTraceFunctionEntryExt( DMMCMEDIADRIVERFLASH_LAUNCHPHYSREAD_ENTRY, this ); |
148 | 952 |
OstTraceExt3( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_LAUNCHPHYSREAD, "position=%x:%x; length=0x%x", (TInt) I64HIGH(iReqCur), (TInt) I64LOW(iReqCur), (TInt) I64LOW(iReqEnd - iReqCur)); |
0 | 953 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:physr:0x%lx,0x%x", aStart, aLength)); |
954 |
__ASSERT_DEBUG(TotalSizeInBytes() > aStart, Panic(ELRStart)); |
|
955 |
__ASSERT_DEBUG(aLength > 0, Panic(ELRNotPositive)); |
|
956 |
__ASSERT_DEBUG(TotalSizeInBytes() >= aStart + aLength, Panic(ELREnd)); |
|
957 |
__ASSERT_CACHE(GetCachedBlock(aStart & ~iBlkMsk) == 0, Panic(ELRCached)); |
|
958 |
__ASSERT_DEBUG(iSession != NULL, Panic(ECFSessPtrNull)); |
|
959 |
||
960 |
TInt r(KErrNone); |
|
961 |
||
962 |
iDoPhysicalAddress = ETrue; |
|
963 |
iDoDoubleBuffer = EFalse; |
|
964 |
||
965 |
// Local Media Subsystem ensures DMA Addressable range not exceeded. |
|
966 |
// @see LocDrv::RegisterDmaDevice() |
|
967 |
iPhysEnd = (iReqEnd + iBlkMsk) & ~iBlkMsk; |
|
968 |
||
969 |
iRdROB = 0; |
|
970 |
iFragOfset = iIPCLen = iNxtIPCLen = iBufOfset = 0; |
|
971 |
||
972 |
// Determine if start/end are block aligned |
|
973 |
// physical memory can only read the exact amount, not more! |
|
974 |
const TBool firstPartial( (aStart & iBlkMsk) != 0); |
|
975 |
||
976 |
TPhysAddr physAddr(0); |
|
977 |
TInt physLength(0); |
|
978 |
TUint32 physLen(I64LOW(iPhysEnd - iPhysStart)); |
|
979 |
||
980 |
if (firstPartial) |
|
981 |
{ |
|
982 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:physr:FirstPartial")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
983 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_LAUNCH_PHYSREAD_FP, "FirstPartial"); |
0 | 984 |
// first index does not start on block boundary |
985 |
// iIntBuf linear address is used for IPC within DoReadDataTransferCallBack() |
|
986 |
iRdROB |= KIPCWrite; |
|
987 |
||
988 |
iIntBuf = ReserveReadBlocks(iPhysStart, iPhysStart+iBlkLen,(TUint32*)&physLength); |
|
989 |
#if !defined(__WINS__) |
|
990 |
physAddr = Epoc::LinearToPhysical((TLinAddr)iIntBuf); |
|
991 |
#else |
|
992 |
physAddr = (TPhysAddr)iIntBuf; |
|
993 |
#endif |
|
994 |
// Set SecondBuffer flag to indicate IPC cannot be done on next callback |
|
995 |
iSecondBuffer = ETrue; |
|
996 |
iBufOfset = I64LOW(iReqStart - iPhysStart); |
|
997 |
//iReqCur already set in DoRead; |
|
998 |
iFragOfset = iNxtIPCLen = physLength - iBufOfset; |
|
999 |
} |
|
1000 |
else |
|
1001 |
{ |
|
1002 |
// Determine offset from start due to data possibly recovered from local cache |
|
1003 |
iFragOfset = I64LOW(aStart - iReqStart); |
|
1004 |
r = PrepareFirstPhysicalFragment(physAddr, physLength, aLength); |
|
1005 |
||
1006 |
// No use for secondBuffer yet... |
|
1007 |
iSecondBuffer = EFalse; |
|
1008 |
} |
|
1009 |
||
1010 |
if(r == KErrNone) |
|
1011 |
{ |
|
1012 |
iDbEnd = iPhysEnd; |
|
1013 |
iPhysEnd = iPhysStart + physLength; |
|
1014 |
||
1015 |
if ((TUint32)physLength > physLen) physLength = physLen; // more memory in chunk than required |
|
1016 |
||
1017 |
iSession->SetupCIMReadBlock(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2), (TUint8*)physAddr, physLen >> KMMCardHighCapBlockSizeLog2); |
|
1018 |
||
1019 |
iSession->Command().iFlags|= KMMCCmdFlagPhysAddr; |
|
1020 |
iSession->EnableDoubleBuffering(physLength >> KDiskSectorShift); |
|
1021 |
||
1022 |
r = EngageAndSetReadRequest(EMReqRead); |
|
1023 |
} |
|
1024 |
||
1025 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:lphysr:%d", r)); |
|
1026 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1027 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_LAUNCHPHYSREAD_EXIT, this, r ); |
0 | 1028 |
return r; |
1029 |
} |
|
1030 |
||
1031 |
||
1032 |
TInt DMmcMediaDriverFlash::DoWrite() |
|
1033 |
// |
|
1034 |
// set up iReqStart, iReqEnd, and iReqCur, and launch first write. Any subsequent |
|
1035 |
// writes are launched from the session end DFC. LaunchWrite() handles pre-reading |
|
1036 |
// any sectors that are only partially modified. |
|
1037 |
// |
|
1038 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1039 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_DOWRITE_ENTRY, this ); |
0 | 1040 |
const TInt64 pos = iCurrentReq->Pos(); |
1041 |
const TUint32 length = I64LOW(iCurrentReq->Length()); |
|
1042 |
||
1043 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:dw:0x%lx,0x%x", pos, length)); |
|
148 | 1044 |
OstTraceExt3( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DOWRITE, "position=%x:%x; length=0x%x", (TUint) I64HIGH(pos), (TUint) I64LOW(pos), (TUint) length); |
0 | 1045 |
__ASSERT_DEBUG(CurrentRequest() == EMReqIdle, Panic(EDWInUse)); |
1046 |
__ASSERT_DEBUG(pos < TotalSizeInBytes(), Panic(EDWStart)); |
|
1047 |
__ASSERT_DEBUG(length > 0, Panic(EDWNotPositive)); |
|
1048 |
__ASSERT_DEBUG(TotalSizeInBytes() >= pos + length, Panic(EDWEnd)); |
|
1049 |
||
1050 |
iReqCur = iReqStart = pos; |
|
1051 |
iReqEnd = iReqStart + length; |
|
1052 |
||
1053 |
// iWtRBM is zero on construction because CBase-derived, and cleared at end |
|
1054 |
// of successful writes. If a write does not complete successfully, it may |
|
1055 |
// be left in non-zero state. |
|
1056 |
iWtRBM = 0; |
|
1057 |
||
1058 |
iSecondBuffer = EFalse; |
|
1059 |
iDoLastRMW = EFalse; |
|
1060 |
iDoDoubleBuffer= EFalse; |
|
1061 |
iDoPhysicalAddress = EFalse; |
|
1062 |
||
1063 |
const TInt r = LaunchWrite(iReqStart, length, EMReqWrite); |
|
1064 |
||
1065 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:dw:%d", r)); |
|
1066 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1067 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOWRITE_EXIT, this, r ); |
0 | 1068 |
return r; |
1069 |
} |
|
1070 |
||
1071 |
||
1072 |
TInt DMmcMediaDriverFlash::DoFormat() |
|
1073 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1074 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_DOFORMAT_ENTRY, this ); |
0 | 1075 |
const TInt64 pos = iCurrentReq->Pos(); |
1076 |
const TUint32 length = I64LOW(iCurrentReq->Length()); |
|
1077 |
||
1078 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:df:0x%lx,0x%x", pos, length)); |
|
148 | 1079 |
OstTraceExt3( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DOFORMAT, "position=%x:%x; length=0x%x", (TUint) I64HIGH(pos), (TUint) I64LOW(pos), (TUint) length); |
0 | 1080 |
__ASSERT_DEBUG(CurrentRequest() == EMReqIdle, Panic(EDFInUse)); |
1081 |
__ASSERT_DEBUG(pos < TotalSizeInBytes(), Panic(EDFStart)); |
|
1082 |
__ASSERT_DEBUG(length > 0, Panic(EDFNotPositive)); |
|
1083 |
__ASSERT_DEBUG(TotalSizeInBytes() >= pos + length, Panic(EDFEnd)); |
|
1084 |
||
1085 |
iReqCur = iReqStart = pos & ~iBlkMsk; |
|
1086 |
iReqEnd = (iReqStart + length + iBlkMsk) & ~iBlkMsk; |
|
1087 |
||
1088 |
// the cache isn't maintained during a format operation to avoid redundantly |
|
1089 |
// writing 0xff to memory (the blocks won't be re-used.) |
|
1090 |
InvalidateCache(); |
|
1091 |
||
1092 |
// create an MBR after the first format step (or second if misaligned) |
|
1093 |
||
1094 |
if (iInternalSlot) |
|
1095 |
{ |
|
1096 |
iCreateMbr = EFalse; |
|
1097 |
} |
|
1098 |
else |
|
1099 |
{ |
|
1100 |
if (iReqStart == (TInt64(iHiddenSectors) << KDiskSectorShift) && CreateMBRAfterFormat(iCard)) |
|
1101 |
iCreateMbr = ETrue; |
|
1102 |
} |
|
1103 |
||
1104 |
const TInt r = LaunchFormat(iReqStart, I64LOW(iReqEnd - iReqStart)); |
|
1105 |
||
1106 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:df:%d", r)); |
|
1107 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1108 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOFORMAT_EXIT, this, r ); |
0 | 1109 |
return r; |
1110 |
} |
|
1111 |
||
1112 |
||
1113 |
TInt DMmcMediaDriverFlash::LaunchFormat(TInt64 aStart, TUint32 aLength) |
|
1114 |
// |
|
1115 |
// starts writes from DoWrite(), DoFormat() and the session end DFC. This function does not |
|
1116 |
// maintain the iReq* instance variables. It sets iIntBuf, iPhysStart and iPhysEnd. |
|
1117 |
// |
|
1118 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1119 |
OstTraceFunctionEntryExt( DMMCMEDIADRIVERFLASH_LAUNCHFORMAT_ENTRY, this ); |
148 | 1120 |
OstTraceExt3( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_LAUNCHFORMAT, "position=%x:%x; length=0x%x", (TInt) I64HIGH(iReqCur), (TInt) I64LOW(iReqCur), (TInt) I64LOW(iReqEnd - iReqCur)); |
0 | 1121 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:lf:0x%lx,0x%x", aStart, aLength)); |
1122 |
__ASSERT_DEBUG(TotalSizeInBytes() > aStart, Panic(ELFStart)); |
|
1123 |
__ASSERT_DEBUG((aStart & iBlkMsk) == 0, Panic(ELWFmtStAlign)); |
|
1124 |
__ASSERT_DEBUG(aLength > 0, Panic(ELFNotPositive)); |
|
1125 |
__ASSERT_DEBUG(TotalSizeInBytes() >= aStart + aLength, Panic(ELFEnd)); |
|
1126 |
__ASSERT_DEBUG((aLength & iBlkMsk) == 0, Panic(ELWFmtEndAlign)); |
|
1127 |
__ASSERT_DEBUG(iSession != NULL, Panic(ECFSessPtrNull)); |
|
1128 |
||
1129 |
TInt r; |
|
1130 |
||
1131 |
if ((r = CheckDevice(EMReqTypeNormalWr)) == KErrNone) |
|
1132 |
{ |
|
1133 |
iPhysStart = aStart & ~iBlkMsk; |
|
1134 |
||
1135 |
// formats are always block-aligned, and the buffer is initialized to 0xff |
|
148 | 1136 |
// Check whether erase commands are supported by this card |
1137 |
if ( (iCard->CSD().CCC() & KMMCCmdClassErase) && iEraseInfo.iEraseFlags) |
|
0 | 1138 |
{ |
1139 |
// Determine the erase end point for the next command. We don't erase past the preferred erase unit |
|
1140 |
// size. Therefore, check which is lower, the preferred erase unit size or the end of the requested range. |
|
1141 |
TInt64 prefEraseUnitEnd = (iPhysStart + iEraseInfo.iPreferredEraseUnitSize) & ~iEraseUnitMsk; |
|
1142 |
iPhysEnd = UMin(prefEraseUnitEnd, aStart + aLength); |
|
1143 |
||
1144 |
const TUint32 minEraseSectorSize=iEraseInfo.iMinEraseSectorSize; |
|
1145 |
const TInt64 minEraseSecMsk = TInt64(minEraseSectorSize-1); |
|
1146 |
||
1147 |
// If erase start point doesn't lie on a min. erase unit boundary, then truncate the erase endpoint to |
|
1148 |
// the next min. erase unit boundary (assuming requested range allows this) |
|
1149 |
if ((iPhysStart & minEraseSecMsk)!=0) |
|
1150 |
{ |
|
1151 |
prefEraseUnitEnd=(iPhysStart+minEraseSectorSize) & ~minEraseSecMsk; |
|
1152 |
iPhysEnd=UMin(prefEraseUnitEnd,iPhysEnd); |
|
1153 |
} |
|
1154 |
||
1155 |
// Otherwise, if calculated erase end point doesn't lie on a min. erase unit boundary, but is at least one |
|
1156 |
// min. erase unit beyond the erase start point then move erase endpoint back to last min. erase unit boundary |
|
1157 |
else if ((iPhysEnd & minEraseSecMsk)!=0 && (iPhysEnd & ~minEraseSecMsk)>iPhysStart) |
|
1158 |
{ |
|
1159 |
iPhysEnd&=(~minEraseSecMsk); |
|
1160 |
} |
|
1161 |
||
1162 |
// 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) |
|
1164 |
{ |
|
1165 |
// Aligned erase |
|
1166 |
// Check that erase commands are supported prior to issuing an erase command |
|
1167 |
if(iEraseInfo.EraseGroupCmdsSupported()) |
|
1168 |
{ |
|
1169 |
iSession->SetupCIMEraseMGroup(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2), |
|
1170 |
I64LOW((iPhysEnd-iPhysStart) >> KMMCardHighCapBlockSizeLog2)); // Use ACMD35/36/38 (Erase Group) |
|
1171 |
} |
|
1172 |
else |
|
1173 |
{ |
|
1174 |
iSession->SetupCIMEraseMSector(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2), |
|
1175 |
I64LOW((iPhysEnd - iPhysStart) >> KMMCardHighCapBlockSizeLog2)); // Use ACMD32/33/38 (Erase Sector) |
|
1176 |
} |
|
1177 |
} |
|
1178 |
else |
|
1179 |
{ |
|
1180 |
// Misaligned erase - use multi-block write. However, first - check write length doesn't exceed buffer size. |
|
1181 |
if ((iPhysEnd-iPhysStart)>(TUint32)iMaxBufSize) |
|
1182 |
{ |
|
1183 |
iPhysEnd=(iPhysStart+iMaxBufSize); |
|
1184 |
} |
|
1185 |
||
1186 |
__ASSERT_DEBUG((iPhysEnd - iPhysStart) > 0, Panic(ELWLength)); |
|
1187 |
const TUint32 writeLen = I64LOW(iPhysEnd - iPhysStart); |
|
1188 |
memset (iCacheBuf, 0x00, writeLen); |
|
1189 |
iSession->SetupCIMWriteBlock(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2), iCacheBuf, writeLen >> KMMCardHighCapBlockSizeLog2); |
|
1190 |
} |
|
1191 |
} |
|
1192 |
else |
|
1193 |
{ |
|
1194 |
// Write to end of current write group, or end of request range, whichever is lower |
|
1195 |
const TInt64 prefEraseUnitEnd = (iPhysStart + iPrWtGpLen) & ~iPrWtGpMsk; |
|
1196 |
iPhysEnd = Min(prefEraseUnitEnd, aStart + aLength); |
|
1197 |
||
1198 |
__ASSERT_DEBUG((iPhysEnd - iPhysStart) > 0, Panic(ELWLength)); |
|
1199 |
const TUint32 writeLen = I64LOW(iPhysEnd - iPhysStart); |
|
1200 |
memset (iCacheBuf, 0x00, writeLen); |
|
1201 |
iSession->SetupCIMWriteBlock(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2), iCacheBuf, writeLen >> KMMCardHighCapBlockSizeLog2); |
|
1202 |
} |
|
1203 |
||
1204 |
r = EngageAndSetWriteRequest(EMReqFormat); |
|
1205 |
} |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1206 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_LAUNCHFORMAT_EXIT, this, r ); |
0 | 1207 |
return r; |
1208 |
} |
|
1209 |
||
1210 |
||
1211 |
||
1212 |
TInt DMmcMediaDriverFlash::LaunchWrite(TInt64 aStart, TUint32 aLength, TMediaRequest aMedReq) |
|
1213 |
// |
|
1214 |
// starts writes from DoWrite(), DoFormat() and the session end DFC. This function does not |
|
1215 |
// maintain the iReq* instance variables. It sets iIntBuf, iPhysStart and iPhysEnd. |
|
1216 |
// |
|
1217 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1218 |
OstTraceExt4(TRACE_FLOW, DMMCMEDIADRIVERFLASH_LAUNCHWRITE_ENTRY, "DMmcMediaDriverFlash::LaunchWrite;aStart=%Ld;aLength=%x;aMedReq=%d;this=%x", aStart, (TUint) aLength, (TInt) aMedReq, (TUint) this); |
148 | 1219 |
OstTraceExt3( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_LAUNCHWRITE, "position=%x:%x; length=0x%x", (TInt) I64HIGH(iReqCur), (TInt) I64LOW(iReqCur),(TInt) I64LOW(iReqEnd - iReqCur)); |
0 | 1220 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("\n>mmd:lw:0x%lx,%d,%d", aStart, aLength, aMedReq)); |
1221 |
__ASSERT_DEBUG(aMedReq == EMReqWrite || aMedReq == EMReqFormat, Panic(ELWRequest)); |
|
1222 |
__ASSERT_DEBUG(TotalSizeInBytes() > aStart, Panic(ELWStart)); |
|
1223 |
__ASSERT_DEBUG(!(aMedReq == EMReqFormat) || (aStart & iBlkMsk) == 0, Panic(ELWFmtStAlign)); |
|
1224 |
__ASSERT_DEBUG(aLength > 0, Panic(ELWNotPositive)); |
|
1225 |
__ASSERT_DEBUG(TotalSizeInBytes() >= aStart + aLength, Panic(ELWEnd)); |
|
1226 |
__ASSERT_DEBUG(!(aMedReq == EMReqFormat) || (aLength & iBlkMsk) == 0, Panic(ELWFmtEndAlign)); |
|
1227 |
__ASSERT_DEBUG(iSession != NULL, Panic(ECFSessPtrNull)); |
|
1228 |
||
1229 |
TInt r; |
|
1230 |
||
1231 |
if ((r = CheckDevice(EMReqTypeNormalWr)) == KErrNone) |
|
1232 |
{ |
|
1233 |
iPhysStart = aStart & ~iBlkMsk; |
|
1234 |
||
1235 |
// PSL MUST support double-buffering for DMA requests |
|
1236 |
// first write, or have just completed previous write |
|
1237 |
if (iWtRBM == 0) |
|
1238 |
{ |
|
1239 |
if(iDoDoubleBuffer == EFalse) |
|
1240 |
{ |
|
1241 |
// |
|
1242 |
// Can we use double-buffering for this request? |
|
1243 |
// |
|
1244 |
// - Only if PSL supports double buffering and the request length |
|
1245 |
// is greater than the maximum PSL buffer size. |
|
1246 |
// |
|
1247 |
iDoPhysicalAddress = iCurrentReq->IsPhysicalAddress(); |
|
1248 |
||
33
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1249 |
TInt64 medEnd = aStart + aLength; |
0 | 1250 |
|
1251 |
TInt64 maxPslEnd = medEnd; |
|
1252 |
const TUint32 maxDbLength = iSocket->MaxDataTransferLength(); |
|
1253 |
||
1254 |
if(maxDbLength) |
|
1255 |
{ |
|
1256 |
// |
|
1257 |
// If the PSL specifies a limit on the maximum size of a data transfer, then truncate the request... |
|
1258 |
// |
|
1259 |
maxPslEnd = UMin(medEnd, iPhysStart + maxDbLength); |
|
1260 |
} |
|
1261 |
||
1262 |
iPhysEnd = (maxPslEnd + iBlkMsk) & ~iBlkMsk; |
|
1263 |
||
1264 |
if (iDoPhysicalAddress) |
|
1265 |
{ |
|
1266 |
iDoDoubleBuffer = EFalse; |
|
1267 |
iIntBuf = ReserveWriteBlocks(aStart, medEnd, &iWtRBM); |
|
1268 |
iPhysEnd = (medEnd + iBlkMsk) & ~iBlkMsk; |
|
1269 |
} |
|
1270 |
||
1271 |
if (!iDoPhysicalAddress) |
|
1272 |
{ |
|
1273 |
iDoDoubleBuffer = iSocket->SupportsDoubleBuffering() && ((iPhysEnd - iPhysStart) > iMaxBufSize); |
|
1274 |
if(iDoDoubleBuffer) |
|
1275 |
{ |
|
1276 |
// |
|
1277 |
// Conditions for double-buffering are met. Set up the size of the first |
|
1278 |
// transfer to half the size of the block cache. |
|
1279 |
// |
|
1280 |
// Note that we don't bother to align to write groups here, as the entire |
|
1281 |
// request will be processed under one multi-block command so there's no |
|
1282 |
// danger of forcing the card into RMW cycles as would be the case when |
|
1283 |
// issuing multiple misaligned commands. |
|
1284 |
// |
|
1285 |
iDbEnd = maxPslEnd; // The end of the complete double-buffered transfer |
|
1286 |
iPhysEnd = (iPhysStart + (iMaxBufSize >> 1) + iBlkMsk) &~ iBlkMsk; // The end of the first double-buffered transfer |
|
1287 |
__ASSERT_DEBUG(iPhysEnd - iPhysStart <= (iMaxBufSize >> 1), Panic(ELWLength)); |
|
1288 |
||
1289 |
// |
|
1290 |
// Now reserve write blocks from the buffer cache. When double-buffering, |
|
1291 |
// write blocks are only really reserved during the last transfer to avoid |
|
1292 |
// continuously updating the cache indexes. Since the block cache is |
|
1293 |
// continuously recycled, the following call shall invalidate the cache |
|
1294 |
// and inform us as to whether we need to perform an RMW operation for |
|
1295 |
// the first and last blocks prior to initiating data transfer. |
|
1296 |
// |
|
1297 |
iIntBuf = ReserveWriteBlocks(aStart, iDbEnd, &iWtRBM); |
|
1298 |
} |
|
1299 |
else |
|
33
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1300 |
{ |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1301 |
if ( (iPhysEnd - iPhysStart) > iMaxBufSize) |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1302 |
{ |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1303 |
// |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1304 |
// reserve buffers to end of first write group, or end of request range, |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1305 |
// whichever is lower. Note that if the range already exists in the buffer, |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1306 |
// e.g. because of a previous RBM, the same range will be returned. This |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1307 |
// means that iWtRBM can be set to zero in the callback DFC, and this code |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1308 |
// will retrieve the reserved range. |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1309 |
// |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1310 |
const TInt64 wtGpEnd = (iPhysStart + iPrWtGpLen) & ~iPrWtGpMsk; |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1311 |
medEnd = UMin(wtGpEnd, aStart + aLength); |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1312 |
iPhysEnd = (medEnd + iBlkMsk) & ~iBlkMsk; |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1313 |
} |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1314 |
|
0 | 1315 |
iIntBuf = ReserveWriteBlocks(aStart, medEnd, &iWtRBM); |
1316 |
} |
|
1317 |
} //if (!iDoPhysicalAddress) |
|
1318 |
} //if(iDoDoubleBuffer == EFalse) |
|
1319 |
} //if (iWtRBM == 0) |
|
1320 |
||
1321 |
if (iWtRBM & KWtRBMFst) |
|
1322 |
{ |
|
1323 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("mmd:lw: read-before-modify required on first block")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1324 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_LAUNCHWRITE_RBMF, "Read-before-modify required on first block"); |
0 | 1325 |
if (iDoPhysicalAddress) |
1326 |
iSession->SetupCIMReadBlock(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2), iMinorBuf, iBlkLen >> KMMCardHighCapBlockSizeLog2); |
|
1327 |
else |
|
1328 |
iSession->SetupCIMReadBlock(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2), iIntBuf, iBlkLen >> KMMCardHighCapBlockSizeLog2); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1329 |
r = EngageAndSetReadRequest(aMedReq); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1330 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_LAUNCHWRITE_EXIT1, this, r ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1331 |
return r; |
0 | 1332 |
} |
1333 |
||
1334 |
else if (iWtRBM & KWtRBMLst) |
|
1335 |
{ |
|
1336 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("mmd:lw: read-before-modify required on last block")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1337 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_LAUNCHWRITE_RBML, "Read-before-modify required on last block"); |
0 | 1338 |
if(iDoDoubleBuffer || iDoPhysicalAddress) |
1339 |
{ |
|
1340 |
// |
|
1341 |
// When double-buffering, the result of the RMW-read operation shall be stored |
|
1342 |
// in the minor buffer, otherwise the data would be overwritten before the last |
|
1343 |
// data transfer takes place. |
|
1344 |
// |
|
1345 |
const TInt64 lastBlock = (aStart + aLength) & ~iBlkMsk; // start posn in media to read from (we know aStart + aLength isn't block aligned due to KWtRBMLst flag) |
|
1346 |
if (iDoDoubleBuffer) |
|
1347 |
iSession->SetupCIMReadBlock(I64LOW(lastBlock >> KMMCardHighCapBlockSizeLog2), iMinorBuf, iBlkLen >> KMMCardHighCapBlockSizeLog2); |
|
1348 |
else |
|
1349 |
iSession->SetupCIMReadBlock(I64LOW(lastBlock >> KMMCardHighCapBlockSizeLog2), iCacheBuf, iBlkLen >> KMMCardHighCapBlockSizeLog2); |
|
1350 |
} |
|
1351 |
else |
|
1352 |
{ |
|
1353 |
// |
|
1354 |
// If not double-buffering, we can read the RMW data of the last block directly |
|
1355 |
// into the block cache as we know that the data transfer will fit entirely |
|
1356 |
// within the cache.. |
|
1357 |
// |
|
1358 |
const TInt64 lastBlock = iPhysEnd - iBlkLen; // start posn in media to read from |
|
1359 |
iSession->SetupCIMReadBlock(I64LOW(lastBlock >> KMMCardHighCapBlockSizeLog2), iIntBuf + (lastBlock - iPhysStart), iBlkLen >> KMMCardHighCapBlockSizeLog2); |
|
1360 |
} |
|
1361 |
||
1362 |
// Kick off the RMW-read operation for the last block... |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1363 |
r = EngageAndSetReadRequest(aMedReq); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1364 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_LAUNCHWRITE_EXIT2, this, r ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1365 |
return r; |
0 | 1366 |
} |
1367 |
||
1368 |
if (iWtRBM & KWtMinFst) |
|
1369 |
{ |
|
1370 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("mmd:lw:Phys write-first-block-only")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1371 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_LAUNCHWRITE_FBO, "Write first block only"); |
0 | 1372 |
//Overwrite first block with the new data |
1373 |
TInt32 tlen = I64LOW(aStart & iBlkMsk); |
|
1374 |
TInt32 wlen = UMin(I64LOW((iBlkMsk+1) - tlen), aLength); |
|
1375 |
||
1376 |
const TInt64 usrOfst = (aStart - iReqStart); |
|
1377 |
TPtr8 tgt(&iMinorBuf[tlen], I64LOW(wlen)); |
|
1378 |
||
1379 |
if ( (r = iCurrentReq->ReadRemote(&tgt,I64LOW(usrOfst))) != KErrNone) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1380 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1381 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_LAUNCHWRITE_EXIT3, this, r ); |
0 | 1382 |
return r; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1383 |
} |
0 | 1384 |
} |
1385 |
||
1386 |
if (iWtRBM & KWtMinLst) |
|
1387 |
{ |
|
1388 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("mmd:lw:Phys write-last-block-only")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1389 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_LAUNCHWRITE_LBO, "Write last block only"); |
0 | 1390 |
iWtRBM &= ~KWtMinLst; |
1391 |
//Overwrite last block with the new data |
|
1392 |
const TInt64 medEnds = aStart + aLength; |
|
1393 |
TInt64 tlen = medEnds & iBlkMsk; |
|
1394 |
||
1395 |
const TInt64 usrOfst = (aStart - iReqStart); |
|
1396 |
TPtr8 tgt(iCacheBuf, I64LOW(tlen)); |
|
1397 |
||
1398 |
if ( (r = iCurrentReq->ReadRemote(&tgt,I64LOW(usrOfst+aLength-tlen))) !=KErrNone) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1399 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1400 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_LAUNCHWRITE_EXIT4, this, r ); |
0 | 1401 |
return r; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1402 |
} |
0 | 1403 |
} |
1404 |
||
1405 |
// no reads required - read data from user buffer and launch write |
|
1406 |
const TInt64 usrOfst = (aStart - iReqStart); |
|
1407 |
const TInt64 bufOfst = aStart - iPhysStart; // offset into first sector, not whole buffer |
|
1408 |
const TInt64 len = UMin(aStart + aLength, iPhysEnd) - iReqCur; |
|
1409 |
__ASSERT_DEBUG(len > 0, Panic(ELWLength)); |
|
1410 |
__ASSERT_DEBUG(I64HIGH(usrOfst) == 0, Panic(ELWLength)); |
|
1411 |
||
1412 |
if (iDoPhysicalAddress) |
|
1413 |
{ |
|
1414 |
TPhysAddr physAddr = 0; |
|
1415 |
TInt physLength = 0; |
|
1416 |
TUint32 physLen = I64LOW(iPhysEnd - iPhysStart); |
|
1417 |
||
1418 |
if (iWtRBM & KWtMinFst) |
|
1419 |
{ |
|
1420 |
#if !defined(__WINS__) |
|
1421 |
physAddr = Epoc::LinearToPhysical((TLinAddr)iMinorBuf); |
|
1422 |
#else |
|
1423 |
physAddr = (TPhysAddr)iMinorBuf; |
|
1424 |
#endif |
|
1425 |
physLength = iBlkLen; |
|
1426 |
iBufOfset = I64LOW(iReqStart - iPhysStart); |
|
1427 |
//iReqCur already set in DoWrite |
|
1428 |
iFragOfset = iIPCLen = iBlkLen - iBufOfset; |
|
1429 |
iWtRBM &= ~KWtMinFst; |
|
1430 |
} |
|
1431 |
else |
|
1432 |
{ |
|
1433 |
iFragOfset = I64LOW(usrOfst); |
|
1434 |
||
1435 |
r = PrepareFirstPhysicalFragment(physAddr, physLength, aLength); |
|
1436 |
} |
|
1437 |
||
1438 |
if (r == KErrNone) |
|
1439 |
{ |
|
1440 |
iDbEnd = iPhysEnd; |
|
1441 |
iPhysEnd = iPhysStart+physLength; |
|
1442 |
||
1443 |
if ((TUint32)physLength > physLen) physLength = physLen; // more memory in fragment than required! |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1444 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_LAUNCHWRITE_PHYSICAL, "Physical write request" ); |
0 | 1445 |
iSession->SetupCIMWriteBlock(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2), (TUint8*) physAddr, physLen >> KMMCardHighCapBlockSizeLog2); |
1446 |
iSession->Command().iFlags|= KMMCCmdFlagPhysAddr; |
|
1447 |
iSession->EnableDoubleBuffering(physLength >> KDiskSectorShift); |
|
1448 |
} |
|
1449 |
else |
|
1450 |
{ |
|
1451 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:lw:Phys:%d", r)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1452 |
|
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1453 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_LAUNCHWRITE_EXIT5, this, r ); |
0 | 1454 |
return r; |
1455 |
} |
|
1456 |
} // if (iDoPhysicalAddress) |
|
1457 |
else |
|
1458 |
{ |
|
1459 |
TPtr8 tgt(&iIntBuf[bufOfst], I64LOW(len)); |
|
1460 |
||
1461 |
r = ReadDataFromUser(tgt, I64LOW(usrOfst)); |
|
1462 |
if (r == KErrNone) |
|
1463 |
{ |
|
1464 |
if(!iDoDoubleBuffer) |
|
1465 |
{ |
|
1466 |
// EPBUSM automatically uses CMD24 instead of CMD25 for single block writes |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1467 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_LAUNCHWRITE_STANDARD, "Standard write request" ); |
0 | 1468 |
iSession->SetupCIMWriteBlock(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2), iIntBuf, I64LOW((iPhysEnd - iPhysStart) >> KMMCardHighCapBlockSizeLog2)); |
1469 |
} |
|
1470 |
else |
|
1471 |
{ |
|
1472 |
// |
|
1473 |
// When double-buffering, set up the data transfer command to the entire |
|
1474 |
// request range. and flag the session to enable double-buffering (as well |
|
1475 |
// as specifying the length of each double-buffered transfer as calculated |
|
1476 |
// in 'len' above). This is performed only once - the double-buffering |
|
1477 |
// is subsequently handled within the DoDataTransferCallback function. |
|
1478 |
// |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1479 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_LAUNCHWRITE_DB, "Double-buffered write request" ); |
0 | 1480 |
iSession->SetupCIMWriteBlock(I64LOW(iPhysStart >> KMMCardHighCapBlockSizeLog2), iIntBuf, I64LOW((((iDbEnd + iBlkMsk) & ~iBlkMsk) - iPhysStart) >> KMMCardHighCapBlockSizeLog2)); |
1481 |
iSession->EnableDoubleBuffering(I64LOW((len + iBlkMsk) & ~iBlkMsk) >> KDiskSectorShift); |
|
1482 |
||
1483 |
// ...and switch to the 'second' buffer, which will be populated in the |
|
1484 |
// data transfer callback in parallel with hardware transfer of the first. |
|
1485 |
iSecondBuffer = ETrue; |
|
1486 |
} |
|
1487 |
} |
|
1488 |
} |
|
133 | 1489 |
|
1490 |
#ifdef _ENABLE_EMMC_RELIABLE_WRITE_ |
|
0 | 1491 |
//Reliable Write only supported by v4.3+ MMC media |
1492 |
if (iCard->ExtendedCSD().ExtendedCSDRev() >= 3) |
|
1493 |
{ |
|
1494 |
// One request, i.e. not end of previous DB request |
|
1495 |
// 512 Bytes long when sector aligned |
|
1496 |
if ( ( I64LOW(iPhysEnd - iPhysStart) == iBlkLen) && ((iReqStart & ~iBlkMsk) == iPhysStart) ) |
|
1497 |
{ |
|
1498 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("mmd:lw:AtomicWrite")); |
|
1499 |
iSession->Command().iFlags|= KMMCCmdFlagReliableWrite; |
|
1500 |
} |
|
1501 |
} |
|
133 | 1502 |
#endif //_ENABLE_EMMC_RELIABLE_WRITE_ |
0 | 1503 |
|
1504 |
// Engage the data transfer session... |
|
1505 |
r = EngageAndSetWriteRequest(aMedReq); |
|
1506 |
} // if ((r = CheckDevice(EMReqTypeNormalWr)) == KErrNone) |
|
1507 |
||
1508 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:lw:%d", r)); |
|
1509 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1510 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_LAUNCHWRITE_EXIT6, this, r ); |
0 | 1511 |
return r; |
1512 |
} |
|
1513 |
||
1514 |
TInt DMmcMediaDriverFlash::PartitionInfo(TPartitionInfo& anInfo) |
|
1515 |
// |
|
1516 |
// Read the partition information for the media. If the user supplied a password, |
|
1517 |
// then unlock the card before trying to read the first sector. |
|
1518 |
// |
|
1519 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1520 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_PARTITIONINFO_ENTRY, this ); |
0 | 1521 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:rpi")); |
1522 |
__ASSERT_DEBUG(CurrentRequest() == EMReqIdle, Panic(ERPIInUse)); |
|
1523 |
||
1524 |
iPartitionInfo = &anInfo; |
|
1525 |
||
1526 |
if(iMmcPartitionInfo) |
|
1527 |
{ |
|
1528 |
// If this is an embedded device, use the custom formatting function: |
|
1529 |
TInt r = iMmcPartitionInfo->PartitionInfo(*iPartitionInfo, iSessionEndCallBack); |
|
1530 |
||
1531 |
iHiddenSectors = 0; // Not used for internal media |
|
1532 |
||
1533 |
if (KErrNone == r) |
|
1534 |
iMedReq = EMReqEMMCPtnInfo; |
|
1535 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1536 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_PARTITIONINFO_EXIT1, this, r ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1537 |
return r; |
0 | 1538 |
} |
1539 |
||
1540 |
// Assume MBR will be present or is not required |
|
1541 |
iMbrMissing = EFalse; |
|
1542 |
||
1543 |
// If media driver is persistent (see EMediaDriverPersistent), |
|
1544 |
// the card may have changed since last power down, so reset CID |
|
1545 |
iSession->SetCard(iCard); |
|
1546 |
||
1547 |
TInt r = LaunchRPIRead(); |
|
1548 |
||
1549 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:rpi:%d", r)); |
|
1550 |
||
1551 |
if(r == KErrLocked) |
|
1552 |
{ |
|
1553 |
// If the media is locked, we present a default partition entry to the local |
|
1554 |
// media subsystem, which will be updated when the media is finally unlocked. |
|
1555 |
r = CreateDefaultPartition(); |
|
1556 |
if (r != KErrNone) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1557 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1558 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_PARTITIONINFO_EXIT2, this, r ); |
0 | 1559 |
return r; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1560 |
} |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1561 |
|
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1562 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_PARTITIONINFO_EXIT3, this, KErrLocked ); |
0 | 1563 |
return KErrLocked; |
1564 |
} |
|
1565 |
||
1566 |
// KErrNone indicates asynchronous completion |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1567 |
|
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1568 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_PARTITIONINFO_EXIT4, this, r ); |
0 | 1569 |
return r; |
1570 |
} |
|
1571 |
||
1572 |
TInt DMmcMediaDriverFlash::LaunchRPIUnlock(TLocalDrivePasswordData& aPasswordData) |
|
1573 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1574 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_LAUNCHRPIUNLOCK_ENTRY, this ); |
0 | 1575 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:lru:%d,%d", iCard->IsReady(), iCard->IsLocked())); |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1576 |
OstTraceExt2( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_LAUNCHRPIUNLOCK_ICARD, "iCard->IsReady=%d; iCard->IsLocked=%d", iCard->IsReady(), iCard->IsLocked()); |
0 | 1577 |
__ASSERT_DEBUG(iSession != NULL, Panic(ECFSessPtrNull)); |
1578 |
||
1579 |
TInt r = KErrNone; |
|
1580 |
||
1581 |
// CMD42 is an adtc, so check state in same way as for write |
|
1582 |
if ((r = CheckDevice(EMReqTypeUnlockPswd)) == KErrNone) |
|
1583 |
{ |
|
1584 |
r = Stack().MMCSocket()->PrepareStore(CardNum(), DLocalDrive::EPasswordUnlock, aPasswordData); |
|
1585 |
||
1586 |
if (r == KErrNone) |
|
1587 |
{ |
|
1588 |
TMediaPassword curPwd; |
|
1589 |
||
1590 |
curPwd = *aPasswordData.iOldPasswd; |
|
1591 |
||
1592 |
TInt curPwdLen = curPwd.Length(); |
|
1593 |
TInt blockLen = 2 + curPwdLen; |
|
1594 |
||
1595 |
TPtr8 pbuf(&iMinorBuf[0], 2, blockLen); |
|
1596 |
pbuf[0] = 0; // LOCK_UNLOCK = 0; SET_PWD = 0 |
|
1597 |
pbuf[1] = static_cast<TUint8>(curPwdLen); |
|
1598 |
pbuf.Append(curPwd); |
|
1599 |
iSession->SetupCIMLockUnlock(blockLen, iMinorBuf); |
|
1600 |
||
1601 |
r = EngageAndSetWriteRequest(EMReqUpdatePtnInfo); |
|
1602 |
} |
|
1603 |
} |
|
1604 |
||
1605 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:lru:%d", r)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1606 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_LAUNCHRPIUNLOCK_EXIT, this, r ); |
0 | 1607 |
return r; |
1608 |
} |
|
1609 |
||
1610 |
||
1611 |
TInt DMmcMediaDriverFlash::LaunchRPIRead() |
|
1612 |
// |
|
1613 |
// launch read request on first KDiskSectorSize (512) bytes |
|
1614 |
// |
|
1615 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1616 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_LAUNCHRPIREAD_ENTRY, this ); |
0 | 1617 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf((">mmd:lrr"))); |
1618 |
__ASSERT_DEBUG(iSession != NULL, Panic(ECFSessPtrNull)); |
|
1619 |
||
1620 |
// the partition information is read before any other area is read from / |
|
1621 |
// written to, and so does not need to maintain cache coherence. Therefore |
|
1622 |
// it can safely use the minor buffer. |
|
1623 |
||
1624 |
TInt r; |
|
1625 |
if ((r = CheckDevice(EMReqTypeNormalRd)) == KErrNone) |
|
1626 |
{ |
|
1627 |
iIntBuf = iMinorBuf; |
|
1628 |
iSession->SetupCIMReadBlock(0, iIntBuf); // aBlocks = 1 |
|
1629 |
r = EngageAndSetReadRequest(EMReqPtnInfo); |
|
1630 |
} |
|
1631 |
||
1632 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:lrr:%d", r)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1633 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_LAUNCHRPIREAD_EXIT, this, r ); |
0 | 1634 |
return r; |
1635 |
} |
|
1636 |
||
1637 |
||
1638 |
TInt DMmcMediaDriverFlash::LaunchRPIErase() |
|
1639 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1640 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_LAUNCHRPIERASE_ENTRY, this ); |
0 | 1641 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:lre:%d,%d", iCard->IsReady(), iCard->IsLocked())); |
1642 |
__ASSERT_DEBUG(iSession != NULL, Panic(ECFSessPtrNull)); |
|
1643 |
||
1644 |
TInt r = KErrNone; |
|
1645 |
||
1646 |
// CMD42 is an adtc, so check state in same way as for write |
|
1647 |
if ((r = CheckDevice(EMReqTypeUnlockPswd)) == KErrNone) |
|
1648 |
{ |
|
1649 |
if(iCard->IsWriteProtected()) |
|
1650 |
{ |
|
1651 |
r = KErrAccessDenied; |
|
1652 |
} |
|
1653 |
else |
|
1654 |
{ |
|
1655 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("mmd:df:EMReqForceErase")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1656 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_LAUNCHRPIERASE_FORCE_ERASE, "Force erase"); |
0 | 1657 |
iMinorBuf[0] = KMMCLockUnlockErase; |
1658 |
iSession->SetupCIMLockUnlock(1, iMinorBuf); |
|
1659 |
r = EngageAndSetWriteRequest(EMReqForceErase); |
|
1660 |
} |
|
1661 |
} |
|
1662 |
||
1663 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:lru:%d", r)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1664 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_LAUNCHRPIERASE_EXIT, this, r ); |
0 | 1665 |
return r; |
1666 |
} |
|
1667 |
||
1668 |
||
1669 |
TInt DMmcMediaDriverFlash::DecodePartitionInfo() |
|
1670 |
// |
|
1671 |
// decode partition info that was read into internal buffer |
|
1672 |
// |
|
1673 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1674 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_DECODEPARTITIONINFO_ENTRY, this ); |
0 | 1675 |
TInt partitionCount=iPartitionInfo->iPartitionCount=0; |
1676 |
TInt defaultPartitionNumber=-1; |
|
1677 |
TMBRPartitionEntry* pe; |
|
1678 |
const TUint KMBRFirstPartitionOffsetAligned = KMBRFirstPartitionOffset & ~3; |
|
1679 |
TInt i; |
|
1680 |
||
1681 |
// Read of the first sector successful so check for a Master Boot Record |
|
1682 |
if (*(TUint16*)(&iIntBuf[KMBRSignatureOffset])!=0xAA55) |
|
1683 |
goto mbr_done; |
|
1684 |
||
1685 |
__ASSERT_COMPILE(KMBRFirstPartitionOffsetAligned + KMBRMaxPrimaryPartitions * sizeof(TMBRPartitionEntry) <= KMBRSignatureOffset); |
|
1686 |
||
1687 |
memmove(&iIntBuf[0], &iIntBuf[2], |
|
1688 |
KMBRFirstPartitionOffsetAligned + KMBRMaxPrimaryPartitions * sizeof(TMBRPartitionEntry)); |
|
1689 |
||
1690 |
||
1691 |
for (i=0, pe = (TMBRPartitionEntry*)(&iIntBuf[KMBRFirstPartitionOffsetAligned]); |
|
1692 |
pe->iPartitionType != 0 && i < KMBRMaxPrimaryPartitions;i++,pe++) |
|
1693 |
{ |
|
1694 |
if (pe->IsDefaultBootPartition()) |
|
1695 |
{ |
|
1696 |
SetPartitionEntry(&iPartitionInfo->iEntry[0],pe->iFirstSector,pe->iNumSectors); |
|
1697 |
defaultPartitionNumber=i; |
|
1698 |
partitionCount++; |
|
1699 |
break; |
|
1700 |
} |
|
1701 |
} |
|
1702 |
||
1703 |
// Now add any other partitions |
|
1704 |
for (i=0, pe = (TMBRPartitionEntry*)(&iIntBuf[KMBRFirstPartitionOffsetAligned]); |
|
1705 |
pe->iPartitionType != 0 && i < KMBRMaxPrimaryPartitions;i++,pe++) |
|
1706 |
{ |
|
1707 |
TBool validPartition = ETrue; // assume partition valid |
|
1708 |
||
1709 |
if (defaultPartitionNumber==i) |
|
1710 |
{ |
|
1711 |
// Already sorted |
|
1712 |
} |
|
1713 |
||
1714 |
// FAT partition ? |
|
33
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1715 |
else if (pe->IsValidDosPartition() || pe->IsValidFAT32Partition() || pe->IsValidExFATPartition()) |
0 | 1716 |
{ |
1717 |
SetPartitionEntry(&iPartitionInfo->iEntry[partitionCount],pe->iFirstSector,pe->iNumSectors); |
|
1718 |
__KTRACE_OPT(KLOCDPAGING, Kern::Printf("Mmc: FAT partition found at sector #%u", pe->iFirstSector)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1719 |
OstTrace1(TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DECODEPARTITIONINFO_FS,"FAT partition found at sector #%u", pe->iFirstSector); |
0 | 1720 |
partitionCount++; |
1721 |
} |
|
1722 |
else |
|
1723 |
{ |
|
1724 |
validPartition = EFalse; |
|
1725 |
} |
|
1726 |
||
1727 |
if (validPartition && partitionCount == 1) |
|
1728 |
iHiddenSectors = pe->iFirstSector; |
|
1729 |
||
1730 |
} |
|
1731 |
||
1732 |
// Check the validity of the partition address boundaries |
|
1733 |
// If there is any |
|
1734 |
if(partitionCount > 0) |
|
1735 |
{ |
|
1736 |
const TInt64 deviceSize = iCard->DeviceSize64(); |
|
1737 |
TPartitionEntry& part = iPartitionInfo->iEntry[partitionCount - 1]; |
|
1738 |
// Check that the card address space boundary is not exceeded by the last partition |
|
1739 |
// In case of only 1 partition in the media check also it |
|
1740 |
if(part.iPartitionBaseAddr + part.iPartitionLen > deviceSize) |
|
1741 |
{ |
|
1742 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: MBR partition exceeds card memory space")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1743 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DECODEPARTITIONINFO_PARTCOUNT1, "MBR partition exceeds card memory space" ); |
0 | 1744 |
// Adjust the partition length to card address boundary |
1745 |
part.iPartitionLen = (deviceSize - part.iPartitionBaseAddr); |
|
1746 |
||
1747 |
// Check that the base address contained valid information |
|
1748 |
if(part.iPartitionLen <= 0) |
|
1749 |
{ |
|
1750 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: Invalid base address")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1751 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DECODEPARTITIONINFO_PARTCOUNT2, "Invalid base address" ); |
0 | 1752 |
// Invalid MBR - assume the boot sector is in the first sector |
1753 |
defaultPartitionNumber =-1; |
|
1754 |
partitionCount=0; |
|
1755 |
} |
|
1756 |
} |
|
1757 |
// More than one partition. Go through all of them |
|
1758 |
if (partitionCount > 0) |
|
1759 |
{ |
|
1760 |
for(i=partitionCount-1; i>0; i--) |
|
1761 |
{ |
|
1762 |
const TPartitionEntry& curr = iPartitionInfo->iEntry[i]; |
|
1763 |
TPartitionEntry& prev = iPartitionInfo->iEntry[i-1]; |
|
1764 |
// Check if partitions overlap |
|
1765 |
if(curr.iPartitionBaseAddr < (prev.iPartitionBaseAddr + prev.iPartitionLen)) |
|
1766 |
{ |
|
1767 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: Overlapping partitions")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1768 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DECODEPARTITIONINFO_PARTCOUNT3, "Overlapping partitions" ); |
0 | 1769 |
// Adjust the partition length to not overlap the next partition |
1770 |
prev.iPartitionLen = (curr.iPartitionBaseAddr - prev.iPartitionBaseAddr); |
|
1771 |
||
1772 |
// Check that the base address contained valid information |
|
1773 |
if(prev.iPartitionLen <= 0) |
|
1774 |
{ |
|
1775 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc: Invalid base address")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1776 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DECODEPARTITIONINFO_PARTCOUNT4, "Invalid base address" ); |
0 | 1777 |
// Invalid MBR - assume the boot sector is in the first sector |
1778 |
defaultPartitionNumber=(-1); |
|
1779 |
partitionCount=0; |
|
1780 |
} |
|
1781 |
} |
|
1782 |
} |
|
1783 |
} |
|
1784 |
} |
|
1785 |
||
1786 |
mbr_done: |
|
1787 |
if (defaultPartitionNumber==(-1) && partitionCount==0) |
|
1788 |
{ |
|
1789 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("Mmc:PartitionInfo no MBR")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1790 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DECODEPARTITIONINFO_MBRDONE1, "No MBR" ); |
0 | 1791 |
if (MBRMandatory(iCard)) |
1792 |
{ |
|
1793 |
// If the MBR is missing AND is required, we present a default partition entry to the local |
|
1794 |
// media subsystem, which will be updated when the media is finally formatted |
|
1795 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("MBR mandatory, defining space for MBR + default partition")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1796 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DECODEPARTITIONINFO_MBRDONE2, "MBR mandatory, defining space for MBR + default partition" ); |
0 | 1797 |
iMbrMissing = ETrue; |
1798 |
TInt r = CreateDefaultPartition(); |
|
1799 |
if (r != KErrNone) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1800 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1801 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DECODEPARTITIONINFO_EXIT1, this, r ); |
0 | 1802 |
return r; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1803 |
} |
0 | 1804 |
} |
1805 |
else |
|
1806 |
{ |
|
1807 |
// Assume it has no MBR, and the Boot Sector is in the 1st sector |
|
1808 |
SetPartitionEntry(&iPartitionInfo->iEntry[0],0,I64LOW(iCard->DeviceSize64()>>KDiskSectorShift)); |
|
1809 |
iHiddenSectors=0; |
|
1810 |
} |
|
1811 |
partitionCount=1; |
|
1812 |
} |
|
1813 |
||
1814 |
iPartitionInfo->iPartitionCount=partitionCount; |
|
1815 |
iPartitionInfo->iMediaSizeInBytes=TotalSizeInBytes(); |
|
1816 |
||
1817 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<Mmc:PartitionInfo (C:%d)",iPartitionInfo->iPartitionCount)); |
|
1818 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(" Partition1 (B:%xH L:%xH)",I64LOW(iPartitionInfo->iEntry[0].iPartitionBaseAddr),I64LOW(iPartitionInfo->iEntry[0].iPartitionLen))); |
|
1819 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(" Partition2 (B:%xH L:%xH)",I64LOW(iPartitionInfo->iEntry[1].iPartitionBaseAddr),I64LOW(iPartitionInfo->iEntry[1].iPartitionLen))); |
|
1820 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(" Partition3 (B:%xH L:%xH)",I64LOW(iPartitionInfo->iEntry[2].iPartitionBaseAddr),I64LOW(iPartitionInfo->iEntry[2].iPartitionLen))); |
|
1821 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(" Partition4 (B:%xH L:%xH)",I64LOW(iPartitionInfo->iEntry[3].iPartitionBaseAddr),I64LOW(iPartitionInfo->iEntry[3].iPartitionLen))); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1822 |
OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_MMCDEBUG, DMMCMEDIADRIVERFLASH_DECODEPARTITIONINFO_PARTINFO1, "Partition1 (B:0x%x L:0x%x); Partition2 (B:0x%x L:0x%x)", I64LOW(iPartitionInfo->iEntry[0].iPartitionBaseAddr),I64LOW(iPartitionInfo->iEntry[0].iPartitionLen),I64LOW(iPartitionInfo->iEntry[1].iPartitionBaseAddr),I64LOW(iPartitionInfo->iEntry[1].iPartitionLen)); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1823 |
OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_MMCDEBUG, DMMCMEDIADRIVERFLASH_DECODEPARTITIONINFO_PARTINFO2, "Partition3 (B:0x%x L:0x%x); Partition4 (B:0x%x L:0x%x)", I64LOW(iPartitionInfo->iEntry[2].iPartitionBaseAddr),I64LOW(iPartitionInfo->iEntry[2].iPartitionLen),I64LOW(iPartitionInfo->iEntry[3].iPartitionBaseAddr),I64LOW(iPartitionInfo->iEntry[3].iPartitionLen)); |
0 | 1824 |
|
1825 |
#ifdef _DEBUG |
|
1826 |
TMBRPartitionEntry cPe; |
|
1827 |
if(GetDefaultPartitionInfo(cPe) == KErrNone) |
|
1828 |
{ |
|
1829 |
pe = (TMBRPartitionEntry*)(&iIntBuf[0]); |
|
1830 |
||
1831 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("-------------------------------------------")); |
|
1832 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("-- Partition Entry Validation/Comparison --")); |
|
1833 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("-------------------------------------------")); |
|
1834 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("-- iX86BootIndicator [%02x:%02x] %c -", pe->iX86BootIndicator, cPe.iX86BootIndicator, pe->iX86BootIndicator == cPe.iX86BootIndicator ? ' ' : 'X')); |
|
1835 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("-- iStartHead [%02x:%02x] %c -", pe->iStartHead, cPe.iStartHead, pe->iStartHead == cPe.iStartHead ? ' ' : 'X')); |
|
1836 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("-- iStartSector [%02x:%02x] %c -", pe->iStartSector, cPe.iStartSector, pe->iStartSector == cPe.iStartSector ? ' ' : 'X')); |
|
1837 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("-- iStartCylinder [%02x:%02x] %c -", pe->iStartCylinder, cPe.iStartCylinder, pe->iStartCylinder == cPe.iStartCylinder ? ' ' : 'X')); |
|
1838 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("-- iPartitionType [%02x:%02x] %c -", pe->iPartitionType, cPe.iPartitionType, pe->iPartitionType == cPe.iPartitionType ? ' ' : 'X')); |
|
1839 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("-- iEndHead [%02x:%02x] %c -", pe->iEndHead, cPe.iEndHead, pe->iEndHead == cPe.iEndHead ? ' ' : 'X')); |
|
1840 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("-- iEndSector [%02x:%02x] %c -", pe->iEndSector, cPe.iEndSector, pe->iEndSector == cPe.iEndSector ? ' ' : 'X')); |
|
1841 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("-- iEndCylinder [%02x:%02x] %c -", pe->iEndCylinder, cPe.iEndCylinder, pe->iEndCylinder == cPe.iEndCylinder ? ' ' : 'X')); |
|
1842 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("-- iFirstSector [%08x:%08x] %c -", pe->iFirstSector, cPe.iFirstSector, pe->iFirstSector == cPe.iFirstSector ? ' ' : 'X')); |
|
1843 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("-- iNumSectors [%08x:%08x] %c -", pe->iNumSectors, cPe.iNumSectors, pe->iNumSectors == cPe.iNumSectors ? ' ' : 'X')); |
|
1844 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("-------------------------------------------")); |
|
1845 |
} |
|
1846 |
#endif |
|
1847 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1848 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DECODEPARTITIONINFO_EXIT2, this, KErrNone ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1849 |
return KErrNone; |
0 | 1850 |
} |
1851 |
||
1852 |
||
1853 |
TInt DMmcMediaDriverFlash::WritePartitionInfo() |
|
1854 |
/** |
|
1855 |
Write the default partition table to freshly formatted media |
|
1856 |
@return Standard Symbian OS Error Code |
|
1857 |
*/ |
|
1858 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1859 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_WRITEPARTITIONINFO_ENTRY, this ); |
0 | 1860 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:wpi")); |
1861 |
__ASSERT_DEBUG(iSession != NULL, Panic(ECFSessPtrNull)); |
|
1862 |
||
1863 |
TMBRPartitionEntry partitionEntry; |
|
1864 |
TInt err = GetDefaultPartitionInfo(partitionEntry); |
|
1865 |
if(err == KErrNone) |
|
1866 |
{ |
|
1867 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("mmd:MBR/Partition Table")); |
|
1868 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(" Boot ID : %02xh", partitionEntry.iX86BootIndicator)); |
|
1869 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(" Start Head : %02xh", partitionEntry.iStartHead)); |
|
1870 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(" Start Sector : %02xh", partitionEntry.iStartSector)); |
|
1871 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(" Start Cyclinder : %02xh", partitionEntry.iStartCylinder)); |
|
1872 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(" System ID : %02xh", partitionEntry.iPartitionType)); |
|
1873 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(" End Head : %02xh", partitionEntry.iEndHead)); |
|
1874 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(" End Sector : %02xh", partitionEntry.iEndSector)); |
|
1875 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(" End Cyclinder : %02xh", partitionEntry.iEndCylinder)); |
|
1876 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(" Relative Sector : %08xh", partitionEntry.iFirstSector)); |
|
1877 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(" Number of Sectors: %08xh", partitionEntry.iNumSectors)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1878 |
OstTraceExt5(TRACE_MMCDEBUG, DMMCMEDIADRIVERFLASH_WRITEPARTITIONINFO_PARTINFO1, "Boot ID=0x%02x; Start Head=0x%02x; Start Sector=0x%02x; Start Cyclinder=0x%02x; System ID=0x%02x", (TUint) partitionEntry.iX86BootIndicator, (TUint) partitionEntry.iStartHead, (TUint) partitionEntry.iStartSector, (TUint) partitionEntry.iStartCylinder, (TUint) partitionEntry.iPartitionType); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1879 |
OstTraceExt5(TRACE_MMCDEBUG, DMMCMEDIADRIVERFLASH_WRITEPARTITIONINFO_PARTINFO2, "End Head=0x%02x; End Sector=0x%02x; End Cyclinder=0x%02x; Relative Sector=0x%08x; Number of Sectors=0x%08x", (TUint) partitionEntry.iEndHead, (TUint) partitionEntry.iEndSector, (TUint) partitionEntry.iEndCylinder, (TUint) partitionEntry.iFirstSector, (TUint) partitionEntry.iNumSectors); |
0 | 1880 |
// |
1881 |
// Clear all other partition entries and align the partition info into the minor buffer for writing... |
|
1882 |
// |
|
1883 |
memclr(iMinorBuf, KDiskSectorSize); |
|
1884 |
memcpy(&iMinorBuf[KMBRFirstPartitionEntry], &partitionEntry, sizeof(TMBRPartitionEntry)); |
|
1885 |
||
1886 |
*(TUint16*)(&iMinorBuf[KMBRSignatureOffset]) = 0xAA55; |
|
1887 |
||
1888 |
iSession->SetupCIMWriteBlock(0, iMinorBuf); |
|
1889 |
||
1890 |
// |
|
1891 |
// Write the partition table and engage the read to validate and complete the mount process |
|
1892 |
// |
|
1893 |
iMbrMissing = EFalse; |
|
1894 |
iCreateMbr = EFalse; |
|
1895 |
err = EngageAndSetWriteRequest(EMReqUpdatePtnInfo); |
|
1896 |
} |
|
1897 |
||
1898 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:wpi:%d", err)); |
|
1899 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1900 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_WRITEPARTITIONINFO_EXIT, this, err ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1901 |
return err; |
0 | 1902 |
} |
1903 |
||
1904 |
||
1905 |
TInt DMmcMediaDriverFlash::CreateDefaultPartition() |
|
1906 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1907 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_CREATEDEFAULTPARTITION_ENTRY, this ); |
0 | 1908 |
TMBRPartitionEntry defPartition; |
1909 |
TInt r = GetDefaultPartitionInfo(defPartition); |
|
1910 |
if (r == KErrNone) |
|
1911 |
{ |
|
1912 |
SetPartitionEntry(&iPartitionInfo->iEntry[0], defPartition.iFirstSector, defPartition.iNumSectors); |
|
1913 |
iHiddenSectors = defPartition.iFirstSector; |
|
1914 |
iPartitionInfo->iPartitionCount = 1; |
|
1915 |
iPartitionInfo->iMediaSizeInBytes = TotalSizeInBytes(); |
|
1916 |
} |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1917 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_CREATEDEFAULTPARTITION_EXIT, this, r ); |
0 | 1918 |
return r; |
1919 |
} |
|
1920 |
||
1921 |
TInt DMmcMediaDriverFlash::GetDefaultPartitionInfo(TMBRPartitionEntry& aPartitionEntry) |
|
1922 |
/** |
|
1923 |
Calculates the default patition information for an specific card. |
|
1924 |
@param aPartitionEntry The TMBRPartitionEntry to be filled in with the format parameters |
|
1925 |
@return Standard Symbian OS Error Code |
|
1926 |
*/ |
|
1927 |
{ |
|
1928 |
memclr(&aPartitionEntry, sizeof(TMBRPartitionEntry)); |
|
1929 |
TUint16 reservedSectors; // Not used |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1930 |
TInt r = GetMediaDefaultPartitionInfo(aPartitionEntry, reservedSectors, iCard); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1931 |
return r; |
0 | 1932 |
} |
1933 |
||
1934 |
||
1935 |
void DMmcMediaDriverFlash::SetPartitionEntry(TPartitionEntry* aEntry, TUint aFirstSector, TUint aNumSectors) |
|
1936 |
// |
|
1937 |
// auxiliary static function to record partition information in TPartitionEntry object |
|
1938 |
// |
|
1939 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1940 |
OstTraceFunctionEntry0( DMMCMEDIADRIVERFLASH_SETPARTITIONENTRY_ENTRY ); |
0 | 1941 |
aEntry->iPartitionBaseAddr=aFirstSector; |
1942 |
aEntry->iPartitionBaseAddr<<=KDiskSectorShift; |
|
1943 |
aEntry->iPartitionLen=aNumSectors; |
|
1944 |
aEntry->iPartitionLen<<=KDiskSectorShift; |
|
1945 |
aEntry->iPartitionType=KPartitionTypeFAT12; |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1946 |
OstTraceFunctionExit0( DMMCMEDIADRIVERFLASH_SETPARTITIONENTRY_EXIT ); |
0 | 1947 |
} |
1948 |
||
1949 |
TInt DMmcMediaDriverFlash::DoPasswordOp() |
|
1950 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1951 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_DOPASSWORDOP_ENTRY, this ); |
0 | 1952 |
// Reconstruct password data structure in our address space |
1953 |
TLocalDrivePasswordData clientData; |
|
1954 |
TInt r = iCurrentReq->ReadRemoteRaw(&clientData, sizeof(TLocalDrivePasswordData)); |
|
1955 |
||
1956 |
TMediaPassword oldPassword; |
|
1957 |
if (r == KErrNone) |
|
1958 |
r = iCurrentReq->ReadRemote(clientData.iOldPasswd, &oldPassword); |
|
1959 |
||
1960 |
TMediaPassword newPassword; |
|
1961 |
if (r == KErrNone) |
|
1962 |
r = iCurrentReq->ReadRemote(clientData.iNewPasswd, &newPassword); |
|
1963 |
||
1964 |
TLocalDrivePasswordData passData(oldPassword, newPassword, clientData.iStorePasswd); |
|
1965 |
||
1966 |
if (r == KErrNone) |
|
1967 |
{ |
|
1968 |
TInt id=iCurrentReq->Id(); |
|
1969 |
switch (id) |
|
1970 |
{ |
|
1971 |
case DLocalDrive::EPasswordUnlock: |
|
1972 |
r = LaunchRPIUnlock(passData); |
|
1973 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:rpi:%d", r)); |
|
1974 |
break; |
|
1975 |
case DLocalDrive::EPasswordLock: |
|
1976 |
case DLocalDrive::EPasswordClear: |
|
1977 |
PasswordControl(id, passData); |
|
1978 |
break; |
|
1979 |
} |
|
1980 |
} |
|
1981 |
||
1982 |
// This will complete the request in the event of an error |
|
1983 |
if(r != KErrNone) |
|
1984 |
PartitionInfoComplete(r); |
|
1985 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1986 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_DOPASSWORDOP_EXIT, this, KErrNone ); |
0 | 1987 |
return KErrNone; // ensures to indicate asynchronoous completion |
1988 |
} |
|
1989 |
||
1990 |
void DMmcMediaDriverFlash::PasswordControl(TInt aFunc, TLocalDrivePasswordData& aData) |
|
1991 |
// |
|
1992 |
// Change a card's password, or clear the pasword from a locked card. The card |
|
1993 |
// must be unlocked for this function. A locked card is unlocked when it is mounted, |
|
1994 |
// to read the partition information. This is done from ReadPartitionInfo() and |
|
1995 |
// LaunchRPIUnlock(). |
|
1996 |
// |
|
1997 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
1998 |
OstTraceExt2(TRACE_FLOW, DMMCMEDIADRIVERFLASH_PASSWORDCONTROL_ENTRY ,"DMmcMediaDriverFlash::PasswordControl;aFunc=%d;this=%x", aFunc, (TUint) this); |
0 | 1999 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:pc:%d", (TInt) aFunc)); |
2000 |
__ASSERT_DEBUG(CurrentRequest() == EMReqIdle, Panic(EPCInUse)); |
|
2001 |
__ASSERT_DEBUG(aFunc == DLocalDrive::EPasswordLock || aFunc == DLocalDrive::EPasswordClear, Panic(EPCFunc)); |
|
2002 |
__ASSERT_DEBUG(iSession != NULL, Panic(ECFSessPtrNull)); |
|
2003 |
||
2004 |
TInt r; |
|
2005 |
||
2006 |
if ((r = CheckDevice(EMReqTypeChangePswd)) == KErrNone) |
|
2007 |
{ |
|
2008 |
// check if the current password is correct here. (This makes the |
|
2009 |
// clear operation redundant only if the password is stored and it |
|
2010 |
// is wrong.) Complete with same value as DoSessionEndDfc() would. |
|
2011 |
||
2012 |
TMediaPassword curPwd; |
|
2013 |
||
2014 |
curPwd = *aData.iOldPasswd; |
|
2015 |
TInt curPwdLen = curPwd.Length(); |
|
2016 |
TInt blockLen; |
|
2017 |
||
2018 |
if (!(iCard->iFlags & KMMCardIsLockable)) |
|
2019 |
r = KErrNotSupported; |
|
2020 |
else if (Stack().PasswordStore()->IsMappingIncorrect(iCard->CID(), curPwd)) |
|
2021 |
r = KErrAccessDenied; |
|
2022 |
else |
|
2023 |
{ |
|
2024 |
if ((r = Stack().MMCSocket()->PrepareStore(CardNum(), aFunc, aData/*, aThread*/)) == KErrNone) |
|
2025 |
{ |
|
2026 |
switch (aFunc) |
|
2027 |
{ |
|
2028 |
case DLocalDrive::EPasswordLock: |
|
2029 |
{ |
|
2030 |
TMediaPassword newPwd; |
|
2031 |
newPwd = *aData.iNewPasswd; |
|
2032 |
TInt newPwdLen = newPwd.Length(); |
|
2033 |
blockLen = 1 + 1 + curPwdLen + newPwdLen; |
|
2034 |
||
2035 |
#ifndef __EPOC32__ |
|
2036 |
TUint16 env_Var[]=L"_EPOC_PWD_LEN"; |
|
2037 |
TUint16 env_Val[2]; |
|
2038 |
env_Val[0]=(TUint16)(curPwdLen+1); |
|
2039 |
env_Val[1]=0;//make a null terminated string |
|
2040 |
r=SetEnvironmentVariable(env_Var,&env_Val[0]); |
|
2041 |
__ASSERT_DEBUG(r!=0, Panic(EPCFunc)); |
|
2042 |
||
2043 |
#endif |
|
2044 |
||
2045 |
TPtr8 pbuf(&iMinorBuf[0], 2, blockLen); |
|
2046 |
pbuf[0] = KMMCLockUnlockSetPwd; // LOCK_UNLOCK = 0, SET_PWD = 1 |
|
2047 |
pbuf[1] = static_cast<TUint8>(curPwdLen + newPwdLen); |
|
2048 |
pbuf.Append(curPwd); |
|
2049 |
pbuf.Append(newPwd); |
|
2050 |
} |
|
2051 |
break; |
|
2052 |
||
2053 |
case DLocalDrive::EPasswordClear: |
|
2054 |
{ |
|
2055 |
blockLen = 1 + 1 + curPwdLen; |
|
2056 |
||
2057 |
TPtr8 pbuf(&iMinorBuf[0], 2, blockLen); |
|
2058 |
pbuf[0] = KMMCLockUnlockClrPwd; // LOCK_UNLOCK = dc, CLR_PWD = 1 |
|
2059 |
pbuf[1] = static_cast<TUint8>(curPwdLen); |
|
2060 |
pbuf.Append(curPwd); |
|
2061 |
} |
|
2062 |
break; |
|
2063 |
||
2064 |
default: |
|
2065 |
// DLocalDrive::EPasswordUnlock is not handled. This avoids warnings for unused |
|
2066 |
// case, and uninitialized variable. |
|
2067 |
blockLen = 0; |
|
2068 |
break; |
|
2069 |
} // switch (aFunc) |
|
2070 |
||
2071 |
iSession->SetupCIMLockUnlock(blockLen, iMinorBuf); |
|
2072 |
r = EngageAndSetWriteRequest(EMReqPswdCtrl); |
|
2073 |
} // if ((r = Stack().PrepareStore(CardNum(), aFunc, aData, aThread)) == KErrNone) |
|
2074 |
} // else (Stack().IsMappingIncorrect(iCard->CID(), curPwd)) |
|
2075 |
} // (r = CheckDevice(EMReqTypeChangePswd)) == KErrNone |
|
2076 |
||
2077 |
// complete immediately if error occured |
|
2078 |
if (r != KErrNone) |
|
2079 |
CompleteRequest(r); |
|
2080 |
||
2081 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:pc:%d", r)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2082 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_PASSWORDCONTROL_EXIT, this ); |
0 | 2083 |
} |
2084 |
||
2085 |
||
2086 |
// ---- device status, callback DFC ---- |
|
2087 |
||
2088 |
TInt DMmcMediaDriverFlash::CheckDevice(TMediaReqType aReqType) |
|
2089 |
// |
|
2090 |
// Check the device before initiating a command |
|
2091 |
// |
|
2092 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2093 |
OstTraceExt2(TRACE_FLOW, DMMCMEDIADRIVERFLASH_CHECKDEVICE_ENTRY, "DMmcMediaDriverFlash::CheckDevice;aReqType=%d;this=%x", (TInt) aReqType, (TUint) this); |
0 | 2094 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:cd:%d",aReqType)); |
2095 |
||
2096 |
TInt r=KErrNone; |
|
2097 |
||
2098 |
if (!iCard->IsReady()) |
|
2099 |
r=KErrNotReady; |
|
2100 |
||
2101 |
// The card must be locked if attempting to unlock during RPI, and |
|
2102 |
// unlocked at all other times. |
|
2103 |
else if (aReqType!=EMReqTypeUnlockPswd && iCard->IsLocked()) |
|
2104 |
r=KErrLocked; |
|
2105 |
// Don't perform Password setting for WriteProtected cards, |
|
2106 |
// unable to recover (ForcedErase) if password lost. |
|
2107 |
else if (aReqType==EMReqTypeChangePswd) |
|
2108 |
{ |
|
2109 |
if (iCard->MediaType()==EMultiMediaROM) |
|
2110 |
{ |
|
2111 |
r=KErrAccessDenied; |
|
2112 |
} |
|
2113 |
} |
|
2114 |
else if (iMbrMissing && aReqType==EMReqTypeNormalRd) |
|
2115 |
r=KErrCorrupt; |
|
2116 |
||
2117 |
#if !defined(__WINS__) |
|
2118 |
// Don't perform write/password operations when the battery is low |
|
2119 |
// else if (aReqType!=EMReqTypeNormalRd && Hal::MainBatteryStatus()<ELow && !Hal::ExternalPowerPresent()) |
|
2120 |
// r=KErrBadPower; |
|
2121 |
#endif |
|
2122 |
// Don't perform write operations when the mechanical write protect switch is set |
|
2123 |
else if (aReqType==EMReqTypeNormalWr && iCard->IsWriteProtected()) |
|
2124 |
r=KErrAccessDenied; |
|
2125 |
// Don't perform write/format operations on MMC ROM cards |
|
2126 |
else if (iMediaType==EMultiMediaROM && aReqType == EMReqTypeNormalWr) |
|
2127 |
r=KErrAccessDenied; |
|
2128 |
||
2129 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:cd:%d", r)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2130 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_CHECKDEVICE_EXIT, this, r ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2131 |
return r; |
0 | 2132 |
} |
2133 |
||
2134 |
void DMmcMediaDriverFlash::SessionEndCallBack(TAny* aMediaDriver) |
|
2135 |
// |
|
2136 |
// called by EPBUS when a single session has finished. Queues DFC to launch |
|
2137 |
// next session or to complete client request. |
|
2138 |
// |
|
2139 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2140 |
OstTraceFunctionEntry0( DMMCMEDIADRIVERFLASH_SESSIONENDCALLBACK_ENTRY ); |
0 | 2141 |
DMmcMediaDriverFlash& md = *static_cast<DMmcMediaDriverFlash*>(aMediaDriver); |
2142 |
__ASSERT_DEBUG(! md.iSessionEndDfc.Queued(), Panic(ESECBQueued)); |
|
2143 |
md.iSessionEndDfc.Enque(); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2144 |
OstTraceFunctionExit0( DMMCMEDIADRIVERFLASH_SESSIONENDCALLBACK_EXIT ); |
0 | 2145 |
} |
2146 |
||
2147 |
||
2148 |
void DMmcMediaDriverFlash::SessionEndDfc(TAny* aMediaDriver) |
|
2149 |
{ |
|
2150 |
static_cast<DMmcMediaDriverFlash*>(aMediaDriver)->DoSessionEndDfc(); |
|
2151 |
} |
|
2152 |
||
2153 |
||
2154 |
void DMmcMediaDriverFlash::DoSessionEndDfc() |
|
2155 |
// |
|
2156 |
// launch next session or complete client request |
|
2157 |
// |
|
2158 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2159 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_DOSESSIONENDDFC_ENTRY, this ); |
0 | 2160 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:dsed:%d", CurrentRequest())); |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2161 |
OstTrace1( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DOSESSIONENDDFC_REQUEST, "Current Request=%d", CurrentRequest()); |
0 | 2162 |
|
2163 |
TInt r=KErrNone; |
|
2164 |
||
2165 |
EndInCritical(); |
|
2166 |
||
2167 |
// Abort if writing or formatting and power has gone down |
|
2168 |
if (!Kern::PowerGood() && CurrentRequest()!=EMReqRead) |
|
2169 |
r=KErrAbort; |
|
2170 |
// Return KErrNotReady if we have has a deferred media change |
|
2171 |
if (!iCard->IsReady()) |
|
2172 |
r=KErrNotReady; |
|
2173 |
// if stack has powered down session pointer will be NULL |
|
2174 |
if (iSession == NULL) |
|
2175 |
r = KErrNotReady; |
|
2176 |
||
2177 |
TBool complete = ETrue; |
|
2178 |
||
2179 |
if (r==KErrNone) |
|
2180 |
{ |
|
2181 |
r = iSession->EpocErrorCode(); |
|
2182 |
||
2183 |
switch (CurrentRequest()) |
|
2184 |
{ |
|
2185 |
case EMReqRead: |
|
2186 |
{ |
|
2187 |
if (r != KErrNone) // abort if MMC error |
|
2188 |
break; |
|
2189 |
||
2190 |
if(iDoDoubleBuffer) |
|
2191 |
{ |
|
2192 |
// |
|
2193 |
// This is the end of a double-buffered transfer. |
|
2194 |
// - Now we have two buffers to copy back to the user... |
|
2195 |
// |
|
2196 |
TUint8* bufPtr = iIntBuf + (iSecondBuffer ? (iMaxBufSize >> 1) : 0); |
|
2197 |
if((r = WriteDataToUser(bufPtr)) == KErrNone) |
|
2198 |
{ |
|
2199 |
MarkBlocks(iReqCur, iPhysEnd, CchMemToIdx(bufPtr)); |
|
2200 |
||
2201 |
iReqCur = iPhysEnd; |
|
2202 |
iPhysEnd = iDbEnd; |
|
2203 |
||
2204 |
bufPtr = iIntBuf + (iSecondBuffer ? 0 : (iMaxBufSize >> 1)); |
|
2205 |
if((r = WriteDataToUser(bufPtr)) == KErrNone) |
|
2206 |
{ |
|
2207 |
MarkBlocks(iReqCur, (iPhysEnd + iBlkMsk) & ~iBlkMsk, CchMemToIdx(bufPtr)); |
|
2208 |
} |
|
2209 |
} |
|
2210 |
iDoDoubleBuffer = EFalse; |
|
2211 |
} |
|
2212 |
else if (iDoPhysicalAddress) |
|
2213 |
{ |
|
2214 |
if (iRdROB & KIPCWrite) |
|
2215 |
{ |
|
2216 |
// partial end point |
|
2217 |
TInt len = I64LOW(iReqEnd & iBlkMsk); |
|
2218 |
const TInt ofset = I64LOW(iPhysEnd - iBlkLen - iReqStart); |
|
2219 |
||
2220 |
TPtrC8 extrView(iIntBuf, len); |
|
2221 |
r = iCurrentReq->WriteRemote(&extrView,ofset); |
|
2222 |
} |
|
2223 |
// Reset attributes |
|
2224 |
iRdROB = 0; |
|
2225 |
iFragOfset = iIPCLen = iBufOfset = 0; |
|
2226 |
iReqCur = iPhysEnd = iReqEnd; |
|
2227 |
iDoPhysicalAddress = EFalse; |
|
2228 |
} |
|
2229 |
else |
|
2230 |
{ |
|
2231 |
r = WriteDataToUser(&iIntBuf[I64LOW(iReqCur - iPhysStart)]); |
|
2232 |
} |
|
2233 |
||
2234 |
if (r != KErrNone) |
|
2235 |
break; |
|
2236 |
||
2237 |
// if there is more information to read for the user then engage another session |
|
2238 |
if ((iReqCur = iPhysEnd) < iReqEnd) |
|
2239 |
{ |
|
2240 |
TBool allDone = EFalse; |
|
2241 |
if ( ((r = ReadDataUntilCacheExhausted(&allDone)) == KErrNone) && !allDone) |
|
2242 |
{ |
|
2243 |
iPhysStart = iReqCur & ~iBlkMsk; |
|
2244 |
TUint32 length = I64LOW(iReqEnd - iReqCur); |
|
2245 |
||
2246 |
if ( (iReqEnd - iPhysStart) > iMaxBufSize && iSocket->SupportsDoubleBuffering() && !iReadToEndOfCard) |
|
2247 |
r = LaunchDBRead(); |
|
2248 |
else |
|
2249 |
r = LaunchRead(iReqCur, length); |
|
2250 |
||
2251 |
if ( r == KErrNone) |
|
2252 |
complete = EFalse; |
|
2253 |
} |
|
2254 |
} |
|
2255 |
} |
|
2256 |
break; |
|
2257 |
||
2258 |
case EMReqWrite: |
|
2259 |
{ |
|
2260 |
if (r != KErrNone) // abort if MMC error |
|
2261 |
{ |
|
2262 |
break; |
|
2263 |
} |
|
2264 |
||
2265 |
if (iWtRBM == 0) |
|
2266 |
{ |
|
2267 |
iReqCur = iPhysEnd; |
|
2268 |
iDoDoubleBuffer = EFalse; |
|
2269 |
iDoPhysicalAddress = EFalse; |
|
2270 |
iRdROB = 0; |
|
2271 |
iFragOfset = iIPCLen = iBufOfset = 0; |
|
2272 |
} |
|
2273 |
// clear current RBM flag |
|
2274 |
else |
|
2275 |
{ |
|
2276 |
if (iWtRBM & KWtRBMFst) |
|
2277 |
{ |
|
2278 |
iWtRBM &= ~KWtRBMFst; |
|
2279 |
} |
|
2280 |
else if (iWtRBM & KWtRBMLst) |
|
2281 |
{ |
|
2282 |
iWtRBM &= ~KWtRBMLst; |
|
2283 |
} |
|
2284 |
} |
|
2285 |
||
2286 |
// advance media position if just finished write, as opposed to read-before-modify |
|
2287 |
if (iReqCur < iReqEnd) |
|
2288 |
{ |
|
2289 |
if ((r = LaunchWrite(iReqCur, I64LOW(iReqEnd - iReqCur), EMReqWrite)) == KErrNone) |
|
2290 |
{ |
|
2291 |
complete = EFalse; |
|
2292 |
} |
|
2293 |
||
2294 |
complete = (r != KErrNone) ? (TBool)ETrue : (TBool)EFalse; |
|
2295 |
} |
|
2296 |
} |
|
2297 |
break; |
|
2298 |
||
2299 |
case EMReqFormat: |
|
2300 |
{ |
|
2301 |
if (r != KErrNone) // abort if MMC error |
|
2302 |
break; |
|
2303 |
||
2304 |
if ((iEraseUnitMsk == KMaxTUint64) || // no erase unit defined (Erase Class Commands not supported) ? |
|
2305 |
(iPhysEnd == iReqEnd) || // finshed already ? |
|
2306 |
((iPhysStart & iEraseUnitMsk) == 0 && (iPhysEnd & iEraseUnitMsk) == 0)) |
|
2307 |
{ |
|
2308 |
iReqCur = iPhysEnd; |
|
2309 |
} |
|
2310 |
else |
|
2311 |
{ |
|
2312 |
// 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 |
|
2314 |
// boundary, and return the adjustment info to the file system |
|
2315 |
r = I64LOW(iPhysEnd - iPhysStart); |
|
2316 |
iReqCur = iReqEnd; |
|
2317 |
} |
|
2318 |
||
2319 |
if(r == KErrNone) |
|
2320 |
{ |
|
2321 |
// advance media position if just finished write, as opposed to read-before-modify |
|
2322 |
if (iReqCur < iReqEnd) |
|
2323 |
{ |
|
2324 |
if ((r = LaunchFormat(iReqCur, I64LOW(iReqEnd - iReqCur))) == KErrNone) |
|
2325 |
{ |
|
2326 |
complete = EFalse; |
|
2327 |
} |
|
2328 |
} |
|
2329 |
// if format finished, write an MBR if required |
|
2330 |
// Always write an MBR if it's an SD card |
|
2331 |
else if (iCreateMbr) |
|
2332 |
{ |
|
2333 |
// Finished Format, so write the MBR/default partition table if required |
|
2334 |
r = WritePartitionInfo(); |
|
2335 |
complete = (r != KErrNone) ? (TBool)ETrue : (TBool)EFalse; |
|
2336 |
} |
|
2337 |
} |
|
2338 |
} |
|
2339 |
break; |
|
2340 |
||
2341 |
case EMReqPtnInfo: |
|
2342 |
if (r == KErrNone) |
|
2343 |
r = DecodePartitionInfo(); // set up iPartitionInfo |
|
2344 |
||
2345 |
PartitionInfoComplete(r == KErrNone?KErrNone:KErrNotReady); |
|
2346 |
break; |
|
2347 |
||
2348 |
case EMReqEMMCPtnInfo: |
|
2349 |
iMedReq = EMReqIdle; |
|
2350 |
// For now do nothing.. |
|
2351 |
break; |
|
2352 |
||
2353 |
case EMReqUpdatePtnInfo: |
|
2354 |
break; |
|
2355 |
||
2356 |
case EMReqPswdCtrl: |
|
2357 |
if (r == KErrLocked) |
|
2358 |
r = KErrAccessDenied; |
|
2359 |
break; |
|
2360 |
||
2361 |
case EMReqForceErase: |
|
2362 |
||
2363 |
if (r == KErrNone) |
|
2364 |
{ |
|
2365 |
// Finished Forced Erase , so write the default partition table... |
|
2366 |
r = WritePartitionInfo(); |
|
2367 |
} |
|
2368 |
||
2369 |
complete = (r != KErrNone) ? (TBool)ETrue : (TBool)EFalse; |
|
2370 |
break; |
|
2371 |
||
2372 |
case EMReqWritePasswordData: |
|
2373 |
// |
|
2374 |
// WritePasswordData also kicks off an auto-unlock session to ensure that |
|
2375 |
// any locked cards that have passwords in the password store are immediately |
|
2376 |
// available. We can safely ignore any errors returned at this stage, as the |
|
2377 |
// password store will have been successfully updated (in locmedia.cpp), even |
|
2378 |
// if the card is unable to accept the password. |
|
2379 |
// |
|
2380 |
r = KErrNone; |
|
2381 |
break; |
|
2382 |
||
2383 |
case EMReqIdle: |
|
2384 |
// request has been completed already (e.g. due to a power down) |
|
2385 |
break; |
|
2386 |
||
2387 |
||
2388 |
default: |
|
2389 |
__ASSERT_DEBUG(EFalse, Panic(EDSEDRequest)); |
|
2390 |
break; |
|
2391 |
} |
|
2392 |
} |
|
2393 |
||
2394 |
// r != KErrNone => complete |
|
2395 |
__ASSERT_DEBUG(!(r != KErrNone) || complete, Panic(EDSEDNotErrComplete)); |
|
2396 |
||
2397 |
if (complete) |
|
2398 |
{ |
|
2399 |
if (r != KErrNone) |
|
2400 |
InvalidateCache(); |
|
2401 |
||
2402 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mdf:dsed:cmp:%d", r)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2403 |
OstTrace1( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DOSESSIONENDDFC_COMPLETE, "Complete request; retval=%d", r); |
0 | 2404 |
CompleteRequest(r); |
2405 |
} |
|
2406 |
else |
|
2407 |
{ |
|
2408 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mdf:dsed:ncmp")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2409 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_DOSESSIONENDDFC_NOT_COMPLETE, "Request not complete"); |
0 | 2410 |
} |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2411 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_DOSESSIONENDDFC_EXIT, this ); |
0 | 2412 |
} |
2413 |
||
2414 |
void DMmcMediaDriverFlash::DataTransferCallBack(TAny* aMediaDriver) |
|
2415 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2416 |
OstTraceFunctionEntry0( DMMCMEDIADRIVERFLASH_DATATRANSFERCALLBACK_ENTRY ); |
0 | 2417 |
DMmcMediaDriverFlash& md = *static_cast<DMmcMediaDriverFlash*>(aMediaDriver); |
2418 |
__ASSERT_DEBUG(! md.iDataTransferCallBackDfc.Queued(), Panic(EDBCBQueued)); |
|
2419 |
md.iDataTransferCallBackDfc.Enque(); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2420 |
OstTraceFunctionExit0( DMMCMEDIADRIVERFLASH_DATATRANSFERCALLBACK_EXIT ); |
0 | 2421 |
} |
2422 |
||
2423 |
void DMmcMediaDriverFlash::DataTransferCallBackDfc(TAny* aMediaDriver) |
|
2424 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2425 |
OstTraceFunctionEntry0( DMMCMEDIADRIVERFLASH_DATATRANSFERCALLBACKDFC_ENTRY ); |
0 | 2426 |
DMmcMediaDriverFlash& md = *static_cast<DMmcMediaDriverFlash*>(aMediaDriver); |
2427 |
||
2428 |
if (md.iDoPhysicalAddress) |
|
2429 |
{ |
|
2430 |
if(md.CurrentRequest() == EMReqWrite) |
|
2431 |
{ |
|
2432 |
md.DoPhysWriteDataTransferCallBack(); |
|
2433 |
} |
|
2434 |
else |
|
2435 |
{ |
|
2436 |
md.DoPhysReadDataTransferCallBack(); |
|
2437 |
} |
|
2438 |
} |
|
2439 |
else |
|
2440 |
{ |
|
2441 |
if(md.CurrentRequest() == EMReqWrite) |
|
2442 |
{ |
|
2443 |
md.DoWriteDataTransferCallBack(); |
|
2444 |
} |
|
2445 |
else |
|
2446 |
{ |
|
2447 |
md.DoReadDataTransferCallBack(); |
|
2448 |
} |
|
2449 |
} |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2450 |
OstTraceFunctionExit0( DMMCMEDIADRIVERFLASH_DATATRANSFERCALLBACKDFC_EXIT ); |
0 | 2451 |
} |
2452 |
||
2453 |
void DMmcMediaDriverFlash::DoPhysWriteDataTransferCallBack() |
|
2454 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2455 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_DOPHYSWRITEDATATRANSFERCALLBACK_ENTRY, this ); |
0 | 2456 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("++DMmcMediaDriverFlash::DoPhysWriteDataTransferCallBack()")); |
2457 |
||
2458 |
TInt err = KErrNone; |
|
2459 |
||
2460 |
if ( (iRdROB & KIPCSetup) || ((iReqEnd - iPhysEnd) < iBlkLen) ) |
|
2461 |
{ |
|
2462 |
//IPC to be setup, or partial end block read |
|
2463 |
iRdROB &= ~KIPCSetup; |
|
2464 |
||
2465 |
if ((iReqEnd - iPhysEnd) < iBlkLen) |
|
2466 |
{ |
|
2467 |
iIntBuf = iCacheBuf; |
|
2468 |
} |
|
2469 |
else |
|
2470 |
{ |
|
2471 |
TPtr8 tgt(iMinorBuf, iBlkLen); |
|
2472 |
err = ReadDataFromUser(tgt, I64LOW(iPhysEnd-iReqStart)); |
|
2473 |
iIntBuf = iMinorBuf; |
|
2474 |
} |
|
2475 |
||
2476 |
iReqCur = iPhysEnd; |
|
2477 |
iPhysEnd += iBlkLen; |
|
2478 |
iBufOfset = 0; |
|
2479 |
iIPCLen = iBlkLen; |
|
2480 |
||
2481 |
#if !defined(__WINS__) |
|
2482 |
iSession->MoreDataAvailable( (TInt)(iBlkLen >> KDiskSectorShift), (TUint8*)Epoc::LinearToPhysical((TLinAddr) iIntBuf), err); |
|
2483 |
#else |
|
2484 |
iSession->MoreDataAvailable( (TInt)(iBlkLen >> KDiskSectorShift), iIntBuf, err); |
|
2485 |
#endif |
|
2486 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("--iDoPhysicalAddress(KIPCSetup)")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2487 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_DOPHYSWRITEDATATRANSFERCALLBACK_EXIT1, this ); |
0 | 2488 |
return; |
2489 |
} |
|
2490 |
||
2491 |
PrepareNextPhysicalFragment(); |
|
2492 |
||
2493 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("--DMmcMediaDriverFlash::DoPhysWriteDataTransferCallBack()")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2494 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_DOPHYSWRITEDATATRANSFERCALLBACK_EXIT2, this ); |
0 | 2495 |
} |
2496 |
||
2497 |
||
2498 |
void DMmcMediaDriverFlash::DoPhysReadDataTransferCallBack() |
|
2499 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2500 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_DOPHYSREADDATATRANSFERCALLBACK_ENTRY, this ); |
0 | 2501 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("++DMmcMediaDriverFlash::DoPhysReadTransferCallBack()")); |
2502 |
||
2503 |
TInt err = KErrNone; |
|
2504 |
||
2505 |
if ((iRdROB & KIPCWrite) && !iSecondBuffer) |
|
2506 |
{ |
|
2507 |
// an IPC transfer completed |
|
2508 |
iRdROB &= ~KIPCWrite; |
|
2509 |
if(iNxtIPCLen) |
|
2510 |
{ |
|
2511 |
// First transfer is an IPC, |
|
2512 |
// Corner-case - transfer is most likely IPC-DMA-IPC, |
|
2513 |
// because write cannot occur until after the first 2 iterations it is possible to arrive here with both IPCSetup & IPCWrite Set. |
|
2514 |
// need to use iIPCNxtLen instead |
|
2515 |
TPtrC8 extrView(&iIntBuf[iBufOfset], iNxtIPCLen); |
|
2516 |
err = iCurrentReq->WriteRemote(&extrView,I64LOW(iReqCur - iReqStart)); |
|
2517 |
iNxtIPCLen = iBufOfset = 0; |
|
2518 |
} |
|
2519 |
else |
|
2520 |
{ |
|
2521 |
TPtrC8 extrView(&iIntBuf[iBufOfset], iIPCLen); |
|
2522 |
err = iCurrentReq->WriteRemote(&extrView,I64LOW(iReqCur - iReqStart)); |
|
2523 |
iIPCLen = iBufOfset = 0; |
|
2524 |
} |
|
2525 |
} |
|
2526 |
||
2527 |
if ( (iRdROB & KIPCSetup) || ((iReqEnd - iPhysEnd) < iBlkLen) ) |
|
2528 |
{ |
|
2529 |
// IPC to be setup, or partial end block read. |
|
2530 |
iRdROB &= ~KIPCSetup; |
|
2531 |
iRdROB |= KIPCWrite; |
|
2532 |
||
2533 |
iIntBuf = ReserveReadBlocks(iPhysEnd,(iPhysEnd+iBlkLen), &iIPCLen); |
|
2534 |
||
2535 |
iReqCur = iPhysEnd; |
|
2536 |
iPhysEnd += iIPCLen; |
|
2537 |
iBufOfset = 0; |
|
2538 |
#if !defined(__WINS__) |
|
2539 |
iSession->MoreDataAvailable( (TInt)(iIPCLen >> KDiskSectorShift), (TUint8*)Epoc::LinearToPhysical((TLinAddr) iIntBuf), err); |
|
2540 |
#else |
|
2541 |
iSession->MoreDataAvailable( (TInt)(iIPCLen >> KDiskSectorShift), iIntBuf, err); |
|
2542 |
#endif |
|
2543 |
iSecondBuffer = ETrue; |
|
2544 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("--iDoPhysicalAddress(KIPCWrite)")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2545 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_DOPHYSREADDATATRANSFERCALLBACK_EXIT1, this ); |
0 | 2546 |
return; |
2547 |
} |
|
2548 |
||
2549 |
PrepareNextPhysicalFragment(); |
|
2550 |
||
2551 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("--DMmcMediaDriverFlash::DoPhysReadTransferCallBack()")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2552 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_DOPHYSREADDATATRANSFERCALLBACK_EXIT2, this ); |
0 | 2553 |
} |
2554 |
||
2555 |
void DMmcMediaDriverFlash::DoWriteDataTransferCallBack() |
|
2556 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2557 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_DOWRITEDATATRANSFERCALLBACK_ENTRY, this ); |
0 | 2558 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("++DMmcMediaDriverFlash::DoWriteDataTransferCallBack()")); |
2559 |
||
2560 |
TInt err = KErrNone; |
|
2561 |
||
2562 |
// Advance current request progress... |
|
2563 |
iReqCur = iPhysEnd; |
|
2564 |
||
2565 |
const TUint32 doubleBufferSize = iMaxBufSize >> 1; |
|
2566 |
||
2567 |
TInt64 length = iDbEnd - iReqCur; |
|
2568 |
TInt64 medEnd = UMin(iReqCur + doubleBufferSize, iReqCur + length); |
|
2569 |
||
2570 |
iPhysEnd = (medEnd + iBlkMsk) & ~iBlkMsk; |
|
2571 |
TInt64 len = UMin(iDbEnd, iPhysEnd) - iReqCur; |
|
2572 |
||
2573 |
if(len > doubleBufferSize) |
|
2574 |
{ |
|
2575 |
// Adjust for maximum size of double-buffering |
|
2576 |
len = doubleBufferSize; |
|
2577 |
} |
|
2578 |
||
2579 |
__ASSERT_DEBUG(len > 0, Panic(EDBLength)); |
|
2580 |
__ASSERT_DEBUG(I64HIGH((len + (KDiskSectorSize-1)) >> KDiskSectorShift) == 0, Panic(EDBLengthTooBig)); |
|
2581 |
||
2582 |
TUint32 numBlocks = I64LOW((len + (KDiskSectorSize-1)) >> KDiskSectorShift); |
|
2583 |
||
2584 |
const TInt64 usrOfst = (iReqCur - iReqStart); |
|
2585 |
||
2586 |
__ASSERT_DEBUG(I64HIGH(usrOfst) == 0, Panic(EDBOffsetTooBig)); |
|
2587 |
||
2588 |
// Setup the next buffer pointer and switch buffers... |
|
2589 |
TUint8* bufPtr = iIntBuf + (iSecondBuffer ? doubleBufferSize : 0); |
|
2590 |
TPtr8 tgt(bufPtr, I64LOW(len)); |
|
2591 |
iSecondBuffer = iSecondBuffer ? (TBool)EFalse : (TBool)ETrue; |
|
2592 |
||
2593 |
if(iDoLastRMW && length < doubleBufferSize) |
|
2594 |
{ |
|
2595 |
// |
|
2596 |
// This is the last transfer, and RMW is required. The result of the read exists |
|
2597 |
// in iMinorBuf, so copy the non-modified section of the block to the active buffer. |
|
2598 |
// |
|
2599 |
memcpy(&bufPtr[(numBlocks-1) << KDiskSectorShift], iMinorBuf, KDiskSectorSize); |
|
2600 |
} |
|
2601 |
||
2602 |
if(I64LOW(iDbEnd - iReqCur) <= iMaxBufSize) |
|
2603 |
{ |
|
2604 |
// |
|
2605 |
// This is the last transfer (with or without RMW) |
|
2606 |
// - Mark the last blocks as active in the buffer cache. |
|
2607 |
// |
|
2608 |
MarkBlocks(iReqCur, iPhysEnd, CchMemToIdx(bufPtr)); |
|
2609 |
} |
|
2610 |
||
2611 |
// |
|
2612 |
// Read the requested data from the remote thread... |
|
2613 |
// |
|
2614 |
err = ReadDataFromUser(tgt, I64LOW(usrOfst)); |
|
2615 |
||
2616 |
// |
|
2617 |
// ...and signal that data is available to the PSL. |
|
2618 |
// |
|
2619 |
iSession->MoreDataAvailable(numBlocks, bufPtr, err); |
|
2620 |
||
2621 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("--DMmcMediaDriverFlash::DoWriteDataTransferCallBack()")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2622 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_DOWRITEDATATRANSFERCALLBACK_EXIT, this ); |
0 | 2623 |
} |
2624 |
||
2625 |
||
2626 |
void DMmcMediaDriverFlash::DoReadDataTransferCallBack() |
|
2627 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2628 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_DOREADDATATRANSFERCALLBACK_ENTRY, this ); |
0 | 2629 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("++DMmcMediaDriverFlash::DoReadTransferCallBack()")); |
2630 |
||
2631 |
TInt err = KErrNone; |
|
2632 |
||
2633 |
const TUint32 doubleBufferSize = iMaxBufSize >> 1; |
|
2634 |
||
2635 |
TUint32 bufOfst = 0; |
|
2636 |
||
2637 |
if((iReqCur & ~iBlkMsk) == iPhysStart) |
|
2638 |
{ |
|
2639 |
if(iSecondBuffer) |
|
2640 |
{ |
|
2641 |
// |
|
2642 |
// If this is the first callback, don't copy data as it's not available yet |
|
2643 |
// - just drop through to set up the next buffer. |
|
2644 |
// |
|
2645 |
TUint32 numBlocks = I64LOW((doubleBufferSize + (KDiskSectorSize-1)) >> KDiskSectorShift); |
|
2646 |
TUint8* bufPtr = iIntBuf + doubleBufferSize; |
|
2647 |
||
2648 |
iSecondBuffer = EFalse; |
|
2649 |
||
2650 |
iSession->MoreDataAvailable(numBlocks, bufPtr, KErrNone); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2651 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_DOREADDATATRANSFERCALLBACK_EXIT1, this ); |
0 | 2652 |
return; |
2653 |
} |
|
2654 |
else |
|
2655 |
{ |
|
2656 |
// |
|
2657 |
// If this is the second callback we're ready to copy |
|
2658 |
// back to the client - data may be mis-aligned in the first |
|
2659 |
// instance, but all subsequent data will be aligned... |
|
2660 |
// |
|
2661 |
bufOfst = I64LOW(iReqCur - iPhysStart); |
|
2662 |
} |
|
2663 |
} |
|
2664 |
||
2665 |
// ...otherwise, write the previous buffer contents to the user |
|
2666 |
TUint8* bufPtr = iIntBuf + (iSecondBuffer ? doubleBufferSize : 0); |
|
2667 |
||
2668 |
err = WriteDataToUser(bufPtr + bufOfst); |
|
2669 |
||
2670 |
// Advance current request progress... |
|
2671 |
iReqCur = iPhysEnd; |
|
2672 |
||
2673 |
TInt64 medEnd = UMin(iReqCur + doubleBufferSize, iDbEnd); |
|
2674 |
||
2675 |
iPhysEnd = (medEnd + iBlkMsk) & ~iBlkMsk; |
|
2676 |
||
2677 |
// Current buffer is one step ahead of the current request progress... |
|
2678 |
TInt64 len = UMin((iDbEnd - iPhysEnd + iBlkMsk) & ~iBlkMsk, TInt64(doubleBufferSize)); |
|
2679 |
||
2680 |
__ASSERT_DEBUG(len == 0 || (I64HIGH((len + (KDiskSectorSize-1)) >> KDiskSectorShift) == 0), Panic(EDBLengthTooBig)); |
|
2681 |
||
2682 |
TUint32 numBlocks = I64LOW((len + (KDiskSectorSize-1)) >> KDiskSectorShift); |
|
2683 |
||
2684 |
// |
|
2685 |
// ...switch buffers and signal that data is available to the PSL. |
|
2686 |
// |
|
2687 |
iSecondBuffer = iSecondBuffer ? (TBool)EFalse : (TBool)ETrue; |
|
2688 |
||
2689 |
iSession->MoreDataAvailable(numBlocks, bufPtr, err); |
|
2690 |
||
2691 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("--DMmcMediaDriverFlash::DoDataTransferCallBack()")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2692 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_DOREADDATATRANSFERCALLBACK_EXIT2, this ); |
0 | 2693 |
} |
2694 |
||
2695 |
||
2696 |
// ---- request management ---- |
|
2697 |
||
2698 |
||
2699 |
TInt DMmcMediaDriverFlash::EngageAndSetReadRequest(DMmcMediaDriverFlash::TMediaRequest aRequest) |
|
2700 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2701 |
OstTraceExt2(TRACE_FLOW, DMMCMEDIADRIVERFLASH_ENGAGEANDSETREADREQUEST_ENTRY, "DMmcMediaDriverFlash::EngageAndSetReadRequest;aRequest=%d;this=%x", (TInt) aRequest, (TUint) this); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2702 |
TInt r = EngageAndSetRequest(aRequest, iReadCurrentInMilliAmps); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2703 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_ENGAGEANDSETREADREQUEST_EXIT, this, r ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2704 |
return r; |
0 | 2705 |
} |
2706 |
||
2707 |
||
2708 |
TInt DMmcMediaDriverFlash::EngageAndSetWriteRequest(DMmcMediaDriverFlash::TMediaRequest aRequest) |
|
2709 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2710 |
OstTraceExt2(TRACE_FLOW, DMMCMEDIADRIVERFLASH_ENGAGEANDSETWRITEREQUEST_ENTRY, "DMmcMediaDriverFlash::EngageAndSetReadRequest;aRequest=%d;this=%x", (TInt) aRequest, (TUint) this); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2711 |
TInt r = EngageAndSetRequest(aRequest, iWriteCurrentInMilliAmps); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2712 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_ENGAGEANDSETWRITEREQUEST_EXIT, this, r ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2713 |
return r; |
0 | 2714 |
} |
2715 |
||
2716 |
||
2717 |
TInt DMmcMediaDriverFlash::EngageAndSetRequest(DMmcMediaDriverFlash::TMediaRequest aRequest, TInt aCurrent) |
|
2718 |
// |
|
2719 |
// In WINS, all of the processing, including the callbacks, is done when Engage() is called, |
|
2720 |
// so the request value must be set up in advanced. Both the request and the current are |
|
2721 |
// cleared in the corresponding call to CompleteRequest(). |
|
2722 |
// |
|
2723 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2724 |
OstTraceExt3(TRACE_FLOW, DMMCMEDIADRIVERFLASH_ENGAGEANDSETREQUEST_ENTRY, "DMmcMediaDriverFlash::EngageAndSetRequest;aRequest=%d;aCurrent=%d;this=%x", (TInt) aRequest, aCurrent, (TUint) this); |
0 | 2725 |
__ASSERT_DEBUG(iSession != NULL, Panic(ECFSessPtrNull)); |
2726 |
||
2727 |
iMedReq = aRequest; |
|
2728 |
SetCurrentConsumption(aCurrent); |
|
2729 |
||
244 | 2730 |
// Reset the card pointer just in case the stack has changed it. |
2731 |
iSession->SetCard(iCard); |
|
2732 |
||
0 | 2733 |
TInt r = InCritical(); |
2734 |
if (r == KErrNone) |
|
2735 |
{ |
|
2736 |
r = iSession->Engage(); |
|
2737 |
} |
|
2738 |
||
2739 |
if(r != KErrNone) |
|
2740 |
{ |
|
2741 |
if (!Kern::PowerGood()) |
|
2742 |
r=KErrAbort; // If emergency power down - return abort rather than anything else. |
|
2743 |
if (!iCard->IsReady()) |
|
2744 |
r=KErrNotReady; // If media change - return not ready rather than anything else. |
|
2745 |
EndInCritical(); |
|
2746 |
} |
|
2747 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2748 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_ENGAGEANDSETREQUEST_EXIT, this, r ); |
0 | 2749 |
return r; |
2750 |
} |
|
2751 |
||
2752 |
||
2753 |
void DMmcMediaDriverFlash::CompleteRequest(TInt aReason) |
|
2754 |
// |
|
2755 |
// completes the specified request |
|
2756 |
// |
|
2757 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2758 |
OstTraceFunctionEntryExt( DMMCMEDIADRIVERFLASH_COMPLETEREQUEST_ENTRY, this ); |
0 | 2759 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("=mmd:cr0x%08x,%d", iCurrentReq, aReason)); |
2760 |
||
2761 |
iMedReq = EMReqIdle; |
|
2762 |
SetCurrentConsumption(KIdleCurrentInMilliAmps); |
|
2763 |
||
2764 |
TLocDrvRequest* pR=iCurrentReq; |
|
2765 |
if (pR) |
|
2766 |
{ |
|
2767 |
#ifdef __DEMAND_PAGING__ |
|
2768 |
#if defined(__TEST_PAGING_MEDIA_DRIVER__) |
|
2769 |
__KTRACE_OPT(KLOCDPAGING,Kern::Printf("DMediaDriverFlash::Complete req Id(%d) with(%d)", pR->Id(), aReason)); |
|
2770 |
#endif // __TEST_PAGING_MEDIA_DRIVER__ |
|
2771 |
#endif // __DEMAND_PAGING__ |
|
2772 |
iCurrentReq=NULL; |
|
2773 |
DMediaDriver::Complete(*pR,aReason); |
|
2774 |
} |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2775 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_COMPLETEREQUEST_EXIT, this ); |
0 | 2776 |
} |
2777 |
||
2778 |
TInt DMmcMediaDriverFlash::Caps(TLocDrv& aDrive, TLocalDriveCapsV6& aInfo) |
|
2779 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2780 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_CAPS_ENTRY, this ); |
0 | 2781 |
// Fill buffer with current media caps. |
2782 |
aInfo.iType = EMediaHardDisk; |
|
33
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
2783 |
aInfo.iConnectionBusType = EConnectionBusInternal; |
0 | 2784 |
aInfo.iDriveAtt = KDriveAttLocal; |
2785 |
aInfo.iMediaAtt = KMediaAttFormattable; |
|
2786 |
||
2787 |
if(iCard->iFlags & KMMCardIsLockable) |
|
2788 |
aInfo.iMediaAtt |= KMediaAttLockable; |
|
2789 |
||
2790 |
if (iCard->HasPassword()) |
|
2791 |
aInfo.iMediaAtt |= KMediaAttHasPassword; |
|
2792 |
if (iCard->IsWriteProtected()) |
|
2793 |
aInfo.iMediaAtt |= KMediaAttWriteProtected; |
|
2794 |
if (iCard->IsLocked()) |
|
2795 |
aInfo.iMediaAtt |= KMediaAttLocked; |
|
2796 |
||
271 | 2797 |
aInfo.iFileSystemId = KDriveFileSysFAT; //-- note, it may be overridden by GetCardFormatInfo() |
0 | 2798 |
|
2799 |
// Format is performed in multiples of the erase sector (or multiple block) size |
|
2800 |
aInfo.iMaxBytesPerFormat = iEraseInfo.iPreferredEraseUnitSize; |
|
2801 |
||
271 | 2802 |
if ((!iInternalSlot) && (GetCardFormatInfo(iCard, aInfo) == KErrNone)) |
0 | 2803 |
{ |
2804 |
TUint16 reservedSectors; |
|
2805 |
TMBRPartitionEntry dummy; // Not used here |
|
2806 |
const TInt r = GetMediaDefaultPartitionInfo(dummy, reservedSectors, iCard); |
|
2807 |
if(r != KErrNone) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2808 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2809 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_CAPS_EXIT1, this, r ); |
0 | 2810 |
return r; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2811 |
} |
0 | 2812 |
|
2813 |
aInfo.iFormatInfo.iReservedSectors = reservedSectors; |
|
271 | 2814 |
|
2815 |
//-- indicates that the driver wishes to dictate how the volume should be formatted |
|
2816 |
aInfo.iExtraInfo = ETrue; |
|
0 | 2817 |
} |
2818 |
||
2819 |
// Set serial number to CID |
|
2820 |
__ASSERT_DEBUG(KMMCCIDLength<=KMaxSerialNumLength, Kern::PanicCurrentThread(_L("Mmc"), KErrOverflow)); |
|
2821 |
aInfo.iSerialNumLength = KMMCCIDLength; |
|
2822 |
for (TUint i=0; i<KMMCCIDLength; i++) |
|
2823 |
aInfo.iSerialNum[i] = iCard->CID().At(i); |
|
2824 |
||
2825 |
// Get block size & erase block size to allow the file system to align first usable cluster correctly |
|
2826 |
aInfo.iBlockSize = BlockSize(iCard); |
|
2827 |
aInfo.iEraseBlockSize = EraseBlockSize(iCard); |
|
2828 |
||
2829 |
#if defined(__DEMAND_PAGING__) |
|
2830 |
// If the stack has flagged this as a demand-paging device, then it is assumed that it is internal |
|
2831 |
// and (optionally) write protected. |
|
2832 |
if(aDrive.iPrimaryMedia->iPagingMedia) |
|
2833 |
{ |
|
2834 |
aInfo.iMediaAtt|= KMediaAttPageable; |
|
2835 |
if (iDemandPagingInfo.iWriteProtected) |
|
2836 |
{ |
|
2837 |
aInfo.iMediaAtt|= KMediaAttWriteProtected; |
|
2838 |
aInfo.iMediaAtt&= ~KMediaAttFormattable; |
|
2839 |
} |
|
2840 |
} |
|
2841 |
||
2842 |
// code paging enabled on this drive ? |
|
2843 |
if(aDrive.iPagingDrv) |
|
2844 |
{ |
|
2845 |
aInfo.iDriveAtt|= KDriveAttPageable; |
|
2846 |
} |
|
2847 |
||
2848 |
#endif |
|
2849 |
||
2850 |
if (iInternalSlot) |
|
2851 |
{ |
|
2852 |
aInfo.iDriveAtt|= KDriveAttInternal; |
|
2853 |
} |
|
2854 |
else |
|
2855 |
{ |
|
2856 |
aInfo.iDriveAtt|= KDriveAttRemovable; |
|
2857 |
} |
|
2858 |
||
2859 |
||
2860 |
if (iMmcPartitionInfo) |
|
2861 |
{ |
|
2862 |
TLocalDriveCapsV6Buf CapsInfo = aInfo; |
|
2863 |
iMmcPartitionInfo->PartitionCaps(aDrive,CapsInfo); |
|
2864 |
aInfo = CapsInfo(); |
|
2865 |
} |
|
2866 |
||
2867 |
||
2868 |
if (iMediaType==EMultiMediaROM) |
|
2869 |
{ |
|
2870 |
aInfo.iMediaAtt|= KMediaAttWriteProtected; |
|
2871 |
aInfo.iMediaAtt&= ~KMediaAttFormattable; |
|
2872 |
} |
|
2873 |
||
2874 |
// Must return KErrCompletion to indicate that this |
|
2875 |
// is a synchronous version of the function |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2876 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_CAPS_EXIT2, this, KErrCompletion ); |
0 | 2877 |
return KErrCompletion; |
2878 |
} |
|
2879 |
||
2880 |
||
2881 |
// ---- cache ---- |
|
2882 |
||
2883 |
TInt DMmcMediaDriverFlash::ReadDataUntilCacheExhausted(TBool* aAllDone) |
|
2884 |
// |
|
2885 |
// scans the cache for blocks corresponding to the range iReqCur to iReqEnd and |
|
2886 |
// writes them to user memory. Starts at iReqCur & ~iBlkMsk and looks for blocks |
|
2887 |
// at sequential media positions. Completes when a block is not available, even |
|
2888 |
// if a following block is available in the cache. *aAllDone is undefined if the |
|
2889 |
// return value is not KErrNone. |
|
2890 |
// |
|
2891 |
// This function is linear in the number of blocks in the cache. |
|
2892 |
// |
|
2893 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2894 |
OstTraceFunctionEntryExt( DMMCMEDIADRIVERFLASH_READDATAUNTILCACHEEXHAUSTED_ENTRY, this ); |
0 | 2895 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:rdc:%x,%x", iReqCur, iReqEnd)); |
148 | 2896 |
OstTraceExt3( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_READDATAUNTILCACHEEXHAUSTED, "iReqCur=%x:%x; iReqEnd=0x%x", (TUint) I64HIGH(iReqCur), (TUint) I64LOW(iReqCur), (TUint) iReqEnd ); |
0 | 2897 |
|
148 | 2898 |
if ( (iCurrentReq->DriverFlags() & RLocalDrive::ELocDrvDirectIO) || iCurrentReq->IsPhysicalAddress() |
0 | 2899 |
#if defined(__DEMAND_PAGING__) && !defined(__WINS__) |
33
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
2900 |
|| DMediaPagingDevice::PageInRequest(*iCurrentReq) |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
2901 |
#endif //DEMAND_PAGING |
0173bcd7697c
Revision: 201001
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
2902 |
) |
0 | 2903 |
{ |
2904 |
*aAllDone = EFalse; |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2905 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_READDATAUNTILCACHEEXHAUSTED_EXIT1, this, KErrNone ); |
0 | 2906 |
return KErrNone; |
2907 |
} |
|
2908 |
||
2909 |
TInt64 physStart = iReqCur & ~iBlkMsk; |
|
2910 |
TInt64 physEnd = Min(physStart + iMaxBufSize, (iReqEnd + iBlkMsk) & ~iBlkMsk); |
|
2911 |
BuildGammaArray(physStart, physEnd); |
|
2912 |
||
2913 |
TInt r = KErrNone; |
|
2914 |
TInt curBlk = 0; |
|
2915 |
TInt cchBlk; |
|
2916 |
while ( |
|
2917 |
r == KErrNone |
|
2918 |
&& physStart + (curBlk << iBlkLenLog2) < physEnd |
|
2919 |
&& (cchBlk = iGamma[curBlk]) != KNoCacheBlock ) |
|
2920 |
{ |
|
2921 |
// set up instance variables for WriteDataToUser() |
|
2922 |
iPhysStart = physStart + (curBlk << iBlkLenLog2); |
|
2923 |
iPhysEnd = iPhysStart + iBlkLen; |
|
2924 |
iIntBuf = IdxToCchMem(cchBlk); |
|
2925 |
||
2926 |
if ((r = WriteDataToUser(&iIntBuf[I64LOW(iReqCur - iPhysStart)])) == KErrNone) |
|
2927 |
{ |
|
2928 |
iReqCur = iPhysEnd; |
|
2929 |
iLstUsdCchEnt = iGamma[curBlk]; |
|
2930 |
++curBlk; |
|
2931 |
} |
|
2932 |
} |
|
2933 |
||
2934 |
*aAllDone = (iReqCur >= iReqEnd); |
|
2935 |
||
2936 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:rdc:%d,%d", *aAllDone, r)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2937 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_READDATAUNTILCACHEEXHAUSTED_EXIT2, this, r ); |
0 | 2938 |
return r; |
2939 |
} |
|
2940 |
||
2941 |
||
2942 |
TInt DMmcMediaDriverFlash::WriteDataToUser(TUint8* aBufPtr) |
|
2943 |
// |
|
2944 |
// write the data from the most recent read operation to the user descriptor |
|
2945 |
// |
|
2946 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2947 |
OstTraceFunctionEntryExt( DMMCMEDIADRIVERFLASH_WRITEDATATOUSER_ENTRY, this ); |
0 | 2948 |
TInt r = KErrNotSupported; |
2949 |
||
2950 |
// get range of data to read out of internal buffer |
|
2951 |
||
2952 |
TInt len = I64LOW(UMin(iPhysEnd, iReqEnd) - iReqCur); |
|
2953 |
TPtrC8 extrView(aBufPtr, len); |
|
2954 |
||
2955 |
// write data from internal buffer |
|
2956 |
TUint usrOfst = I64LOW(iReqCur - iReqStart); |
|
2957 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2958 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_WRITEDATATOUSER_LATENCY1, "Begin writing user data" ); |
123 | 2959 |
r = iCurrentReq->WriteRemote(&extrView,usrOfst); |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2960 |
|
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2961 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_WRITEDATATOUSER_LATENCY2, "End writing user data" ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2962 |
|
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2963 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_WRITEDATATOUSER_EXIT, this, r ); |
0 | 2964 |
return r; |
2965 |
} |
|
2966 |
||
2967 |
TInt DMmcMediaDriverFlash::ReadDataFromUser(TDes8& aDes, TInt aOffset) |
|
2968 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2969 |
OstTraceExt2(TRACE_FLOW, DMMCMEDIADRIVERFLASH_READDATAFROMUSER_ENTRY ,"DMmcMediaDriverFlash::ReadDataFromUser;aOffset=%d;this=%x", aOffset, (TUint) this); |
123 | 2970 |
|
2971 |
TInt r = iCurrentReq->ReadRemote(&aDes, aOffset); |
|
2972 |
||
2973 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_READDATAFROMUSER_EXIT1, this, r ); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2974 |
return r; |
0 | 2975 |
} |
2976 |
||
2977 |
TInt DMmcMediaDriverFlash::AdjustPhysicalFragment(TPhysAddr &aPhysAddr, TInt &aPhysLength) |
|
2978 |
// |
|
2979 |
// Retrieve next Physical memory fragment and adjust the start pointer and length with |
|
2980 |
// respect to the set offset {iFragOfset}. |
|
2981 |
// Note the offset may encompass multiple memory fragments. |
|
2982 |
// |
|
2983 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2984 |
OstTraceExt3(TRACE_FLOW, DMMCMEDIADRIVERFLASH_ADJUSTPHYSICALFRAGMENT_ENTRY, "DMmcMediaDriverFlash::AdjustPhysicalFragment;aPhysAddr=%x;aPhysLength=%d;this=%x", (TUint) aPhysAddr, aPhysLength, (TUint) this); |
0 | 2985 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:APF")); |
2986 |
||
2987 |
TInt err = KErrNone; |
|
2988 |
TInt offset = iFragOfset; |
|
2989 |
||
2990 |
do |
|
2991 |
{ |
|
2992 |
err = iCurrentReq->GetNextPhysicalAddress(aPhysAddr, aPhysLength); |
|
2993 |
||
2994 |
if (err != KErrNone) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2995 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2996 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_ADJUSTPHYSICALFRAGMENT_EXIT1, this, err ); |
0 | 2997 |
return err; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
2998 |
} |
0 | 2999 |
|
3000 |
if (offset >= aPhysLength) // more offset than in this physical chunk |
|
3001 |
{ |
|
3002 |
offset -= aPhysLength; |
|
3003 |
} |
|
3004 |
else |
|
3005 |
{ |
|
3006 |
// offset < physLength |
|
3007 |
// offset lies within the memory chunk |
|
3008 |
// Adjust length and address for first transfer |
|
3009 |
aPhysLength -= offset; |
|
3010 |
aPhysAddr += offset; |
|
3011 |
offset = -1; |
|
3012 |
} |
|
3013 |
||
3014 |
} while (offset >= 0); |
|
3015 |
||
3016 |
iFragOfset = 0; // reset offset now complete |
|
3017 |
||
3018 |
if (aPhysAddr == 0) |
|
3019 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3020 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_ADJUSTPHYSICALFRAGMENT_EXIT2, this, KErrNoMemory ); |
0 | 3021 |
return KErrNoMemory; |
3022 |
} |
|
3023 |
||
3024 |
#ifdef _DEBUG |
|
3025 |
// DMAHelper ensures memory is dma aligned |
|
3026 |
if ( (aPhysAddr & (iSocket->DmaAlignment()-1) ) ) |
|
3027 |
{ |
|
3028 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("mmd:lr:Memory Fragment Not Word Aligned!")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3029 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_ADJUSTPHYSICALFRAGMENT_DMA, "Memory fragment not word aligned"); |
0 | 3030 |
Panic(ENotDMAAligned); |
3031 |
} |
|
3032 |
#endif //_DEBUG |
|
3033 |
||
3034 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:APF physAddr(0x%x), physLength(%d)",aPhysAddr, aPhysLength)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3035 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_ADJUSTPHYSICALFRAGMENT_EXIT3, this, err ); |
0 | 3036 |
return err; |
3037 |
} |
|
3038 |
||
3039 |
TInt DMmcMediaDriverFlash::PrepareFirstPhysicalFragment(TPhysAddr &aPhysAddr, TInt &aPhysLength, TUint32 aLength) |
|
3040 |
// |
|
3041 |
// Retrieves the first Physical memory fragment and determines the type of the next transfer |
|
3042 |
// Next transfer may either be the last block (end not block aligned) or a block may straddle |
|
3043 |
// memory fragments. |
|
3044 |
// |
|
3045 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3046 |
OstTraceExt4(TRACE_FLOW, DMMCMEDIADRIVERFLASH_PREPAREFIRSTPHYSICALFRAGMENT_ENTRY, "DMmcMediaDriverFlash::PrepareFirstPhysicalFragment;aPhysAddr=%x;aPhysLength=%d;aLength=%x;this=%x", (TUint) aPhysAddr, aPhysLength, (TUint) aLength, (TUint) this); |
0 | 3047 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:PFPF")); |
3048 |
TInt r = KErrNone; |
|
3049 |
||
3050 |
r = AdjustPhysicalFragment(aPhysAddr, aPhysLength); |
|
3051 |
||
3052 |
if (r == KErrNone) |
|
3053 |
{ |
|
3054 |
TUint len = I64LOW(iReqEnd & iBlkMsk); |
|
3055 |
if ( ((TUint32)aPhysLength >= aLength) && len ) |
|
3056 |
{ |
|
3057 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:PFPF-end block")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3058 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_PREPAREFIRSTPHYSICALFRAGMENT_EB, "End block"); |
0 | 3059 |
//next iteration will be an IPC for the end block |
3060 |
//There is enough space in physical memory to fit |
|
3061 |
//the extended read, but exceeds boundary for this request. |
|
3062 |
iIPCLen = len; |
|
3063 |
iRdROB |= KIPCSetup; // IPC setup for next iteration |
|
3064 |
aPhysLength -= len; |
|
3065 |
} |
|
3066 |
||
3067 |
if (aPhysLength & iBlkMsk) |
|
3068 |
{ |
|
3069 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:PFPF-straddles boundary")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3070 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_PREPAREFIRSTPHYSICALFRAGMENT_SB, "Straddles boundary"); |
0 | 3071 |
// block must be straddling a fragment boundary |
3072 |
// Next iteration must be an IPC |
|
3073 |
iRdROB |= KIPCSetup; |
|
3074 |
||
3075 |
// Calculate the offset into the next memory block |
|
3076 |
iFragOfset = I64LOW(iBlkLen - (aPhysLength & iBlkMsk)); |
|
3077 |
aPhysLength &= ~iBlkMsk; |
|
3078 |
} |
|
3079 |
} |
|
3080 |
||
3081 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:PFPF err(%d), physAddr(0x%x), physLength(%d)",r, aPhysAddr, aPhysLength)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3082 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_PREPAREFIRSTPHYSICALFRAGMENT_EXIT, this, r ); |
0 | 3083 |
return r; |
3084 |
} |
|
3085 |
||
3086 |
||
3087 |
void DMmcMediaDriverFlash::PrepareNextPhysicalFragment() |
|
3088 |
// |
|
3089 |
// Retrieves next Physical memory fragment and determines the type of the next transfer |
|
3090 |
// Next transfer may either be the last block (end not block aligned) or a block may straddle |
|
3091 |
// memory fragments. |
|
3092 |
// |
|
3093 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3094 |
OstTraceFunctionEntry0( DMMCMEDIADRIVERFLASH_PREPARENEXTPHYSICALFRAGMENT_ENTRY ); |
0 | 3095 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:PNPF")); |
3096 |
TInt err = KErrNone; |
|
3097 |
TPhysAddr physAddr = 0; |
|
3098 |
TInt physLength = 0; |
|
3099 |
||
3100 |
err = AdjustPhysicalFragment(physAddr, physLength); |
|
3101 |
||
3102 |
if (err == KErrNone) |
|
3103 |
{ |
|
3104 |
if (iPhysEnd+physLength >= iReqEnd) |
|
3105 |
{ |
|
3106 |
//Last physical transfer ... |
|
3107 |
TUint len = I64LOW(iReqEnd & iBlkMsk); |
|
3108 |
if (len) |
|
3109 |
{ |
|
3110 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:PNPF-end block")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3111 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_PREPARENEXTPHYSICALFRAGMENT_EB, "End block" ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3112 |
|
0 | 3113 |
// end point not block aligned! |
3114 |
// next iteration must be an IPC call |
|
3115 |
iRdROB |= KIPCSetup; |
|
3116 |
iIPCLen = len; |
|
3117 |
physLength -= len; |
|
3118 |
} |
|
3119 |
else{ |
|
3120 |
physLength = I64LOW(iDbEnd - iPhysEnd); |
|
3121 |
} |
|
3122 |
} |
|
3123 |
||
3124 |
if (physLength & iBlkMsk) |
|
3125 |
{ |
|
3126 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:PNPF-straddles boundary")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3127 |
OstTrace0( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_PREPARENEXTPHYSICALFRAGMENT_SB, "Straddles boundary" ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3128 |
|
0 | 3129 |
// block must be straddling a fragment boundary |
3130 |
// Next iteration must be an IPC |
|
3131 |
iRdROB |= KIPCSetup; |
|
3132 |
||
3133 |
// Calculate the offset into the next memory block |
|
3134 |
iFragOfset = I64LOW(iBlkLen - (physLength & iBlkMsk)); |
|
3135 |
physLength &= ~iBlkMsk; |
|
3136 |
} |
|
3137 |
||
3138 |
iPhysEnd += physLength; |
|
3139 |
} |
|
3140 |
||
3141 |
iSession->MoreDataAvailable( (physLength >> KDiskSectorShift), (TUint8*) physAddr, err); |
|
3142 |
iSecondBuffer = EFalse; |
|
3143 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:PNPF")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3144 |
OstTraceFunctionExit0( DMMCMEDIADRIVERFLASH_PREPARENEXTPHYSICALFRAGMENT_EXIT ); |
0 | 3145 |
} |
3146 |
||
3147 |
TUint8* DMmcMediaDriverFlash::ReserveReadBlocks(TInt64 aStart, TInt64 aEnd, TUint32* aLength) |
|
3148 |
// |
|
3149 |
// Assume the cache has been drained before this function is called and so |
|
3150 |
// the first block is not in the cache. The length of the allocated range is |
|
3151 |
// either aEnd - aStart, or enough blocks such that the next block to read |
|
3152 |
// is already available in the cache, and so will be read when |
|
3153 |
// ReadDataUntilCacheExhausted() is called from the callback DFC. |
|
3154 |
// |
|
3155 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3156 |
OstTraceFunctionEntryExt( DMMCMEDIADRIVERFLASH_RESERVEREADBLOCKS_ENTRY, this ); |
0 | 3157 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:rrb:%lx,%lx", aStart, aEnd)); |
3158 |
||
3159 |
__ASSERT_DEBUG((aStart & iBlkMsk) == 0, Panic(ERRBStAlign)); |
|
3160 |
__ASSERT_DEBUG(TotalSizeInBytes() > aStart, Panic(ERRBStPos)); |
|
3161 |
__ASSERT_DEBUG(aEnd > aStart, Panic(ERRBNotPositive)); |
|
3162 |
__ASSERT_DEBUG((aEnd & iBlkMsk) == 0, Panic(ERRBEndAlign)); |
|
3163 |
__ASSERT_DEBUG(TotalSizeInBytes() >= aEnd, Panic(ERRBEndPos)); |
|
3164 |
__ASSERT_DEBUG(!iDoDoubleBuffer, Panic(ENoDBSupport)); |
|
3165 |
__ASSERT_CACHE(CacheInvariant(), Panic(ERRBCchInv)); |
|
3166 |
__ASSERT_CACHE(GetCachedBlock(aStart & ~iBlkMsk) == 0, Panic(ERRBExist)); |
|
3167 |
||
3168 |
TUint8* raby; |
|
3169 |
||
3170 |
BuildGammaArray(aStart, aEnd); |
|
3171 |
||
3172 |
// reposition start index at 0 if the full range would run off the end of the |
|
3173 |
// buffer. This is heuristic - enabling a longer multi-block may cost some |
|
3174 |
// cached reads. However, assume long reads do not generally re-read the same |
|
3175 |
// data, and are used for streaming large amounts of data into memory. |
|
3176 |
||
3177 |
const TInt blocksInRange = I64LOW((aEnd - aStart) >> iBlkLenLog2); |
|
3178 |
TInt startIndex = (iLstUsdCchEnt + 1) % iBlocksInBuffer; |
|
3179 |
if (startIndex + blocksInRange > iBlocksInBuffer) |
|
3180 |
startIndex = 0; |
|
3181 |
||
3182 |
// starting at startIndex, increase the range until it covers aEnd - aStart, |
|
3183 |
// or until the next block to read is available in the cache. |
|
3184 |
||
3185 |
TInt blkCnt = 0; |
|
3186 |
TBool finished; |
|
3187 |
do |
|
3188 |
{ |
|
3189 |
finished = ( |
|
3190 |
// range allocated for entire read |
|
3191 |
blkCnt == blocksInRange |
|
3192 |
// next block already exists in buffer and has not been overwritten |
|
3193 |
// by existing multi-block read |
|
3194 |
|| ( iGamma[blkCnt] != KNoCacheBlock |
|
3195 |
&& ( iGamma[blkCnt] < startIndex |
|
3196 |
|| iGamma[blkCnt] >= startIndex + blkCnt ) ) ); |
|
3197 |
||
3198 |
if (! finished) |
|
3199 |
++blkCnt; |
|
3200 |
} while (! finished); |
|
3201 |
||
3202 |
iLstUsdCchEnt = startIndex + blkCnt - 1; |
|
3203 |
||
3204 |
if (blkCnt < 1) blkCnt = 1; //RBW required < 1 block to be read |
|
3205 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3206 |
OstTraceExt2( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_RESERVEREADBLOCKS_RANGE, "blocksInRange=%d; blkCnt=%d", blocksInRange, blkCnt ); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3207 |
|
0 | 3208 |
TUint32 lengthInBytes = blkCnt << iBlkLenLog2; |
3209 |
*aLength = lengthInBytes; |
|
3210 |
MarkBlocks(aStart, aStart + lengthInBytes, startIndex); |
|
3211 |
||
3212 |
raby = IdxToCchMem(startIndex); |
|
3213 |
||
3214 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:rrb:%x", (TUint32) raby)); |
|
3215 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3216 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_RESERVEREADBLOCKS_EXIT, this, ( TUint )( raby ) ); |
0 | 3217 |
return raby; |
3218 |
} |
|
3219 |
||
3220 |
||
3221 |
TUint8* DMmcMediaDriverFlash::ReserveWriteBlocks(TInt64 aStart, TInt64 aEnd, TUint* aRBM) |
|
3222 |
// |
|
3223 |
// reserve a range of blocks in the buffer. If the block containing aStart or aEnd |
|
3224 |
// are already in the buffer, attempts to position on them. This can save one or two |
|
3225 |
// RBMs for writes. |
|
3226 |
// |
|
3227 |
// This function is linear in the number of blocks - it runs through the array |
|
3228 |
// exactly twice. |
|
3229 |
// |
|
3230 |
// aStart and aEnd are not necessarily block aligned - the function uses alignment |
|
3231 |
// information to minimize RBMs. |
|
3232 |
// |
|
3233 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3234 |
OstTraceFunctionEntryExt( DMMCMEDIADRIVERFLASH_RESERVEWRITEBLOCKS_ENTRY, this ); |
0 | 3235 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:rwb:%lx,%lx", aStart, aEnd)); |
3236 |
||
3237 |
TInt64 physStart = aStart & ~iBlkMsk; |
|
3238 |
TInt64 physEnd = (aEnd + iBlkMsk) & ~iBlkMsk; |
|
3239 |
||
3240 |
__ASSERT_DEBUG(TotalSizeInBytes() > physStart, Panic(ERWBStPos)); |
|
3241 |
__ASSERT_DEBUG(aEnd > aStart, Panic(ERWBNotPositive)); |
|
3242 |
__ASSERT_DEBUG(TotalSizeInBytes() >= physEnd, Panic(ERWBEndPos)); |
|
3243 |
__ASSERT_DEBUG(iDoPhysicalAddress || iDoDoubleBuffer || (!iDoDoubleBuffer && !iDoPhysicalAddress && physEnd - physStart <= (TInt64)iMaxBufSize), Panic(ERWBOverflow)); |
|
3244 |
__ASSERT_CACHE(CacheInvariant(), Panic(ERWBCchInv)); |
|
3245 |
||
3246 |
const TBool firstPartial = (aStart & iBlkMsk) != 0; |
|
3247 |
const TBool lastPartial = (aEnd & iBlkMsk) != 0; |
|
3248 |
||
3249 |
const TInt blkCnt = I64LOW((physEnd - physStart) >> iBlkLenLog2); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3250 |
OstTrace1( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_RESERVEWRITEBLOCKS_RANGE, "blkCnt=%d", blkCnt ); |
0 | 3251 |
|
3252 |
TBool startUsed = EFalse; |
|
3253 |
TBool endUsed = EFalse; |
|
3254 |
||
3255 |
TUint8* raby = NULL; |
|
3256 |
||
3257 |
if(iDoDoubleBuffer) |
|
3258 |
{ |
|
3259 |
// |
|
3260 |
// If we're double-buffering, then the entire cache will be re-used |
|
3261 |
// continuously. Rather than continually reserve blocks during each |
|
3262 |
// transfer we calculate the blocks that will be present after all |
|
3263 |
// transfers have completed. |
|
3264 |
// |
|
3265 |
InvalidateCache(); |
|
3266 |
raby = iCacheBuf; |
|
3267 |
} |
|
3268 |
else |
|
3269 |
{ |
|
3270 |
TInt idx; |
|
3271 |
||
3272 |
// check if the first or last blocks are already in the buffer. |
|
3273 |
TInt fst = -1, lst = -1; |
|
3274 |
const TInt64 lstBlk = physEnd - iBlkLen; |
|
3275 |
TInt i; |
|
3276 |
for (i = 0; i < iBlocksInBuffer; ++i) |
|
3277 |
{ |
|
3278 |
if (iCachedBlocks[i] == physStart) |
|
3279 |
fst = i; |
|
3280 |
||
3281 |
if (iCachedBlocks[i] == lstBlk) |
|
3282 |
lst = i; |
|
3283 |
} |
|
3284 |
||
3285 |
const TBool firstUsable = (fst != -1) && (iBlocksInBuffer - fst) >= blkCnt; |
|
3286 |
const TBool lastUsable = (lst != -1) && lst >= (blkCnt - 1); |
|
3287 |
||
3288 |
if (iDoPhysicalAddress) |
|
3289 |
{ |
|
3290 |
if ( (firstPartial || lastPartial) && blkCnt <= 2) |
|
3291 |
{ |
|
3292 |
//Physical addressing not to be used. |
|
3293 |
//more efficent to use local Cache copying |
|
3294 |
iDoPhysicalAddress = EFalse; |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3295 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_RESERVEWRITEBLOCKS_EXIT1, this, ( TUint )( raby ) ); |
0 | 3296 |
return raby; |
3297 |
} |
|
3298 |
else |
|
3299 |
{ |
|
3300 |
raby = iMinorBuf; |
|
3301 |
||
3302 |
const TBool firstPres = (fst != -1); |
|
3303 |
const TBool lastPres = (lst != -1); |
|
3304 |
||
3305 |
if (firstPartial && firstPres) |
|
3306 |
{ |
|
3307 |
// move to minor buffer |
|
3308 |
memcpy(iMinorBuf, IdxToCchMem(fst), iBlkLen); |
|
3309 |
} |
|
3310 |
if (lastPartial && lastPres) |
|
3311 |
{ |
|
3312 |
// move to beginning of cache |
|
3313 |
memcpy(iCacheBuf, IdxToCchMem(lst), iBlkLen); |
|
3314 |
} |
|
3315 |
||
3316 |
InvalidateCache(physStart,physEnd); |
|
3317 |
||
3318 |
if (lastPartial) |
|
3319 |
{ |
|
3320 |
//re-mark beginning of cache |
|
3321 |
MarkBlocks((physEnd-iBlkLen), physEnd, 0); |
|
3322 |
} |
|
3323 |
||
3324 |
if (aRBM) |
|
3325 |
{ |
|
3326 |
*aRBM = 0; |
|
3327 |
||
3328 |
if (firstPartial) |
|
3329 |
*aRBM |= KWtMinFst; |
|
3330 |
||
3331 |
if (firstPartial && !firstPres) |
|
3332 |
*aRBM |= KWtRBMFst; |
|
3333 |
||
3334 |
if (lastPartial) |
|
3335 |
*aRBM |= KWtMinLst; |
|
3336 |
||
3337 |
if (lastPartial && !lastPres) |
|
3338 |
*aRBM |= KWtRBMLst; |
|
3339 |
} |
|
3340 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3341 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_RESERVEWRITEBLOCKS_EXIT2, this, ( TUint )( raby ) ); |
0 | 3342 |
return raby; |
3343 |
} |
|
3344 |
} // if (iDoPhysicalAddress) |
|
3345 |
||
3346 |
if (!firstUsable && !lastUsable) |
|
3347 |
{ |
|
3348 |
if(iDoDoubleBuffer) |
|
3349 |
{ |
|
3350 |
idx = iSecondBuffer ? iBlocksInBuffer >> 1 : 0; |
|
3351 |
} |
|
3352 |
else |
|
3353 |
{ |
|
3354 |
idx = (iLstUsdCchEnt + 1) % iBlocksInBuffer; |
|
3355 |
if (idx + blkCnt > iBlocksInBuffer) |
|
3356 |
idx = 0; |
|
3357 |
} |
|
3358 |
} |
|
3359 |
else if (firstUsable && ! lastUsable) |
|
3360 |
{ |
|
3361 |
idx = fst; |
|
3362 |
} |
|
3363 |
else if (! firstUsable && lastUsable) |
|
3364 |
{ |
|
3365 |
idx = lst - (blkCnt - 1); |
|
3366 |
} |
|
3367 |
else // (lastUsable && firstUsable) |
|
3368 |
{ |
|
3369 |
if (firstPartial || ! lastPartial) |
|
3370 |
idx = fst; |
|
3371 |
else |
|
3372 |
idx = lst - (blkCnt - 1); |
|
3373 |
} |
|
3374 |
||
3375 |
MarkBlocks(physStart, physEnd, idx); |
|
3376 |
||
3377 |
// if the range started or ended on a partial block, but could not |
|
3378 |
// be allocated on that existing block, and the existing block is |
|
3379 |
// somewhere in the cache, then memcpy() that block to the end of the |
|
3380 |
// range. used is not the same as usable - both the start and end |
|
3381 |
// blocks may be usable, through not in the same range, or any range. |
|
3382 |
||
3383 |
const TInt startExtent = I64LOW(aStart & iBlkMsk); |
|
3384 |
TBool firstInTemp = EFalse; |
|
3385 |
startUsed = (idx == fst); |
|
3386 |
if (! startUsed && firstPartial && fst != -1) |
|
3387 |
{ |
|
3388 |
// if the range has started at index occupied by the last block then |
|
3389 |
// temporarily copy to minor buffer. This is unnecessary when the |
|
3390 |
// last block is not partial because the last block does not need to |
|
3391 |
// be preserved. |
|
3392 |
||
3393 |
if (idx == lst && lastPartial) |
|
3394 |
{ |
|
3395 |
firstInTemp = ETrue; |
|
3396 |
memcpy(iMinorBuf, IdxToCchMem(fst), startExtent); |
|
3397 |
} |
|
3398 |
else |
|
3399 |
{ |
|
3400 |
memcpy(IdxToCchMem(idx), IdxToCchMem(fst), startExtent); |
|
3401 |
} |
|
3402 |
||
3403 |
startUsed = ETrue; |
|
3404 |
} |
|
3405 |
||
3406 |
endUsed = (idx + blkCnt - 1 == lst); |
|
3407 |
if (! endUsed && lastPartial && lst != -1) |
|
3408 |
{ |
|
3409 |
const TInt endOffset = I64LOW(aEnd & iBlkMsk); |
|
3410 |
const TInt endExtent = iBlkLen - endOffset; |
|
3411 |
memcpy(IdxToCchMem(idx + blkCnt - 1) + endOffset, IdxToCchMem(lst) + endOffset, endExtent); |
|
3412 |
endUsed = ETrue; |
|
3413 |
} |
|
3414 |
||
3415 |
if (firstInTemp) |
|
3416 |
memcpy(IdxToCchMem(idx), iMinorBuf, startExtent); |
|
3417 |
||
3418 |
// start reclaiming at block following this range |
|
3419 |
iLstUsdCchEnt = idx + blkCnt - 1; |
|
3420 |
raby = IdxToCchMem(idx); |
|
3421 |
} |
|
3422 |
||
3423 |
// work out if read-before-write required |
|
3424 |
if (aRBM) |
|
3425 |
{ |
|
3426 |
*aRBM = 0; |
|
3427 |
// first index was not already in range, and does not start on block boundary |
|
3428 |
if (firstPartial && ! startUsed) |
|
3429 |
*aRBM |= KWtRBMFst; |
|
3430 |
||
3431 |
// last index was not already in range, and does not end on block boundary |
|
3432 |
if (lastPartial && ! endUsed) |
|
3433 |
*aRBM |= KWtRBMLst; |
|
3434 |
||
3435 |
// only use one pre-read if contained in single block |
|
3436 |
if (blkCnt == 1 && *aRBM == (KWtRBMFst | KWtRBMLst)) |
|
3437 |
*aRBM = KWtRBMFst; |
|
3438 |
||
3439 |
// |
|
3440 |
// When double-buffering, RMW for the last block is stored in the |
|
3441 |
// minor buffer and writen during the last transfer, so flag this |
|
3442 |
// seperately (as aRBM is used for the initial RMW Read then subsequently cleared). |
|
3443 |
// |
|
3444 |
if(iDoDoubleBuffer && (*aRBM & KWtRBMLst)) |
|
3445 |
iDoLastRMW = ETrue; |
|
3446 |
} |
|
3447 |
||
3448 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:rwb:%x", (TUint32) raby)); |
|
3449 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3450 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_RESERVEWRITEBLOCKS_EXIT3, this, ( TUint )( raby ) ); |
0 | 3451 |
return raby; |
3452 |
} |
|
3453 |
||
3454 |
void DMmcMediaDriverFlash::MarkBlocks(TInt64 aStart, TInt64 aEnd, TInt aStartIndex) |
|
3455 |
// |
|
3456 |
// mark range of blocks for media range. If existing cache entries for any part of |
|
3457 |
// the cache are already in the buffer they are invalidated. |
|
3458 |
// |
|
3459 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3460 |
OstTraceFunctionEntryExt( DMMCMEDIADRIVERFLASH_MARKBLOCKS_ENTRY, this ); |
0 | 3461 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("=mmd:mb:%lx,%lx,%d", aStart, aEnd, aStartIndex)); |
3462 |
||
3463 |
__ASSERT_DEBUG(TotalSizeInBytes() > aStart, Panic(EMBStPos)); |
|
3464 |
__ASSERT_DEBUG((aStart & iBlkMsk) == 0, Panic(EMBStAlign)); |
|
3465 |
__ASSERT_DEBUG(aEnd > aStart, Panic(EMBNotPositive)); |
|
3466 |
__ASSERT_DEBUG(TotalSizeInBytes() >= aEnd, Panic(EMBEndPos)); |
|
3467 |
__ASSERT_DEBUG((aEnd & iBlkMsk) == 0, Panic(EMBEndAlign)); |
|
3468 |
__ASSERT_DEBUG(aStartIndex + (TInt)((aEnd - aStart) >> iBlkLenLog2) <= iBlocksInBuffer, Panic(EMBOverflow)); |
|
3469 |
__ASSERT_CACHE(CacheInvariant(), Panic(EMBCchInvPre)); |
|
3470 |
||
3471 |
TInt i; |
|
3472 |
||
3473 |
for (i = 0; i < aStartIndex; ++i) |
|
3474 |
{ |
|
3475 |
if (iCachedBlocks[i] >= aStart && iCachedBlocks[i] < aEnd) |
|
3476 |
iCachedBlocks[i] = KInvalidBlock; |
|
3477 |
} |
|
3478 |
||
3479 |
TInt blkCnt = I64LOW((aEnd - aStart) >> iBlkLenLog2); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3480 |
OstTrace1( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_MARKBLOCKS_RANGE, "blkCnt=%d", blkCnt ); |
0 | 3481 |
for (i = aStartIndex; i < aStartIndex + blkCnt; ++i) |
3482 |
iCachedBlocks[i] = aStart + (static_cast<TUint32>(i - aStartIndex) << iBlkLenLog2); |
|
3483 |
||
3484 |
for (i = aStartIndex + blkCnt; i < iBlocksInBuffer; ++i) |
|
3485 |
{ |
|
3486 |
if (iCachedBlocks[i] >= aStart && iCachedBlocks[i] < aEnd) |
|
3487 |
iCachedBlocks[i] = KInvalidBlock; |
|
3488 |
} |
|
3489 |
||
3490 |
__ASSERT_CACHE(CacheInvariant(), Panic(EMBCchInvPost)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3491 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_MARKBLOCKS_EXIT, this ); |
0 | 3492 |
} |
3493 |
||
3494 |
||
3495 |
void DMmcMediaDriverFlash::BuildGammaArray(TInt64 aStart, TInt64 aEnd) |
|
3496 |
// |
|
3497 |
// iGamma is an array of indexes that correspond to cached blocks starting |
|
3498 |
// from aStart. iGamma[0] is the index of aStart, iGamma[1] is the index of |
|
3499 |
// aStart + iBlkLen, and so on. Building an array here means that all of |
|
3500 |
// the available cached entries can be found in linear time instead of |
|
3501 |
// quadratically searching through the array for each block. |
|
3502 |
// |
|
3503 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3504 |
OstTraceFunctionEntryExt( DMMCMEDIADRIVERFLASH_BUILDGAMMAARRAY_ENTRY, this ); |
0 | 3505 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("=mmd:bga:%lx,%lx", aStart, aEnd)); |
3506 |
||
3507 |
__ASSERT_DEBUG(TotalSizeInBytes() > aStart, Panic(EBGAStPos)); |
|
3508 |
__ASSERT_DEBUG((aStart & iBlkMsk) == 0, Panic(EBGAStAlign)); |
|
3509 |
__ASSERT_DEBUG(aEnd > aStart, Panic(EBGANotPositive)); |
|
3510 |
__ASSERT_DEBUG(TotalSizeInBytes() >= aEnd, Panic(EBGAEndPos)); |
|
3511 |
__ASSERT_DEBUG((aEnd & iBlkMsk) == 0, Panic(EBGAEndAlign)); |
|
3512 |
__ASSERT_DEBUG(aEnd - aStart <= (TInt64) iMaxBufSize, Panic(EBGAOverflow)); |
|
3513 |
__ASSERT_CACHE(CacheInvariant(), Panic(EBGACchInv)); |
|
3514 |
||
3515 |
// KNoCacheBlock = (0xff) x 4 |
|
3516 |
TUint blocksInRange = I64LOW((aEnd - aStart) >> iBlkLenLog2); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3517 |
OstTrace1( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_BUILDGAMMAARRAY_RANGE, "blocksInRange=%d", blocksInRange ); |
0 | 3518 |
memset(iGamma, 0xff, sizeof(*iGamma) * blocksInRange); |
3519 |
||
3520 |
TInt64 blkAddr = 0; |
|
3521 |
for (TInt i = 0; ( (blocksInRange > 0 ) && (i < iBlocksInBuffer) ); ++i) |
|
3522 |
{ |
|
3523 |
blkAddr = iCachedBlocks[i]; |
|
3524 |
if (blkAddr >= aStart && blkAddr < aEnd) |
|
3525 |
{ |
|
3526 |
iGamma[I64LOW((blkAddr - aStart) >> iBlkLenLog2)] = i; |
|
3527 |
blocksInRange--; |
|
3528 |
} |
|
3529 |
} |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3530 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_BUILDGAMMAARRAY_EXIT, this ); |
0 | 3531 |
} |
3532 |
||
3533 |
void DMmcMediaDriverFlash::InvalidateCache() |
|
3534 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3535 |
OstTraceFunctionEntry0( DMMCMEDIADRIVERFLASH_INVALIDATECACHE1_ENTRY ); |
0 | 3536 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("=mmd:ich")); |
3537 |
||
3538 |
// KInvalidBlock = (0xff) x 4 |
|
3539 |
memset(iCachedBlocks, 0xff, sizeof(*iCachedBlocks) * iBlocksInBuffer); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3540 |
OstTraceFunctionExit0( DMMCMEDIADRIVERFLASH_INVALIDATECACHE1_EXIT ); |
0 | 3541 |
} |
3542 |
||
3543 |
// Invalidate any cache entries from aStart to aEnd |
|
3544 |
// This is for DMA writes and is to prevent the cache becoming inconsistent with the media. |
|
3545 |
void DMmcMediaDriverFlash::InvalidateCache(TInt64 aStart, TInt64 aEnd) |
|
3546 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3547 |
OstTraceFunctionEntryExt( DMMCMEDIADRIVERFLASH_INVALIDATECACHE2_ENTRY, this ); |
0 | 3548 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("=mmd:ich:%lx,%lx", aStart, aEnd)); |
3549 |
||
3550 |
__ASSERT_DEBUG(TotalSizeInBytes() > aStart, Panic(EBGAStPos)); |
|
3551 |
__ASSERT_DEBUG(aEnd > aStart, Panic(EBGANotPositive)); |
|
3552 |
__ASSERT_DEBUG(TotalSizeInBytes() >= aEnd, Panic(EBGAEndPos)); |
|
3553 |
||
3554 |
const TInt blkCnt = I64LOW((aStart - aEnd) >> iBlkLenLog2); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3555 |
OstTrace1( TRACE_INTERNALS, DMMCMEDIADRIVERFLASH_INVALIDATECACHE_RANGE, "blocksInRange=%d", blkCnt ); |
0 | 3556 |
|
3557 |
__ASSERT_CACHE(CacheInvariant(), Panic(EBGACchInv)); |
|
3558 |
||
3559 |
TInt64 endBlk = (blkCnt == 0) ? (aStart+iBlkLen) : aEnd; |
|
3560 |
||
3561 |
for (TInt i = 0; i < iBlocksInBuffer; ++i) |
|
3562 |
{ |
|
3563 |
const TInt64 blkAddr = iCachedBlocks[i]; |
|
3564 |
if (blkAddr >= aStart && blkAddr < endBlk) |
|
3565 |
iCachedBlocks[i] = KInvalidBlock; |
|
3566 |
} |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3567 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_INVALIDATECACHE2_EXIT, this ); |
0 | 3568 |
} |
3569 |
||
3570 |
TUint8* DMmcMediaDriverFlash::IdxToCchMem(TInt aIdx) const |
|
3571 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3572 |
OstTraceFunctionEntryExt( DMMCMEDIADRIVERFLASH_IDXTOCCHMEM_ENTRY, this ); |
0 | 3573 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("=mmd:icm:%d", aIdx)); |
3574 |
||
3575 |
__ASSERT_DEBUG(aIdx >= 0, Panic(EICMNegative)); |
|
3576 |
__ASSERT_DEBUG(aIdx < iBlocksInBuffer, Panic(EICMOverflow)); |
|
3577 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3578 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_IDXTOCCHMEM_EXIT, this ); |
0 | 3579 |
return &iCacheBuf[aIdx << iBlkLenLog2]; |
3580 |
} |
|
3581 |
||
3582 |
TInt DMmcMediaDriverFlash::CchMemToIdx(TUint8* aMemP) const |
|
3583 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3584 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_CCHMEMTOIDX_ENTRY, this ); |
0 | 3585 |
__ASSERT_DEBUG((aMemP >= iCacheBuf) && (aMemP < iCacheBuf + (iBlocksInBuffer << iBlkLenLog2)), Panic(ECMIOverflow)); |
3586 |
||
3587 |
return((aMemP - iCacheBuf) >> iBlkLenLog2); |
|
3588 |
} |
|
3589 |
||
3590 |
#ifdef _DEBUG_CACHE |
|
3591 |
TBool DMmcMediaDriverFlash::CacheInvariant() |
|
3592 |
// |
|
3593 |
// check each cache entry refers to a valid block and that no two |
|
3594 |
// entries cover the same block. This algorithm is quadratic in |
|
3595 |
// the cache length. |
|
3596 |
// |
|
3597 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3598 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_CACHEINVARIANT_ENTRY, this ); |
0 | 3599 |
for (TInt i = 0; i < iBlocksInBuffer; ++i) |
3600 |
{ |
|
3601 |
if (iCachedBlocks[i] == KInvalidBlock) |
|
3602 |
continue; |
|
3603 |
||
3604 |
if ((iCachedBlocks[i] & iBlkMsk) != 0) |
|
3605 |
return EFalse; |
|
3606 |
||
3607 |
if (iCachedBlocks[i] >= TotalSizeInBytes()) |
|
3608 |
return EFalse; |
|
3609 |
||
3610 |
for (TInt j = i + 1; j < iBlocksInBuffer; ++j) |
|
3611 |
{ |
|
3612 |
if (iCachedBlocks[i] == iCachedBlocks[j]) |
|
3613 |
return EFalse; |
|
3614 |
} |
|
3615 |
} |
|
3616 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3617 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_CACHEINVARIANT_EXIT, this ); |
0 | 3618 |
return ETrue; |
3619 |
} |
|
3620 |
#endif |
|
3621 |
||
3622 |
void DMmcMediaDriverFlash::NotifyPowerDown() |
|
3623 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3624 |
OstTraceFunctionEntry0( DMMCMEDIADRIVERFLASH_NOTIFYPOWERDOWN_ENTRY ); |
0 | 3625 |
__KTRACE_OPT(KPBUSDRV,Kern::Printf(">Mmc:NotifyPowerDown")); |
3626 |
||
3627 |
iSessionEndDfc.Cancel(); |
|
3628 |
iDataTransferCallBackDfc.Cancel(); |
|
3629 |
||
3630 |
EndInCritical(); |
|
3631 |
||
3632 |
// need to cancel the session as the stack doesn't take too kindly to having the same session engaged more than once. |
|
3633 |
if (iSession) |
|
3634 |
iStack->CancelSession(iSession); |
|
3635 |
||
3636 |
CompleteRequest(KErrNotReady); |
|
3637 |
iMedReq = EMReqIdle; |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3638 |
OstTraceFunctionExit0( DMMCMEDIADRIVERFLASH_NOTIFYPOWERDOWN_EXIT ); |
0 | 3639 |
} |
3640 |
||
3641 |
void DMmcMediaDriverFlash::NotifyEmergencyPowerDown() |
|
3642 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3643 |
OstTraceFunctionEntry0( DMMCMEDIADRIVERFLASH_NOTIFYEMERGENCYPOWERDOWN_ENTRY ); |
0 | 3644 |
__KTRACE_OPT(KPBUSDRV,Kern::Printf(">Ata:NotifyEmergencyPowerDown")); |
3645 |
||
3646 |
iSessionEndDfc.Cancel(); |
|
3647 |
iDataTransferCallBackDfc.Cancel(); |
|
3648 |
||
3649 |
TInt r=KErrNotReady; |
|
3650 |
if (iCritical) |
|
3651 |
r=KErrAbort; |
|
3652 |
EndInCritical(); |
|
3653 |
||
3654 |
// need to cancel the session as the stack doesn't take too kindly to having the same session engaged more than once. |
|
3655 |
if (iSession) |
|
3656 |
iStack->CancelSession(iSession); |
|
3657 |
||
3658 |
CompleteRequest(r); |
|
3659 |
iMedReq = EMReqIdle; |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3660 |
OstTraceFunctionExit0( DMMCMEDIADRIVERFLASH_NOTIFYEMERGENCYPOWERDOWN_EXIT ); |
0 | 3661 |
} |
3662 |
||
3663 |
TInt DMmcMediaDriverFlash::Request(TLocDrvRequest& aRequest) |
|
3664 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3665 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_REQUEST_ENTRY, this ); |
0 | 3666 |
__KTRACE_OPT(KLOCDRV,Kern::Printf("MmcMd:Req %08x id %d",&aRequest,aRequest.Id())); |
3667 |
TInt r=KErrNotSupported; |
|
3668 |
TInt id=aRequest.Id(); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3669 |
OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DMMCMEDIADRIVERFLASH_REQUEST_ID, "Request=0x%08x; Request ID=%d", (TUint) &aRequest, id); |
0 | 3670 |
|
3671 |
#if defined (__TEST_PAGING_MEDIA_DRIVER__) |
|
3672 |
DThread* client=aRequest.Client(); |
|
3673 |
__KTRACE_OPT(KLOCDPAGING,Kern::Printf("Client:0x%08x",client)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3674 |
OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DMMCMEDIADRIVERFLASH_REQUEST_CLIENT, "Request client=0x%08x", (TUint) client); |
0 | 3675 |
#endif // __TEST_PAGING_MEDIA_DRIVER__ |
3676 |
||
3677 |
// First handle requests that can be handled without deferring |
|
3678 |
if(id==DLocalDrive::ECaps) |
|
3679 |
{ |
|
3680 |
TLocalDriveCapsV6& c = *(TLocalDriveCapsV6*)aRequest.RemoteDes(); |
|
3681 |
TLocDrv& drive = *aRequest.Drive(); |
|
3682 |
r = Caps(drive, c); |
|
3683 |
c.iSize = drive.iPartitionLen; |
|
3684 |
c.iPartitionType = drive.iPartitionType; |
|
3685 |
c.iHiddenSectors = (TUint) (drive.iPartitionBaseAddr >> KDiskSectorShift); |
|
123 | 3686 |
SetTotalSizeInBytes(c); |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3687 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_REQUEST_EXIT1, this, r ); |
0 | 3688 |
return r; |
3689 |
} |
|
3690 |
||
3691 |
// All other requests must be deferred if a request is currently in progress |
|
3692 |
if (iCurrentReq) |
|
3693 |
{ |
|
3694 |
||
3695 |
#if defined(__TEST_PAGING_MEDIA_DRIVER__) |
|
3696 |
if (DMediaPagingDevice::PageInRequest(*iCurrentReq)) |
|
3697 |
iMmcStats.iReqPage++; |
|
3698 |
else |
|
3699 |
iMmcStats.iReqNormal++; |
|
3700 |
#endif // __TEST_PAGING_MEDIA_DRIVER__ |
|
3701 |
||
3702 |
// a request is already in progress, so hold on to this one |
|
3703 |
__KTRACE_OPT(KLOCDRV,Kern::Printf("MmcMd:Req %08x ret 1",&aRequest)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3704 |
OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DMMCMEDIADRIVERFLASH_REQUEST_IN_PROGRESS, "Request in progress=0x%08x", (TUint) &aRequest); |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3705 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_REQUEST_EXIT2, this, KMediaDriverDeferRequest ); |
0 | 3706 |
return KMediaDriverDeferRequest; |
3707 |
} |
|
3708 |
else |
|
3709 |
{ |
|
3710 |
iCurrentReq=&aRequest; |
|
3711 |
TUint partitionType = iCurrentReq->Drive()->iPartitionType; |
|
3712 |
TBool readOnly = (partitionType == KPartitionTypeRofs || partitionType == KPartitionTypeROM); |
|
3713 |
||
3714 |
switch (id) |
|
3715 |
{ |
|
3716 |
||
3717 |
||
3718 |
#if defined(__DEMAND_PAGING__) |
|
3719 |
case DMediaPagingDevice::ERomPageInRequest: |
|
3720 |
__KTRACE_OPT(KLOCDPAGING,Kern::Printf("DMediaDriverFlash::Request(ERomPageInRequest)")); |
|
3721 |
BTraceContext8(BTrace::EPagingMedia,BTrace::EPagingMediaPagingMedDrvBegin,MEDIA_DEVICE_MMC,iCurrentReq); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3722 |
OstTraceDef0( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DMMCMEDIADRIVERFLASH_REQUEST_ROM_PAGE_IN, "ROM page-in request"); |
0 | 3723 |
r=DoRead(); |
3724 |
break; |
|
3725 |
case DMediaPagingDevice::ECodePageInRequest: |
|
3726 |
__KTRACE_OPT(KLOCDPAGING,Kern::Printf("DMediaDriverFlash::Request(ECodePageInRequest)")); |
|
3727 |
BTraceContext8(BTrace::EPagingMedia,BTrace::EPagingMediaPagingMedDrvBegin,MEDIA_DEVICE_MMC,iCurrentReq); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3728 |
OstTraceDef0( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DMMCMEDIADRIVERFLASH_REQUEST_CODE_PAGE_IN, "Code page-in request"); |
0 | 3729 |
r=DoRead(); |
3730 |
break; |
|
3731 |
#endif // __DEMAND_PAGING__ |
|
3732 |
||
3733 |
case DLocalDrive::EQueryDevice: |
|
3734 |
r = KErrNotSupported; |
|
3735 |
break; |
|
3736 |
||
3737 |
case DLocalDrive::ERead: |
|
3738 |
r=DoRead(); |
|
3739 |
break; |
|
3740 |
case DLocalDrive::EWrite: |
|
3741 |
if (readOnly) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3742 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3743 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_REQUEST_EXIT3, this, KErrNotSupported ); |
0 | 3744 |
return KErrNotSupported; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3745 |
} |
0 | 3746 |
r=DoWrite(); |
3747 |
break; |
|
3748 |
case DLocalDrive::EFormat: |
|
3749 |
if (readOnly) |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3750 |
{ |
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3751 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_REQUEST_EXIT4, this, KErrNotSupported ); |
0 | 3752 |
return KErrNotSupported; |
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3753 |
} |
0 | 3754 |
r=DoFormat(); |
3755 |
break; |
|
3756 |
||
3757 |
#if defined __TEST_PAGING_MEDIA_DRIVER__ |
|
3758 |
case DLocalDrive::EControlIO: |
|
3759 |
{ |
|
3760 |
r = HandleControlIORequest(); |
|
3761 |
break; |
|
3762 |
} |
|
3763 |
#endif |
|
3764 |
||
3765 |
case DLocalDrive::EPasswordUnlock: |
|
3766 |
case DLocalDrive::EPasswordLock: |
|
3767 |
case DLocalDrive::EPasswordClear: |
|
3768 |
// Don't allow passords on internal MMC; one reason is that this may be used for paging and |
|
3769 |
// we can't really stop paging just because the password hasn't been supplied |
|
3770 |
if (iInternalSlot) |
|
3771 |
r = KErrNotSupported; |
|
3772 |
else |
|
3773 |
r = DoPasswordOp(); |
|
3774 |
break; |
|
3775 |
case DLocalDrive::EPasswordErase: |
|
3776 |
{ |
|
3777 |
r = LaunchRPIErase(); |
|
3778 |
// This will complete the request in the event of an error |
|
3779 |
if(r != KErrNone) |
|
3780 |
PartitionInfoComplete(r); |
|
3781 |
||
3782 |
r = KErrNone; // ensures to indicate asynchronoous completion |
|
3783 |
break; |
|
3784 |
} |
|
3785 |
case DLocalDrive::EWritePasswordStore: |
|
3786 |
{ |
|
3787 |
// |
|
3788 |
// If the card is ready and locked, request the stack to perform the |
|
3789 |
// auto-unlock sequence. This is required, as the stack only performs |
|
3790 |
// automatic unlocking during power-up, and the stack may already be powered. |
|
3791 |
// |
|
3792 |
r = KErrNone; // asynchronous completion |
|
3793 |
||
3794 |
if(iCard->IsReady() && iCard->IsLocked()) |
|
3795 |
{ |
|
3796 |
iSession->SetupCIMAutoUnlock(); |
|
3797 |
if(EngageAndSetRequest(EMReqWritePasswordData, 0) != KErrNone) |
|
3798 |
{ |
|
3799 |
// If error, complete with KErrNone anyway |
|
3800 |
// - The password store has been set, any errors |
|
3801 |
// will be reported on the next access. |
|
3802 |
CompleteRequest(KErrNone); |
|
3803 |
} |
|
3804 |
} |
|
3805 |
else |
|
3806 |
{ |
|
3807 |
CompleteRequest(KErrNone); |
|
3808 |
} |
|
3809 |
break; |
|
3810 |
} |
|
3811 |
case DLocalDrive::EEnlarge: |
|
3812 |
case DLocalDrive::EReduce: |
|
3813 |
default: |
|
3814 |
r=KErrNotSupported; |
|
3815 |
break; |
|
3816 |
} |
|
3817 |
} |
|
3818 |
||
3819 |
__KTRACE_OPT(KLOCDRV,Kern::Printf("MmcMd:Req %08x cmp %d",&aRequest,r)); |
|
3820 |
||
3821 |
if (r != KErrNone) |
|
3822 |
{ |
|
3823 |
iMedReq = EMReqIdle; |
|
3824 |
iCurrentReq=NULL; |
|
3825 |
SetCurrentConsumption(KIdleCurrentInMilliAmps); |
|
3826 |
} |
|
3827 |
||
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3828 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_REQUEST_EXIT5, this, r ); |
0 | 3829 |
return r; |
3830 |
} |
|
3831 |
||
3832 |
void DMmcMediaDriverFlash::Disconnect(DLocalDrive* aLocalDrive, TThreadMessage* aMsg) |
|
3833 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3834 |
OstTraceFunctionEntry1( DMMCMEDIADRIVERFLASH_DISCONNECT_ENTRY, this ); |
0 | 3835 |
// Complete using the default implementation |
3836 |
DMediaDriver::Disconnect(aLocalDrive, aMsg); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3837 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_DISCONNECT_EXIT, this ); |
0 | 3838 |
} |
3839 |
||
3840 |
#ifdef _DEBUG_CACHE |
|
3841 |
TUint8* DMmcMediaDriverFlash::GetCachedBlock(TInt64 aMdAddr) |
|
3842 |
// |
|
3843 |
// return cache block for media at aMdAddr, 0 if not found. |
|
3844 |
// This is a debug function to determine whether or not a block is in |
|
3845 |
// the cache. It should not be used for general block retrieval. |
|
3846 |
// If there are m blocks in the cache, and n in the requested range, |
|
3847 |
// this function is o(mn), whereas BuildGammaArray() is theta(m). |
|
3848 |
// |
|
3849 |
{ |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3850 |
OstTraceFunctionEntryExt( DMMCMEDIADRIVERFLASH_GETCACHEDBLOCK_ENTRY, this ); |
0 | 3851 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf(">mmd:gcb:%lx", aMdAddr)); |
3852 |
||
3853 |
__ASSERT_DEBUG((aMdAddr & iBlkMsk) == 0, Panic(EGCBAlign)); |
|
3854 |
__ASSERT_DEBUG(TotalSizeInBytes() > aMdAddr, Panic(EGCBPos)); |
|
3855 |
__ASSERT_CACHE(CacheInvariant(), Panic(EGCBCchInv)); |
|
3856 |
||
3857 |
for (TInt i = 0; i < iBlocksInBuffer; ++i) |
|
3858 |
{ |
|
3859 |
if (iCachedBlocks[i] == aMdAddr) |
|
3860 |
{ |
|
3861 |
TUint8* raby = IdxToCchMem(i); |
|
3862 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:gcb:%x", (TUint32) raby)); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3863 |
OstTraceFunctionExitExt( DMMCMEDIADRIVERFLASH_GETCACHEDBLOCK_EXIT1, this, ( TUint )( raby ) ); |
0 | 3864 |
return raby; |
3865 |
} |
|
3866 |
} |
|
3867 |
||
3868 |
__KTRACE_OPT(KPBUSDRV, Kern::Printf("<mmd:gcb:0")); |
|
39
5d2844f35677
Revision: 201004
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
33
diff
changeset
|
3869 |
OstTraceFunctionExit1( DMMCMEDIADRIVERFLASH_GETCACHEDBLOCK_EXIT2, this ); |
0 | 3870 |
return 0; |
3871 |
} |
|
3872 |
#endif // _DEBUG_CACHE |
|
3873 |
||
3874 |
||
3875 |
#if defined(__TEST_PAGING_MEDIA_DRIVER__) |
|
3876 |
/** |
|
3877 |
Handles a ControlIO request to the MMC media driver. |
|
3878 |
made by one of the MMC paging tests |
|
3879 |
||
3880 |
@internalTechnology |
|
3881 |
||
3882 |
@return Corresponding Symbian OS error code |
|
3883 |
*/ |
|
3884 |
TInt DMmcMediaDriverFlash::HandleControlIORequest() |
|
3885 |
{ |
|
3886 |
const TInt command = iCurrentReq->Int0(); |
|
3887 |
TAny* aParam1 = iCurrentReq->Ptr1(); |
|
3888 |
// TAny* aParam2 = iCurrentReq->Ptr2(); |
|
3889 |
||
3890 |
TInt r = KErrCompletion; |
|
3891 |
||
3892 |
__KTRACE_OPT(KLOCDPAGING,Kern::Printf("[MD : ] HandleControlIORequest aCommand: 0x%x", command)); |
|
3893 |
||
3894 |
||
3895 |
switch (command) |
|
3896 |
{ |
|
3897 |
case KMmcGetStats: |
|
3898 |
{ |
|
3899 |
DThread* pC = iCurrentReq->Client(); |
|
3900 |
DThread* pT = iCurrentReq->RemoteThread(); |
|
3901 |
if (!pT) |
|
3902 |
pT = pC; |
|
3903 |
Kern::ThreadRawWrite(pT, aParam1, &iMmcStats, sizeof(iMmcStats), pC); |
|
3904 |
||
3905 |
iMmcStats.iReqNormal=0; |
|
3906 |
iMmcStats.iNormalFragmenting=0; |
|
3907 |
iMmcStats.iClashFragmenting=0; |
|
3908 |
||
3909 |
break; |
|
3910 |
} |
|
3911 |
default: |
|
3912 |
r=KErrNotSupported; |
|
3913 |
break; |
|
3914 |
} |
|
3915 |
||
3916 |
return r; |
|
3917 |
} |
|
3918 |
#endif // __TEST_PAGING_MEDIA_DRIVER__ |
|
3919 |
||
3920 |
||
3921 |
||
3922 |
||
3923 |
DECLARE_EXTENSION_PDD() |
|
3924 |
{ |
|
3925 |
// NB if the media driver has been defined as a kernel extension in the .OBY/.IBY file |
|
3926 |
// i.e the "extension" keyword has been used rather than "device", then an instance of |
|
3927 |
// DPhysicalDeviceMediaMmcFlash will already have been created by InitExtension(). In this |
|
3928 |
// case the kernel will see that an object of the same name already exists and delete the |
|
3929 |
// new one. |
|
3930 |
return new DPhysicalDeviceMediaMmcFlash; |
|
3931 |
} |
|
3932 |
DECLARE_STANDARD_EXTENSION() |
|
3933 |
{ |
|
3934 |
__KTRACE_OPT(KBOOT,Kern::Printf("Creating MMCDrv PDD")); |
|
3935 |
||
3936 |
DPhysicalDeviceMediaMmcFlash* device = new DPhysicalDeviceMediaMmcFlash; |
|
3937 |
||
3938 |
TInt r; |
|
3939 |
if (device==NULL) |
|
3940 |
r=KErrNoMemory; |
|
3941 |
else |
|
3942 |
r=Kern::InstallPhysicalDevice(device); |
|
3943 |
__KTRACE_OPT(KBOOT,Kern::Printf("Installing MMCDrv PDD in kernel returned %d",r)); |
|
3944 |
||
3945 |
__KTRACE_OPT(KBOOT,Kern::Printf("Mmc extension entry point drive returns %d",r)); |
|
3946 |
return r; |
|
3947 |
} |
|
3948 |
||
3949 |