[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Problem with external dma and linked lists.



An eop in the output DMA descriptor will cause the external DMA channel 
to stop after the descriptor has been fully processed. So, if 
you have eop set in the first descriptor, the external DMA channel
will stop after the first descriptor. 

One solution could be to not set eop in the output DMA descriptor
(and wait is not needed either, although it does no harm).

Hope this helps

Per Zander

On Mon, 5 May 2003, Arne Bockholdt wrote:

> Hi,
> 
> I've got a problem with our driver that uses the external dma channel 0.
> Here a description of the problem : 
> 
> I try to setup a linked list for output transfers. The driver works
> perfectly when there is only one descriptor available to the dma
> controller. When I try to setup a linked list, the output channel 0 stops
> after the first descriptor.  Here the content of the dma registers in the
> interrupt routine that will be called after the first packet has been
> processed. 
> 
> Altera ACEX 1k Adding descriptor to EMPTY queue
> Altera ACEX 1k Added descriptor = 0x40e8d200
> Altera ACEX 1k Adding descriptor to queue
> Altera ACEX 1k Added descriptor = 0x40e8d280
> 
> <interrupt>
> 
> Altera ACEX 1k Bytes send = 32760, Bytes left = 32696
> Altera ACEX 1k Bytes in FIFO = 64
> Altera ACEX 1k CH4 DESCR = 0x40e8d280
> Altera ACEX 1k CH4 FIRST = 0x40e8d280
> Altera ACEX 1k CH4 NEXT = 0x0
> Altera ACEX 1k CH4 Status = 0x3
> Altera ACEX 1k DMA0 Status = 0x0
> 
> I try to transfer 32760 bytes with the second descriptor. The descriptor
> has been loaded by the dma controller, the address has been updated in CH4
> DESCR register. The dma channel 4 is still running but the external dma
> channel has been stopped.  The linked list seems to be okay, the
> descriptor data has been successfully processed and the register data
> seems to be okay.
> 
> Here the setup of the external dma channel  :
> 
> 			IO_STATE (R_EXT_DMA_0_CMD, cnt, disable) |
> 			IO_STATE (R_EXT_DMA_0_CMD, rqpol, ahigh) |
> 			IO_STATE (R_EXT_DMA_0_CMD, apol, ahigh) |
> 			IO_STATE (R_EXT_DMA_0_CMD, rq_ack, handsh) |
> 			IO_STATE (R_EXT_DMA_0_CMD, wid, word) |
> 			IO_STATE (R_EXT_DMA_0_CMD, dir, output) |
> 			IO_STATE (R_EXT_DMA_0_CMD, run, start) |
> 			nCount >> 1;
> 
> The counter is disabled, the controller works in handshake mode.
> 
> Here the code that adds a new descriptor to the linked list : 
> 
> 		g_pDmaDescr = 	(etrax_dma_descr*) kmalloc( sizeof( etrax_dma_descr ),
> GFP_KERNEL );
> 	
> 		if( g_pDmaDescr == NULL )
> 			return -ENOMEM;
> 
> 		/* Clear descriptor struct */
> 
> 		memset( g_pDmaDescr, 0, sizeof( etrax_dma_descr ));
> 
> 		/* Fill out DMA descriptor */
> 
> 		g_pDmaDescr->sw_len 	= nCount;
> 		g_pDmaDescr->ctrl	= d_eol | d_eop | d_wait;
> 		g_pDmaDescr->next	= 0;
> 		g_pDmaDescr->hw_len 	= 0;
> 		g_pDmaDescr->status 	= 0;
> 		g_pDmaDescr->buf 	= virt_to_phys( pBuffer );
> 
> 
> 		g_pLastDmaDescr->next = virt_to_phys( g_pDmaDescr );
> 
> 		/* Clear last decriptor flag */
> 
> 		g_pLastDmaDescr->ctrl &= ~d_eol;
> 
> 		printk(KERN_ERR "%s Added descriptor = 0x%x\n", FPGA_NAME,
> g_pLastDmaDescr->next );
> 
> 		/* Remember new last descriptor */
> 
> 		g_pLastDmaDescr = g_pDmaDescr;
> 
> 		/* Restart DMA channel */
> 
> 		*R_DMA_CH4_CMD 		= IO_STATE( R_DMA_CH4_CMD, cmd, restart );
> 
> 
> g_pLastDmaDescr is a static pointer to the last descriptor that has been
> transfered to the dma controller.
> 
> Do I miss something ? After processing the link list, the dma controller
> needs to be resetted for further operation. 
> 
> Thank you in advance,
> 
> 	Arne Bockholdt
> 
> Dipl. Inform. Arne Bockholdt
> REA Elektronik GmbH
> Teichwiesenstr. 1
> 64367 Mühltal-Waschenbach
> Tel. +49 (0) 6154 / 638-115, Fax -195
> ABockholdt@xxxxxxx.de
>