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

Commit 06bf98d0 authored by Dolev Raviv's avatar Dolev Raviv Committed by Raviv Shvili
Browse files

scsi: ufs: add queries retry mechanism



Some of the queries might fail during init. To avoid
system failure, we add retry mechanism to issue queries
several times.

Change-Id: Ibab1d1dbfbaab763baad63c24218289b61da7b28
Signed-off-by: default avatarRaviv Shvili <rshvili@codeaurora.org>
Signed-off-by: default avatarDolev Raviv <draviv@codeaurora.org>
parent f5edc513
Loading
Loading
Loading
Loading
+44 −8
Original line number Diff line number Diff line
@@ -1666,7 +1666,18 @@ static inline int ufshcd_read_power_desc(struct ufs_hba *hba,
					 u8 *buf,
					 u32 size)
{
	return ufshcd_read_desc(hba, QUERY_DESC_IDN_POWER, 0, buf, size);
	int err = 0;
	int retries;

	for (retries = QUERY_REQ_RETRIES; retries > 0; retries--) {
		/* Read descriptor*/
		err = ufshcd_read_desc(hba, QUERY_DESC_IDN_POWER, 0, buf, size);
		if (!err)
			break;
		dev_dbg(hba->dev, "%s: error %d retrying\n", __func__, err);
	}

	return err;
}

/**
@@ -2454,17 +2465,25 @@ static int ufshcd_verify_dev_init(struct ufs_hba *hba)
static void ufshcd_set_queue_depth(struct scsi_device *sdev)
{
	int ret = 0;
	int retries;
	u8 lun_qdepth;
	struct ufs_hba *hba;

	hba = shost_priv(sdev->host);

	lun_qdepth = hba->nutrs;
	for (retries = QUERY_REQ_RETRIES; retries > 0; retries--) {
		/* Read descriptor*/
		ret = ufshcd_read_unit_desc_param(hba,
				  ufshcd_scsi_to_upiu_lun(sdev->lun),
				  UNIT_DESC_PARAM_LU_Q_DEPTH,
				  &lun_qdepth,
				  sizeof(lun_qdepth));
		if (!ret || ret == -ENOTSUPP)
			break;

		dev_dbg(hba->dev, "%s: error %d retrying\n", __func__, ret);
	}

	/* Some WLUN doesn't support unit descriptor */
	if (ret == -EOPNOTSUPP)
@@ -3740,6 +3759,24 @@ out:
	return icc_level;
}

static int ufshcd_set_icc_levels_attr(struct ufs_hba *hba, u32 icc_level)
{
	int ret = 0;
	int retries;

	for (retries = QUERY_REQ_RETRIES; retries > 0; retries--) {
		/* write attribute */
		ret = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_WRITE_ATTR,
			QUERY_ATTR_IDN_ACTIVE_ICC_LVL, 0, 0, &icc_level);
		if (!ret)
			break;

		dev_dbg(hba->dev, "%s: failed with error %d\n", __func__, ret);
	}

	return ret;
}

static void ufshcd_init_icc_levels(struct ufs_hba *hba)
{
	u32 icc_level;
@@ -3759,8 +3796,7 @@ static void ufshcd_init_icc_levels(struct ufs_hba *hba)
	icc_level = ufshcd_find_max_sup_active_icc_level(hba, desc_buf,
								buff_len);

	ret = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_WRITE_ATTR,
			QUERY_ATTR_IDN_ACTIVE_ICC_LVL, 0, 0, &icc_level);
	ret = ufshcd_set_icc_levels_attr(hba, icc_level);

	if (ret)
		dev_err(hba->dev,