Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c974ab60 authored by Veerabhadrarao Badiganti's avatar Veerabhadrarao Badiganti Committed by Y
Browse files

scsi: ufs: While completing the request ensure ice is not holding it



UFS driver keeps re-queuing the request until it gets valid key info from
the ICE driver. And the ICE driver continues to use the same request
pointer to fetch the key info.

But if the shutdown process starts during this time, UFS driver simply
completes. But ICE driver still holds the completed request pointer.

So before completing the request when the shutdown is in progress,
check if ICE is still holding the request pointer. If it's not holding then
only complete it, otherwise just re-queue it.

Change-Id: I0260f4f143c2f64869f0276f784b36d05d1514ea
Signed-off-by: default avatarVeerabhadrarao Badiganti <vbadigan@codeaurora.org>
parent 4d044fea
Loading
Loading
Loading
Loading
+16 −0
Original line number Original line Diff line number Diff line
@@ -1018,12 +1018,27 @@ static int ufs_qcom_crypto_engine_get_status(struct ufs_hba *hba, u32 *status)


	return ufs_qcom_ice_get_status(host, status);
	return ufs_qcom_ice_get_status(host, status);
}
}

static int ufs_qcom_crypto_get_pending_req_status(struct ufs_hba *hba)
{
	struct ufs_qcom_host *host = ufshcd_get_variant(hba);
	int err = 0;

	if (!host->ice.pdev)
		goto out;

	err = ufs_qcom_is_ice_busy(host);
out:
	return err;
}

#else /* !CONFIG_SCSI_UFS_QCOM_ICE */
#else /* !CONFIG_SCSI_UFS_QCOM_ICE */
#define ufs_qcom_crypto_req_setup		NULL
#define ufs_qcom_crypto_req_setup		NULL
#define ufs_qcom_crytpo_engine_cfg_start	NULL
#define ufs_qcom_crytpo_engine_cfg_start	NULL
#define ufs_qcom_crytpo_engine_cfg_end		NULL
#define ufs_qcom_crytpo_engine_cfg_end		NULL
#define ufs_qcom_crytpo_engine_reset		NULL
#define ufs_qcom_crytpo_engine_reset		NULL
#define ufs_qcom_crypto_engine_get_status	NULL
#define ufs_qcom_crypto_engine_get_status	NULL
#define ufs_qcom_crypto_get_pending_req_status	NULL
#endif /* CONFIG_SCSI_UFS_QCOM_ICE */
#endif /* CONFIG_SCSI_UFS_QCOM_ICE */


struct ufs_qcom_dev_params {
struct ufs_qcom_dev_params {
@@ -2807,6 +2822,7 @@ static struct ufs_hba_crypto_variant_ops ufs_hba_crypto_variant_ops = {
	.crypto_engine_cfg_end	= ufs_qcom_crytpo_engine_cfg_end,
	.crypto_engine_cfg_end	= ufs_qcom_crytpo_engine_cfg_end,
	.crypto_engine_reset	  = ufs_qcom_crytpo_engine_reset,
	.crypto_engine_reset	  = ufs_qcom_crytpo_engine_reset,
	.crypto_engine_get_status = ufs_qcom_crypto_engine_get_status,
	.crypto_engine_get_status = ufs_qcom_crypto_engine_get_status,
	.crypto_get_req_status = ufs_qcom_crypto_get_pending_req_status,
};
};


static struct ufs_hba_pm_qos_variant_ops ufs_hba_pm_qos_variant_ops = {
static struct ufs_hba_pm_qos_variant_ops ufs_hba_pm_qos_variant_ops = {
+7 −3
Original line number Original line Diff line number Diff line
@@ -3702,9 +3702,13 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
	err = ufshcd_get_read_lock(hba, cmd->device->lun);
	err = ufshcd_get_read_lock(hba, cmd->device->lun);
	if (unlikely(err < 0)) {
	if (unlikely(err < 0)) {
		if (err == -EPERM) {
		if (err == -EPERM) {
			if (!ufshcd_vops_crypto_engine_get_req_status(hba)) {
				set_host_byte(cmd, DID_ERROR);
				set_host_byte(cmd, DID_ERROR);
				cmd->scsi_done(cmd);
				cmd->scsi_done(cmd);
				return 0;
				return 0;
			} else {
				return SCSI_MLQUEUE_HOST_BUSY;
			}
		}
		}
		if (err == -EAGAIN)
		if (err == -EAGAIN)
			return SCSI_MLQUEUE_HOST_BUSY;
			return SCSI_MLQUEUE_HOST_BUSY;
+11 −1
Original line number Original line Diff line number Diff line
@@ -380,6 +380,7 @@ struct ufs_hba_variant_ops {
 *						   according to tag parameter
 *						   according to tag parameter
 * @crypto_engine_reset: perform reset to the cryptographic engine
 * @crypto_engine_reset: perform reset to the cryptographic engine
 * @crypto_engine_get_status: get errors status of the cryptographic engine
 * @crypto_engine_get_status: get errors status of the cryptographic engine
 * @crypto_get_req_status: Check if crypto driver still holds request or not
 */
 */
struct ufs_hba_crypto_variant_ops {
struct ufs_hba_crypto_variant_ops {
	int	(*crypto_req_setup)(struct ufs_hba *, struct ufshcd_lrb *lrbp,
	int	(*crypto_req_setup)(struct ufs_hba *, struct ufshcd_lrb *lrbp,
@@ -389,6 +390,7 @@ struct ufs_hba_crypto_variant_ops {
			struct request *);
			struct request *);
	int	(*crypto_engine_reset)(struct ufs_hba *);
	int	(*crypto_engine_reset)(struct ufs_hba *);
	int	(*crypto_engine_get_status)(struct ufs_hba *, u32 *);
	int	(*crypto_engine_get_status)(struct ufs_hba *, u32 *);
	int     (*crypto_get_req_status)(struct ufs_hba *);
};
};


/**
/**
@@ -1536,7 +1538,6 @@ static inline int ufshcd_vops_crypto_engine_reset(struct ufs_hba *hba)


static inline int ufshcd_vops_crypto_engine_get_status(struct ufs_hba *hba,
static inline int ufshcd_vops_crypto_engine_get_status(struct ufs_hba *hba,
		u32 *status)
		u32 *status)

{
{
	if (hba->var && hba->var->crypto_vops &&
	if (hba->var && hba->var->crypto_vops &&
	    hba->var->crypto_vops->crypto_engine_get_status)
	    hba->var->crypto_vops->crypto_engine_get_status)
@@ -1560,4 +1561,13 @@ static inline void ufshcd_vops_pm_qos_req_end(struct ufs_hba *hba,
		hba->var->pm_qos_vops->req_end(hba, req, lock);
		hba->var->pm_qos_vops->req_end(hba, req, lock);
}
}


static inline int ufshcd_vops_crypto_engine_get_req_status(struct ufs_hba *hba)

{
	if (hba->var && hba->var->crypto_vops &&
	    hba->var->crypto_vops->crypto_get_req_status)
		return hba->var->crypto_vops->crypto_get_req_status(hba);
	return 0;
}

#endif /* End of Header */
#endif /* End of Header */