summaryrefslogtreecommitdiff
path: root/drivers/scsi/ufs/ufshcd.c
diff options
context:
space:
mode:
authorAndrey Markovytch <andreym@codeaurora.org>2016-04-14 16:02:05 +0300
committerJeevan Shriram <jshriram@codeaurora.org>2016-04-25 17:46:15 -0700
commitd9d0ee4b785cfd710c6ae6ea9695a8a6a2ab7855 (patch)
treeeaa838d6f12fe859d9accd3f1ff63a715412890a /drivers/scsi/ufs/ufshcd.c
parentfe9cbb77bf9b673eb3743b6986406c55e254c4ce (diff)
scsi: ufs: qcom-ice: block further requests until ICE config is complete
Requests that need to go through the ICE must be setup with a key before and have a key index ready. In cases where the key is not ready as it is not in the key cache, the ICE 'config_start' callback returns -EAGAIN and we need to block further requests and call 'config_start' again from a non-atomic context until key setup is ready and then resume requests handling. Change-Id: I51ff1e99240386ce533b5ab3f5f024043532b0ad Signed-off-by: Gilad Broner <gbroner@codeaurora.org> Signed-off-by: Andrey Markovytch <andreym@codeaurora.org>
Diffstat (limited to 'drivers/scsi/ufs/ufshcd.c')
-rw-r--r--drivers/scsi/ufs/ufshcd.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 66d66f9799df..6863cc1013f8 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1954,14 +1954,6 @@ int ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag)
{
int ret = 0;
- ret = ufshcd_vops_crypto_engine_cfg_start(hba, task_tag);
- if (ret) {
- dev_err(hba->dev,
- "%s: failed to configure crypto engine %d\n",
- __func__, ret);
- return ret;
- }
-
hba->lrb[task_tag].issue_time_stamp = ktime_get();
hba->lrb[task_tag].complete_time_stamp = ktime_set(0, 0);
ufshcd_clk_scaling_start_busy(hba);
@@ -2627,6 +2619,22 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
goto out;
}
+ err = ufshcd_vops_crypto_engine_cfg_start(hba, tag);
+ if (err) {
+ if (err != -EAGAIN)
+ dev_err(hba->dev,
+ "%s: failed to configure crypto engine %d\n",
+ __func__, err);
+
+ scsi_dma_unmap(lrbp->cmd);
+ lrbp->cmd = NULL;
+ clear_bit_unlock(tag, &hba->lrb_in_use);
+ ufshcd_release_all(hba);
+ ufshcd_vops_pm_qos_req_end(hba, cmd->request, true);
+
+ goto out;
+ }
+
/* Make sure descriptors are ready before ringing the doorbell */
wmb();
/* issue command to the controller */
@@ -2640,6 +2648,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
clear_bit_unlock(tag, &hba->lrb_in_use);
ufshcd_release_all(hba);
ufshcd_vops_pm_qos_req_end(hba, cmd->request, true);
+ ufshcd_vops_crypto_engine_cfg_end(hba, lrbp, cmd->request);
dev_err(hba->dev, "%s: failed sending command, %d\n",
__func__, err);
err = DID_ERROR;
@@ -4938,7 +4947,7 @@ void ufshcd_abort_outstanding_transfer_requests(struct ufs_hba *hba, int result)
/* Mark completed command as NULL in LRB */
lrbp->cmd = NULL;
ufshcd_release_all(hba);
- if (cmd->request)
+ if (cmd->request) {
/*
* As we are accessing the "request" structure,
* this must be called before calling
@@ -4946,6 +4955,9 @@ void ufshcd_abort_outstanding_transfer_requests(struct ufs_hba *hba, int result)
*/
ufshcd_vops_pm_qos_req_end(hba, cmd->request,
true);
+ ufshcd_vops_crypto_engine_cfg_end(hba,
+ lrbp, cmd->request);
+ }
/* Do not touch lrbp after scsi done */
cmd->scsi_done(cmd);
} else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE) {
@@ -4990,7 +5002,7 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
lrbp->cmd = NULL;
__ufshcd_release(hba, false);
__ufshcd_hibern8_release(hba, false);
- if (cmd->request)
+ if (cmd->request) {
/*
* As we are accessing the "request" structure,
* this must be called before calling
@@ -4998,6 +5010,10 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
*/
ufshcd_vops_pm_qos_req_end(hba, cmd->request,
false);
+ ufshcd_vops_crypto_engine_cfg_end(hba,
+ lrbp, cmd->request);
+ }
+
/* Do not touch lrbp after scsi done */
cmd->scsi_done(cmd);
} else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE) {