diff options
| author | Yaniv Gardi <ygardi@codeaurora.org> | 2015-04-01 17:05:01 +0300 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-22 10:59:47 -0700 |
| commit | 33e8deb4418fd60ed58e95bad31dfd57f9c9287e (patch) | |
| tree | 25d3d9ed8e009afd0a8368146f965739b8cd491e | |
| parent | d53a1c974d8990e9bcc72d52a734e7680f514f03 (diff) | |
scsi: ufs: add debugfs for error injection statistics
This change adds a capability to record how many errors are
injected per error scenario, and also the debugfs entry to read them
and to reset them.
cat /d/ufshcd0/err_inj_stats
to analyze how many error were injected per error scenario
echo 1 > /d/ufshcd0/err_inj_stats
(or any other value, to reset all statistics)
Change-Id: Ide06c30d1a9d3b65df99cd8bc24cffecc9a4b724
Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org>
| -rw-r--r-- | drivers/scsi/ufs/ufs-debugfs.c | 56 | ||||
| -rw-r--r-- | drivers/scsi/ufs/ufshcd.h | 1 |
2 files changed, 57 insertions, 0 deletions
diff --git a/drivers/scsi/ufs/ufs-debugfs.c b/drivers/scsi/ufs/ufs-debugfs.c index 975bbc655986..7ef0fcb1937b 100644 --- a/drivers/scsi/ufs/ufs-debugfs.c +++ b/drivers/scsi/ufs/ufs-debugfs.c @@ -65,6 +65,7 @@ struct ufsdbg_err_scenario { u32 err_code_mask; const int *err_code_arr; u32 num_err_codes; + u32 num_err_injected; }; /* @@ -355,6 +356,7 @@ void ufsdbg_error_inject_dispatcher(struct ufs_hba *hba, should_fail: *ret_value = opt_ret; + err_scen_arr[usecase].num_err_injected++; pr_debug("%s: error code index [%d], error code %d (0x%x) is injected for scenario \"%s\"\n", __func__, err_code_index, *ret_value, *ret_value, err_scen_arr[usecase].name); @@ -438,6 +440,47 @@ static const struct file_operations ufsdbg_err_code_ops = { .write = ufsdbg_err_code_write, }; +static int ufsdbg_err_inj_stats_read(struct seq_file *file, void *data) +{ + enum ufsdbg_err_inject_scenario err; + + seq_printf(file, "%-40s %-20s\n", + "Error Scenario:", "Num of Errors Injected"); + + for (err = 0; err < ERR_INJECT_MAX_ERR_SCENARIOS; err++) { + seq_printf(file, "%-40s %-20d\n", + err_scen_arr[err].name, + err_scen_arr[err].num_err_injected); + } + + return 0; +} + +static +int ufsdbg_err_inj_stats_open(struct inode *inode, struct file *file) +{ + return single_open(file, + ufsdbg_err_inj_stats_read, inode->i_private); +} + +static ssize_t ufsdbg_err_inj_stats_write(struct file *file, + const char __user *ubuf, size_t cnt, + loff_t *ppos) +{ + enum ufsdbg_err_inject_scenario err; + + for (err = 0; err < ERR_INJECT_MAX_ERR_SCENARIOS; err++) + err_scen_arr[err].num_err_injected = 0; + + return cnt; +} + +static const struct file_operations ufsdbg_err_inj_stats_ops = { + .open = ufsdbg_err_inj_stats_open, + .read = seq_read, + .write = ufsdbg_err_inj_stats_write, +}; + static void ufsdbg_setup_fault_injection(struct ufs_hba *hba) { struct dentry *fault_dir; @@ -484,8 +527,21 @@ static void ufsdbg_setup_fault_injection(struct ufs_hba *hba) goto fail_err_inj_codes; } + hba->debugfs_files.err_inj_stats = + debugfs_create_file("err_inj_stats", S_IRUSR | S_IWUSR, + hba->debugfs_files.debugfs_root, hba, + &ufsdbg_err_inj_stats_ops); + if (!hba->debugfs_files.err_inj_stats) { + dev_err(hba->dev, + "%s: failed create err_inj_stats debugfs entry\n", + __func__); + goto fail_err_inj_stats; + } + return; +fail_err_inj_stats: + debugfs_remove(hba->debugfs_files.err_inj_codes); fail_err_inj_codes: debugfs_remove(hba->debugfs_files.err_inj_scenario); fail_err_inj_scenario: diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 58126491f624..806d8bafb79f 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -480,6 +480,7 @@ struct debugfs_files { #ifdef CONFIG_UFS_FAULT_INJECTION struct dentry *err_inj_codes; struct dentry *err_inj_scenario; + struct dentry *err_inj_stats; u32 err_inj_scenario_mask; struct fault_attr fail_attr; #endif |
