]> err.no Git - linux-2.6/blobdiff - crypto/async_tx/async_tx.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[linux-2.6] / crypto / async_tx / async_tx.c
index 69756164b61dd094f9b442f9d7d3777b43b22af7..85eaf7b1c53153ef07bdc33efa3a9d9c6cdff839 100644 (file)
@@ -23,6 +23,7 @@
  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  *
  */
+#include <linux/rculist.h>
 #include <linux/kernel.h>
 #include <linux/async_tx.h>
 
@@ -294,7 +295,7 @@ dma_channel_add_remove(struct dma_client *client,
        case DMA_RESOURCE_REMOVED:
                found = 0;
                spin_lock_irqsave(&async_tx_lock, flags);
-               list_for_each_entry_rcu(ref, &async_tx_master_list, node)
+               list_for_each_entry(ref, &async_tx_master_list, node)
                        if (ref->chan == chan) {
                                /* permit backing devices to go away */
                                dma_chan_put(ref->chan);
@@ -446,7 +447,7 @@ async_tx_channel_switch(struct dma_async_tx_descriptor *depend_tx,
         * otherwise poll for completion
         */
        if (dma_has_cap(DMA_INTERRUPT, device->cap_mask))
-               intr_tx = device->device_prep_dma_interrupt(chan);
+               intr_tx = device->device_prep_dma_interrupt(chan, 0);
        else
                intr_tx = NULL;
 
@@ -515,7 +516,8 @@ async_tx_submit(struct dma_chan *chan, struct dma_async_tx_descriptor *tx,
                 * 2/ dependencies are 1:1 i.e. two transactions can
                 * not depend on the same parent
                 */
-               BUG_ON(depend_tx->ack || depend_tx->next || tx->parent);
+               BUG_ON(async_tx_test_ack(depend_tx) || depend_tx->next ||
+                      tx->parent);
 
                /* the lock prevents async_tx_run_dependencies from missing
                 * the setting of ->next when ->parent != NULL
@@ -594,7 +596,7 @@ async_trigger_callback(enum async_tx_flags flags,
                if (device && !dma_has_cap(DMA_INTERRUPT, device->cap_mask))
                        device = NULL;
 
-               tx = device ? device->device_prep_dma_interrupt(chan) : NULL;
+               tx = device ? device->device_prep_dma_interrupt(chan, 0) : NULL;
        } else
                tx = NULL;
 
@@ -606,23 +608,34 @@ async_trigger_callback(enum async_tx_flags flags,
                pr_debug("%s: (sync)\n", __func__);
 
                /* wait for any prerequisite operations */
-               if (depend_tx) {
-                       /* if ack is already set then we cannot be sure
-                        * we are referring to the correct operation
-                        */
-                       BUG_ON(depend_tx->ack);
-                       if (dma_wait_for_async_tx(depend_tx) == DMA_ERROR)
-                               panic("%s: DMA_ERROR waiting for depend_tx\n",
-                                       __func__);
-               }
+               async_tx_quiesce(&depend_tx);
 
-               async_tx_sync_epilog(flags, depend_tx, cb_fn, cb_param);
+               async_tx_sync_epilog(cb_fn, cb_param);
        }
 
        return tx;
 }
 EXPORT_SYMBOL_GPL(async_trigger_callback);
 
+/**
+ * async_tx_quiesce - ensure tx is complete and freeable upon return
+ * @tx - transaction to quiesce
+ */
+void async_tx_quiesce(struct dma_async_tx_descriptor **tx)
+{
+       if (*tx) {
+               /* if ack is already set then we cannot be sure
+                * we are referring to the correct operation
+                */
+               BUG_ON(async_tx_test_ack(*tx));
+               if (dma_wait_for_async_tx(*tx) == DMA_ERROR)
+                       panic("DMA_ERROR waiting for transaction\n");
+               async_tx_ack(*tx);
+               *tx = NULL;
+       }
+}
+EXPORT_SYMBOL_GPL(async_tx_quiesce);
+
 module_init(async_tx_init);
 module_exit(async_tx_exit);