omap3530/beagle_drivers/medstaticrd/beagle_medstaticrd.cpp
changeset 46 78c240f59c9d
equal deleted inserted replaced
39:cdb163c0843f 46:78c240f59c9d
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - contribution.
       
    11 *
       
    12 * Contributors:
       
    13 * Gareth Long - Symbian Foundation
       
    14 *
       
    15 * Description: Minimalistic non volatile memory driver
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include "locmedia.h"
       
    21 #include "platform.h"
       
    22 #include "\sf\adaptation\beagleboard\omap3530\beagleboard\inc\variantmediadef.h"
       
    23 #include "beagle_medstaticrd.h"
       
    24 //#include "syborg.h"
       
    25 
       
    26 #define NVMEM1_DRIVENAME "STATICRD"
       
    27 #define NVMEM1_DRIVECOUNT 1
       
    28 #define NVMEM1_DRIVELIST 1
       
    29 #define NVMEM1_NUMMEDIA 1
       
    30 
       
    31 _LIT(KNVMemPddName, "Media.MEDTATICRD");
       
    32 _LIT(KNVMemDriveName,NVMEM1_DRIVENAME);
       
    33 
       
    34 class DPhysicalDeviceMediaStaticRD : public DPhysicalDevice
       
    35 	{
       
    36 public:
       
    37 	DPhysicalDeviceMediaStaticRD();
       
    38 public:
       
    39 	// Implementing the interface
       
    40 	virtual TInt Install();
       
    41 	virtual void GetCaps(TDes8& aDes) const;
       
    42 	virtual TInt Create(DBase*& aChannel, TInt aMediaId, const TDesC8* anInfo, const TVersion& aVer);
       
    43 	virtual TInt Validate(TInt aDeviceType, const TDesC8* anInfo, const TVersion& aVer);
       
    44 	virtual TInt Info(TInt aFunction, TAny* a1);
       
    45 	};
       
    46 								
       
    47 class DMediaDriverStaticRD : public DMediaDriver
       
    48 	{
       
    49 public:
       
    50 	DMediaDriverStaticRD(TInt aMediaId);
       
    51 public:
       
    52 	// Implementing the interface
       
    53 	virtual TInt Request(TLocDrvRequest& aRequest);
       
    54 	virtual void Disconnect(DLocalDrive* aLocalDrive, TThreadMessage* aMsg);
       
    55 	virtual TInt PartitionInfo(TPartitionInfo &anInfo);
       
    56 	virtual void NotifyPowerDown();
       
    57 	virtual void NotifyEmergencyPowerDown();
       
    58 public:
       
    59 	void CompleteRequest(TInt aReason);
       
    60 	TInt DoCreate(TInt aMediaId);
       
    61 	TInt Caps(TLocDrvRequest& aRequest);
       
    62 	TInt Read();
       
    63 	TInt Write();
       
    64 	TInt Format();
       
    65 	static void TransactionLaunchDfc(TAny* aMediaDriver);
       
    66 	void DoTransactionLaunchDfc();
       
    67 	static void SessionEndDfc(TAny* aMediaDriver);
       
    68 	void DoSessionEndDfc();
       
    69 	TUint32 GetNVMemSize( void );
       
    70 
       
    71 public:
       
    72 	TUint32 iLatestTransferSectorCount;
       
    73 	TDfc iSessionEndDfc;
       
    74 
       
    75 private:
       
    76 	TInt ContinueTransaction( TUint32 aTransactionSectorOffset, TUint32 aTransactionSectorCount, TUint32 aDirection );
       
    77 	static void Isr(TAny* aPtr);
       
    78 
       
    79 private:
       
    80 	TLocDrvRequest* iCurrentRequest;				// Current Request
       
    81 	Int64 iTotalLength;
       
    82 	Int64 iProsessedLength;
       
    83 	Int64 iPos;
       
    84 	TPhysAddr iTransferBufferPhys;
       
    85 	TUint8* iTransferBufferLin;
       
    86 	TUint8* iDiscBufferLin;
       
    87 	TUint32 iHead;
       
    88 	TUint32 iTail;
       
    89 	TUint32 iSplitted;
       
    90 	TUint32 iAlignmentOverhead;
       
    91 	TBool iReadModifyWrite;
       
    92 	TDfc iTransactionLaunchDfc;
       
    93 	};
       
    94 
       
    95 DPhysicalDeviceMediaStaticRD::DPhysicalDeviceMediaStaticRD()
       
    96 //
       
    97 // Constructor
       
    98 //
       
    99 	{
       
   100 	__DEBUG_PRINT(">DPhysicalDeviceMediaStaticRD::DPhysicalDeviceMediaStaticRD");
       
   101 	iUnitsMask=0x1;
       
   102 	iVersion=TVersion(KMediaDriverInterfaceMajorVersion,KMediaDriverInterfaceMinorVersion,KMediaDriverInterfaceBuildVersion);
       
   103 	}
       
   104 
       
   105 TInt DPhysicalDeviceMediaStaticRD::Install()
       
   106 //
       
   107 // Install the Internal NVMem PDD.
       
   108 //
       
   109 	{
       
   110 	__DEBUG_PRINT("DPhysicalDeviceMediaStaticRD::Install()");
       
   111 	return SetName(&KNVMemPddName);
       
   112 	}
       
   113 
       
   114 void DPhysicalDeviceMediaStaticRD::GetCaps(TDes8& /*aDes*/) const
       
   115 //
       
   116 // Return the media drivers capabilities.
       
   117 //
       
   118 	{
       
   119 	__DEBUG_PRINT("DPhysicalDeviceMediaStaticRD::GetCaps()");
       
   120 	}
       
   121 
       
   122 TInt DPhysicalDeviceMediaStaticRD::Create(DBase*& aChannel, TInt aMediaId, const TDesC8* /* anInfo */,const TVersion &aVer)
       
   123 //
       
   124 // Create an Internal Ram media driver.
       
   125 //
       
   126 	{
       
   127 	__DEBUG_PRINT("DPhysicalDeviceMediaStaticRD::Create()");
       
   128 	if (!Kern::QueryVersionSupported(iVersion,aVer))
       
   129 		return KErrNotSupported;
       
   130 	TInt r=KErrNoMemory;
       
   131 	DMediaDriverStaticRD* pD=new DMediaDriverStaticRD(aMediaId);
       
   132 	aChannel=pD;
       
   133 	if (pD)
       
   134 		{
       
   135 		r=pD->DoCreate(aMediaId);
       
   136 		}
       
   137 	if( r==KErrNone )
       
   138 		{
       
   139 		pD->OpenMediaDriverComplete(KErrNone);
       
   140 		}
       
   141 
       
   142 	return r;
       
   143 	}
       
   144 
       
   145 TInt DPhysicalDeviceMediaStaticRD::Validate(TInt aDeviceType, const TDesC8* /*anInfo*/, const TVersion& aVer)
       
   146 	{
       
   147 	__DEBUG_PRINT("DPhysicalDeviceMediaStaticRD::Validate()");
       
   148 	if (!Kern::QueryVersionSupported(iVersion,aVer))
       
   149 		return KErrNotSupported;
       
   150 	if (aDeviceType!=EFixedMedia1)
       
   151 		return KErrNotSupported;
       
   152 	return KErrNone;
       
   153 	}
       
   154 
       
   155 TInt DPhysicalDeviceMediaStaticRD::Info(TInt aFunction, TAny*)
       
   156 //
       
   157 // Return the priority of this media driver
       
   158 //
       
   159 	{
       
   160 	__DEBUG_PRINT("DPhysicalDeviceMediaStaticRD::Info()");
       
   161 	if (aFunction==EPriority)
       
   162 		return KMediaDriverPriorityNormal;
       
   163 	return KErrNotSupported;
       
   164 	}
       
   165 
       
   166 DMediaDriverStaticRD::DMediaDriverStaticRD(TInt aMediaId)
       
   167 //
       
   168 // Constructor.
       
   169 //
       
   170 	:	DMediaDriver(aMediaId),
       
   171 		iSessionEndDfc(DMediaDriverStaticRD::SessionEndDfc, this, 1),
       
   172 		iTransferBufferPhys(0),
       
   173 		iTransactionLaunchDfc(DMediaDriverStaticRD::TransactionLaunchDfc, this, KMaxDfcPriority)
       
   174 	{
       
   175 	__DEBUG_PRINT("DMediaDriverStaticRD::DMediaDriverStaticRD()");
       
   176 	}
       
   177 
       
   178 TInt DMediaDriverStaticRD::DoCreate(TInt /*aMediaId*/)
       
   179 //
       
   180 // Create the media driver.
       
   181 //
       
   182 	{
       
   183 	__DEBUG_PRINT(">DMediaDriverStaticRD::DoCreate");
       
   184 	TInt r = KErrNone; 
       
   185 	// Inform our size
       
   186 	Int64 size=GetNVMemSize()<<KDiskSectorShift;
       
   187 	if( size<=0 )
       
   188 		{
       
   189 		Kern::Fault("DMediaDriverStaticRD zero size nv memory array", 0);
       
   190 		}
       
   191 	SetTotalSizeInBytes(size);
       
   192 	// Some dfc initialization
       
   193 	if( r==KErrNone )
       
   194 		{
       
   195 		iSessionEndDfc.SetDfcQ( this->iPrimaryMedia->iDfcQ );
       
   196 		iTransactionLaunchDfc.SetDfcQ( this->iPrimaryMedia->iDfcQ );
       
   197 		}
       
   198 	// Create our piece of physically contiguous transfer buffer. 
       
   199 	r = Epoc::AllocPhysicalRam( KNVMemTransferBufferSize, iTransferBufferPhys );
       
   200 	if( r != KErrNone )
       
   201 		{
       
   202 		Kern::Fault("DMediaDriverStaticRD Allocate Ram %d",r);
       
   203 		}
       
   204 
       
   205     DPlatChunkHw* bufChunk = NULL;
       
   206     DPlatChunkHw* bufChunk2 = NULL;
       
   207 
       
   208     // Create HW Memory Chunk
       
   209     r = DPlatChunkHw::New( bufChunk, iTransferBufferPhys, KNVMemTransferBufferSize, EMapAttrUserRw | EMapAttrFullyBlocking );
       
   210 
       
   211     if( r != KErrNone )
       
   212         {
       
   213         // Check Physical Memory
       
   214         if( iTransferBufferPhys )
       
   215 			{
       
   216             // Free Physical Memory
       
   217             Epoc::FreePhysicalRam( iTransferBufferPhys, KNVMemTransferBufferSize );
       
   218 			}
       
   219 		Kern::Fault("DMediaDriverStaticRD error in creating transfer buffer", r);
       
   220         }
       
   221     
       
   222 
       
   223     // Set Main Buffer Pointer
       
   224     iTransferBufferLin = reinterpret_cast<TUint8*>(bufChunk->LinearAddress());
       
   225 
       
   226     
       
   227     
       
   228     // Create HW Memory Chunk for drive image
       
   229        r = DPlatChunkHw::New( bufChunk2, 0x81000000, 0x1000000, EMapAttrUserRw | EMapAttrFullyBlocking );
       
   230        if( r != KErrNone )
       
   231               {
       
   232 			   Kern::Fault("DMediaDriverStaticRD error in creating disc image linear address", r);
       
   233               }
       
   234             
       
   235            
       
   236        // Set Main Buffer Pointer
       
   237        iDiscBufferLin = reinterpret_cast<TUint8*>(bufChunk2->LinearAddress());
       
   238 
       
   239        
       
   240   	// Inform "hardware" about the shared memory
       
   241   	//WriteReg( KHwNVMemoryDevice, R_NVMEM_SHARED_MEMORY_BASE, iTransferBufferPhys );
       
   242   	//WriteReg( KHwNVMemoryDevice, R_NVMEM_SHARED_MEMORY_SIZE, KNVMemTransferBufferSize );
       
   243   	//WriteReg( KHwNVMemoryDevice, R_NVMEM_ENABLE, 1 );
       
   244 
       
   245 	// Set up interrupt service
       
   246   	//r = Interrupt::Bind( EIntNVMemoryDevice, Isr, this );
       
   247   	//Interrupt::Enable( EIntNVMemoryDevice );
       
   248 
       
   249 
       
   250 	__DEBUG_PRINT("<DMediaDriverStaticRD::DoCreate %d", r);
       
   251 	return(r);
       
   252 	}
       
   253 
       
   254 TInt DMediaDriverStaticRD::Request(TLocDrvRequest& m)
       
   255 	{
       
   256 	TInt request=m.Id();
       
   257 	__DEBUG_PRINT(">DMediaDriverStaticRD::Request %d",request);
       
   258 	TInt r=KErrNone;
       
   259 	
       
   260 	// Requests that can be handled synchronously
       
   261 	if( request == DLocalDrive::ECaps ) 
       
   262 		{
       
   263 		r=Caps(m);
       
   264 		return r;
       
   265 		}
       
   266 
       
   267 	// All other requests must be deferred if a request is currently in progress
       
   268 	if (iCurrentRequest)
       
   269 		{
       
   270 		// a request is already in progress, so hold on to this one
       
   271 		r = KMediaDriverDeferRequest;
       
   272 		}
       
   273 	else
       
   274 		{
       
   275 
       
   276 		iCurrentRequest=&m;
       
   277 		iProsessedLength = 0;
       
   278 		iHead = 0;
       
   279 		iTail = 0;
       
   280 		iSplitted = 0;
       
   281 		iAlignmentOverhead = 0;
       
   282 
       
   283 		iPos = m.Pos();
       
   284 		iTotalLength = m.Length();
       
   285 
       
   286 
       
   287 		__DEBUG_PRINT(">DMediaDriverStaticRD::Request pos:0x%lx len:0x%lx", iPos, iTotalLength);
       
   288 		if( iTotalLength<0 || iPos<0 )
       
   289 			{
       
   290 			Kern::Fault("DMediaDriverStaticRD::Request: illegal access!", 0);
       
   291 			}
       
   292 		// Handle unaligned operations
       
   293 		iHead = iPos % KDiskSectorSize;
       
   294 		TUint32 tailAlignment = ((iHead + iTotalLength) % KDiskSectorSize);
       
   295 		if( tailAlignment )
       
   296 			{
       
   297 			iTail = KDiskSectorSize - tailAlignment;
       
   298 			}
       
   299 
       
   300 		iSplitted = (iTotalLength + iHead + iTail) / KNVMemTransferBufferSize;
       
   301 
       
   302 		__DEBUG_PRINT(">DMediaDriverStaticRD::Request head: %d tail: %d splitted: %d\n", iHead, iTail, iSplitted );
       
   303 		__DEBUG_PRINT(">DMediaDriverStaticRD::Request partitionlen: %lx", iCurrentRequest->Drive()->iPartitionLen );
       
   304 
       
   305 		if( (iTotalLength + iPos) > iCurrentRequest->Drive()->iPartitionLen )
       
   306 			{
       
   307 			Kern::Fault("DMediaDriverStaticRD::Request: Access over partition boundary!", 0);
       
   308 			}
       
   309 		if( iTotalLength > KMaxTInt32 )
       
   310 			{
       
   311 			Kern::Fault("DMediaDriverStaticRD::Request: Access length overflow!", 0);
       
   312 			}
       
   313 		switch (request)
       
   314 			{
       
   315 			case DLocalDrive::ERead:
       
   316 			case DLocalDrive::EWrite:
       
   317 			case DLocalDrive::EFormat:
       
   318 				__DEBUG_PRINT("DMediaDriverStaticRD::Request iTransactionLaunchDfc.Enque()>");
       
   319 				iTransactionLaunchDfc.Enque();
       
   320 				__DEBUG_PRINT("DMediaDriverStaticRD::Request iTransactionLaunchDfc.Enque()<");
       
   321 			break;
       
   322 			case DLocalDrive::EEnlarge:
       
   323 			case DLocalDrive::EReduce:
       
   324 			default:
       
   325 				r=KErrNotSupported;
       
   326 			break;
       
   327 			}
       
   328 		}
       
   329 
       
   330 	__DEBUG_PRINT("<DMediaDriverStaticRD::Request %d",r);
       
   331 	return r;
       
   332 	}
       
   333 
       
   334 void DMediaDriverStaticRD::CompleteRequest(TInt aReason)
       
   335 //
       
   336 // completes the request which is being currently processed
       
   337 //
       
   338 	{
       
   339 	__DEBUG_PRINT("DMediaDriverStaticRD::CompleteRequest() reason: %d", aReason);
       
   340 	TLocDrvRequest* pR=iCurrentRequest;
       
   341 	if (pR)
       
   342 		{
       
   343 		iCurrentRequest=NULL;
       
   344 		DMediaDriver::Complete(*pR,aReason);
       
   345 		}
       
   346 	}
       
   347 
       
   348 void DMediaDriverStaticRD::Disconnect( DLocalDrive* aLocalDrive, TThreadMessage* aMsg )
       
   349 	{
       
   350 	__DEBUG_PRINT(">DMediaDriverStaticRD::Disconnect()");
       
   351 	// Complete using the default implementation
       
   352 	DMediaDriver::Disconnect(aLocalDrive, aMsg);
       
   353 	__DEBUG_PRINT("<DMediaDriverStaticRD::Disconnect()");
       
   354 	}
       
   355 
       
   356 void DMediaDriverStaticRD::NotifyPowerDown()
       
   357 	{
       
   358 	__DEBUG_PRINT("DMediaDriverStaticRD::NotifyPowerDown()");
       
   359 	// no action required
       
   360 	}
       
   361 
       
   362 void DMediaDriverStaticRD::NotifyEmergencyPowerDown()
       
   363 	{
       
   364 	__DEBUG_PRINT("DMediaDriverStaticRD::NotifyEmergencyPowerDown()");
       
   365 	// no action required
       
   366 	}
       
   367 
       
   368 TInt DMediaDriverStaticRD::Caps(TLocDrvRequest& m)
       
   369 	{
       
   370 	__DEBUG_PRINT("DMediaDriverStaticRD::Caps()");
       
   371 	TLocalDriveCapsV6& caps=*(TLocalDriveCapsV6*)m.RemoteDes();
       
   372 	caps.iType=EMediaHardDisk;
       
   373 	caps.iConnectionBusType=EConnectionBusInternal;
       
   374 	caps.iDriveAtt=KDriveAttLocal|KDriveAttInternal;
       
   375 	caps.iMediaAtt=KMediaAttFormattable;
       
   376 	caps.iFileSystemId=KDriveFileSysFAT;
       
   377 	caps.iPartitionType=KPartitionTypeFAT16;
       
   378 	caps.iSize=m.Drive()->iPartitionLen;
       
   379 	caps.iHiddenSectors=0;
       
   380 	caps.iEraseBlockSize = KNVMemTransferBufferSize; 
       
   381 	caps.iBlockSize=KDiskSectorSize;
       
   382 	caps.iMaxBytesPerFormat = KNVMemTransferBufferSize;
       
   383 
       
   384 	return KErrCompletion;									
       
   385 	}
       
   386 
       
   387 TInt DMediaDriverStaticRD::Read()
       
   388 	{
       
   389 	__DEBUG_PRINT(">DMediaDriverStaticRD::Read() pos: %lx, size: %lx", iPos, iTotalLength);
       
   390 	// Set our sector offset
       
   391 	TUint32 transactionSectorOffset = (TUint32)(iPos / KDiskSectorSize); 
       
   392 	TUint32 transactionLength = 0;
       
   393 	TUint32 transactionDirection = NVMEM_TRANSACTION_READ;
       
   394 	// Do we have an operation longer than our shared memory?
       
   395 	if( iSplitted > 0 )
       
   396 		{
       
   397 		transactionLength = KNVMemTransferBufferSize;
       
   398 		}
       
   399 	else
       
   400 		{
       
   401 		// Do the whole operation in one go since we have enough room in our memory
       
   402 		transactionLength = I64LOW(iTotalLength);
       
   403 		// Read the "broken" tail sector
       
   404 		if( iTail )
       
   405 			{
       
   406 			transactionLength += iTail;
       
   407 			iAlignmentOverhead += iTail;
       
   408 			}
       
   409 		}
       
   410 	// Read the "broken" head sector
       
   411 	if( iHead > 0 )
       
   412 		{
       
   413 		transactionLength += iHead;
       
   414 		iAlignmentOverhead += iHead;
       
   415 		}
       
   416 
       
   417 	// We should be ok to continue
       
   418 	ContinueTransaction( transactionSectorOffset, transactionLength/KDiskSectorSize, transactionDirection );
       
   419 	__DEBUG_PRINT("<DMediaDriverStaticRD::Read()");
       
   420 	return KErrNone;
       
   421 	}
       
   422 
       
   423 TInt DMediaDriverStaticRD::Write()
       
   424 	{
       
   425 	__DEBUG_PRINT("DMediaDriverStaticRD::Write() pos: 0x%lx, size: 0x%lx", iPos, iTotalLength);
       
   426 	TInt r = KErrNone;
       
   427 	// Set our sector offset
       
   428 	TUint32 transactionSectorOffset = (TUint32)(iPos / KDiskSectorSize); 
       
   429 	TUint32 transactionLength = 0;
       
   430 	TUint32 transactionDirection = NVMEM_TRANSACTION_WRITE;
       
   431 	// Do we have an operation longer than our shared memory?
       
   432 	if( iSplitted > 0 )
       
   433 		{
       
   434 		transactionLength = KNVMemTransferBufferSize;
       
   435 		}
       
   436 	else
       
   437 		{
       
   438 		// Do the whole operation in one go since we have enough room in our memory
       
   439 		transactionLength = I64LOW(iTotalLength);
       
   440 		if( iTail )
       
   441 			{
       
   442 			iReadModifyWrite = ETrue;
       
   443 			// Read the "broken" tail sector
       
   444 			transactionLength += iTail;
       
   445 			iAlignmentOverhead += iTail;
       
   446 			}
       
   447 		}
       
   448 	// Is there a need to read modify write the "broken" head sector of the operation
       
   449 	if( iHead > 0 )
       
   450 		{
       
   451 		iReadModifyWrite = ETrue;
       
   452 		// If splitted operation we only need the broken sector
       
   453 		if( iSplitted > 0 )
       
   454 			{
       
   455 			transactionLength = KDiskSectorSize;
       
   456 			iAlignmentOverhead += iHead;
       
   457 			}
       
   458 		else
       
   459 			{
       
   460 			// Read the "broken" head sector in addition to everything else
       
   461 			transactionLength += iHead;
       
   462 			iAlignmentOverhead += iHead;
       
   463 			}
       
   464 		}
       
   465 	
       
   466 	// Was there a need to read-modify before writing
       
   467 	if( iReadModifyWrite )
       
   468 		{
       
   469 		transactionDirection = NVMEM_TRANSACTION_READ;
       
   470 		}
       
   471 	else
       
   472 		{
       
   473 		// Handle format here
       
   474 		if( iCurrentRequest->Id() == DLocalDrive::EFormat )
       
   475 			{
       
   476 			// Not much handling just flow through since we have filled the shared memory with zeroes already
       
   477 			}
       
   478 		else
       
   479 			{
       
   480 			// Read from client
       
   481 			TPtr8 targetDescriptor(iTransferBufferLin, transactionLength);
       
   482 			r = iCurrentRequest->ReadRemote(&targetDescriptor,0);
       
   483 			}
       
   484 		}
       
   485 	
       
   486 	// We should be ok to continue
       
   487 	ContinueTransaction( transactionSectorOffset, transactionLength/KDiskSectorSize, transactionDirection );
       
   488 
       
   489 	return r;
       
   490 	}
       
   491 
       
   492 
       
   493 TInt DMediaDriverStaticRD::Format()
       
   494 	{
       
   495 	__DEBUG_PRINT("DMediaDriverStaticRD::Format() pos: 0x%lx, size: 0x%lx", iPos, iTotalLength);
       
   496 	memset( iTransferBufferLin, 0x00, KNVMemTransferBufferSize );
       
   497 	// Stop the nonsense here. Write operations should be used for partial sector data removal operations
       
   498 	if( iHead > 0 || iTail > 0 )
       
   499 		{
       
   500 		Kern::Fault("DMediaDriverStaticRD::Format: alignment violation!", 0);
       
   501 		}
       
   502 	Write();
       
   503 //	DoTransaction( m, NVMEM_TRANSACTION_WRITE );
       
   504 	return KErrNone;
       
   505 	}
       
   506 
       
   507 TInt DMediaDriverStaticRD::ContinueTransaction( TUint32 aTransactionSectorOffset, TUint32 aTransactionSectorCount, TUint32 aTransactionDirection )
       
   508 	{
       
   509 	__DEBUG_PRINT("DMediaDriverStaticRD::ContinueTransaction() sectoroffset: %d, sectorcount: %d, direction: %d", aTransactionSectorOffset, aTransactionSectorCount, aTransactionDirection);
       
   510 	if( aTransactionDirection != NVMEM_TRANSACTION_UNDEFINED )
       
   511 		{
       
   512 	  	//WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_OFFSET, aTransactionSectorOffset );
       
   513 	  	//WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_SIZE, aTransactionSectorCount );
       
   514 	  	//WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_DIRECTION, aTransactionDirection );
       
   515 	  	//WriteReg( KHwNVMemoryDevice, R_NVMEM_TRANSACTION_EXECUTE, aTransactionDirection );
       
   516 		if ( aTransactionDirection == NVMEM_TRANSACTION_WRITE )
       
   517 		{
       
   518 			memcpy( (TAny *)(iDiscBufferLin+(aTransactionSectorOffset<<9)), iTransferBufferLin, aTransactionSectorCount*512 );
       
   519 		}
       
   520 		else if ( aTransactionDirection == NVMEM_TRANSACTION_READ )
       
   521 		{
       
   522 			memcpy( iTransferBufferLin, (TAny *)(iDiscBufferLin+(aTransactionSectorOffset<<9)), aTransactionSectorCount*512 );
       
   523 		}
       
   524 		iLatestTransferSectorCount = aTransactionSectorCount;
       
   525 		Isr(this); // terrible hack, we've yransferred all the sectors and now we pretend to generate an interrupt
       
   526 		}
       
   527 	else
       
   528 		{
       
   529 		Kern::Fault("DMediaDriverStaticRD::ContinueTransaction: Undefined transaction!", 0);
       
   530 		}
       
   531 	return KErrNone;
       
   532 	}
       
   533 
       
   534 
       
   535 TInt DMediaDriverStaticRD::PartitionInfo(TPartitionInfo& anInfo)
       
   536 //
       
   537 // Return partition information on the media.
       
   538 //
       
   539 	{
       
   540 	__DEBUG_PRINT("DMediaDriverStaticRD::PartitionInfo()");
       
   541 	anInfo.iPartitionCount=1;
       
   542 	anInfo.iEntry[0].iPartitionBaseAddr=0;
       
   543 	anInfo.iEntry[0].iPartitionLen=anInfo.iMediaSizeInBytes=TotalSizeInBytes();
       
   544 	anInfo.iEntry[0].iPartitionType=KPartitionTypeFAT16;
       
   545 	return KErrCompletion;
       
   546 	}
       
   547 
       
   548 void DMediaDriverStaticRD::TransactionLaunchDfc(TAny* aMediaDriver)
       
   549 	{
       
   550 	static_cast<DMediaDriverStaticRD*>(aMediaDriver)->DoTransactionLaunchDfc();
       
   551 	}
       
   552 
       
   553 void DMediaDriverStaticRD::DoTransactionLaunchDfc()
       
   554 	{
       
   555 	__DEBUG_PRINT(">DMediaDriverStaticRD::DoTransactionLaunchDfc()");
       
   556 	TInt request = iCurrentRequest->Id();
       
   557 	TInt r(KErrNone);
       
   558 	switch (request)
       
   559 		{
       
   560 		case DLocalDrive::ERead:
       
   561 			r=Read();
       
   562 		break;
       
   563 		case DLocalDrive::EWrite:
       
   564 			r=Write();
       
   565 		break;
       
   566 		case DLocalDrive::EFormat:
       
   567 			r=Format();
       
   568 		break;
       
   569 		case DLocalDrive::EEnlarge:
       
   570 		case DLocalDrive::EReduce:
       
   571 		default:
       
   572 			r=KErrNotSupported;
       
   573 		break;
       
   574 		}
       
   575 	if( r != KErrNone )
       
   576 		{
       
   577 		// TODO some proper error handling here
       
   578 		}
       
   579 	__DEBUG_PRINT("<MediaDriverStaticRD::DoTransactionLaunchDfc %d",r);
       
   580 	}
       
   581 
       
   582 void DMediaDriverStaticRD::SessionEndDfc(TAny* aMediaDriver)
       
   583 	{
       
   584 	static_cast<DMediaDriverStaticRD*>(aMediaDriver)->DoSessionEndDfc();
       
   585 	}
       
   586 
       
   587 void DMediaDriverStaticRD::DoSessionEndDfc()
       
   588 	{
       
   589 	__DEBUG_PRINT(">DMediaDriverStaticRD::DoSessionEndDfc()");
       
   590 	TInt r = KErrNone;
       
   591 	// Check that we have a request in process
       
   592 	if( iCurrentRequest )
       
   593 		{
       
   594 		// Transaction variables
       
   595 		TUint32 transactionSectorOffset(0);
       
   596 		TUint32 transactionLength(0);
       
   597 		TUint32 transactionDirection( NVMEM_TRANSACTION_UNDEFINED );
       
   598 		// How much did we actually transfer? 
       
   599 		TUint32 latestTransferSize = (iLatestTransferSectorCount * KDiskSectorSize);
       
   600 		__DEBUG_PRINT("DMediaDriverStaticRD::DoSessionEndDfc() latestTransferSize: %d", latestTransferSize );
       
   601 		// Subtract alignment overhead
       
   602 		latestTransferSize = latestTransferSize - iAlignmentOverhead;
       
   603 		// For decision whether the buffer is ready for operation already
       
   604 		TBool bufferReady(EFalse);
       
   605 		// For decision whether we have finished the latest request
       
   606 		TBool sessionComplete(EFalse);
       
   607 
       
   608 		// Was there a read-modify-write (RWM) for which we need to do some buffer manipulation before proceeding?
       
   609 		// Note that in case of format we triggered to alignment violation in earlier method already and can not enter to following 
       
   610 		// condition when there is a format operation going on
       
   611 		if( iReadModifyWrite )
       
   612 			{
       
   613 			bufferReady = ETrue;
       
   614 			iReadModifyWrite = EFalse;
       
   615 			// Was it a splitted operation for which we only need to take care of the broken head sector.
       
   616 			if( iSplitted > 0 )
       
   617 				{
       
   618 				// We have a sector here here filled with data from mass memory. Modify with client data.
       
   619 				__DEBUG_PRINT("DMediaDriverStaticRD::DoSessionEndDfc() readremote splitted: %d head: %d", latestTransferSize, iHead );
       
   620 				TPtr8 targetDescriptor(&iTransferBufferLin[iHead], KNVMemTransferBufferSize - iHead);
       
   621 				r = iCurrentRequest->ReadRemote(&targetDescriptor,0);
       
   622 				}
       
   623 			// Else we need to take care of both head and tail
       
   624 			else
       
   625 				{
       
   626 				// We have a piece of data read from mass memory. Modify with client data.
       
   627 				__DEBUG_PRINT("DMediaDriverStaticRD::DoSessionEndDfc() readremote: %d head: %d", I64LOW(iTotalLength - iProsessedLength), iHead );
       
   628 				TPtr8 targetDescriptor(&iTransferBufferLin[iHead], I64LOW(iTotalLength - iProsessedLength));
       
   629 				r = iCurrentRequest->ReadRemote(&targetDescriptor,0);
       
   630 //				latestTransferSize -= (KDiskSectorSize - iTail);
       
   631 				iTail = 0;
       
   632 				}
       
   633 			}
       
   634 		else
       
   635 			{
       
   636 			// Overhead is processed when we enter here
       
   637 			iAlignmentOverhead = 0;
       
   638 			// Update position
       
   639 			iPos += latestTransferSize;
       
   640 			// Save the information on how many bytes we transferred already
       
   641 			iProsessedLength += latestTransferSize; 
       
   642 			// Update the splitted information. We don't take head into account here anymore since it is already taken care of
       
   643 			iSplitted = (iTotalLength - iProsessedLength + iTail) / KNVMemTransferBufferSize;
       
   644 			// Check if we have done already
       
   645 			if( iProsessedLength >= iTotalLength )
       
   646 				{
       
   647 				// If this was the final transfer for this request let's take tail into account as well (if not taken already)
       
   648 				// iProsessedLength -= iTail;
       
   649 				// latestTransferSize -= iTail;
       
   650 				if( iProsessedLength > iTotalLength )
       
   651 					{
       
   652 					Kern::Fault("DMediaDriverStaticRD: Illegal transfer operation!", 0);
       
   653 					}
       
   654 				sessionComplete = ETrue;
       
   655 				}
       
   656 			}
       
   657 
       
   658 		TInt request = iCurrentRequest->Id();
       
   659 
       
   660 		// Set our sector offset
       
   661 		transactionSectorOffset = (TUint32)(iPos / KDiskSectorSize); 
       
   662 		
       
   663 		if( bufferReady )
       
   664 			{
       
   665 			// Write as much as we read in RMW operation
       
   666 			transactionLength = (iLatestTransferSectorCount * KDiskSectorSize);
       
   667 			}
       
   668 		else
       
   669 			{
       
   670 			// Do we have an operation longer than our shared memory?
       
   671 			if( iSplitted > 0 )
       
   672 				{
       
   673 				transactionLength = KNVMemTransferBufferSize;
       
   674 				}
       
   675 			else
       
   676 				{
       
   677 				// Do the whole operation in one go since we have enough room in our memory
       
   678 				transactionLength = I64LOW(iTotalLength - iProsessedLength);
       
   679 				// Read the "broken" tail sector
       
   680 				if( iTail > 0 && request == DLocalDrive::EWrite )
       
   681 					{
       
   682 					iReadModifyWrite = ETrue;
       
   683 					// Read the "broken" tail sector
       
   684 					transactionLength += iTail;
       
   685 	   				iAlignmentOverhead = iTail;
       
   686 	   				}
       
   687 				}
       
   688 			}
       
   689 		
       
   690 		// Was there a need to read-modify before writing
       
   691 		if( iReadModifyWrite )
       
   692 			{
       
   693 			transactionDirection = NVMEM_TRANSACTION_READ;
       
   694 			}
       
   695 		else
       
   696 			{
       
   697 			if( request == DLocalDrive::ERead )
       
   698 				{
       
   699 				transactionDirection = NVMEM_TRANSACTION_READ;
       
   700 				// Write to client
       
   701 				__DEBUG_PRINT("DMediaDriverStaticRD::DoSessionEndDfc() WriteRemote: %d head: %d", latestTransferSize, iHead );
       
   702 				TPtrC8 sourceDescriptor(&iTransferBufferLin[iHead], latestTransferSize);
       
   703 				r = iCurrentRequest->WriteRemote( &sourceDescriptor, 0 );
       
   704 				}
       
   705 			// Head is processed
       
   706 			iHead = 0;
       
   707 			if( request == DLocalDrive::EWrite && !sessionComplete )
       
   708 				{
       
   709 				transactionDirection = NVMEM_TRANSACTION_WRITE;
       
   710 				if( bufferReady )
       
   711 					{
       
   712 					// Actually no need for any actions here
       
   713 					}
       
   714 				else
       
   715 					{
       
   716 					// Prepare a buffer for transfer
       
   717 					__DEBUG_PRINT("DMediaDriverStaticRD::DoSessionEndDfc() ReadRemote: %d head: %d", latestTransferSize, iHead );
       
   718 					TPtr8 targetDescriptor(iTransferBufferLin, transactionLength);
       
   719 					r = iCurrentRequest->ReadRemote(&targetDescriptor,0);
       
   720 					}
       
   721 				}
       
   722 			if( request == DLocalDrive::EFormat )
       
   723 				{
       
   724 				transactionDirection = NVMEM_TRANSACTION_WRITE;
       
   725 				}
       
   726 			}
       
   727 		if( sessionComplete )
       
   728 			{
       
   729 			CompleteRequest( r );
       
   730 			}
       
   731 		else
       
   732 			{
       
   733 			ContinueTransaction( transactionSectorOffset, transactionLength/KDiskSectorSize, transactionDirection );
       
   734 			}
       
   735 		}
       
   736 	else
       
   737 		{
       
   738 		// Let's just flow through for now
       
   739 		}
       
   740 
       
   741 	__DEBUG_PRINT("<DMediaDriverStaticRD::DoSessionEndDfc()" );
       
   742 	}
       
   743 
       
   744 
       
   745 TUint32  DMediaDriverStaticRD::GetNVMemSize( void )
       
   746 	{
       
   747 	__DEBUG_PRINT("DMediaDriverStaticRD::GetNVMemSize()");
       
   748 	TUint32 sizeInSectors = 32768;//ReadReg( KHwNVMemoryDevice, R_NVMEM_NV_MEMORY_SIZE );
       
   749 	return sizeInSectors; 
       
   750 	}
       
   751 
       
   752 void DMediaDriverStaticRD::Isr(TAny* aPtr)
       
   753 	{
       
   754 	__DEBUG_PRINT(">DMediaDriverStaticRD::Isr");
       
   755 
       
   756     DMediaDriverStaticRD* nvMem = reinterpret_cast<DMediaDriverStaticRD*>(aPtr);
       
   757 
       
   758 	// Save the amount of transferred sectors. This clears the interrupt from HW as well
       
   759 	//nvMem->iLatestTransferSectorCount = ReadReg( KHwNVMemoryDevice, R_NVMEM_STATUS );
       
   760 
       
   761 	// Clear from framework
       
   762 	//Interrupt::Clear( EIntNVMemoryDevice );
       
   763 
       
   764 	nvMem->iSessionEndDfc.Add();
       
   765 	}
       
   766 
       
   767 
       
   768 DECLARE_EXTENSION_PDD()
       
   769 	{
       
   770 	__DEBUG_PRINT(">MediaDriverStaticRD create device");
       
   771 	return new DPhysicalDeviceMediaStaticRD;
       
   772 	}
       
   773 
       
   774 static const TInt NVMemDriveNumbers[NVMEM1_DRIVECOUNT]={NVMEM1_DRIVELIST};	
       
   775 
       
   776 DECLARE_STANDARD_EXTENSION()
       
   777 	{
       
   778 	__DEBUG_PRINT("Registering STATICRD drive");
       
   779 	TInt r=KErrNoMemory;
       
   780 
       
   781 	DPrimaryMediaBase* pM=new DPrimaryMediaBase;
       
   782 
       
   783 	TDynamicDfcQue* NVMemoryDfcQ;
       
   784 	 
       
   785 	r = Kern::DynamicDfcQCreate( NVMemoryDfcQ, KNVMemDfcThreadPriority, KNVMemDriveName );
       
   786 
       
   787 	if( r == KErrNone )
       
   788 		{
       
   789 		pM->iDfcQ = NVMemoryDfcQ;
       
   790 		}
       
   791 	else
       
   792 		{
       
   793 		__DEBUG_PRINT("NVMEM DFCQ initialization failed");
       
   794 		}
       
   795 
       
   796 	if (pM)
       
   797 
       
   798 		{
       
   799 		r=LocDrv::RegisterMediaDevice(EFixedMedia1,NVMEM1_DRIVECOUNT,&NVMemDriveNumbers[0],pM,NVMEM1_NUMMEDIA,KNVMemDriveName);
       
   800 		}
       
   801 
       
   802 	pM->iMsgQ.Receive();
       
   803 
       
   804 	__DEBUG_PRINT("Registering NVMEM drive - return %d",r);
       
   805 
       
   806 	return r;
       
   807 	}