Commit c7d812e3 authored by Marek Vasut's avatar Marek Vasut Committed by Vinod Koul
Browse files

dmaengine: xilinx: xilinx_dma: Fix unmasked residue subtraction



The segment .control and .status fields both contain top bits which are
not part of the buffer size, the buffer size is located only in the bottom
max_buffer_len bits. To avoid interference from those top bits, mask out
the size using max_buffer_len first, and only then subtract the values.

Fixes: a575d0b4 ("dmaengine: xilinx_dma: Introduce xilinx_dma_get_residue")
Signed-off-by: default avatarMarek Vasut <marex@nabladev.com>
Link: https://patch.msgid.link/20260316222530.163815-1-marex@nabladev.com


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent f61d1459
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -997,16 +997,16 @@ static u32 xilinx_dma_get_residue(struct xilinx_dma_chan *chan,
					      struct xilinx_cdma_tx_segment,
					      node);
			cdma_hw = &cdma_seg->hw;
			residue += (cdma_hw->control - cdma_hw->status) &
				   chan->xdev->max_buffer_len;
			residue += (cdma_hw->control & chan->xdev->max_buffer_len) -
			           (cdma_hw->status & chan->xdev->max_buffer_len);
		} else if (chan->xdev->dma_config->dmatype ==
			   XDMA_TYPE_AXIDMA) {
			axidma_seg = list_entry(entry,
						struct xilinx_axidma_tx_segment,
						node);
			axidma_hw = &axidma_seg->hw;
			residue += (axidma_hw->control - axidma_hw->status) &
				   chan->xdev->max_buffer_len;
			residue += (axidma_hw->control & chan->xdev->max_buffer_len) -
			           (axidma_hw->status & chan->xdev->max_buffer_len);
		} else {
			aximcdma_seg =
				list_entry(entry,
@@ -1014,8 +1014,8 @@ static u32 xilinx_dma_get_residue(struct xilinx_dma_chan *chan,
					   node);
			aximcdma_hw = &aximcdma_seg->hw;
			residue +=
				(aximcdma_hw->control - aximcdma_hw->status) &
				chan->xdev->max_buffer_len;
				(aximcdma_hw->control & chan->xdev->max_buffer_len) -
				(aximcdma_hw->status & chan->xdev->max_buffer_len);
		}
	}