Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[sfrench/cifs-2.6.git] / drivers / scsi / ufs / ufshcd.c
index 029da74bb2f5c1a0e43efd5ad7bd7d1dc521ec24..034dd9cb9ec8ccd9cd12738170bda35d2de3a58e 100644 (file)
@@ -299,16 +299,6 @@ static void ufshcd_scsi_block_requests(struct ufs_hba *hba)
                scsi_block_requests(hba->host);
 }
 
-/* replace non-printable or non-ASCII characters with spaces */
-static inline void ufshcd_remove_non_printable(char *val)
-{
-       if (!val)
-               return;
-
-       if (*val < 0x20 || *val > 0x7e)
-               *val = ' ';
-}
-
 static void ufshcd_add_cmd_upiu_trace(struct ufs_hba *hba, unsigned int tag,
                const char *str)
 {
@@ -390,24 +380,25 @@ static void ufshcd_print_clk_freqs(struct ufs_hba *hba)
        }
 }
 
-static void ufshcd_print_uic_err_hist(struct ufs_hba *hba,
-               struct ufs_uic_err_reg_hist *err_hist, char *err_name)
+static void ufshcd_print_err_hist(struct ufs_hba *hba,
+                                 struct ufs_err_reg_hist *err_hist,
+                                 char *err_name)
 {
        int i;
        bool found = false;
 
-       for (i = 0; i < UIC_ERR_REG_HIST_LENGTH; i++) {
-               int p = (i + err_hist->pos) % UIC_ERR_REG_HIST_LENGTH;
+       for (i = 0; i < UFS_ERR_REG_HIST_LENGTH; i++) {
+               int p = (i + err_hist->pos) % UFS_ERR_REG_HIST_LENGTH;
 
                if (err_hist->reg[p] == 0)
                        continue;
-               dev_err(hba->dev, "%s[%d] = 0x%x at %lld us\n", err_name, i,
+               dev_err(hba->dev, "%s[%d] = 0x%x at %lld us\n", err_name, p,
                        err_hist->reg[p], ktime_to_us(err_hist->tstamp[p]));
                found = true;
        }
 
        if (!found)
-               dev_err(hba->dev, "No record of %s uic errors\n", err_name);
+               dev_err(hba->dev, "No record of %s errors\n", err_name);
 }
 
 static void ufshcd_print_host_regs(struct ufs_hba *hba)
@@ -423,11 +414,22 @@ static void ufshcd_print_host_regs(struct ufs_hba *hba)
                ktime_to_us(hba->ufs_stats.last_hibern8_exit_tstamp),
                hba->ufs_stats.hibern8_exit_cnt);
 
-       ufshcd_print_uic_err_hist(hba, &hba->ufs_stats.pa_err, "pa_err");
-       ufshcd_print_uic_err_hist(hba, &hba->ufs_stats.dl_err, "dl_err");
-       ufshcd_print_uic_err_hist(hba, &hba->ufs_stats.nl_err, "nl_err");
-       ufshcd_print_uic_err_hist(hba, &hba->ufs_stats.tl_err, "tl_err");
-       ufshcd_print_uic_err_hist(hba, &hba->ufs_stats.dme_err, "dme_err");
+       ufshcd_print_err_hist(hba, &hba->ufs_stats.pa_err, "pa_err");
+       ufshcd_print_err_hist(hba, &hba->ufs_stats.dl_err, "dl_err");
+       ufshcd_print_err_hist(hba, &hba->ufs_stats.nl_err, "nl_err");
+       ufshcd_print_err_hist(hba, &hba->ufs_stats.tl_err, "tl_err");
+       ufshcd_print_err_hist(hba, &hba->ufs_stats.dme_err, "dme_err");
+       ufshcd_print_err_hist(hba, &hba->ufs_stats.auto_hibern8_err,
+                             "auto_hibern8_err");
+       ufshcd_print_err_hist(hba, &hba->ufs_stats.fatal_err, "fatal_err");
+       ufshcd_print_err_hist(hba, &hba->ufs_stats.link_startup_err,
+                             "link_startup_fail");
+       ufshcd_print_err_hist(hba, &hba->ufs_stats.resume_err, "resume_fail");
+       ufshcd_print_err_hist(hba, &hba->ufs_stats.suspend_err,
+                             "suspend_fail");
+       ufshcd_print_err_hist(hba, &hba->ufs_stats.dev_reset, "dev_reset");
+       ufshcd_print_err_hist(hba, &hba->ufs_stats.host_reset, "host_reset");
+       ufshcd_print_err_hist(hba, &hba->ufs_stats.task_abort, "task_abort");
 
        ufshcd_print_clk_freqs(hba);
 
@@ -3199,7 +3201,7 @@ out:
 static inline int ufshcd_read_desc(struct ufs_hba *hba,
                                   enum desc_idn desc_id,
                                   int desc_index,
-                                  u8 *buf,
+                                  void *buf,
                                   u32 size)
 {
        return ufshcd_read_desc_param(hba, desc_id, desc_index, 0, buf, size);
@@ -3217,49 +3219,78 @@ 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);
 }
 
