kernel/eka/drivers/medlfs/flash_media.cpp
changeset 0 a41df078684a
child 6 0173bcd7697c
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32\drivers\medlfs\flash_media.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <drivers/flash_media.h>
       
    19 #include "variantmediadef.h"
       
    20 
       
    21 _LIT(KPddName, "Media.Flash");
       
    22 _LIT(KFlashThreadName,"FlashThread");
       
    23 
       
    24 const TInt KFlashThreadPriority=24;	// same as file server
       
    25 
       
    26 GLDEF_C TDfcQue FlashDfcQ;
       
    27 
       
    28 class DPhysicalDeviceMediaFlash : public DPhysicalDevice
       
    29 	{
       
    30 public:
       
    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);
       
    37 	};
       
    38 								
       
    39 DPhysicalDeviceMediaFlash::DPhysicalDeviceMediaFlash()
       
    40 //
       
    41 // Constructor
       
    42 //
       
    43 	{
       
    44 	iUnitsMask=0x2;
       
    45 	iVersion=TVersion(KMediaDriverInterfaceMajorVersion,KMediaDriverInterfaceMinorVersion,KMediaDriverInterfaceBuildVersion);
       
    46 	}
       
    47 
       
    48 TInt DPhysicalDeviceMediaFlash::Install()
       
    49 //
       
    50 // Install the media drives PDD.
       
    51 //
       
    52 	{
       
    53 
       
    54 	return SetName(&KPddName);
       
    55 	}
       
    56 
       
    57 void DPhysicalDeviceMediaFlash::GetCaps(TDes8& /*aDes*/) const
       
    58 //
       
    59 // Return the media drivers capabilities.
       
    60 //
       
    61 	{
       
    62 	}
       
    63 
       
    64 TInt DPhysicalDeviceMediaFlash::Create(DBase*& aChannel, TInt aMediaId, const TDesC8* /* anInfo */,const TVersion &aVer)
       
    65 //
       
    66 // Create an LFFS media driver.
       
    67 //
       
    68 	{
       
    69 	if (!Kern::QueryVersionSupported(iVersion,aVer))
       
    70 		return KErrNotSupported;
       
    71 	DMediaDriverFlash *pD=DMediaDriverFlash::New(aMediaId);
       
    72 	aChannel=pD;
       
    73 	TInt r=KErrNoMemory;
       
    74 	if (pD)
       
    75 		r=pD->DoCreate(aMediaId);
       
    76 	if (r==KErrNone)
       
    77 		pD->OpenMediaDriverComplete(KErrNone);
       
    78 	return r;
       
    79 	}
       
    80 
       
    81 TInt DPhysicalDeviceMediaFlash::Validate(TInt aDeviceType, const TDesC8* /*anInfo*/, const TVersion& aVer)
       
    82 	{
       
    83 	if (!Kern::QueryVersionSupported(iVersion,aVer))
       
    84 		return KErrNotSupported;
       
    85 	if (aDeviceType!=MEDIA_DEVICE_LFFS)
       
    86 		return KErrNotSupported;
       
    87 	return KErrNone;
       
    88 	}
       
    89 
       
    90 TInt DPhysicalDeviceMediaFlash::Info(TInt aFunction, TAny*)
       
    91 //
       
    92 // Return the priority of this media driver
       
    93 //
       
    94 	{
       
    95 	if (aFunction==EPriority)
       
    96 		return KMediaDriverPriorityNormal;
       
    97 	return KErrNotSupported;
       
    98 	}
       
    99 
       
   100 
       
   101 
       
   102 
       
   103 /**
       
   104 @internalComponent
       
   105 */
       
   106 DMediaDriverFlash::DMediaDriverFlash(TInt aMediaId)
       
   107 //
       
   108 // Constructor.
       
   109 //
       
   110 	:	DMediaDriver(aMediaId)
       
   111 	{}
       
   112 
       
   113 
       
   114 
       
   115 
       
   116 /**
       
   117 @internalComponent
       
   118 */
       
   119 TInt DMediaDriverFlash::DoCreate(TInt /*aMediaId*/)
       
   120 //
       
   121 // Create the media driver.
       
   122 //
       
   123 	{
       
   124 	
       
   125 	TInt r=Initialise();		// interrogate FLASH etc.
       
   126 	if (r==KErrNone)
       
   127 		{
       
   128 		TUint32 size=TotalSize();
       
   129 		SetTotalSizeInBytes(size);
       
   130 		}
       
   131 	return r;
       
   132 	}
       
   133 
       
   134 
       
   135 
       
   136 
       
   137 /** 
       
   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.
       
   140 
       
   141 The implementation delegates the handling of reading, writing and erasing
       
   142 to the specific layer's DoRead(), DoWrite() and DoErase() functions 
       
   143 respectively.
       
   144 	
       
   145 @param aRequest An object that encapsulates information about the request.
       
   146     
       
   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.
       
   154         
       
   155 @see DMediaDriverFlash::DoRead()        
       
   156 @see DMediaDriverFlash::DoWrite()
       
   157 @see DMediaDriverFlash::DoErase()
       
   158 */
       
   159 TInt DMediaDriverFlash::Request(TLocDrvRequest& m)
       
   160 	{
       
   161 	TInt r=KErrNotSupported;
       
   162 	TInt id=m.Id();
       
   163 	__KTRACE_OPT(KLOCDRV,Kern::Printf(">DMediaDriverFlash::Request %d",id));
       
   164 	if (id==DLocalDrive::ECaps)
       
   165 		{
       
   166   		TLocalDriveCapsV2& c=*(TLocalDriveCapsV2*)m.RemoteDes();
       
   167 		r=Caps(c);
       
   168 		c.iSize=m.Drive()->iPartitionLen;
       
   169 		c.iPartitionType=m.Drive()->iPartitionType;
       
   170 		return r;
       
   171 		}
       
   172 	switch (id)
       
   173 		{
       
   174 		case DLocalDrive::ERead:
       
   175 			if (iReadReq)
       
   176 				return KMediaDriverDeferRequest;	// read already in progress so defer this one
       
   177 			iReadReq=&m;
       
   178 			r=DoRead();
       
   179 			if (r!=KErrNone)
       
   180 				iReadReq=NULL;
       
   181 			break;
       
   182 		case DLocalDrive::EWrite:
       
   183 			if (iWriteReq)
       
   184 				return KMediaDriverDeferRequest;	// write already in progress so defer this one
       
   185 			iWriteReq=&m;
       
   186 			r=DoWrite();
       
   187 			if (r!=KErrNone)
       
   188 				iWriteReq=NULL;
       
   189 			break;
       
   190 		case DLocalDrive::EFormat:
       
   191 			if (iEraseReq)
       
   192 				return KMediaDriverDeferRequest;	// erase already in progress so defer this one
       
   193 			iEraseReq=&m;
       
   194 			r=DoErase();
       
   195 			if (r!=KErrNone)
       
   196 				iEraseReq=NULL;
       
   197 			break;
       
   198 		case DLocalDrive::EEnlarge:
       
   199 		case DLocalDrive::EReduce:
       
   200 		default:
       
   201 			r=KErrNotSupported;
       
   202 			break;
       
   203 		}
       
   204 	__KTRACE_OPT(KLOCDRV,Kern::Printf("<DMediaDriverFlash::Request %d",r));
       
   205 	if (r<0)
       
   206 		DMediaDriver::Complete(m,r);
       
   207 	return r;
       
   208 	}
       
   209 
       
   210 
       
   211 
       
   212 
       
   213 /**
       
   214 A function called by the local media subsystem to inform the driver
       
   215 that the device should power down.
       
   216 
       
   217 The default implementation does nothing.
       
   218 */
       
   219 void DMediaDriverFlash::NotifyPowerDown()
       
   220 	{
       
   221 	// no action required
       
   222 	}
       
   223 
       
   224 
       
   225 
       
   226 
       
   227 /**
       
   228 A function called by the local media subsystem to inform the driver
       
   229 that the device is to be immediately powered down.
       
   230 
       
   231 The default implementation does nothing.
       
   232 */
       
   233 void DMediaDriverFlash::NotifyEmergencyPowerDown()
       
   234 	{
       
   235 	// no action required
       
   236 	}
       
   237 
       
   238 
       
   239 
       
   240 
       
   241 /**
       
   242 Called by the specific layer of the LFFS media driver to inform
       
   243 the generic layer that a request is complete.
       
   244     
       
   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.
       
   250                 
       
   251 @see DMediaDriverFlash::TRequest                
       
   252 */
       
   253 void DMediaDriverFlash::Complete(TInt aRequest, TInt aResult)
       
   254 	{
       
   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);
       
   259 	}
       
   260 
       
   261 
       
   262 
       
   263 /**
       
   264 Called by the generic layer to get the capabilities of the flash device.
       
   265 
       
   266 The default implementation is synchronous, and returns KErrCompletion.
       
   267 
       
   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.
       
   275 
       
   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
       
   281 */
       
   282 
       
   283 TInt DMediaDriverFlash::Caps(TLocalDriveCapsV2& caps)
       
   284 	{
       
   285 	caps.iType=EMediaFlash;
       
   286 	caps.iBattery=EBatNotSupported;
       
   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();
       
   293 
       
   294     __KTRACE_OPT( KLOCDRV, Kern::Printf("MLFS: ) type=%d", caps.iType) );
       
   295     __KTRACE_OPT( KLOCDRV, Kern::Printf("MLFS: ) battery=%d", caps.iBattery) );
       
   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) );
       
   300 
       
   301 	return KErrCompletion;	// synchronous completion
       
   302 	}
       
   303 
       
   304 
       
   305 
       
   306 
       
   307 /**
       
   308 A function called by the local media subsystem to get partition information
       
   309 for the flash device.
       
   310 	
       
   311 It is called once the subsystem has been notified that the media driver
       
   312 is open and has been succesfully initialised.
       
   313 
       
   314 The function should be overriden by the specific layer of
       
   315 the LFFS media driver.
       
   316 
       
   317 The default implementation is synchronous
       
   318 and sets:
       
   319 
       
   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.
       
   325 
       
   326 @param anInfo An object that, on successful return, contains
       
   327               the partition information.
       
   328 	
       
   329 @return KErrNone, if retrieval of partition information is to be
       
   330         done asynchronously;
       
   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.
       
   335 */
       
   336 TInt DMediaDriverFlash::PartitionInfo(TPartitionInfo& aInfo)
       
   337 	{
       
   338 	aInfo.iPartitionCount				= 1;
       
   339 	aInfo.iEntry[0].iPartitionBaseAddr	= 0;
       
   340 	aInfo.iEntry[0].iPartitionLen		= TotalSizeInBytes();
       
   341 	aInfo.iEntry[0].iPartitionType		= KPartitionTypeEneaLFFS;
       
   342 	
       
   343 	aInfo.iMediaSizeInBytes				= TotalSizeInBytes();
       
   344 	return KErrCompletion;
       
   345 	}
       
   346 
       
   347 
       
   348 DECLARE_EXTENSION_PDD()
       
   349 	{
       
   350 	return new DPhysicalDeviceMediaFlash;
       
   351 	}
       
   352 
       
   353 static const TInt LffsDriveNumbers[LFFS_DRIVECOUNT]={LFFS_DRIVELIST};	
       
   354 _LIT(KFlashDriveName,LFFS_DRIVENAME);
       
   355 
       
   356 DECLARE_STANDARD_EXTENSION()
       
   357 	{
       
   358 	__KTRACE_OPT(KBOOT,Kern::Printf("Registering FLASH drive"));
       
   359 	if (Kern::SuperPage().iCpuId & KCpuIdISS)
       
   360 		return KErrNone;	// no FLASH on ARMULATOR
       
   361 
       
   362 	TInt r=Kern::DfcQInit(&FlashDfcQ,KFlashThreadPriority,&KFlashThreadName);
       
   363 	if (r==KErrNone)
       
   364 		{
       
   365 		DPrimaryMediaBase* pM=new DPrimaryMediaBase;
       
   366 		if (pM)
       
   367 			{
       
   368 			pM->iDfcQ=&FlashDfcQ;
       
   369 			r=LocDrv::RegisterMediaDevice(EFixedMedia1,LFFS_DRIVECOUNT,&LffsDriveNumbers[0],pM,LFFS_NUMMEDIA,KFlashDriveName);
       
   370 			if (r==KErrNone)
       
   371 				pM->iMsgQ.Receive();
       
   372 			}
       
   373 		}
       
   374 	__KTRACE_OPT(KBOOT,Kern::Printf("Registering FLASH drive - return %d",r));
       
   375 	return r;
       
   376 	}
       
   377