From 8c33ae06fcfc6d303960e3d4eedf36a1acd0ec9d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 8 Dec 2008 13:46:00 -0700 Subject: [PATCH] --- yaml --- r: 119962 b: refs/heads/master c: a06d568f7c5e40e34ea64881842deb8f4382babf h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/crypto/async_tx/async_xor.c | 11 +++++++++-- trunk/drivers/dma/iop-adma.c | 16 +++++++++++++--- trunk/drivers/dma/mv_xor.c | 15 ++++++++++++--- 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/[refs] b/[refs] index f30aecfe20e0..6abdb29e55ac 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b0b42b16ff2b90f17bc1a4308366c9beba4b276e +refs/heads/master: a06d568f7c5e40e34ea64881842deb8f4382babf diff --git a/trunk/crypto/async_tx/async_xor.c b/trunk/crypto/async_tx/async_xor.c index c029d3eb9ef0..595b78672b36 100644 --- a/trunk/crypto/async_tx/async_xor.c +++ b/trunk/crypto/async_tx/async_xor.c @@ -53,10 +53,17 @@ do_async_xor(struct dma_chan *chan, struct page *dest, struct page **src_list, int xor_src_cnt; dma_addr_t dma_dest; - dma_dest = dma_map_page(dma->dev, dest, offset, len, DMA_FROM_DEVICE); - for (i = 0; i < src_cnt; i++) + /* map the dest bidrectional in case it is re-used as a source */ + dma_dest = dma_map_page(dma->dev, dest, offset, len, DMA_BIDIRECTIONAL); + for (i = 0; i < src_cnt; i++) { + /* only map the dest once */ + if (unlikely(src_list[i] == dest)) { + dma_src[i] = dma_dest; + continue; + } dma_src[i] = dma_map_page(dma->dev, src_list[i], offset, len, DMA_TO_DEVICE); + } while (src_cnt) { async_flags = flags; diff --git a/trunk/drivers/dma/iop-adma.c b/trunk/drivers/dma/iop-adma.c index c7a9306d951d..6be317262200 100644 --- a/trunk/drivers/dma/iop-adma.c +++ b/trunk/drivers/dma/iop-adma.c @@ -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); } diff --git a/trunk/drivers/dma/mv_xor.c b/trunk/drivers/dma/mv_xor.c index 0328da020a10..bcda17426411 100644 --- a/trunk/drivers/dma/mv_xor.c +++ b/trunk/drivers/dma/mv_xor.c @@ -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); }