Merge tag 'for-5.19/parisc-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
[linux-2.6-microblaze.git] / drivers / crypto / virtio / virtio_crypto_core.c
index c6f482d..1198bd3 100644 (file)
@@ -22,6 +22,56 @@ virtcrypto_clear_request(struct virtio_crypto_request *vc_req)
        }
 }
 
+static void virtio_crypto_ctrlq_callback(struct virtio_crypto_ctrl_request *vc_ctrl_req)
+{
+       complete(&vc_ctrl_req->compl);
+}
+
+static void virtcrypto_ctrlq_callback(struct virtqueue *vq)
+{
+       struct virtio_crypto *vcrypto = vq->vdev->priv;
+       struct virtio_crypto_ctrl_request *vc_ctrl_req;
+       unsigned long flags;
+       unsigned int len;
+
+       spin_lock_irqsave(&vcrypto->ctrl_lock, flags);
+       do {
+               virtqueue_disable_cb(vq);
+               while ((vc_ctrl_req = virtqueue_get_buf(vq, &len)) != NULL) {
+                       spin_unlock_irqrestore(&vcrypto->ctrl_lock, flags);
+                       virtio_crypto_ctrlq_callback(vc_ctrl_req);
+                       spin_lock_irqsave(&vcrypto->ctrl_lock, flags);
+               }
+               if (unlikely(virtqueue_is_broken(vq)))
+                       break;
+       } while (!virtqueue_enable_cb(vq));
+       spin_unlock_irqrestore(&vcrypto->ctrl_lock, flags);
+}
+
+int virtio_crypto_ctrl_vq_request(struct virtio_crypto *vcrypto, struct scatterlist *sgs[],
+               unsigned int out_sgs, unsigned int in_sgs,
+               struct virtio_crypto_ctrl_request *vc_ctrl_req)
+{
+       int err;
+       unsigned long flags;
+
+       init_completion(&vc_ctrl_req->compl);
+
+       spin_lock_irqsave(&vcrypto->ctrl_lock, flags);
+       err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, out_sgs, in_sgs, vc_ctrl_req, GFP_ATOMIC);
+       if (err < 0) {
+               spin_unlock_irqrestore(&vcrypto->ctrl_lock, flags);
+               return err;
+       }
+
+       virtqueue_kick(vcrypto->ctrl_vq);
+       spin_unlock_irqrestore(&vcrypto->ctrl_lock, flags);
+
+       wait_for_completion(&vc_ctrl_req->compl);
+
+       return 0;
+}
+
 static void virtcrypto_dataq_callback(struct virtqueue *vq)
 {
        struct virtio_crypto *vcrypto = vq->vdev->priv;
@@ -73,7 +123,7 @@ static int virtcrypto_find_vqs(struct virtio_crypto *vi)
                goto err_names;
 
        /* Parameters for control virtqueue */
-       callbacks[total_vqs - 1] = NULL;
+       callbacks[total_vqs - 1] = virtcrypto_ctrlq_callback;
        names[total_vqs - 1] = "controlq";
 
        /* Allocate/initialize parameters for data virtqueues */
@@ -94,7 +144,8 @@ static int virtcrypto_find_vqs(struct virtio_crypto *vi)
                spin_lock_init(&vi->data_vq[i].lock);
                vi->data_vq[i].vq = vqs[i];
                /* Initialize crypto engine */
-               vi->data_vq[i].engine = crypto_engine_alloc_init(dev, 1);
+               vi->data_vq[i].engine = crypto_engine_alloc_init_and_set(dev, true, NULL, true,
+                                               virtqueue_get_vring_size(vqs[i]));
                if (!vi->data_vq[i].engine) {
                        ret = -ENOMEM;
                        goto err_engine;