crypto: Set a unique handle when opening qce device

- Define a new handle data structure "qcedev_handle"
  This structures holds internal context data
  "qcedev_sha_ctxt" and pointer to "qcedev_control"
- Allocate memory for the hanlde, each time a client
  opens the device. Thereby, ensuring a unique handle
  for each client.
- Use the new handle for each operation (instead of
  qcedev_control pointer)
- Remove the internal sha context data structure
  "qcedev_sha_ctx" from the "qcedev_sha_op_req".
  This is now correctly tied to each handle.

Signed-off-by: Mona Hossain <mhossain@codeaurora.org>
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index 6515ae1..464616c 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -57,7 +57,7 @@
   QCEDEV_CRYPTO_OPER_LAST
 };
 
-struct qcedev_control;
+struct qcedev_handle;
 
 struct qcedev_cipher_req {
 	struct ablkcipher_request creq;
@@ -66,10 +66,20 @@
 
 struct qcedev_sha_req {
 	struct ahash_request sreq;
-	struct qcedev_sha_ctxt *sha_ctxt;
 	void *cookie;
 };
 
+struct	qcedev_sha_ctxt {
+	uint32_t	auth_data[4];
+	uint8_t		digest[QCEDEV_MAX_SHA_DIGEST];
+	uint32_t	diglen;
+	uint8_t		trailing_buf[64];
+	uint32_t	trailing_buf_len;
+	uint8_t		first_blk;
+	uint8_t		last_blk;
+	uint8_t		authkey[QCEDEV_MAX_SHA_BLOCK_SIZE];
+};
+
 struct qcedev_async_req {
 	struct list_head			list;
 	struct completion			complete;
@@ -82,7 +92,7 @@
 		struct qcedev_cipher_req	cipher_req;
 		struct qcedev_sha_req		sha_req;
 	};
-	struct qcedev_control			*podev;
+	struct qcedev_handle			*handle;
 	int					err;
 };
 
@@ -121,6 +131,13 @@
 	struct tasklet_struct done_tasklet;
 };
 
+struct qcedev_handle {
+	/* qcedev control handle */
+	struct qcedev_control *cntl;
+	/* qce internal sha context*/
+	struct	qcedev_sha_ctxt sha_ctxt;
+};
+
 /*-------------------------------------------------------------------------
 * Resource Locking Service
 * ------------------------------------------------------------------------*/
@@ -266,6 +283,7 @@
 
 static int qcedev_open(struct inode *inode, struct file *file)
 {
+	struct qcedev_handle *handle;
 	struct qcedev_control *podev;
 
 	podev = qcedev_minor_to_control(MINOR(inode->i_rdev));
@@ -275,7 +293,15 @@
 		return -ENOENT;
 	}
 
-	file->private_data = podev;
+	handle = kzalloc(sizeof(struct qcedev_handle), GFP_KERNEL);
+	if (handle == NULL) {
+		pr_err("Failed to allocate memory %ld\n",
+					PTR_ERR(handle));
+		return -ENOMEM;
+	}
+
+	handle->cntl = podev;
+	file->private_data = handle;
 
 	return 0;
 }
