os/kernelhwsrv/kernel/eka/drivers/medlfs/flash_media.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
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".
     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.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();
   293 
   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) );
   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