201015_18
authorhgs
Fri, 23 Apr 2010 22:38:37 +0100
changeset 126 2b2a51c87b12
parent 125 947dd86c44e2
child 127 e408fc570bb5
201015_18
kernel/eka/drivers/dma/dma2_pil.cpp
kernel/eka/drivers/dma/dmapil.cpp
kernel/eka/drivers/locmedia/locmedia.cpp
kernel/eka/include/e32ver.h
kernel/eka/kernel/arm/cipc.cia
kernel/eka/release.txt
kerneltest/e32test/mediaext/d_nfe.cpp
kerneltest/e32test/prime/t_timer.cpp
--- a/kernel/eka/drivers/dma/dma2_pil.cpp	Fri Apr 23 22:32:39 2010 +0100
+++ b/kernel/eka/drivers/dma/dma2_pil.cpp	Fri Apr 23 22:38:37 2010 +0100
@@ -1205,6 +1205,7 @@
 		__KTRACE_OPT(KPANIC, Kern::Printf("An ISR cb request exists - not queueing"));
 		// Undo the request count increment...
 		req_count = --iChannel.iQueuedRequests;
+		__DMA_INVARIANT();
 		iChannel.Signal();
 		if (req_count == 0)
 			{
@@ -1220,6 +1221,7 @@
 		__KTRACE_OPT(KPANIC, Kern::Printf("Request queue not empty - not queueing"));
 		// Undo the request count increment...
 		req_count = --iChannel.iQueuedRequests;
+		__DMA_INVARIANT();
 		iChannel.Signal();
 		if (req_count == 0)
 			{
@@ -1231,6 +1233,7 @@
 		__KTRACE_OPT(KPANIC, Kern::Printf("Channel requests cancelled - not queueing"));
 		// Someone is cancelling all requests - undo the request count increment...
 		req_count = --iChannel.iQueuedRequests;
+		__DMA_INVARIANT();
 		iChannel.Signal();
 		if (req_count == 0)
 			{
@@ -1257,10 +1260,10 @@
 			}
 		iChannel.DoQueue(const_cast<const DDmaRequest&>(*this));
 		r = KErrNone;
+		__DMA_INVARIANT();
 		iChannel.Signal();
 		}
 
-	__DMA_INVARIANT();
 	return r;
 	}
 
@@ -1477,7 +1480,15 @@
 #ifdef _DEBUG
 void DDmaRequest::Invariant()
 	{
-	iChannel.Wait();
+	// This invariant may be called either with,
+	// or without the channel lock already held
+	TBool channelLockAquired=EFalse;
+	if(!iChannel.iLock.HeldByCurrentThread())
+		{
+		iChannel.Wait();
+		channelLockAquired = ETrue;
+		}
+
 	__DMA_ASSERTD(LOGICAL_XOR(iCb, iDmaCb));
 	if (iChannel.iDmacCaps->iAsymHwDescriptors)
 		{
@@ -1512,7 +1523,11 @@
 			__DMA_ASSERTD(iChannel.iController->IsValidHdr(iLastHdr));
 			}
 		}
-	iChannel.Signal();
+
+	if(channelLockAquired)
+			{
+			iChannel.Signal();
+			}
 	}
 #endif
 
--- a/kernel/eka/drivers/dma/dmapil.cpp	Fri Apr 23 22:32:39 2010 +0100
+++ b/kernel/eka/drivers/dma/dmapil.cpp	Fri Apr 23 22:38:37 2010 +0100
@@ -491,20 +491,20 @@
 		*iChannel.iNullPtr = iFirstHdr;
 		iChannel.iNullPtr = &(iLastHdr->iNext);
 		iChannel.DoQueue(*this);
+		__DMA_INVARIANT();
 		iChannel.Signal();
 		}
 	else
 		{
 		// Someone is cancelling all requests...
 		req_count = --iChannel.iQueuedRequests;
+		__DMA_INVARIANT();
 		iChannel.Signal();
 		if (req_count == 0)
 			{
 			iChannel.QueuedRequestCountChanged();
 			}
 		}
-
-	__DMA_INVARIANT();
 	}
 
 EXPORT_C TInt DDmaRequest::ExpandDesList(TInt aCount)
