xilinx_dma_start_transfer() locally buffered the tail segment of the pending list, then it operated over the head. However In case of a 1-length descriptor list, where head and tail are the same, the tail segment changes. The local buffering at the beginning is thus broken. This patch fixes this. Signed-off-by: Andrea Merello <andrea.merello@xxxxxxxxx> --- drivers/dma/xilinx/xilinx_dma.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index b99094c..4ae2c10 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -1206,11 +1206,7 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) } head_desc = list_first_entry(&chan->pending_list, - struct xilinx_dma_tx_descriptor, node); - tail_desc = list_last_entry(&chan->pending_list, - struct xilinx_dma_tx_descriptor, node); - tail_segment = list_last_entry(&tail_desc->segments, - struct xilinx_axidma_tx_segment, node); + struct xilinx_dma_tx_descriptor, node); if (chan->has_sg && !chan->xdev->mcdma) { old_head = list_first_entry(&head_desc->segments, @@ -1223,8 +1219,18 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) list_replace_init(&old_head->node, &new_head->node); chan->seg_v = old_head; + tail_desc = list_last_entry(&chan->pending_list, + struct xilinx_dma_tx_descriptor, node); + tail_segment = list_last_entry(&tail_desc->segments, + struct xilinx_axidma_tx_segment, node); + tail_segment->hw.next_desc = chan->seg_v->phys; head_desc->async_tx.phys = new_head->phys; + } else { + tail_desc = list_last_entry(&chan->pending_list, + struct xilinx_dma_tx_descriptor, node); + tail_segment = list_last_entry(&tail_desc->segments, + struct xilinx_axidma_tx_segment, node); } reg = dma_ctrl_read(chan, XILINX_DMA_REG_DMACR); -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe dmaengine" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html