@@ -283,14 +309,15 @@
 static int qcedev_release(struct inode *inode, struct file *file)
 {
 	struct qcedev_control *podev;
+	struct qcedev_handle *handle;
 
-	podev =  file->private_data;
-
+	handle =  file->private_data;
+	podev =  handle->cntl;
 	if (podev != NULL && podev->magic != QCEDEV_MAGIC) {
 		printk(KERN_ERR "%s: invalid handle %p\n",
 			__func__, podev);
 	}
-
+	kzfree(handle);
 	file->private_data = NULL;
 
 	return 0;
@@ -344,19 +371,22 @@
 {
 	struct qcedev_sha_req *areq;
 	struct qcedev_control *pdev;
+	struct qcedev_handle *handle;
+
 	uint32_t *auth32 = (uint32_t *)authdata;
 
 	areq = (struct qcedev_sha_req *) cookie;
-	pdev = (struct qcedev_control *) areq->cookie;
+	handle = (struct qcedev_handle *) areq->cookie;
+	pdev = handle->cntl;
 
 	if (digest)
-		memcpy(&areq->sha_ctxt->digest[0], digest, 32);
+		memcpy(&handle->sha_ctxt.digest[0], digest, 32);
 
 	if (authdata) {
-		areq->sha_ctxt->auth_data[0] = auth32[0];
-		areq->sha_ctxt->auth_data[1] = auth32[1];
-		areq->sha_ctxt->auth_data[2] = auth32[2];
-		areq->sha_ctxt->auth_data[3] = auth32[3];
+		handle->sha_ctxt.auth_data[0] = auth32[0];
+		handle->sha_ctxt.auth_data[1] = auth32[1];
+		handle->sha_ctxt.auth_data[2] = auth32[2];
+		handle->sha_ctxt.auth_data[3] = auth32[3];
 	}
 
 	tasklet_schedule(&pdev->done_tasklet);
@@ -367,17 +397,19 @@
 	unsigned char *iv, int ret)
 {
 	struct qcedev_cipher_req *areq;
-	struct qcedev_control *pdev;
+	struct qcedev_handle *handle;
+	struct qcedev_control *podev;
 	struct qcedev_async_req *qcedev_areq;
 
 	areq = (struct qcedev_cipher_req *) cookie;
-	pdev = (struct qcedev_control *) areq->cookie;
-	qcedev_areq = pdev->active_command;
+	handle = (struct qcedev_handle *) areq->cookie;
+	podev = handle->cntl;
+	qcedev_areq = podev->active_command;
 
 	if (iv)
 		memcpy(&qcedev_areq->cipher_op_req.iv[0], iv,
 					qcedev_areq->cipher_op_req.ivlen);
-	tasklet_schedule(&pdev->done_tasklet);
+	tasklet_schedule(&podev->done_tasklet);
 };
 
 static int start_cipher_req(struct qcedev_control *podev)
@@ -388,9 +420,8 @@
 
 	/* start the command on the podev->active_command */
 	qcedev_areq = podev->active_command;
-	qcedev_areq->podev = podev;
 
-	qcedev_areq->cipher_req.cookie = qcedev_areq->podev;
+	qcedev_areq->cipher_req.cookie = qcedev_areq->handle;
 	creq.use_pmem = qcedev_areq->cipher_op_req.use_pmem;
 	if (qcedev_areq->cipher_op_req.use_pmem == QCEDEV_USE_PMEM)
 		creq.pmem = &qcedev_areq->cipher_op_req.pmem;
@@ -490,10 +521,11 @@
 	struct qcedev_async_req *qcedev_areq;
 	struct qce_sha_req sreq;
 	int ret = 0;
+	struct qcedev_handle *handle;
 
 	/* start the command on the podev->active_command */
 	qcedev_areq = podev->active_command;
-	qcedev_areq->podev = podev;
+	handle = qcedev_areq->handle;
 
 	switch (qcedev_areq->sha_op_req.alg) {
 	case QCEDEV_ALG_SHA1:
@@ -505,8 +537,7 @@
 	case QCEDEV_ALG_SHA1_HMAC:
 		if (podev->ce_support.sha_hmac) {
 			sreq.alg = QCE_HASH_SHA1_HMAC;
-			sreq.authkey =
-				&qcedev_areq->sha_op_req.ctxt.authkey[0];
+			sreq.authkey = &handle->sha_ctxt.authkey[0];
 
 		} else {
 			sreq.alg = QCE_HASH_SHA1;
@@ -516,8 +547,7 @@
 	case QCEDEV_ALG_SHA256_HMAC:
 		if (podev->ce_support.sha_hmac) {
 			sreq.alg = QCE_HASH_SHA256_HMAC;
-			sreq.authkey =
-				&qcedev_areq->sha_op_req.ctxt.authkey[0];
+			sreq.authkey = &handle->sha_ctxt.authkey[0];
 
 		} else {
 			sreq.alg = QCE_HASH_SHA256;
@@ -526,30 +556,28 @@
 		break;
 	case QCEDEV_ALG_AES_CMAC:
 		sreq.alg = QCE_HASH_AES_CMAC;
-		sreq.authkey = &qcedev_areq->sha_op_req.ctxt.authkey[0];
+		sreq.authkey = &handle->sha_ctxt.authkey[0];
 		sreq.authklen = qcedev_areq->sha_op_req.authklen;
 		break;
 	default:
 		break;
 	};
 
-	qcedev_areq->sha_req.cookie = podev;
+	qcedev_areq->sha_req.cookie = handle;
 
 	sreq.qce_cb = qcedev_sha_req_cb;
 	if (qcedev_areq->sha_op_req.alg != QCEDEV_ALG_AES_CMAC) {
-		sreq.auth_data[0] = qcedev_areq->sha_op_req.ctxt.auth_data[0];
-		sreq.auth_data[1] = qcedev_areq->sha_op_req.ctxt.auth_data[1];
-		sreq.auth_data[2] = qcedev_areq->sha_op_req.ctxt.auth_data[2];
-		sreq.auth_data[3] = qcedev_areq->sha_op_req.ctxt.auth_data[3];
-		sreq.digest = &qcedev_areq->sha_op_req.ctxt.digest[0];
-		sreq.first_blk = qcedev_areq->sha_op_req.ctxt.first_blk;
-		sreq.last_blk = qcedev_areq->sha_op_req.ctxt.last_blk;
+		sreq.auth_data[0] = handle->sha_ctxt.auth_data[0];
+		sreq.auth_data[1] = handle->sha_ctxt.auth_data[1];
+		sreq.auth_data[2] = handle->sha_ctxt.auth_data[2];
+		sreq.auth_data[3] = handle->sha_ctxt.auth_data[3];
+		sreq.digest = &handle->sha_ctxt.digest[0];
+		sreq.first_blk = handle->sha_ctxt.first_blk;
+		sreq.last_blk = handle->sha_ctxt.last_blk;
 	}
 	sreq.size = qcedev_areq->sha_req.sreq.nbytes;
 	sreq.src = qcedev_areq->sha_req.sreq.src;
 	sreq.areq = (void *)&qcedev_areq->sha_req;
-	qcedev_areq->sha_req.sha_ctxt =
-		(struct qcedev_sha_ctxt *)(&qcedev_areq->sha_op_req.ctxt);
 
 	ret = qce_process_sha_req(podev->qce, &sreq);
 
@@ -561,13 +589,15 @@
 };
 
 static int submit_req(struct qcedev_async_req *qcedev_areq,
-					struct qcedev_control *podev)
+					struct qcedev_handle *handle)
 {
+	struct qcedev_control *podev;
 	unsigned long flags = 0;
 	int ret = 0;
 	struct qcedev_stat *pstat;
 
 	qcedev_areq->err = 0;
+	podev = handle->cntl;
 
 	if (podev->platform_support.ce_shared) {
 		ret = qcedev_lock_ce(podev);
@@ -630,9 +660,9 @@
 }
 
 static int qcedev_sha_init(struct qcedev_async_req *areq,
-				struct qcedev_control *podev)
+				struct qcedev_handle *handle)
 {
-	struct qcedev_sha_ctxt *sha_ctxt = &areq->sha_op_req.ctxt;
+	struct qcedev_sha_ctxt *sha_ctxt = &handle->sha_ctxt;
 
 	memset(sha_ctxt, 0, sizeof(struct qcedev_sha_ctxt));
 	sha_ctxt->first_blk = 1;
@@ -656,7 +686,7 @@
 
 
 static int qcedev_sha_update_max_xfer(struct qcedev_async_req *qcedev_areq,
-				struct qcedev_control *podev)
+				struct qcedev_handle *handle)
 {
 	int err = 0;
 	int i = 0;
@@ -670,7 +700,7 @@
 
 	uint32_t sha_pad_len = 0;
 	uint32_t trailing_buf_len = 0;
-	uint32_t t_buf = qcedev_areq->sha_op_req.ctxt.trailing_buf_len;
+	uint32_t t_buf = handle->sha_ctxt.trailing_buf_len;
 	uint32_t sha_block_size;
 
 	total = qcedev_areq->sha_op_req.data_len + t_buf;
@@ -685,7 +715,7 @@
 
 		i = 0;
 
-		k_src = &qcedev_areq->sha_op_req.ctxt.trailing_buf[t_buf];
+		k_src = &handle->sha_ctxt.trailing_buf[t_buf];
 
 		/* Copy data from user src(s) */
 		while (len > 0) {
@@ -700,7 +730,7 @@
 			k_src += qcedev_areq->sha_op_req.data[i].len;
 			i++;
 		}
-		qcedev_areq->sha_op_req.ctxt.trailing_buf_len = total;
+		handle->sha_ctxt.trailing_buf_len = total;
 
 		return 0;
 	}
@@ -717,7 +747,7 @@
 
 	/* check for trailing buffer from previous updates and append it */
 	if (t_buf > 0) {
-		memcpy(k_src, &qcedev_areq->sha_op_req.ctxt.trailing_buf[0],
+		memcpy(k_src, &handle->sha_ctxt.trailing_buf[0],
 								t_buf);
 		k_src += t_buf;
 	}
@@ -755,24 +785,24 @@
 
 	/*  update sha_ctxt trailing buf content to new trailing buf */
 	if (trailing_buf_len > 0) {
-		memset(&qcedev_areq->sha_op_req.ctxt.trailing_buf[0], 0, 64);
-		memcpy(&qcedev_areq->sha_op_req.ctxt.trailing_buf[0],
+		memset(&handle->sha_ctxt.trailing_buf[0], 0, 64);
+		memcpy(&handle->sha_ctxt.trailing_buf[0],
 			(k_src - trailing_buf_len),
 			trailing_buf_len);
 	}
-	qcedev_areq->sha_op_req.ctxt.trailing_buf_len = trailing_buf_len;
+	handle->sha_ctxt.trailing_buf_len = trailing_buf_len;
 
-	err = submit_req(qcedev_areq, podev);
+	err = submit_req(qcedev_areq, handle);
 
-	qcedev_areq->sha_op_req.ctxt.last_blk = 0;
-	qcedev_areq->sha_op_req.ctxt.first_blk = 0;
+	handle->sha_ctxt.last_blk = 0;
+	handle->sha_ctxt.first_blk = 0;
 
 	kfree(k_buf_src);
 	return err;
 }
 
 static int qcedev_sha_update(struct qcedev_async_req *qcedev_areq,
-				struct qcedev_control *podev)
+				struct qcedev_handle *handle)
 {
 	int err = 0;
 	int i = 0;
@@ -819,7 +849,7 @@
 				sreq->entries = 1;
 
 				err = qcedev_sha_update_max_xfer(qcedev_areq,
-									podev);
+									handle);
 
 				sreq->data[i].len = req.data[i].len -
 							QCE_MAX_OPER_DATA;
@@ -853,7 +883,7 @@
 
 				i = j;
 				err = qcedev_sha_update_max_xfer(qcedev_areq,
-									podev);
+									handle);
 				num_entries = 0;
 
 				sreq->data[i].vaddr = req.data[i].vaddr +