@@ -574,7 +574,15 @@
 
 void DDmaRequest::Invariant()
 	{
-	iChannel.Wait();
+	// This invariant may be called either with,
+	// or without the channel lock already held
+	TBool channelLockAquired=EFalse;
+	if(!iChannel.iLock.HeldByCurrentThread())
+		{
+		iChannel.Wait();
+		channelLockAquired = ETrue;
+		}
+
 	__DMA_ASSERTD(iChannel.IsOpened());
 	__DMA_ASSERTD(0 <= iMaxTransferSize);
 	__DMA_ASSERTD(0 <= iDesCount && iDesCount <= iChannel.iMaxDesCount);
@@ -588,7 +596,11 @@
 		__DMA_ASSERTD(iChannel.iController->IsValidHdr(iFirstHdr));
 		__DMA_ASSERTD(iChannel.iController->IsValidHdr(iLastHdr));
 		}
-	iChannel.Signal();
+
+	if(channelLockAquired)
+		{
+		iChannel.Signal();
+		}
 	}
 
 #endif
--- a/kernel/eka/drivers/locmedia/locmedia.cpp	Fri Apr 23 22:32:39 2010 +0100
+++ b/kernel/eka/drivers/locmedia/locmedia.cpp	Fri Apr 23 22:38:37 2010 +0100
@@ -2500,6 +2500,14 @@
 			{
 			TUint flags = (TUint) m.Pos();
 
+#ifdef __DEMAND_PAGING__
+			// if this is a paging media (ROM,code or data), turn off the KMediaRemountForceMediaChange flag 
+			// as this normally results in a call to DPBusSocket::ForceMediaChange() which effectively disables 
+			// the media for a small time period - which would be disasterous if a paging request arrived
+			if (iBody->iPagingDevice)
+				flags&= ~KMediaRemountForceMediaChange;
+#endif
+
 			// For media extension drivers, send a copy of the request to the next drive in the chain and wait for it. 
 			TLocDrv* drv = m.Drive();
 			if (drv->iNextDrive)
@@ -6150,14 +6158,22 @@
 			TLocDrvRequest m;
 			memclr(&m, sizeof(m));
 
+			// Get the Caps from the device. NB for MMC/SD we may need to retry as there may have been an earlier 
+			// EForceMediaChange request which can result in the cancellation of requests already in the queue
 			TBuf8<KMaxLocalDriveCapsLength> capsBuf;
-			capsBuf.SetMax();
-			capsBuf.FillZ();
-			m.Drive() = attachedDrive;
-			m.Id() = DLocalDrive::ECaps;
-			m.RemoteDes() = (TAny*)capsBuf.Ptr();
-			m.Length() = KMaxLocalDriveCapsLength;
-			TInt r = attachedDrive->iPrimaryMedia->Request(m);
+			TInt i;
+			const TInt KRetries = 5;
+			TInt r = KErrNotReady;
+			for (i=0; r == KErrNotReady && i < KRetries; i++)
+				{
+				capsBuf.SetMax();
+				capsBuf.FillZ();
+				m.Drive() = attachedDrive;
+				m.Id() = DLocalDrive::ECaps;
+				m.RemoteDes() = (TAny*)capsBuf.Ptr();
+				m.Length() = KMaxLocalDriveCapsLength;
+				r = attachedDrive->iPrimaryMedia->Request(m);
+				}
 
 			__KTRACE_OPT2(KBOOT,KLOCDPAGING, Kern::Printf("DMediaDriverExtension::PartitionInfo(ECaps: i %d: r %d ", driveIter.Index(), r));
 			
--- a/kernel/eka/include/e32ver.h	Fri Apr 23 22:32:39 2010 +0100
+++ b/kernel/eka/include/e32ver.h	Fri Apr 23 22:38:37 2010 +0100
@@ -28,7 +28,7 @@
 
 const TInt KE32MajorVersionNumber=2;
 const TInt KE32MinorVersionNumber=0;
-const TInt KE32BuildVersionNumber=3069;
+const TInt KE32BuildVersionNumber=3072;
 
 const TInt KMachineConfigurationMajorVersionNumber=1;
 const TInt KMachineConfigurationMinorVersionNumber=0;
--- a/kernel/eka/kernel/arm/cipc.cia	Fri Apr 23 22:32:39 2010 +0100
+++ b/kernel/eka/kernel/arm/cipc.cia	Fri Apr 23 22:38:37 2010 +0100
@@ -57,7 +57,7 @@
 
 __NAKED__ void ExecHandler::MessageComplete(RMessageK* /*aMsg*/, TInt /*aReason*/)
 	{
-	asm("ldr ip, [r0, #%a0]" : : "i" _FOFF(RMessageK, iFunction));		// get iFunction, as per preprocessor
+	asm("ldr ip, [r0, #%a0]" : : "i" _FOFF(RMessageK, iFunction));				// get iFunction, as per preprocessor
 
 	// Subroutine MessageComplete
 	// Complete an IPC message
@@ -69,65 +69,73 @@
 
 #ifdef BTRACE_CLIENT_SERVER
 	asm("stmfd sp!,{r0,r1,ip,lr}");
-	asm("mov r2,r1");							// arg2 = aReason
-	asm("mov r1,r0");							// arg1 = aMsg
-	asm("ldr r0,_messageCompleteTraceHeader");	// arg0 = header
+	asm("mov r2,r1");															// arg2 = aReason
+	asm("mov r1,r0");															// arg1 = aMsg
+	asm("ldr r0,_messageCompleteTraceHeader");									// arg0 = header
 	asm("bl " CSM_ZN6BTrace4OutXEmmmm);
 	asm("ldmfd sp!,{r0,r1,ip,lr}");
 #endif
 
 	asm("cmp ip, #%a0" : : "i" (RMessage2::EDisConnect));
 	asm("ldreq r0, [r0, #%a0]" : : "i" _FOFF(RMessageK,iSession));
-	asm("beq " CSM_ZN8DSession19CloseFromDisconnectEv );	// if disconnect, do it in C++
-	asm("mov r2, r1 ");					// r2=aReason
+	asm("beq " CSM_ZN8DSession19CloseFromDisconnectEv );						// if disconnect, do it in C++
+
+	asm("mov r2, r1 ");															// r2 = aReason
 	ASM_DEBUG2(Complete,r0,r2);
-	asm("ldr r3, [r0, #%a0]" : : "i" _FOFF(RMessageK, iSession)); 	// r3=iSession
-	
-	asm("subs r1, ip, #%a0" : : "i" (RMessage2::EConnect));		// (m.iFunction == RMessage2::EConnect)?
-	asm("streq r1, [r3, #%a0] " : : "i" _FOFF(DSession, iConnectMsgPtr));	// iSession->iConnectMsgPtr = NULL
-
-	asm("ldr r1, [r3, #%a0]" : : "i" _FOFF(DSession,iAccessCount));	// r1=iSession->iAccessCount	
-	asm("cmp r1, #0 ");					// iAccessCount = 0?
+	asm("ldr r3, [r0, #%a0]" : : "i" _FOFF(RMessageK, iSession)); 				// r3 = iSession
+	asm("subs r1, ip, #%a0" : : "i" (RMessage2::EConnect));						// (m.iFunction == RMessage2::EConnect)?
+	asm("streq r1, [r3, #%a0] " : : "i" _FOFF(DSession, iConnectMsgPtr));		// iSession->iConnectMsgPtr = NULL
+	asm("ldr r1, [r3, #%a0]" : : "i" _FOFF(DSession,iAccessCount));				// r1 = iSession->iAccessCount	
+	asm("cmp r1, #0 ");															// iAccessCount = 0?
 	asm("beq 2f ");
 
-	// if (!s->IsClosing())
-	asm("mov r1, r0");					// r1 = RMessageK ptr
-	asm("ldr r0, [r0, #%a0] " : : "i" _FOFF(RMessageK,iClient));    // r0=iClient
+	// !s->IsClosing()
+	asm("mov r1, r0");															// r1 = RMessageK ptr
+	asm("ldr r0, [r0, #%a0] " : : "i" _FOFF(RMessageK,iClient));    			// r0 = iClient
+	asm("ldrb ip, [r0, #%a0] " : : "i" _FOFF(DThread,iMState));    				// ip = iClient->iMState
+	asm("cmp ip, #%a0" : : "i" (DThread::EDead));								// (iMState == EDead)?
+	asm("beq 1f ");
+
+	// if (!s->IsClosing() && m.iClient->iMState != DThread::EDead)
 	asm("mov ip, #1");
-	asm("str ip, [r1, #%a0]" : : "i" _FOFF(RMessageK, iServerLink.iNext));	// iServerLink.iNext=1
-	asm("b " CSM_ZN4Kern20QueueRequestCompleteEP7DThreadP14TClientRequesti);
+	asm("str ip, [r1, #%a0]" : : "i" _FOFF(RMessageK, iServerLink.iNext));		// iServerLink.iNext=1
+	asm("b " CSM_ZN4Kern20QueueRequestCompleteEP7DThreadP14TClientRequesti);	// tail call
 
-	// if (s->IsClosing())
+	// m.iClient->iMState == DThread::EDead
+	asm("1: ");																	// shuffle RMessageK and iFunction back to expected registers
+	asm("ldr ip, [r1, #%a0]" : : "i" _FOFF(RMessageK, iFunction));				// refetch iFunction
+	asm("mov r0, r1");															// r0 = RMessageK ptr
+
+	// else (closing or dead)
 	asm("2: ");
-	asm("cmp ip, #%a0" : : "i" (RMessage2::EConnect));	// (m.iFunction == RMessage2::EConnect)?
-	asm("beq 4f ");
-	asm("3: ");
-	asm("stmfd sp!, {r0,lr} ");
-	asm("bl " CSM_ZN14TClientRequest5ResetEv);
-	asm("ldmfd sp!, {r0,lr} ");
-	asm("b " CSM_ZN9RMessageK8CloseRefEv);
+	asm("cmp ip, #%a0" : : "i" (RMessage2::EConnect));							// (m.iFunction == RMessage2::EConnect)?
+	asm("bne 3f ");
 
-	asm("4: ");
-	// if closing & connect msg
-	asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie));	// r2=iSession->iSessionCookie
+	// (closing or dead) and it's a connect msg
+	asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie));			// r2=iSession->iSessionCookie
 	asm("teq r2, #0");
 #ifdef _DEBUG
 	asm("beq nosession ");
-	asm("ldr r1, [r3, #%a0] " : : "i" _FOFF(DSession, iServer));		// r1=iSession->iServer
+	asm("ldr r1, [r3, #%a0] " : : "i" _FOFF(DSession, iServer));				// r1=iSession->iServer
 	asm("cmp r1, #0 ");
  	asm("beq noserver ");
-	asm("ldr r2, [r3, #%a0] " : : "i" (_FOFF(DSession, iDisconnectMsgPtr)));  // r2=iSession->iDisconnectMsgPtr
+	asm("ldr r2, [r3, #%a0] " : : "i" (_FOFF(DSession, iDisconnectMsgPtr)));	// r2=iSession->iDisconnectMsgPtr
 	asm("ldr r2, [r2, #%a0] " : : "i" (_FOFF(RMessageK, iServerLink.iNext)));	// r2=iDisconnectMsgPtr->iServerLink.iNext
 	asm("cmp r2, #0 ");
-	asm("beq __FaultMsgCompleteDiscNotSent ");	// die if a session has been created and no disc msg sent
-	asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie));	// r2=iSession->iSessionCookie
+	asm("beq __FaultMsgCompleteDiscNotSent ");									// tail call to die if a session has been created and no disc msg sent
+	asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie));			// r2=iSession->iSessionCookie
 	asm("noserver: ");
 	asm("teq r2, #0");
 	asm("nosession: ");
 #endif //_DEBUG
 	asm("moveq r0, r3 ");
-	asm("beq __SendDiscMsg ");	// if no session object to clean up, send disc msg in C++
-	asm("b 3b ");				// return
+	asm("beq __SendDiscMsg ");													// if no session object to clean up, tail call to send disc msg in C++
+
+	asm("3: ");
+	asm("stmfd sp!, {r0,lr} ");
+	asm("bl " CSM_ZN14TClientRequest5ResetEv);
+	asm("ldmfd sp!, {r0,lr} ");
+	asm("b " CSM_ZN9RMessageK8CloseRefEv);										// tail call
 
 #ifdef BTRACE_CLIENT_SERVER
 	asm("_messageCompleteTraceHeader:");
@@ -358,8 +366,8 @@
 #endif
 	asm("ldr r1, [r1, #%a0]" : : "i" (_FOFF(DThread,iOwningProcess)-_FOFF(DThread,iNThread)));	// r1->process to check
 	asm("bl do_messagek ");
+	asm("bcc 0f ");														// if bad handle, panic
 	asm("ldr ip, [r0, #%a0]" : : "i" _FOFF(RMessageK,iFunction));		// ip = function
-	asm("bcc 0f ");														// if bad handle, panic
 	asm("cmp ip, #%a0" : : "i" ((TInt)RMessage2::EDisConnect));			// check iFunction != RMessage2::EDisConnect
 	asm("ldmnefd sp!, {r4,pc} ");										// if not, return OK
 	asm("0: ");
--- a/kernel/eka/release.txt	Fri Apr 23 22:32:39 2010 +0100
+++ b/kernel/eka/release.txt	Fri Apr 23 22:38:37 2010 +0100
@@ -1,3 +1,30 @@
+Version 2.00.3072
+=================
+(Made by vfebvre 22/04/2010)
+
+1.	migubarr
+	1.	ou1cimx1#356834 Execution of the kernelhwsrv test suites on H4HRP.ARMV5.U*.FMM.MMCPAGE does not complete
+
+
+Version 2.00.3071
+=================
+(Made by vfebvre 21/04/2010)
+
+1.	davegord
+	1.	ou1cimx1#353902 MCL DownloadServerMgr.exe causes phone crash
+
+
+Version 2.00.3070
+=================
+(Made by vfebvre 20/04/2010)
+
+1.	seolney
+	1.	PDEF145220 Fault possible if client deletes DMA request in callback
+
+2.	lanerobe
+	1.	ou1cimx1#352938 E32TEST T_TIMER test failure investigation
+
+
 Version 2.00.3069
 =================
 (Made by vfebvre 20/04/2010)
--- a/kerneltest/e32test/mediaext/d_nfe.cpp	Fri Apr 23 22:32:39 2010 +0100
+++ b/kerneltest/e32test/mediaext/d_nfe.cpp	Fri Apr 23 22:38:37 2010 +0100
@@ -873,6 +873,9 @@
 
 		di.iDriveFinalised = EFalse;	// a remount clears the finalised state
 
+		// Make sure we haven't lost the swap partition
+		__ASSERT_ALWAYS(!(di.iEntry.iPartitionType == KPartitionTypePagedData && aInfo.iEntry[i].iPartitionType != KPartitionTypePagedData), NFE_FAULT());
+
 		// Make a copy of the TPartitionEntry
 		di.iEntry = aInfo.iEntry[i];
 
--- a/kerneltest/e32test/prime/t_timer.cpp	Fri Apr 23 22:32:39 2010 +0100
+++ b/kerneltest/e32test/prime/t_timer.cpp	Fri Apr 23 22:38:37 2010 +0100
@@ -290,16 +290,17 @@
             t2.HomeTime();
             }
         while (t2==t1);
-#if defined(_DEBUG)
-		TDateTime dt=t2.DateTime();
-		test.Printf(_L("%d:%d\r\n"),dt.Second(),dt.MicroSecond());
-#endif
-        test(t2>t1);
+
+		if (t2 <= t1 && t1.MicroSecondsFrom(t2) > TTimeIntervalMicroSeconds(1000)) // HomeTime() only operates at ms precision
+			{
+			test.Printf(_L("Time comparison failed\r\n"));
+			test.Printf(_L("Before: 0x%lx\r\n"), t1.Int64());
+			test.Printf(_L("After:  0x%lx\r\n"), t2.Int64());
+			test(t2>t1);
+			}
+
         t1=t2;
         }
-#if defined(_DEBUG)
-	test.Printf(_L("\r\n"));
-#endif
     }
 
 TInt AtTwice(TAny*)