diff options
| author | Dolev Raviv <draviv@codeaurora.org> | 2014-10-28 10:12:10 +0200 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-22 10:57:54 -0700 |
| commit | 3c0960d0f11f70d22d155e30ebdfdd7805a1d43d (patch) | |
| tree | 8f0badff381869603cd5468e2225a4f91ca27b1d /include/linux | |
| parent | b0c1404cb07d813f05c0936749b7b34ffc6e01bc (diff) | |
scsi: ufs: Improve fatal error logs
Errors such as UIC error, illegal OCS values, and others may require
more information for debugging. Such information could be hibern8 events,
events sequences, recoverable errors, error history, and more.
This patch improves tracking of important errors and events in debug level
to be enabled when debugging a such issues. It includes:
* UIC error history
* Successful hibern8 events
* Successful command after hibern8 exit
* Clk-freq info
* Failed device command
* Infrastructure for dumping host controller debug information
Change-Id: If3b38b86caeec4ffc669d001b452050a4a6b5173
Signed-off-by: Dolev Raviv <draviv@codeaurora.org>
[subhashj@codeaurora.org: resolved trivial merge conflicts]
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/scsi/ufs/ufshcd.h | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/include/linux/scsi/ufs/ufshcd.h b/include/linux/scsi/ufs/ufshcd.h index 18a4ec1509d9..4d877170d268 100644 --- a/include/linux/scsi/ufs/ufshcd.h +++ b/include/linux/scsi/ufs/ufshcd.h @@ -171,6 +171,10 @@ struct ufs_pm_lvl_states { * @ucd_req_ptr: UCD address of the command * @ucd_rsp_ptr: Response UPIU address for this command * @ucd_prdt_ptr: PRDT address of the command + * @utrd_dma_addr: UTRD dma address for debug + * @ucd_prdt_dma_addr: PRDT dma address for debug + * @ucd_rsp_dma_addr: UPIU response dma address for debug + * @ucd_req_dma_addr: UPIU request dma address for debug * @cmd: pointer to SCSI command * @sense_buffer: pointer to sense buffer address of the SCSI command * @sense_bufflen: Length of the sense buffer @@ -179,6 +183,7 @@ struct ufs_pm_lvl_states { * @task_tag: Task tag of the command * @lun: LUN of the command * @intr_cmd: Interrupt command (doesn't participate in interrupt aggregation) + * @issue_time_stamp: time stamp for debug purposes */ struct ufshcd_lrb { struct utp_transfer_req_desc *utr_descriptor_ptr; @@ -186,6 +191,11 @@ struct ufshcd_lrb { struct utp_upiu_rsp *ucd_rsp_ptr; struct ufshcd_sg_entry *ucd_prdt_ptr; + dma_addr_t utrd_dma_addr; + dma_addr_t ucd_req_dma_addr; + dma_addr_t ucd_rsp_dma_addr; + dma_addr_t ucd_prdt_dma_addr; + struct scsi_cmnd *cmd; u8 *sense_buffer; unsigned int sense_bufflen; @@ -195,6 +205,7 @@ struct ufshcd_lrb { int task_tag; u8 lun; /* UPIU LUN id field is only 8-bit wide */ bool intr_cmd; + ktime_t issue_time_stamp; }; /** @@ -294,6 +305,7 @@ struct ufs_pwr_mode_info { * should be reset. * @crypto_engine_reset_err: resets the saved error status of * the cryptographic engine + * @dbg_register_dump: used to dump controller debug information */ struct ufs_hba_variant_ops { const char *name; @@ -320,6 +332,7 @@ struct ufs_hba_variant_ops { int (*crypto_engine_eh)(struct ufs_hba *); int (*crypto_engine_get_err)(struct ufs_hba *); void (*crypto_engine_reset_err)(struct ufs_hba *); + void (*dbg_register_dump)(struct ufs_hba *hba); }; /* clock gating state */ @@ -411,14 +424,52 @@ struct ufs_init_prefetch { u32 icc_level; }; -#ifdef CONFIG_DEBUG_FS +#define UIC_ERR_REG_HIST_LENGTH 8 +/** + * struct ufs_uic_err_reg_hist - keeps history of uic errors + * @pos: index to indicate cyclic buffer position + * @reg: cyclic buffer for registers value + * @tstamp: cyclic buffer for time stamp + */ +struct ufs_uic_err_reg_hist { + int pos; + u32 reg[UIC_ERR_REG_HIST_LENGTH]; + ktime_t tstamp[UIC_ERR_REG_HIST_LENGTH]; +}; + +/** + * struct ufs_stats - keeps usage/err statistics + * @enabled: enable tagstats for debugfs + * @tag_stats: pointer to tag statistic counters + * @q_depth: current amount of busy slots + * @err_stats: counters to keep track of various errors + * @hibern8_exit_cnt: Counter to keep track of number of exits, + * reset this after link-startup. + * @last_hibern8_exit_tstamp: Set time after the hibern8 exit. + * Clear after the first successful command completion. + * @pa_err: tracks pa-uic errors + * @dl_err: tracks dl-uic errors + * @nl_err: tracks nl-uic errors + * @tl_err: tracks tl-uic errors + * @dme_err: tracks dme errors + */ struct ufs_stats { +#ifdef CONFIG_DEBUG_FS bool enabled; u64 **tag_stats; int q_depth; int err_stats[UFS_ERR_MAX]; +#endif + u32 hibern8_exit_cnt; + ktime_t last_hibern8_exit_tstamp; + struct ufs_uic_err_reg_hist pa_err; + struct ufs_uic_err_reg_hist dl_err; + struct ufs_uic_err_reg_hist nl_err; + struct ufs_uic_err_reg_hist tl_err; + struct ufs_uic_err_reg_hist dme_err; }; +#ifdef CONFIG_DEBUG_FS struct debugfs_files { struct dentry *debugfs_root; struct dentry *tag_stats; @@ -660,8 +711,8 @@ struct ufs_hba { struct ufs_dev_info dev_info; bool auto_bkops_enabled; -#ifdef CONFIG_DEBUG_FS struct ufs_stats ufs_stats; +#ifdef CONFIG_DEBUG_FS struct debugfs_files debugfs_files; #endif |