@@ -877,13 +907,13 @@
 		sreq->data_len = saved_req->data_len;
 		kfree(saved_req);
 	} else
-		err = qcedev_sha_update_max_xfer(qcedev_areq, podev);
+		err = qcedev_sha_update_max_xfer(qcedev_areq, handle);
 
 	return err;
 }
 
 static int qcedev_sha_final(struct qcedev_async_req *qcedev_areq,
-				struct qcedev_control *podev)
+				struct qcedev_handle *handle)
 {
 	int err = 0;
 	struct scatterlist sg_src;
@@ -892,10 +922,10 @@
 	uint8_t *k_buf_src = NULL;
 	uint8_t *k_align_src = NULL;
 
-	qcedev_areq->sha_op_req.ctxt.first_blk = 0;
-	qcedev_areq->sha_op_req.ctxt.last_blk = 1;
+	handle->sha_ctxt.first_blk = 0;
+	handle->sha_ctxt.last_blk = 1;
 
-	total = qcedev_areq->sha_op_req.ctxt.trailing_buf_len;
+	total = handle->sha_ctxt.trailing_buf_len;
 
 	if (total) {
 		k_buf_src = kmalloc(total + CACHE_LINE_SIZE * 2,
@@ -905,12 +935,10 @@
 
 		k_align_src = (uint8_t *) ALIGN(((unsigned int)k_buf_src),
 							CACHE_LINE_SIZE);
-		memcpy(k_align_src,
-				&qcedev_areq->sha_op_req.ctxt.trailing_buf[0],
-				total);
+		memcpy(k_align_src, &handle->sha_ctxt.trailing_buf[0], total);
 	}
-	qcedev_areq->sha_op_req.ctxt.last_blk = 1;
-	qcedev_areq->sha_op_req.ctxt.first_blk = 0;
+	handle->sha_ctxt.last_blk = 1;
+	handle->sha_ctxt.first_blk = 0;
 
 	qcedev_areq->sha_req.sreq.src = (struct scatterlist *) &sg_src;
 	sg_set_buf(qcedev_areq->sha_req.sreq.src, k_align_src, total);
@@ -918,23 +946,21 @@
 
 	qcedev_areq->sha_req.sreq.nbytes = total;
 
-	err = submit_req(qcedev_areq, podev);
+	err = submit_req(qcedev_areq, handle);
 
-	qcedev_areq->sha_op_req.ctxt.first_blk = 0;
-	qcedev_areq->sha_op_req.ctxt.last_blk = 0;
-	qcedev_areq->sha_op_req.ctxt.auth_data[0] = 0;
-	qcedev_areq->sha_op_req.ctxt.auth_data[1] = 0;
-	qcedev_areq->sha_op_req.ctxt.auth_data[2] = 0;
-	qcedev_areq->sha_op_req.ctxt.auth_data[3] = 0;
-	qcedev_areq->sha_op_req.ctxt.trailing_buf_len = 0;
-	memset(&qcedev_areq->sha_op_req.ctxt.trailing_buf[0], 0, 64);
+	handle->sha_ctxt.first_blk = 0;
+	handle->sha_ctxt.last_blk = 0;
+	handle->sha_ctxt.auth_data[0] = 0;
+	handle->sha_ctxt.auth_data[1] = 0;
+	handle->sha_ctxt.trailing_buf_len = 0;
+	memset(&handle->sha_ctxt.trailing_buf[0], 0, 64);
 
 	kfree(k_buf_src);
 	return err;
 }
 
 static int qcedev_hash_cmac(struct qcedev_async_req *qcedev_areq,
-					struct qcedev_control *podev)
+					struct qcedev_handle *handle)
 {
 	int err = 0;
 	int i = 0;
@@ -959,7 +985,7 @@
 				(void __user *)qcedev_areq->sha_op_req.authkey,
 				qcedev_areq->sha_op_req.authklen))
 			return -EFAULT;
