diff options
Diffstat (limited to 'drivers/crypto/talitos.c')
-rw-r--r-- | drivers/crypto/talitos.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index b44f4ddc565c..a3d2e9b88c41 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c | |||
@@ -338,20 +338,29 @@ DEF_TALITOS_DONE(ch1_3, TALITOS_ISR_CH_1_3_DONE) | |||
338 | static u32 current_desc_hdr(struct device *dev, int ch) | 338 | static u32 current_desc_hdr(struct device *dev, int ch) |
339 | { | 339 | { |
340 | struct talitos_private *priv = dev_get_drvdata(dev); | 340 | struct talitos_private *priv = dev_get_drvdata(dev); |
341 | int tail = priv->chan[ch].tail; | 341 | int tail, iter; |
342 | dma_addr_t cur_desc; | 342 | dma_addr_t cur_desc; |
343 | 343 | ||
344 | cur_desc = in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO); | 344 | cur_desc = ((u64)in_be32(priv->chan[ch].reg + TALITOS_CDPR)) << 32; |
345 | cur_desc |= in_be32(priv->chan[ch].reg + TALITOS_CDPR_LO); | ||
345 | 346 | ||
346 | while (priv->chan[ch].fifo[tail].dma_desc != cur_desc) { | 347 | if (!cur_desc) { |
347 | tail = (tail + 1) & (priv->fifo_len - 1); | 348 | dev_err(dev, "CDPR is NULL, giving up search for offending descriptor\n"); |
348 | if (tail == priv->chan[ch].tail) { | 349 | return 0; |
350 | } | ||
351 | |||
352 | tail = priv->chan[ch].tail; | ||
353 | |||
354 | iter = tail; | ||
355 | while (priv->chan[ch].fifo[iter].dma_desc != cur_desc) { | ||
356 | iter = (iter + 1) & (priv->fifo_len - 1); | ||
357 | if (iter == tail) { | ||
349 | dev_err(dev, "couldn't locate current descriptor\n"); | 358 | dev_err(dev, "couldn't locate current descriptor\n"); |
350 | return 0; | 359 | return 0; |
351 | } | 360 | } |
352 | } | 361 | } |
353 | 362 | ||
354 | return priv->chan[ch].fifo[tail].desc->hdr; | 363 | return priv->chan[ch].fifo[iter].desc->hdr; |
355 | } | 364 | } |
356 | 365 | ||
357 | /* | 366 | /* |