+/**
+ * struct uc_string_id - unicode string
+ *
+ * @len: size of this descriptor inclusive
+ * @type: descriptor type
+ * @uc: unicode string character
+ */
+struct uc_string_id {
+       u8 len;
+       u8 type;
+       wchar_t uc[0];
+} __packed;
+
+/* replace non-printable or non-ASCII characters with spaces */
+static inline char ufshcd_remove_non_printable(u8 ch)
+{
+       return (ch >= 0x20 && ch <= 0x7e) ? ch : ' ';
+}
+
 /**
  * ufshcd_read_string_desc - read string descriptor
  * @hba: pointer to adapter instance
  * @desc_index: descriptor index
- * @buf: pointer to buffer where descriptor would be read
- * @size: size of buf
+ * @buf: pointer to buffer where descriptor would be read,
+ *       the caller should free the memory.
  * @ascii: if true convert from unicode to ascii characters
+ *         null terminated string.
  *
- * Return 0 in case of success, non-zero otherwise
+ * Return:
+ * *      string size on success.
+ * *      -ENOMEM: on allocation failure
+ * *      -EINVAL: on a wrong parameter
  */
-int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index,
-                           u8 *buf, u32 size, bool ascii)
+int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index,
+                           u8 **buf, bool ascii)
 {
-       int err = 0;
+       struct uc_string_id *uc_str;
+       u8 *str;
+       int ret;
 
-       err = ufshcd_read_desc(hba,
-                               QUERY_DESC_IDN_STRING, desc_index, buf, size);
+       if (!buf)
+               return -EINVAL;
 
-       if (err) {
-               dev_err(hba->dev, "%s: reading String Desc failed after %d retries. err = %d\n",
-                       __func__, QUERY_REQ_RETRIES, err);
+       uc_str = kzalloc(QUERY_DESC_MAX_SIZE, GFP_KERNEL);
+       if (!uc_str)
+               return -ENOMEM;
+
+       ret = ufshcd_read_desc(hba, QUERY_DESC_IDN_STRING,
+                              desc_index, uc_str,
+                              QUERY_DESC_MAX_SIZE);
+       if (ret < 0) {
+               dev_err(hba->dev, "Reading String Desc failed after %d retries. err = %d\n",
+                       QUERY_REQ_RETRIES, ret);
+               str = NULL;
+               goto out;
+       }
+
+       if (uc_str->len <= QUERY_DESC_HDR_SIZE) {
+               dev_dbg(hba->dev, "String Desc is of zero length\n");
+               str = NULL;
+               ret = 0;
                goto out;
        }
 
        if (ascii) {
-               int desc_len;
-               int ascii_len;
+               ssize_t ascii_len;
                int i;
-               char *buff_ascii;
-
-               desc_len = buf[0];
                /* remove header and divide by 2 to move from UTF16 to UTF8 */
-               ascii_len = (desc_len - QUERY_DESC_HDR_SIZE) / 2 + 1;
-               if (size < ascii_len + QUERY_DESC_HDR_SIZE) {
-                       dev_err(hba->dev, "%s: buffer allocated size is too small\n",
-                                       __func__);
-                       err = -ENOMEM;
-                       goto out;
-               }
-
-               buff_ascii = kmalloc(ascii_len, GFP_KERNEL);
-               if (!buff_ascii) {
-                       err = -ENOMEM;
+               ascii_len = (uc_str->len - QUERY_DESC_HDR_SIZE) / 2 + 1;
+               str = kzalloc(ascii_len, GFP_KERNEL);
+               if (!str) {
+                       ret = -ENOMEM;
                        goto out;
                }
 
@@ -3267,22 +3298,28 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index,
                 * the descriptor contains string in UTF16 format
                 * we need to convert to utf-8 so it can be displayed
                 */
-               utf16s_to_utf8s((wchar_t *)&buf[QUERY_DESC_HDR_SIZE],
-                               desc_len - QUERY_DESC_HDR_SIZE,
-                               UTF16_BIG_ENDIAN, buff_ascii, ascii_len);
+               ret = utf16s_to_utf8s(uc_str->uc,
+                                     uc_str->len - QUERY_DESC_HDR_SIZE,
+                                     UTF16_BIG_ENDIAN, str, ascii_len);
 
                /* replace non-printable or non-ASCII characters with spaces */
-               for (i = 0; i < ascii_len; i++)
-                       ufshcd_remove_non_printable(&buff_ascii[i]);
+               for (i = 0; i < ret; i++)
+                       str[i] = ufshcd_remove_non_printable(str[i]);
 
-               memset(buf + QUERY_DESC_HDR_SIZE, 0,
-                               size - QUERY_DESC_HDR_SIZE);
-               memcpy(buf + QUERY_DESC_HDR_SIZE, buff_ascii, ascii_len);
-               buf[QUERY_DESC_LENGTH_OFFSET] = ascii_len + QUERY_DESC_HDR_SIZE;
-               kfree(buff_ascii);
+               str[ret++] = '\0';
+
+       } else {
+               str = kmemdup(uc_str, uc_str->len, GFP_KERNEL);
+               if (!str) {
+                       ret = -ENOMEM;
+                       goto out;
+               }
+               ret = uc_str->len;
        }
 out:
-       return err;
+       *buf = str;
+       kfree(uc_str);
+       return ret;
 }
 
 /**
@@ -4214,12 +4251,6 @@ static int ufshcd_hba_execute_hce(struct ufs_hba *hba)
 {
        int retry;
 
-       /*
-        * msleep of 1 and 5 used in this function might result in msleep(20),
-        * but it was necessary to send the UFS FPGA to reset mode during
-        * development and testing of this driver. msleep can be changed to
-        * mdelay and retry count can be reduced based on the controller.
-        */
        if (!ufshcd_is_hba_active(hba))
                /* change controller state to "reset state" */
                ufshcd_hba_stop(hba, true);
@@ -4242,7 +4273,7 @@ static int ufshcd_hba_execute_hce(struct ufs_hba *hba)
         * instruction might be read back.
         * This delay can be changed based on the controller.
         */
-       msleep(1);
+       usleep_range(1000, 1100);
 
        /* wait for the host controller to complete initialization */
        retry = 10;
@@ -4254,7 +4285,7 @@ static int ufshcd_hba_execute_hce(struct ufs_hba *hba)
                                "Controller enable failed\n");
                        return -EIO;
                }
