[1/4] I/OAT: fix channel resources free for not allocated channels
[linux-2.6.git] / drivers / dma / mv_xor.c
index f0c123c..0328da0 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/memory.h>
-#include <asm/plat-orion/mv_xor.h>
+#include <plat/mv_xor.h>
 #include "mv_xor.h"
 
 static void mv_xor_issue_pending(struct dma_chan *chan);
@@ -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;
                }
@@ -588,7 +598,8 @@ submit_done:
 }
 
 /* returns the number of allocated descriptors */
-static int mv_xor_alloc_chan_resources(struct dma_chan *chan)
+static int mv_xor_alloc_chan_resources(struct dma_chan *chan,
+                                      struct dma_client *client)
 {
        char *hw_desc;
        int idx;
@@ -938,7 +949,7 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device)
        dma_chan = container_of(device->common.channels.next,
                                struct dma_chan,
                                device_node);
-       if (mv_xor_alloc_chan_resources(dma_chan) < 1) {
+       if (mv_xor_alloc_chan_resources(dma_chan, NULL) < 1) {
                err = -ENODEV;
                goto out;
        }
@@ -1033,7 +1044,7 @@ mv_xor_xor_self_test(struct mv_xor_device *device)
        dma_chan = container_of(device->common.channels.next,
                                struct dma_chan,
                                device_node);
-       if (mv_xor_alloc_chan_resources(dma_chan) < 1) {
+       if (mv_xor_alloc_chan_resources(dma_chan, NULL) < 1) {
                err = -ENODEV;
                goto out;
        }