aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/async_tx/async_tx.c34
1 files changed, 16 insertions, 18 deletions
diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c
index e8362c1efa30..dcbf1be149f3 100644
--- a/crypto/async_tx/async_tx.c
+++ b/crypto/async_tx/async_tx.c
@@ -115,34 +115,32 @@ EXPORT_SYMBOL_GPL(dma_wait_for_async_tx);
115 * (start) dependent operations on their target channel 115 * (start) dependent operations on their target channel
116 * @tx: transaction with dependencies 116 * @tx: transaction with dependencies
117 */ 117 */
118void 118void async_tx_run_dependencies(struct dma_async_tx_descriptor *tx)
119async_tx_run_dependencies(struct dma_async_tx_descriptor *tx)
120{ 119{
121 struct dma_async_tx_descriptor *next = tx->next; 120 struct dma_async_tx_descriptor *dep = tx->next;
121 struct dma_async_tx_descriptor *dep_next;
122 struct dma_chan *chan; 122 struct dma_chan *chan;
123 123
124 if (!next) 124 if (!dep)
125 return; 125 return;
126 126
127 tx->next = NULL; 127 chan = dep->chan;
128 chan = next->chan;
129 128
130 /* keep submitting up until a channel switch is detected 129 /* keep submitting up until a channel switch is detected
131 * in that case we will be called again as a result of 130 * in that case we will be called again as a result of
132 * processing the interrupt from async_tx_channel_switch 131 * processing the interrupt from async_tx_channel_switch
133 */ 132 */
134 while (next && next->chan == chan) { 133 for (; dep; dep = dep_next) {
135 struct dma_async_tx_descriptor *_next; 134 spin_lock_bh(&dep->lock);
136 135 dep->parent = NULL;
137 spin_lock_bh(&next->lock); 136 dep_next = dep->next;
138 next->parent = NULL; 137 if (dep_next && dep_next->chan == chan)
139 _next = next->next; 138 dep->next = NULL; /* ->next will be submitted */
140 if (_next && _next->chan == chan) 139 else
141 next->next = NULL; 140 dep_next = NULL; /* submit current dep and terminate */
142 spin_unlock_bh(&next->lock); 141 spin_unlock_bh(&dep->lock);
143 142
144 next->tx_submit(next); 143 dep->tx_submit(dep);
145 next = _next;
146 } 144 }
147 145
148 chan->device->device_issue_pending(chan); 146 chan->device->device_issue_pending(chan);