forked from Minki/linux
crypto: omap-aes - redundant locking is removed
Submitting request involved double locking for enqueuing and dequeuing. Now it is done under the same lock. FLAGS_BUSY is now handled under the same lock. Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@nokia.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
3bd2e2216b
commit
eeb2b202c5
@ -78,7 +78,7 @@
|
||||
#define FLAGS_NEW_IV BIT(5)
|
||||
#define FLAGS_INIT BIT(6)
|
||||
#define FLAGS_FAST BIT(7)
|
||||
#define FLAGS_BUSY 8
|
||||
#define FLAGS_BUSY BIT(8)
|
||||
|
||||
struct omap_aes_ctx {
|
||||
struct omap_aes_dev *dd;
|
||||
@ -179,9 +179,8 @@ static int omap_aes_wait(struct omap_aes_dev *dd, u32 offset, u32 bit)
|
||||
|
||||
static int omap_aes_hw_init(struct omap_aes_dev *dd)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
clk_enable(dd->iclk);
|
||||
|
||||
if (!(dd->flags & FLAGS_INIT)) {
|
||||
/* is it necessary to reset before every operation? */
|
||||
omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_SOFTRESET,
|
||||
@ -193,18 +192,15 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd)
|
||||
__asm__ __volatile__("nop");
|
||||
__asm__ __volatile__("nop");
|
||||
|
||||
err = omap_aes_wait(dd, AES_REG_SYSSTATUS,
|
||||
AES_REG_SYSSTATUS_RESETDONE);
|
||||
if (!err)
|
||||
dd->flags |= FLAGS_INIT;
|
||||
if (omap_aes_wait(dd, AES_REG_SYSSTATUS,
|
||||
AES_REG_SYSSTATUS_RESETDONE)) {
|
||||
clk_disable(dd->iclk);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
dd->flags |= FLAGS_INIT;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void omap_aes_hw_cleanup(struct omap_aes_dev *dd)
|
||||
{
|
||||
clk_disable(dd->iclk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap_aes_write_ctrl(struct omap_aes_dev *dd)
|
||||
@ -538,6 +534,8 @@ static void omap_aes_finish_req(struct omap_aes_dev *dd, int err)
|
||||
|
||||
pr_debug("err: %d\n", err);
|
||||
|
||||
dd->flags &= ~FLAGS_BUSY;
|
||||
|
||||
ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(dd->req));
|
||||
|
||||
if (!dd->total)
|
||||
@ -553,7 +551,7 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)
|
||||
|
||||
omap_aes_write_mask(dd, AES_REG_MASK, 0, AES_REG_MASK_START);
|
||||
|
||||
omap_aes_hw_cleanup(dd);
|
||||
clk_disable(dd->iclk);
|
||||
|
||||
omap_stop_dma(dd->dma_lch_in);
|
||||
omap_stop_dma(dd->dma_lch_out);
|
||||
@ -580,22 +578,26 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int omap_aes_handle_req(struct omap_aes_dev *dd)
|
||||
static int omap_aes_handle_req(struct omap_aes_dev *dd,
|
||||
struct ablkcipher_request *req)
|
||||
{
|
||||
struct crypto_async_request *async_req, *backlog;
|
||||
struct omap_aes_ctx *ctx;
|
||||
struct omap_aes_reqctx *rctx;
|
||||
struct ablkcipher_request *req;
|
||||
unsigned long flags;
|
||||
|
||||
if (dd->total)
|
||||
goto start;
|
||||
int err = 0;
|
||||
|
||||
spin_lock_irqsave(&dd->lock, flags);
|
||||
if (req)
|
||||
err = ablkcipher_enqueue_request(&dd->queue, req);
|
||||
if (dd->flags & FLAGS_BUSY) {
|
||||
spin_unlock_irqrestore(&dd->lock, flags);
|
||||
return err;
|
||||
}
|
||||
backlog = crypto_get_backlog(&dd->queue);
|
||||
async_req = crypto_dequeue_request(&dd->queue);
|
||||
if (!async_req)
|
||||
clear_bit(FLAGS_BUSY, &dd->flags);
|
||||
if (async_req)
|
||||
dd->flags |= FLAGS_BUSY;
|
||||
spin_unlock_irqrestore(&dd->lock, flags);
|
||||
|
||||
if (!async_req)
|
||||
@ -637,20 +639,23 @@ static int omap_aes_handle_req(struct omap_aes_dev *dd)
|
||||
if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE))
|
||||
pr_err("request size is not exact amount of AES blocks\n");
|
||||
|
||||
start:
|
||||
return omap_aes_crypt_dma_start(dd);
|
||||
omap_aes_crypt_dma_start(dd);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void omap_aes_task(unsigned long data)
|
||||
{
|
||||
struct omap_aes_dev *dd = (struct omap_aes_dev *)data;
|
||||
int err;
|
||||
|
||||
pr_debug("enter\n");
|
||||
|
||||
err = omap_aes_crypt_dma_stop(dd);
|
||||
omap_aes_crypt_dma_stop(dd);
|
||||
|
||||
err = omap_aes_handle_req(dd);
|
||||
if (dd->total)
|
||||
omap_aes_crypt_dma_start(dd);
|
||||
else
|
||||
omap_aes_handle_req(dd, NULL);
|
||||
|
||||
pr_debug("exit\n");
|
||||
}
|
||||
@ -661,8 +666,6 @@ static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode)
|
||||
crypto_ablkcipher_reqtfm(req));
|
||||
struct omap_aes_reqctx *rctx = ablkcipher_request_ctx(req);
|
||||
struct omap_aes_dev *dd;
|
||||
unsigned long flags;
|
||||
int err;
|
||||
|
||||
pr_debug("nbytes: %d, enc: %d, cbc: %d\n", req->nbytes,
|
||||
!!(mode & FLAGS_ENCRYPT),
|
||||
@ -674,16 +677,7 @@ static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode)
|
||||
|
||||
rctx->mode = mode;
|
||||
|
||||
spin_lock_irqsave(&dd->lock, flags);
|
||||
err = ablkcipher_enqueue_request(&dd->queue, req);
|
||||
spin_unlock_irqrestore(&dd->lock, flags);
|
||||
|
||||
if (!test_and_set_bit(FLAGS_BUSY, &dd->flags))
|
||||
omap_aes_handle_req(dd);
|
||||
|
||||
pr_debug("exit\n");
|
||||
|
||||
return err;
|
||||
return omap_aes_handle_req(dd, req);
|
||||
}
|
||||
|
||||
/* ********************** ALG API ************************************ */
|
||||
|
Loading…
Reference in New Issue
Block a user