|
@@ -85,18 +85,28 @@ iop_adma_run_tx_complete_actions(struct iop_adma_desc_slot *desc,
|
|
enum dma_ctrl_flags flags = desc->async_tx.flags;
|
|
enum dma_ctrl_flags flags = desc->async_tx.flags;
|
|
u32 src_cnt;
|
|
u32 src_cnt;
|
|
dma_addr_t addr;
|
|
dma_addr_t addr;
|
|
|
|
+ dma_addr_t dest;
|
|
|
|
|
|
|
|
+ src_cnt = unmap->unmap_src_cnt;
|
|
|
|
+ dest = iop_desc_get_dest_addr(unmap, iop_chan);
|
|
if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
|
|
if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
|
|
- addr = iop_desc_get_dest_addr(unmap, iop_chan);
|
|
|
|
- dma_unmap_page(dev, addr, len, DMA_FROM_DEVICE);
|
|
|
|
|
|
+ enum dma_data_direction dir;
|
|
|
|
+
|
|
|
|
+ if (src_cnt > 1) /* is xor? */
|
|
|
|
+ dir = DMA_BIDIRECTIONAL;
|
|
|
|
+ else
|
|
|
|
+ dir = DMA_FROM_DEVICE;
|
|
|
|
+
|
|
|
|
+ dma_unmap_page(dev, dest, len, dir);
|
|
}
|
|
}
|
|
|
|
|
|
if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
|
|
if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
|
|
- src_cnt = unmap->unmap_src_cnt;
|
|
|
|
while (src_cnt--) {
|
|
while (src_cnt--) {
|
|
addr = iop_desc_get_src_addr(unmap,
|
|
addr = iop_desc_get_src_addr(unmap,
|
|
iop_chan,
|
|
iop_chan,
|
|
src_cnt);
|
|
src_cnt);
|
|
|
|
+ if (addr == dest)
|
|
|
|
+ continue;
|
|
dma_unmap_page(dev, addr, len,
|
|
dma_unmap_page(dev, addr, len,
|
|
DMA_TO_DEVICE);
|
|
DMA_TO_DEVICE);
|
|
}
|
|
}
|