kernel/eka/drivers/locmedia/locmedia.cpp
branchRCL_3
changeset 28 5b5d147c7838
parent 26 c734af59ce98
child 36 bbf8bed59bcb
equal deleted inserted replaced
26:c734af59ce98 28:5b5d147c7838
    74 	TInt iPhysDevIndex;
    74 	TInt iPhysDevIndex;
    75 	TInt iRequestCount;
    75 	TInt iRequestCount;
    76 #ifdef __DEMAND_PAGING__
    76 #ifdef __DEMAND_PAGING__
    77 	DMediaPagingDevice* iPagingDevice;
    77 	DMediaPagingDevice* iPagingDevice;
    78 	TInt iPageSizeMsk;			// Mask of page size (e.g. 4096-1 -> 4095)
    78 	TInt iPageSizeMsk;			// Mask of page size (e.g. 4096-1 -> 4095)
       
    79 	TInt iPageSizeLog2;        // LOG2 of page size (i.e. 4096 -> 12)
    79 	TInt iMediaChanges;
    80 	TInt iMediaChanges;
    80 #endif
    81 #endif
    81 	};
    82 	};
    82 
    83 
    83 #ifdef __DEMAND_PAGING__
    84 #ifdef __DEMAND_PAGING__
   256 	NKern::FMSignal(&iLock);
   257 	NKern::FMSignal(&iLock);
   257 	OstTraceFunctionExit1( DPINOBJECTALLOCATOR_RELEASEPINOBJECT_EXIT, this );
   258 	OstTraceFunctionExit1( DPINOBJECTALLOCATOR_RELEASEPINOBJECT_EXIT, this );
   258 	}
   259 	}
   259 
   260 
   260 #endif	// __DEMAND_PAGING__
   261 #endif	// __DEMAND_PAGING__
   261 
       
   262 
   262 
   263 /********************************************
   263 /********************************************
   264  * Local drive device base class
   264  * Local drive device base class
   265  ********************************************/
   265  ********************************************/
   266 DECLARE_EXTENSION_LDD()
   266 DECLARE_EXTENSION_LDD()
  1375 	Pos()=d.iPos;
  1375 	Pos()=d.iPos;
  1376 	Length()=d.iLength;
  1376 	Length()=d.iLength;
  1377 	RemoteDes()=(TAny*)d.iPtr;
  1377 	RemoteDes()=(TAny*)d.iPtr;
  1378 	RemoteDesOffset()=d.iOffset;
  1378 	RemoteDesOffset()=d.iOffset;
  1379 	DriverFlags()=d.iFlags;
  1379 	DriverFlags()=d.iFlags;
       
  1380 	
       
  1381 	// EPhysAddrOnly should not be set for client requests
       
  1382 	Flags() &= ~TLocDrvRequest::EPhysAddrOnly;
       
  1383 	
  1380 	if (Pos()<0 || Length()<0)
  1384 	if (Pos()<0 || Length()<0)
  1381 	    {
  1385 	    {
  1382 		OstTraceFunctionExitExt( TLOCDRVREQUEST_PROCESSMESSAGEDATA_EXIT2, this, KErrArgument );
  1386 		OstTraceFunctionExitExt( TLOCDRVREQUEST_PROCESSMESSAGEDATA_EXIT2, this, KErrArgument );
  1383 		return KErrArgument;
  1387 		return KErrArgument;
  1384 	    }
  1388 	    }
  1638 	
  1642 	
  1639 
  1643 
  1640 #ifdef __DEMAND_PAGING__
  1644 #ifdef __DEMAND_PAGING__
  1641 	TInt pageSize = Kern::RoundToPageSize(1);
  1645 	TInt pageSize = Kern::RoundToPageSize(1);
  1642 	iBody->iPageSizeMsk = pageSize-1;
  1646 	iBody->iPageSizeMsk = pageSize-1;
       
  1647 	iBody->iPageSizeLog2 = __e32_find_ms1_32(pageSize);
  1643 #endif
  1648 #endif
  1644 
  1649 
  1645 	iLastMediaId=aLastMediaId;
  1650 	iLastMediaId=aLastMediaId;
  1646 	if (r==KErrNone && iDfcQ)
  1651 	if (r==KErrNone && iDfcQ)
  1647 		{
  1652 		{
  3613 // For data-paging media, calls DPagingDevice::NotifyBusy() when count goes positive
  3618 // For data-paging media, calls DPagingDevice::NotifyBusy() when count goes positive
  3614 //
  3619 //
  3615 void DPrimaryMediaBase::RequestCountInc()
  3620 void DPrimaryMediaBase::RequestCountInc()
  3616 	{
  3621 	{
  3617 	__ASSERT_DEBUG(iBody, LOCM_FAULT());
  3622 	__ASSERT_DEBUG(iBody, LOCM_FAULT());
  3618 	if (iBody->iPagingDevice)
  3623 	TInt oldVal = (TInt) __e32_atomic_add_ord32(&iBody->iRequestCount, (TUint) 1);
  3619 		{
  3624 //Kern::Printf("RCINC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal);
  3620 		NFastMutex* lock = iBody->iPagingDevice->NotificationLock();
  3625 	
  3621 		NKern::FMWait(lock);
  3626 	OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTINC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal );
  3622 		TInt oldVal = iBody->iRequestCount++;
  3627 	
  3623 		//Kern::Printf("RCINC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal);
  3628 	if (oldVal == 0 && iBody->iPagingDevice)
  3624 		OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTINC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal );
  3629 		{
  3625 		if (oldVal == 0)
  3630 //Kern::Printf("RCINC: NotifyBusy()");
  3626 			{
  3631 		iBody->iPagingDevice->NotifyBusy();
  3627 			//Kern::Printf("RCINC: NotifyBusy()");
       
  3628 			iBody->iPagingDevice->NotifyBusy();
       
  3629 			}
       
  3630 		NKern::FMSignal(lock);
       
  3631 		}
  3632 		}
  3632 	}
  3633 	}
  3633 
  3634 
  3634 // RequestCountDec()
  3635 // RequestCountDec()
  3635 // 
  3636 // 
  3637 // For data-paging media, calls DPagingDevice::NotifyIdle() when count reaches zero
  3638 // For data-paging media, calls DPagingDevice::NotifyIdle() when count reaches zero
  3638 //
  3639 //
  3639 void DPrimaryMediaBase::RequestCountDec()
  3640 void DPrimaryMediaBase::RequestCountDec()
  3640 	{
  3641 	{
  3641 	__ASSERT_DEBUG(iBody, LOCM_FAULT());
  3642 	__ASSERT_DEBUG(iBody, LOCM_FAULT());
  3642 	if (iBody->iPagingDevice)
  3643 	TInt oldVal = (TInt) __e32_atomic_add_ord32(&iBody->iRequestCount, (TUint) -1);
  3643 		{
  3644 //Kern::Printf("RCDEC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal);
  3644 		NFastMutex* lock = iBody->iPagingDevice->NotificationLock();
  3645 	
  3645 		NKern::FMWait(lock);
  3646 	OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTDEC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal );
  3646 		TInt oldVal = iBody->iRequestCount--;
  3647 	
  3647 		//Kern::Printf("RCDEC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal);
  3648 	if (oldVal == 1 && iBody->iPagingDevice)
  3648 		OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTDEC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal );
  3649 		{
  3649 		if (oldVal == 1)
  3650 //Kern::Printf("RCDEC: NotifyIdle()");
  3650 			{
  3651 		iBody->iPagingDevice->NotifyIdle();
  3651 			//Kern::Printf("RCDEC: NotifyIdle()");
  3652 		}
  3652 			iBody->iPagingDevice->NotifyIdle();
  3653 	__ASSERT_DEBUG(iBody->iRequestCount >= 0, LOCM_FAULT());
  3653 			}		
       
  3654 		NKern::FMSignal(lock);
       
  3655 		__ASSERT_DEBUG(iBody->iRequestCount >= 0, LOCM_FAULT());
       
  3656 		}
       
  3657 	}
  3654 	}
  3658 #endif	// __DEMAND_PAGING__
  3655 #endif	// __DEMAND_PAGING__
  3659 
  3656 
  3660 TPartitionInfo::TPartitionInfo()
  3657 TPartitionInfo::TPartitionInfo()
  3661 //
  3658 //
  3774 	
  3771 	
  3775 	TLinAddr addr = (TLinAddr) m.RemoteDes();
  3772 	TLinAddr addr = (TLinAddr) m.RemoteDes();
  3776 	TInt len = I64LOW(m.Length());
  3773 	TInt len = I64LOW(m.Length());
  3777 
  3774 
  3778 	TBool needSyncAfterRead = EFalse;
  3775 	TBool needSyncAfterRead = EFalse;
  3779 	if (m.Drive()->iDmaHelper)
  3776     if (m.Drive()->iDmaHelper)
  3780 		{
  3777         {        
  3781 		m.Flags() |= TLocDrvRequest::EPhysAddr;
  3778         m.Flags() |= TLocDrvRequest::EPhysAddr;
  3782 		if (m.Id() == DLocalDrive::EWrite)
  3779         // don't cache sync for zero mapping...
  3783 			{
  3780         if (!(m.Flags() & TLocDrvRequest::EPhysAddrOnly))
  3784 			Cache::SyncMemoryBeforeDmaWrite(addr, len);
  3781             {
  3785 			}
  3782             if (m.Id() == DLocalDrive::EWrite)
  3786 		else
  3783                 {
  3787 			{
  3784                 Cache::SyncMemoryBeforeDmaWrite(addr, len);
  3788 			Cache::SyncMemoryBeforeDmaRead(addr, len);
  3785                 }
  3789 			needSyncAfterRead = ETrue;
  3786             else
  3790 			}
  3787                 {
  3791 		}
  3788                 Cache::SyncMemoryBeforeDmaRead(addr, len);
       
  3789                 needSyncAfterRead = ETrue;
       
  3790                 }
       
  3791             }
       
  3792 	    }
  3792 
  3793 
  3793 	// Count the number of outstanding requests if this is the data-paging media, so that
  3794 	// Count the number of outstanding requests if this is the data-paging media, so that
  3794 	// we can call DPagingDevice::NotifyBusy() / DPagingDevice::NotifyIdle()
  3795 	// we can call DPagingDevice::NotifyBusy() / DPagingDevice::NotifyIdle()
  3795 	if ((m.Flags() & TLocDrvRequest::EBackgroundPaging) == 0)
  3796 	if ((m.Flags() & TLocDrvRequest::EBackgroundPaging) == 0)
  3796 		iPrimaryMedia->RequestCountInc();
  3797 		iPrimaryMedia->RequestCountInc();
  3843 	iPrimaryMedia->CompleteRequest(*((TLocDrvRequest*) aMsg), aResult);
  3844 	iPrimaryMedia->CompleteRequest(*((TLocDrvRequest*) aMsg), aResult);
  3844 	OstTraceFunctionExit1( DMEDIAPAGINGDEVICE_COMPLETEREQUEST_EXIT, this );
  3845 	OstTraceFunctionExit1( DMEDIAPAGINGDEVICE_COMPLETEREQUEST_EXIT, this );
  3845 	}
  3846 	}
  3846 
  3847 
  3847 TInt DMediaPagingDevice::Read(TThreadMessage* aReq,TLinAddr aBuffer,TUint aOffset,TUint aSize,TInt aDrvNumber)
  3848 TInt DMediaPagingDevice::Read(TThreadMessage* aReq,TLinAddr aBuffer,TUint aOffset,TUint aSize,TInt aDrvNumber)
       
  3849     {
       
  3850     return BaseRead(aReq,(TUint32)aBuffer,aOffset,aSize,aDrvNumber,EFalse);
       
  3851     }
       
  3852 
       
  3853 TInt DMediaPagingDevice::ReadPhysical(TThreadMessage* aReq, TPhysAddr* aPageArray, TUint aPageCount, TUint aOffset, TInt aDrvNumber)
       
  3854     {    
       
  3855     TUint adjSize = (aPageCount << iPrimaryMedia->iBody->iPageSizeLog2) >> iReadUnitShift; // translate to Read Units
       
  3856     return BaseRead(aReq,(TUint32)aPageArray,aOffset,adjSize,aDrvNumber,ETrue);
       
  3857     }
       
  3858 
       
  3859 TInt DMediaPagingDevice::BaseRead(TThreadMessage* aReq,TUint32 aBuffer,TUint aOffset,TUint aSize,TInt aDrvNumber, TBool aPhysAddr)
  3848 	{
  3860 	{
  3849 	OstTraceFunctionEntry1( DMEDIAPAGINGDEVICE_READ_ENTRY, this );
  3861 	OstTraceFunctionEntry1( DMEDIAPAGINGDEVICE_READ_ENTRY, this );
  3850 	__ASSERT_ALWAYS(NKern::CurrentThread()!=iPrimaryMedia->iDfcQ->iThread,LOCM_FAULT());	// that would lock up the system, thus better die now
  3862 	__ASSERT_ALWAYS(NKern::CurrentThread()!=iPrimaryMedia->iDfcQ->iThread,LOCM_FAULT());	// that would lock up the system, thus better die now
  3851 	__ASSERT_ALWAYS(aReq,LOCM_FAULT());
  3863 	__ASSERT_ALWAYS(aReq,LOCM_FAULT());
  3852 	__ASSERT_CRITICAL
  3864 	__ASSERT_CRITICAL
  3991 		m.RemoteThread()=NULL;
  4003 		m.RemoteThread()=NULL;
  3992 		m.Pos()=offset;
  4004 		m.Pos()=offset;
  3993 		m.Length()=Int64(size);
  4005 		m.Length()=Int64(size);
  3994 		m.RemoteDes()=(TAny*)aBuffer;
  4006 		m.RemoteDes()=(TAny*)aBuffer;
  3995 		m.RemoteDesOffset()=0;		// pre-aligned
  4007 		m.RemoteDesOffset()=0;		// pre-aligned
  3996 		m.DriverFlags()=0;
  4008 		m.DriverFlags() = 0;
       
  4009 		if (aPhysAddr)
       
  4010 		    m.Flags() |= TLocDrvRequest::EPhysAddrOnly;
       
  4011 
  3997 		__KTRACE_OPT2(KLOCDRV,KLOCDPAGING,Kern::Printf("ReqId=%d, Pos=0x%lx, Len=0x%lx, remote Des 0x%x",m.Id(),m.Pos(),m.Length(),m.RemoteDes()));
  4012 		__KTRACE_OPT2(KLOCDRV,KLOCDPAGING,Kern::Printf("ReqId=%d, Pos=0x%lx, Len=0x%lx, remote Des 0x%x",m.Id(),m.Pos(),m.Length(),m.RemoteDes()));
  3998 		OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DMEDIAPAGINGDEVICE_READ2, "reqId=%d; position=0x%lx; length=0x%x; remote Des=0x%x", (TInt) m.Id(), (TUint) m.Pos(), (TUint) m.Length(), (TUint) m.RemoteDes());
  4013 		OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DMEDIAPAGINGDEVICE_READ2, "reqId=%d; position=0x%lx; length=0x%x; remote Des=0x%x", (TInt) m.Id(), (TUint) m.Pos(), (TUint) m.Length(), (TUint) m.RemoteDes());
  3999 		
  4014 		
  4000 		__ASSERT_DEBUG(iPrimaryMedia->iBody, LOCM_FAULT());
  4015 		__ASSERT_DEBUG(iPrimaryMedia->iBody, LOCM_FAULT());
  4001 		TInt mediaChanges = iPrimaryMedia->iBody->iMediaChanges;
  4016 		TInt mediaChanges = iPrimaryMedia->iBody->iMediaChanges;
  4039 	OstTraceFunctionExitExt( DMEDIAPAGINGDEVICE_READ_EXIT2, this, retVal );
  4054 	OstTraceFunctionExitExt( DMEDIAPAGINGDEVICE_READ_EXIT2, this, retVal );
  4040 	return retVal;
  4055 	return retVal;
  4041 	}
  4056 	}
  4042 
  4057 
  4043 TInt DMediaPagingDevice::Write(TThreadMessage* aReq,TLinAddr aBuffer,TUint aOffset,TUint aSize,TBool aBackground)
  4058 TInt DMediaPagingDevice::Write(TThreadMessage* aReq,TLinAddr aBuffer,TUint aOffset,TUint aSize,TBool aBackground)
  4044 	{
  4059     {
       
  4060     return BaseWrite(aReq,(TUint32)aBuffer,aOffset,aSize,aBackground,EFalse);
       
  4061     }
       
  4062 
       
  4063 TInt DMediaPagingDevice::WritePhysical(TThreadMessage* aReq, TPhysAddr* aPageArray, TUint aPageCount, TUint aOffset, TBool aBackground)
       
  4064 	{
       
  4065     TUint adjSize = (aPageCount << iPrimaryMedia->iBody->iPageSizeLog2) >> iReadUnitShift; // translate to Read Units
       
  4066     return BaseWrite(aReq,(TUint32)aPageArray,aOffset,adjSize,aBackground,ETrue);
       
  4067 	}
       
  4068 
       
  4069 TInt DMediaPagingDevice::BaseWrite(TThreadMessage* aReq,TUint32 aBuffer,TUint aOffset,TUint aSize,TBool aBackground, TBool aPhysAddr)
       
  4070     {
  4045 	OstTraceFunctionEntry1( DMEDIAPAGINGDEVICE_WRITE_ENTRY, this );
  4071 	OstTraceFunctionEntry1( DMEDIAPAGINGDEVICE_WRITE_ENTRY, this );
  4046 	__ASSERT_ALWAYS(NKern::CurrentThread()!=iPrimaryMedia->iDfcQ->iThread,LOCM_FAULT());	// that would lock up the system, thus better die now
  4072 	__ASSERT_ALWAYS(NKern::CurrentThread()!=iPrimaryMedia->iDfcQ->iThread,LOCM_FAULT());	// that would lock up the system, thus better die now
  4047 	__ASSERT_ALWAYS(aReq,LOCM_FAULT());
  4073 	__ASSERT_ALWAYS(aReq,LOCM_FAULT());
  4048 	__ASSERT_CRITICAL
  4074 	__ASSERT_CRITICAL
  4049 
  4075 
  4099 	// Write to the media and allow for retries in the unlikely event of an error.
  4125 	// Write to the media and allow for retries in the unlikely event of an error.
  4100 	const TInt KPageOutRetries = 5;
  4126 	const TInt KPageOutRetries = 5;
  4101 	TInt retVal = KErrGeneral;
  4127 	TInt retVal = KErrGeneral;
  4102 	for (TInt i=0; retVal != KErrNone && i < KPageOutRetries; i++)
  4128 	for (TInt i=0; retVal != KErrNone && i < KPageOutRetries; i++)
  4103 		{
  4129 		{
  4104 		m.Flags() = TLocDrvRequest::EPaging | TLocDrvRequest::EDataPaging | (aBackground ? TLocDrvRequest::EBackgroundPaging : 0);
  4130 		m.Flags() = TLocDrvRequest::EPaging | 
       
  4131                     TLocDrvRequest::EDataPaging | 
       
  4132                     (aBackground ? TLocDrvRequest::EBackgroundPaging : 0) |
       
  4133                     (aPhysAddr ? TLocDrvRequest::EPhysAddrOnly : 0);
  4105 
  4134 
  4106 		m.Id() = DLocalDrive::EWrite;
  4135 		m.Id() = DLocalDrive::EWrite;
  4107 		m.Drive() = TheDrives[iDataPagingDriveNumber];
  4136 		m.Drive() = TheDrives[iDataPagingDriveNumber];
  4108 
  4137 
  4109 		m.RemoteThread()=NULL;
  4138 		m.RemoteThread()=NULL;
  4110 		m.Pos()=offset;
  4139 		m.Pos()=offset;
  4111 		m.Length()=Int64(size);
  4140 		m.Length()=Int64(size);
  4112 		m.RemoteDes()=(TAny*)aBuffer;
  4141 		m.RemoteDes()=(TAny*)aBuffer;
  4113 		m.RemoteDesOffset()=0;		// pre-aligned
  4142 		m.RemoteDesOffset()=0;		// pre-aligned
  4114 		m.DriverFlags()=0;
  4143 		m.DriverFlags() = 0;        
       
  4144 
  4115 		__KTRACE_OPT2(KLOCDRV,KLOCDPAGING,Kern::Printf("ReqId=%d, Pos=0x%lx, Len=0x%lx, remote Des 0x%x",m.Id(),m.Pos(),m.Length(),m.RemoteDes()));
  4145 		__KTRACE_OPT2(KLOCDRV,KLOCDPAGING,Kern::Printf("ReqId=%d, Pos=0x%lx, Len=0x%lx, remote Des 0x%x",m.Id(),m.Pos(),m.Length(),m.RemoteDes()));
  4116 		OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DMEDIAPAGINGDEVICE_WRITE2, "reqId=%d; position=0x%lx; length=0x%lx; remote Des=0x%x", (TInt) m.Id(), (TUint) m.Pos(), (TUint) m.Length(), (TUint) m.RemoteDes());
  4146 		OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DMEDIAPAGINGDEVICE_WRITE2, "reqId=%d; position=0x%lx; length=0x%lx; remote Des=0x%x", (TInt) m.Id(), (TUint) m.Pos(), (TUint) m.Length(), (TUint) m.RemoteDes());
  4117 		
  4147 		
  4118 		__ASSERT_DEBUG(iPrimaryMedia->iBody, LOCM_FAULT());
  4148 		__ASSERT_DEBUG(iPrimaryMedia->iBody, LOCM_FAULT());
  4119 		TInt mediaChanges = iPrimaryMedia->iBody->iMediaChanges;
  4149 		TInt mediaChanges = iPrimaryMedia->iBody->iMediaChanges;
  4818 		__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Unsupported paging type, exiting"));
  4848 		__KTRACE_OPT2(KBOOT,KLOCDPAGING,Kern::Printf("Unsupported paging type, exiting"));
  4819 		OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT1, "< Unsupported paging type; KErrArgument");
  4849 		OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT1, "< Unsupported paging type; KErrArgument");
  4820 		return KErrArgument;
  4850 		return KErrArgument;
  4821 		}
  4851 		}
  4822 
  4852 
  4823 
       
  4824 
       
  4825 	for(i=0; i<KMaxLocalDrives; i++)
  4853 	for(i=0; i<KMaxLocalDrives; i++)
  4826 		{
  4854 		{
  4827 		if (ThePagingDevices[i] == NULL)
  4855 		if (ThePagingDevices[i] == NULL)
  4828 			continue;
  4856 			continue;
  4829 		if ((ThePagingDevices[i]->iType&DPagingDevice::ERom) &&	(aPagingType & DPagingDevice::ERom))
  4857 		if ((ThePagingDevices[i]->iType&DPagingDevice::ERom) &&	(aPagingType & DPagingDevice::ERom))
  4897 	TInt firstLocalDriveNumber = KErrNotFound; 
  4925 	TInt firstLocalDriveNumber = KErrNotFound; 
  4898 	TInt romPagingDriveNumber = KErrNotFound;
  4926 	TInt romPagingDriveNumber = KErrNotFound;
  4899 
  4927 
  4900 	TInt dataPagingDriveNumber = KErrNotFound;
  4928 	TInt dataPagingDriveNumber = KErrNotFound;
  4901 	TInt swapSize = 0;
  4929 	TInt swapSize = 0;
       
  4930 	TInt blockSize = 0;
       
  4931 	TUint16 flags = 0;
  4902 
  4932 
  4903 	// find the local drive assocated with the primary media
  4933 	// find the local drive assocated with the primary media
  4904 	for (i=0; i<KMaxLocalDrives; ++i)
  4934 	for (i=0; i<KMaxLocalDrives; ++i)
  4905 		{
  4935 		{
  4906 		if(TheDrives[i] && TheDrives[i]->iPrimaryMedia == aPrimaryMedia)
  4936 		if(TheDrives[i] && TheDrives[i]->iPrimaryMedia == aPrimaryMedia)
  4927 			return KErrNotReady;
  4957 			return KErrNotReady;
  4928 			}
  4958 			}
  4929 
  4959 
  4930 
  4960 
  4931 		TLocDrvRequest m;
  4961 		TLocDrvRequest m;
       
  4962         TBuf8<KMaxLocalDriveCapsLength> capsBuf;
       
  4963         
  4932 		memclr(&m, sizeof(m));
  4964 		memclr(&m, sizeof(m));
  4933 		
  4965 		
  4934 
       
  4935 		// Get the Caps from the device. NB for MMC/SD we may need to retry as some PSLs start up
  4966 		// Get the Caps from the device. NB for MMC/SD we may need to retry as some PSLs start up
  4936 		// in "door open" or "media not present" state which can result in the cancellation of requests
  4967 		// in "door open" or "media not present" state which can result in the cancellation of requests
  4937 		TInt i;
  4968 		TInt i;
  4938 		const TInt KRetries = 5;
  4969 		const TInt KRetries = 5;
  4939 		TInt r = KErrNotReady;
  4970 		TInt r = KErrNotReady;
  4940 		for (i=0; r == KErrNotReady && i < KRetries; i++)
  4971 		for (i=0; r == KErrNotReady && i < KRetries; i++)
  4941 			{
  4972 			{
  4942 			TBuf8<KMaxLocalDriveCapsLength> capsBuf;
       
  4943 			capsBuf.SetMax();
  4973 			capsBuf.SetMax();
  4944 			capsBuf.FillZ();
  4974 			capsBuf.FillZ();
  4945 			m.Drive() = TheDrives[firstLocalDriveNumber];
  4975 			m.Drive() = TheDrives[firstLocalDriveNumber];
  4946 			m.Id() = DLocalDrive::ECaps;
  4976 			m.Id() = DLocalDrive::ECaps;
  4947 			m.RemoteDes() = (TAny*)capsBuf.Ptr();	// overload this
  4977 			m.RemoteDes() = (TAny*)capsBuf.Ptr();	// overload this
  4959             // Media driver failure; media maybe recoverable after boot.
  4989             // Media driver failure; media maybe recoverable after boot.
  4960             // Can't register any page drives so return not supported.
  4990             // Can't register any page drives so return not supported.
  4961 			return KErrNotSupported;
  4991 			return KErrNotSupported;
  4962 		    }
  4992 		    }
  4963 
  4993 
       
  4994 		TLocalDriveCapsV6& caps = *(TLocalDriveCapsV6*)capsBuf.Ptr();
       
  4995 		blockSize = caps.iBlockSize;
       
  4996 		
  4964 		TLocDrv* drive;
  4997 		TLocDrv* drive;
  4965 		for (i=0; i<KMaxLocalDrives; ++i)
  4998 		for (i=0; i<KMaxLocalDrives; ++i)
  4966 			{
  4999 			{
  4967 			drive = TheDrives[i];
  5000 			drive = TheDrives[i];
  4968 			if(drive && drive->iPrimaryMedia == aPrimaryMedia)
  5001 			if(drive && drive->iPrimaryMedia == aPrimaryMedia)
  4980 					{
  5013 					{
  4981 					__KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found swap partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen)));
  5014 					__KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("Found swap partition on local drive %d, size %x", i, I64LOW(drive->iPartitionLen)));
  4982 					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) );			
  5015 					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) );			
  4983 					dataPagingDriveNumber = i;
  5016 					dataPagingDriveNumber = i;
  4984 					swapSize = drive->iPartitionLen >> aReadShift;
  5017 					swapSize = drive->iPartitionLen >> aReadShift;
       
  5018 					
       
  5019 			        // Mark Paging Device capable of utilising physical addresss only accesses
       
  5020 			        if (drive->iDmaHelper)
       
  5021 			            flags |= DPagingDevice::ESupportsPhysicalAccess;  
  4985 					}
  5022 					}
  4986 				}
  5023 				}
  4987 			}
  5024 			}
  4988 
  5025 
  4989 		if (swapSize == 0)
  5026 		if (swapSize == 0)
  5004 		OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT_EXIT10, "< RegisterPagingDevice: could not create paging device; KErrNoMemory");
  5041 		OstTrace0(TRACE_FLOW, LOVDRV_REGISTERPAGINGDEVICE_EXIT_EXIT10, "< RegisterPagingDevice: could not create paging device; KErrNoMemory");
  5005 		return KErrNoMemory;
  5042 		return KErrNoMemory;
  5006 		}
  5043 		}
  5007 
  5044 
  5008 	pagingDevice->iType = aPagingType;
  5045 	pagingDevice->iType = aPagingType;
       
  5046 	pagingDevice->iFlags = flags;
  5009 	pagingDevice->iReadUnitShift = aReadShift;
  5047 	pagingDevice->iReadUnitShift = aReadShift;
  5010 
  5048 
  5011 	pagingDevice->iFirstLocalDriveNumber = firstLocalDriveNumber;
  5049 	pagingDevice->iFirstLocalDriveNumber = firstLocalDriveNumber;
  5012 	pagingDevice->iRomPagingDriveNumber = romPagingDriveNumber;
  5050 	pagingDevice->iRomPagingDriveNumber = romPagingDriveNumber;
  5013 
  5051 
  5014 	pagingDevice->iDataPagingDriveNumber = dataPagingDriveNumber;
  5052 	pagingDevice->iDataPagingDriveNumber = dataPagingDriveNumber;
  5015 	pagingDevice->iSwapSize = swapSize;
  5053 	pagingDevice->iSwapSize = swapSize;
       
  5054 		
       
  5055 	pagingDevice->iPreferredWriteShift = (blockSize) ? __e32_find_ms1_32(blockSize) : 0;
  5016 
  5056 
  5017 #ifdef __DEBUG_DEMAND_PAGING__
  5057 #ifdef __DEBUG_DEMAND_PAGING__
  5018 	Kern::Printf("PagingDevice :");
  5058 	Kern::Printf("PagingDevice :");
  5019 	Kern::Printf("iType 0x%x\n", pagingDevice->iType);
  5059 	Kern::Printf("iType 0x%x\n", pagingDevice->iType);
       
  5060 	Kern::Printf("iFlags 0x%x\n", pagingDevice->iFlags);
  5020 	Kern::Printf("iReadUnitShift 0x%x\n", pagingDevice->iReadUnitShift);
  5061 	Kern::Printf("iReadUnitShift 0x%x\n", pagingDevice->iReadUnitShift);
  5021 	Kern::Printf("iFirstLocalDriveNumber 0x%x\n", pagingDevice->iFirstLocalDriveNumber);
  5062 	Kern::Printf("iFirstLocalDriveNumber 0x%x\n", pagingDevice->iFirstLocalDriveNumber);
  5022 	Kern::Printf("iRomPagingDriveNumber 0x%x\n", pagingDevice->iRomPagingDriveNumber);
  5063 	Kern::Printf("iRomPagingDriveNumber 0x%x\n", pagingDevice->iRomPagingDriveNumber);
  5023 	Kern::Printf("iDataPagingDriveNumber 0x%x\n", pagingDevice->iDataPagingDriveNumber);
  5064 	Kern::Printf("iDataPagingDriveNumber 0x%x\n", pagingDevice->iDataPagingDriveNumber);
  5024 	Kern::Printf("iSwapSize 0x%x\n", pagingDevice->iSwapSize);
  5065 	Kern::Printf("iSwapSize 0x%x\n", pagingDevice->iSwapSize);
       
  5066 	Kern::Printf("iPreferredWriteShift 0x%x\n", pagingDevice->iPreferredWriteShift);
  5025 #endif
  5067 #endif
  5026 
  5068 
  5027 
  5069 
  5028 	// This table is indexed by DPagingDevice::TType
  5070 	// This table is indexed by DPagingDevice::TType
  5029 	const char* DeviceName[] = 
  5071 	const char* DeviceName[] =