diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2007-04-16 06:48:54 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2007-05-02 00:38:31 -0400 |
commit | b5b7f08869340aa8cfa23303f7d195f161479592 (patch) | |
tree | dd1f3f00165e7ca31e29a52d64909439cdfab8fd /crypto/algapi.c | |
parent | ebc610e5bc76df073221e64e86c3f7533a09ea40 (diff) |
[CRYPTO] api: Add async blkcipher type
This patch adds the mid-level interface for asynchronous block ciphers.
It also includes a generic queueing mechanism that can be used by other
asynchronous crypto operations in future.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/algapi.c')
-rw-r--r-- | crypto/algapi.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/crypto/algapi.c b/crypto/algapi.c index 491205e11cbe..1c2185b5b005 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c | |||
@@ -507,6 +507,68 @@ err_free_inst: | |||
507 | } | 507 | } |
508 | EXPORT_SYMBOL_GPL(crypto_alloc_instance); | 508 | EXPORT_SYMBOL_GPL(crypto_alloc_instance); |
509 | 509 | ||
510 | void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen) | ||
511 | { | ||
512 | INIT_LIST_HEAD(&queue->list); | ||
513 | queue->backlog = &queue->list; | ||
514 | queue->qlen = 0; | ||
515 | queue->max_qlen = max_qlen; | ||
516 | } | ||
517 | EXPORT_SYMBOL_GPL(crypto_init_queue); | ||
518 | |||
519 | int crypto_enqueue_request(struct crypto_queue *queue, | ||
520 | struct crypto_async_request *request) | ||
521 | { | ||
522 | int err = -EINPROGRESS; | ||
523 | |||
524 | if (unlikely(queue->qlen >= queue->max_qlen)) { | ||
525 | err = -EBUSY; | ||
526 | if (!(request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) | ||
527 | goto out; | ||
528 | if (queue->backlog == &queue->list) | ||
529 | queue->backlog = &request->list; | ||
530 | } | ||
531 | |||
532 | queue->qlen++; | ||
533 | list_add_tail(&request->list, &queue->list); | ||
534 | |||
535 | out: | ||
536 | return err; | ||
537 | } | ||
538 | EXPORT_SYMBOL_GPL(crypto_enqueue_request); | ||
539 | |||
540 | struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue) | ||
541 | { | ||
542 | struct list_head *request; | ||
543 | |||
544 | if (unlikely(!queue->qlen)) | ||
545 | return NULL; | ||
546 | |||
547 | queue->qlen--; | ||
548 | |||
549 | if (queue->backlog != &queue->list) | ||
550 | queue->backlog = queue->backlog->next; | ||
551 | |||
552 | request = queue->list.next; | ||
553 | list_del(request); | ||
554 | |||
555 | return list_entry(request, struct crypto_async_request, list); | ||
556 | } | ||
557 | EXPORT_SYMBOL_GPL(crypto_dequeue_request); | ||
558 | |||
559 | int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm) | ||
560 | { | ||
561 | struct crypto_async_request *req; | ||
562 | |||
563 | list_for_each_entry(req, &queue->list, list) { | ||
564 | if (req->tfm == tfm) | ||
565 | return 1; | ||
566 | } | ||
567 | |||
568 | return 0; | ||
569 | } | ||
570 | EXPORT_SYMBOL_GPL(crypto_tfm_in_queue); | ||
571 | |||
510 | static int __init crypto_algapi_init(void) | 572 | static int __init crypto_algapi_init(void) |
511 | { | 573 | { |
512 | crypto_init_proc(); | 574 | crypto_init_proc(); |