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