-	if (__copy_from_user(&qcedev_areq->sha_op_req.ctxt.authkey[0],
+	if (__copy_from_user(&handle->sha_ctxt.authkey[0],
 				(void __user *)qcedev_areq->sha_op_req.authkey,
 				qcedev_areq->sha_op_req.authklen))
 		return -EFAULT;
@@ -989,15 +1015,15 @@
 	sg_mark_end(qcedev_areq->sha_req.sreq.src);
 
 	qcedev_areq->sha_req.sreq.nbytes = total;
-	qcedev_areq->sha_op_req.ctxt.diglen = qcedev_areq->sha_op_req.diglen;
-	err = submit_req(qcedev_areq, podev);
+	handle->sha_ctxt.diglen = qcedev_areq->sha_op_req.diglen;
+	err = submit_req(qcedev_areq, handle);
 
 	kfree(k_buf_src);
 	return err;
 }
 
 static int qcedev_set_hmac_auth_key(struct qcedev_async_req *areq,
-					struct qcedev_control *podev)
+					struct qcedev_handle *handle)
 {
 	int err = 0;
 
@@ -1007,7 +1033,7 @@
 				(void __user *)areq->sha_op_req.authkey,
 				areq->sha_op_req.authklen))
 			return -EFAULT;
-		if (__copy_from_user(&areq->sha_op_req.ctxt.authkey[0],
+		if (__copy_from_user(&handle->sha_ctxt.authkey[0],
 				(void __user *)areq->sha_op_req.authkey,
 				areq->sha_op_req.authklen))
 			return -EFAULT;
@@ -1031,21 +1057,21 @@
 
 		authkey_areq.op_type = QCEDEV_CRYPTO_OPER_SHA;
 
-		qcedev_sha_init(&authkey_areq, podev);
-		err = qcedev_sha_update(&authkey_areq, podev);
+		qcedev_sha_init(&authkey_areq, handle);
+		err = qcedev_sha_update(&authkey_areq, handle);
 		if (!err)
-			err = qcedev_sha_final(&authkey_areq, podev);
+			err = qcedev_sha_final(&authkey_areq, handle);
 		else
 			return err;
-		memcpy(&areq->sha_op_req.ctxt.authkey[0],
-				&authkey_areq.sha_op_req.ctxt.digest[0],
-				authkey_areq.sha_op_req.ctxt.diglen);
+		memcpy(&handle->sha_ctxt.authkey[0],
+				&handle->sha_ctxt.digest[0],
+				handle->sha_ctxt.diglen);
 	}
 	return err;
 }
 
 static int qcedev_hmac_get_ohash(struct qcedev_async_req *qcedev_areq,
-				struct qcedev_control *podev)
+				struct qcedev_handle *handle)
 {
 	int err = 0;
 	struct scatterlist sg_src;
@@ -1067,48 +1093,46 @@
 		return -ENOMEM;
 
 	/* check for trailing buffer from previous updates and append it */
-	memcpy(k_src, &qcedev_areq->sha_op_req.ctxt.trailing_buf[0],
-			qcedev_areq->sha_op_req.ctxt.trailing_buf_len);
+	memcpy(k_src, &handle->sha_ctxt.trailing_buf[0],
+			handle->sha_ctxt.trailing_buf_len);
 
 	qcedev_areq->sha_req.sreq.src = (struct scatterlist *) &sg_src;
 	sg_set_buf(qcedev_areq->sha_req.sreq.src, k_src, sha_block_size);
 	sg_mark_end(qcedev_areq->sha_req.sreq.src);
 
 	qcedev_areq->sha_req.sreq.nbytes = sha_block_size;
-	memset(&qcedev_areq->sha_op_req.ctxt.trailing_buf[0], 0,
-							sha_block_size);
-	memcpy(&qcedev_areq->sha_op_req.ctxt.trailing_buf[0],
-					&qcedev_areq->sha_op_req.ctxt.digest[0],
+	memset(&handle->sha_ctxt.trailing_buf[0], 0, sha_block_size);
+	memcpy(&handle->sha_ctxt.trailing_buf[0], &handle->sha_ctxt.digest[0],
 					sha_digest_size);
-	qcedev_areq->sha_op_req.ctxt.trailing_buf_len = sha_digest_size;
+	handle->sha_ctxt.trailing_buf_len = sha_digest_size;
 
-	qcedev_areq->sha_op_req.ctxt.first_blk = 1;
-	qcedev_areq->sha_op_req.ctxt.last_blk = 0;
-	qcedev_areq->sha_op_req.ctxt.auth_data[0] = 0;
-	qcedev_areq->sha_op_req.ctxt.auth_data[1] = 0;
+	handle->sha_ctxt.first_blk = 1;
+	handle->sha_ctxt.last_blk = 0;
+	handle->sha_ctxt.auth_data[0] = 0;
+	handle->sha_ctxt.auth_data[1] = 0;
 
 	if (qcedev_areq->sha_op_req.alg == QCEDEV_ALG_SHA1_HMAC) {
-		memcpy(&qcedev_areq->sha_op_req.ctxt.digest[0],
+		memcpy(&handle->sha_ctxt.digest[0],
 			&_std_init_vector_sha1_uint8[0], SHA1_DIGEST_SIZE);
-		qcedev_areq->sha_op_req.ctxt.diglen = SHA1_DIGEST_SIZE;
+		handle->sha_ctxt.diglen = SHA1_DIGEST_SIZE;
 	}
 
 	if (qcedev_areq->sha_op_req.alg == QCEDEV_ALG_SHA256_HMAC) {
-		memcpy(&qcedev_areq->sha_op_req.ctxt.digest[0],
+		memcpy(&handle->sha_ctxt.digest[0],
 			&_std_init_vector_sha256_uint8[0], SHA256_DIGEST_SIZE);
-		qcedev_areq->sha_op_req.ctxt.diglen = SHA256_DIGEST_SIZE;
+		handle->sha_ctxt.diglen = SHA256_DIGEST_SIZE;
 	}
-	err = submit_req(qcedev_areq, podev);
+	err = submit_req(qcedev_areq, handle);
 
-	qcedev_areq->sha_op_req.ctxt.last_blk = 0;
-	qcedev_areq->sha_op_req.ctxt.first_blk = 0;
+	handle->sha_ctxt.last_blk = 0;
+	handle->sha_ctxt.first_blk = 0;
 
 	kfree(k_src);
 	return err;
 }
 
 static int qcedev_hmac_update_iokey(struct qcedev_async_req *areq,
-				struct qcedev_control *podev, bool ikey)
+				struct qcedev_handle *handle, bool ikey)
 {
 	int i;
 	uint32_t constant;
@@ -1124,75 +1148,77 @@
 	else
 		sha_block_size = SHA256_BLOCK_SIZE;
 
-	memset(&areq->sha_op_req.ctxt.trailing_buf[0], 0, sha_block_size);
+	memset(&handle->sha_ctxt.trailing_buf[0], 0, sha_block_size);
 	for (i = 0; i < sha_block_size; i++)
-		areq->sha_op_req.ctxt.trailing_buf[i] =
-				(areq->sha_op_req.ctxt.authkey[i] ^ constant);
+		handle->sha_ctxt.trailing_buf[i] =
+				(handle->sha_ctxt.authkey[i] ^ constant);
 
-	areq->sha_op_req.ctxt.trailing_buf_len = sha_block_size;
+	handle->sha_ctxt.trailing_buf_len = sha_block_size;
 	return 0;
 }
 
 static int qcedev_hmac_init(struct qcedev_async_req *areq,
-				struct qcedev_control *podev)
+				struct qcedev_handle *handle)
 {
 	int err;
+	struct qcedev_control *podev = handle->cntl;
 
-	qcedev_sha_init(areq, podev);
-	err = qcedev_set_hmac_auth_key(areq, podev);
+	qcedev_sha_init(areq, handle);
+	err = qcedev_set_hmac_auth_key(areq, handle);
 	if (err)
 		return err;
 	if (!podev->ce_support.sha_hmac)
-		qcedev_hmac_update_iokey(areq, podev, true);
+		qcedev_hmac_update_iokey(areq, handle, true);
 	return 0;
 }
 
 static int qcedev_hmac_final(struct qcedev_async_req *areq,
-				struct qcedev_control *podev)
+				struct qcedev_handle *handle)
 {
 	int err;
+	struct qcedev_control *podev = handle->cntl;
 
-	err = qcedev_sha_final(areq, podev);
+	err = qcedev_sha_final(areq, handle);
 	if (podev->ce_support.sha_hmac)
 		return err;
 
-	qcedev_hmac_update_iokey(areq, podev, false);
-	err = qcedev_hmac_get_ohash(areq, podev);
+	qcedev_hmac_update_iokey(areq, handle, false);
+	err = qcedev_hmac_get_ohash(areq, handle);
 	if (err)
 		return err;
-	err = qcedev_sha_final(areq, podev);
+	err = qcedev_sha_final(areq, handle);
 
 	return err;
 }
 
 static int qcedev_hash_init(struct qcedev_async_req *areq,
-				struct qcedev_control *podev)
+				struct qcedev_handle *handle)
 {
 	if ((areq->sha_op_req.alg == QCEDEV_ALG_SHA1) ||
 			(areq->sha_op_req.alg == QCEDEV_ALG_SHA256))
-		return qcedev_sha_init(areq, podev);
+		return qcedev_sha_init(areq, handle);
 	else
-		return qcedev_hmac_init(areq, podev);
+		return qcedev_hmac_init(areq, handle);
 }
 
 static int qcedev_hash_update(struct qcedev_async_req *qcedev_areq,
-				struct qcedev_control *podev)
+				struct qcedev_handle *handle)
 {
-	return qcedev_sha_update(qcedev_areq, podev);
+	return qcedev_sha_update(qcedev_areq, handle);
 }
 
 static int qcedev_hash_final(struct qcedev_async_req *areq,
-				struct qcedev_control *podev)
+				struct qcedev_handle *handle)
 {
 	if ((areq->sha_op_req.alg == QCEDEV_ALG_SHA1) ||
 			(areq->sha_op_req.alg == QCEDEV_ALG_SHA256))
-		return qcedev_sha_final(areq, podev);
+		return qcedev_sha_final(areq, handle);
 	else
-		return qcedev_hmac_final(areq, podev);
+		return qcedev_hmac_final(areq, handle);
 }
 
 static int qcedev_pmem_ablk_cipher_max_xfer(struct qcedev_async_req *areq,
-						struct qcedev_control *podev)
+						struct qcedev_handle *handle)
 {
 	int i = 0;
 	int err = 0;
@@ -1269,7 +1295,7 @@
 	areq->cipher_req.creq.nbytes = areq->cipher_op_req.data_len;
 	areq->cipher_req.creq.info = areq->cipher_op_req.iv;
 
-	err = submit_req(areq, podev);
+	err = submit_req(areq, handle);
 
 	kfree(sg_src);
 	kfree(sg_dst);
@@ -1284,7 +1310,7 @@
 
 
 static int qcedev_pmem_ablk_cipher(struct qcedev_async_req *qcedev_areq,
-						struct qcedev_control *podev)
+						struct qcedev_handle *handle)
 {
 	int err = 0;
 	int i = 0;
@@ -1325,7 +1351,7 @@
 
 				err =
 				qcedev_pmem_ablk_cipher_max_xfer(qcedev_areq,
-								podev);
+								handle);
 
 				creq->pmem.src[i].len =	req.pmem.src[i].len -
 							QCE_MAX_OPER_DATA;
