kernel/eka/drivers/dma/dma2_pil.cpp
changeset 231 75252ea6123b
parent 199 189ece41fa29
child 243 c7a0ce20c48c
equal deleted inserted replaced
202:9aca3be14c27 231:75252ea6123b
  1861 
  1861 
  1862 	// Append request to queue and link new descriptor list to existing one.
  1862 	// Append request to queue and link new descriptor list to existing one.
  1863 	iChannel.Wait();
  1863 	iChannel.Wait();
  1864 
  1864 
  1865 	TUint32 req_count = iChannel.iQueuedRequests++;
  1865 	TUint32 req_count = iChannel.iQueuedRequests++;
  1866 	if (req_count == 0)
  1866 	if (iChannel.iCallQueuedRequestFn)
  1867 		{
  1867 		{
  1868 		iChannel.Signal();
  1868 		if (req_count == 0)
  1869 		iChannel.QueuedRequestCountChanged();
  1869 			{
  1870 		iChannel.Wait();
  1870 			iChannel.Signal();
       
  1871 			iChannel.QueuedRequestCountChanged();
       
  1872 			iChannel.Wait();
       
  1873 			}
  1871 		}
  1874 		}
  1872 
  1875 
  1873 	TInt r = KErrGeneral;
  1876 	TInt r = KErrGeneral;
  1874 	const TBool ch_isr_cb = __e32_atomic_load_acq32(&iChannel.iIsrCbRequest);
  1877 	const TBool ch_isr_cb = __e32_atomic_load_acq32(&iChannel.iIsrCbRequest);
  1875 	if (ch_isr_cb)
  1878 	if (ch_isr_cb)
  1881 		__KTRACE_OPT(KPANIC, Kern::Printf("An ISR cb request exists - not queueing"));
  1884 		__KTRACE_OPT(KPANIC, Kern::Printf("An ISR cb request exists - not queueing"));
  1882 		// Undo the request count increment...
  1885 		// Undo the request count increment...
  1883 		req_count = --iChannel.iQueuedRequests;
  1886 		req_count = --iChannel.iQueuedRequests;
  1884 		__DMA_INVARIANT();
  1887 		__DMA_INVARIANT();
  1885 		iChannel.Signal();
  1888 		iChannel.Signal();
  1886 		if (req_count == 0)
  1889 		if (iChannel.iCallQueuedRequestFn)
  1887 			{
  1890 			{
  1888 			iChannel.QueuedRequestCountChanged();
  1891 			if (req_count == 0)
       
  1892 				{
       
  1893 				iChannel.QueuedRequestCountChanged();
       
  1894 				}
  1889 			}
  1895 			}
  1890 		}
  1896 		}
  1891 	else if (iIsrCb && !iChannel.IsQueueEmpty())
  1897 	else if (iIsrCb && !iChannel.IsQueueEmpty())
  1892 		{
  1898 		{
  1893 		// Client mustn't try to queue an ISR callback request whilst any
  1899 		// Client mustn't try to queue an ISR callback request whilst any
  1897 		__KTRACE_OPT(KPANIC, Kern::Printf("Request queue not empty - not queueing"));
  1903 		__KTRACE_OPT(KPANIC, Kern::Printf("Request queue not empty - not queueing"));
  1898 		// Undo the request count increment...
  1904 		// Undo the request count increment...
  1899 		req_count = --iChannel.iQueuedRequests;
  1905 		req_count = --iChannel.iQueuedRequests;
  1900 		__DMA_INVARIANT();
  1906 		__DMA_INVARIANT();
  1901 		iChannel.Signal();
  1907 		iChannel.Signal();
  1902 		if (req_count == 0)
  1908 		if (iChannel.iCallQueuedRequestFn)
  1903 			{
  1909 			{
  1904 			iChannel.QueuedRequestCountChanged();
  1910 			if (req_count == 0)
       
  1911 				{
       
  1912 				iChannel.QueuedRequestCountChanged();
       
  1913 				}
  1905 			}
  1914 			}
  1906 		}
  1915 		}
  1907 	else if (iChannel.iIsrDfc & (TUint32)TDmaChannel::KCancelFlagMask)
  1916 	else if (iChannel.iIsrDfc & (TUint32)TDmaChannel::KCancelFlagMask)
  1908 		{
  1917 		{
  1909 		__KTRACE_OPT(KPANIC, Kern::Printf("Channel requests cancelled - not queueing"));
  1918 		__KTRACE_OPT(KPANIC, Kern::Printf("Channel requests cancelled - not queueing"));
  1910 		// Someone is cancelling all requests - undo the request count increment...
  1919 		// Someone is cancelling all requests - undo the request count increment...
  1911 		req_count = --iChannel.iQueuedRequests;
  1920 		req_count = --iChannel.iQueuedRequests;
  1912 		__DMA_INVARIANT();
  1921 		__DMA_INVARIANT();
  1913 		iChannel.Signal();
  1922 		iChannel.Signal();
  1914 		if (req_count == 0)
  1923 		if (iChannel.iCallQueuedRequestFn)
  1915 			{
  1924 			{
  1916 			iChannel.QueuedRequestCountChanged();
  1925 			if (req_count == 0)
       
  1926 				{
       
  1927 				iChannel.QueuedRequestCountChanged();
       
  1928 				}
  1917 			}
  1929 			}
  1918 		}
  1930 		}
  1919 	else
  1931 	else
  1920 		{
  1932 		{
  1921 		iQueued = ETrue;
  1933 		iQueued = ETrue;
  2273 	  iAvailDesCount(0),
  2285 	  iAvailDesCount(0),
  2274 	  iIsrDfc(0),
  2286 	  iIsrDfc(0),
  2275 	  iReqQ(),
  2287 	  iReqQ(),
  2276 	  iReqCount(0),
  2288 	  iReqCount(0),
  2277 	  iQueuedRequests(0),
  2289 	  iQueuedRequests(0),
       
  2290 	  iCallQueuedRequestFn(ETrue),
  2278 	  iCancelInfo(NULL),
  2291 	  iCancelInfo(NULL),
  2279 	  iRedoRequest(EFalse),
  2292 	  iRedoRequest(EFalse),
  2280 	  iIsrCbRequest(EFalse)
  2293 	  iIsrCbRequest(EFalse)
  2281 	{
  2294 	{
  2282 	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::TDmaChannel =0x%08X", this));
  2295 	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::TDmaChannel =0x%08X", this));
  2474 
  2487 
  2475  	NKern::ThreadLeaveCS();
  2488  	NKern::ThreadLeaveCS();
  2476 
  2489 
  2477 	// Only call PSL if there were requests queued when we entered AND there
  2490 	// Only call PSL if there were requests queued when we entered AND there
  2478 	// are now no requests left on the queue.
  2491 	// are now no requests left on the queue.
  2479 	if ((req_count_before != 0) && (req_count_after == 0))
  2492 	if (iCallQueuedRequestFn)
  2480 		{
  2493 		{
  2481 		QueuedRequestCountChanged();
  2494 		if ((req_count_before != 0) && (req_count_after == 0))
       
  2495 			{
       
  2496 			QueuedRequestCountChanged();
       
  2497 			}
  2482 		}
  2498 		}
  2483 
  2499 
  2484 	__DMA_INVARIANT();
  2500 	__DMA_INVARIANT();
  2485 	}
  2501 	}
  2486 
  2502 
  2788 		}
  2804 		}
  2789 
  2805 
  2790 	// Only call PSL if there were requests queued when we entered AND there
  2806 	// Only call PSL if there were requests queued when we entered AND there
  2791 	// are now no requests left on the queue (after also having executed all
  2807 	// are now no requests left on the queue (after also having executed all
  2792 	// client callbacks).
  2808 	// client callbacks).
  2793 	if ((req_count_before != 0) && (req_count_after == 0))
  2809 	if (iCallQueuedRequestFn)
  2794 		{
  2810 		{
  2795 		QueuedRequestCountChanged();
  2811 		if ((req_count_before != 0) && (req_count_after == 0))
       
  2812 			{
       
  2813 			QueuedRequestCountChanged();
       
  2814 			}
  2796 		}
  2815 		}
  2797 
  2816 
  2798 	__DMA_INVARIANT();
  2817 	__DMA_INVARIANT();
  2799 	}
  2818 	}
  2800 
  2819 
  2847 
  2866 
  2848 
  2867 
  2849 /** PSL may override */
  2868 /** PSL may override */
  2850 void TDmaChannel::QueuedRequestCountChanged()
  2869 void TDmaChannel::QueuedRequestCountChanged()
  2851 	{
  2870 	{
  2852 #ifdef _DEBUG
  2871 	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::QueuedRequestCountChanged(): "
       
  2872 									"disabling further calls"));
  2853 	Wait();
  2873 	Wait();
  2854 	__KTRACE_OPT(KDMA,
  2874 	iCallQueuedRequestFn = EFalse;
  2855 				 Kern::Printf("TDmaChannel::QueuedRequestCountChanged() %d",
       
  2856 							  iQueuedRequests));
       
  2857 	__DMA_ASSERTA(iQueuedRequests >= 0);
       
  2858 	Signal();
  2875 	Signal();
  2859 #endif
       
  2860 	}
  2876 	}
  2861 
  2877 
  2862 
  2878 
  2863 #ifdef _DEBUG
  2879 #ifdef _DEBUG
  2864 void TDmaChannel::Invariant()
  2880 void TDmaChannel::Invariant()