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

Commit e7792e27 authored by Sachin Gupta's avatar Sachin Gupta Committed by Todd Kjos
Browse files

BACKPORT: scsi: ufs: Resume ufs host before accessing ufs device

As a part of sysfs reading of descriptors/attributes/flags,
query commands should only be executed when hba's
power runtime status is active.
To guarantee this, add pm_runtime_get/put_sync()
to those paths where query commands are sent.

Bug: 232878917
Link: https://lore.kernel.org/r/f712a4f7bdb0ae32e0d83634731e7aaa1b3a6cdd.1585009663.git.asutoshd@codeaurora.org


Change-Id: I56b89be3ac850794b874a7b46295a8d12ef4ea02
(cherry picked from commit 0c2039dc1591bb9a3b887753b37946f09f4bf208)
[sachgupt: Resolved minor conflict in drivers/scsi/ufs/ufs-sysfs.c]
Signed-off-by: default avatarNitin Rawat <quic_nitirawa@quicinc.com>
Signed-off-by: default avatarSachin Gupta <quic_sachgupt@quicinc.com>
parent 12bf063c
Loading
Loading
Loading
Loading
+25 −7
Original line number Diff line number Diff line
@@ -211,8 +211,11 @@ static ssize_t ufs_sysfs_read_desc_param(struct ufs_hba *hba,
	if (param_size > 8)
		return -EINVAL;

	pm_runtime_get_sync(hba->dev);
	ret = ufshcd_read_desc_param(hba, desc_id, desc_index,
				param_offset, desc_buf, param_size);
	pm_runtime_put_sync(hba->dev);

	if (ret)
		return -EINVAL;
	switch (param_size) {
@@ -578,6 +581,7 @@ static ssize_t _name##_show(struct device *dev, \
	desc_buf = kzalloc(QUERY_DESC_MAX_SIZE, GFP_ATOMIC);		\
	if (!desc_buf)                                                  \
		return -ENOMEM;                                         \
	pm_runtime_get_sync(hba->dev);					\
	ret = ufshcd_query_descriptor_retry(hba,			\
		UPIU_QUERY_OPCODE_READ_DESC, QUERY_DESC_IDN_DEVICE,	\
		0, 0, desc_buf, &desc_len);				\
@@ -594,6 +598,7 @@ static ssize_t _name##_show(struct device *dev, \
		goto out;						\
	ret = snprintf(buf, PAGE_SIZE, "%s\n", desc_buf);		\
out:									\
	pm_runtime_put_sync(hba->dev);					\
	kfree(desc_buf);						\
	return ret;							\
}									\
@@ -630,12 +635,16 @@ static ssize_t _name##_show(struct device *dev, \
	struct device_attribute *attr, char *buf)			\
{									\
	bool flag;							\
	int ret;							\
	u8 index = 0;							\
	struct ufs_hba *hba = dev_get_drvdata(dev);			\
	if (ufshcd_is_wb_flags(QUERY_FLAG_IDN##_uname))			\
		index = ufshcd_wb_get_query_index(hba);			\
	if (ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_READ_FLAG,		\
		QUERY_FLAG_IDN##_uname, index, &flag))			\
	pm_runtime_get_sync(hba->dev);					\
	ret = ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_READ_FLAG,	\
			QUERY_FLAG_IDN##_uname, index, &flag);		\
	pm_runtime_put_sync(hba->dev);					\
	if (ret)							\
		return -EINVAL;						\
	return sprintf(buf, "%s\n", flag ? "true" : "false");		\
}									\
@@ -686,10 +695,14 @@ static ssize_t _name##_show(struct device *dev, \
	struct ufs_hba *hba = dev_get_drvdata(dev);			\
	u32 value;							\
	u8 index = 0;							\
	int ret;							\
	if (ufshcd_is_wb_attrs(QUERY_ATTR_IDN##_uname))			\
		index = ufshcd_wb_get_query_index(hba);			\
	if (ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR,		\
		QUERY_ATTR_IDN##_uname, index, 0, &value))		\
	pm_runtime_get_sync(hba->dev);					\
	ret = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR,	\
			QUERY_ATTR_IDN##_uname, index, 0, &value);	\
	pm_runtime_put_sync(hba->dev);					\
	if (ret)							\
		return -EINVAL;						\
	return sprintf(buf, "0x%08X\n", value);				\
}									\
@@ -822,10 +835,15 @@ static ssize_t dyn_cap_needed_attribute_show(struct device *dev,
	struct scsi_device *sdev = to_scsi_device(dev);
	struct ufs_hba *hba = shost_priv(sdev->host);
	u8 lun = ufshcd_scsi_to_upiu_lun(sdev->lun);
	int ret;

	if (ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR,
		QUERY_ATTR_IDN_DYN_CAP_NEEDED, lun, 0, &value))
	pm_runtime_get_sync(hba->dev);
	ret = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR,
			QUERY_ATTR_IDN_DYN_CAP_NEEDED, lun, 0, &value);
	pm_runtime_put_sync(hba->dev);
	if (ret)
		return -EINVAL;

	return sprintf(buf, "0x%08X\n", value);
}
static DEVICE_ATTR_RO(dyn_cap_needed_attribute);