summaryrefslogtreecommitdiffstats
path: root/crypto/algapi.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-04-16 20:48:54 +1000
committerHerbert Xu <herbert@gondor.apana.org.au>2007-05-02 14:38:31 +1000
commitb5b7f08869340aa8cfa23303f7d195f161479592 (patch)
treedd1f3f00165e7ca31e29a52d64909439cdfab8fd /crypto/algapi.c
parentebc610e5bc76df073221e64e86c3f7533a09ea40 (diff)
downloadlinux-b5b7f08869340aa8cfa23303f7d195f161479592.tar.gz
linux-b5b7f08869340aa8cfa23303f7d195f161479592.tar.bz2
linux-b5b7f08869340aa8cfa23303f7d195f161479592.zip
[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.c62
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:
}
EXPORT_SYMBOL_GPL(crypto_alloc_instance);
+void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen)
+{
+ INIT_LIST_HEAD(&queue->list);
+ queue->backlog = &queue->list;
+ queue->qlen = 0;
+ queue->max_qlen = max_qlen;
+}
+EXPORT_SYMBOL_GPL(crypto_init_queue);
+
+int crypto_enqueue_request(struct crypto_queue *queue,
+ struct crypto_async_request *request)
+{
+ int err = -EINPROGRESS;
+
+ if (unlikely(queue->qlen >= queue->max_qlen)) {
+ err = -EBUSY;
+ if (!(request->flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
+ goto out;
+ if (queue->backlog == &queue->list)
+ queue->backlog = &request->list;
+ }
+
+ queue->qlen++;
+ list_add_tail(&request->list, &queue->list);
+
+out:
+ return err;
+}
+EXPORT_SYMBOL_GPL(crypto_enqueue_request);
+
+struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
+{
+ struct list_head *request;
+
+ if (unlikely(!queue->qlen))
+ return NULL;
+
+ queue->qlen--;
+
+ if (queue->backlog != &queue->list)
+ queue->backlog = queue->backlog->next;
+
+ request = queue->list.next;
+ list_del(request);
+
+ return list_entry(request, struct crypto_async_request, list);
+}
+EXPORT_SYMBOL_GPL(crypto_dequeue_request);
+
+int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm)
+{
+ struct crypto_async_request *req;
+
+ list_for_each_entry(req, &queue->list, list) {
+ if (req->tfm == tfm)
+ return 1;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(crypto_tfm_in_queue);
+
static int __init crypto_algapi_init(void)
{
crypto_init_proc();