@@ -1362,7 +1388,7 @@
 				i = j;
 				err =
 				qcedev_pmem_ablk_cipher_max_xfer(qcedev_areq,
-								podev);
+								handle);
 				num_entries = 0;
 
 					creq->pmem.src[i].offset =
@@ -1383,7 +1409,7 @@
 		} /* end of while ((i < req.entries) && (err == 0)) */
 
 	} else
-		err = qcedev_pmem_ablk_cipher_max_xfer(qcedev_areq, podev);
+		err = qcedev_pmem_ablk_cipher_max_xfer(qcedev_areq, handle);
 
 	/* Restore the original req structure */
 	for (i = 0; i < saved_req->entries; i++) {
@@ -1399,7 +1425,7 @@
 }
 
 static int qcedev_vbuf_ablk_cipher_max_xfer(struct qcedev_async_req *areq,
-				int *di, struct qcedev_control *podev,
+				int *di, struct qcedev_handle *handle,
 				uint8_t *k_align_src)
 {
 	int err = 0;
@@ -1451,7 +1477,7 @@
 	areq->cipher_req.creq.info = areq->cipher_op_req.iv;
 	areq->cipher_op_req.entries = 1;
 
-	err = submit_req(areq, podev);
+	err = submit_req(areq, handle);
 
 	/* copy data to destination buffer*/
 	creq->data_len -= byteoffset;
@@ -1487,7 +1513,7 @@
 };
 
 static int qcedev_vbuf_ablk_cipher(struct qcedev_async_req *areq,
-						struct qcedev_control *podev)
+						struct qcedev_handle *handle)
 {
 	int err = 0;
 	int di = 0;
@@ -1562,7 +1588,7 @@
 				creq->entries = 1;
 
 				err = qcedev_vbuf_ablk_cipher_max_xfer(areq,
-						&di, podev, k_align_src);
+						&di, handle, k_align_src);
 				if (err < 0) {
 					kfree(k_buf_src);
 					kfree(saved_req);
@@ -1604,7 +1630,7 @@
 
 				i = j;
 				err = qcedev_vbuf_ablk_cipher_max_xfer(areq,
-						&di, podev, k_align_src);
+						&di, handle, k_align_src);
 				if (err < 0) {
 					kfree(k_buf_src);
 					kfree(saved_req);
@@ -1633,7 +1659,7 @@
 
 		} /* end of while ((i < req.entries) && (err == 0)) */
 	} else
-		err = qcedev_vbuf_ablk_cipher_max_xfer(areq, &di, podev,
+		err = qcedev_vbuf_ablk_cipher_max_xfer(areq, &di, handle,
 								k_align_src);
 
 	/* Restore the original req structure */
@@ -1746,11 +1772,14 @@
 static long qcedev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 {
 	int err = 0;
+	struct qcedev_handle *handle;
 	struct qcedev_control *podev;
 	struct qcedev_async_req qcedev_areq;
 	struct qcedev_stat *pstat;
 
-	podev =  file->private_data;
+	handle =  file->private_data;
+	podev =  handle->cntl;
+	qcedev_areq.handle = handle;
 	if (podev == NULL || podev->magic != QCEDEV_MAGIC) {
 		printk(KERN_ERR "%s: invalid handle %p\n",
 			__func__, podev);
@@ -1794,9 +1823,9 @@
 			return -EINVAL;
 
 		if (qcedev_areq.cipher_op_req.use_pmem == QCEDEV_USE_PMEM)
-			err = qcedev_pmem_ablk_cipher(&qcedev_areq, podev);
+			err = qcedev_pmem_ablk_cipher(&qcedev_areq, handle);
 		else
-			err = qcedev_vbuf_ablk_cipher(&qcedev_areq, podev);
+			err = qcedev_vbuf_ablk_cipher(&qcedev_areq, handle);
 		if (err)
 			return err;
 		if (__copy_to_user((void __user *)arg,
@@ -1818,7 +1847,7 @@
 		if (qcedev_check_sha_params(&qcedev_areq.sha_op_req, podev))
 			return -EINVAL;
 		qcedev_areq.op_type = QCEDEV_CRYPTO_OPER_SHA;
-		err = qcedev_hash_init(&qcedev_areq, podev);
+		err = qcedev_hash_init(&qcedev_areq, handle);
 		if (err)
 			return err;
 		if (__copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req,
@@ -1842,18 +1871,18 @@
 		qcedev_areq.op_type = QCEDEV_CRYPTO_OPER_SHA;
 
 		if (qcedev_areq.sha_op_req.alg == QCEDEV_ALG_AES_CMAC) {
-			err = qcedev_hash_cmac(&qcedev_areq, podev);
+			err = qcedev_hash_cmac(&qcedev_areq, handle);
 			if (err)
 				return err;
 		} else {
-			err = qcedev_hash_update(&qcedev_areq, podev);
+			err = qcedev_hash_update(&qcedev_areq, handle);
 			if (err)
 				return err;
 		}
 
 		memcpy(&qcedev_areq.sha_op_req.digest[0],
-				&qcedev_areq.sha_op_req.ctxt.digest[0],
-				qcedev_areq.sha_op_req.ctxt.diglen);
+				&handle->sha_ctxt.digest[0],
+				handle->sha_ctxt.diglen);
 		if (__copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req,
 					sizeof(struct qcedev_sha_op_req)))
 			return -EFAULT;
@@ -1872,14 +1901,13 @@
 		if (qcedev_check_sha_params(&qcedev_areq.sha_op_req, podev))
 			return -EINVAL;
 		qcedev_areq.op_type = QCEDEV_CRYPTO_OPER_SHA;
-		err = qcedev_hash_final(&qcedev_areq, podev);
+		err = qcedev_hash_final(&qcedev_areq, handle);
 		if (err)
 			return err;
-		qcedev_areq.sha_op_req.diglen =
-				qcedev_areq.sha_op_req.ctxt.diglen;
+		qcedev_areq.sha_op_req.diglen = handle->sha_ctxt.diglen;
 		memcpy(&qcedev_areq.sha_op_req.digest[0],
-				&qcedev_areq.sha_op_req.ctxt.digest[0],
-				qcedev_areq.sha_op_req.ctxt.diglen);
+				&handle->sha_ctxt.digest[0],
+				handle->sha_ctxt.diglen);
 		if (__copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req,
 					sizeof(struct qcedev_sha_op_req)))
 			return -EFAULT;
@@ -1898,18 +1926,17 @@
 		if (qcedev_check_sha_params(&qcedev_areq.sha_op_req, podev))
 			return -EINVAL;
 		qcedev_areq.op_type = QCEDEV_CRYPTO_OPER_SHA;
-		qcedev_hash_init(&qcedev_areq, podev);
-		err = qcedev_hash_update(&qcedev_areq, podev);
+		qcedev_hash_init(&qcedev_areq, handle);
+		err = qcedev_hash_update(&qcedev_areq, handle);
 		if (err)
 			return err;
-		err = qcedev_hash_final(&qcedev_areq, podev);
+		err = qcedev_hash_final(&qcedev_areq, handle);
 		if (err)
 			return err;
-		qcedev_areq.sha_op_req.diglen =
-				qcedev_areq.sha_op_req.ctxt.diglen;
+		qcedev_areq.sha_op_req.diglen =	handle->sha_ctxt.diglen;
 		memcpy(&qcedev_areq.sha_op_req.digest[0],
-				&qcedev_areq.sha_op_req.ctxt.digest[0],
-				qcedev_areq.sha_op_req.ctxt.diglen);
+				&handle->sha_ctxt.digest[0],
+				handle->sha_ctxt.diglen);
 		if (__copy_to_user((void __user *)arg, &qcedev_areq.sha_op_req,
 					sizeof(struct qcedev_sha_op_req)))
 			return -EFAULT;
@@ -1943,7 +1970,6 @@
 	podev->platform_support.hw_key_support =
 				platform_support->hw_key_support;
 	podev->ce_lock_count = 0;
-
 	INIT_LIST_HEAD(&podev->ready_commands);
 	podev->active_command = NULL;
 
@@ -2115,7 +2141,7 @@
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
 MODULE_DESCRIPTION("Qualcomm DEV Crypto driver");
-MODULE_VERSION("1.21");
+MODULE_VERSION("1.22");
 
 module_init(qcedev_init);
 module_exit(qcedev_exit);