--- /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