From: Bean Huo <beanhuo@xxxxxxxxxx> This patch is to add a new function ufshcd_init_device_param() for initialization of UFS device related parameters which are used by driver. In this version patch, there is only dev_info.max_lu_supported being initialized. Signed-off-by: Bean Huo <beanhuo@xxxxxxxxxx> --- drivers/scsi/ufs/ufshcd.c | 47 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 1b97f2dc0b63..a297fe55e36a 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -3158,6 +3158,11 @@ static int ufshcd_read_device_desc(struct ufs_hba *hba, u8 *buf, u32 size) return ufshcd_read_desc(hba, QUERY_DESC_IDN_DEVICE, 0, buf, size); } +static int ufshcd_read_geometry_desc(struct ufs_hba *hba, u8 *buf, u32 size) +{ + return ufshcd_read_desc(hba, QUERY_DESC_IDN_GEOMETRY, 0, buf, size); +} + /** * struct uc_string_id - unicode string * @@ -6827,6 +6832,37 @@ static void ufshcd_clear_dbg_ufs_stats(struct ufs_hba *hba) hba->req_abort_count = 0; } +static int ufshcd_init_device_param(struct ufs_hba *hba) +{ + int err; + size_t buff_len; + u8 *desc_buf; + + buff_len = QUERY_DESC_MAX_SIZE; + desc_buf = kmalloc(buff_len, GFP_KERNEL); + if (!desc_buf) { + err = -ENOMEM; + goto out; + } + + err = ufshcd_read_geometry_desc(hba, desc_buf, + hba->desc_size.geom_desc); + if (err) { + dev_err(hba->dev, "%s: Failed reading Geometry Desc. err = %d\n", + __func__, err); + goto out; + } + + if (desc_buf[GEOMETRY_DESC_PARAM_MAX_NUM_LUN] == 1) + hba->dev_info.max_lu_supported = 32; + else if (desc_buf[GEOMETRY_DESC_PARAM_MAX_NUM_LUN] == 0) + hba->dev_info.max_lu_supported = 8; + +out: + kfree(desc_buf); + return err; +} + static void ufshcd_init_desc_sizes(struct ufs_hba *hba) { int err; @@ -7016,13 +7052,22 @@ static int ufshcd_probe_hba(struct ufs_hba *hba) /* * If we are in error handling context or in power management callbacks - * context, no need to scan the host + * context, no need to scan the host and to reinitialize the parameters */ if (!ufshcd_eh_in_progress(hba) && !hba->pm_op_in_progress) { bool flag; /* clear any previous UFS device information */ memset(&hba->dev_info, 0, sizeof(hba->dev_info)); + /* Init parameters according to UFS relevant descriptors */ + ret = ufshcd_init_device_param(hba); + if (ret) { + dev_err(hba->dev, + "%s: Init of device param failed. err = %d\n", + __func__, ret); + goto out; + } + if (!ufshcd_query_flag_retry(hba, UPIU_QUERY_OPCODE_READ_FLAG, QUERY_FLAG_IDN_PWR_ON_WPE, &flag)) hba->dev_info.f_power_on_wp_en = flag; -- 2.17.1