dect
/
linux-2.6
Archived
13
0
Fork 0

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:
Dmitry Kasatkin 2010-11-30 10:13:28 +02:00 committed by Herbert Xu
parent 3bd2e2216b
commit eeb2b202c5
1 changed files with 32 additions and 38 deletions

View File

@ -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 ************************************ */