mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
async_xor: dma_map destination DMA_BIDIRECTIONAL
Mapping the destination multiple times is a misuse of the dma-api. Since the destination may be reused as a source, ensure that it is only mapped once and that it is mapped bidirectionally. This appears to add ugliness on the unmap side in that it always reads back the destination address from the descriptor, but gcc can determine that dma_unmap is a nop and not emit the code that calculates its arguments. Cc: <[email protected]> Cc: Saeed Bishara <[email protected]> Acked-by: Yuri Tikhonov <[email protected]> Signed-off-by: Dan Williams <[email protected]>
This commit is contained in:
parent
b0b42b16ff
commit
a06d568f7c
3 changed files with 34 additions and 8 deletions
|
|
@ -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;
|
||||
u32 src_cnt;
|
||||
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)) {
|
||||
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)) {
|
||||
src_cnt = unmap->unmap_src_cnt;
|
||||
while (src_cnt--) {
|
||||
addr = iop_desc_get_src_addr(unmap,
|
||||
iop_chan,
|
||||
src_cnt);
|
||||
if (addr == dest)
|
||||
continue;
|
||||
dma_unmap_page(dev, addr, len,
|
||||
DMA_TO_DEVICE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -311,17 +311,26 @@ mv_xor_run_tx_complete_actions(struct mv_xor_desc_slot *desc,
|
|||
enum dma_ctrl_flags flags = desc->async_tx.flags;
|
||||
u32 src_cnt;
|
||||
dma_addr_t addr;
|
||||
dma_addr_t dest;
|
||||
|
||||
src_cnt = unmap->unmap_src_cnt;
|
||||
dest = mv_desc_get_dest_addr(unmap);
|
||||
if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
|
||||
addr = mv_desc_get_dest_addr(unmap);
|
||||
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)) {
|
||||
src_cnt = unmap->unmap_src_cnt;
|
||||
while (src_cnt--) {
|
||||
addr = mv_desc_get_src_addr(unmap,
|
||||
src_cnt);
|
||||
if (addr == dest)
|
||||
continue;
|
||||
dma_unmap_page(dev, addr, len,
|
||||
DMA_TO_DEVICE);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue