sl@0: // Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // f32\sfat\sl_disk.cpp sl@0: // sl@0: // sl@0: sl@0: //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! sl@0: //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! sl@0: //!! sl@0: //!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it sl@0: //!! sl@0: //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! sl@0: //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! sl@0: sl@0: #include "sl_disk.h" sl@0: #include "sl_cache.h" sl@0: #include "sl_dir_cache.h" sl@0: sl@0: /** sl@0: @file sl@0: */ sl@0: sl@0: sl@0: //################################################################################################################################ sl@0: //# CRawDisk implementation sl@0: //################################################################################################################################ sl@0: sl@0: sl@0: /** sl@0: Factory function. Constructs objects of the classes derived from CRawDisk. sl@0: sl@0: @param aOwner reference to the onwning FAT Mount class sl@0: @param aLocDrvCaps local drive capabilities from the media driver sl@0: @return pointer to the constructed object. May be NULL on error. sl@0: */ sl@0: CRawDisk* CRawDisk::NewL(CFatMountCB& aOwner, const TLocalDriveCaps& aLocDrvCaps) sl@0: { sl@0: __PRINT1(_L("CRawDisk::NewL() drv:%d"), aOwner.DriveNumber()); sl@0: sl@0: if(aLocDrvCaps.iMediaAtt & KMediaAttVariableSize) sl@0: {//-- this is the RAM drive "attribute" sl@0: ASSERT((aLocDrvCaps.iDriveAtt & (KDriveAttInternal|KDriveAttLocal)) && aLocDrvCaps.iType == EMediaRam); sl@0: if(!aLocDrvCaps.iBaseAddress) sl@0: { sl@0: ASSERT(0); sl@0: return NULL; sl@0: } sl@0: sl@0: return CRamDisk::NewL(aOwner); sl@0: } sl@0: sl@0: //-- create CAtaDisk by default sl@0: return CAtaDisk::NewL(aOwner); sl@0: } sl@0: sl@0: sl@0: CRawDisk::CRawDisk(CFatMountCB& aOwner) sl@0: { sl@0: iFatMount = &aOwner; sl@0: } sl@0: sl@0: /** sl@0: Default implementation. Initialises and re-initialises the object. sl@0: */ sl@0: void CRawDisk::InitializeL() sl@0: { sl@0: ASSERT(iFatMount); sl@0: } sl@0: sl@0: sl@0: TInt CRawDisk::GetLastErrorInfo(TDes8& /*aErrorInfo*/) const sl@0: { sl@0: return KErrNotSupported; sl@0: } sl@0: sl@0: //################################################################################################################################ sl@0: //## CAtaDisk class implementation sl@0: //################################################################################################################################ sl@0: sl@0: CAtaDisk::CAtaDisk(CFatMountCB& aFatMount) sl@0: :CRawDisk(aFatMount), iDrive(aFatMount.DriveInterface()) sl@0: { sl@0: } sl@0: sl@0: CAtaDisk::~CAtaDisk() sl@0: { sl@0: delete ipDirCache; sl@0: delete iUidCache; sl@0: sl@0: } sl@0: sl@0: sl@0: //------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: CAtaDisk factory method. sl@0: sl@0: @param aFatMount reference to the owner. sl@0: @return pointer to the constructed object. sl@0: */ sl@0: CAtaDisk* CAtaDisk::NewL(CFatMountCB& aFatMount) sl@0: { sl@0: __PRINT1(_L("CAtaDisk::NewL() drv:%d"), aFatMount.DriveNumber()); sl@0: sl@0: CAtaDisk* pSelf = new (ELeave) CAtaDisk(aFatMount); sl@0: sl@0: CleanupStack::PushL(pSelf); sl@0: sl@0: pSelf->ConstructL(); sl@0: pSelf->InitializeL(); sl@0: sl@0: CleanupStack::Pop(); sl@0: sl@0: return pSelf; sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------- sl@0: sl@0: /** 2nd stage constructor */ sl@0: void CAtaDisk::ConstructL() sl@0: { sl@0: //=========================== create data WT cache that is primarily used for caching exacutable modules' UIDs sl@0: const TUint32 KUidCachePageSzLog2 = 9; //-- 512 bytes in page sl@0: const TUint32 KUidCachePages = 64; //-- 64 pages; total cache size is 32K sl@0: sl@0: iUidCache = CMediaWTCache::NewL(iDrive, KUidCachePages, KUidCachePageSzLog2); sl@0: sl@0: sl@0: //=========================== create directory cache sl@0: sl@0: //-- Get dir. cache parameters from config. They may be set in estart.txt for a specified drive. sl@0: const TUint32 KDirCacheSize = iFatMount->FatConfig().DirCacheSize(); //- Total directory cache size, bytes. sl@0: const TUint32 KMaxDirCachePageSzLog2 = iFatMount->FatConfig().DirCacheMaxPageSizeLog2(); //- Log2 of the Max. dir. cache page. sl@0: sl@0: __PRINT2(_L("CAtaDisk::ConstructL() Dir Cache config:%d,%d"),KDirCacheSize,KMaxDirCachePageSzLog2); sl@0: sl@0: ASSERT(KDirCacheSize >= K1KiloByte && KDirCacheSize <= K1MegaByte); sl@0: ASSERT((KMaxDirCachePageSzLog2 >= KDefSectorSzLog2) && (Pow2(KMaxDirCachePageSzLog2) <= KDirCacheSize)); sl@0: sl@0: //-- calculate the size and number of pages for the dir. cache. sl@0: //-- if the mount's cluster size is less than max. page size from config, the page size will be cluster size. sl@0: //-- otherwise it will be the value from config. I.e the minimal page size is cluster size; the maximal page size is taken from config. sl@0: //-- The number of pages depends on total cache size and page size. sl@0: const TUint clustSizeLog2 = iFatMount->ClusterSizeLog2(); //-- current FAT cluster size Log2 sl@0: const TUint32 pageSzLog2 = (clustSizeLog2 <= KMaxDirCachePageSzLog2) ? clustSizeLog2 : KMaxDirCachePageSzLog2; sl@0: const TUint32 numPages = KDirCacheSize / (Pow2(pageSzLog2)); sl@0: sl@0: ASSERT(!ipDirCache); sl@0: sl@0: #ifdef USE_DP_DIR_CACHE sl@0: sl@0: //=========================== create Demand Paging type of the directory cache sl@0: sl@0: // initialize cache memory manager as all file systems have mounted by now sl@0: if(CCacheMemoryManagerFactory::CacheMemoryManager()) sl@0: { sl@0: // Note: the configuration data of min and max cache size are aligned with the memory size it sl@0: // occupies in kernel as we are using demand paging subsystem for dynamic cache size support. sl@0: // Therefore, they are refered as 'Mem Size' in following calculation. sl@0: // However, 'Data Size' refers to the logical size of a page, i.e. the actual data size each page sl@0: // contains. sl@0: // The constraints we have to consider when setting up the dynamic cache: sl@0: // 1. each page's data size is aligned with cluster size, unless cluster size is bigger than sl@0: // the default maximum page size allowed (typically 32 KB). sl@0: // 2. if page's data size is smaller than segment size (typically 4 KB), i.e. the unit size of sl@0: // demand paging subsystem's page management, we will still use up the whole segment for sl@0: // that page. sl@0: // 3. the default min and max cache's memory size is pre-defined in fat_config.cpp file. sl@0: // (see KDef_DynamicDirCacheMin & KDef_DynamicDirCacheMax). sl@0: sl@0: // calculate page data size (logical view of page size) sl@0: const TUint32 DefMaxCachePageLog2 = iFatMount->FatConfig().DynamicDirCacheMaxPageSizeLog2(); sl@0: const TUint32 PageDataSizeLog2 = clustSizeLog2 < DefMaxCachePageLog2 ? clustSizeLog2 : DefMaxCachePageLog2; sl@0: sl@0: // calculate page number, based on memory size we have reserved sl@0: const TUint32 SegmentSizeLog2 = CCacheMemoryManagerFactory::CacheMemoryManager()->SegmentSizeInBytesLog2(); sl@0: const TUint32 PageMemSizeLog2 = PageDataSizeLog2 < SegmentSizeLog2 ? SegmentSizeLog2 : PageDataSizeLog2; sl@0: TUint32 CacheSizeMinInPages = iFatMount->FatConfig().DynamicDirCacheSizeMin() >> PageMemSizeLog2; sl@0: TUint32 CacheSizeMaxInPages = iFatMount->FatConfig().DynamicDirCacheSizeMax() >> PageMemSizeLog2; sl@0: sl@0: // cache memory client is connected via name sl@0: TBuf<0x20> clientName = _L("CACHE_MEM_CLIENT:"); sl@0: clientName.Append('A'+iFatMount->DriveNumber()); sl@0: sl@0: TRAPD(err, ipDirCache = CDynamicDirCache::NewL(iDrive, CacheSizeMinInPages, CacheSizeMaxInPages, PageDataSizeLog2, clientName)); sl@0: if (err == KErrNone) sl@0: { sl@0: __PRINT4(_L("CDynamicDirCache::NewL(drv:%C, minPageNum:%u, maxPageNum:%u, pageDataSize:%u)\n"), 'A'+iFatMount->DriveNumber(), CacheSizeMinInPages, CacheSizeMaxInPages, 1<DriveNumber(), numPages, 1<InvalidateCache(); sl@0: sl@0: TInt64 cacheBasePos; sl@0: sl@0: if(iFatMount->FatType() == EFat32) sl@0: { sl@0: //-- this is FAT32, all directories including Root are files and aligned to the cluster heap boundary sl@0: //-- set dir. cache base position to the cluster heap boundary sl@0: const TUint32 offsetMask = (1 << iFatMount->ClusterSizeLog2() )-1; sl@0: cacheBasePos = (iFatMount->ClusterBasePosition() & offsetMask); sl@0: } sl@0: else sl@0: { sl@0: //-- this is FAT12/16. Root directory is a separate volume object and has no alignment. sl@0: //-- set cache base position to its beginning. sl@0: cacheBasePos = iFatMount->StartOfRootDirInBytes(); sl@0: } sl@0: sl@0: ipDirCache->SetCacheBasePos(cacheBasePos); sl@0: sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Read data from the media through LRU data cache cache. sl@0: sl@0: @param aPos absolute media position sl@0: @param aLength how many bytes to read sl@0: @param aDes data descriptor sl@0: sl@0: @leave on error sl@0: */ sl@0: void CAtaDisk::ReadCachedL(TInt64 aPos,TInt aLength,TDes8& aDes) const sl@0: { sl@0: __PRINT3(_L("CAtaDisk::ReadL() pos:%u:%u, len:%u"), I64HIGH(aPos), I64LOW(aPos), aLength); sl@0: iUidCache->ReadL(aPos, aLength, aDes); sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Write data to the media through LRU data cache sl@0: sl@0: @param aPos absolute media position sl@0: @param aDes data descriptor sl@0: sl@0: @leave on error sl@0: */ sl@0: void CAtaDisk::WriteCachedL(TInt64 aPos, const TDesC8& aDes) sl@0: { sl@0: __PRINT3(_L("CAtaDisk::WriteL() pos:%u:%u, len:%u"), I64HIGH(aPos), I64LOW(aPos), aDes.Size()); sl@0: iUidCache->WriteL(aPos, aDes); sl@0: } sl@0: sl@0: sl@0: //------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Read data from the media directly without any caches. sl@0: Mostly used by file IO sl@0: sl@0: @param aPos absolute media position sl@0: @param aLength how many bytes to read sl@0: @param aTrg Pointer to the data descriptor, i.e. (const TAny*)(&TDes8) sl@0: @param aMessage Refrence to server message from request sl@0: @param anOffset Offset into read data to write sl@0: sl@0: @leave on error sl@0: */ sl@0: void CAtaDisk::ReadL(TInt64 aPos,TInt aLength,const TAny* aTrg,const RMessagePtr2 &aMessage,TInt anOffset) const sl@0: { sl@0: sl@0: __PRINT4(_L("CAtaDisk::ReadL() pos:%u:%u, len:%u, offset:%u"), I64HIGH(aPos), I64LOW(aPos), aLength, anOffset); sl@0: User::LeaveIfError(iDrive.ReadNonCritical(aPos,aLength,aTrg,aMessage,anOffset)); sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Write data to the media directly without any cached. sl@0: Mostly used by file IO sl@0: sl@0: This method shall invalidate some data caches to keep them in synch with the media. sl@0: sl@0: @param aPos Media position in bytes sl@0: @param aLength Length in bytes of write sl@0: @param aTrg Pointer to the data descriptor, i.e. (const TAny*)(&TDes8) sl@0: @param aMessage Refrence to server message from request, contains data sl@0: @param anOffset Offset into write data to use in write sl@0: sl@0: @leave on error sl@0: */ sl@0: void CAtaDisk::WriteL(TInt64 aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2 &aMessage,TInt anOffset) sl@0: { sl@0: __PRINT4(_L("CAtaDisk::WriteL() pos:%u:%u, len:%u, offset:%u"), I64HIGH(aPos), I64LOW(aPos), aLength, anOffset); sl@0: sl@0: //-- write data to the media directly sl@0: User::LeaveIfError(iDrive.WriteNonCritical(aPos,aLength,aSrc,aMessage,anOffset)); sl@0: sl@0: //-- we need to invalidate UID cache page that corresponds to aPos (if any). This is UID caching specific. UID is stored in the first few bytes of sl@0: //-- the executable module and therefore belongs to one cache page only. sl@0: //-- If someone writes to the beginning of the exe module file, corresponding UID cache page will be invalidated and re-read from the media later sl@0: iUidCache->InvalidateCachePage(aPos); sl@0: sl@0: //-- invalidate affected(if any) part of the FAT cache in the case if someone used to write data to FAT area, which usually do not happen sl@0: iFatMount->FAT().InvalidateCacheL(aPos,aLength); sl@0: sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------- sl@0: sl@0: /** Get information for last disk error */ sl@0: TInt CAtaDisk::GetLastErrorInfo(TDes8& aErrorInfo) const sl@0: { sl@0: return iDrive.GetLastErrorInfo(aErrorInfo); sl@0: } sl@0: sl@0: sl@0: //------------------------------------------------------------------------------------- sl@0: /** Invalidate whole UID cache */ sl@0: void CAtaDisk::InvalidateUidCache() sl@0: { sl@0: ASSERT(iUidCache); sl@0: iUidCache->InvalidateCache(); sl@0: } sl@0: sl@0: /** sl@0: Invalidate the UID cache page that has aPos cached. sl@0: This method doesn't pay attention to the length of the block being invalidated because sl@0: UID lives in the very beginning of the exe module and always fits into a single page sl@0: */ sl@0: void CAtaDisk::InvalidateUidCachePage(TUint64 aPos) sl@0: { sl@0: ASSERT(iUidCache); sl@0: iUidCache->InvalidateCachePage(aPos); sl@0: } sl@0: sl@0: sl@0: //################################################################################################################################ sl@0: //## CRamDisk class implementation sl@0: //################################################################################################################################ sl@0: sl@0: sl@0: /** sl@0: CRamDisk factory method. sl@0: sl@0: @param aFatMount reference to the owner. sl@0: @return pointer to the constructed object. sl@0: */ sl@0: CRamDisk* CRamDisk::NewL(CFatMountCB& aFatMount) sl@0: { sl@0: __PRINT1(_L("CRamDisk::NewL() drv:%d"), aFatMount.DriveNumber()); sl@0: CRamDisk* pSelf = new(ELeave)CRamDisk(aFatMount); sl@0: sl@0: CleanupStack::PushL(pSelf); sl@0: sl@0: pSelf->InitializeL(); sl@0: sl@0: CleanupStack::Pop(); sl@0: sl@0: return pSelf; sl@0: } sl@0: sl@0: CRamDisk::CRamDisk(CFatMountCB& aFatMount) sl@0: :CRawDisk(aFatMount) sl@0: { sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------- sl@0: sl@0: /** sl@0: Initialises and re-initialises the object. sl@0: */ sl@0: void CRamDisk::InitializeL() sl@0: { sl@0: CRawDisk::InitializeL(); sl@0: sl@0: //-- set the RAM disk base sl@0: TLocalDriveCapsV2 caps; sl@0: TPckg capsPckg(caps); sl@0: User::LeaveIfError(iFatMount->LocalDrive()->Caps(capsPckg)); sl@0: sl@0: ASSERT(caps.iMediaAtt & KMediaAttVariableSize); sl@0: sl@0: //-- set RAM disk base sl@0: iRamDiskBase = caps.iBaseAddress; sl@0: ASSERT(iRamDiskBase); sl@0: } sl@0: sl@0: sl@0: sl@0: /** @return the start address of the Ram Drive in low memory */ sl@0: TUint8* CRamDisk::RamDiskBase() const sl@0: { sl@0: return iRamDiskBase; sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------- sl@0: // sl@0: // Read aLength of data from the disk sl@0: // sl@0: void CRamDisk::ReadCachedL(TInt64 aPos,TInt aLength,TDes8& aDes) const sl@0: { sl@0: sl@0: __PRINT3(_L("CRamDisk::ReadL Base 0x%x Pos 0x%x, Len %d"),RamDiskBase(),I64LOW(aPos),aLength); sl@0: __ASSERT_ALWAYS((aPos+aLength<=I64INT(iFatMount->Size())) && (aLength>=0),User::Leave(KErrCorrupt)); sl@0: Mem::Copy((TUint8*)aDes.Ptr(),RamDiskBase()+I64LOW(aPos),aLength); sl@0: aDes.SetLength(aLength); sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------- sl@0: // sl@0: // Write aLength of data to the disk sl@0: // sl@0: void CRamDisk::WriteCachedL(TInt64 aPos,const TDesC8& aDes) sl@0: { sl@0: sl@0: __PRINT3(_L("CRamDisk::WriteL Base 0x%x Pos 0x%x, Len %d"),RamDiskBase(),aPos,aDes.Length()); sl@0: __ASSERT_ALWAYS(aPos+aDes.Length()<=I64INT(iFatMount->Size()),User::Leave(KErrCorrupt)); sl@0: Mem::Copy(RamDiskBase()+I64LOW(aPos),(TUint8*)aDes.Ptr(),aDes.Length()); sl@0: } sl@0: sl@0: sl@0: //------------------------------------------------------------------------------------- sl@0: // sl@0: // Read from ramDrive into thread relative descriptor sl@0: // sl@0: void CRamDisk::ReadL(TInt64 aPos,TInt aLength,const TAny* /*aTrg*/,const RMessagePtr2 &aMessage,TInt anOffset) const sl@0: { sl@0: __PRINT2(_L("CRamDisk::ReadL TAny* Pos 0x%x, Len %d"),aPos,aLength); sl@0: __ASSERT_ALWAYS((aPos+aLength<=I64INT(iFatMount->Size())) && (aLength>=0),User::Leave(KErrCorrupt)); sl@0: TUint8* pos=RamDiskBase()+I64LOW(aPos); sl@0: TPtrC8 buf(pos,aLength); sl@0: aMessage.WriteL(0,buf,anOffset); sl@0: } sl@0: sl@0: //------------------------------------------------------------------------------------- sl@0: // sl@0: // Write from thread relative descriptor into ramDrive sl@0: // sl@0: void CRamDisk::WriteL(TInt64 aPos,TInt aLength,const TAny* /*aSrc*/,const RMessagePtr2 &aMessage,TInt anOffset) sl@0: { sl@0: __PRINT2(_L("CRamDisk::WriteL TAny* Pos 0x%x, Len %d"),aPos,aLength); sl@0: __ASSERT_ALWAYS(aPos+aLength<=I64INT(iFatMount->Size()),User::Leave(KErrCorrupt)); sl@0: TUint8* pos=RamDiskBase()+I64LOW(aPos); sl@0: TPtr8 buf(pos,aLength); sl@0: aMessage.ReadL(0,buf,anOffset); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: