kernel/eka/drivers/dma/dmapil.cpp
branchRCL_3
changeset 80 597aaf25e343
parent 36 538db54a451d
child 81 e7d2d738d3c2
equal deleted inserted replaced
62:4a8fed1c0ef6 80:597aaf25e343
   859 		Signal();
   859 		Signal();
   860 
   860 
   861 		// release threads doing CancelAll()
   861 		// release threads doing CancelAll()
   862 		waiters->Signal();
   862 		waiters->Signal();
   863 		}
   863 		}
   864 	else if (!error && !iDfc.Queued() && !iReqQ.IsEmpty() && iController->IsIdle(*this))
   864 	else if (!error && iController->IsIdle(*this) && !iReqQ.IsEmpty() && !iDfc.Queued())
   865 		{
   865 		{
   866 		__KTRACE_OPT(KDMA, Kern::Printf("Missed interrupt(s) - draining request queue"));
   866 		// Wait for a bit. If during that time the condition goes away then it
   867 		ResetStateMachine();
   867 		// was a 'spurious missed interrupt', in which case we just do nothing.
   868 
   868 		TBool spurious = EFalse;
   869 		// Move orphaned requests to temporary queue so channel queue can
   869 		const TUint32 nano_secs_per_loop = 1000 * 1000;			// 1ms
   870 		// accept new requests.
   870 		for (TInt i = 5; i > 0; i--)
   871 		SDblQue q;
       
   872 		q.MoveFrom(&iReqQ);
       
   873 
       
   874 		SDblQueLink* pL;
       
   875 		while ((pL = q.GetFirst()) != NULL)
       
   876 			{
   871 			{
   877 			iQueuedRequests--;
   872 			if (!iController->IsIdle(*this))
   878 			DDmaRequest* pR = _LOFF(pL, DDmaRequest, iLink);
       
   879 			__KTRACE_OPT(KDMA, Kern::Printf("Removing request from queue and notifying client"));
       
   880 			pR->OnDeque();
       
   881 			DDmaRequest::TCallback cb = pR->iCb;
       
   882 			TAny* arg = pR->iCbArg;
       
   883 			if (cb)
       
   884 				{
   873 				{
   885 				Signal();
   874 				__KTRACE_OPT(KDMA, Kern::Printf("DMAC no longer idle (i = %d)", i));
   886 				(*cb)(DDmaRequest::EOk, arg);
   875 				spurious = ETrue;
   887 				Wait();
   876 				break;
       
   877 				}
       
   878 			else if (iDfc.Queued())
       
   879 				{
       
   880 				__KTRACE_OPT(KDMA, Kern::Printf("DFC now queued (i = %d)", i));
       
   881 				spurious = ETrue;
       
   882 				break;
       
   883 				}
       
   884 			Kern::NanoWait(nano_secs_per_loop);
       
   885 			}
       
   886 		if (!spurious)
       
   887 			{
       
   888 			__KTRACE_OPT(KDMA,
       
   889 						 Kern::Printf("Missed interrupt(s) - draining request queue on ch %d",
       
   890 									  PslId()));
       
   891 			ResetStateMachine();
       
   892 
       
   893 			// Move orphaned requests to temporary queue so channel queue can
       
   894 			// accept new requests.
       
   895 			SDblQue q;
       
   896 			q.MoveFrom(&iReqQ);
       
   897 
       
   898 			SDblQueLink* pL;
       
   899 			while ((pL = q.GetFirst()) != NULL)
       
   900 				{
       
   901 				iQueuedRequests--;
       
   902 				DDmaRequest* pR = _LOFF(pL, DDmaRequest, iLink);
       
   903 				__KTRACE_OPT(KDMA, Kern::Printf("Removing request from queue and notifying client"));
       
   904 				pR->OnDeque();
       
   905 				DDmaRequest::TCallback cb = pR->iCb;
       
   906 				TAny* arg = pR->iCbArg;
       
   907 				if (cb)
       
   908 					{
       
   909 					Signal();
       
   910 					(*cb)(DDmaRequest::EOk, arg);
       
   911 					Wait();
       
   912 					}
   888 				}
   913 				}
   889 			}
   914 			}
   890 		req_count_after = iQueuedRequests;
   915 		req_count_after = iQueuedRequests;
   891 		Signal();
   916 		Signal();
   892 		}
   917 		}