-               msleep(5);
+               usleep_range(5000, 5100);
        }
 
        /* enable UIC related interrupts */
@@ -4326,6 +4357,14 @@ static inline int ufshcd_disable_device_tx_lcc(struct ufs_hba *hba)
        return ufshcd_disable_tx_lcc(hba, true);
 }
 
+static void ufshcd_update_reg_hist(struct ufs_err_reg_hist *reg_hist,
+                                  u32 reg)
+{
+       reg_hist->reg[reg_hist->pos] = reg;
+       reg_hist->tstamp[reg_hist->pos] = ktime_get();
+       reg_hist->pos = (reg_hist->pos + 1) % UFS_ERR_REG_HIST_LENGTH;
+}
+
 /**
  * ufshcd_link_startup - Initialize unipro link startup
  * @hba: per adapter instance
@@ -4353,6 +4392,8 @@ link_startup:
 
                /* check if device is detected by inter-connect layer */
                if (!ret && !ufshcd_is_device_present(hba)) {
+                       ufshcd_update_reg_hist(&hba->ufs_stats.link_startup_err,
+                                              0);
                        dev_err(hba->dev, "%s: Device not present\n", __func__);
                        ret = -ENXIO;
                        goto out;
@@ -4363,13 +4404,19 @@ link_startup:
                 * but we can't be sure if the link is up until link startup
                 * succeeds. So reset the local Uni-Pro and try again.
                 */
-               if (ret && ufshcd_hba_enable(hba))
+               if (ret && ufshcd_hba_enable(hba)) {
+                       ufshcd_update_reg_hist(&hba->ufs_stats.link_startup_err,
+                                              (u32)ret);
                        goto out;
+               }
        } while (ret && retries--);
 
