diff mbox

[2/5] dmaengine: xilinx_dma: fix working on wrong tail segment

Message ID 1484926369-30910-2-git-send-email-andrea.merello@gmail.com (mailing list archive)
State Changes Requested
Headers show

Commit Message

Andrea Merello Jan. 20, 2017, 3:32 p.m. UTC
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@gmail.com>
---
 drivers/dma/xilinx/xilinx_dma.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)
diff mbox

Patch

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);