kernel/eka/drivers/locmedia/locmedia.cpp
branchRCL_3
changeset 42 a179b74831c9
parent 36 bbf8bed59bcb
child 43 c1f20ce4abcf
equal deleted inserted replaced
41:0ffb4e86fcc9 42:a179b74831c9
    27 #pragma warning(disable: 4127) // disabling warning "conditional expression is constant"
    27 #pragma warning(disable: 4127) // disabling warning "conditional expression is constant"
    28 #endif
    28 #endif
    29 #include "locmediaTraces.h"
    29 #include "locmediaTraces.h"
    30 #endif
    30 #endif
    31 
    31 
    32 
       
    33 #if defined(_DEBUG) && defined(__DEMAND_PAGING__)
    32 #if defined(_DEBUG) && defined(__DEMAND_PAGING__)
    34 //#define __DEBUG_DEMAND_PAGING__
    33 //#define __DEBUG_DEMAND_PAGING__
    35 #endif
    34 #endif
    36 
    35 
    37 
    36 
    69 TPasswordStore* ThePasswordStore=NULL;
    68 TPasswordStore* ThePasswordStore=NULL;
    70 
    69 
    71 class DPrimaryMediaBase::DBody : public DBase
    70 class DPrimaryMediaBase::DBody : public DBase
    72 	{
    71 	{
    73 public:
    72 public:
       
    73 	DBody(DPrimaryMediaBase& aPrimaryMediaBase);
       
    74 public:
       
    75 	DPrimaryMediaBase& iPrimaryMediaBase;	// ptr to parent
    74 	TInt iPhysDevIndex;
    76 	TInt iPhysDevIndex;
    75 	TInt iRequestCount;
    77 	TInt iRequestCount;
    76 #ifdef __DEMAND_PAGING__
    78 #ifdef __DEMAND_PAGING__
    77 	DMediaPagingDevice* iPagingDevice;
    79 	DMediaPagingDevice* iPagingDevice;
    78 	TInt iPageSizeMsk;			// Mask of page size (e.g. 4096-1 -> 4095)
    80 	TInt iPageSizeMsk;			// Mask of page size (e.g. 4096-1 -> 4095)
    79 	TInt iPageSizeLog2;        // LOG2 of page size (i.e. 4096 -> 12)
    81 	TInt iPageSizeLog2;        // LOG2 of page size (i.e. 4096 -> 12)
    80 	TInt iMediaChanges;
    82 	TInt iMediaChanges;
    81 #endif
    83 #endif
       
    84 
       
    85 	// This bit mask indicates which local drives the media is attached to
       
    86 	TUint32 iRegisteredDriveMask;
       
    87 
       
    88 	// Set to ETrue for media extension drivers
       
    89 	TBool iMediaExtension;
       
    90 	
       
    91 	// Media change DFCs to allow media change events from attached media
       
    92 	// to be handled in the context of an extension media's thread
       
    93 	TDfc iMediaChangeDfc;
       
    94 	TDfc iMediaPresentDfc;
    82 	};
    95 	};
    83 
    96 
    84 #ifdef __DEMAND_PAGING__
    97 #ifdef __DEMAND_PAGING__
    85 DMediaPagingDevice* ThePagingDevices[KMaxLocalDrives];
    98 DMediaPagingDevice* ThePagingDevices[KMaxLocalDrives];
    86 DPrimaryMediaBase* TheRomPagingMedia = NULL;
    99 DPrimaryMediaBase* TheRomPagingMedia = NULL;
    87 DPrimaryMediaBase* TheDataPagingMedia = NULL;
   100 DPrimaryMediaBase* TheDataPagingMedia = NULL;
       
   101 TLocDrv* TheDataPagingDrive = NULL;
    88 TBool DataPagingDeviceRegistered = EFalse;
   102 TBool DataPagingDeviceRegistered = EFalse;
    89 class DPinObjectAllocator;
   103 class DPinObjectAllocator;
    90 DPinObjectAllocator* ThePinObjectAllocator = NULL;
   104 DPinObjectAllocator* ThePinObjectAllocator = NULL;
    91 
   105 
    92 // The paging media might share a DfcQ with other non-paging media (e.g. 2 MMC/SD cards sharing the same stack)
   106 // The paging media might share a DfcQ with other non-paging media (e.g. 2 MMC/SD cards sharing the same stack)
    93 // In this case, we need to avoid taking page faults on the non-paging media too, hence the need for these checks:
   107 // In this case, we need to avoid taking page faults on the non-paging media too, hence the need for these checks:
    94 inline TBool DataPagingDfcQ(DPrimaryMediaBase* aPrimaryMedia)
   108 inline TBool DataPagingDfcQ(DPrimaryMediaBase* aPrimaryMedia)
    95 	{return TheDataPagingMedia && TheDataPagingMedia->iDfcQ == aPrimaryMedia->iDfcQ;}
   109 	{return TheDataPagingMedia && TheDataPagingMedia->iDfcQ == aPrimaryMedia->iDfcQ;}
       
   110 
       
   111 
       
   112 TBool DataPagingMedia(DPrimaryMediaBase* aPrimaryMedia)
       
   113 	{
       
   114 	for (TLocDrv* drv = TheDataPagingDrive; drv; drv = drv->iNextDrive)
       
   115 		if (drv->iPrimaryMedia == aPrimaryMedia)
       
   116 			return ETrue;
       
   117 	return EFalse;
       
   118 	}
       
   119 
    96 inline TBool RomPagingDfcQ(DPrimaryMediaBase* aPrimaryMedia)
   120 inline TBool RomPagingDfcQ(DPrimaryMediaBase* aPrimaryMedia)
    97 	{return TheRomPagingMedia && TheRomPagingMedia->iDfcQ == aPrimaryMedia->iDfcQ;}
   121 	{return TheRomPagingMedia && TheRomPagingMedia->iDfcQ == aPrimaryMedia->iDfcQ;}
       
   122 
       
   123 
       
   124 #if defined(_DEBUG)
       
   125 	#define SETDEBUGFLAG(aBitNum) {Kern::SuperPage().iDebugMask[aBitNum >> 5] |= (1 << (aBitNum & 31));}
       
   126 	#define CLRDEBUGFLAG(aBitNum) {Kern::SuperPage().iDebugMask[aBitNum >> 5] &= ~(1 << (aBitNum & 31));}
       
   127 #else
       
   128 	#define SETDEBUGFLAG(aBitNum)
       
   129 	#define CLRDEBUGFLAG(aBitNum)
       
   130 #endif
    98 
   131 
    99 
   132 
   100 
   133 
   101 /* 
   134 /* 
   102 DPinObjectAllocator
   135 DPinObjectAllocator
   103 
   136 
   104 Internal class which contains :
   137 Internal class which contains :
   105 	(1) a queue of pre-allocated TVirtualPinObject's; 
   138 	(1) a queue of pre-allocated TVirtualPinObject's; 
   106 	(2) a single pre-allocated DFragmentationPagingLock object: 
   139 	(2) a single pre-allocated DFragmentationPagingLock object: 
   107 		this may be used if there are no TVirtualPinObject's available or if Kern::PinVirtualMemory() fails
   140 		this may be used if there are no TVirtualPinObject's available or if Kern::PinVirtualMemory() fails
       
   141 @internalTechnology
   108 */
   142 */
   109 NONSHARABLE_CLASS(DPinObjectAllocator) : public DBase
   143 NONSHARABLE_CLASS(DPinObjectAllocator) : public DBase
   110 	{
   144 	{
   111 public:
   145 public:
   112 	/*
   146 	/*
   156 		{
   190 		{
   157 		iPreAllocatedDataLock->Cleanup();
   191 		iPreAllocatedDataLock->Cleanup();
   158 		delete iPreAllocatedDataLock;
   192 		delete iPreAllocatedDataLock;
   159 		}
   193 		}
   160 
   194 
   161 	for (TInt n=0; n<iObjectCount; n++)
   195 	for (TInt n=0; iVirtualPinContainers!= NULL && n<iObjectCount; n++)
   162 		{
   196 		{
   163 		SVirtualPinContainer& virtualPinContainer = iVirtualPinContainers[n];
   197 		SVirtualPinContainer& virtualPinContainer = iVirtualPinContainers[n];
   164 		if (virtualPinContainer.iObject)
   198 		if (virtualPinContainer.iObject)
   165 			Kern::DestroyVirtualPinObject(virtualPinContainer.iObject);
   199 			Kern::DestroyVirtualPinObject(virtualPinContainer.iObject);
   166 		}
   200 		}
   191 		OstTraceFunctionExitExt( DPINOBJECTALLOCATOR_CONSTRUCT_EXIT2, this, r );
   225 		OstTraceFunctionExitExt( DPINOBJECTALLOCATOR_CONSTRUCT_EXIT2, this, r );
   192 		return r;
   226 		return r;
   193 	    }
   227 	    }
   194 
   228 
   195 
   229 
   196 	SVirtualPinContainer* iVirtualPinContainers = new SVirtualPinContainer[aObjectCount];
   230 	iVirtualPinContainers = new SVirtualPinContainer[aObjectCount];
   197 	if (iVirtualPinContainers == NULL)
   231 	if (iVirtualPinContainers == NULL)
   198 	    {
   232 	    {
   199 		OstTraceFunctionExitExt( DPINOBJECTALLOCATOR_CONSTRUCT_EXIT3, this, KErrNoMemory );
   233 		OstTraceFunctionExitExt( DPINOBJECTALLOCATOR_CONSTRUCT_EXIT3, this, KErrNoMemory );
   200 		return KErrNoMemory;
   234 		return KErrNoMemory;
   201 	    }
   235 	    }
   258 	OstTraceFunctionExit1( DPINOBJECTALLOCATOR_RELEASEPINOBJECT_EXIT, this );
   292 	OstTraceFunctionExit1( DPINOBJECTALLOCATOR_RELEASEPINOBJECT_EXIT, this );
   259 	}
   293 	}
   260 
   294 
   261 #endif	// __DEMAND_PAGING__
   295 #endif	// __DEMAND_PAGING__
   262 
   296 
       
   297 
       
   298 /* 
       
   299 TDriveIterator
       
   300 
       
   301 Internal class which supports iterating through all local drives (TLocDrv's)
       
   302 If there are media extensions present, then this will iterate through all attached drives.
       
   303 @internalTechnology
       
   304 */
       
   305 class TDriveIterator
       
   306 	{
       
   307 public:
       
   308 	TDriveIterator();
       
   309 	TLocDrv* NextDrive();
       
   310 	inline TInt Index()
       
   311 		{return iIndex;}
       
   312 	static TLocDrv* GetDrive(TInt aDriveNum, DPrimaryMediaBase* aPrimaryMedia);
       
   313 	static TLocDrv* GetPhysicalDrive(TLocDrv* aDrv);
       
   314 
       
   315 #if defined(__DEMAND_PAGING__) && defined(__DEMAND_PAGING_BENCHMARKS__)
       
   316 	static DMediaPagingDevice* PagingDevice(TInt aDriveNum, DPagingDevice::TType aType);
       
   317 #endif
       
   318 
       
   319 private:
       
   320 	TInt iIndex;
       
   321 	TLocDrv* iDrive;
       
   322 	};
       
   323 
       
   324 TDriveIterator::TDriveIterator() :
       
   325 	iIndex(0), iDrive(NULL)
       
   326 	{
       
   327 	}
       
   328 
       
   329 TLocDrv* TDriveIterator::NextDrive()
       
   330 	{
       
   331 	if (iDrive)	// i.e. if not first time
       
   332 		{
       
   333 		if (iDrive->iNextDrive)
       
   334 			{
       
   335 			iDrive = iDrive->iNextDrive;
       
   336 			return iDrive;
       
   337 			}
       
   338 		iIndex++;
       
   339 		}
       
   340 
       
   341 	for (iDrive = NULL; iIndex < KMaxLocalDrives; iIndex++)
       
   342 		{
       
   343 		iDrive = TheDrives[iIndex];
       
   344 		if (iDrive)
       
   345 			break;
       
   346 		}
       
   347 
       
   348 	return iDrive;
       
   349 	}
       
   350 
       
   351 /*
       
   352 Returns the first TLocDrv in the chain of attached drives which matches DPrimaryMediaBase
       
   353 */
       
   354 TLocDrv* TDriveIterator::GetDrive(TInt aDriveNum, DPrimaryMediaBase* aPrimaryMedia)
       
   355 	{
       
   356 	TLocDrv* drive = TheDrives[aDriveNum];
       
   357 	while (drive && drive->iPrimaryMedia != aPrimaryMedia)
       
   358 		{
       
   359 		drive = drive->iNextDrive ? drive->iNextDrive : NULL;
       
   360 		}
       
   361 	return drive;
       
   362 	}
       
   363 
       
   364 /*
       
   365 Returns the last TLocDrv in the chain of attached drives - 
       
   366 i.e. the TLocDrv attached to physical media rather than a TLocDrv corresponding to a media extension 
       
   367 */
       
   368 TLocDrv* TDriveIterator::GetPhysicalDrive(TLocDrv* aDrv)
       
   369 	{
       
   370 	__ASSERT_DEBUG(aDrv, LOCM_FAULT());
       
   371 	while (aDrv->iNextDrive)
       
   372 		aDrv = aDrv->iNextDrive;
       
   373 	return aDrv;
       
   374 	}
       
   375 
       
   376 #if defined(__DEMAND_PAGING__) && defined(__DEMAND_PAGING_BENCHMARKS__)
       
   377 DMediaPagingDevice* TDriveIterator::PagingDevice(TInt aDriveNum, DPagingDevice::TType aType)
       
   378 	{
       
   379 	TLocDrv* drive = TheDrives[aDriveNum];
       
   380 	DMediaPagingDevice* pagingDevice = drive ? drive->iPrimaryMedia->iBody->iPagingDevice : NULL;
       
   381 	while (drive && (pagingDevice == NULL || (pagingDevice->iType & aType) == 0))
       
   382 		{
       
   383 		drive = drive->iNextDrive ? drive->iNextDrive : NULL;
       
   384 		pagingDevice = drive ? drive->iPrimaryMedia->iBody->iPagingDevice : NULL;
       
   385 		}
       
   386 	return pagingDevice;
       
   387 	}
       
   388 #endif
       
   389 
   263 /********************************************
   390 /********************************************
   264  * Local drive device base class
   391  * Local drive device base class
   265  ********************************************/
   392  ********************************************/
   266 DECLARE_EXTENSION_LDD()
   393 DECLARE_EXTENSION_LDD()
   267 	{
   394 	{
   310 	}
   437 	}
   311 
   438 
   312 /********************************************
   439 /********************************************
   313  * Local drive interface class
   440  * Local drive interface class
   314  ********************************************/
   441  ********************************************/
   315 DLocalDrive::DLocalDrive()
   442 DLocalDrive::DLocalDrive() :
       
   443 	iMediaChangeObserver(MediaChangeCallback, this, TCallBackLink::EDLocalDriveObject)
   316 	{
   444 	{
   317 //	iLink.iNext=NULL;
   445 //	iLink.iNext=NULL;
   318 	}
   446 	}
   319 
   447 
   320 DLocalDrive::~DLocalDrive()
   448 DLocalDrive::~DLocalDrive()
   491 			m.Id()=ECaps;
   619 			m.Id()=ECaps;
   492 			m.RemoteDes()=(TAny*)capsBuf.Ptr();	// overload this
   620 			m.RemoteDes()=(TAny*)capsBuf.Ptr();	// overload this
   493 			m.Length()=KMaxLocalDriveCapsLength;	// for pinning
   621 			m.Length()=KMaxLocalDriveCapsLength;	// for pinning
   494 			r=iDrive->Request(m);
   622 			r=iDrive->Request(m);
   495 
   623 
   496 			if(r == KErrNone && iDrive->iMedia != NULL && iDrive->iMedia->iDriver != NULL)
       
   497 				{
       
   498 				// Fill in default media size if not specified by the driver
       
   499 				//
       
   500 				// - This uses the members of TLocalDriveCapsV4 which was primarily used
       
   501 				//   to report NAND flash characteristics, but are general enough to be
       
   502 				//	 used to report the size of any type of media without adding yet
       
   503 				//	 another extension to TLocalDriveCapsVx.
       
   504 				//
       
   505 				
       
   506 				TLocalDriveCapsV4& caps = *(TLocalDriveCapsV4*)capsBuf.Ptr();
       
   507 				
       
   508 				if(caps.iSectorSizeInBytes == 0)
       
   509 					{
       
   510 					// Fill in a default value for the disk sector size
       
   511 					caps.iSectorSizeInBytes = 512;
       
   512 
       
   513 					// Zero the number of sectors, as a sector count makes no sense without a sector size
       
   514 					//  - Fault in debug mode if a sector count is provided to ensure that media driver creators
       
   515 					//	  set this value,but in release mode continue gracefully be recalculating the sector count.
       
   516 					__ASSERT_DEBUG(caps.iNumberOfSectors == 0, LOCM_FAULT());
       
   517 					caps.iNumberOfSectors  = 0;
       
   518 					caps.iNumPagesPerBlock = 1;	// ...to ensure compatiility with NAND semantics
       
   519 					}
       
   520 
       
   521 				if(caps.iNumberOfSectors == 0)
       
   522 					{
       
   523 					const Int64 totalSizeInSectors = iDrive->iMedia->iDriver->TotalSizeInBytes() / caps.iSectorSizeInBytes;
       
   524 					__ASSERT_DEBUG(I64HIGH(totalSizeInSectors) == 0, LOCM_FAULT());
       
   525 
       
   526 					if(I64HIGH(totalSizeInSectors) == 0)
       
   527 						{
       
   528 						caps.iNumberOfSectors = I64LOW(totalSizeInSectors);
       
   529 						}
       
   530 					}
       
   531 				}
       
   532 
   624 
   533 #if defined(OST_TRACE_COMPILER_IN_USE) && defined(_DEBUG)
   625 #if defined(OST_TRACE_COMPILER_IN_USE) && defined(_DEBUG)
   534 			const TLocalDriveCapsV5& caps=*(const TLocalDriveCapsV5*)capsBuf.Ptr();
   626 			const TLocalDriveCapsV5& caps=*(const TLocalDriveCapsV5*)capsBuf.Ptr();
   535 #endif
   627 #endif
   536 			
   628 			
   595 			break;
   687 			break;
   596 		case RLocalDrive::EControlIsRemovable:
   688 		case RLocalDrive::EControlIsRemovable:
   597 			{
   689 			{
   598 	        OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_CONTROLISREMOVABLE, "EControlIsRemovable; TLocDrvRequest Object=0x%x", (TUint) &m);
   690 	        OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_CONTROLISREMOVABLE, "EControlIsRemovable; TLocDrvRequest Object=0x%x", (TUint) &m);
   599 			TInt sockNum;
   691 			TInt sockNum;
   600 			r=iDrive->iPrimaryMedia->IsRemovableDevice(sockNum);
   692 
       
   693 			// Pass request on to last chained drive
       
   694 			TLocDrv* drv = TDriveIterator::GetPhysicalDrive(iDrive);
       
   695 			r = drv->iPrimaryMedia->IsRemovableDevice(sockNum);
       
   696 
   601 			if (r)
   697 			if (r)
   602 				kumemput32(a1,&sockNum,sizeof(TInt));
   698 				kumemput32(a1,&sockNum,sizeof(TInt));
   603 			break;	
   699 			break;	
   604 			}
   700 			}
   605 		case RLocalDrive::EControlControlIO:
   701 		case RLocalDrive::EControlControlIO:
   638 		case RLocalDrive::EControlSetMountInfo:
   734 		case RLocalDrive::EControlSetMountInfo:
   639 			{
   735 			{
   640 			OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_CONTROLSETMOUNTINFO, "EControlSetMountInfo; TLocDrvRequest Object=0x%x", (TUint) &m);
   736 			OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_CONTROLSETMOUNTINFO, "EControlSetMountInfo; TLocDrvRequest Object=0x%x", (TUint) &m);
   641 			m.Id()=ERead;
   737 			m.Id()=ERead;
   642 			r=m.ProcessMessageData(a1);
   738 			r=m.ProcessMessageData(a1);
   643 			DPrimaryMediaBase* pM=iDrive->iPrimaryMedia;
   739 
       
   740 			// Pass request on to last chained drive
       
   741 			TLocDrv* drv = TDriveIterator::GetPhysicalDrive(iDrive);
       
   742 			DPrimaryMediaBase* pM = drv->iPrimaryMedia;
       
   743 
   644 			if(!pM || r!=KErrNone)
   744 			if(!pM || r!=KErrNone)
   645 				break;
   745 				break;
   646 
   746 
   647 			if (pM->iMountInfo.iThread)
   747 			if (pM->iMountInfo.iThread)
   648 				{
   748 				{
   876 		case RLocalDrive::EControlQueryDevice:
   976 		case RLocalDrive::EControlQueryDevice:
   877 			{
   977 			{
   878 			TBuf8<KMaxQueryDeviceLength> queryBuf;
   978 			TBuf8<KMaxQueryDeviceLength> queryBuf;
   879 			queryBuf.SetMax();
   979 			queryBuf.SetMax();
   880 			queryBuf.FillZ();
   980 			queryBuf.FillZ();
   881 			
   981 
       
   982 			DThread* pT = m.Client();
       
   983 			r = Kern::ThreadDesRead(pT, (TDes8*)a2, queryBuf, 0 ,KChunkShiftBy0);
       
   984 
       
   985 			queryBuf.SetMax();
   882 			m.Id() = EQueryDevice;
   986 			m.Id() = EQueryDevice;
   883 			m.iArg[0] = a1;		// RLocalDrive::TQueryDevice
   987 			m.iArg[0] = a1;							// RLocalDrive::TQueryDevice
   884 			m.RemoteDes() = (TAny*)queryBuf.Ptr();	// overload this
   988 			m.RemoteDes() = (TAny*)queryBuf.Ptr();	// overload this
   885 			m.Length() = KMaxLocalDriveCapsLength;	// for pinning
   989 			m.Length() = KMaxQueryDeviceLength;
   886 			OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_QUERYDEVICE, "EQueryDevice; TLocDrvRequest Object=0x%x", (TUint) &m);
   990 			OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_QUERYDEVICE, "EQueryDevice; TLocDrvRequest Object=0x%x", (TUint) &m);
   887 			r=iDrive->Request(m);
   991 			r=iDrive->Request(m);
   888 			OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_QUERYDEVICE_RETURN, "EQueryDevice Return; TLocDrvRequest Object=0x%x", (TUint) &m);
   992 			OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DLOCALDRIVE_REQUEST_QUERYDEVICE_RETURN, "EQueryDevice Return; TLocDrvRequest Object=0x%x", (TUint) &m);
   889 			Kern::InfoCopy(*(TDes8*)a2, queryBuf);
   993 			Kern::InfoCopy(*(TDes8*)a2, queryBuf);
   890 			break;
   994 			break;
  1035 void DLocalDrive::UnlockMountInfo(DPrimaryMediaBase& aPrimaryMedia)
  1139 void DLocalDrive::UnlockMountInfo(DPrimaryMediaBase& aPrimaryMedia)
  1036 	{
  1140 	{
  1037 	OstTrace1(TRACE_FLOW, DLOCALDRIVE_UNLOCKMOUNTINFO_ENTRY, "> DLocalDrive::UnlockMountInfo;aPrimaryMedia=%x", (TUint) &aPrimaryMedia);
  1141 	OstTrace1(TRACE_FLOW, DLOCALDRIVE_UNLOCKMOUNTINFO_ENTRY, "> DLocalDrive::UnlockMountInfo;aPrimaryMedia=%x", (TUint) &aPrimaryMedia);
  1038 	
  1142 	
  1039 	DMediaPagingDevice* pagingDevice = aPrimaryMedia.iBody->iPagingDevice; 
  1143 	DMediaPagingDevice* pagingDevice = aPrimaryMedia.iBody->iPagingDevice; 
  1040 	if (pagingDevice == NULL || pagingDevice->iMountInfoDataLock == NULL)
  1144 	if (pagingDevice == NULL)
  1041 	    {
  1145 	    {
  1042 		OstTraceFunctionExit1( DLOCALDRIVE_UNLOCKMOUNTINFO_EXIT1, this );
  1146 		OstTraceFunctionExit1( DLOCALDRIVE_UNLOCKMOUNTINFO_EXIT1, this );
  1043 		return;
  1147 		return;
  1044 	    }
  1148 	    }
  1045 
  1149 
  1067 	
  1171 	
  1068 	OstTraceFunctionExit1( DLOCALDRIVE_UNLOCKMOUNTINFO_EXIT2, this );
  1172 	OstTraceFunctionExit1( DLOCALDRIVE_UNLOCKMOUNTINFO_EXIT2, this );
  1069 	}
  1173 	}
  1070 #endif	// __DEMAND_PAGING__
  1174 #endif	// __DEMAND_PAGING__
  1071 
  1175 
  1072 void DLocalDrive::NotifyChange(DPrimaryMediaBase& aPrimaryMedia, TBool aMediaChange)
  1176 void DLocalDrive::NotifyChange()
  1073 	{
  1177 	{
  1074     OstTraceExt2( TRACE_FLOW, DLOCALDRIVE_NOTIFYCHANGE_ENTRY, "> DLocalDrive::NotifyChange;aPrimaryMedia=%x;aMediaChange=%d", (TUint) &aPrimaryMedia, aMediaChange );
  1178     OstTrace0( TRACE_FLOW, DLOCALDRIVE_NOTIFYCHANGE_ENTRY, "> DLocalDrive::NotifyChange");
  1075 #ifndef __DEMAND_PAGING__
  1179 
  1076 	aPrimaryMedia;
  1180 
  1077 #endif
  1181 	// Complete any notification request on media change
  1078 
  1182 	DThread* pC=NULL;
  1079 	// Complete any notification request on media change or power down
  1183 	NKern::LockSystem();
  1080 	if (aMediaChange)
  1184 	if (iCleanup.iThread)
  1081 		{
  1185 		{
  1082 		DThread* pC=NULL;
  1186 		pC=iCleanup.iThread;
  1083 		NKern::LockSystem();
  1187 		pC->Open();
  1084 		if (iCleanup.iThread)
  1188 		}
  1085 			{
  1189 	NKern::UnlockSystem();
  1086 			pC=iCleanup.iThread;
  1190 	if (pC)
  1087 			pC->Open();
  1191 		{
  1088 			}
  1192 		TBool b = ETrue;
  1089 		NKern::UnlockSystem();
  1193 		// if change not yet queued, queue it now
  1090 		if (pC)
  1194 		if (iNotifyChangeRequest->IsReady())
  1091 			{
  1195 			{
  1092 			TBool b = ETrue;
  1196 			*((TBool*) iNotifyChangeRequest->Buffer()) = b;
  1093 			// if change not yet queued, queue it now
  1197 			Kern::QueueRequestComplete(pC,iNotifyChangeRequest,KErrNone);
  1094 			if (iNotifyChangeRequest->IsReady())
  1198 			}
  1095 				{
  1199 		// If change has not even been requested by the client, maintain the pre-wdp behaviour 
  1096 				*((TBool*) iNotifyChangeRequest->Buffer()) = b;
  1200 		// and write data immediately back to client (possibly taking a page fault)
  1097 				Kern::QueueRequestComplete(pC,iNotifyChangeRequest,KErrNone);
  1201 		// N.B. Must NOT do this on data paging media
  1098 				}
       
  1099 			// If change has not even been requested by the client, maintain the pre-wdp behaviour 
       
  1100 			// and write data immediately back to client (possibly taking a page fault)
       
  1101 			// N.B. Must NOT do this on data paging media
       
  1102 #ifdef __DEMAND_PAGING__
  1202 #ifdef __DEMAND_PAGING__
  1103 			else if (!DataPagingDfcQ(&aPrimaryMedia))
  1203 		else if (!DataPagingDfcQ(iDrive->iPrimaryMedia))
  1104 #else
  1204 #else
  1105 			else
  1205 		else
  1106 #endif
  1206 #endif
  1107 				{
  1207 			{
  1108 				Kern::ThreadRawWrite(pC, iNotifyChangeRequest->DestPtr(), &b, sizeof(b), NULL);
  1208 			Kern::ThreadRawWrite(pC, iNotifyChangeRequest->DestPtr(), &b, sizeof(b), NULL);
  1109 				}
  1209 			}
  1110 			pC->AsyncClose();
  1210 		pC->AsyncClose();
  1111 			}
       
  1112 		}
  1211 		}
  1113 	OstTraceFunctionExit1( DLOCALDRIVE_NOTIFYCHANGE_EXIT, this );
  1212 	OstTraceFunctionExit1( DLOCALDRIVE_NOTIFYCHANGE_EXIT, this );
       
  1213 	}
       
  1214 
       
  1215 // This function is called by the primary media when a media change occurs
       
  1216 TInt DLocalDrive::MediaChangeCallback(TAny* aLocalDrive, TInt /* aNotifyType*/)
       
  1217 	{
       
  1218 	((DLocalDrive*) aLocalDrive)->NotifyChange();
       
  1219 	return KErrNone;
  1114 	}
  1220 	}
  1115 
  1221 
  1116 TLocalDriveCleanup::TLocalDriveCleanup()
  1222 TLocalDriveCleanup::TLocalDriveCleanup()
  1117 	{
  1223 	{
  1118 	}
  1224 	}
  1129 	NKern::UnlockSystem();
  1235 	NKern::UnlockSystem();
  1130 	pC->Close(NULL);	// balances Open() in DoCreate
  1236 	pC->Close(NULL);	// balances Open() in DoCreate
  1131 	NKern::LockSystem();
  1237 	NKern::LockSystem();
  1132 	}
  1238 	}
  1133 
  1239 
       
  1240 
       
  1241 EXPORT_C TInt DLocalDrive::Caps(TInt aDriveNumber, TDes8& aCaps)
       
  1242 	{
       
  1243 	if(!Kern::CurrentThreadHasCapability(ECapabilityTCB,__PLATSEC_DIAGNOSTIC_STRING("Checked by ELOCD.LDD (Local Media Driver)")))
       
  1244 	    {
       
  1245 		return KErrPermissionDenied;
       
  1246 	    }
       
  1247 	
       
  1248 
       
  1249 	if (aDriveNumber >= KMaxLocalDrives)
       
  1250 		return KErrArgument;
       
  1251 
       
  1252 	TLocDrv* drive = TheDrives[aDriveNumber];
       
  1253 	if (!drive)
       
  1254 		return KErrNotSupported;
       
  1255 
       
  1256 	TLocDrvRequest request;
       
  1257 	memclr(&request, sizeof(request));
       
  1258 
       
  1259 	request.Drive() = drive;
       
  1260 	request.Id() = DLocalDrive::ECaps;
       
  1261 	request.Length() = aCaps.Length();
       
  1262 	request.RemoteDes() = (TAny*) aCaps.Ptr();
       
  1263 
       
  1264 	return request.SendReceive(&drive->iPrimaryMedia->iMsgQ);
       
  1265 	}
       
  1266 
  1134 /********************************************
  1267 /********************************************
  1135  * Local drive request class
  1268  * Local drive request class
  1136  ********************************************/
  1269  ********************************************/
  1137  
  1270  
  1138 /**
  1271 /**
  1157 */
  1290 */
  1158 EXPORT_C TInt TLocDrvRequest::ReadRemote(TDes8* aDes, TInt anOffset)
  1291 EXPORT_C TInt TLocDrvRequest::ReadRemote(TDes8* aDes, TInt anOffset)
  1159 	{
  1292 	{
  1160 	OstTraceFunctionEntry1( TLOCDRVREQUEST_READREMOTE_ENTRY, this );
  1293 	OstTraceFunctionEntry1( TLOCDRVREQUEST_READREMOTE_ENTRY, this );
  1161 	TInt r;
  1294 	TInt r;
       
  1295 
       
  1296 	if (Flags() & TLocDrvRequest::EKernelBuffer)
       
  1297 		{
       
  1298 		(void)memcpy((TAny*) aDes->Ptr(), (TAny*)((TUint32)RemoteDes()+anOffset), aDes->MaxLength());
       
  1299 		aDes->SetLength(aDes->MaxLength());
       
  1300 		return KErrNone;
       
  1301 		}
       
  1302 
  1162 	DThread* pT=RemoteThread();
  1303 	DThread* pT=RemoteThread();
  1163 	if (!pT)
  1304 	if (!pT)
  1164 		pT=Client();
  1305 		pT=Client();
  1165 
  1306 
  1166 #ifdef __DEMAND_PAGING__	// only if driver has its own thread, we don't support paging in MD which run in the context of their clients
  1307 #ifdef __DEMAND_PAGING__	// only if driver has its own thread, we don't support paging in MD which run in the context of their clients
  1296 */
  1437 */
  1297 EXPORT_C TInt TLocDrvRequest::WriteRemote(const TDesC8* aDes, TInt anOffset)
  1438 EXPORT_C TInt TLocDrvRequest::WriteRemote(const TDesC8* aDes, TInt anOffset)
  1298 	{
  1439 	{
  1299     OstTraceFunctionEntry1( TLOCDRVREQUEST_WRITEREMOTE_ENTRY, this );
  1440     OstTraceFunctionEntry1( TLOCDRVREQUEST_WRITEREMOTE_ENTRY, this );
  1300     TInt r;
  1441     TInt r;
       
  1442 
       
  1443 	if (Flags() & TLocDrvRequest::EKernelBuffer)
       
  1444 		{
       
  1445 		(void)memcpy((TAny*)((TUint32)RemoteDes()+anOffset), (TAny*) aDes->Ptr(), aDes->Length());
       
  1446 		OstTraceFunctionExitExt( TLOCDRVREQUEST_WRITEREMOTE_EXIT1, this, KErrNone );
       
  1447 		return KErrNone;
       
  1448 		}
       
  1449 
  1301 	DThread* pC=Client();
  1450 	DThread* pC=Client();
  1302 	DThread* pT=RemoteThread();
  1451 	DThread* pT=RemoteThread();
  1303 	if (!pT)
  1452 	if (!pT)
  1304 		pT=pC;
  1453 		pT=pC;
  1305 
  1454 
  1306 #ifdef __DEMAND_PAGING__
  1455 #ifdef __DEMAND_PAGING__
  1307 	if (Flags() & ETClientBuffer)
  1456 	if (Flags() & ETClientBuffer)
  1308 	    {
  1457 	    {
  1309         r = Kern::ThreadBufWrite(pT, (TClientBuffer*) RemoteDes(),*aDes,anOffset+RemoteDesOffset(),KChunkShiftBy0,pC);
  1458         r = Kern::ThreadBufWrite(pT, (TClientBuffer*) RemoteDes(),*aDes,anOffset+RemoteDesOffset(),KChunkShiftBy0,pC);
  1310 		OstTraceFunctionExitExt( TLOCDRVREQUEST_WRITEREMOTE_EXIT1, this, r );
  1459 		OstTraceFunctionExitExt( TLOCDRVREQUEST_WRITEREMOTE_EXIT2, this, r );
  1311 		return r;
  1460 		return r;
  1312 	    }
  1461 	    }
  1313 #endif
  1462 #endif
  1314 	r = Kern::ThreadDesWrite(pT,RemoteDes(),*aDes,anOffset+RemoteDesOffset(),KChunkShiftBy0,pC);
  1463 	r = Kern::ThreadDesWrite(pT,RemoteDes(),*aDes,anOffset+RemoteDesOffset(),KChunkShiftBy0,pC);
  1315 	OstTraceFunctionExitExt( TLOCDRVREQUEST_WRITEREMOTE_EXIT2, this, r );
  1464 	OstTraceFunctionExitExt( TLOCDRVREQUEST_WRITEREMOTE_EXIT3, this, r );
  1316 	return r;
  1465 	return r;
  1317 	}
  1466 	}
  1318 
  1467 
  1319 
  1468 
  1320 /**
  1469 /**
  1443 			else
  1592 			else
  1444 			    r = KErrNone;
  1593 			    r = KErrNone;
  1445 			break;
  1594 			break;
  1446 		case DLocalDrive::EReduce:
  1595 		case DLocalDrive::EReduce:
  1447 			__KTRACE_OPT(KLOCDRV,Kern::Printf("Reduce request %lx@%lx",Length(),Pos()));
  1596 			__KTRACE_OPT(KLOCDRV,Kern::Printf("Reduce request %lx@%lx",Length(),Pos()));
  1448 			OstTraceExt4( TRACE_INTERNALS, TLOCDRVREQUEST_CHECKANDADJUSTFORPARTITION3, "Reduce request length=%x:%x; position=%x:%x", (TUint) I64HIGH(Length()), (TUint) I64LOW(Length()), (TUint) I64HIGH(Pos()), (TUint) I64LOW(Pos()) );
  1597 			OstTraceExt4( TRACE_INTERNALS, TLOCDRVREQUEST_CHECKANDADJUSTFORPARTITION3, "Reduce request length=%x:%x; position=%x:%x", (TUint) I64HIGH(Length()), (TUint) I64LOW(Length()), (TUint) I64HIGH (Pos()), (TUint) I64LOW (Pos()) );
  1449 			if (Pos()+Length()>d.iPartitionLen)
  1598 			if (Pos()+Length()>d.iPartitionLen)
  1450 				r = KErrArgument;
  1599 				r = KErrArgument;
  1451 			else
  1600 			else
  1452                 r = KErrNone;
  1601                 r = KErrNone;
  1453 			break;
  1602 			break;
  1454 		case DLocalDrive::EFormat:
  1603 		case DLocalDrive::EFormat:
  1455 			__KTRACE_OPT(KLOCDRV,Kern::Printf("Format request %lx@%lx",Length(),Pos()));
  1604 			__KTRACE_OPT(KLOCDRV,Kern::Printf("Format request %lx@%lx",Length(),Pos()));
  1456 			OstTraceExt4( TRACE_INTERNALS, TLOCDRVREQUEST_CHECKANDADJUSTFORPARTITION4, "Format request length=%x:%x; position=%x:%x", (TUint) I64HIGH(Length()),(TUint) I64LOW(Length()), (TUint) I64HIGH(Pos()), (TUint) I64LOW(Pos()) );
  1605 			OstTraceExt4( TRACE_INTERNALS, TLOCDRVREQUEST_CHECKANDADJUSTFORPARTITION4, "Format request length=%x:%x; position=%x:%x", (TUint) I64HIGH(Length()),(TUint) I64LOW(Length()), (TUint) I64HIGH (Pos()), (TUint) I64LOW (Pos()) );
  1457 			if (!(DriverFlags() & RLocalDrive::ELocDrvWholeMedia))
  1606 			if (!(DriverFlags() & RLocalDrive::ELocDrvWholeMedia))
  1458 				{
  1607 				{
  1459 				if (Pos()>d.iPartitionLen)
  1608 				if (Pos()>d.iPartitionLen)
  1460 					{
  1609 					{
  1461 					Length()=0;
  1610 					Length()=0;
  1479 		case DMediaPagingDevice::ERomPageInRequest:
  1628 		case DMediaPagingDevice::ERomPageInRequest:
  1480 //          if the ROM was reported to LOCM then it will also need to be adjusted.... 
  1629 //          if the ROM was reported to LOCM then it will also need to be adjusted.... 
  1481 //		    Otherwise the media driver adjust it internally
  1630 //		    Otherwise the media driver adjust it internally
  1482 		case DMediaPagingDevice::ECodePageInRequest:
  1631 		case DMediaPagingDevice::ECodePageInRequest:
  1483 			__KTRACE_OPT(KLOCDPAGING,Kern::Printf("Adjusted Paging read request %lx@%lx",Length(),Pos()));
  1632 			__KTRACE_OPT(KLOCDPAGING,Kern::Printf("Adjusted Paging read request %lx@%lx",Length(),Pos()));
  1484 			OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, TLOCDRVREQUESTCHECKANDADJUSTFORPARTITION5, "Adjusted Paging read request length=%x:%x; position=%x%:%x", (TUint) I64HIGH(Length()), (TUint) I64LOW(Length()),  (TUint) I64HIGH(Pos()), (TUint) I64LOW(Pos()));
  1633 			OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, TLOCDRVREQUESTCHECKANDADJUSTFORPARTITION5, "Adjusted Paging read request length=%x:%x; position=%x:%x", (TUint) I64HIGH(Length()), (TUint) I64LOW(Length()),  (TUint) I64HIGH(Pos()), (TUint) I64LOW(Pos()));
  1485 			if (Pos()+Length()>d.iPartitionLen)
  1634 			if (Pos()+Length()>d.iPartitionLen)
  1486 			    {
  1635 			    {
  1487 				r = KErrArgument;
  1636 				r = KErrArgument;
  1488 				break;
  1637 				break;
  1489 			    }
  1638 			    }
  1492 			break;
  1641 			break;
  1493 #endif
  1642 #endif
  1494 		
  1643 		
  1495 		default:	// read or write or fragment
  1644 		default:	// read or write or fragment
  1496 			__KTRACE_OPT(KLOCDRV,Kern::Printf("R/W request %lx@%lx",Length(),Pos()));
  1645 			__KTRACE_OPT(KLOCDRV,Kern::Printf("R/W request %lx@%lx",Length(),Pos()));
  1497 			OstTraceExt4( TRACE_INTERNALS, TLOCDRVREQUEST_CHECKANDADJUSTFORPARTITION6, "Read/Write request length=%x:%x; position=%x:%x", (TUint) I64HIGH(Length()), (TUint) I64LOW(Length()), (TUint) I64HIGH(Pos()), (TUint) I64LOW(Pos()));
  1646 			OstTraceExt4( TRACE_INTERNALS, TLOCDRVREQUEST_CHECKANDADJUSTFORPARTITION6, "Read/Write request length=%x:%x; position=%x:%x", (TUint)I64HIGH (Length()), (TUint)I64LOW (Length()), (TUint) I64HIGH (Pos()), (TUint) I64LOW (Pos()));
  1498 			if (DriverFlags() & RLocalDrive::ELocDrvWholeMedia)
  1647 			if (DriverFlags() & RLocalDrive::ELocDrvWholeMedia)
  1499 				{
  1648 				{
  1500 				if (d.iMedia && d.iMedia->iDriver && Pos()+Length() > d.iMedia->iDriver->iTotalSizeInBytes)
  1649 				if (d.iMedia && d.iMedia->iDriver && Pos()+Length() > d.iMedia->iPartitionInfo.iMediaSizeInBytes)
  1501 				    {
  1650 				    {
  1502 					r = KErrArgument;
  1651 					r = KErrArgument;
  1503 					break;
  1652 					break;
  1504 				    }
  1653 				    }
  1505 				}
  1654 				}
  1525 	{
  1674 	{
  1526 	OstTraceFunctionEntryExt( TLOCDRV_TLOCDRV_ENTRY, this );
  1675 	OstTraceFunctionEntryExt( TLOCDRV_TLOCDRV_ENTRY, this );
  1527 	memclr(this, sizeof(TLocDrv));
  1676 	memclr(this, sizeof(TLocDrv));
  1528 	iDriveNumber=aDriveNumber;
  1677 	iDriveNumber=aDriveNumber;
  1529 	iPartitionNumber=-1;
  1678 	iPartitionNumber=-1;
       
  1679 	iMediaChangeObserver.iFunction = MediaChangeCallback;
       
  1680 	iMediaChangeObserver.iPtr= this;
       
  1681 	iMediaChangeObserver.iObjectType = TCallBackLink::ETLocDrvObject;
  1530 	OstTraceFunctionExit1( TLOCDRV_TLOCDRV_EXIT, this );
  1682 	OstTraceFunctionExit1( TLOCDRV_TLOCDRV_EXIT, this );
  1531 	}
  1683 	}
       
  1684 
       
  1685 TInt TLocDrv::MediaChangeCallback(TAny* aLocDrv, TInt aNotifyType)
       
  1686 	{
       
  1687 	__ASSERT_DEBUG(aNotifyType == DPrimaryMediaBase::EMediaChange || aNotifyType == DPrimaryMediaBase::EMediaPresent, LOCM_FAULT());
       
  1688 	if (aNotifyType == DPrimaryMediaBase::EMediaPresent)
       
  1689 		return ((TLocDrv*) aLocDrv)->iPrimaryMedia->iBody->iMediaPresentDfc.Enque();
       
  1690 	else
       
  1691 		return ((TLocDrv*) aLocDrv)->iPrimaryMedia->iBody->iMediaChangeDfc.Enque();
       
  1692 	}
       
  1693 
  1532 
  1694 
  1533 /**
  1695 /**
  1534 Initialises the DMedia entity with the media device number and ID.
  1696 Initialises the DMedia entity with the media device number and ID.
  1535  
  1697  
  1536 @param	aDevice		The unique ID for this device. This can take one of the
  1698 @param	aDevice		The unique ID for this device. This can take one of the
  1592 		}
  1754 		}
  1593 
  1755 
  1594 
  1756 
  1595 	primaryMedia->iMsgQ.Receive();	// allow reception of more messages
  1757 	primaryMedia->iMsgQ.Receive();	// allow reception of more messages
  1596 	OstTraceFunctionExit0( _HANDLEMSG_EXIT );
  1758 	OstTraceFunctionExit0( _HANDLEMSG_EXIT );
       
  1759 	}
       
  1760 
       
  1761 
       
  1762 void mediaChangeDfc(TAny* aPtr)
       
  1763 	{
       
  1764 	DPrimaryMediaBase* pM = (DPrimaryMediaBase*)aPtr;
       
  1765 	pM->NotifyMediaChange();
       
  1766 	}
       
  1767 
       
  1768 void mediaPresentDfc(TAny* aPtr)
       
  1769 	{
       
  1770 	DPrimaryMediaBase* pM = (DPrimaryMediaBase*)aPtr;
       
  1771 	pM->NotifyMediaPresent();
       
  1772 	}
       
  1773 
       
  1774 DPrimaryMediaBase::DBody::DBody(DPrimaryMediaBase& aPrimaryMediaBase) :
       
  1775 	iPrimaryMediaBase(aPrimaryMediaBase),
       
  1776 	iMediaChangeDfc(mediaChangeDfc, &aPrimaryMediaBase, KMaxDfcPriority),
       
  1777 	iMediaPresentDfc(mediaPresentDfc, &aPrimaryMediaBase, KMaxDfcPriority)
       
  1778 	{
  1597 	}
  1779 	}
  1598 
  1780 
  1599 EXPORT_C DPrimaryMediaBase::DPrimaryMediaBase()
  1781 EXPORT_C DPrimaryMediaBase::DPrimaryMediaBase()
  1600 	:	iMsgQ(handleMsg, this, NULL, 1),
  1782 	:	iMsgQ(handleMsg, this, NULL, 1),
  1601 		iDeferred(NULL, NULL, NULL, 0),			// callback never used
  1783 		iDeferred(NULL, NULL, NULL, 0),			// callback never used
  1633 	
  1815 	
  1634 	if (r != KErrNone)
  1816 	if (r != KErrNone)
  1635 	    {
  1817 	    {
  1636 		OstTraceFunctionExitExt( DPRIMARYMEDIABASE_CREATE_EXIT1, this, r );
  1818 		OstTraceFunctionExitExt( DPRIMARYMEDIABASE_CREATE_EXIT1, this, r );
  1637 		return r;
  1819 		return r;
  1638 	    }
  1820 		}
  1639 	iBody = new DBody;
  1821 	iBody = new DBody(*this);
  1640 	if (iBody == NULL)
  1822 	if (iBody == NULL)
  1641 	    {
  1823 	    {
  1642 		OstTraceFunctionExitExt( DPRIMARYMEDIABASE_CREATE_EXIT2, this, KErrNoMemory );
  1824 		OstTraceFunctionExitExt( DPRIMARYMEDIABASE_CREATE_EXIT2, this, KErrNoMemory );
  1643 		return KErrNoMemory;
  1825 		return KErrNoMemory;
  1644 	    }
  1826 		}
  1645 	
  1827 	if (iDfcQ)
  1646 	
  1828 		{
       
  1829 		iBody->iMediaChangeDfc.SetDfcQ(iDfcQ);
       
  1830 		iBody->iMediaPresentDfc.SetDfcQ(iDfcQ);
       
  1831 		}
  1647 
  1832 
  1648 #ifdef __DEMAND_PAGING__
  1833 #ifdef __DEMAND_PAGING__
  1649 	TInt pageSize = Kern::RoundToPageSize(1);
  1834 	TInt pageSize = Kern::RoundToPageSize(1);
  1650 	iBody->iPageSizeMsk = pageSize-1;
  1835 	iBody->iPageSizeMsk = pageSize-1;
  1651 	iBody->iPageSizeLog2 = __e32_find_ms1_32(pageSize);
  1836 	iBody->iPageSizeLog2 = __e32_find_ms1_32(pageSize);
  1704 	// If this is the first connection, open media driver now
  1889 	// If this is the first connection, open media driver now
  1705 	// Assume no non-primary media exist on this device
  1890 	// Assume no non-primary media exist on this device
  1706 	
  1891 	
  1707 	NKern::LockSystem();
  1892 	NKern::LockSystem();
  1708 	TBool first=iConnectionQ.IsEmpty();
  1893 	TBool first=iConnectionQ.IsEmpty();
  1709 	iConnectionQ.Add(&aLocalDrive->iLink);
  1894 	iConnectionQ.Add(&aLocalDrive->iMediaChangeObserver.iLink);
  1710 	NKern::UnlockSystem();
  1895 	NKern::UnlockSystem();
  1711 	if (first)
  1896 	if (first)
  1712 		{
  1897 		{
  1713 		r=OpenMediaDriver();
  1898 		r=OpenMediaDriver();
  1714 		if (r!=KErrNone)
  1899 		if (r!=KErrNone)
  1772 	if (pD)
  1957 	if (pD)
  1773 		pD->Close();
  1958 		pD->Close();
  1774 	OstTraceFunctionExit1( DPRIMARYMEDIABASE_DISCONNECT_EXIT2, this );
  1959 	OstTraceFunctionExit1( DPRIMARYMEDIABASE_DISCONNECT_EXIT2, this );
  1775 	}
  1960 	}
  1776 
  1961 
       
  1962 
       
  1963 /**
       
  1964 Connects a TLocDrv containing a media extension to the next primary media in the chain
       
  1965 */
       
  1966 TInt DPrimaryMediaBase::Connect(TLocDrv* aLocDrv)
       
  1967 	{
       
  1968 	TInt r = KErrNone;
       
  1969 
       
  1970 	NKern::LockSystem();
       
  1971 	TBool first = iConnectionQ.IsEmpty();
       
  1972 	iConnectionQ.Add(&aLocDrv->iMediaChangeObserver.iLink);
       
  1973 	NKern::UnlockSystem();
       
  1974 
       
  1975 	if (first && !iDfcQ)
       
  1976 		{
       
  1977 		r = OpenMediaDriver();
       
  1978 		if (r!=KErrNone)
       
  1979 			{
       
  1980 			NKern::LockSystem();
       
  1981 			aLocDrv->iMediaChangeObserver.iLink.Deque();
       
  1982 			NKern::UnlockSystem();
       
  1983 			}
       
  1984 		}
       
  1985 	return r;
       
  1986 	}
       
  1987 
       
  1988 TInt DPrimaryMediaBase::HandleMediaNotPresent(TLocDrvRequest& aReq)
       
  1989 	{
       
  1990 	TInt reqId = aReq.Id();
       
  1991 
       
  1992 	if (reqId == DLocalDrive::ECaps)
       
  1993 		DefaultDriveCaps(*(TLocalDriveCapsV2*)aReq.RemoteDes());	// fill in stuff we know even if no media present
       
  1994 
       
  1995 	TInt r = QuickCheckStatus();
       
  1996 	if (r != KErrNone && 
       
  1997 		reqId != DLocalDrive::EForceMediaChange &&			// EForceMediaChange, and 
       
  1998 		reqId != DLocalDrive::EReadPasswordStore &&			// Password store operations 
       
  1999 		reqId != DLocalDrive::EWritePasswordStore &&			// do not require the media 
       
  2000 		reqId != DLocalDrive::EPasswordStoreLengthInBytes)	// to be ready.)
       
  2001  	 	{
       
  2002 		return r;
       
  2003  	  	}
       
  2004 
       
  2005 	return KErrNone;
       
  2006 	}
       
  2007 
  1777 EXPORT_C TInt DPrimaryMediaBase::Request(TLocDrvRequest& aReq)
  2008 EXPORT_C TInt DPrimaryMediaBase::Request(TLocDrvRequest& aReq)
  1778 /**
  2009 /**
  1779 Issues a local drive request. It is called from TLocDrv::Request() function .
  2010 Issues a local drive request. It is called from TLocDrv::Request() function .
  1780 Each local drive request is encapsulated as a TLocDrvRequest- a class derived from TThreadMessage, the kernel message class. 
  2011 Each local drive request is encapsulated as a TLocDrvRequest- a class derived from TThreadMessage, the kernel message class. 
  1781 TLocDrvRequest contains information pertaining to the request, including the ID and any associated parameters such as drive position, length and source/destination location.
  2012 TLocDrvRequest contains information pertaining to the request, including the ID and any associated parameters such as drive position, length and source/destination location.
  1792 	Otherwise, one of the other system wide error codes.
  2023 	Otherwise, one of the other system wide error codes.
  1793 
  2024 
  1794 @see TLocDrvRequest
  2025 @see TLocDrvRequest
  1795 */
  2026 */
  1796 	{
  2027 	{
  1797 OstTraceFunctionEntry1( DPRIMARYMEDIABASE_REQUEST_ENTRY, this );
  2028 	OstTraceFunctionEntry1( DPRIMARYMEDIABASE_REQUEST_ENTRY, this );
  1798 
  2029 
  1799 	__KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::Request(%08x)",iMediaId,&aReq));
  2030 	__KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::Request(%08x)",iMediaId,&aReq));
  1800 	__KTRACE_OPT(KLOCDRV,Kern::Printf("this=%x, ReqId=%d, Pos=%lx, Len=%lx, remote thread %O",this,aReq.Id(),aReq.Pos(),aReq.Length(),aReq.RemoteThread()));
  2031 	__KTRACE_OPT(KLOCDRV,Kern::Printf("this=%x, ReqId=%d, Pos=%lx, Len=%lx, remote thread %O",this,aReq.Id(),aReq.Pos(),aReq.Length(),aReq.RemoteThread()));
  1801 
  2032 
  1802 	OstTraceDefExt2(OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DPRIMARYMEDIABASE_REQUEST, "reqId=%d; remote thread=0x%x", (TInt) aReq.Id(), (TUint) aReq.RemoteThread());
  2033 	OstTraceDefExt2(OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DPRIMARYMEDIABASE_REQUEST, "reqId=%d; remote thread=0x%x", (TInt) aReq.Id(), (TUint) aReq.RemoteThread());
  1803 	OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DPRIMARYMEDIABASE_REQUEST2, "length=%x:%x; position=%x:%x", (TUint) I64HIGH(aReq.Length()), (TUint) I64LOW(aReq.Length()), (TUint) I64HIGH(aReq.Pos()), (TUint) I64LOW(aReq.Pos()));
  2034 	OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_REQUEST, DPRIMARYMEDIABASE_REQUEST2, "length=%x:%x; position=%x:%x", (TUint) I64HIGH(aReq.Length()), (TUint) I64LOW(aReq.Length()), (TUint) I64HIGH(aReq.Pos()), (TUint) I64LOW(aReq.Pos()));
  1804 	
  2035 	
  1805 	TInt reqId = aReq.Id();
  2036 	TInt reqId = aReq.Id();
  1806 
  2037 
  1807 	if (reqId == DLocalDrive::ECaps)
  2038 	TInt r = HandleMediaNotPresent(aReq);
  1808 		DefaultDriveCaps(*(TLocalDriveCapsV2*)aReq.RemoteDes());	// fill in stuff we know even if no media present
  2039 	if (r != KErrNone)
  1809 
  2040 		{
  1810 	TInt r = QuickCheckStatus();
       
  1811 	if (r != KErrNone && aReq.Id()!=DLocalDrive::EForceMediaChange &&			// EForceMediaChange, and 
       
  1812  			 			 aReq.Id()!=DLocalDrive::EReadPasswordStore &&			// Password store operations 
       
  1813  						 aReq.Id()!=DLocalDrive::EWritePasswordStore &&			// do not require the media 
       
  1814  						 aReq.Id()!=DLocalDrive::EPasswordStoreLengthInBytes)	// to be ready.)
       
  1815  	 	{
       
  1816 		OstTraceFunctionExitExt( DPRIMARYMEDIABASE_REQUEST_EXIT, this, r );
  2041 		OstTraceFunctionExitExt( DPRIMARYMEDIABASE_REQUEST_EXIT, this, r );
  1817 		return r;
  2042 		return r;
  1818  	  	}
  2043 		}
       
  2044 
  1819  	  	
  2045  	  	
  1820 
  2046 
  1821 	// for ERead & EWrite requests, get the linear address for pinning & DMA
  2047 	// for ERead & EWrite requests, get the linear address for pinning & DMA
  1822 	TUint8* linAddress = NULL;
  2048 	TUint8* linAddress = NULL;
  1823 	TClientBuffer clientBuffer;
  2049 	TClientBuffer clientBuffer;
  2259 	switch (m.iValue)
  2485 	switch (m.iValue)
  2260 		{
  2486 		{
  2261 		case EConnect:
  2487 		case EConnect:
  2262 			{
  2488 			{
  2263 			DLocalDrive* pD=(DLocalDrive*)m.Ptr0();
  2489 			DLocalDrive* pD=(DLocalDrive*)m.Ptr0();
  2264 			iConnectionQ.Add(&pD->iLink);
  2490 			iConnectionQ.Add(&pD->iMediaChangeObserver.iLink);
  2265 			m.Complete(KErrNone, EFalse);
  2491 			m.Complete(KErrNone, EFalse);
  2266 			OstTraceFunctionExit1( DPRIMARYMEDIABASE_HANDLEMSG_EXIT1, this );
  2492 			OstTraceFunctionExit1( DPRIMARYMEDIABASE_HANDLEMSG_EXIT1, this );
  2267 			return;
  2493 			return;
  2268 			}
  2494 			}
  2269 		case EDisconnect:
  2495 		case EDisconnect:
  2282 			return;
  2508 			return;
  2283 			}
  2509 			}
  2284 		case DLocalDrive::EForceMediaChange:
  2510 		case DLocalDrive::EForceMediaChange:
  2285 			{
  2511 			{
  2286 			TUint flags = (TUint) m.Pos();
  2512 			TUint flags = (TUint) m.Pos();
       
  2513 
       
  2514 #ifdef __DEMAND_PAGING__
       
  2515 			// if this is a paging media (ROM,code or data), turn off the KMediaRemountForceMediaChange flag 
       
  2516 			// as this normally results in a call to DPBusSocket::ForceMediaChange() which effectively disables 
       
  2517 			// the media for a small time period - which would be disasterous if a paging request arrived
       
  2518 			if (iBody->iPagingDevice)
       
  2519 				flags&= ~KMediaRemountForceMediaChange;
       
  2520 #endif
       
  2521 
       
  2522 			// For media extension drivers, send a copy of the request to the next drive in the chain and wait for it. 
       
  2523 			TLocDrv* drv = m.Drive();
       
  2524 			if (drv->iNextDrive)
       
  2525 				{
       
  2526 				TLocDrvRequest request;
       
  2527 				request.Drive() = drv->iNextDrive;
       
  2528 				request.Id() = DLocalDrive::EForceMediaChange;
       
  2529 				request.Pos() = m.Pos();	// flags
       
  2530 
       
  2531 				request.SendReceive(&drv->iNextDrive->iPrimaryMedia->iMsgQ);
       
  2532 
       
  2533 				CompleteRequest(m, request.iValue);
       
  2534 				return;
       
  2535 				}
       
  2536 
  2287 
  2537 
  2288 			// if KForceMediaChangeReOpenDriver specified wait for power up, 
  2538 			// if KForceMediaChangeReOpenDriver specified wait for power up, 
  2289 			// and then re-open this drive's media driver
  2539 			// and then re-open this drive's media driver
  2290 			__KTRACE_OPT(KLOCDRV, Kern::Printf("EForceMediaChange, flags %08X\n", flags));
  2540 			__KTRACE_OPT(KLOCDRV, Kern::Printf("EForceMediaChange, flags %08X\n", flags));
  2291 			if (flags == (TUint) KForceMediaChangeReOpenMediaDriver)
  2541 			if (flags == (TUint) KForceMediaChangeReOpenMediaDriver)
  2513 	
  2763 	
  2514 	// re-open this drive's media driver ?
  2764 	// re-open this drive's media driver ?
  2515 	if (m.iValue == DLocalDrive::EForceMediaChange)
  2765 	if (m.iValue == DLocalDrive::EForceMediaChange)
  2516 		{
  2766 		{
  2517 		__ASSERT_DEBUG(((TUint) m.Pos()) == (TUint) KForceMediaChangeReOpenMediaDriver, LOCM_FAULT());
  2767 		__ASSERT_DEBUG(((TUint) m.Pos()) == (TUint) KForceMediaChangeReOpenMediaDriver, LOCM_FAULT());
  2518 
       
  2519 		iCurrentReq=NULL;
  2768 		iCurrentReq=NULL;
  2520 
  2769 
  2521 		TLocDrv* pL = m.Drive();
  2770 		TLocDrv* pL = m.Drive();
  2522 		DMedia* media = pL->iMedia;
  2771 		DMedia* media = pL->iMedia;
       
  2772 
  2523 		if (media && media->iDriver)
  2773 		if (media && media->iDriver)
  2524 			CloseMediaDrivers(media);
  2774 			CloseMediaDrivers(media);
  2525 
  2775 
  2526 		iState=EOpening;
  2776 		iState=EOpening;
  2527 		StartOpenMediaDrivers();
  2777 		StartOpenMediaDrivers();
  2528 
  2778 
  2529 		NotifyClients(ETrue,pL);
  2779 		NotifyClients(EMediaChange, pL);
  2530 		CompleteRequest(m, r);
  2780 		CompleteRequest(m, r);
  2531 		OstTraceFunctionExitExt( DPRIMARYMEDIABASE_DOREQUEST_EXIT, this, r );
  2781 		OstTraceFunctionExitExt( DPRIMARYMEDIABASE_DOREQUEST_EXIT, this, r );
  2532 		return r;
  2782 		return r;
  2533 		}
  2783 		}
  2534 
  2784 
  2551 			return KErrNone;
  2801 			return KErrNone;
  2552 			}
  2802 			}
  2553 		if (!(m.Flags() & TLocDrvRequest::EAdjusted))
  2803 		if (!(m.Flags() & TLocDrvRequest::EAdjusted))
  2554 			{
  2804 			{
  2555 			// If this isn't the only partition, don't allow access to the whole media 
  2805 			// If this isn't the only partition, don't allow access to the whole media 
  2556 			if (iTotalPartitionsOpened > 1)
  2806 			if (TDriveIterator::GetPhysicalDrive(m.Drive())->iPrimaryMedia->iTotalPartitionsOpened > 1)
  2557 				m.DriverFlags() &= ~RLocalDrive::ELocDrvWholeMedia;
  2807 				m.DriverFlags() &= ~RLocalDrive::ELocDrvWholeMedia;
  2558 			r=m.CheckAndAdjustForPartition();
  2808 			r=m.CheckAndAdjustForPartition();
  2559 			}
  2809 			}
  2560 		if (r==KErrNone)
  2810 		if (r==KErrNone)
  2561 			{
  2811 			{
  2637 			OstTraceDefExt2(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_DOREQUEST4, "Media driver cannot service or defer PageIn request 0x%08x or serviced it synchronously; retval=%d",(TUint) &m, s);
  2887 			OstTraceDefExt2(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_DOREQUEST4, "Media driver cannot service or defer PageIn request 0x%08x or serviced it synchronously; retval=%d",(TUint) &m, s);
  2638 			iBody->iPagingDevice->CompleteRequest(&m, s);
  2888 			iBody->iPagingDevice->CompleteRequest(&m, s);
  2639 			}
  2889 			}
  2640 		else
  2890 		else
  2641 #endif
  2891 #endif
  2642 
  2892 			{
  2643 		CompleteRequest(m, s);
  2893 			CompleteRequest(m, s);
  2644 		OstTraceDefExt3( OST_TRACE_CATEGORY_RND, TRACE_INTERNALS, DPRIMARYMEDIABASE_DOREQUEST_RETURN, "Return req Id=%d; Remote Thread=0x%x; retval=%d", (TInt) m.Id(), (TUint) m.RemoteThread(), (TInt) s);
  2894 			OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_INTERNALS, DPRIMARYMEDIABASE_DOREQUEST_RETURN, "Return Remote Thread=0x%x; retval=%d", (TUint) m.RemoteThread(), (TInt) s);
       
  2895 			}
  2645 		}
  2896 		}
  2646 
  2897 
  2647 	iCurrentReq=NULL;
  2898 	iCurrentReq=NULL;
  2648 	OstTraceFunctionExitExt( DPRIMARYMEDIABASE_DOREQUEST_EXIT3, this, r );
  2899 	OstTraceFunctionExitExt( DPRIMARYMEDIABASE_DOREQUEST_EXIT3, this, r );
  2649 	return r;
  2900 	return r;
  2695 	OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS1, "DPrimaryMediaBase iMediaId=%d", iMediaId );
  2946 	OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS1, "DPrimaryMediaBase iMediaId=%d", iMediaId );
  2696 	
  2947 	
  2697 	// we mustn't ever close the media driver if it's responsible for data paging as re-opening the drive
  2948 	// we mustn't ever close the media driver if it's responsible for data paging as re-opening the drive
  2698 	// would involve memory allocation which might cause deadlock if the kernel heap were to grow
  2949 	// would involve memory allocation which might cause deadlock if the kernel heap were to grow
  2699 #ifdef __DEMAND_PAGING__
  2950 #ifdef __DEMAND_PAGING__
  2700 	if (DataPagingDfcQ(this))
  2951 	if (DataPagingMedia(this))
  2701 		{
  2952 		{
  2702 		__KTRACE_OPT(KLOCDRV,Kern::Printf("CloseMediaDrivers aborting for data paging media %08X", this));
  2953 		__KTRACE_OPT(KLOCDRV,Kern::Printf("CloseMediaDrivers aborting for data paging media %08X", this));
  2703 		OstTrace1(TRACE_FLOW, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS_EXIT1, "CloseMediaDrivers aborting for data paging media 0x%08x", this);
  2954 		OstTrace1(TRACE_FLOW, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS_EXIT1, "CloseMediaDrivers aborting for data paging media 0x%08x", this);
  2704 		return;
  2955 		return;
  2705 		}
  2956 		}
  2706 #endif
  2957 #endif
  2707 
  2958 
  2708 	TInt i;
  2959 
  2709 	for (i=0; i<KMaxLocalDrives; i++)
  2960 	// Don't close any media extension drivers either, since it won't serve any purpose
  2710 		{
  2961 	// and keeping the driver open allows it to maintain internal state
  2711 		TLocDrv* pL=TheDrives[i];
  2962 	if (iBody->iMediaExtension)
       
  2963 		{
       
  2964 		__KTRACE_OPT(KLOCDRV,Kern::Printf("CloseMediaDrivers aborting for extension media %08X", this));
       
  2965 		return;
       
  2966 		}
       
  2967 
       
  2968 
       
  2969 	TDriveIterator driveIter;
       
  2970 	for (TLocDrv* pL = driveIter.NextDrive(); pL != NULL; pL = driveIter.NextDrive())
       
  2971 		{
  2712 		if (pL && pL->iPrimaryMedia==this)
  2972 		if (pL && pL->iPrimaryMedia==this)
  2713 			{
  2973 			{
  2714 			__KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d",i));
  2974 			__KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d",driveIter.Index()));
  2715 			OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS2, "Drive=%d", i );
  2975 			OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_CLOSEMEDIADRIVERS2, "Drive=%d", driveIter.Index());
  2716 			if (aMedia == NULL || pL->iMedia == aMedia)
  2976 			if (aMedia == NULL || pL->iMedia == aMedia)
  2717 				{
  2977 				{
  2718 				pL->iMedia=NULL;
  2978 				pL->iMedia=NULL;
  2719 				}
  2979 				}
  2720 			}
  2980 			}
  2721 		}
  2981 		}
  2722 	for (i=iLastMediaId; i>=iMediaId; i--)
  2982 	for (TInt i=iLastMediaId; i>=iMediaId; i--)
  2723 		{
  2983 		{
  2724 		DMedia* pM=TheMedia[i];
  2984 		DMedia* pM=TheMedia[i];
  2725 		if (aMedia == NULL || pM == aMedia)
  2985 		if (aMedia == NULL || pM == aMedia)
  2726 			{
  2986 			{
  2727 			DMediaDriver* pD=pM->iDriver;
  2987 			DMediaDriver* pD=pM->iDriver;
  2874 		{
  3134 		{
  2875 		// couldn't read partition info or driver failed to open
  3135 		// couldn't read partition info or driver failed to open
  2876 		if (pM->iDriver)
  3136 		if (pM->iDriver)
  2877 			{
  3137 			{
  2878 #ifdef __DEMAND_PAGING__
  3138 #ifdef __DEMAND_PAGING__
  2879 			if (DataPagingDfcQ(this))
  3139 			if (DataPagingMedia(this))
  2880 				{
  3140 				{
  2881 				__KTRACE_OPT(KLOCDRV,Kern::Printf("DoPartitionInfoComplete(%d) Close Media Driver aborted for data paging media %08X", this));
  3141 				__KTRACE_OPT(KLOCDRV,Kern::Printf("DoPartitionInfoComplete(%d) Close Media Driver aborted for data paging media %08X", this));
  2882 				OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_DOPARTITIONINFOCOMPLETE2, "Close Media Driver for data paging media 0x%08x", this);
  3142 				OstTraceDef1(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_DOPARTITIONINFOCOMPLETE2, "Close Media Driver for data paging media 0x%08x", this);
  2883 				}
  3143 				}
  2884 			else
  3144 			else
  2940 	// work out mapping of drives to partitions/media
  3200 	// work out mapping of drives to partitions/media
  2941 	TInt totalPartitions=iTotalPartitionsOpened;
  3201 	TInt totalPartitions=iTotalPartitionsOpened;
  2942 	TInt id=iMediaId;	// start with primary media
  3202 	TInt id=iMediaId;	// start with primary media
  2943 	TInt partitionsOnThisMedia=PartitionCount();
  3203 	TInt partitionsOnThisMedia=PartitionCount();
  2944 	TInt partition=0;
  3204 	TInt partition=0;
  2945 	TInt j;
  3205 
  2946 	for (j=0; j<KMaxLocalDrives; j++)
  3206 	TDriveIterator driveIter;
  2947 		{
  3207 	for (TLocDrv* pD = driveIter.NextDrive(); pD != NULL; pD = driveIter.NextDrive())
  2948 		TLocDrv* pD=TheDrives[j];
  3208 		{
  2949 		if (pD && pD->iPrimaryMedia==this)
  3209 		if (pD && pD->iPrimaryMedia==this)
  2950 			{
  3210 			{
  2951 			if (totalPartitions==0)
  3211 			if (totalPartitions==0)
  2952 				{
  3212 				{
  2953 				pD->iMedia=NULL;
  3213 				pD->iMedia=NULL;
  2957 				{
  3217 				{
  2958 				id++;
  3218 				id++;
  2959 				partition=0;
  3219 				partition=0;
  2960 				partitionsOnThisMedia=TheMedia[id]->PartitionCount();
  3220 				partitionsOnThisMedia=TheMedia[id]->PartitionCount();
  2961 				}
  3221 				}
  2962 			__KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d = Media %d Partition %d",j,id,partition));
  3222 			__KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d = Media %d Partition %d",driveIter.Index(),id,partition));
  2963 			OstTraceExt3( TRACE_INTERNALS, DPRIMARYMEDIABASE_DOPARTITIONINFOCOMPLETE5, "Local Drive=%d; iMediaId=%d; partition=%d", j, id, partition );
  3223 			OstTraceExt3( TRACE_INTERNALS, DPRIMARYMEDIABASE_DOPARTITIONINFOCOMPLETE5, "Local Drive=%d; iMediaId=%d; partition=%d", driveIter.Index(), id, partition );
  2964 			
       
  2965 			pD->iMedia=TheMedia[id];
  3224 			pD->iMedia=TheMedia[id];
  2966 			pD->iPartitionNumber=partition;
  3225 			pD->iPartitionNumber=partition;
  2967 			memcpy(pD, pD->iMedia->iPartitionInfo.iEntry+partition, sizeof(TPartitionEntry));
  3226 			memcpy(pD, pD->iMedia->iPartitionInfo.iEntry+partition, sizeof(TPartitionEntry));
  2968 			partition++;
  3227 			partition++;
  2969 			totalPartitions--;
  3228 			totalPartitions--;
  3225 
  3484 
  3226 	iWaitMedChg.CompleteAll(KErrNone);
  3485 	iWaitMedChg.CompleteAll(KErrNone);
  3227 	OstTraceFunctionExit1( DPRIMARYMEDIABASE_SETCLOSED_EXIT, this );
  3486 	OstTraceFunctionExit1( DPRIMARYMEDIABASE_SETCLOSED_EXIT, this );
  3228 	}
  3487 	}
  3229 
  3488 
  3230 void DPrimaryMediaBase::NotifyClients(TBool aMediaChange,TLocDrv* aLocDrv)
  3489 void DPrimaryMediaBase::NotifyClients(TNotifyType aNotifyType, TLocDrv* aLocDrv)
  3231 
  3490 
  3232 //
  3491 //
  3233 // Notify all clients of a media change or power-down event
  3492 // Notify all clients of a media change or media present event
  3234 //
  3493 //
  3235 	{
  3494 	{
  3236 	OstTraceFunctionEntryExt( DPRIMARYMEDIABASE_NOTIFYCLIENTS_ENTRY, this );
  3495 	OstTraceFunctionEntryExt( DPRIMARYMEDIABASE_NOTIFYCLIENTS_ENTRY, this );
  3237 	
  3496 	
  3238 	SDblQueLink* pL=iConnectionQ.iA.iNext;
  3497 	SDblQueLink* pL=iConnectionQ.iA.iNext;
  3239 	while (pL!=&iConnectionQ.iA)
  3498 	while (pL!=&iConnectionQ.iA)
  3240 		{
  3499 		{
  3241 		DLocalDrive* pD=_LOFF(pL,DLocalDrive,iLink);
  3500 		// Get pointer to TCallBackLink
       
  3501 		TCallBackLink* pCallBackLink = _LOFF(pL,TCallBackLink,iLink);
       
  3502 
       
  3503 		// The link is embedded in either a TLocDrv or a  DLocalDrive object;
       
  3504 		// find out which one it is and then get TLocDrv pointer from that
       
  3505 		__ASSERT_DEBUG(pCallBackLink->iObjectType == TCallBackLink::EDLocalDriveObject || pCallBackLink->iObjectType == TCallBackLink::ETLocDrvObject, LOCM_FAULT());
       
  3506 		TLocDrv* locDrv;
       
  3507 		if (pCallBackLink->iObjectType == TCallBackLink::EDLocalDriveObject)
       
  3508 			locDrv = ((DLocalDrive*) _LOFF(pCallBackLink,DLocalDrive, iMediaChangeObserver))->iDrive;
       
  3509 		else
       
  3510 			locDrv = ((TLocDrv*) _LOFF(pCallBackLink,TLocDrv, iMediaChangeObserver))->iNextDrive;
       
  3511 
  3242 		// Issue the notification if the caller wants to notify all drives (aLocDrv == NULL) or 
  3512 		// Issue the notification if the caller wants to notify all drives (aLocDrv == NULL) or 
  3243 		// the specified drive matches this one
  3513 		// the specified drive matches this one
  3244 		if (aLocDrv == NULL || aLocDrv == pD->iDrive)
  3514 		if (aLocDrv == NULL || aLocDrv == locDrv)
  3245 			pD->NotifyChange(*this, aMediaChange);
  3515 			pCallBackLink->CallBack(aNotifyType);
       
  3516 
  3246 		pL=pL->iNext;
  3517 		pL=pL->iNext;
  3247 		}
  3518 		}
  3248 	OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYCLIENTS_EXIT, this );
  3519 	OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYCLIENTS_EXIT, this );
  3249 	}
  3520 	}
  3250 
  3521 
  3258 	OstTraceFunctionEntry1( DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE_ENTRY, this );
  3529 	OstTraceFunctionEntry1( DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE_ENTRY, this );
  3259 	__KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::NotifyMediaChange state %d",iMediaId,iState));
  3530 	__KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::NotifyMediaChange state %d",iMediaId,iState));
  3260 
  3531 
  3261 	OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE, "iMediaId=%d; iState=%d", iMediaId, iState );
  3532 	OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_MEDIACHANGE, DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE, "iMediaId=%d; iState=%d", iMediaId, iState );
  3262 	
  3533 	
  3263 	TInt state=iState;
  3534 	// This should only be called in the context of the media thread
  3264 
  3535 	__ASSERT_ALWAYS(NKern::CurrentThread() == iDfcQ->iThread, LOCM_FAULT());
  3265 	__ASSERT_DEBUG(iBody, LOCM_FAULT());
  3536 
  3266 
  3537 	MediaChange();
  3267 #ifdef __DEMAND_PAGING__
       
  3268 	iBody->iMediaChanges++;
       
  3269 
       
  3270 	// As data paging media never close, need to ensure the media driver cancels
       
  3271 	// any requests it owns as the stack may be powered down by DPBusPrimaryMedia::ForceMediaChange().
       
  3272 	// DMediaDriver::NotifyPowerDown() should do this
       
  3273 	if(DataPagingDfcQ(this))
       
  3274 		NotifyPowerDown();
       
  3275 #endif
       
  3276 
       
  3277 	// complete any outstanding requests with KErrNotReady
       
  3278 	// and any force media change requests with KErrNone
       
  3279 	SetClosed(KErrNotReady);
       
  3280 
       
  3281 	// close all media drivers on this device
       
  3282 	if (state>=EOpening)
       
  3283 		{
       
  3284 		CloseMediaDrivers();
       
  3285 		}
       
  3286 
  3538 
  3287 	// notify all connections that media change has occurred
  3539 	// notify all connections that media change has occurred
  3288 	NotifyClients(ETrue);
  3540 	NotifyClients(EMediaChange);
  3289 
  3541 
  3290 	// complete any force media change requests
  3542 	// complete any force media change requests
  3291 	iWaitMedChg.CompleteAll(KErrNone);
  3543 	iWaitMedChg.CompleteAll(KErrNone);
  3292 	OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE_EXIT, this );
  3544 	OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYMEDIACHANGE_EXIT, this );
  3293 	}
  3545 	}
  3352 	else
  3604 	else
  3353 		{
  3605 		{
  3354 		CloseMediaDrivers();
  3606 		CloseMediaDrivers();
  3355 		SetClosed(KErrNotReady);
  3607 		SetClosed(KErrNotReady);
  3356 		}
  3608 		}
  3357 
       
  3358 	NotifyClients(EFalse);
       
  3359 	OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYPOWERDOWN_EXIT, this );
  3609 	OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYPOWERDOWN_EXIT, this );
  3360 	}
  3610 	}
  3361 
  3611 
  3362 
  3612 
  3363 EXPORT_C void DPrimaryMediaBase::NotifyPsuFault(TInt anError)
  3613 EXPORT_C void DPrimaryMediaBase::NotifyPsuFault(TInt anError)
  3423 		// if ready, media driver should complete current request
  3673 		// if ready, media driver should complete current request
  3424 		CompleteCurrent(KErrNotReady);
  3674 		CompleteCurrent(KErrNotReady);
  3425 		}
  3675 		}
  3426 	CloseMediaDrivers();
  3676 	CloseMediaDrivers();
  3427 	SetClosed(KErrNotReady);
  3677 	SetClosed(KErrNotReady);
  3428 	NotifyClients(EFalse);
       
  3429 	OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYEMERGENCYPOWERDOWN_EXIT, this );
  3678 	OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYEMERGENCYPOWERDOWN_EXIT, this );
       
  3679 	}
       
  3680 
       
  3681 
       
  3682 /**
       
  3683 Called by NotifyMediaPresent() and NotifyMediaChange() to ensure the media is in the correct state
       
  3684 */
       
  3685 void DPrimaryMediaBase::MediaChange()
       
  3686 	{
       
  3687 	// Media has been inserted, so we need to cancel any outstanding requests and 
       
  3688 	// ensure that the partition info is read again
       
  3689 	TInt state = iState;
       
  3690 
       
  3691 	__ASSERT_DEBUG(iBody, LOCM_FAULT());
       
  3692 
       
  3693 #ifdef __DEMAND_PAGING__
       
  3694 	iBody->iMediaChanges++;
       
  3695 
       
  3696 	// As data paging media never close, need to ensure the media driver cancels
       
  3697 	// any requests it owns as the stack may be powered down by DPBusPrimaryMedia::ForceMediaChange().
       
  3698 	// DMediaDriver::NotifyPowerDown() should do this
       
  3699 	if (DataPagingMedia(this))
       
  3700 		NotifyPowerDown();
       
  3701 #endif
       
  3702 
       
  3703 	// complete any outstanding requests with KErrNotReady
       
  3704 	// and any force media change requests with KErrNone
       
  3705 	SetClosed(KErrNotReady);
       
  3706 
       
  3707 	// close all media drivers on this device
       
  3708 	if (state>=EOpening)
       
  3709 		{
       
  3710 		CloseMediaDrivers();
       
  3711 		}
  3430 	}
  3712 	}
  3431 
  3713 
  3432 EXPORT_C void DPrimaryMediaBase::NotifyMediaPresent()
  3714 EXPORT_C void DPrimaryMediaBase::NotifyMediaPresent()
  3433 /**
  3715 /**
  3434 Notifies clients of a media change by calling NotifyClients ( ) function to indicate that media is present.
  3716 Notifies clients of a media change by calling NotifyClients ( ) function to indicate that media is present.
  3435 */
  3717 */
  3436 	{
  3718 	{
  3437 	OstTraceFunctionEntry1( DPRIMARYMEDIABASE_NOTIFYMEDIAPRESENT_ENTRY, this );
  3719 	OstTraceFunctionEntry1( DPRIMARYMEDIABASE_NOTIFYMEDIAPRESENT_ENTRY, this );
  3438 	NotifyClients(ETrue);
  3720 	__KTRACE_OPT(KLOCDRV,Kern::Printf("DPrimaryMediaBase(%d)::NotifyMediaPresent state %d",iMediaId,iState));
       
  3721 
       
  3722 	// This should only be called in the context of the media thread
       
  3723 	__ASSERT_ALWAYS(NKern::CurrentThread() == iDfcQ->iThread, LOCM_FAULT());
       
  3724 
       
  3725 	MediaChange();
       
  3726 
       
  3727 	NotifyClients(EMediaPresent);
  3439 	OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYMEDIAPRESENT_EXIT, this );
  3728 	OstTraceFunctionExit1( DPRIMARYMEDIABASE_NOTIFYMEDIAPRESENT_EXIT, this );
  3440 	}
  3729 	}
  3441 
  3730 
  3442 EXPORT_C TInt DPrimaryMediaBase::DoInCritical()
  3731 EXPORT_C TInt DPrimaryMediaBase::DoInCritical()
  3443 /**
  3732 /**
  3584 	if (r==KErrNone)
  3873 	if (r==KErrNone)
  3585 		{
  3874 		{
  3586 		TInt id=iMediaId;	// start with primary media
  3875 		TInt id=iMediaId;	// start with primary media
  3587 		TInt partitionsOnThisMedia=PartitionCount();
  3876 		TInt partitionsOnThisMedia=PartitionCount();
  3588 		TInt partition=0;
  3877 		TInt partition=0;
  3589 		TInt j;
  3878 		
  3590 		for (j=0; j<KMaxLocalDrives; j++)
  3879 		TDriveIterator driveIter;
  3591 			{
  3880 		for (TLocDrv* pD = driveIter.NextDrive(); pD != NULL; pD = driveIter.NextDrive())
  3592 			TLocDrv* pD=TheDrives[j];
  3881 			{
  3593 			if (pD && pD->iPrimaryMedia==this)
  3882 			if (pD && pD->iPrimaryMedia==this)
  3594 				{
  3883 				{
  3595 				if (totalPartitions==0)
  3884 				if (totalPartitions==0)
  3596 					{
  3885 					{
  3597 					pD->iMedia=NULL;
  3886 					pD->iMedia=NULL;
  3624 // For data-paging media, calls DPagingDevice::NotifyBusy() when count goes positive
  3913 // For data-paging media, calls DPagingDevice::NotifyBusy() when count goes positive
  3625 //
  3914 //
  3626 void DPrimaryMediaBase::RequestCountInc()
  3915 void DPrimaryMediaBase::RequestCountInc()
  3627 	{
  3916 	{
  3628 	__ASSERT_DEBUG(iBody, LOCM_FAULT());
  3917 	__ASSERT_DEBUG(iBody, LOCM_FAULT());
  3629 	TInt oldVal = (TInt) __e32_atomic_add_ord32(&iBody->iRequestCount, (TUint) 1);
  3918 	if (iBody->iPagingDevice)
  3630 //Kern::Printf("RCINC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal);
  3919 		{
  3631 	
  3920 		NFastMutex* lock = iBody->iPagingDevice->NotificationLock();
  3632 	OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTINC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal );
  3921 		NKern::FMWait(lock);
  3633 	
  3922 		TInt oldVal = iBody->iRequestCount++;
  3634 	if (oldVal == 0 && iBody->iPagingDevice)
  3923 		//Kern::Printf("RCINC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal);
  3635 		{
  3924 		OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTINC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal );
  3636 //Kern::Printf("RCINC: NotifyBusy()");
  3925 		if (oldVal == 0)
  3637 		iBody->iPagingDevice->NotifyBusy();
  3926 			{
       
  3927 			//Kern::Printf("RCINC: NotifyBusy()");
       
  3928 			iBody->iPagingDevice->NotifyBusy();
       
  3929 			}
       
  3930 		NKern::FMSignal(lock);
  3638 		}
  3931 		}
  3639 	}
  3932 	}
  3640 
  3933 
  3641 // RequestCountDec()
  3934 // RequestCountDec()
  3642 // 
  3935 // 
  3644 // For data-paging media, calls DPagingDevice::NotifyIdle() when count reaches zero
  3937 // For data-paging media, calls DPagingDevice::NotifyIdle() when count reaches zero
  3645 //
  3938 //
  3646 void DPrimaryMediaBase::RequestCountDec()
  3939 void DPrimaryMediaBase::RequestCountDec()
  3647 	{
  3940 	{
  3648 	__ASSERT_DEBUG(iBody, LOCM_FAULT());
  3941 	__ASSERT_DEBUG(iBody, LOCM_FAULT());
  3649 	TInt oldVal = (TInt) __e32_atomic_add_ord32(&iBody->iRequestCount, (TUint) -1);
  3942 	if (iBody->iPagingDevice)
  3650 //Kern::Printf("RCDEC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal);
  3943 		{
  3651 	
  3944 		NFastMutex* lock = iBody->iPagingDevice->NotificationLock();
  3652 	OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTDEC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal );
  3945 		NKern::FMWait(lock);
  3653 	
  3946 		TInt oldVal = iBody->iRequestCount--;
  3654 	if (oldVal == 1 && iBody->iPagingDevice)
  3947 		//Kern::Printf("RCDEC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal);
  3655 		{
  3948 		OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTDEC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal );
  3656 //Kern::Printf("RCDEC: NotifyIdle()");
  3949 		if (oldVal == 1)
  3657 		iBody->iPagingDevice->NotifyIdle();
  3950 			{
  3658 		}
  3951 			//Kern::Printf("RCDEC: NotifyIdle()");
  3659 	__ASSERT_DEBUG(iBody->iRequestCount >= 0, LOCM_FAULT());
  3952 			iBody->iPagingDevice->NotifyIdle();
       
  3953 			}		
       
  3954 		NKern::FMSignal(lock);
       
  3955 		__ASSERT_DEBUG(iBody->iRequestCount >= 0, LOCM_FAULT());
       
  3956 		}
  3660 	}
  3957 	}
  3661 #endif	// __DEMAND_PAGING__
  3958 #endif	// __DEMAND_PAGING__
  3662 
  3959 
  3663 TPartitionInfo::TPartitionInfo()
  3960 TPartitionInfo::TPartitionInfo()
  3664 //
  3961 //
  3955 	// Read from the media and allow for retries in the unlikely event of an error.
  4252 	// Read from the media and allow for retries in the unlikely event of an error.
  3956 	const TInt KPageInRetries = 5;
  4253 	const TInt KPageInRetries = 5;
  3957 	TInt retVal = KErrGeneral;
  4254 	TInt retVal = KErrGeneral;
  3958 	for (TInt i=0; retVal != KErrNone && i < KPageInRetries; i++)
  4255 	for (TInt i=0; retVal != KErrNone && i < KPageInRetries; i++)
  3959 		{
  4256 		{
  3960 		m.Flags() = TLocDrvRequest::EPaging;
  4257 		m.Flags() = TLocDrvRequest::EKernelBuffer | TLocDrvRequest::EPaging;
  3961 		TLocDrv* pL=NULL;
  4258 		TLocDrv* pL=NULL;
  3962 		if(aDrvNumber == EDriveRomPaging)					// ROM paging
  4259 		if(aDrvNumber == EDriveRomPaging)					// ROM paging
  3963 			{
  4260 			{
  3964 			m.Id() = DMediaPagingDevice::ERomPageInRequest;
  4261 			m.Id() = DMediaPagingDevice::ERomPageInRequest;
  3965 			if (iRomPagingDriveNumber == KErrNotFound)
  4262 			if (iRomPagingDriveNumber == KErrNotFound)
  3994 		else if ((aDrvNumber >=0) && (aDrvNumber<KMaxLocalDrives))	// Code paging
  4291 		else if ((aDrvNumber >=0) && (aDrvNumber<KMaxLocalDrives))	// Code paging
  3995 			{
  4292 			{
  3996 			m.Id() = DMediaPagingDevice::ECodePageInRequest;
  4293 			m.Id() = DMediaPagingDevice::ECodePageInRequest;
  3997 			m.Flags() |= TLocDrvRequest::ECodePaging;
  4294 			m.Flags() |= TLocDrvRequest::ECodePaging;
  3998 			pL=TheDrives[aDrvNumber];
  4295 			pL=TheDrives[aDrvNumber];
  3999 			__ASSERT_DEBUG(pL&&(pL->iPrimaryMedia==iPrimaryMedia),LOCM_FAULT());	// valid drive number?
  4296 			__ASSERT_DEBUG(pL && TDriveIterator::GetDrive(aDrvNumber, iPrimaryMedia) ,LOCM_FAULT());	// valid drive number?
  4000 			m.Drive()=pL;
  4297 			m.Drive()=pL;
  4001 #ifdef __DEMAND_PAGING_BENCHMARKS__
  4298 #ifdef __DEMAND_PAGING_BENCHMARKS__
  4002 			__e32_atomic_add_ord32(&iMediaPagingInfo.iCodePageInCount, (TUint) 1);
  4299 			__e32_atomic_add_ord32(&iMediaPagingInfo.iCodePageInCount, (TUint) 1);
  4003 			info = &iCodeBenchmarkData;
  4300 			info = &iCodeBenchmarkData;
  4004 #endif
  4301 #endif
  4132 	// Write to the media and allow for retries in the unlikely event of an error.
  4429 	// Write to the media and allow for retries in the unlikely event of an error.
  4133 	const TInt KPageOutRetries = 5;
  4430 	const TInt KPageOutRetries = 5;
  4134 	TInt retVal = KErrGeneral;
  4431 	TInt retVal = KErrGeneral;
  4135 	for (TInt i=0; retVal != KErrNone && i < KPageOutRetries; i++)
  4432 	for (TInt i=0; retVal != KErrNone && i < KPageOutRetries; i++)
  4136 		{
  4433 		{
  4137 		m.Flags() = TLocDrvRequest::EPaging | 
  4434 		m.Flags() = TLocDrvRequest::EKernelBuffer |
       
  4435 					TLocDrvRequest::EPaging | 
  4138                     TLocDrvRequest::EDataPaging | 
  4436                     TLocDrvRequest::EDataPaging | 
  4139                     (aBackground ? TLocDrvRequest::EBackgroundPaging : 0) |
  4437                     (aBackground ? TLocDrvRequest::EBackgroundPaging : 0) |
  4140                     (aPhysAddr ? TLocDrvRequest::EPhysAddrOnly : 0);
  4438                     (aPhysAddr ? TLocDrvRequest::EPhysAddrOnly : 0);
  4141 
  4439 
  4142 		m.Id() = DLocalDrive::EWrite;
  4440 		m.Id() = DLocalDrive::EWrite;
  4233 		}
  4531 		}
  4234 
  4532 
  4235 	TLocDrvRequest& m=*(TLocDrvRequest*)(aReq);
  4533 	TLocDrvRequest& m=*(TLocDrvRequest*)(aReq);
  4236 
  4534 
  4237 
  4535 
  4238 	m.Flags() = TLocDrvRequest::EPaging | TLocDrvRequest::EDataPaging;
  4536 	m.Flags() = TLocDrvRequest::EKernelBuffer | TLocDrvRequest::EPaging  | TLocDrvRequest::EDataPaging;
  4239 	m.Id() = DLocalDrive::EDeleteNotify;
  4537 	m.Id() = DLocalDrive::EDeleteNotify;
  4240 	m.Drive() = TheDrives[iDataPagingDriveNumber];
  4538 	m.Drive() = TheDrives[iDataPagingDriveNumber];
  4241 
  4539 
  4242 	m.RemoteThread() = NULL;
  4540 	m.RemoteThread() = NULL;
  4243 	m.Pos() = offset;
  4541 	m.Pos() = offset;
  4266 	OstTraceFunctionExitExt( DMEDIAPAGINGDEVICE_DELETENOTIFY_EXIT3, this, retVal );
  4564 	OstTraceFunctionExitExt( DMEDIAPAGINGDEVICE_DELETENOTIFY_EXIT3, this, retVal );
  4267 	return retVal;
  4565 	return retVal;
  4268 	}
  4566 	}
  4269 
  4567 
  4270 
  4568 
  4271 
       
  4272 EXPORT_C TInt TLocDrvRequest::WriteToPageHandler(const TAny* aSrc, TInt aSize, TInt anOffset)
  4569 EXPORT_C TInt TLocDrvRequest::WriteToPageHandler(const TAny* aSrc, TInt aSize, TInt anOffset)
  4273 	{
  4570 	{
  4274 	OstTraceFunctionEntry1( TLOCDRVREQUEST_WRITETOPAGEHANDLER_ENTRY, this );
  4571 	OstTraceFunctionEntry1( TLOCDRVREQUEST_WRITETOPAGEHANDLER_ENTRY, this );
  4275 #ifdef BTRACE_PAGING_MEDIA
  4572 #ifdef BTRACE_PAGING_MEDIA
  4276 	TMediaDevice medDev=Drive()->iMedia->iDevice;
  4573 	TMediaDevice medDev=Drive()->iMedia->iDevice;
  4454 	if (aLocDrv)
  4751 	if (aLocDrv)
  4455 		aLocDrv->iPartitionLen=aTotalSizeInBytes;
  4752 		aLocDrv->iPartitionLen=aTotalSizeInBytes;
  4456 	OstTraceFunctionExit1( DMEDIADRIVER_SETTOTALSIZEINBYTES_EXIT, this );
  4753 	OstTraceFunctionExit1( DMEDIADRIVER_SETTOTALSIZEINBYTES_EXIT, this );
  4457 	}
  4754 	}
  4458 
  4755 
       
  4756 /**
       
  4757 For non NAND devices, i.e. devices which don't set TLocalDriveCapsV4::iNumOfBlocks,
       
  4758 set iSectorSizeInBytes, iNumberOfSectors & iNumPagesPerBlock appropriately to allow 
       
  4759 TLocalDriveCapsV4::MediaSizeInBytes() to correctly return the media size
       
  4760 
       
  4761 Media drivers should call this when they receive a DLocalDrive::ECaps request
       
  4762 */
       
  4763 EXPORT_C void DMediaDriver::SetTotalSizeInBytes(TLocalDriveCapsV4& aCaps)
       
  4764 	{
       
  4765 	if (aCaps.iNumOfBlocks == 0)
       
  4766 		{
       
  4767 		aCaps.iSectorSizeInBytes = 512;
       
  4768 		aCaps.iNumPagesPerBlock = 1;	// ...to ensure compatibility with NAND semantics
       
  4769 		Int64 numberOfSectors = iTotalSizeInBytes >> 9;
       
  4770 		while (I64HIGH(numberOfSectors) > 0)
       
  4771 			{
       
  4772 			aCaps.iNumPagesPerBlock<<= 1;
       
  4773 			numberOfSectors>>= 1;
       
  4774 			}
       
  4775 		aCaps.iNumberOfSectors = I64LOW(numberOfSectors);
       
  4776 		}
       
  4777 	}
  4459 
  4778 
  4460 
  4779 
  4461 
  4780 
  4462 /**
  4781 /**
  4463 Gets the total size of the media.
  4782 Gets the total size of the media.
  4683 */
  5002 */
  4684 EXPORT_C TInt LocDrv::RegisterMediaDevice(TMediaDevice aDevice, TInt aDriveCount, const TInt* aDriveList, DPrimaryMediaBase* aPrimaryMedia, TInt aNumMedia, const TDesC& aName)
  5003 EXPORT_C TInt LocDrv::RegisterMediaDevice(TMediaDevice aDevice, TInt aDriveCount, const TInt* aDriveList, DPrimaryMediaBase* aPrimaryMedia, TInt aNumMedia, const TDesC& aName)
  4685 	{
  5004 	{
  4686 	OstTraceFunctionEntry0( LOCDRV_REGISTERMEDIADEVICE_ENTRY );
  5005 	OstTraceFunctionEntry0( LOCDRV_REGISTERMEDIADEVICE_ENTRY );
  4687 	// Create TLocDrv / DMedia objects to handle a media device
  5006 	// Create TLocDrv / DMedia objects to handle a media device
  4688 	__KTRACE_OPT(KBOOT,Kern::Printf("RegisterMediaDevice %lS dev=%1d #drives=%d 1st=%d PM=%08x #media=%d",&aName,aDevice,aDriveCount,*aDriveList,aPrimaryMedia,aNumMedia));
  5007 	__KTRACE_OPT(KBOOT,Kern::Printf("RegisterMediaDevice %S dev=%1d #drives=%d 1st=%d PM=%08x #media=%d",&aName,aDevice,aDriveCount,*aDriveList,aPrimaryMedia,aNumMedia));
  4689 	OstTraceExt5( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE1, "aDevice=%d; aDriveCount=%d; aDriveList=%d; aPrimaryMedia=0x%08x; aNumMedia=%d", (TInt) aDevice, (TInt) aDriveCount, (TInt) *aDriveList, (TUint) aPrimaryMedia, (TInt) aNumMedia );
  5008 	OstTraceExt5( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE1, "aDevice=%d; aDriveCount=%d; aDriveList=%d; aPrimaryMedia=0x%08x; aNumMedia=%d", (TInt) aDevice, (TInt) aDriveCount, (TInt) *aDriveList, (TUint) aPrimaryMedia, (TInt) aNumMedia );
  4690 	
  5009 
  4691 	const TInt* p=aDriveList;
       
  4692 	TInt i;
       
  4693 	TInt r=0;
       
  4694 	if (UsedMedia+aNumMedia>KMaxLocalDrives)
  5010 	if (UsedMedia+aNumMedia>KMaxLocalDrives)
  4695 	    {
  5011 	    {
  4696 		OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT1, "< KErrInUse");
  5012 		OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT1, "< KErrInUse");
  4697 		return KErrInUse;
  5013 		return KErrInUse;
  4698 	    }
  5014 		}
  4699 	for (i=0; i<aDriveCount; ++i)
  5015 
  4700 		{
  5016 	// make a local copy of the name
  4701 		TInt drv = *p++;
       
  4702 		// -1 means not used; this is to enable Dual-slot MMC support 
       
  4703 		if (drv == -1)
       
  4704 			continue;
       
  4705 		__KTRACE_OPT(KBOOT,Kern::Printf("Registering drive %d", drv));
       
  4706 		OstTrace1( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE2, "Registering drive=%d", drv );
       
  4707 		if (TheDrives[drv])
       
  4708 			{
       
  4709 			__KTRACE_OPT(KBOOT,Kern::Printf("Drive %d already in use", drv));
       
  4710 			OstTrace1( TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT2, "< Drive %d already in use; KErrInUse", drv);
       
  4711 			return KErrInUse;
       
  4712 			}
       
  4713 		}
       
  4714 	HBuf* pN=HBuf::New(aName);
  5017 	HBuf* pN=HBuf::New(aName);
  4715 	if (!pN)
  5018 	if (!pN)
  4716 	    {
  5019 	    {
  4717         OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT3, "< KErrNoMemory");
  5020         OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT3, "< KErrNoMemory");
  4718 		return KErrNoMemory;
  5021 		return KErrNoMemory;
  4719 	    }
  5022 		}
  4720 	TInt lastMedia=UsedMedia+aNumMedia-1;
  5023 
       
  5024 	// Register the primary media and any secondary media
       
  5025 	TInt lastMedia = UsedMedia+aNumMedia-1;
       
  5026 	TInt i;
       
  5027 	TInt r=0;
  4721 	for (i=UsedMedia; i<=lastMedia; ++i)
  5028 	for (i=UsedMedia; i<=lastMedia; ++i)
  4722 		{
  5029 		{
  4723 		if (i==UsedMedia)
  5030 		if (i==UsedMedia)
  4724 			TheMedia[i]=aPrimaryMedia;
  5031 			TheMedia[i]=aPrimaryMedia;
  4725 		else
  5032 		else
  4736 		    {
  5043 		    {
  4737             OstTrace1(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT5, "< retval=%d", r);
  5044             OstTrace1(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT5, "< retval=%d", r);
  4738 			return r;
  5045 			return r;
  4739 		    }
  5046 		    }
  4740 		}
  5047 		}
  4741 
       
  4742 	__KTRACE_OPT(KBOOT,Kern::Printf("FirstMedia %d LastMedia %d",UsedMedia,lastMedia));
  5048 	__KTRACE_OPT(KBOOT,Kern::Printf("FirstMedia %d LastMedia %d",UsedMedia,lastMedia));
  4743 	OstTraceExt2( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE4, "FirstMedia=%d; LastMedia=%d", UsedMedia, lastMedia );
  5049 	OstTraceExt2( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE4, "FirstMedia=%d; LastMedia=%d", UsedMedia, lastMedia );
  4744 	UsedMedia+=aNumMedia;
  5050 	UsedMedia+=aNumMedia;
  4745 	p=aDriveList;
  5051 
       
  5052 	if (__IS_EXTENSION(aDevice))
       
  5053 		aPrimaryMedia->iBody->iMediaExtension = ETrue;
       
  5054 
       
  5055 	// Register the drives
       
  5056 	const TInt* p=aDriveList;
  4746 	for (i=0; i<aDriveCount; ++i)
  5057 	for (i=0; i<aDriveCount; ++i)
  4747 		{
  5058 		{
  4748 		TInt drv=*p++;
  5059 		TInt drv = *p++;
       
  5060 		// -1 means not used; this is to enable Dual-slot MMC support 
  4749 		if (drv == -1)
  5061 		if (drv == -1)
  4750 			continue;
  5062 			continue;
  4751 		TLocDrv* pL=new TLocDrv(drv);
  5063 
  4752 		if (!pL)
  5064 		__KTRACE_OPT(KBOOT,Kern::Printf("Registering drive %d", drv));
  4753 		    {
  5065 		if (!__IS_EXTENSION(aDevice) && TheDrives[drv])
       
  5066 			{
       
  5067 			__KTRACE_OPT(KBOOT,Kern::Printf("Drive %d already in use", drv));
       
  5068 			return KErrInUse;
       
  5069 			}
       
  5070 		else if (__IS_EXTENSION(aDevice) && !TheDrives[drv])
       
  5071 			{
       
  5072 			__KTRACE_OPT(KBOOT,Kern::Printf("Drive %d not initialized", drv));
       
  5073 			return KErrNotReady;
       
  5074 			}
       
  5075 
       
  5076 		TLocDrv* pNewDrive = new TLocDrv(drv);
       
  5077 		if (!pNewDrive)
       
  5078 			{
  4754             OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT6, "< KErrNoMemory");
  5079             OstTrace0(TRACE_FLOW, LOCDRV_REGISTERMEDIADEVICE_EXIT6, "< KErrNoMemory");
  4755 			return KErrNoMemory;
  5080 			return KErrNoMemory;
  4756 		    }
  5081 			}
  4757 		TheDrives[drv]=pL;
  5082 
  4758 		DriveNames[drv]=pN;
  5083 
  4759 		pL->iPrimaryMedia=aPrimaryMedia;
  5084 		TLocDrv* pOldDrive = TheDrives[drv];
  4760 		__KTRACE_OPT(KBOOT,Kern::Printf("Drive %d: TLocDrv @ %08x",drv,pL));
  5085 		aPrimaryMedia->iBody->iRegisteredDriveMask|= (0x1 << drv);
  4761 		OstTraceExt2( TRACE_INTERNALS, LOCDRV_REGISTERMEDIADEVICE5, "Drive=%d; TLocDrv 0x%08x;", (TInt) drv, (TUint) pL );
  5086 		pNewDrive->iNextDrive = pOldDrive;
  4762 		}
  5087 
       
  5088 		TheDrives[drv] = pNewDrive;
       
  5089 		DriveNames[drv] = pN;
       
  5090 		pNewDrive->iPrimaryMedia = aPrimaryMedia;
       
  5091 
       
  5092 
       
  5093 		if (pOldDrive)
       
  5094 			{
       
  5095 			TInt r = pOldDrive->iPrimaryMedia->Connect(pNewDrive);
       
  5096 			if (r != KErrNone)
       
  5097 				return r;
       
  5098 
       
  5099 #ifdef __DEMAND_PAGING__
       
  5100 			// If we've hooked a drive letter which is being used for ROM paging by a media driver
       
  5101 			// which does not report the ROM partition, then we need to change iFirstLocalDriveNumber
       
  5102 			// so that ROM page-in requests go directly to that driver
       
  5103 			DMediaPagingDevice* oldPagingDevice = pOldDrive->iPrimaryMedia->iBody->iPagingDevice;
       
  5104 			if (oldPagingDevice && 
       
  5105 				(oldPagingDevice->iType & DPagingDevice::ERom) &&
       
  5106 				oldPagingDevice->iRomPagingDriveNumber == KErrNotFound && 
       
  5107 				oldPagingDevice->iFirstLocalDriveNumber == drv)
       
  5108 				{
       
  5109 				__KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("TRACE: hooking ROM paging device with no defined ROM partition"));
       
  5110 				TInt n;
       
  5111 				for (n=0; n<KMaxLocalDrives; ++n)
       
  5112 					{
       
  5113 					if(TheDrives[n] && TheDrives[n]->iPrimaryMedia == pOldDrive->iPrimaryMedia)
       
  5114 						{
       
  5115 						__KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("TRACE: Changing iFirstLocalDriveNumber from %d to %d", oldPagingDevice->iFirstLocalDriveNumber, n));
       
  5116 						oldPagingDevice->iFirstLocalDriveNumber = n;
       
  5117 						break;
       
  5118 						}
       
  5119 					}
       
  5120 				__ASSERT_ALWAYS(n < KMaxLocalDrives, LOCM_FAULT());
       
  5121 				}
       
  5122 #endif
       
  5123 
       
  5124 			}
       
  5125 
       
  5126 		__KTRACE_OPT(KBOOT,Kern::Printf("Drive %d: TLocDrv @ %08x",drv,pNewDrive));
       
  5127 		}
       
  5128 
  4763 
  5129 
  4764 	OstTraceFunctionExit0( LOCDRV_REGISTERMEDIADEVICE_EXIT7 );
  5130 	OstTraceFunctionExit0( LOCDRV_REGISTERMEDIADEVICE_EXIT7 );
  4765 	return KErrNone;
  5131 	return KErrNone;
  4766 	}
  5132 	}
  4767 
  5133 
  4843                      or one of the other system-wide error codes.  
  5209                      or one of the other system-wide error codes.  
  4844 */
  5210 */
  4845 EXPORT_C TInt LocDrv::RegisterPagingDevice(DPrimaryMediaBase* aPrimaryMedia, const TInt* aPagingDriveList, TInt aDriveCount, TUint aPagingType, TInt aReadShift, TUint aNumPages)
  5211 EXPORT_C TInt LocDrv::RegisterPagingDevice(DPrimaryMediaBase* aPrimaryMedia, const TInt* aPagingDriveList, TInt aDriveCount, TUint aPagingType, TInt aReadShift, TUint aNumPages)
  4846 	{
  5212 	{
  4847 	OstTraceFunctionEntry0( LOCDRV_REGISTERPAGINGDEVICE_ENTRY );
  5213 	OstTraceFunctionEntry0( LOCDRV_REGISTERPAGINGDEVICE_ENTRY );
       
  5214 //	SETDEBUGFLAG(KLOCDPAGING);
  4848 	
  5215 	
  4849 	__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf(">RegisterPagingDevice: paging type=%d PM=0x%x read shift=%d",aPagingType,aPrimaryMedia,aReadShift));
  5216 	__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf(">RegisterPagingDevice: paging type=%d PM=0x%x read shift=%d",aPagingType,aPrimaryMedia,aReadShift));
  4850 	OstTraceDefExt3( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE1, "aPagingType=%d; aPrimaryMedia=0x%x; aReadShift=%d", (TInt) aPagingType, (TUint) aPrimaryMedia, (TInt) aReadShift);
  5217 	OstTraceDefExt3( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE1, "aPagingType=%d; aPrimaryMedia=0x%x; aReadShift=%d", (TInt) aPagingType, (TUint) aPrimaryMedia, (TInt) aReadShift);
  4851 	
  5218 	
  4852 	TInt i;
  5219 	TInt i = 0;
  4853 
  5220 
  4854 	if(!aPagingType || (aPagingType&~(DPagingDevice::ERom | DPagingDevice::ECode | DPagingDevice::EData)))
  5221 	if(!aPagingType || (aPagingType&~(DPagingDevice::ERom | DPagingDevice::ECode | DPagingDevice::EData)))
  4855 		{
  5222 		{
  4856 		__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Unsupported paging type, exiting"));
  5223 		__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Unsupported paging type, exiting"));
  4857 		OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT1, "< Unsupported paging type; KErrArgument");
  5224 		OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT1, "< Unsupported paging type; KErrArgument");
  4858 		return KErrArgument;
  5225 		return KErrArgument;
  4859 		}
  5226 		}
  4860 
  5227 
  4861 	for(i=0; i<KMaxLocalDrives; i++)
  5228 
  4862 		{
  5229 	// Check for duplicate drives
  4863 		if (ThePagingDevices[i] == NULL)
  5230 	if (!aPrimaryMedia->iBody->iMediaExtension)
  4864 			continue;
  5231 		{
  4865 		if ((ThePagingDevices[i]->iType&DPagingDevice::ERom) &&	(aPagingType & DPagingDevice::ERom))
  5232 		for(i=0; i<KMaxLocalDrives; i++)
  4866 			{
  5233 			{
  4867 			aPagingType&=~DPagingDevice::ERom;		// already have a ROM paging device
  5234 			if (ThePagingDevices[i] == NULL)
  4868 			__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has ROM pager on locdrv no %d",i));
  5235 				continue;
  4869 			}
  5236 			if ((ThePagingDevices[i]->iType&DPagingDevice::ERom) &&	(aPagingType & DPagingDevice::ERom))
  4870 		if ((ThePagingDevices[i]->iType&DPagingDevice::EData) && (aPagingType & DPagingDevice::EData))
  5237 				{
  4871 			{
  5238 				aPagingType&=~DPagingDevice::ERom;		// already have a ROM paging device
  4872 			aPagingType&=~DPagingDevice::EData;		// already have a Data paging device
  5239 				__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has ROM pager on locdrv no %d",i));
  4873 			__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has Data pager on locdrv no %d",i));
  5240 				}
       
  5241 			if ((ThePagingDevices[i]->iType&DPagingDevice::EData) && (aPagingType & DPagingDevice::EData))
       
  5242 				{
       
  5243 				aPagingType&=~DPagingDevice::EData;		// already have a Data paging device
       
  5244 				__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Already has Data pager on locdrv no %d",i));
       
  5245 				}
  4874 			}
  5246 			}
  4875 		}
  5247 		}
  4876 
  5248 
  4877 
  5249 
  4878 	if (aPagingType == 0)
  5250 	if (aPagingType == 0)
  4951 	__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("DMediaPagingDevice(), firstLocalDriveNumber %d", firstLocalDriveNumber));
  5323 	__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("DMediaPagingDevice(), firstLocalDriveNumber %d", firstLocalDriveNumber));
  4952 	OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE3, "firstLocalDriveNumber=%d", firstLocalDriveNumber );
  5324 	OstTraceDef1( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE3, "firstLocalDriveNumber=%d", firstLocalDriveNumber );
  4953 	
  5325 	
  4954 	// Send an ECaps message to wake up the media driver & ensure all partitions are 
  5326 	// Send an ECaps message to wake up the media driver & ensure all partitions are 
  4955 	// reported, then search for paged-data or paged-ROM partitions
  5327 	// reported, then search for paged-data or paged-ROM partitions
       
  5328 	// NB: older media drivers supporting ROM and/or code paging only may not have started their DFC queues, 
       
  5329 	// so for these media drivers, use the first local drive supported for ROM-pagin-in  requests and
       
  5330 	// assume the media driver itself will adjust the request position internally to match the ROM partition
       
  5331 	// @see DMediaPagingDevice::Read()
  4956 	if ((aPagingType & DPagingDevice::EData) ||
  5332 	if ((aPagingType & DPagingDevice::EData) ||
  4957 		(aPagingType & DPagingDevice::ERom && aPrimaryMedia->iDfcQ && aPrimaryMedia->iMsgQ.iReady))
  5333 		(aPagingType & DPagingDevice::ERom && aPrimaryMedia->iDfcQ && aPrimaryMedia->iMsgQ.iReady))
  4958 		{
  5334 		{
  4959 		// the message queue must have been started already (by the media driver calling iMsgQ.Receive())
  5335 		// the message queue must have been started already (by the media driver calling iMsgQ.Receive())
  4960 		// otherwise we can't send the DLocalDrive::EQueryDevice request
  5336 		// otherwise we can't send the DLocalDrive::ECaps request
  4961 		if (aPrimaryMedia->iDfcQ && !aPrimaryMedia->iMsgQ.iReady)
  5337 		if (!aPrimaryMedia->iDfcQ || !aPrimaryMedia->iMsgQ.iReady)
  4962 			{
  5338 			{
  4963 			__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: Message queue not started"));
  5339 			__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: Message queue not started"));
  4964 			OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT8, "< RegisterPagingDevice: Message queue not started; KErrNotReady");
  5340 			OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT8, "< RegisterPagingDevice: Message queue not started; KErrNotReady");
  4965 			return KErrNotReady;
  5341 			return KErrNotReady;
  4966 			}
  5342 			}
  4991 			OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE4, "Paging device ECaps: i %d retval=%d", i, r);
  5367 			OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE4, "Paging device ECaps: i %d retval=%d", i, r);
  4992 			}
  5368 			}
  4993 
  5369 
  4994 		if (r != KErrNone)
  5370 		if (r != KErrNone)
  4995 		    {
  5371 		    {
  4996             OstTrace1(TRACE_FLOW, LOCRV_REGISTERPAGINGDEVICE_EXIT9, "< Caps::retval=%d - return KErrNotSupported",r);
  5372             OstTrace1(TRACE_FLOW, LOCRV_REGISTERPAGINGDEVICE_EXIT9, "< retval=%d",r);
  4997             // Media driver failure; media maybe recoverable after boot.
  5373             // Media driver failure; media maybe recoverable after boot.
  4998             // Can't register any page drives so return not supported.
  5374             // Can't register any page drives so return not supported.
  4999 			return KErrNotSupported;
  5375 			return KErrNotSupported;
  5000 		    }
  5376 		    }
  5001 
  5377 
  5002 		TLocalDriveCapsV6& caps = *(TLocalDriveCapsV6*)capsBuf.Ptr();
  5378 		TLocalDriveCapsV6& caps = *(TLocalDriveCapsV6*)capsBuf.Ptr();
  5003 		blockSize = caps.iBlockSize;
  5379 		blockSize = caps.iBlockSize;
       
  5380 		__ASSERT_DEBUG(blockSize,LOCM_FAULT());
       
  5381 		__ASSERT_DEBUG(__e32_bit_count_32(blockSize)==1,LOCM_FAULT());
  5004 		
  5382 		
  5005 		TLocDrv* drive;
  5383 		TLocDrv* drive;
  5006 		for (i=0; i<KMaxLocalDrives; ++i)
  5384 		for (i=0; i<KMaxLocalDrives; ++i)
  5007 			{
  5385 			{
  5008 			drive = TheDrives[i];
  5386 			drive = TheDrives[i];
  5009 			if(drive && drive->iPrimaryMedia == aPrimaryMedia)
  5387 			if(drive && drive->iPrimaryMedia == aPrimaryMedia)
  5010 				{
  5388 				{
  5011 				__KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("RegisterPagingDevice: local drive %d, partition type %x size %x", i, drive->iPartitionType, I64LOW(drive->iPartitionLen)));
  5389 				__KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("RegisterPagingDevice: local drive %d, partition type %x base %lx size %lx name %S", i, drive->iPartitionType, drive->iPartitionBaseAddr, drive->iPartitionLen, DriveNames[i] ? DriveNames[i] : &KNullDesC8));
  5012 				// ROM partition ?
  5390 				// ROM partition ?
  5013 				if ((romPagingDriveNumber == KErrNotFound) && (drive->iPartitionType == KPartitionTypeROM))
  5391 				if ((romPagingDriveNumber == KErrNotFound) && 
       
  5392 					(drive->iPartitionType == KPartitionTypeROM) &&
       
  5393 					(aPagingType & DPagingDevice::ERom))
  5014 					{
  5394 					{
  5015 					__KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found ROM partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen)));
  5395 					__KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found ROM partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen)));
  5016 					OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE5, "Found ROM partition on local drive=%d; size=0x%x", (TInt) i, (TUint) I64LOW(drive->iPartitionLen));
  5396 					OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE5, "Found ROM partition on local drive=%d; size=0x%x", (TInt) i, (TUint) I64LOW(drive->iPartitionLen));
  5017 					romPagingDriveNumber = i;
  5397 					romPagingDriveNumber = i;
  5018 					}
  5398 					}
  5019 			    // swap partition ?
  5399 			    // swap partition ?
  5020 				else if ((dataPagingDriveNumber == KErrNotFound) && (drive->iPartitionType == KPartitionTypePagedData))
  5400 				else if ((dataPagingDriveNumber == KErrNotFound) && 
       
  5401 					(drive->iPartitionType == KPartitionTypePagedData) &&
       
  5402 					(aPagingType & DPagingDevice::EData))
  5021 					{
  5403 					{
  5022 					__KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found swap partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen)));
  5404 					__KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found swap partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen)));
  5023 					OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE6, "Found SWAP partition on local drive=%d; size=0x%x", (TInt) i, (TUint) I64LOW(drive->iPartitionLen) );			
  5405 					OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, LOCDRV_REGISTERPAGINGDEVICE6, "Found SWAP partition on local drive=%d; size=0x%x", (TInt) i, (TUint) I64LOW(drive->iPartitionLen) );			
  5024 					dataPagingDriveNumber = i;
  5406 					dataPagingDriveNumber = i;
       
  5407 					TheDataPagingDrive = drive;
  5025 					swapSize = drive->iPartitionLen >> aReadShift;
  5408 					swapSize = drive->iPartitionLen >> aReadShift;
  5026 					
  5409 					
  5027 			        // Mark Paging Device capable of utilising physical addresss only accesses
  5410 			        // Mark Paging Device capable of utilising physical addresss only accesses
  5028 			        if (drive->iDmaHelper)
  5411 			        if (drive->iDmaHelper)
  5029 			            flags |= DPagingDevice::ESupportsPhysicalAccess;  
  5412 			            flags |= DPagingDevice::ESupportsPhysicalAccess;  
  5049 		OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT_EXIT10, "< RegisterPagingDevice: could not create paging device; KErrNoMemory");
  5432 		OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT_EXIT10, "< RegisterPagingDevice: could not create paging device; KErrNoMemory");
  5050 		return KErrNoMemory;
  5433 		return KErrNoMemory;
  5051 		}
  5434 		}
  5052 
  5435 
  5053 	pagingDevice->iType = aPagingType;
  5436 	pagingDevice->iType = aPagingType;
  5054 	pagingDevice->iFlags = flags;
  5437 	if (aPrimaryMedia->iBody->iMediaExtension)
       
  5438 		pagingDevice->iType|= DPagingDevice::EMediaExtension;
       
  5439 
  5055 	pagingDevice->iReadUnitShift = aReadShift;
  5440 	pagingDevice->iReadUnitShift = aReadShift;
  5056 
  5441 
  5057 	pagingDevice->iFirstLocalDriveNumber = firstLocalDriveNumber;
  5442 	pagingDevice->iFirstLocalDriveNumber = firstLocalDriveNumber;
  5058 	pagingDevice->iRomPagingDriveNumber = romPagingDriveNumber;
  5443 	pagingDevice->iRomPagingDriveNumber = romPagingDriveNumber;
  5059 
  5444 
  5062 		
  5447 		
  5063 	pagingDevice->iPreferredWriteShift = (blockSize) ? __e32_find_ms1_32(blockSize) : 0;
  5448 	pagingDevice->iPreferredWriteShift = (blockSize) ? __e32_find_ms1_32(blockSize) : 0;
  5064 
  5449 
  5065 #ifdef __DEBUG_DEMAND_PAGING__
  5450 #ifdef __DEBUG_DEMAND_PAGING__
  5066 	Kern::Printf("PagingDevice :");
  5451 	Kern::Printf("PagingDevice :");
  5067 	Kern::Printf("iType 0x%x\n", pagingDevice->iType);
  5452 	Kern::Printf("Name %S", firstLocalDriveNumber >= 0 && DriveNames[firstLocalDriveNumber] ? DriveNames[firstLocalDriveNumber] : &KNullDesC8);
       
  5453 	Kern::Printf("iType 0x%x", pagingDevice->iType);
  5068 	Kern::Printf("iFlags 0x%x\n", pagingDevice->iFlags);
  5454 	Kern::Printf("iFlags 0x%x\n", pagingDevice->iFlags);
  5069 	Kern::Printf("iReadUnitShift 0x%x\n", pagingDevice->iReadUnitShift);
  5455 	Kern::Printf("iReadUnitShift 0x%x", pagingDevice->iReadUnitShift);
  5070 	Kern::Printf("iFirstLocalDriveNumber 0x%x\n", pagingDevice->iFirstLocalDriveNumber);
  5456 	Kern::Printf("iFirstLocalDriveNumber 0x%x", pagingDevice->iFirstLocalDriveNumber);
  5071 	Kern::Printf("iRomPagingDriveNumber 0x%x\n", pagingDevice->iRomPagingDriveNumber);
  5457 	Kern::Printf("iRomPagingDriveNumber 0x%x", pagingDevice->iRomPagingDriveNumber);
  5072 	Kern::Printf("iDataPagingDriveNumber 0x%x\n", pagingDevice->iDataPagingDriveNumber);
  5458 	Kern::Printf("iDataPagingDriveNumber 0x%x", pagingDevice->iDataPagingDriveNumber);
  5073 	Kern::Printf("iSwapSize 0x%x\n", pagingDevice->iSwapSize);
  5459 	Kern::Printf("iSwapSize 0x%x", pagingDevice->iSwapSize);
  5074 	Kern::Printf("iPreferredWriteShift 0x%x\n", pagingDevice->iPreferredWriteShift);
  5460 	Kern::Printf("iPreferredWriteShift 0x%x\n", pagingDevice->iPreferredWriteShift);
  5075 #endif
  5461 #endif
  5076 
  5462 
  5077 
  5463 
  5078 	// This table is indexed by DPagingDevice::TType
  5464 	// This table is indexed by DPagingDevice::TType
  5090 
  5476 
  5091 
  5477 
  5092 	if(aPagingType & DPagingDevice::ECode)
  5478 	if(aPagingType & DPagingDevice::ECode)
  5093 		{
  5479 		{
  5094 		for (i=0; i<aDriveCount; ++i)
  5480 		for (i=0; i<aDriveCount; ++i)
  5095 			pagingDevice->iDrivesSupported|=(0x1<<aPagingDriveList[i]);
  5481 			pagingDevice->iDrivesSupported |= (0x1<<aPagingDriveList[i]);
  5096 		}
  5482 		}
  5097 	pagingDevice->iName = DeviceName[aPagingType];
  5483 	pagingDevice->iName = DeviceName[aPagingType];
  5098 
  5484 
       
  5485 	// If ThePinObjectAllocator has already been created with a smaller number of pages,
       
  5486 	// delete it & then re-create it
       
  5487 	__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: ThePinObjectAllocator %x", ThePinObjectAllocator));
       
  5488 	if (ThePinObjectAllocator && ThePinObjectAllocator->iFragmentGranularity < Kern::RoundToPageSize(1) * aNumPages)
       
  5489 		{
       
  5490 		__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: Recreating ThePinObjectAllocator..."));
       
  5491 		delete ThePinObjectAllocator;
       
  5492 		ThePinObjectAllocator = NULL;
       
  5493 		}
       
  5494 
       
  5495 
       
  5496 	TInt r;
  5099 	if (ThePinObjectAllocator == NULL)
  5497 	if (ThePinObjectAllocator == NULL)
       
  5498 		{
  5100 		ThePinObjectAllocator = new DPinObjectAllocator();
  5499 		ThePinObjectAllocator = new DPinObjectAllocator();
  5101 	if(!ThePinObjectAllocator)
  5500 		if(!ThePinObjectAllocator)
  5102 		{
  5501 			{
  5103 		__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not create ThePinObjectAllocator"));
  5502 			__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not create ThePinObjectAllocator"));
  5104 		OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT11, "RegisterPagingDevice: could not create ThePinObjectAllocator; KErrNoMemory");
  5503 			OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT11, "RegisterPagingDevice: could not create ThePinObjectAllocator; KErrNoMemory");
  5105 		return KErrNoMemory;
  5504 			return KErrNoMemory;
  5106 		}
  5505 			}
  5107 	TInt r = ThePinObjectAllocator->Construct(KDynamicPagingLockCount, aNumPages);
  5506 		r = ThePinObjectAllocator->Construct(KDynamicPagingLockCount, aNumPages);
  5108 	if (r != KErrNone)
  5507 		if (r != KErrNone)
  5109 		{
  5508 			{
  5110 		__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not construct ThePinObjectAllocator"));
  5509 			__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("RegisterPagingDevice: could not construct ThePinObjectAllocator"));
  5111 		OstTrace1(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT12, "< RegisterPagingDevice: could not construct ThePinObjectAllocator; retval=%d",r);
  5510 			OstTrace1(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT12, "< RegisterPagingDevice: could not construct ThePinObjectAllocator; retval=%d",r);
  5112 		return r;
  5511 			return r;
       
  5512 			}
  5113 		}
  5513 		}
  5114 
  5514 
  5115 
  5515 
  5116 	// Register our DPagingDevice with the Kernel
  5516 	// Register our DPagingDevice with the Kernel
  5117 	r=Kern::InstallPagingDevice(pagingDevice);
  5517 	r=Kern::InstallPagingDevice(pagingDevice);
  5137 	if (aPagingType&DPagingDevice::ECode)
  5537 	if (aPagingType&DPagingDevice::ECode)
  5138 		{
  5538 		{
  5139 		for (i=0; i<aDriveCount; ++i)
  5539 		for (i=0; i<aDriveCount; ++i)
  5140 			{
  5540 			{
  5141 			TLocDrv* pD=TheDrives[*p++];
  5541 			TLocDrv* pD=TheDrives[*p++];
  5142 			pD->iPagingDrv=1;
  5542 			pD->iPagingDrv = 1;
       
  5543 			// mark all attached drives as pageable too - this is really 
       
  5544 			// only to avoid hitting an ASSERT in DMediaDriver::Complete()
       
  5545 			while (pD->iNextDrive)
       
  5546 				{
       
  5547 				pD->iNextDrive->iPagingDrv = 1;
       
  5548 				pD = pD->iNextDrive;
       
  5549 				}
  5143 			}
  5550 			}
  5144 		}
  5551 		}
  5145 
  5552 
  5146 	// Flags to indicate that a paging device is registered and pinning of user requests may be required
  5553 	// Flags to indicate that a paging device is registered and pinning of user requests may be required
  5147 	aPrimaryMedia->iPagingMedia = 1;
  5554 	aPrimaryMedia->iPagingMedia = 1;
  5181 		TheDataPagingMedia = aPrimaryMedia;
  5588 		TheDataPagingMedia = aPrimaryMedia;
  5182 		}
  5589 		}
  5183 
  5590 
  5184 	__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("< RegisterPagingDevice"));
  5591 	__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("< RegisterPagingDevice"));
  5185 	OstTraceFunctionExit0( LOCDRV_REGISTERPAGINGDEVICE_EXIT14 );
  5592 	OstTraceFunctionExit0( LOCDRV_REGISTERPAGINGDEVICE_EXIT14 );
       
  5593 //	CLRDEBUGFLAG(KLOCDPAGING);
  5186 	return KErrNone;
  5594 	return KErrNone;
  5187 	}
  5595 	}
  5188 
  5596 
  5189 #else //__DEMAND_PAGING__
  5597 #else //__DEMAND_PAGING__
  5190 
  5598 
  5256 	for (i=0; i<KMaxLocalDrives; ++i)
  5664 	for (i=0; i<KMaxLocalDrives; ++i)
  5257 		{
  5665 		{
  5258 		TLocDrv* pL=TheDrives[i];
  5666 		TLocDrv* pL=TheDrives[i];
  5259 		if (pL)
  5667 		if (pL)
  5260 			{
  5668 			{
       
  5669 			pL = TDriveIterator::GetPhysicalDrive(TheDrives[i]);
  5261 			++drives;
  5670 			++drives;
  5262 			TInt sockNum;
  5671 			TInt sockNum;
  5263 			DPrimaryMediaBase* pM=pL->iPrimaryMedia;
  5672 			DPrimaryMediaBase* pM=pL->iPrimaryMedia;
  5264 			if (pM->IsRemovableDevice(sockNum))
  5673 			if (pM->IsRemovableDevice(sockNum))
  5265 				{
  5674 				{
  5266 				if (!(sock_mask & (1<<sockNum)))
  5675 				if (!(sock_mask & (1<<sockNum)))
  5267 					{
  5676 					{
  5268 					info.iSocketName[sockNum]=*DriveNames[i];
  5677 					info.iSocketName[sockNum]=*DriveNames[i];
  5269 					__KTRACE_OPT(KLOCDRV,Kern::Printf("Socket %d device %d name %lS", sockNum, pM->iDevice, DriveNames[i]));
  5678 					__KTRACE_OPT(KLOCDRV,Kern::Printf("Socket %d device %d name %S", sockNum, pM->iDevice, DriveNames[i]));
  5270 					OstTraceExt2( TRACE_INTERNALS, GETDRIVEINFO1, "Socket=%d; device=%d", sockNum, (TUint) pM->iDevice );
  5679 					OstTraceExt2( TRACE_INTERNALS, GETDRIVEINFO1, "Socket=%d; device=%d", sockNum, (TUint) pM->iDevice );
  5271 					if ( (sockNum + 1) > sockets )
  5680 					if ( (sockNum + 1) > sockets )
  5272 						sockets = sockNum + 1;
  5681 						sockets = sockNum + 1;
  5273 					}
  5682 					}
  5274 				sock_mask |= (1<<sockNum);
  5683 				sock_mask |= (1<<sockNum);
  5275 				}
  5684 				}
  5276 			info.iDriveName[i]=*DriveNames[i];
  5685 			info.iDriveName[i]=*DriveNames[i];
  5277 			__KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d device %d name %lS",i,pM->iDevice,DriveNames[i]));
  5686 			__KTRACE_OPT(KLOCDRV,Kern::Printf("Drive %d device %d name %S",i,pM->iDevice,DriveNames[i]));
  5278 			OstTraceExt2( TRACE_INTERNALS, GETDRIVEINFO2, "Drive=%d; device=%d", i, (TUint) pM->iDevice );
  5687 			OstTraceExt2( TRACE_INTERNALS, GETDRIVEINFO2, "Drive=%d; device=%d", i, (TUint) pM->iDevice );
  5279 			
  5688 			
  5280 			info.iRegisteredDriveBitmask |= (0x01 << i);
  5689 			info.iRegisteredDriveBitmask |= (0x01 << i);
  5281 			}
  5690 			}
  5282 		}
  5691 		}
  5395 			break;
  5804 			break;
  5396 			}
  5805 			}
  5397 #if defined(__DEMAND_PAGING__) && defined(__CONCURRENT_PAGING_INSTRUMENTATION__)
  5806 #if defined(__DEMAND_PAGING__) && defined(__CONCURRENT_PAGING_INSTRUMENTATION__)
  5398 		case EMediaHalGetROMConcurrencyInfo:
  5807 		case EMediaHalGetROMConcurrencyInfo:
  5399 			{
  5808 			{
  5400 			TInt drvNo=(TInt)a1;
  5809 			DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ERom);
  5401 			TLocDrv* drv=TheDrives[drvNo];
       
  5402 			if(!drv)
       
  5403 				break;
       
  5404 			DMediaPagingDevice* device = drv->iPrimaryMedia->iBody->iPagingDevice;
       
  5405 			if(!device)
  5810 			if(!device)
  5406 				break;
  5811 				break;
  5407 			NKern::FMWait(&device->iInstrumentationLock);
  5812 			NKern::FMWait(&device->iInstrumentationLock);
  5408 			SMediaROMPagingConcurrencyInfo info=device->iROMStats;
  5813 			SMediaROMPagingConcurrencyInfo info=device->iROMStats;
  5409 			NKern::FMSignal(&device->iInstrumentationLock);
  5814 			NKern::FMSignal(&device->iInstrumentationLock);
  5411 			r=KErrNone;
  5816 			r=KErrNone;
  5412 			break;
  5817 			break;
  5413 			}
  5818 			}
  5414 		case EMediaHalGetCodeConcurrencyInfo:
  5819 		case EMediaHalGetCodeConcurrencyInfo:
  5415 			{
  5820 			{
  5416 			TInt drvNo=(TInt)a1;
  5821 			DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ECode);
  5417 			TLocDrv* drv=TheDrives[drvNo];
       
  5418 			if(!drv)
       
  5419 				break;
       
  5420 			DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
       
  5421 			if(!device)
  5822 			if(!device)
  5422 				break;
  5823 				break;
  5423 			NKern::FMWait(&device->iInstrumentationLock);
  5824 			NKern::FMWait(&device->iInstrumentationLock);
  5424 			SMediaCodePagingConcurrencyInfo info=device->iCodeStats;
  5825 			SMediaCodePagingConcurrencyInfo info=device->iCodeStats;
  5425 			NKern::FMSignal(&device->iInstrumentationLock);
  5826 			NKern::FMSignal(&device->iInstrumentationLock);
  5427 			r=KErrNone;
  5828 			r=KErrNone;
  5428 			break;
  5829 			break;
  5429 			}
  5830 			}
  5430 		case EMediaHalGetDataConcurrencyInfo:
  5831 		case EMediaHalGetDataConcurrencyInfo:
  5431 			{
  5832 			{
  5432 			TInt drvNo=(TInt)a1;
  5833 			DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::EData);
  5433 			TLocDrv* drv=TheDrives[drvNo];
       
  5434 			if(!drv)
       
  5435 				break;
       
  5436 			DMediaPagingDevice* device = drv->iPrimaryMedia->iBody->iPagingDevice;
       
  5437 			if(!device)
  5834 			if(!device)
  5438 				break;
  5835 				break;
  5439 			NKern::FMWait(&device->iInstrumentationLock);
  5836 			NKern::FMWait(&device->iInstrumentationLock);
  5440 			SMediaDataPagingConcurrencyInfo info=device->iDataStats;
  5837 			SMediaDataPagingConcurrencyInfo info=device->iDataStats;
  5441 			NKern::FMSignal(&device->iInstrumentationLock);
  5838 			NKern::FMSignal(&device->iInstrumentationLock);
  5443 			r=KErrNone;
  5840 			r=KErrNone;
  5444 			break;
  5841 			break;
  5445 			}
  5842 			}
  5446 		case EMediaHalResetConcurrencyInfo:
  5843 		case EMediaHalResetConcurrencyInfo:
  5447 			{
  5844 			{
  5448 			TInt drvNo=(TInt)a1;
       
  5449 			TLocDrv* drv=TheDrives[drvNo];
       
  5450 			if(!drv)
       
  5451 				break;
       
  5452 			DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
       
  5453 			if(!device)
       
  5454 				break;
       
  5455 			TUint index=(TInt)a2;
  5845 			TUint index=(TInt)a2;
  5456 			if(index>EMediaPagingStatsCode)
  5846 			if(index>EMediaPagingStatsCode)
  5457 				break;
  5847 				break;
  5458 			ResetConcurrencyStats(device, (TMediaPagingStats)index);
  5848 
       
  5849 			DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ERom);
       
  5850 			if (device)
       
  5851 				ResetConcurrencyStats(device, (TMediaPagingStats)index);
       
  5852 			device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ECode);
       
  5853 			if (device)
       
  5854 				ResetConcurrencyStats(device, (TMediaPagingStats)index);
       
  5855 			device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::EData);
       
  5856 			if (device)
       
  5857 				ResetConcurrencyStats(device, (TMediaPagingStats)index);
       
  5858 
  5459 			r=KErrNone;
  5859 			r=KErrNone;
  5460 			break;
  5860 			break;
  5461 			}
  5861 			}
  5462 #endif
  5862 #endif
  5463 #if defined(__DEMAND_PAGING__) && defined(__DEMAND_PAGING_BENCHMARKS__)
  5863 #if defined(__DEMAND_PAGING__) && defined(__DEMAND_PAGING_BENCHMARKS__)
  5464 		case EMediaHalGetROMPagingBenchmark:
  5864 		case EMediaHalGetROMPagingBenchmark:
  5465 			{
  5865 			{
  5466 			TInt drvNo=(TInt)a1;
  5866 			DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ERom);
  5467 			TLocDrv* drv=TheDrives[drvNo];
       
  5468 			if(!drv)
       
  5469 				break;
       
  5470 			DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
       
  5471 			if(!device)
  5867 			if(!device)
  5472 				break;
  5868 				break;
  5473 			NKern::FMWait(&device->iInstrumentationLock);
  5869 			NKern::FMWait(&device->iInstrumentationLock);
  5474 			SPagingBenchmarkInfo info = device->iROMBenchmarkData;
  5870 			SPagingBenchmarkInfo info = device->iROMBenchmarkData;
  5475 			NKern::FMSignal(&device->iInstrumentationLock);
  5871 			NKern::FMSignal(&device->iInstrumentationLock);
  5477 			r=KErrNone;
  5873 			r=KErrNone;
  5478 			break;
  5874 			break;
  5479 			}		
  5875 			}		
  5480 		case EMediaHalGetCodePagingBenchmark:
  5876 		case EMediaHalGetCodePagingBenchmark:
  5481 			{
  5877 			{
  5482 			TInt drvNo=(TInt)a1;
  5878 			DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ECode);
  5483 			TLocDrv* drv=TheDrives[drvNo];
       
  5484 			if(!drv)
       
  5485 				break;
       
  5486 			DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
       
  5487 			if(!device)
  5879 			if(!device)
  5488 				break;
  5880 				break;
  5489 			NKern::FMWait(&device->iInstrumentationLock);
  5881 			NKern::FMWait(&device->iInstrumentationLock);
  5490 			SPagingBenchmarkInfo info = device->iCodeBenchmarkData;
  5882 			SPagingBenchmarkInfo info = device->iCodeBenchmarkData;
  5491 			NKern::FMSignal(&device->iInstrumentationLock);
  5883 			NKern::FMSignal(&device->iInstrumentationLock);
  5493 			r=KErrNone;
  5885 			r=KErrNone;
  5494 			break;
  5886 			break;
  5495 			}	
  5887 			}	
  5496 		case EMediaHalGetDataInPagingBenchmark:
  5888 		case EMediaHalGetDataInPagingBenchmark:
  5497 			{
  5889 			{
  5498 			TInt drvNo=(TInt)a1;
  5890 			DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::EData);
  5499 			TLocDrv* drv=TheDrives[drvNo];
       
  5500 			if(!drv)
       
  5501 				break;
       
  5502 			DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
       
  5503 			if(!device)
  5891 			if(!device)
  5504 				break;
  5892 				break;
  5505 			NKern::FMWait(&device->iInstrumentationLock);
  5893 			NKern::FMWait(&device->iInstrumentationLock);
  5506 			SPagingBenchmarkInfo info = device->iDataInBenchmarkData;
  5894 			SPagingBenchmarkInfo info = device->iDataInBenchmarkData;
  5507 			NKern::FMSignal(&device->iInstrumentationLock);
  5895 			NKern::FMSignal(&device->iInstrumentationLock);
  5509 			r=KErrNone;
  5897 			r=KErrNone;
  5510 			break;
  5898 			break;
  5511 			}		
  5899 			}		
  5512 		case EMediaHalGetDataOutPagingBenchmark:
  5900 		case EMediaHalGetDataOutPagingBenchmark:
  5513 			{
  5901 			{
  5514 			TInt drvNo=(TInt)a1;
  5902 			DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::EData);
  5515 			TLocDrv* drv=TheDrives[drvNo];
       
  5516 			if(!drv)
       
  5517 				break;
       
  5518 			DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
       
  5519 			if(!device)
  5903 			if(!device)
  5520 				break;
  5904 				break;
  5521 			NKern::FMWait(&device->iInstrumentationLock);
  5905 			NKern::FMWait(&device->iInstrumentationLock);
  5522 			SPagingBenchmarkInfo info = device->iDataOutBenchmarkData;
  5906 			SPagingBenchmarkInfo info = device->iDataOutBenchmarkData;
  5523 			NKern::FMSignal(&device->iInstrumentationLock);
  5907 			NKern::FMSignal(&device->iInstrumentationLock);
  5525 			r=KErrNone;
  5909 			r=KErrNone;
  5526 			break;
  5910 			break;
  5527 			}		
  5911 			}		
  5528 		case EMediaHalResetPagingBenchmark:
  5912 		case EMediaHalResetPagingBenchmark:
  5529 			{
  5913 			{
  5530 			TInt drvNo=(TInt)a1;
       
  5531 			TLocDrv* drv=TheDrives[drvNo];
       
  5532 			if(!drv)
       
  5533 				break;
       
  5534 			DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
       
  5535 			if(!device)
       
  5536 				break;
       
  5537 			TUint index=(TInt)a2;
  5914 			TUint index=(TInt)a2;
  5538 			if(index>EMediaPagingStatsCode)
  5915 			if(index>EMediaPagingStatsCode)
  5539 				break;
  5916 				break;
  5540 			ResetBenchmarkStats(device, (TMediaPagingStats)index);
  5917 
       
  5918 			DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ERom);
       
  5919 			if (device)
       
  5920 				ResetBenchmarkStats(device, (TMediaPagingStats)index);
       
  5921 			device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::ECode);
       
  5922 			if (device)
       
  5923 				ResetBenchmarkStats(device, (TMediaPagingStats)index);
       
  5924 			device = TDriveIterator::PagingDevice((TInt)a1, DPagingDevice::EData);
       
  5925 			if (device)
       
  5926 				ResetBenchmarkStats(device, (TMediaPagingStats)index);
       
  5927 
  5541 			r=KErrNone;
  5928 			r=KErrNone;
  5542 			break;
  5929 			break;
  5543 			}
  5930 			}
  5544 		case EMediaHalGetPagingInfo:
  5931 		case EMediaHalGetPagingInfo:
  5545 			{
  5932 			{
  5546 			TInt drvNo=(TInt)a1;
  5933 			DMediaPagingDevice* device = TDriveIterator::PagingDevice((TInt)a1, (DPagingDevice::TType) 0xFF);
  5547 			TLocDrv* drv=TheDrives[drvNo];
       
  5548 			if(!drv)
       
  5549 				break;
       
  5550 			DMediaPagingDevice* device=drv->iPrimaryMedia->iBody->iPagingDevice;
       
  5551 			if(!device)
  5934 			if(!device)
  5552 				break;
  5935 				break;
  5553 			NKern::FMWait(&device->iInstrumentationLock);
  5936 			NKern::FMWait(&device->iInstrumentationLock);
  5554 			SMediaPagingInfo info = device->iMediaPagingInfo;
  5937 			SMediaPagingInfo info = device->iMediaPagingInfo;
  5555 			NKern::FMSignal(&device->iInstrumentationLock);
  5938 			NKern::FMSignal(&device->iInstrumentationLock);
  5785 		}
  6168 		}
  5786 	}
  6169 	}
  5787 
  6170 
  5788 
  6171 
  5789 /******************************************************************************
  6172 /******************************************************************************
       
  6173  DMediaDriverExtension base class
       
  6174  ******************************************************************************/
       
  6175 
       
  6176 EXPORT_C DMediaDriverExtension::DMediaDriverExtension(TInt aMediaId) :
       
  6177 	DMediaDriver(aMediaId)
       
  6178 	{
       
  6179 	}
       
  6180 
       
  6181 /**
       
  6182 */
       
  6183 EXPORT_C DMediaDriverExtension::~DMediaDriverExtension()
       
  6184 	{
       
  6185 	}
       
  6186 
       
  6187 /**
       
  6188 Closes the media driver.
       
  6189 
       
  6190 This default implementation simply deletes this DMediaDriverExtension object.
       
  6191 
       
  6192 Media drivers can provide their own implementation, which gives them
       
  6193 the opportunity to clean up resources before closure; for example,
       
  6194 cancelling a DFC.
       
  6195 Any replacement function must call this base class function as
       
  6196 the last instruction. 
       
  6197 */
       
  6198 EXPORT_C void DMediaDriverExtension::Close()
       
  6199 	{
       
  6200 	DMediaDriver::Close();
       
  6201 	}
       
  6202 
       
  6203 /**
       
  6204 DoDrivePartitionInfo()
       
  6205 
       
  6206 Fills out the passed TPartitionInfo object with information from the attached drives
       
  6207 */
       
  6208 EXPORT_C TInt DMediaDriverExtension::DoDrivePartitionInfo(TPartitionInfo& aInfo)
       
  6209 	{
       
  6210 	memclr(&aInfo, sizeof(aInfo));
       
  6211 	aInfo.iPartitionCount = 0;
       
  6212 	aInfo.iMediaSizeInBytes = 0;
       
  6213 
       
  6214 	TDriveIterator driveIter;
       
  6215 	for (TLocDrv* drv = driveIter.NextDrive(); drv != NULL; drv = driveIter.NextDrive())
       
  6216 		{
       
  6217 		if (drv && drv->iPrimaryMedia == iPrimaryMedia)
       
  6218 			{
       
  6219 			TLocDrv* attachedDrive = drv->iNextDrive;
       
  6220 			__ASSERT_DEBUG(attachedDrive, LOCM_FAULT());
       
  6221 			TLocDrvRequest m;
       
  6222 			memclr(&m, sizeof(m));
       
  6223 
       
  6224 			// Get the Caps from the device. NB for MMC/SD we may need to retry as there may have been an earlier 
       
  6225 			// EForceMediaChange request which can result in the cancellation of requests already in the queue
       
  6226 			TBuf8<KMaxLocalDriveCapsLength> capsBuf;
       
  6227 			TInt i;
       
  6228 			const TInt KRetries = 5;
       
  6229 			TInt r = KErrNotReady;
       
  6230 			for (i=0; r == KErrNotReady && i < KRetries; i++)
       
  6231 				{
       
  6232 				capsBuf.SetMax();
       
  6233 				capsBuf.FillZ();
       
  6234 				m.Drive() = attachedDrive;
       
  6235 				m.Id() = DLocalDrive::ECaps;
       
  6236 				m.RemoteDes() = (TAny*)capsBuf.Ptr();
       
  6237 				m.Length() = KMaxLocalDriveCapsLength;
       
  6238 				r = attachedDrive->iPrimaryMedia->Request(m);
       
  6239 				}
       
  6240 
       
  6241 			__KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("DMediaDriverExtension::PartitionInfo(ECaps: i %d: r %d ", driveIter.Index(), r));
       
  6242 			
       
  6243 			// NB The ECaps call might legitimately fail if one of the attached drives is removable
       
  6244 			// If this happens, just ignore & proceed to the next attached drive
       
  6245 			if (r == KErrNone)
       
  6246 				{
       
  6247 				aInfo.iEntry[aInfo.iPartitionCount] = *attachedDrive;
       
  6248 				// Set the media size to be that of the largest attached media
       
  6249 				// This is only needed to ensure that the test in TLocDrvRequest::CheckAndAdjustForPartition()
       
  6250 				// with the ELocDrvWholeMedia flag set succeeds: A further check on whether a request's
       
  6251 				// position & length are outside the media will be made when its is delievered  to the attached media....
       
  6252 				aInfo.iMediaSizeInBytes = Max(
       
  6253 					aInfo.iMediaSizeInBytes, 
       
  6254 					((TLocalDriveCapsV4*) capsBuf.Ptr())->MediaSizeInBytes());
       
  6255 				}
       
  6256 
       
  6257 
       
  6258 			aInfo.iPartitionCount++;
       
  6259 			}
       
  6260 		}
       
  6261 
       
  6262 	return KErrNone;
       
  6263 	}
       
  6264 
       
  6265 /**
       
  6266 ForwardRequest() - 
       
  6267 
       
  6268 forwards the request onto the next attached drive in the chain
       
  6269 */
       
  6270 EXPORT_C TInt DMediaDriverExtension::ForwardRequest(TLocDrvRequest& aRequest)
       
  6271 	{
       
  6272 	TLocDrv* drive = aRequest.Drive();
       
  6273 	TLocDrv* attachedDrive = drive->iNextDrive;
       
  6274 	__ASSERT_DEBUG(attachedDrive, LOCM_FAULT());
       
  6275 	aRequest.Drive() = attachedDrive;
       
  6276 
       
  6277 
       
  6278 	TInt r = attachedDrive->iPrimaryMedia->HandleMediaNotPresent(aRequest);
       
  6279 	if (r != KErrNone)
       
  6280 		{
       
  6281 		return r;
       
  6282 		}
       
  6283 	
       
  6284 	aRequest.Forward(&attachedDrive->iPrimaryMedia->iMsgQ, EFalse);
       
  6285 	return KErrNone;
       
  6286 	}
       
  6287 
       
  6288 
       
  6289 TInt DMediaDriverExtension::SendRequest(TInt aReqId, TBool aPagingRequest, TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen)
       
  6290 	{
       
  6291 	__ASSERT_DEBUG(aLen > 0, LOCM_FAULT());
       
  6292 
       
  6293 	// Ensure this is a legitimate attached drive registered using LocDrv::RegisterMediaDevice()
       
  6294 	if (!(iPrimaryMedia->iBody->iRegisteredDriveMask & (0x1 << aDriveNumber)))
       
  6295 		return KErrArgument;
       
  6296 
       
  6297 	TLocDrv* drive = TDriveIterator::GetDrive(aDriveNumber, iPrimaryMedia);
       
  6298 	__ASSERT_DEBUG(drive, LOCM_FAULT());
       
  6299 	TLocDrv* attachedDrive = drive->iNextDrive;
       
  6300 	__ASSERT_DEBUG(attachedDrive, LOCM_FAULT());
       
  6301 
       
  6302 	TLocDrvRequest request;
       
  6303 	memclr(&request, sizeof(request));
       
  6304 
       
  6305 	request.Drive() = attachedDrive;
       
  6306 	request.Id() = aReqId;
       
  6307 	request.Length() = aLen;
       
  6308 	request.RemoteDes() = (TAny*) aData;
       
  6309 	request.Pos() = aPos;
       
  6310 	request.Flags() = TLocDrvRequest::EKernelBuffer | TLocDrvRequest::EAdjusted;
       
  6311 
       
  6312 #ifdef __DEMAND_PAGING__
       
  6313 	if (aPagingRequest)
       
  6314 		{
       
  6315 		request.Flags()|= TLocDrvRequest::EPaging;
       
  6316 		// If the buffer is page aligned, use SendToMainQueueDfcAndBlock() as this 
       
  6317 		// is more efficient if the attached drive use DMA.
       
  6318 		const TInt KPageSizeMask = 4096-1;
       
  6319 		if (aData & KPageSizeMask)
       
  6320 			{
       
  6321 			return attachedDrive->iPrimaryMedia->SendReceive(request, aData);
       
  6322 			}
       
  6323 		else
       
  6324 			{
       
  6325 			attachedDrive->iPrimaryMedia->iBody->iPagingDevice->SendToMainQueueDfcAndBlock(&request);
       
  6326 			return 0;
       
  6327 			}
       
  6328 		}
       
  6329 #else
       
  6330 	aPagingRequest;
       
  6331 #endif
       
  6332 
       
  6333 	return attachedDrive->iPrimaryMedia->SendReceive(request, aData);
       
  6334 	}
       
  6335 
       
  6336 
       
  6337 /**
       
  6338 Read() - 
       
  6339 
       
  6340 reads data from the next attached drive in the chain
       
  6341 
       
  6342 N.B. The position is assumed to be already adjusted i.e. relative to the start of the
       
  6343 media, not the partition
       
  6344 */
       
  6345 EXPORT_C TInt DMediaDriverExtension::Read(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen)
       
  6346 	{
       
  6347 	return SendRequest(DLocalDrive::ERead, EFalse, aDriveNumber, aPos, aData, aLen);
       
  6348 	}
       
  6349 
       
  6350 /**
       
  6351 Write() - 
       
  6352 
       
  6353 writes data to the next attached drive in the chain
       
  6354 
       
  6355 N.B. The position is assumed to be already adjusted i.e. relative to the start of the
       
  6356 media, not the partition
       
  6357 */
       
  6358 EXPORT_C TInt DMediaDriverExtension::Write(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen)
       
  6359 	{
       
  6360 	return SendRequest(DLocalDrive::EWrite, EFalse, aDriveNumber, aPos, aData, aLen);
       
  6361 	}
       
  6362 
       
  6363 
       
  6364 #ifdef __DEMAND_PAGING__
       
  6365 /**
       
  6366 ReadPaged() - 
       
  6367 
       
  6368 Sends a paging read request to the specified attached drive
       
  6369 
       
  6370 N.B. The position is assumed to be already adjusted i.e. relative to the start of the
       
  6371 media, not the partition
       
  6372 */
       
  6373 EXPORT_C TInt DMediaDriverExtension::ReadPaged(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen)
       
  6374 	{
       
  6375 	return SendRequest(DLocalDrive::ERead, ETrue, aDriveNumber, aPos, aData, aLen);
       
  6376 	}
       
  6377 
       
  6378 /**
       
  6379 WritePaged() - 
       
  6380 
       
  6381 Send a paging write request to the specified attached drive
       
  6382 
       
  6383 N.B. The position is assumed to be already adjusted i.e. relative to the start of the
       
  6384 media, not the partition
       
  6385 */
       
  6386 EXPORT_C TInt DMediaDriverExtension::WritePaged(TInt aDriveNumber, TInt64 aPos, TLinAddr aData, TUint aLen)
       
  6387 	{
       
  6388 	return SendRequest(DLocalDrive::EWrite, ETrue, aDriveNumber, aPos, aData, aLen);
       
  6389 	}
       
  6390 #endif	// __DEMAND_PAGING__
       
  6391 
       
  6392 
       
  6393 
       
  6394 /**
       
  6395 Caps() - 
       
  6396 
       
  6397 gets the caps from the next attached drive in the chain
       
  6398 
       
  6399 N.B. The position is assumed to be already adjusted i.e. relative to the start of the
       
  6400 media, not the partition
       
  6401 */
       
  6402 EXPORT_C TInt DMediaDriverExtension::Caps(TInt aDriveNumber, TDes8& aCaps)
       
  6403 	{
       
  6404 	// Ensure this is a legitimate attached drive registered using LocDrv::RegisterMediaDevice()
       
  6405 	if (!(iPrimaryMedia->iBody->iRegisteredDriveMask & (0x1 << aDriveNumber)))
       
  6406 		return KErrArgument;
       
  6407 
       
  6408 	TLocDrv* drive = TDriveIterator::GetDrive(aDriveNumber, iPrimaryMedia);
       
  6409 	__ASSERT_DEBUG(drive, LOCM_FAULT());
       
  6410 	TLocDrv* attachedDrive = drive->iNextDrive;
       
  6411 	__ASSERT_DEBUG(attachedDrive, LOCM_FAULT());
       
  6412 
       
  6413 	TLocDrvRequest request;
       
  6414 	memclr(&request, sizeof(request));
       
  6415 
       
  6416 	request.Drive() = attachedDrive;
       
  6417 	request.Id() = DLocalDrive::ECaps;
       
  6418 	request.Length() = aCaps.Length();
       
  6419 	request.RemoteDes() = (TAny*) aCaps.Ptr();
       
  6420 
       
  6421 	return request.SendReceive(&attachedDrive->iPrimaryMedia->iMsgQ);
       
  6422 	}
       
  6423 
       
  6424 
       
  6425 
       
  6426 EXPORT_C void DMediaDriverExtension::NotifyPowerDown()
       
  6427 	{
       
  6428 	}
       
  6429 
       
  6430 EXPORT_C void DMediaDriverExtension::NotifyEmergencyPowerDown()
       
  6431 	{
       
  6432 	}
       
  6433 
       
  6434 
       
  6435 /**
       
  6436 Returns ETrue if this media - or any media which this TLocDrv is attached to - is busy
       
  6437 */
       
  6438 EXPORT_C TBool DMediaDriverExtension::MediaBusy(TInt aDriveNumber)
       
  6439 	{
       
  6440 	for (TLocDrv* drive = TDriveIterator::GetDrive(aDriveNumber, iPrimaryMedia); 
       
  6441 		drive; 
       
  6442 		drive = drive->iNextDrive)
       
  6443 		{
       
  6444 		DPrimaryMediaBase* primaryMedia = drive->iPrimaryMedia;
       
  6445 		__ASSERT_DEBUG(primaryMedia, LOCM_FAULT());
       
  6446 
       
  6447 		if ((primaryMedia->iMsgQ.iMessage && primaryMedia->iMsgQ.iMessage->iState != TMessageBase::EFree) || 
       
  6448 			!primaryMedia->iMsgQ.iQ.IsEmpty() ||
       
  6449 			primaryMedia->iBody->iMediaChangeDfc.Queued() ||
       
  6450 			primaryMedia->iBody->iMediaPresentDfc.Queued())
       
  6451 			return ETrue;
       
  6452 
       
  6453 #ifdef __DEMAND_PAGING__
       
  6454 		DMediaPagingDevice* pagingDevice = iPrimaryMedia->iBody->iPagingDevice;
       
  6455 		if (pagingDevice)
       
  6456 			{
       
  6457 			if ((pagingDevice->iMainQ.iMessage && pagingDevice->iMainQ.iMessage->iState != TMessageBase::EFree) || 
       
  6458 				!pagingDevice->iMainQ.iQ.IsEmpty())
       
  6459 			return ETrue;
       
  6460 			}
       
  6461 #endif
       
  6462 		}
       
  6463 
       
  6464 	return EFalse;
       
  6465 	}
       
  6466 
       
  6467 
       
  6468 TCallBackLink::TCallBackLink()
       
  6469 	{
       
  6470 	memclr(this, sizeof(this));
       
  6471 	}
       
  6472 
       
  6473 TCallBackLink::TCallBackLink(TInt (*aFunction)(TAny* aPtr, TInt aParam),TAny* aPtr, TObjectType aObjectType) : 
       
  6474 	iFunction(aFunction), iPtr(aPtr), iObjectType(aObjectType)
       
  6475 	{
       
  6476 	}
       
  6477 
       
  6478 TInt TCallBackLink::CallBack(TInt aParam) const
       
  6479 	{
       
  6480 	return (*iFunction)(iPtr, aParam);
       
  6481 	}
       
  6482 
       
  6483 /******************************************************************************
  5790  Entry point
  6484  Entry point
  5791  ******************************************************************************/
  6485  ******************************************************************************/
  5792 DECLARE_STANDARD_EXTENSION()
  6486 DECLARE_STANDARD_EXTENSION()
  5793 	{
  6487 	{
  5794 	__KTRACE_OPT(KBOOT,Kern::Printf("Starting LOCMEDIA extension"));
  6488 	__KTRACE_OPT(KBOOT,Kern::Printf("Starting LOCMEDIA extension"));
  5795 
  6489 
  5796 	// install the HAL function
  6490 	// install the HAL function
  5797 	TInt r=Kern::AddHalEntry(EHalGroupMedia,MediaHalFunction,NULL);
  6491 	TInt r=Kern::AddHalEntry(EHalGroupMedia,MediaHalFunction,NULL);
       
  6492 
  5798 #ifdef __DEMAND_PAGING__
  6493 #ifdef __DEMAND_PAGING__
  5799 	if (r==KErrNone)
  6494 	if (r==KErrNone)
  5800 		{
  6495 		{
  5801 		__KTRACE_OPT(KBOOT,Kern::Printf("Creating LocDrv device"));
  6496 		__KTRACE_OPT(KBOOT,Kern::Printf("Creating LocDrv device"));
  5802 		DLocalDriveFactory* device = new DLocalDriveFactory;
  6497 		DLocalDriveFactory* device = new DLocalDriveFactory;
  5805 		else
  6500 		else
  5806 			r=Kern::InstallLogicalDevice(device);
  6501 			r=Kern::InstallLogicalDevice(device);
  5807 		__KTRACE_OPT(KBOOT,Kern::Printf("Installing LocDrv device in kernel returned %d",r));
  6502 		__KTRACE_OPT(KBOOT,Kern::Printf("Installing LocDrv device in kernel returned %d",r));
  5808 		}
  6503 		}
  5809 #endif // __DEMAND_PAGING__
  6504 #endif // __DEMAND_PAGING__
       
  6505 
  5810 	return r;
  6506 	return r;
  5811 	}
  6507 	}
  5812 
  6508 
  5813 
  6509