-       if (ret)
+       if (ret) {
                /* failed to get the link up... retire */
+               ufshcd_update_reg_hist(&hba->ufs_stats.link_startup_err,
+                                      (u32)ret);
                goto out;
+       }
 
        if (link_startup_again) {
                link_startup_again = false;
@@ -5345,14 +5392,6 @@ out:
        pm_runtime_put_sync(hba->dev);
 }
 
-static void ufshcd_update_uic_reg_hist(struct ufs_uic_err_reg_hist *reg_hist,
-               u32 reg)
-{
-       reg_hist->reg[reg_hist->pos] = reg;
-       reg_hist->tstamp[reg_hist->pos] = ktime_get();
-       reg_hist->pos = (reg_hist->pos + 1) % UIC_ERR_REG_HIST_LENGTH;
-}
-
 /**
  * ufshcd_update_uic_error - check and set fatal UIC error flags.
  * @hba: per-adapter instance
@@ -5371,13 +5410,13 @@ static void ufshcd_update_uic_error(struct ufs_hba *hba)
                 * must be checked but this error is handled separately.
                 */
                dev_dbg(hba->dev, "%s: UIC Lane error reported\n", __func__);
-               ufshcd_update_uic_reg_hist(&hba->ufs_stats.pa_err, reg);
+               ufshcd_update_reg_hist(&hba->ufs_stats.pa_err, reg);
        }
 
        /* PA_INIT_ERROR is fatal and needs UIC reset */
        reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DATA_LINK_LAYER);
        if (reg)
-               ufshcd_update_uic_reg_hist(&hba->ufs_stats.dl_err, reg);
+               ufshcd_update_reg_hist(&hba->ufs_stats.dl_err, reg);
 
        if (reg & UIC_DATA_LINK_LAYER_ERROR_PA_INIT)
                hba->uic_error |= UFSHCD_UIC_DL_PA_INIT_ERROR;
@@ -5393,19 +5432,19 @@ static void ufshcd_update_uic_error(struct ufs_hba *hba)
        /* UIC NL/TL/DME errors needs software retry */
        reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_NETWORK_LAYER);
        if (reg) {
-               ufshcd_update_uic_reg_hist(&hba->ufs_stats.nl_err, reg);
+               ufshcd_update_reg_hist(&hba->ufs_stats.nl_err, reg);
                hba->uic_error |= UFSHCD_UIC_NL_ERROR;
        }
 
        reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_TRANSPORT_LAYER);
        if (reg) {
-               ufshcd_update_uic_reg_hist(&hba->ufs_stats.tl_err, reg);
+               ufshcd_update_reg_hist(&hba->ufs_stats.tl_err, reg);
                hba->uic_error |= UFSHCD_UIC_TL_ERROR;
        }
 
        reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DME);
        if (reg) {
-               ufshcd_update_uic_reg_hist(&hba->ufs_stats.dme_err, reg);
+               ufshcd_update_reg_hist(&hba->ufs_stats.dme_err, reg);
                hba->uic_error |= UFSHCD_UIC_DME_ERROR;
        }
 
