summaryrefslogtreecommitdiff
path: root/drivers/dma/mv_xor.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2008-07-04 07:13:40 (GMT)
committerDan Williams <dan.j.williams@intel.com>2008-07-08 18:59:12 (GMT)
commite1d181efb14a93cf263d6c588a5395518edf3294 (patch)
tree1792d1faa7e344401789bbcfad8102d0d93036e2 /drivers/dma/mv_xor.c
parent848c536a37b8db4e461f14ca15fe29850151c822 (diff)
downloadlinux-e1d181efb14a93cf263d6c588a5395518edf3294.tar.xz
dmaengine: add DMA_COMPL_SKIP_{SRC,DEST}_UNMAP flags to control dma unmap
In some cases client code may need the dma-driver to skip the unmap of source and/or destination buffers. Setting these flags indicates to the driver to skip the unmap step. In this regard async_xor is currently broken in that it allows the destination buffer to be unmapped while an operation is still in progress, i.e. when the number of sources exceeds the hardware channel's maximum (fixed in a subsequent patch). Acked-by: Saeed Bishara <saeed@marvell.com> Acked-by: Maciej Sosnowski <maciej.sosnowski@intel.com> Acked-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/dma/mv_xor.c')
-rw-r--r--drivers/dma/mv_xor.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index 8239cfd..a4e4494 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -308,13 +308,23 @@ mv_xor_run_tx_complete_actions(struct mv_xor_desc_slot *desc,
struct device *dev =
&mv_chan->device->pdev->dev;
u32 len = unmap->unmap_len;
- u32 src_cnt = unmap->unmap_src_cnt;
- dma_addr_t addr = mv_desc_get_dest_addr(unmap);
+ enum dma_ctrl_flags flags = desc->async_tx.flags;
+ u32 src_cnt;
+ dma_addr_t addr;
- dma_unmap_page(dev, addr, len, DMA_FROM_DEVICE);
- while (src_cnt--) {
- addr = mv_desc_get_src_addr(unmap, src_cnt);
- dma_unmap_page(dev, addr, len, DMA_TO_DEVICE);
+ if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
+ addr = mv_desc_get_dest_addr(unmap);
+ dma_unmap_page(dev, addr, len, DMA_FROM_DEVICE);
+ }
+
+ if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
+ src_cnt = unmap->unmap_src_cnt;
+ while (src_cnt--) {
+ addr = mv_desc_get_src_addr(unmap,
+ src_cnt);
+ dma_unmap_page(dev, addr, len,
+ DMA_TO_DEVICE);
+ }
}
desc->group_head = NULL;
}