diff --git a/drivers/crypto/ti/dthev2-aes.c b/drivers/crypto/ti/dthev2-aes.c
index 10073bbeca113..a034c1c8f20ed 100644
--- a/drivers/crypto/ti/dthev2-aes.c
+++ b/drivers/crypto/ti/dthev2-aes.c
@@ -912,6 +912,7 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
struct device *tx_dev, *rx_dev;
struct dma_async_tx_descriptor *desc_in, *desc_out, *desc_aad_out;
+ bool cleanup_tx_chan = false;
int ret;
int err;
@@ -1012,13 +1013,15 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
src_nents = sg_nents_for_len(src, cryptlen);
if (src_nents < 0) {
ret = src_nents;
- goto aead_dma_prep_aad_err;
+ cleanup_tx_chan = (assoclen != 0);
+ goto aead_dma_map_src_err;
}
src_mapped_nents = dma_map_sg(tx_dev, src, src_nents, src_dir);
if (src_mapped_nents == 0) {
dev_err(dev_data->dev, "Failed to map ciphertext src for TX\n");
ret = -EINVAL;
- goto aead_dma_prep_aad_err;
+ cleanup_tx_chan = (assoclen != 0);
+ goto aead_dma_map_src_err;
}
/* Prepare DMA descriptors for ciphertext TX */@@ -1028,6 +1031,7 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
if (!desc_out) {
dev_err(dev_data->dev, "Ciphertext TX prep_slave_sg() failed\n");
ret = -EINVAL;
+ cleanup_tx_chan = (assoclen != 0);
goto aead_dma_prep_src_err;
}
@@ -1036,12 +1040,14 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
dst_nents = sg_nents_for_len(dst, cryptlen);
if (dst_nents < 0) {
ret = dst_nents;
+ cleanup_tx_chan = true;
goto aead_dma_prep_src_err;
}
dst_mapped_nents = dma_map_sg(rx_dev, dst, dst_nents, dst_dir);
if (dst_mapped_nents == 0) {
dev_err(dev_data->dev, "Failed to map ciphertext dst for RX\n");
ret = -EINVAL;
+ cleanup_tx_chan = true;
goto aead_dma_prep_src_err;
}
} else {@@ -1056,6 +1062,7 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
if (!desc_in) {
dev_err(dev_data->dev, "Ciphertext RX prep_slave_sg() failed\n");
ret = -EINVAL;
+ cleanup_tx_chan = true;
goto aead_dma_prep_dst_err;
}
@@ -1145,6 +1152,10 @@ static int dthe_aead_run(struct crypto_engine *engine, void *areq)
aead_dma_prep_src_err:
if (cryptlen != 0)
dma_unmap_sg(tx_dev, src, src_nents, src_dir);
+aead_dma_map_src_err:
+ /* Free any descriptor prepared on dma_aes_tx but never submitted */
+ if (cleanup_tx_chan)
+ dmaengine_terminate_sync(dev_data->dma_aes_tx);
aead_dma_prep_aad_err:
if (assoclen != 0)
dma_unmap_sg(tx_dev, aad_sg, aad_nents, aad_dir);
--
2.34.1