@@ -5438,8 +5477,10 @@ static void ufshcd_check_errors(struct ufs_hba *hba)
 {
        bool queue_eh_work = false;
 
-       if (hba->errors & INT_FATAL_ERRORS)
+       if (hba->errors & INT_FATAL_ERRORS) {
+               ufshcd_update_reg_hist(&hba->ufs_stats.fatal_err, hba->errors);
                queue_eh_work = true;
+       }
 
        if (hba->errors & UIC_ERROR) {
                hba->uic_error = 0;
@@ -5454,6 +5495,8 @@ static void ufshcd_check_errors(struct ufs_hba *hba)
                        __func__, (hba->errors & UIC_HIBERNATE_ENTER) ?
                        "Enter" : "Exit",
                        hba->errors, ufshcd_get_upmcrs(hba));
+               ufshcd_update_reg_hist(&hba->ufs_stats.auto_hibern8_err,
+                                      hba->errors);
                queue_eh_work = true;
        }
 
@@ -5652,13 +5695,12 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
                memcpy(treq, hba->utmrdl_base_addr + free_slot, sizeof(*treq));
 
                ufshcd_add_tm_upiu_trace(hba, task_tag, "tm_complete");
-
-               spin_lock_irqsave(hba->host->host_lock, flags);
-               __clear_bit(free_slot, &hba->outstanding_tasks);
-               spin_unlock_irqrestore(hba->host->host_lock, flags);
-
        }
 
+       spin_lock_irqsave(hba->host->host_lock, flags);
+       __clear_bit(free_slot, &hba->outstanding_tasks);
+       spin_unlock_irqrestore(hba->host->host_lock, flags);
+
        clear_bit(free_slot, &hba->tm_condition);
        ufshcd_put_tm_slot(hba, free_slot);
        wake_up(&hba->tm_tag_wq);
@@ -5941,6 +5983,7 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd)
 
 out:
        hba->req_abort_count = 0;
+       ufshcd_update_reg_hist(&hba->ufs_stats.dev_reset, (u32)err);
        if (!err) {
                err = SUCCESS;
        } else {
@@ -6034,6 +6077,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
         */
        scsi_print_command(hba->lrb[tag].cmd);
        if (!hba->req_abort_count) {
+               ufshcd_update_reg_hist(&hba->ufs_stats.task_abort, 0);
                ufshcd_print_host_regs(hba);
                ufshcd_print_host_state(hba);
                ufshcd_print_pwr_info(hba);
@@ -6169,7 +6213,7 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba)
 out:
        if (err)
                dev_err(hba->dev, "%s: Host init failed %d\n", __func__, err);
-
+       ufshcd_update_reg_hist(&hba->ufs_stats.host_reset, (u32)err);
        return err;
 }
 
@@ -6189,6 +6233,9 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba)
        int retries = MAX_HOST_RESET_RETRIES;
 
        do {
+               /* Reset the attached device */
+               ufshcd_vops_device_reset(hba);
+
                err = ufshcd_host_reset_and_restore(hba);
        } while (err && --retries);
 
