Commit 0e693789 authored by Tudor Ambarus's avatar Tudor Ambarus Committed by Herbert Xu

crypto: atmel-{aes,sha} - Fix incorrect use of dmaengine_terminate_all()

device_terminate_all() is used to abort all the pending and
ongoing transfers on the channel, it should be used just in the
error path.

Also, dmaengine_terminate_all() is deprecated and one should use
dmaengine_terminate_async() or dmaengine_terminate_sync(). The method
is not used in atomic context, use dmaengine_terminate_sync().

A secondary aspect of this patch is that it luckily avoids a deadlock
between atmel_aes and at_hdmac.c. While in tasklet with the lock held,
the dma controller invokes the client callback (dmaengine_terminate_all),
which tries to get the same lock. The at_hdmac fix would be to drop the
lock before invoking the client callback, a fix on at_hdmac will follow.
Signed-off-by: default avatarTudor Ambarus <tudor.ambarus@microchip.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 7d07de2c
...@@ -857,27 +857,6 @@ static int atmel_aes_dma_transfer_start(struct atmel_aes_dev *dd, ...@@ -857,27 +857,6 @@ static int atmel_aes_dma_transfer_start(struct atmel_aes_dev *dd,
return 0; return 0;
} }
static void atmel_aes_dma_transfer_stop(struct atmel_aes_dev *dd,
enum dma_transfer_direction dir)
{
struct atmel_aes_dma *dma;
switch (dir) {
case DMA_MEM_TO_DEV:
dma = &dd->src;
break;
case DMA_DEV_TO_MEM:
dma = &dd->dst;
break;
default:
return;
}
dmaengine_terminate_all(dma->chan);
}
static int atmel_aes_dma_start(struct atmel_aes_dev *dd, static int atmel_aes_dma_start(struct atmel_aes_dev *dd,
struct scatterlist *src, struct scatterlist *src,
struct scatterlist *dst, struct scatterlist *dst,
...@@ -936,25 +915,18 @@ static int atmel_aes_dma_start(struct atmel_aes_dev *dd, ...@@ -936,25 +915,18 @@ static int atmel_aes_dma_start(struct atmel_aes_dev *dd,
return -EINPROGRESS; return -EINPROGRESS;
output_transfer_stop: output_transfer_stop:
atmel_aes_dma_transfer_stop(dd, DMA_DEV_TO_MEM); dmaengine_terminate_sync(dd->dst.chan);
unmap: unmap:
atmel_aes_unmap(dd); atmel_aes_unmap(dd);
exit: exit:
return atmel_aes_complete(dd, err); return atmel_aes_complete(dd, err);
} }
static void atmel_aes_dma_stop(struct atmel_aes_dev *dd)
{
atmel_aes_dma_transfer_stop(dd, DMA_MEM_TO_DEV);
atmel_aes_dma_transfer_stop(dd, DMA_DEV_TO_MEM);
atmel_aes_unmap(dd);
}
static void atmel_aes_dma_callback(void *data) static void atmel_aes_dma_callback(void *data)
{ {
struct atmel_aes_dev *dd = data; struct atmel_aes_dev *dd = data;
atmel_aes_dma_stop(dd); atmel_aes_unmap(dd);
dd->is_async = true; dd->is_async = true;
(void)dd->resume(dd); (void)dd->resume(dd);
} }
......
...@@ -1429,7 +1429,6 @@ static void atmel_sha_dma_callback2(void *data) ...@@ -1429,7 +1429,6 @@ static void atmel_sha_dma_callback2(void *data)
struct scatterlist *sg; struct scatterlist *sg;
int nents; int nents;
dmaengine_terminate_all(dma->chan);
dma_unmap_sg(dd->dev, dma->sg, dma->nents, DMA_TO_DEVICE); dma_unmap_sg(dd->dev, dma->sg, dma->nents, DMA_TO_DEVICE);
sg = dma->sg; sg = dma->sg;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment