emulator/emulatorbsp/specific/lffsdev.cpp
changeset 0 cec860690d41
equal deleted inserted replaced
-1:000000000000 0:cec860690d41
       
     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 "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 // wins\specific\lffsdev.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <flash_media.h>
       
    19 #include <emulator.h>
       
    20 #include <property.h>
       
    21 
       
    22 #define FLASH_FAULT()	Kern::Fault("LFFSDEV",__LINE__)
       
    23 
       
    24 //#define M18_EMULATION // Test for Control Mode operation
       
    25 
       
    26 /********************************************
       
    27  * Driver definitions
       
    28  ********************************************/
       
    29 
       
    30 /** LFFS image name */
       
    31 const CHAR KLfsFileName[] = "LFSLDRV.BIN";
       
    32 
       
    33 
       
    34 //-- default values for LFFS related entries in "epoc.ini" file
       
    35 const TInt      KDefaultFlashSize = 0x400000;   //-- "FlashSize"        entry, default 4MB
       
    36 const TInt      KEraseBlockSize   = 0x20000;	//-- "FlashEraseSize"   entry, default 128KB
       
    37 const TUint32   KFlashEraseTime   =	1000000;	//-- "FlashEraseTime"   entry, default 1s
       
    38 const TInt      KWriteBlockSize   = 64;         //-- "FlashWriteSize"   entry
       
    39 const TInt      KFlashWriteTime   = 406;		//-- "FlashWriteTime"   entry, default 406us
       
    40 const TInt      KResumeTime       = 5000;		//-- "FlashResumeTime"  entry, default 5ms
       
    41 
       
    42 //-- other possible LFFS related entries in "epoc.ini" file:
       
    43 //-- "FlashHoldOffTime"   default value = iEraseTime/10
       
    44 
       
    45 //-- "FlashForceImgMount" default value = 0. If not 0 LFFS image will be mounted as it is, even if it doesn't have TLfsParams structure in the end.
       
    46 //-- Moreover, it won't be zero filled and TLfsParams structure won't be written at the end of the image file.
       
    47 //-- shall be useful for dealing with real images from the real devices
       
    48 
       
    49 
       
    50 /** 
       
    51     This cunning structure is supposed to be at the very end of the LFFS image file. If it is not foung there, 
       
    52     the image gets zero-filled (depends on "FlashForceImgMount" flag in epoc.ini). 
       
    53 */
       
    54 
       
    55 struct TLfsParams
       
    56 	{
       
    57 	TInt iEraseSize;
       
    58 	};
       
    59 
       
    60 #ifdef _DEBUG
       
    61 /***************************************************
       
    62  * ControlIO command types - for debug builds, only
       
    63  ***************************************************/
       
    64 
       
    65 enum TCtrlIoTypes
       
    66 	{
       
    67 	//KCtrlIoRww=0,
       
    68 	KCtrlIoTimeout=1
       
    69 	};
       
    70 #endif
       
    71 
       
    72 
       
    73 const TInt KDataBufSize=1024;
       
    74 
       
    75 /********************************************
       
    76  * Media driver class
       
    77  ********************************************/
       
    78 class DMediaDriverFlashWin32 : public DMediaDriverFlash
       
    79 	{
       
    80 public:
       
    81 	enum TState
       
    82 		{
       
    83 		EIdle=0,
       
    84 		EWriting=1,
       
    85 		EEraseNoSuspend=2,
       
    86 		EErase=3,
       
    87 		ESuspendPending=4,
       
    88 		ESuspending=5,
       
    89 		ESuspended=6,
       
    90 		EErasePending=7
       
    91 		};
       
    92 public:
       
    93 	DMediaDriverFlashWin32(TInt aMediaId);
       
    94 public:
       
    95 	// replacing pure virtual - FLASH device specific stuff
       
    96 	virtual TInt Initialise();
       
    97 	virtual TUint32 EraseBlockSize();
       
    98 	virtual TUint32 TotalSize();
       
    99 	virtual TInt DoRead();
       
   100 	virtual TInt DoWrite();
       
   101 	virtual TInt DoErase();
       
   102 	virtual TInt Caps(TLocalDriveCapsV2& caps);
       
   103 public:
       
   104 	void HandleEvent();
       
   105 	void StartTimer(TInt aMicros);
       
   106 	void StartErase();
       
   107 	void SuspendErase();
       
   108 	void CompleteErase();
       
   109 	void CompleteWrite();
       
   110 	void CompleteSuspend();
       
   111 	void StartPendingRW();
       
   112 	void ReadFlashParameters();
       
   113 public:
       
   114 	static void TimerFn(TAny* aPtr);
       
   115 	static void EventDfc(TAny* aPtr);
       
   116 #ifdef _DEBUG
       
   117 public:
       
   118     enum TCtrlIoState {/*EIdle=0,ECtrlIoWaitWr=1,ECtrlIoWaitRd=2,ECtrlIoWrActive=3,*/ECtrlIoTimeOutPrep=4};
       
   119     TInt ControlIO(TInt aCommand,TAny* aParam1,TAny* /*aParam2*/);
       
   120 	TInt Request(TLocDrvRequest& m);
       
   121 #endif
       
   122 public:
       
   123 	TState iState;
       
   124 	
       
   125 	TInt iSize;
       
   126 	TInt iEraseBlockSize;
       
   127 	TInt iEraseTime;
       
   128 	TInt iSuspendHoldOffTime;
       
   129 	TInt iResumeTime;
       
   130 	TInt iWriteBlockSize;
       
   131 	TInt iWriteTime;
       
   132     
       
   133 	HANDLE iFile;
       
   134 	HANDLE iMapping;
       
   135 	TUint8* iBase;
       
   136 	TUint8* iData;		// data being written
       
   137 	
       
   138 	NTimer iTimer;
       
   139 	TDfc iEventDfc;
       
   140 	TUint32 iTickPeriod;
       
   141 	TUint32 iEraseCounter;
       
   142 	TUint32 iErasePos;
       
   143 	TInt iTimerExtra;
       
   144 
       
   145 #ifdef _DEBUG
       
   146 public:
       
   147     TUint8 iCtrlIoState;
       
   148 #endif
       
   149 	};
       
   150 
       
   151 DMediaDriverFlashWin32::DMediaDriverFlashWin32(TInt aMediaId)
       
   152 	:	DMediaDriverFlash(aMediaId),
       
   153 		iTimer(&TimerFn,this),
       
   154 		iEventDfc(&EventDfc,this,NULL,2),
       
   155 		iTickPeriod(NKern::TickPeriod())
       
   156 	{
       
   157 	// iState=EIdle;
       
   158 #ifdef _DEBUG
       
   159     //iCtrlIoState=EIdle;
       
   160 #endif
       
   161 
       
   162 	}
       
   163 
       
   164 void DMediaDriverFlashWin32::ReadFlashParameters()
       
   165 //
       
   166 // Read the flash parameters from the ini file, or use defaults
       
   167 //
       
   168 	{
       
   169    
       
   170 	iSize = Property::GetInt("FlashSize", KDefaultFlashSize);
       
   171 
       
   172 	TInt nblocks = Property::GetInt("FlashEraseBlocks", 0);
       
   173 	if (nblocks == 0)
       
   174 		nblocks = iSize/Property::GetInt("FlashEraseSize", KEraseBlockSize);
       
   175 
       
   176 	iEraseBlockSize = iSize / nblocks;
       
   177 	__ASSERT_ALWAYS(iEraseBlockSize * nblocks == iSize, FLASH_FAULT());
       
   178 	__ASSERT_ALWAYS((iEraseBlockSize & (iEraseBlockSize-1)) == 0, FLASH_FAULT());
       
   179 
       
   180 	iEraseTime = Property::GetInt("FlashEraseTime", KFlashEraseTime);
       
   181 	
       
   182 	iSuspendHoldOffTime = Property::GetInt("FlashHoldOffTime", iEraseTime/10);
       
   183 	iResumeTime = Property::GetInt("FlashResumeTime", KResumeTime);
       
   184 	iWriteBlockSize = Property::GetInt("FlashWriteSize", KWriteBlockSize);
       
   185 	__ASSERT_ALWAYS((iWriteBlockSize & (iWriteBlockSize-1)) == 0, FLASH_FAULT());
       
   186 
       
   187 	iWriteTime = Property::GetInt("FlashWriteTime", KFlashWriteTime);
       
   188 	
       
   189 	}
       
   190 
       
   191 TInt DMediaDriverFlashWin32::Initialise()
       
   192 	{
       
   193 	iEventDfc.SetDfcQ(iPrimaryMedia->iDfcQ);
       
   194 	iData=(TUint8*)Kern::Alloc(KDataBufSize);
       
   195 	if (!iData)
       
   196 		return KErrNoMemory;
       
   197 
       
   198 	ReadFlashParameters();
       
   199 
       
   200 	// locate/open the file that models the flash
       
   201 	CHAR filename[MAX_PATH];
       
   202 	strcpy(filename, Property::GetString("EmulatorMediaPath"));
       
   203 	if (!Emulator::CreateAllDirectories(filename))
       
   204 		return Emulator::LastError();
       
   205 	strcat(filename, KLfsFileName);
       
   206 	
       
   207 	iFile = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, NULL);
       
   208 	if (iFile == INVALID_HANDLE_VALUE)
       
   209 		return Emulator::LastError();
       
   210 
       
   211 	TLfsParams p;
       
   212 	p.iEraseSize = -1;
       
   213 	DWORD bytes;
       
   214 	TBool valid;
       
   215 	
       
   216     //-- try to read TLfsParams structure from the end of the image file.
       
   217 	if (SetFilePointer(iFile, iSize, NULL, FILE_BEGIN) != -1
       
   218 		&& ReadFile(iFile, &p, sizeof(TLfsParams), &bytes, NULL)
       
   219 		&& p.iEraseSize == iEraseBlockSize)
       
   220 	{
       
   221         valid = ETrue; //-- read it OK.
       
   222 	}
       
   223 	else
       
   224 	{//-- couldn't read TLfsParams structure from the end of the image file.
       
   225      //-- if "FlashForceImgMount" parameter from epoc.ini is 0 or not present,
       
   226      //-- zero-fill the lffs image file and write TLfsParams structure at the end of the file.
       
   227 
       
   228 		const TInt forceImgMount = Property::GetInt("FlashForceImgMount", 0);
       
   229         if(!forceImgMount)
       
   230 		{
       
   231 		p.iEraseSize = iEraseBlockSize;
       
   232 		if (SetFilePointer(iFile,iSize, NULL, FILE_BEGIN) == -1
       
   233 			|| !WriteFile(iFile, &p, sizeof(p), &bytes, NULL)
       
   234 			|| !SetEndOfFile(iFile))
       
   235 			return Emulator::LastError();
       
   236 		    
       
   237 		valid = EFalse;
       
   238 		}
       
   239         else
       
   240         {//-- mount LFFS image forcingly.
       
   241             valid = ETrue;
       
   242         }
       
   243 	}
       
   244 
       
   245 	iMapping = CreateFileMappingA(iFile, NULL, PAGE_READWRITE, 0, iSize, NULL);
       
   246 	if (iMapping == NULL)
       
   247 		return Emulator::LastError();
       
   248 
       
   249 	iBase = (TUint8*)MapViewOfFile(iMapping, FILE_MAP_WRITE, 0, 0, iSize);
       
   250 	if (iBase == NULL)
       
   251 		return Emulator::LastError();
       
   252 
       
   253 	//-- zero-fill media image it doesn't contain TLfsParams data at the very end.
       
   254 	if (!valid)
       
   255 	    {
       
   256 		memclr(iBase, iSize);
       
   257         }
       
   258 
       
   259 	return KErrNone;
       
   260 	}
       
   261 
       
   262 TUint32 DMediaDriverFlashWin32::EraseBlockSize()
       
   263 	{
       
   264 	return iEraseBlockSize;
       
   265 	}
       
   266 
       
   267 TUint32 DMediaDriverFlashWin32::TotalSize()
       
   268 	{
       
   269 	return iSize;
       
   270 	}
       
   271 
       
   272 TInt DMediaDriverFlashWin32::DoRead()
       
   273 	{
       
   274 	if (iWriteReq)
       
   275 		return 1;	// write in progress so defer read
       
   276 	
       
   277 	__KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:DoRead"));
       
   278 
       
   279 	if (iState==EErasePending)
       
   280 		{
       
   281 		iTimer.Cancel();
       
   282 		iState = ESuspended;
       
   283 		}
       
   284 	if (iState==EIdle || iState==ESuspended)
       
   285 		{
       
   286 		// can do the read now
       
   287 		TInt pos=(TInt)iReadReq->Pos();
       
   288 		TInt len=(TInt)iReadReq->Length();
       
   289 
       
   290 		TPtrC8 des(iBase+pos,len);
       
   291 		TInt r=iReadReq->WriteRemote(&des,0);
       
   292 		Complete(EReqRead,r);
       
   293 		if (iState==ESuspended)
       
   294 			StartErase();
       
   295 		}
       
   296 	else if (iState==EErase)
       
   297 		{
       
   298 		// erase in progress - suspend it
       
   299 		SuspendErase();
       
   300 		}
       
   301 	else if (iState==EEraseNoSuspend)
       
   302 		iState=ESuspendPending;
       
   303 	// wait for suspend to complete
       
   304 	return KErrNone;
       
   305 	}
       
   306 
       
   307 TInt DMediaDriverFlashWin32::DoWrite()
       
   308 	{
       
   309 	if (iReadReq)
       
   310 		return 1;	// read in progress so defer write
       
   311 
       
   312 	if (iState==EErasePending)
       
   313 		{
       
   314 		iTimer.Cancel();
       
   315 		iState = ESuspended;
       
   316 		}
       
   317 	if (iState==EIdle || iState==ESuspended)
       
   318 		{
       
   319 		// can start the write now
       
   320 		__KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:Write Pos=%08x Length=%08x RemDesOff=%08x",
       
   321 											(TInt)iWriteReq->Pos(),(TInt)iWriteReq->Length(),iWriteReq->RemoteDesOffset()));
       
   322 		if (iState==EIdle)
       
   323 			iState=EWriting;
       
   324 		TInt pos = (TInt)iWriteReq->Pos();
       
   325 		TInt end = pos + (TInt)iWriteReq->Length();
       
   326 		pos &= ~(iWriteBlockSize-1);
       
   327 		end = (end + iWriteBlockSize-1) & ~(iWriteBlockSize-1);
       
   328 		StartTimer(((end-pos)/iWriteBlockSize) * iWriteTime);
       
   329 		}
       
   330 	else if (iState==EErase)
       
   331 		{
       
   332 		// erase in progress - suspend it
       
   333 		SuspendErase();
       
   334 		}
       
   335 	else if (iState==EEraseNoSuspend)
       
   336 		iState=ESuspendPending;
       
   337 	// wait for suspend to complete
       
   338 	return KErrNone;
       
   339 	}
       
   340 
       
   341 void DMediaDriverFlashWin32::CompleteWrite()
       
   342 //
       
   343 // Do the actual write in the completion
       
   344 // Transfer data in blocks from the client and AND it to the 'flash'
       
   345 //
       
   346 	{
       
   347 	__KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:WriteComplete"));
       
   348 
       
   349 	TInt r = KErrNone;
       
   350 	TUint8* flash = iBase + (TInt)iWriteReq->Pos();
       
   351 	TInt len = (TInt)iWriteReq->Length();
       
   352 	TInt offset = 0;
       
   353 	while (len > 0)
       
   354 		{
       
   355 		TInt size = Min(len, KDataBufSize);
       
   356 		TPtr8 des(iData,size);
       
   357 		r = iWriteReq->ReadRemote(&des, offset);
       
   358 		if (r!=KErrNone)
       
   359 			break;
       
   360 		len -= size;
       
   361 		offset += size;
       
   362 		const TUint8* ptr = iData;
       
   363 		do
       
   364 			{
       
   365 			*flash++ &= *ptr++;
       
   366 			} while (--size > 0);
       
   367 		}
       
   368 
       
   369 	if (iState == EWriting)
       
   370 		iState = EIdle;
       
   371 	Complete(EReqWrite,r);
       
   372 	if (iState == ESuspended)
       
   373 		StartErase();
       
   374 	}
       
   375 
       
   376 TInt DMediaDriverFlashWin32::DoErase()
       
   377 	{
       
   378 	if (iReadReq || iWriteReq)
       
   379 		return 1;		// read or write in progress so defer this request
       
   380 	TInt pos=(TUint32)iEraseReq->Pos();
       
   381 	TInt len=(TUint32)iEraseReq->Length();
       
   382 	__KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:DoErase %d@%08x",len,pos));
       
   383 	if (len!=iEraseBlockSize)
       
   384 		return KErrArgument;	// only allow single-block erase
       
   385 	if (pos & (iEraseBlockSize-1))
       
   386 		return KErrArgument;	// start position must be on erase block boundary
       
   387 	__ASSERT_ALWAYS(iState==EIdle,FLASH_FAULT());
       
   388 	iErasePos=pos;
       
   389 	StartErase();
       
   390 	return KErrNone;
       
   391 	}
       
   392 
       
   393 void DMediaDriverFlashWin32::StartTimer(TInt aMicros)
       
   394 	{
       
   395 	aMicros += iTimerExtra - (iTickPeriod>>1);
       
   396 	if (aMicros < 0)
       
   397 		{
       
   398 		iTimerExtra = aMicros + (iTickPeriod>>1);
       
   399 		iEventDfc.Enque();		// go off 'immediately'
       
   400 		}
       
   401 	else
       
   402 		{
       
   403 		iTimerExtra = 0;
       
   404 		iTimer.OneShot(aMicros / iTickPeriod);
       
   405 		}
       
   406 	}
       
   407 
       
   408 void DMediaDriverFlashWin32::TimerFn(TAny* aPtr)
       
   409 	{
       
   410 	((DMediaDriverFlashWin32*)aPtr)->iEventDfc.Add();
       
   411 	}
       
   412 
       
   413 void DMediaDriverFlashWin32::EventDfc(TAny* aPtr)
       
   414 	{
       
   415 	((DMediaDriverFlashWin32*)aPtr)->HandleEvent();
       
   416 	}
       
   417 
       
   418 void DMediaDriverFlashWin32::HandleEvent()
       
   419 	{
       
   420 	__KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:Event %d", iState));
       
   421 	switch (iState)
       
   422 		{
       
   423 	case ESuspended:
       
   424 	case EWriting:	// write completed
       
   425 		{
       
   426 #ifdef _DEBUG
       
   427 		if(iCtrlIoState==ECtrlIoTimeOutPrep)
       
   428 			{
       
   429 			iState=EIdle;
       
   430 			iCtrlIoState=EIdle;
       
   431 			Complete(EReqWrite,KErrNotReady);
       
   432 			}
       
   433 		else
       
   434 #endif
       
   435 			CompleteWrite();
       
   436 		break;
       
   437 		}
       
   438 	case EEraseNoSuspend:
       
   439 		{
       
   440 #ifdef _DEBUG
       
   441 		if(iCtrlIoState==ECtrlIoTimeOutPrep)
       
   442 			{
       
   443 			iState=EIdle;
       
   444 			iCtrlIoState=EIdle;
       
   445 			Complete(EReqErase,KErrNotReady);
       
   446 			}
       
   447 		else
       
   448 			{
       
   449 #endif
       
   450 		TInt remain = iEraseCounter - NKern::TickCount();
       
   451 		if (remain <= 0)
       
   452 			CompleteErase();
       
   453 		else
       
   454 			{
       
   455 			iState=EErase;
       
   456 			StartTimer(remain * iTickPeriod);
       
   457 			}
       
   458 #ifdef _DEBUG
       
   459 			}
       
   460 #endif
       
   461 		break;
       
   462 		}
       
   463 	case EErasePending:
       
   464 		StartErase();
       
   465 		break;
       
   466 	case EErase:	// erase completed
       
   467 		CompleteErase();
       
   468 		break;
       
   469 	case ESuspendPending:
       
   470 		if (TInt(iEraseCounter - NKern::TickCount()) <= 0)
       
   471 			CompleteErase();
       
   472 		else
       
   473 			SuspendErase();
       
   474 		break;
       
   475 	case ESuspending:
       
   476 		CompleteSuspend();
       
   477 		break;
       
   478 	default:
       
   479 		__KTRACE_OPT(KPANIC,Kern::Printf("iState=%d",iState));
       
   480 		FLASH_FAULT();
       
   481 		}
       
   482 	}
       
   483 
       
   484 void DMediaDriverFlashWin32::StartErase()
       
   485 //
       
   486 // Continue an erase - iEraseCounter has the remaining time for the erase
       
   487 //
       
   488 	{
       
   489 	__KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:StartErase %08x",iBase+iErasePos));
       
   490 	switch (iState)
       
   491 		{
       
   492 	case ESuspended:
       
   493 		iState = EErasePending;
       
   494 		StartTimer(iResumeTime);
       
   495 		break;
       
   496 	case EIdle:	// starting to erase
       
   497 		iEraseCounter = iEraseTime;
       
   498 	case EErasePending:
       
   499 		{
       
   500 		iState = EEraseNoSuspend;
       
   501 		TUint32 remain = iEraseCounter;
       
   502 		iEraseCounter = NKern::TickCount() + remain/iTickPeriod;
       
   503 		StartTimer(Min(remain, iSuspendHoldOffTime));
       
   504 		}
       
   505 		break;
       
   506 	default:
       
   507 		__KTRACE_OPT(KPANIC,Kern::Printf("iState=%d",iState));
       
   508 		FLASH_FAULT();
       
   509 		}
       
   510 	}
       
   511 
       
   512 void DMediaDriverFlashWin32::SuspendErase()
       
   513 	{
       
   514 	__ASSERT_ALWAYS(iState==EErase || iState==ESuspendPending,FLASH_FAULT());
       
   515 	__KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:SuspendErase %08x",iBase+iErasePos));
       
   516 	iTimer.Cancel();
       
   517 	TInt remain = Max(0, TInt(iEraseCounter - NKern::TickCount()));
       
   518 	iEraseCounter = remain * iTickPeriod;
       
   519 	iState = ESuspending;
       
   520 	StartTimer(0);
       
   521 	}
       
   522 
       
   523 void DMediaDriverFlashWin32::CompleteSuspend()
       
   524 	{
       
   525 	// erase suspend completion
       
   526 	__KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:SuspendComplete"));
       
   527 
       
   528 	iState = ESuspended;
       
   529 	// start any pending read or write requests
       
   530 	StartPendingRW();
       
   531 	}
       
   532 
       
   533 void DMediaDriverFlashWin32::CompleteErase()
       
   534 //
       
   535 // Do the actual erase in the completion
       
   536 //
       
   537 	{
       
   538 	// erase completion
       
   539 	__KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:EraseComplete"));
       
   540 
       
   541 	memset(iBase + iErasePos, 0xff, iEraseBlockSize);
       
   542 
       
   543 	// complete the erase request
       
   544 	iState = EIdle;
       
   545 	Complete(EReqErase,KErrNone);
       
   546 
       
   547 	// start any pending read or write requests
       
   548 	StartPendingRW();
       
   549 	}
       
   550 
       
   551 
       
   552 void DMediaDriverFlashWin32::StartPendingRW()
       
   553 	{
       
   554 	// start any pending read or write requests
       
   555 	if (iReadReq)
       
   556 		DoRead();
       
   557 	if (iWriteReq)
       
   558 		DoWrite();
       
   559 	}
       
   560 
       
   561 #ifdef _DEBUG
       
   562 // Override the base class version in order to provide access to ControlIO
       
   563 //
       
   564 TInt DMediaDriverFlashWin32::Request(TLocDrvRequest& m)
       
   565 	{
       
   566 	TInt r;
       
   567 	TInt id=m.Id();
       
   568 	__KTRACE_OPT(KLOCDRV,Kern::Printf(">DMediaDriverFlashWin32::Request %d",id));
       
   569 	if (id!=DLocalDrive::EControlIO)
       
   570 		{
       
   571 		r=DMediaDriverFlash::Request(m);
       
   572 		return r;
       
   573 		}
       
   574 	r=ControlIO((TInt)m.iArg[0],m.iArg[1],m.iArg[2]);
       
   575 	DMediaDriver::Complete(m,r);
       
   576 	return r;
       
   577 	}
       
   578 
       
   579 TInt DMediaDriverFlashWin32::ControlIO(TInt aCommand,TAny* /*aParam1*/,TAny* /*aParam2*/)
       
   580 	{
       
   581 	switch (aCommand)
       
   582 		{
       
   583 		case(KCtrlIoTimeout):
       
   584 			{
       
   585 			__KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:DoControlIO invoked for KCtrlIoTimeout"));
       
   586 			// The aim of this test is simulate a flash timeout (and so exercise the consequent
       
   587 			// actions of the software that initiated the request)				
       
   588 			if(iCtrlIoState!=EIdle)
       
   589 				{
       
   590 				__KTRACE_OPT(KLOCDRV,Kern::Printf("Flash: ControlIO request before previous completed"));
       
   591 				return KErrServerBusy;
       
   592 				}
       
   593 			else
       
   594 				{
       
   595 				__KTRACE_OPT(KLOCDRV,Kern::Printf("Flash: ControlIO timeout initiated"));
       
   596 				iCtrlIoState=ECtrlIoTimeOutPrep;
       
   597 				}
       
   598 			break;
       
   599 			}
       
   600 		
       
   601 		default:
       
   602 			{
       
   603 			__KTRACE_OPT(KLOCDRV,Kern::Printf("Flash: ERROR - unrecognised ControlIO command %d",aCommand));
       
   604 			FLASH_FAULT();
       
   605 			break;
       
   606 			}
       
   607 		}
       
   608 	return KErrNone;
       
   609 	}
       
   610 	
       
   611 #endif
       
   612 
       
   613 TInt DMediaDriverFlashWin32::Caps(TLocalDriveCapsV2& aCaps)
       
   614 // On return, aCaps data contains capability information about the 
       
   615 // flash device, in the form of a class derived from TLocalDriveCapsV2. 
       
   616 // The size of the derived class should not exceed KMaxLocalDriveCapsLength 
       
   617 // which is defined and used in e32\drivers\locmedia\locmedia.cpp. If a 
       
   618 // larger sized capabilities class is used, and this code is modified to 
       
   619 // write to member data beyond KMaxLocalDriveCapsLength this will cause a 
       
   620 // fault.
       
   621 	{
       
   622 	// Invoke the base class method then update the sizes for
       
   623 	// Control Mode and Object Mode as required.
       
   624 	DMediaDriverFlash::Caps(aCaps);
       
   625 #if defined (M18_EMULATION)
       
   626 	TLocalDriveCapsV7* caps = &((TLocalDriveCapsV7&)(aCaps));
       
   627 	caps->iControlModeSize=16;
       
   628 	caps->iObjectModeSize=1024;
       
   629     __KTRACE_OPT( KLOCDRV, Kern::Printf("MLFS: ) ControlModeSize UPDATED as=0x%x", caps->iControlModeSize) );
       
   630     __KTRACE_OPT( KLOCDRV, Kern::Printf("MLFS: ) ObjectModeSize UPDATED as=0x%x", caps->iObjectModeSize) );
       
   631 #endif
       
   632 	return KErrCompletion;	// synchronous completion
       
   633 	}
       
   634 
       
   635 DMediaDriverFlash* DMediaDriverFlash::New(TInt aDevice)
       
   636 	{
       
   637 	return new DMediaDriverFlashWin32(aDevice);
       
   638 	}
       
   639 
       
   640 
       
   641 
       
   642