@@ -6453,6 +6500,9 @@ static int ufs_get_device_desc(struct ufs_hba *hba,
        u8 model_index;
        u8 *desc_buf;
 
+       if (!dev_desc)
+               return -EINVAL;
+
        buff_len = max_t(size_t, hba->desc_size.dev_desc,
                         QUERY_DESC_MAX_SIZE + 1);
        desc_buf = kmalloc(buff_len, GFP_KERNEL);
@@ -6476,31 +6526,31 @@ static int ufs_get_device_desc(struct ufs_hba *hba,
                                     desc_buf[DEVICE_DESC_PARAM_MANF_ID + 1];
 
        model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME];
-
-       /* Zero-pad entire buffer for string termination. */
-       memset(desc_buf, 0, buff_len);
-
-       err = ufshcd_read_string_desc(hba, model_index, desc_buf,
-                                     QUERY_DESC_MAX_SIZE, true/*ASCII*/);
-       if (err) {
+       err = ufshcd_read_string_desc(hba, model_index,
+                                     &dev_desc->model, SD_ASCII_STD);
+       if (err < 0) {
                dev_err(hba->dev, "%s: Failed reading Product Name. err = %d\n",
                        __func__, err);
                goto out;
        }
 
-       desc_buf[QUERY_DESC_MAX_SIZE] = '\0';
-       strlcpy(dev_desc->model, (desc_buf + QUERY_DESC_HDR_SIZE),
-               min_t(u8, desc_buf[QUERY_DESC_LENGTH_OFFSET],
-                     MAX_MODEL_LEN));
-
-       /* Null terminate the model string */
-       dev_desc->model[MAX_MODEL_LEN] = '\0';
+       /*
+        * ufshcd_read_string_desc returns size of the string
+        * reset the error value
+        */
+       err = 0;
 
 out:
        kfree(desc_buf);
        return err;
 }
 
+static void ufs_put_device_desc(struct ufs_dev_desc *dev_desc)
+{
+       kfree(dev_desc->model);
+       dev_desc->model = NULL;
+}
+
 static void ufs_fixup_device_setup(struct ufs_hba *hba,
                                   struct ufs_dev_desc *dev_desc)
 {
@@ -6509,8 +6559,9 @@ static void ufs_fixup_device_setup(struct ufs_hba *hba,
        for (f = ufs_fixups; f->quirk; f++) {
                if ((f->card.wmanufacturerid == dev_desc->wmanufacturerid ||
                     f->card.wmanufacturerid == UFS_ANY_VENDOR) &&
-                   (STR_PRFX_EQUAL(f->card.model, dev_desc->model) ||
-                    !strcmp(f->card.model, UFS_ANY_MODEL)))
+                    ((dev_desc->model &&
+                      STR_PRFX_EQUAL(f->card.model, dev_desc->model)) ||
+                     !strcmp(f->card.model, UFS_ANY_MODEL)))
                        hba->dev_quirks |= f->quirk;
        }
 }
@@ -6681,17 +6732,8 @@ static void ufshcd_tune_unipro_params(struct ufs_hba *hba)
 
 static void ufshcd_clear_dbg_ufs_stats(struct ufs_hba *hba)
 {
-       int err_reg_hist_size = sizeof(struct ufs_uic_err_reg_hist);
-
        hba->ufs_stats.hibern8_exit_cnt = 0;
        hba->ufs_stats.last_hibern8_exit_tstamp = ktime_set(0, 0);
-
-       memset(&hba->ufs_stats.pa_err, 0, err_reg_hist_size);
-       memset(&hba->ufs_stats.dl_err, 0, err_reg_hist_size);
-       memset(&hba->ufs_stats.nl_err, 0, err_reg_hist_size);
-       memset(&hba->ufs_stats.tl_err, 0, err_reg_hist_size);
-       memset(&hba->ufs_stats.dme_err, 0, err_reg_hist_size);
-
        hba->req_abort_count = 0;
 }
 
@@ -6861,6 +6903,8 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
        }
 
        ufs_fixup_device_setup(hba, &card);
+       ufs_put_device_desc(&card);
+
        ufshcd_tune_unipro_params(hba);
 
        /* UFS device is also active now */
@@ -7823,6 +7867,8 @@ enable_gating:
        ufshcd_release(hba);
 out:
        hba->pm_op_in_progress = 0;
+       if (ret)
+               ufshcd_update_reg_hist(&hba->ufs_stats.suspend_err, (u32)ret);
        return ret;
 }
 
@@ -7925,6 +7971,8 @@ disable_irq_and_vops_clks:
        ufshcd_setup_clocks(hba, false);
 out:
        hba->pm_op_in_progress = 0;
+       if (ret)
+               ufshcd_update_reg_hist(&hba->ufs_stats.resume_err, (u32)ret);
        return ret;
 }
 
@@ -8324,6 +8372,9 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
                goto exit_gating;
        }
 
+       /* Reset the attached device */
+       ufshcd_vops_device_reset(hba);
+
        /* Host controller enable */
        err = ufshcd_hba_enable(hba);
        if (err) {