kernel/eka/include/drivers/locmedia.h
changeset 0 a41df078684a
child 6 0173bcd7697c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/include/drivers/locmedia.h	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,1379 @@
+// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32\include\drivers\locmedia.h
+// 
+//
+
+#ifndef LOCMEDIA_H
+#define LOCMEDIA_H
+#include <plat_priv.h>
+#include <d32locd.h>
+
+#if defined(_DEBUG) && defined(__DEMAND_PAGING__)
+#define __CONCURRENT_PAGING_INSTRUMENTATION__
+#endif
+#if defined(_DEBUG) && defined(__DEMAND_PAGING__)
+#define __DEMAND_PAGING_BENCHMARKS__
+#endif
+
+#ifdef __WINS__
+	#define __EMULATOR_DMA_SUMULATION__
+#endif
+
+/**
+@publishedPartner
+@released
+
+A media driver priority value.
+
+The value can be returned by a media driver's PDD factory Info() function,
+and allows Symbian OS to decide the order in which media drivers are to be opened.
+
+The value is relative to the other media driver priority values.
+
+@see DPhysicalDevice::Info()
+*/
+const TInt KMediaDriverPriorityHigh=2;
+
+
+
+
+/**
+@publishedPartner
+@released
+
+A media driver priority value.
+
+The value can be returned by a media driver's PDD factory Info() function,
+and allows Symbian OS to decide the order in which media drivers are to be opened.
+
+The value is relative to the other media driver priority values, and is
+the one most commonly used.
+
+@see DPhysicalDevice::Info()
+*/
+const TInt KMediaDriverPriorityNormal=1;
+
+
+
+
+/**
+@publishedPartner
+@released
+
+A media driver priority value.
+
+The value can be returned by a media driver's PDD factory Info() function,
+and allows Symbian OS to decide the order in which media drivers are to be opened.
+
+The value is relative to the other media driver priority values.
+
+@see DPhysicalDevice::Info()
+*/
+const TInt KMediaDriverPriorityLow=0;
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Media driver interface major version number.
+*/
+const TInt KMediaDriverInterfaceMajorVersion=1;
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Media driver interface minor version number.
+*/
+const TInt KMediaDriverInterfaceMinorVersion=0;
+
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Media driver interface build number.
+*/
+const TInt KMediaDriverInterfaceBuildVersion=160;
+
+
+
+
+/**
+@publishedPartner
+@released
+*/
+const TInt KMediaDriverDeferRequest=1;
+
+
+
+
+/**
+@internalTechnology
+*/
+#define __TRACE_TIMING(x)
+//#define __TRACE_TIMING(x) *(TInt*)0x63000ff0=x
+
+/**
+@internalComponent
+*/
+NONSHARABLE_CLASS(DLocalDriveFactory) : public DLogicalDevice
+	{
+public:
+	DLocalDriveFactory();
+	virtual TInt Install();
+	virtual void GetCaps(TDes8 &aDes) const;
+	virtual TInt Create(DLogicalChannelBase*& aChannel);
+	};
+
+class TLocDrv;
+class DLocalDrive;
+
+/**
+@internalComponent
+*/
+NONSHARABLE_CLASS(TLocalDriveCleanup) : public TThreadCleanup
+	{
+public:
+	TLocalDriveCleanup();
+	virtual void Cleanup();
+	inline DLocalDrive& LocalDrive();
+	};
+
+
+
+class TLocDrvRequest;
+class DPrimaryMediaBase;
+
+/**
+@publishedPartner
+@released
+
+This class is strictly internal to Symbian; the only part of this class that
+is publicly exposed to partners is the TRequestId enum.
+
+@see DLocalDrive::TRequestId
+*/
+NONSHARABLE_CLASS(DLocalDrive) : public DLogicalChannelBase
+	{
+public:
+	/**
+	Identifies the specific local drive operation.
+	*/
+	enum TRequestId
+		{
+		/**
+		Requests information about the size, type, and attributes of the media.
+		*/
+		ECaps=0,
+		
+		/**
+		Requests an asynchronous read from the media device.
+		*/
+		ERead=1,
+		
+		/**
+		Requests an asynchronous write to the media device.
+		*/
+		EWrite=2,
+		
+		/**
+		Requests the formatting of a section of the media
+		*/
+		EFormat=3,
+		
+		/**
+		A request to expand the total size of the media.
+		*/
+		EEnlarge=4,
+		
+		/**
+		A request to reduce the total size of the media.
+		*/
+		EReduce=5,
+		
+		/**
+		A request to force a remount of the media.
+		*/
+		EForceMediaChange=6,
+		
+		/**
+		Requests an attempt to lock the media with a password.
+		*/
+		EPasswordLock=7,
+		
+		/**
+		Requests an attempt to unlock the media.
+		*/
+		EPasswordUnlock=8,
+		
+		/**
+		Requests an attempt to remove the password from the media.
+		*/
+		EPasswordClear=9,
+		
+		/**
+		Requests an read of the password store.
+		*/
+		EReadPasswordStore=10,
+		
+		/**
+		Requests a write of the password store.
+		*/
+		EWritePasswordStore=11,
+		
+		/** 
+		A request to get the length of the password store.
+		*/
+		EPasswordStoreLengthInBytes=12,
+		/** 
+		A Control IO request
+		*/
+		EControlIO=13,
+		/** 
+		A request to force an erase of the password from the media
+		*/
+		EPasswordErase=14,
+
+		/** 
+		A delete notification from the file system
+		*/
+		EDeleteNotify=15,
+
+		/** 
+		A request for information on the last error
+		*/
+		EGetLastErrorInfo=16,
+
+		EFirstReqNumberReservedForPaging=17,
+		// DO NOT REUSE ANY OF THE REQUEST NUMBERS BETWEEN THIS AND THE LAST RESERVED REQ NUMBER
+		// ALSO DO NOT INSERT ANY REQUEST NUMBERS BEFORE THIS, AS THIS WILL BE A COMPATIBILITY BREEAK
+		ELastReqNumberReservedForPaging=31,
+
+		/**
+		Query device 
+		*/
+		EQueryDevice=32,
+
+		};
+public:
+	DLocalDrive(); 
+	~DLocalDrive();
+public:
+	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); /**< @internalComponent */
+	virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);                      /**< @internalComponent */
+public:
+	void NotifyChange(DPrimaryMediaBase& aPrimaryMedia, TBool aMediaChange);
+public:
+	inline void Deque();                 /**< @internalComponent */
+
+private:
+#ifdef __DEMAND_PAGING__
+	TInt LockMountInfo(DPrimaryMediaBase& aPrimaryMedia, TLocDrvRequest& aReq);
+	void UnlockMountInfo(DPrimaryMediaBase& aPrimaryMedia);
+#endif
+
+public:
+	TLocDrv* iDrive;							/**< @internalComponent */
+	SDblQueLink iLink;							/**< @internalComponent */
+	TClientDataRequest<TBool>* iNotifyChangeRequest;	/**< @internalComponent */
+	TLocalDriveCleanup iCleanup;				 /**< @internalComponent */
+	};
+
+/**
+@internalComponent
+*/
+inline DLocalDrive& TLocalDriveCleanup::LocalDrive()
+	{ return *_LOFF(this,DLocalDrive,iCleanup); }
+
+
+
+
+/**
+@publishedPartner
+@released
+
+A class that encapsulates the request information received from the client,
+and gives the media driver access to the request ID and other associated
+parameters, such as the request length, offset, the requesting thread,
+source and destination address etc.
+
+An object of this type is passed to DMediaDriver::Request().
+
+@see DMediaDriver::Request()
+*/
+class TLocDrvRequest : public TThreadMessage
+	{
+public:
+
+    /** 
+	@internalComponent
+    */
+	enum TFlags
+		{
+		EWholeMedia=1,
+		EAdjusted=2,
+		EPhysAddr=0x04,
+		EPaging=0x08,				// a paging request
+		EBackgroundPaging=0x10,		// a background paging request. @see DMediaPagingDevice::Write()
+		ECodePaging=0x20,			// a code paging request
+		EDataPaging=0x40,			// a data paging request
+		ETClientBuffer=0x80,		// RemoteDes() points to a TClientBuffer
+		};
+public:
+    
+    /**
+    Gets a reference to the object containing the request information.
+    
+    @return The request information.
+    */
+	inline static TLocDrvRequest& Get()
+		{return (TLocDrvRequest&)Kern::Message();}
+	
+		
+    /**
+    Gets the request ID.
+    
+    For media drivers, this is one of the DLocalDrive::TRequestId enumerated values.
+    
+    @return The request ID.
+    
+    @see DLocalDrive::TRequestId
+    */
+	inline TInt& Id()
+		{return *(TInt*)&iValue;}
+		
+		
+    /**
+    Gets the position on the media on which the request operates. 
+    
+    This applies to operations ERead, EWrite and EFormat.
+
+    Note that the partition offset is taken into account by the underlying
+    local media subsystem.
+    
+    @return The position on the media.
+    
+    @see TRequestId::ERead
+    @see TRequestId::EWrite
+    @see TRequestId::EFormat
+    */		
+	inline Int64& Pos()
+		{return *(Int64*)&iArg[0];}
+	
+	
+	/**
+	Gets the length associated with the operation.
+	
+	This is the number of bytes associated with the media request.
+	It applies to operations ERead, EWrite and EFormat.
+	
+	@return The length, in bytes.
+	
+    @see TRequestId::ERead
+    @see TRequestId::EWrite
+    @see TRequestId::EFormat
+	*/
+	inline Int64& Length()
+		{return *(Int64*)&iArg[2];}
+		
+	
+	/**
+	Gets a pointer to the remote thread that requested the operation.
+	
+	This may be used to access the data to be read from the remote thread's process,
+	or the area to which data is to be written in the remote thread's process.
+	However, it is recommended that	such operations be performed
+	using ReadRemote() and WriteRemote()
+	
+	@return A reference to a pointer to the remote thread.
+	
+	@see TLocDrvRequest::ReadRemote()
+	@see TLocDrvRequest::WriteRemote()
+	*/
+	inline DThread*& RemoteThread()
+		{return *(DThread**)&iArg[4];}
+		
+		
+	/**
+	Gets a pointer to the descriptor in the remote thread's process that
+	contains the data to be read, or is the target for data to be written.
+	
+    However, it is recommended that such read or write operations be performed
+    using ReadRemote() and WriteRemote().
+    
+    @return A reference to a pointer to the remote descriptor.
+
+    @see TLocDrvRequest::ReadRemote()
+	@see TLocDrvRequest::WriteRemote()
+	*/	
+	inline TAny*& RemoteDes()
+		{return *(TAny**)&iArg[5];}
+		
+		
+    /**
+    Gets the offset within the descriptor in the remote thread's process.
+    
+    @return The offset within the descriptor.
+    */
+	inline TInt& RemoteDesOffset()
+		{return *(TInt*)&iArg[6];}
+		
+		
+	/**
+	@internalComponent
+	*/
+	inline TInt& Flags()
+		{return *(TInt*)&iArg[7];}
+		
+		
+	/**
+	@internalComponent
+	*/
+	inline TLocDrv*& Drive()
+		{return *(TLocDrv**)&iArg[8];}
+		
+		
+	/**
+	@internalComponent
+	*/
+	inline TInt& DriverFlags()
+		{return *(TInt*)&iArg[9];}
+
+
+	/**
+	Returns true if Physical memory addresses are available for this TLocDrvRequest.
+	@return ETrue if a physical memory address is available.
+	*/
+	inline TBool IsPhysicalAddress()
+		{return Flags() & EPhysAddr;}
+public:
+	TInt ProcessMessageData(TAny* args);
+	void CloseRemoteThread();
+	IMPORT_C TInt ReadRemote(TDes8* aDes, TInt anOffset);
+	IMPORT_C TInt ReadRemote(const TAny* aSrc, TDes8* aDes);
+	IMPORT_C TInt ReadRemoteRaw(TAny* aDes, TInt aSize);
+	IMPORT_C TInt WriteRemote(const TDesC8* aDes, TInt anOffset);
+	IMPORT_C TInt WriteRemoteRaw(const TAny* aSrc, TInt aSize);
+	IMPORT_C TInt CheckAndAdjustForPartition();
+#if !defined(__WINS__)
+	IMPORT_C TInt WriteToPageHandler(const TAny* aSrc, TInt aSize, TInt anOffset);
+	IMPORT_C TInt ReadFromPageHandler(TAny* aDst, TInt aSize, TInt anOffset);
+#endif // __WINS__
+	IMPORT_C TInt GetNextPhysicalAddress(TPhysAddr& aPhysAddr, TInt& aLength);
+	};
+
+
+
+
+/**
+@internalComponent
+*/
+inline void DLocalDrive::Deque()
+	{ iLink.Deque(); }
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Defines a structure used to contain information that describes an individual
+partition. 
+
+There is one of these for each partition that exists on a media device.
+
+@see TPartitionInfo
+*/
+class TPartitionEntry
+	{
+public:
+     
+    /**
+    The start address of the partition, described as a relative offset,
+    in bytes, from the start of the media.
+    
+    This value is used by the local media subsystem to calculate
+    the absolute address on the media whenever an access such as a Read,
+    Write or Format request is made.
+    */
+	Int64 iPartitionBaseAddr;
+ 
+ 	
+	/**
+	The length of the partition, in bytes.
+	*/
+	Int64 iPartitionLen;
+
+	
+	/**
+	The Boot Indicator record, as described in the Master Boot Record on
+	FAT Partitioned devices.
+
+	This is currently unused by the local media subsystem.
+	*/
+	TUint16 iBootIndicator;
+	
+	
+	/**
+	Describes the type of partition.
+	
+	The File Server uses this to decide the type of filesystem to be mounted
+	on the partition. 
+	
+	Symbian OS supports many partition types, as defined in partitions.h.
+	You are, however, free to invent your own partition type, on which
+	you could, for example, mount your own filesystem. However, make sure 
+	that your partition type does not clash with an existing partition type.
+	
+	Note that a media driver does not does not have to verify that
+	the partition actually contains a file system of this type; it just sets
+	this value to indicate the intended use for this partition.
+	*/
+	TUint16 iPartitionType;
+	};
+
+
+
+
+/**
+@publishedPartner
+@released
+
+A constant that defines the maximum number of partitions that can exist on
+a media device.
+
+@see TPartitionInfo::iPartitionCount
+*/
+const TInt KMaxPartitionEntries=0x10;
+
+
+
+
+/**
+@publishedPartner
+@released
+
+Contains partition information for a media device.
+
+An object of this type is passed to the media driver's implementation of
+DMediaDriver::PartitionInfo() to be filled in.
+
+@see DMediaDriver::PartitionInfo()
+*/
+class TPartitionInfo
+	{
+public:
+
+    /**
+    Default constructor that clears this object's memory to binary zeroes.
+    */
+	TPartitionInfo();
+public:
+
+    /**
+    The total size of the media, in bytes.
+    */
+	Int64 iMediaSizeInBytes;
+	
+	
+	/**
+	The total number of partitions that exist on the media.
+	
+	This is always less than or equal to KMaxPartitionEntries.
+	
+    @see KMaxPartitionEntries
+	*/
+	TInt iPartitionCount;
+	
+	
+	/**
+	Information that describes each individual partition on the device.
+	
+	Each partition is represented by an array of TPartitionEntry objects. 
+	Each entry must be created in the order of the start offset, so that 
+	iEntry[0] specifies the partition with
+	the smallest iPartitionBaseAddr value.
+	
+	@see TPartitionEntry::iPartitionBaseAddr
+	@see TPartitionEntry
+	*/
+	TPartitionEntry iEntry[KMaxPartitionEntries];
+	};
+
+
+
+
+class DMedia;
+class DPrimaryMediaBase;
+class DMediaDriver;
+#ifdef __DEMAND_PAGING__
+class DFragmentationPagingLock;
+#endif
+class DDmaHelper;
+
+/**
+@internalComponent
+*/
+class TLocDrv : public TPartitionEntry
+	{
+public:
+	TLocDrv(TInt aDriveNumber);
+public:
+	inline TInt Connect(DLocalDrive* aLocalDrive);
+	inline void Disconnect(DLocalDrive* aLocalDrive);
+	inline TInt Request(TLocDrvRequest& aRequest);
+public:
+	TInt iDriveNumber;
+	DMedia* iMedia;
+	DPrimaryMediaBase* iPrimaryMedia;
+	TInt iPartitionNumber;
+	TErrorInfo iLastErrorInfo;
+#ifdef __DEMAND_PAGING__
+	TInt iSpare0;
+	TUint8 iPagingDrv;
+	TUint8 iSpare1;
+	TUint8 iSpare2;
+	TUint8 iSpare3;
+#endif
+	DDmaHelper* iDmaHelper;
+	};
+
+/**
+@publishedPartner
+@released
+
+Kernel-side representation of a media entity. A DMedia object instantiates a 
+media driver to provide access to the physical media.
+
+Multiple DMedia objects may be required by some devices, e.g. multi-media cards
+with combined SRAM and Flash or cards containing user and protected areas.
+*/
+class DMedia : public DBase
+	{
+public:
+	/**
+	Declaration of all legal states for the media driver.
+	*/
+	enum TMediaState
+		{
+		/** 
+		Media is powered down and the media drivers are closed. This is the 
+		initial state when a media driver is created and the final state when
+		the driver is closed.
+		*/
+		EClosed=0,
+
+		/** Media driver has started powerup sequence. */
+		EPoweringUp1=1,
+
+		/** Media is being opened. */
+		EOpening=2,
+
+		/** Media is open and the partition information is being read. */
+		EReadPartitionInfo=3,
+		
+		/** The media driver is open and ready to accept commands. */
+		EReady=4,
+
+		/** Not used. */
+		EAborted=5,
+
+		/** Powering up with media drivers open. */
+		EPoweringUp2=6,
+
+		/** Not used. */
+		ERecovering=7,
+
+		/** The media is powered down, but the media driver still exists. */
+		EPoweredDown=8 // powered down with media drivers open
+		};
+
+public:
+	IMPORT_C virtual TInt Create(TMediaDevice aDevice, TInt aMediaId, TInt);
+	void Close();
+public:
+	inline Int64 MediaLenInBytes();
+	inline TMediaDevice DeviceType();
+	inline TInt PartitionCount();
+	inline Int64 PartitionBaseAddr(TInt aPartition);
+	inline Int64 PartitionLen(TInt aPartition);
+public:
+    /** Not used. */
+	static TInt MediaCallBack(TAny *aPtr);
+public:
+	/**
+	The unique ID associated with this media entity. 
+	ID allocated when the media is first created.
+	
+	@see LocDrv::RegisterMediaDevice
+	*/
+	TInt iMediaId;
+
+	/**
+	The unique ID for the device.
+
+	@see TMediaDevice
+	*/
+	TMediaDevice iDevice;
+
+	/**
+	Partition information for the media device.
+
+	@see TPartitionInfo
+	*/
+	TPartitionInfo iPartitionInfo;
+
+	/**
+	The media's physical device driver.
+
+	@see DMediaDriver
+	*/
+	DMediaDriver *iDriver;
+
+	/**
+	Mount information for the media device.
+	
+	@see TMountInfoData
+	*/
+	TMountInfoData iMountInfo;
+	};
+
+#ifdef __DEMAND_PAGING__
+class DFragmentationPagingLock;
+class DMediaPagingDevice;
+#endif
+
+
+/**
+@publishedPartner
+@released
+The DPrimaryMedia base class which is derived from DMedia class is responsible for controlling the overall state of the media 
+(for example whether the power is applied or the partition information has been determined and so on). 
+Each media driver or extension that registers for a set of local drives also has to register for a set of DMedia objects at the same time.
+This media set must contain just one primary media object. 
+The driver that performs drive registration is responsible for creating the primary media object itself, 
+which it then passes over to the local media sub-system for ownership. 
+If further media objects are specified in the set, then the local media sub-system itself creates DMedia instances for these on behalf of the driver.
+*/
+class DPrimaryMediaBase : public DMedia
+	{
+public:
+	enum TMsgId
+		{
+		EConnect=-1,
+		EDisconnect=-2,
+		};
+
+	enum TForceMediaChangeFlags
+		{
+		/**
+		Specifying zero as the flag for DPrimaryMediaBase::ForceMediaChange(), 
+		results in all media drivers associated with the primary media being 
+		closed and reopened.
+		All pending requests on all logical drives associated with the primary 
+		media will be cancelled.
+
+		@see DPrimaryMediaBase::ForceMediaChange()
+		@see RLocalDrive::ForceMediaChange()
+		*/
+		KForceMediaChangeReOpenAllMediaDrivers = 0,
+		/**
+		This flag is used to simulate ejecting and re-inserting the media.
+		All pending requests on all logical drives associated with the primary 
+		media will be cancelled.
+		N.B. This is asynchronous in behaviour i.e. the caller will need to wait 
+		for (two) media change notifications before the drive is ready for use
+
+		@see DPBusPrimaryMedia::ForceMediaChange()
+		@see RLocalDrive::ForceMediaChange()
+		*/
+		KMediaRemountForceMediaChange = 0x00000001,
+		/**
+		This flag is used to force the media driver for the specified logical 
+		drive to be closed and reopened.
+		It should not affect any pending requests on other logical drives 
+		associated with the primary media.
+
+		@see DPrimaryMediaBase::ForceMediaChange()
+		@see RLocalDrive::ForceMediaChange()
+		*/
+		KForceMediaChangeReOpenMediaDriver = 0x80000000
+		};
+
+public:
+	IMPORT_C DPrimaryMediaBase();
+public:
+	// provided by implementation
+	IMPORT_C virtual TInt Create(TMediaDevice aDevice, TInt aMediaId, TInt aLastMediaId);
+	IMPORT_C virtual TInt Connect(DLocalDrive* aLocalDrive);
+	IMPORT_C virtual void Disconnect(DLocalDrive* aLocalDrive);
+	IMPORT_C virtual TInt Request(TLocDrvRequest& aRequest);
+	IMPORT_C virtual TInt QuickCheckStatus();
+	IMPORT_C virtual TInt ForceMediaChange(TInt aMode);
+	IMPORT_C virtual TInt InitiatePowerUp();
+	IMPORT_C virtual TInt DoInCritical();
+	IMPORT_C virtual void DoEndInCritical();
+	IMPORT_C virtual void DeltaCurrentConsumption(TInt aCurrent);
+	IMPORT_C virtual void DefaultDriveCaps(TLocalDriveCapsV2& aCaps);
+	IMPORT_C virtual TBool IsRemovableDevice(TInt& aSocketNum);
+public:
+	// used by implementation
+	IMPORT_C void NotifyMediaChange();
+	IMPORT_C void NotifyPowerDown();
+	IMPORT_C void NotifyEmergencyPowerDown();
+	IMPORT_C void NotifyPsuFault(TInt anError);
+	IMPORT_C void NotifyMediaPresent();
+	IMPORT_C void PowerUpComplete(TInt anError);
+public:
+	IMPORT_C virtual void HandleMsg(TLocDrvRequest& aRequest);
+	IMPORT_C virtual TInt DoRequest(TLocDrvRequest& aRequest);
+	TInt OpenMediaDriver();
+	void CloseMediaDrivers(DMedia* aMedia = NULL);
+	void StartOpenMediaDrivers();
+	void OpenNextMediaDriver();
+	void DoOpenMediaDriverComplete(TInt anError);
+	void DoPartitionInfoComplete(TInt anError);
+	void CompleteCurrent(TInt anError);
+	void CompleteRequest(TLocDrvRequest& aMsg, TInt aResult);
+	IMPORT_C void RunDeferred();
+	void SetClosed(TInt anError);
+	void NotifyClients(TBool aMediaChange,TLocDrv* aLocDrv=NULL);
+	TInt InCritical();
+	void EndInCritical();
+	void UpdatePartitionInfo();
+	void MediaReadyHandleRequest();
+	TInt SendReceive(TLocDrvRequest& aReq, TLinAddr aLinAddress = NULL);
+
+#ifdef __DEMAND_PAGING__
+	TInt PinSendReceive(TLocDrvRequest& aReq, TLinAddr aStart = NULL);
+	TInt PinFragmentSendReceive(TLocDrvRequest& aReq, TLinAddr aLinAddress, TInt aLength);
+
+	TBool PagingMediaPinAddress(TLinAddr aLinAddress, TInt aSize);
+	void PagingMediaUnpinAddress();
+#endif
+
+#ifdef __DEMAND_PAGING__
+	void RequestCountInc();
+	void RequestCountDec();
+#endif
+
+public:
+	TInt iLastMediaId;					/**< @internalComponent */
+	TMessageQue iMsgQ;
+	TDfcQue* iDfcQ;
+	SDblQue iConnectionQ;				/**< @internalComponent */
+	TMessageQue iDeferred;				/**< @internalComponent */
+	TMessageQue iWaitMedChg;			/**< @internalComponent */
+	TInt iState;						/**< @internalComponent */
+	TInt iCritical;						/**< @internalComponent */
+	TLocDrvRequest* iCurrentReq;
+	TDfc iAsyncDfc;						/**< @internalComponent */
+	TInt iAsyncErrorCode;				/**< @internalComponent */
+	RPhysicalDeviceArray iPhysDevArray;	/**< @internalComponent */
+
+	class DBody;
+	DBody* iBody;						/**< @internalComponent */
+
+	TInt iNextMediaId;					/**< @internalComponent */
+	TInt iTotalPartitionsOpened;		/**< @internalComponent */
+	TInt iMediaDriversOpened;			/**< @internalComponent */
+	DMediaDriver* iNextMediaDriver;		/**< @internalComponent */
+
+
+#ifdef __DEMAND_PAGING__
+	// keep the size of class as it is used as base for PBus and may not want to bother building DP specific version.
+	TUint8 iPagingMedia;				/**< @internalComponent */
+	TUint8 iDataPagingMedia;			/**< @internalComponent */
+	TUint8 iRomPagingMedia;				/**< @internalComponent */
+	TUint8 iRunningDeferred;			/**< @internalComponent */
+#else
+	TInt iRunningDeferred;				/**< @internalComponent */
+#endif
+	};
+
+#ifdef __DEMAND_PAGING__
+
+/**
+@internalComponent
+@prototype
+*/
+NONSHARABLE_CLASS(DMediaPagingDevice) : public DPagingDevice
+	{
+public:
+	enum TPagingRequestId
+		{
+		/** 
+		Identifies any middle fragment of a Write request on a partition of a media that supports paging.
+		@deprecated
+		*/
+		EWriteRequestFragment		=	DLocalDrive::EFirstReqNumberReservedForPaging,
+
+		/** 
+		Identifies the last fragment of a Write request on a partition of a media that supports paging.
+		@deprecated
+		*/
+		EWriteRequestFragmentLast	=	DLocalDrive::EFirstReqNumberReservedForPaging+1,
+
+		/** 
+		Request for paging in (read) data from the ROM store area.
+		*/
+		ERomPageInRequest			=	DLocalDrive::EFirstReqNumberReservedForPaging+2,
+
+		/** 
+		Request for paging in (read) data from the code store area.
+		*/
+		ECodePageInRequest			=	DLocalDrive::EFirstReqNumberReservedForPaging+3,
+
+        /**
+        Provided to allow the following compile time assert.
+        */
+		EPagingRequestHighWaterMark
+		};
+    __ASSERT_COMPILE(EPagingRequestHighWaterMark <= DLocalDrive::ELastReqNumberReservedForPaging + 1);
+
+	enum TQueue
+		{
+		EMainQ = 0x01,
+		EDeferredQ=0x02
+		};
+
+public:
+	DMediaPagingDevice(DPrimaryMediaBase* aPtr);
+	virtual ~DMediaPagingDevice();
+	
+	// from DPagingDevice
+	virtual TInt Read(TThreadMessage* aReq,TLinAddr aBuffer,TUint aOffset,TUint aSize,TInt aDrvNumber);
+	virtual TInt Write(TThreadMessage* aReq,TLinAddr aBuffer,TUint aOffset,TUint aSize, TBool aBackground);
+	virtual TInt DeleteNotify(TThreadMessage* aReq,TUint aOffset,TUint aSize);
+
+	void CompleteRequest(TThreadMessage* aMsg, TInt aResult);
+	void SendToMainQueueDfcAndBlock(TThreadMessage* aMsg);
+	void SendToDeferredQ(TThreadMessage* aMsg);
+	inline static TBool PageInRequest(TLocDrvRequest& aReq);
+	inline static TBool PageOutRequest(TLocDrvRequest& aReq);
+	inline static TBool PagingRequest(TLocDrvRequest& aReq);
+public:
+	TMessageQue iMainQ;
+	TMessageQue iDeferredQ;
+	DPrimaryMediaBase* iPrimaryMedia;
+
+	TUint8 iEmptyingQ;
+	TUint8 iDeleteNotifyNotSupported;
+	TUint8 iSpare1;
+	TUint8 iSpare2;
+
+	TAny* iMountInfoDataLock;
+	TAny* iMountInfoDescHdrLock;
+	TAny* iMountInfoDescLenLock;
+
+	TInt iFirstLocalDriveNumber;
+	TInt iRomPagingDriveNumber;
+	TInt iDataPagingDriveNumber;
+
+	NFastMutex iInstrumentationLock;			// To protect instrumentation data
+
+#ifdef __CONCURRENT_PAGING_INSTRUMENTATION__
+	TUint8 iServicingROM;
+	TUint8 iServicingCode;
+	TUint8 iServicingDataIn;
+	TUint8 iServicingDataOut;
+
+	SMediaROMPagingConcurrencyInfo iROMStats;
+	SMediaCodePagingConcurrencyInfo iCodeStats;
+	SMediaDataPagingConcurrencyInfo iDataStats;
+#endif
+
+#ifdef __DEMAND_PAGING_BENCHMARKS__
+	SPagingBenchmarkInfo iROMBenchmarkData;
+	SPagingBenchmarkInfo iCodeBenchmarkData;
+	SPagingBenchmarkInfo iDataInBenchmarkData;
+	SPagingBenchmarkInfo iDataOutBenchmarkData;
+	SMediaPagingInfo iMediaPagingInfo;
+#endif
+	};
+
+inline TBool DMediaPagingDevice::PageInRequest(TLocDrvRequest& aReq)
+	{
+	return 
+		(aReq.Flags() & TLocDrvRequest::EPaging) && 
+		(aReq.Id() == ERomPageInRequest || 
+		 aReq.Id() == ECodePageInRequest || 
+		 aReq.Id() == DLocalDrive::ERead);}
+
+inline TBool DMediaPagingDevice::PageOutRequest(TLocDrvRequest& aReq)
+	{
+	return 
+		(aReq.Flags() & TLocDrvRequest::EPaging) && 
+		(aReq.Id() == DLocalDrive::EWrite);}
+
+inline TBool DMediaPagingDevice::PagingRequest(TLocDrvRequest& aReq)
+	{
+	return (aReq.Flags() & TLocDrvRequest::EPaging);
+	}
+
+
+/**
+@internalComponent
+@prototype
+*/
+class DFragmentationPagingLock: public DDemandPagingLock
+	{
+public:
+	TInt Construct(TUint aNumPages);
+	void Cleanup();
+	void LockFragmentation()
+		{
+		__ASSERT_CRITICAL;
+		__ASSERT_DEBUG(iFragmentationMutex, Kern::Fault("LOCMEDIA_H",__LINE__));
+		// called in CS
+		Kern::MutexWait(*iFragmentationMutex);
+		}
+	void UnlockFragmentation()
+		{
+		__ASSERT_CRITICAL;
+		__ASSERT_DEBUG(iFragmentationMutex, Kern::Fault("LOCMEDIA_H",__LINE__));
+		// called in CS
+		Kern::MutexSignal(*iFragmentationMutex);
+		}
+
+
+public:
+	TUint iFragmentGranularity;
+private:
+	DMutex* iFragmentationMutex; // to protect Kernel memory locking
+	};
+#endif //__DEMAND_PAGING__
+
+/**
+@publishedPartner
+@released
+
+An abstract base class for all media drivers in the local drive system.
+
+All media drivers, whether associated with fixed media, such as the internal
+drive, or removable media, such as a PC Card or MultiMediaCard, must define
+and implement a class derived from this one.
+
+An instance of this class is created by the media driver's PDD factory,
+an instance of a class derived from DPhysicalDevice. 
+
+@see DPhysicalDevice::Create()
+@see DPhysicalDevice
+*/
+class DMediaDriver : public DBase
+	{
+public:
+	IMPORT_C DMediaDriver(TInt aMediaId);
+	IMPORT_C virtual ~DMediaDriver();
+	IMPORT_C virtual void Close();
+// Pure virtual
+	IMPORT_C virtual void Disconnect(DLocalDrive* aLocalDrive, TThreadMessage* aMsg);
+	
+	/**
+	A function called by the local media subsystem to deal with a request, 
+	and which must be implemented by the media driver.
+	
+	@param aRequest An object that encapsulates information about the request.
+	
+	@return A value indicating the result:
+	        KErrNone, if the request has been sucessfully initiated;
+	        KErrNotSupported, if the request cannot be handled by the device;
+	        KMediaDriverDeferRequest, if the request cannot be handled
+	        immediately because of an outstanding request (this request will be
+	        deferred until the outstanding request has completed);
+	        otherwise one of the other system-wide error codes.
+	*/
+	virtual TInt Request(TLocDrvRequest& aRequest)=0;
+
+	/**
+	A function called by the local media subsystem to get partition information
+	for the media device.
+	
+	It is called once the subsystem has been notified that the media driver
+	is open and has been succesfully initialised.
+	
+	This function must be implemented by the media driver.
+	
+	@param anInfo An object that, on successful return, contains
+	              the partition information.
+	
+	@return KErrNone, if retrieval of partition information is to be
+	        done asynchronously;
+	        KErrCompletion, if retrieval of partition information has been
+	        done synchronously, and successfully;
+	        one of the other system-wide error codes, if retrieval of partition
+	        information has been done synchronously, but unsuccessfully.
+	*/
+	virtual TInt PartitionInfo(TPartitionInfo &anInfo)=0;
+
+	/**
+	A function called by the local media subsystem to inform the media driver
+	that the device should power down.
+	
+	This function must be implemented by the media driver.
+	*/
+	virtual void NotifyPowerDown()=0;
+
+	/**
+	A function called by the local media subsystem to inform the media driver
+	that the device is to be immediately powered down.
+	
+    This function must be implemented by the media driver.
+	*/
+	virtual void NotifyEmergencyPowerDown()=0;
+public:
+	IMPORT_C void SetTotalSizeInBytes(Int64 aTotalSizeInBytes, TLocDrv* aLocDrv=NULL);
+	IMPORT_C Int64 TotalSizeInBytes();
+	IMPORT_C void SetCurrentConsumption(TInt aValue);
+	IMPORT_C TInt InCritical();
+	IMPORT_C void EndInCritical();
+	IMPORT_C void Complete(TLocDrvRequest& aRequest, TInt aResult);
+	IMPORT_C void OpenMediaDriverComplete(TInt anError);
+	IMPORT_C void PartitionInfoComplete(TInt anError);
+public:
+	DPhysicalDevice* iPhysicalDevice;/**< @internalComponent */
+	Int64 iTotalSizeInBytes;         /**< @internalComponent */
+    TInt iCurrentConsumption;        /**< @internalComponent */
+	DPrimaryMediaBase* iPrimaryMedia;/**< @internalComponent */
+	TBool iCritical;                 /**< @internalComponent */
+	TMountInfoData* iMountInfo;      /**< @internalComponent */
+	};
+
+
+
+
+/**
+@publishedPartner
+@released
+
+A structure that a media driver may find useful in its implementation,
+and is used to contain the information required when registering
+the media driver with the Local Media Subsystem.
+
+@see LocDrv::RegisterMediaDevice()
+*/
+struct SMediaDeviceInfo
+	{
+	
+	/**
+	The unique Media ID for a device.
+	
+    This can take one of the enumerated values defined
+    by the TMediaDevice enum.
+	*/
+	TMediaDevice iDevice;
+	
+	
+	/**
+	Specifies the number of local drive objects to be assigned to the media driver.
+    
+    Drives that support more than one partition must specify a number greater than 1.
+	*/
+	TInt iDriveCount;
+	
+	
+	/**
+    A pointer to an array of TInt values, which define the drive numbers that
+    are to be allocated to each partition.
+    
+    0 signifies Drive C, 1 signifies drive D, etc. For example, to allocate
+    drive letters J and K, specify an array containing the values [7,8].
+    Note that the size of this array must be the same as the value specified
+    by iDriveCount.
+	*/
+	const TInt* iDriveList;
+	
+	
+	/**
+	Specifies the total number of DMedia objects to be associated with
+	the media driver.
+	
+	This number includes the primary DPrimaryMedia object, plus all of
+	the DMedia objects that are created for each additional drive, and
+	which hold basic information about partitions.
+	*/
+	TInt iNumMedia; 
+	
+	
+	/**
+	A pointer to a descriptor containing the name of the media driver,
+	for example: PCCard
+	*/
+	const TDesC* iDeviceName;
+	};
+
+
+
+
+/**
+@publishedPartner
+@released
+
+A set of utility functions used in the management of local media drivers.
+*/
+class LocDrv
+	{
+public:
+	IMPORT_C static TInt RegisterMediaDevice(TMediaDevice aDevice, TInt aDriveCount, const TInt* aDriveList, DPrimaryMediaBase* aPrimaryMedia, TInt aNumMedia, const TDesC& aName);
+	IMPORT_C static TInt RegisterPasswordStore(TPasswordStore* aStore);
+	IMPORT_C static TPasswordStore* PasswordStore();
+#if !defined(__WINS__)
+	IMPORT_C static TInt RegisterPagingDevice(DPrimaryMediaBase* aPrimaryMedia, const TInt* aPagingDriveList, TInt aDriveCount, TUint aPagingType, TInt aReadShift, TUint aNumPages);
+#endif // __WINS__
+	IMPORT_C static TInt RegisterDmaDevice(DPrimaryMediaBase* aPrimaryMedia,
+										   TInt aMediaBlockSize, 
+										   TInt aDmaMaxAddressable,
+										   TInt aDmaAlignment);
+	};
+
+/**
+@internalComponent
+*/
+inline TInt TLocDrv::Connect(DLocalDrive* aLocalDrive)
+	{ return iPrimaryMedia->Connect(aLocalDrive); }
+
+/**
+@internalComponent
+*/
+inline void TLocDrv::Disconnect(DLocalDrive* aLocalDrive)
+	{ iPrimaryMedia->Disconnect(aLocalDrive); }
+
+/**
+@internalComponent
+*/
+inline TInt TLocDrv::Request(TLocDrvRequest& aRequest)
+	{ return iPrimaryMedia->Request(aRequest); }
+
+/**
+Returns the length of the media, in bytes, according to the partition information.
+
+@return Total length of the media, in bytes.
+
+@see	TPartitionInfo
+*/
+inline Int64 DMedia::MediaLenInBytes()
+	{return(iPartitionInfo.iMediaSizeInBytes);}
+
+/**
+Returns the unique media ID for this device.
+
+@return	The device ID that was set in the call to DMedia::Create().
+		The return value will be one of the enumerators declared in TMediaDevice
+
+@see	TMediaDevice
+*/
+inline TMediaDevice DMedia::DeviceType()
+	{return(iDevice);}
+
+/**
+Returns the total number of partitions that exist on the media according to the
+partition information.
+
+This will always be less than or equal to KMaxPartitionEntries.
+
+@return Number of partitions that exist on the media.
+
+@see	KMaxPartitionEntries
+@see	TPartitionInfo
+*/
+inline TInt DMedia::PartitionCount()
+	{return(iPartitionInfo.iPartitionCount);}
+
+/**
+The start address of the partition, described as a relative offset, in bytes,
+from the start of the media.
+
+This value is used by the local media subsystem to calculate the absolute 
+address on the media whenever an access such as a Read, Write or Format request
+is made.
+
+@param	aPartition	The partition whose start address is to be returned.
+
+@return	The start address of the partition.
+
+@see	TPartitionEntry
+@see	TPartitionInfo
+*/
+inline Int64 DMedia::PartitionBaseAddr(TInt aPartition)
+	{return(iPartitionInfo.iEntry[aPartition].iPartitionBaseAddr);}
+
+/**
+Returns the length of the partition, in bytes.
+
+@param	aPartition	The partition whose length is to be returned.
+
+@return	The length of the partition.
+
+@see	TPartitionEntry
+@see	TPartitionInfo
+*/
+inline Int64 DMedia::PartitionLen(TInt aPartition)
+	{return(iPartitionInfo.iEntry[aPartition].iPartitionLen);}
+
+
+/**
+@internalTechnology
+
+A utility class for scanning MBR/EBR partition tables.
+*/
+class TPartitionTableScanner
+	{
+public:
+	enum {ESectorShift=9, ESectorSize=512};
+	enum {EMaxNest=4};
+	struct SPart
+		{
+		SPart(const TUint8* a);
+		TUint8 iBootInd;
+		TUint8 iType;
+		TUint32 iRSS;
+		TUint32 iSectors;
+		};
+	struct SEBR
+		{
+		TInt64 iRSS;
+		TInt64 iSectors;
+		};
+public:
+	IMPORT_C void Set(TUint8* aSectorBuffer, TPartitionEntry* aEntry, TInt aMaxPartitions, TInt64 aMediaSize);
+	IMPORT_C TInt64 NextLBA();
+	IMPORT_C TInt NumberOfPartitionsFound() const;
+	TInt MakeEntry(const SPart& aP);
+public:
+	TInt64 iMediaSize;				// Total media size in sectors
+	TInt64 iLBA;					// LBA currently in sector buffer
+	TInt64 iFirstEBR;				// LBA of first EBR if any
+	SEBR iStack[EMaxNest];
+	TInt iStackPointer;
+	TUint8* iSectorBuffer;			// Pointer to 512 byte area where sector data is stored
+	TPartitionEntry* iFirstEntry;	// Where first scanned partition is stored
+	TPartitionEntry* iNextEntry;	// Where next scanned partition will be stored
+	TPartitionEntry* iLimit;		// iFirstEntry + max partitions
+	};
+
+
+
+#endif