Merge branch 'topic/azt3328' into for-linus
[pandora-kernel.git] / crypto / async_tx / async_xor.c
index c029d3e..90dd3f8 100644 (file)
 #include <linux/raid/xor.h>
 #include <linux/async_tx.h>
 
-/* do_async_xor - dma map the pages and perform the xor with an engine.
- *     This routine is marked __always_inline so it can be compiled away
- *     when CONFIG_DMA_ENGINE=n
- */
-static __always_inline struct dma_async_tx_descriptor *
+/* do_async_xor - dma map the pages and perform the xor with an engine */
+static __async_inline struct dma_async_tx_descriptor *
 do_async_xor(struct dma_chan *chan, struct page *dest, struct page **src_list,
             unsigned int offset, int src_cnt, size_t len,
             enum async_tx_flags flags,
@@ -53,10 +50,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;
@@ -296,7 +300,7 @@ EXPORT_SYMBOL_GPL(async_xor_zero_sum);
 
 static int __init async_xor_init(void)
 {
-       #ifdef CONFIG_DMA_ENGINE
+       #ifdef CONFIG_ASYNC_TX_DMA
        /* To conserve stack space the input src_list (array of page pointers)
         * is reused to hold the array of dma addresses passed to the driver.
         * This conversion is only possible when dma_addr_t is less than the