Loading drivers/scsi/ufs/ufs-qcom-ice.c +45 −2 Original line number Diff line number Diff line Loading @@ -164,7 +164,35 @@ int ufs_qcom_ice_get_dev(struct ufs_qcom_host *qcom_host) out: return err; } static void ufs_qcom_ice_cfg_work(struct work_struct *work) { struct ice_data_setting ice_set; struct ufs_qcom_host *qcom_host = container_of(work, struct ufs_qcom_host, ice_cfg_work); if (!qcom_host->ice.vops->config_start || !qcom_host->req_pending) return; memset(&ice_set, 0, sizeof(ice_set)); /* * config_start is called again as previous attempt returned -EAGAIN, * this call shall now take care of the necessary key setup. * 'ice_set' will not actually be used, instead the next call to * config_start() for this request, in the normal call flow, will * succeed as the key has now been setup. */ qcom_host->ice.vops->config_start(qcom_host->ice.pdev, qcom_host->req_pending, &ice_set, false); /* * Resume with requests processing. We assume config_start has been * successful, but even if it wasn't we still must resume in order to * allow for the request to be retried. */ ufshcd_scsi_unblock_requests(qcom_host->hba); } /** Loading Loading @@ -193,6 +221,7 @@ int ufs_qcom_ice_init(struct ufs_qcom_host *qcom_host) } qcom_host->dbg_print_en |= UFS_QCOM_ICE_DEFAULT_DBG_PRINT_EN; INIT_WORK(&qcom_host->ice_cfg_work, ufs_qcom_ice_cfg_work); out: return err; Loading Loading @@ -300,8 +329,22 @@ int ufs_qcom_ice_cfg_start(struct ufs_qcom_host *qcom_host, err = qcom_host->ice.vops->config_start(qcom_host->ice.pdev, req, &ice_set, true); if (err) { dev_err(dev, "%s: error in ice_vops->config %d\n", __func__, err); /* * config_start() returns -EAGAIN when a key slot is * available but still not configured. As configuration * requires a non-atomic context, this means we should * call the function again from the worker thread to do * the configuration. For this request the error will * propagate so it will be re-queued and until the * configuration is is completed we block further * request processing. */ if (err == -EAGAIN) { qcom_host->req_pending = req; if (schedule_work(&qcom_host->ice_cfg_work)) ufshcd_scsi_block_requests( qcom_host->hba); } goto out; } } Loading drivers/scsi/ufs/ufs-qcom.h +3 −0 Original line number Diff line number Diff line Loading @@ -337,6 +337,9 @@ struct ufs_qcom_host { /* Bitmask for enabling debug prints */ u32 dbg_print_en; struct ufs_qcom_testbus testbus; struct work_struct ice_cfg_work; struct request *req_pending; }; static inline u32 Loading drivers/scsi/ufs/ufshcd.c +26 −10 Original line number Diff line number Diff line Loading @@ -1955,14 +1955,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); Loading Loading @@ -2628,6 +2620,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 */ Loading @@ -2641,6 +2649,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; Loading Loading @@ -4961,7 +4970,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 Loading @@ -4969,6 +4978,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) { Loading Loading @@ -5013,7 +5025,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 Loading @@ -5021,6 +5033,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) { Loading Loading
drivers/scsi/ufs/ufs-qcom-ice.c +45 −2 Original line number Diff line number Diff line Loading @@ -164,7 +164,35 @@ int ufs_qcom_ice_get_dev(struct ufs_qcom_host *qcom_host) out: return err; } static void ufs_qcom_ice_cfg_work(struct work_struct *work) { struct ice_data_setting ice_set; struct ufs_qcom_host *qcom_host = container_of(work, struct ufs_qcom_host, ice_cfg_work); if (!qcom_host->ice.vops->config_start || !qcom_host->req_pending) return; memset(&ice_set, 0, sizeof(ice_set)); /* * config_start is called again as previous attempt returned -EAGAIN, * this call shall now take care of the necessary key setup. * 'ice_set' will not actually be used, instead the next call to * config_start() for this request, in the normal call flow, will * succeed as the key has now been setup. */ qcom_host->ice.vops->config_start(qcom_host->ice.pdev, qcom_host->req_pending, &ice_set, false); /* * Resume with requests processing. We assume config_start has been * successful, but even if it wasn't we still must resume in order to * allow for the request to be retried. */ ufshcd_scsi_unblock_requests(qcom_host->hba); } /** Loading Loading @@ -193,6 +221,7 @@ int ufs_qcom_ice_init(struct ufs_qcom_host *qcom_host) } qcom_host->dbg_print_en |= UFS_QCOM_ICE_DEFAULT_DBG_PRINT_EN; INIT_WORK(&qcom_host->ice_cfg_work, ufs_qcom_ice_cfg_work); out: return err; Loading Loading @@ -300,8 +329,22 @@ int ufs_qcom_ice_cfg_start(struct ufs_qcom_host *qcom_host, err = qcom_host->ice.vops->config_start(qcom_host->ice.pdev, req, &ice_set, true); if (err) { dev_err(dev, "%s: error in ice_vops->config %d\n", __func__, err); /* * config_start() returns -EAGAIN when a key slot is * available but still not configured. As configuration * requires a non-atomic context, this means we should * call the function again from the worker thread to do * the configuration. For this request the error will * propagate so it will be re-queued and until the * configuration is is completed we block further * request processing. */ if (err == -EAGAIN) { qcom_host->req_pending = req; if (schedule_work(&qcom_host->ice_cfg_work)) ufshcd_scsi_block_requests( qcom_host->hba); } goto out; } } Loading
drivers/scsi/ufs/ufs-qcom.h +3 −0 Original line number Diff line number Diff line Loading @@ -337,6 +337,9 @@ struct ufs_qcom_host { /* Bitmask for enabling debug prints */ u32 dbg_print_en; struct ufs_qcom_testbus testbus; struct work_struct ice_cfg_work; struct request *req_pending; }; static inline u32 Loading
drivers/scsi/ufs/ufshcd.c +26 −10 Original line number Diff line number Diff line Loading @@ -1955,14 +1955,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); Loading Loading @@ -2628,6 +2620,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 */ Loading @@ -2641,6 +2649,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; Loading Loading @@ -4961,7 +4970,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 Loading @@ -4969,6 +4978,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) { Loading Loading @@ -5013,7 +5025,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 Loading @@ -5021,6 +5033,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) { Loading