First public contribution.
1 // Copyright (c) 1996-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\drivers\medlfs\flash_media.cpp
18 #include <drivers/flash_media.h>
19 #include "variantmediadef.h"
21 _LIT(KPddName, "Media.Flash");
22 _LIT(KFlashThreadName,"FlashThread");
24 const TInt KFlashThreadPriority=24; // same as file server
26 GLDEF_C TDfcQue FlashDfcQ;
28 class DPhysicalDeviceMediaFlash : public DPhysicalDevice
31 DPhysicalDeviceMediaFlash();
32 virtual TInt Install();
33 virtual void GetCaps(TDes8& aDes) const;
34 virtual TInt Create(DBase*& aChannel, TInt aMediaId, const TDesC8* anInfo, const TVersion& aVer);
35 virtual TInt Validate(TInt aDeviceType, const TDesC8* anInfo, const TVersion& aVer);
36 virtual TInt Info(TInt aFunction, TAny* a1);
39 DPhysicalDeviceMediaFlash::DPhysicalDeviceMediaFlash()
45 iVersion=TVersion(KMediaDriverInterfaceMajorVersion,KMediaDriverInterfaceMinorVersion,KMediaDriverInterfaceBuildVersion);
48 TInt DPhysicalDeviceMediaFlash::Install()
50 // Install the media drives PDD.
54 return SetName(&KPddName);
57 void DPhysicalDeviceMediaFlash::GetCaps(TDes8& /*aDes*/) const
59 // Return the media drivers capabilities.
64 TInt DPhysicalDeviceMediaFlash::Create(DBase*& aChannel, TInt aMediaId, const TDesC8* /* anInfo */,const TVersion &aVer)
66 // Create an LFFS media driver.
69 if (!Kern::QueryVersionSupported(iVersion,aVer))
70 return KErrNotSupported;
71 DMediaDriverFlash *pD=DMediaDriverFlash::New(aMediaId);
75 r=pD->DoCreate(aMediaId);
77 pD->OpenMediaDriverComplete(KErrNone);
81 TInt DPhysicalDeviceMediaFlash::Validate(TInt aDeviceType, const TDesC8* /*anInfo*/, const TVersion& aVer)
83 if (!Kern::QueryVersionSupported(iVersion,aVer))
84 return KErrNotSupported;
85 if (aDeviceType!=MEDIA_DEVICE_LFFS)
86 return KErrNotSupported;
90 TInt DPhysicalDeviceMediaFlash::Info(TInt aFunction, TAny*)
92 // Return the priority of this media driver
95 if (aFunction==EPriority)
96 return KMediaDriverPriorityNormal;
97 return KErrNotSupported;
106 DMediaDriverFlash::DMediaDriverFlash(TInt aMediaId)
110 : DMediaDriver(aMediaId)
119 TInt DMediaDriverFlash::DoCreate(TInt /*aMediaId*/)
121 // Create the media driver.
125 TInt r=Initialise(); // interrogate FLASH etc.
128 TUint32 size=TotalSize();
129 SetTotalSizeInBytes(size);
138 A function called by the local media subsystem to deal with a request;
139 this is implemented by the generic layer of the LFFS media driver.
141 The implementation delegates the handling of reading, writing and erasing
142 to the specific layer's DoRead(), DoWrite() and DoErase() functions
145 @param aRequest An object that encapsulates information about the request.
147 @return A value indicating the result:
148 KErrNone, if the request has been sucessfully initiated;
149 KErrNotSupported, if the request cannot be handled by the device;
150 KMediaDriverDeferRequest, if the request cannot be handled
151 immediately because of an outstanding request (this request will be
152 deferred until the outstanding request has completed);
153 otherwise one of the other system-wide error codes.
155 @see DMediaDriverFlash::DoRead()
156 @see DMediaDriverFlash::DoWrite()
157 @see DMediaDriverFlash::DoErase()
159 TInt DMediaDriverFlash::Request(TLocDrvRequest& m)
161 TInt r=KErrNotSupported;
163 __KTRACE_OPT(KLOCDRV,Kern::Printf(">DMediaDriverFlash::Request %d",id));
164 if (id==DLocalDrive::ECaps)
166 TLocalDriveCapsV2& c=*(TLocalDriveCapsV2*)m.RemoteDes();
168 c.iSize=m.Drive()->iPartitionLen;
169 c.iPartitionType=m.Drive()->iPartitionType;
174 case DLocalDrive::ERead:
176 return KMediaDriverDeferRequest; // read already in progress so defer this one
182 case DLocalDrive::EWrite:
184 return KMediaDriverDeferRequest; // write already in progress so defer this one
190 case DLocalDrive::EFormat:
192 return KMediaDriverDeferRequest; // erase already in progress so defer this one
198 case DLocalDrive::EEnlarge:
199 case DLocalDrive::EReduce:
204 __KTRACE_OPT(KLOCDRV,Kern::Printf("<DMediaDriverFlash::Request %d",r));
206 DMediaDriver::Complete(m,r);
214 A function called by the local media subsystem to inform the driver
215 that the device should power down.
217 The default implementation does nothing.
219 void DMediaDriverFlash::NotifyPowerDown()
221 // no action required
228 A function called by the local media subsystem to inform the driver
229 that the device is to be immediately powered down.
231 The default implementation does nothing.
233 void DMediaDriverFlash::NotifyEmergencyPowerDown()
235 // no action required
242 Called by the specific layer of the LFFS media driver to inform
243 the generic layer that a request is complete.
245 @param aRequest The type of the request that is complete. This is one of
246 the TRequest enum values:
247 EReqRead, EReqWrite or EReqErase as appropriate.
248 @param aResult KErrNone, if the request has been completed successfully,
249 otherwise one if the other system-wide error codes.
251 @see DMediaDriverFlash::TRequest
253 void DMediaDriverFlash::Complete(TInt aRequest, TInt aResult)
255 __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:Complete(%d,%d)",aRequest,aResult));
256 TLocDrvRequest* pR=iRequests[aRequest];
257 iRequests[aRequest]=NULL;
258 DMediaDriver::Complete(*pR,aResult);
264 Called by the generic layer to get the capabilities of the flash device.
266 The default implementation is synchronous, and returns KErrCompletion.
268 @param aCaps On return, descriptor data contains capability information
269 about the flash device, in the form of a class derived from
270 TLocalDriveCapsV2. The size of the derived class should not exceed
271 KMaxLocalDriveCapsLength which is defined and used in
272 e32\drivers\locmedia\locmedia.cpp. If a larger sized capabilities
273 class is used, and this code is modified to write to member data
274 beyond KMaxLocalDriveCapsLength this will cause a fault.
276 @return KErrCompletion, if the operation has been done synchronously and is successful;
277 one of the other system wide error codes (not KErrNone), if
278 the operation has been done synchronously but UNSUCCESSFULLY;
279 KErrNone, if the operation is being done asynchronously.
280 @see TLocalDriveCapsV2
283 TInt DMediaDriverFlash::Caps(TLocalDriveCapsV2& caps)
285 caps.iType=EMediaFlash;
286 caps.iConnectionBusType=EConnectionBusInternal;
287 caps.iDriveAtt=KDriveAttLocal|KDriveAttInternal;
288 caps.iMediaAtt=KMediaAttFormattable;
289 caps.iBaseAddress=(TUint8*)TInternalRamDrive::Base();
290 caps.iFileSystemId=KDriveFileSysLFFS;
291 caps.iHiddenSectors=0;
292 caps.iEraseBlockSize=EraseBlockSize();
294 __KTRACE_OPT( KLOCDRV, Kern::Printf("MLFS: ) type=%d", caps.iType) );
295 __KTRACE_OPT( KLOCDRV, Kern::Printf("MLFS: ) connectionbustype=%d", caps.iConnectionBusType) );
296 __KTRACE_OPT( KLOCDRV, Kern::Printf("MLFS: ) driveatt=0x%x", caps.iDriveAtt) );
297 __KTRACE_OPT( KLOCDRV, Kern::Printf("MLFS: ) mediaatt=0x%x", caps.iMediaAtt) );
298 __KTRACE_OPT( KLOCDRV, Kern::Printf("MLFS: ) filesystemid=0x%x", caps.iFileSystemId) );
299 __KTRACE_OPT( KLOCDRV, Kern::Printf("MLFS: ) eraseblocksize=0x%x", caps.iEraseBlockSize) );
301 return KErrCompletion; // synchronous completion
308 A function called by the local media subsystem to get partition information
309 for the flash device.
311 It is called once the subsystem has been notified that the media driver
312 is open and has been succesfully initialised.
314 The function should be overriden by the specific layer of
315 the LFFS media driver.
317 The default implementation is synchronous
320 - the partition count to 1, meaning that there is only the one partition.
321 - the partition base address to 0.
322 - the partition length to the total size of the flash device.
323 - the size of the media to the total size of the flash device.
324 - the partition type to KPartitionTypeEneaLFFS.
326 @param anInfo An object that, on successful return, contains
327 the partition information.
329 @return KErrNone, if retrieval of partition information is to be
331 KErrCompletion, if retrieval of partition information has been
332 done synchronously, and successfully;
333 one of the other system-wide error codes, if retrieval of partition
334 information has been done synchronously, but unsuccessfully.
336 TInt DMediaDriverFlash::PartitionInfo(TPartitionInfo& aInfo)
338 aInfo.iPartitionCount = 1;
339 aInfo.iEntry[0].iPartitionBaseAddr = 0;
340 aInfo.iEntry[0].iPartitionLen = TotalSizeInBytes();
341 aInfo.iEntry[0].iPartitionType = KPartitionTypeEneaLFFS;
343 aInfo.iMediaSizeInBytes = TotalSizeInBytes();
344 return KErrCompletion;
348 DECLARE_EXTENSION_PDD()
350 return new DPhysicalDeviceMediaFlash;
353 static const TInt LffsDriveNumbers[LFFS_DRIVECOUNT]={LFFS_DRIVELIST};
354 _LIT(KFlashDriveName,LFFS_DRIVENAME);
356 DECLARE_STANDARD_EXTENSION()
358 __KTRACE_OPT(KBOOT,Kern::Printf("Registering FLASH drive"));
359 if (Kern::SuperPage().iCpuId & KCpuIdISS)
360 return KErrNone; // no FLASH on ARMULATOR
362 TInt r=Kern::DfcQInit(&FlashDfcQ,KFlashThreadPriority,&KFlashThreadName);
365 DPrimaryMediaBase* pM=new DPrimaryMediaBase;
368 pM->iDfcQ=&FlashDfcQ;
369 r=LocDrv::RegisterMediaDevice(EFixedMedia1,LFFS_DRIVECOUNT,&LffsDriveNumbers[0],pM,LFFS_NUMMEDIA,KFlashDriveName);
374 __KTRACE_OPT(KBOOT,Kern::Printf("Registering FLASH drive - return %d",r));