diff options
Diffstat (limited to 'crypto/async_tx')
-rw-r--r-- | crypto/async_tx/async_tx.c | 34 |
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 | */ |
118 | void | 118 | void async_tx_run_dependencies(struct dma_async_tx_descriptor *tx) |
119 | async_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); |