1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2020 Intel Corporation
4 #include <linux/debugfs.h>
6 #include "ufs-debugfs.h"
7 #include <ufs/ufshcd.h>
8 #include "ufshcd-priv.h"
10 static struct dentry
*ufs_debugfs_root
;
12 struct ufs_debugfs_attr
{
15 const struct file_operations
*fops
;
18 /* @file corresponds to a debugfs attribute in directory hba->debugfs_root. */
19 static inline struct ufs_hba
*hba_from_file(const struct file
*file
)
21 return d_inode(file
->f_path
.dentry
->d_parent
)->i_private
;
24 void __init
ufs_debugfs_init(void)
26 ufs_debugfs_root
= debugfs_create_dir("ufshcd", NULL
);
29 void ufs_debugfs_exit(void)
31 debugfs_remove_recursive(ufs_debugfs_root
);
34 static int ufs_debugfs_stats_show(struct seq_file
*s
, void *data
)
36 struct ufs_hba
*hba
= hba_from_file(s
->file
);
37 struct ufs_event_hist
*e
= hba
->ufs_stats
.event
;
39 #define PRT(fmt, typ) \
40 seq_printf(s, fmt, e[UFS_EVT_ ## typ].cnt)
42 PRT("PHY Adapter Layer errors (except LINERESET): %llu\n", PA_ERR
);
43 PRT("Data Link Layer errors: %llu\n", DL_ERR
);
44 PRT("Network Layer errors: %llu\n", NL_ERR
);
45 PRT("Transport Layer errors: %llu\n", TL_ERR
);
46 PRT("Generic DME errors: %llu\n", DME_ERR
);
47 PRT("Auto-hibernate errors: %llu\n", AUTO_HIBERN8_ERR
);
48 PRT("IS Fatal errors (CEFES, SBFES, HCFES, DFES): %llu\n", FATAL_ERR
);
49 PRT("DME Link Startup errors: %llu\n", LINK_STARTUP_FAIL
);
50 PRT("PM Resume errors: %llu\n", RESUME_ERR
);
51 PRT("PM Suspend errors : %llu\n", SUSPEND_ERR
);
52 PRT("Logical Unit Resets: %llu\n", DEV_RESET
);
53 PRT("Host Resets: %llu\n", HOST_RESET
);
54 PRT("SCSI command aborts: %llu\n", ABORT
);
58 DEFINE_SHOW_ATTRIBUTE(ufs_debugfs_stats
);
60 static int ee_usr_mask_get(void *data
, u64
*val
)
62 struct ufs_hba
*hba
= data
;
64 *val
= hba
->ee_usr_mask
;
68 static int ufs_debugfs_get_user_access(struct ufs_hba
*hba
)
69 __acquires(&hba
->host_sem
)
72 if (!ufshcd_is_user_access_allowed(hba
)) {
76 ufshcd_rpm_get_sync(hba
);
80 static void ufs_debugfs_put_user_access(struct ufs_hba
*hba
)
81 __releases(&hba
->host_sem
)
83 ufshcd_rpm_put_sync(hba
);
87 static int ee_usr_mask_set(void *data
, u64 val
)
89 struct ufs_hba
*hba
= data
;
92 if (val
& ~(u64
)MASK_EE_STATUS
)
94 err
= ufs_debugfs_get_user_access(hba
);
97 err
= ufshcd_update_ee_usr_mask(hba
, val
, MASK_EE_STATUS
);
98 ufs_debugfs_put_user_access(hba
);
102 DEFINE_DEBUGFS_ATTRIBUTE(ee_usr_mask_fops
, ee_usr_mask_get
, ee_usr_mask_set
, "%#llx\n");
104 void ufs_debugfs_exception_event(struct ufs_hba
*hba
, u16 status
)
110 if (!hba
->debugfs_ee_rate_limit_ms
|| !status
)
113 mutex_lock(&hba
->ee_ctrl_mutex
);
114 ee_ctrl_mask
= hba
->ee_drv_mask
| (hba
->ee_usr_mask
& ~status
);
115 chgd
= ee_ctrl_mask
!= hba
->ee_ctrl_mask
;
117 err
= __ufshcd_write_ee_control(hba
, ee_ctrl_mask
);
119 dev_err(hba
->dev
, "%s: failed to write ee control %d\n",
122 mutex_unlock(&hba
->ee_ctrl_mutex
);
125 unsigned long delay
= msecs_to_jiffies(hba
->debugfs_ee_rate_limit_ms
);
127 queue_delayed_work(system_freezable_wq
, &hba
->debugfs_ee_work
, delay
);
131 static void ufs_debugfs_restart_ee(struct work_struct
*work
)
133 struct ufs_hba
*hba
= container_of(work
, struct ufs_hba
, debugfs_ee_work
.work
);
135 if (!hba
->ee_usr_mask
|| pm_runtime_suspended(hba
->dev
) ||
136 ufs_debugfs_get_user_access(hba
))
138 ufshcd_write_ee_control(hba
);
139 ufs_debugfs_put_user_access(hba
);
142 static int ufs_saved_err_show(struct seq_file
*s
, void *data
)
144 struct ufs_debugfs_attr
*attr
= s
->private;
145 struct ufs_hba
*hba
= hba_from_file(s
->file
);
148 if (strcmp(attr
->name
, "saved_err") == 0) {
150 } else if (strcmp(attr
->name
, "saved_uic_err") == 0) {
151 p
= &hba
->saved_uic_err
;
156 seq_printf(s
, "%d\n", *p
);
160 static ssize_t
ufs_saved_err_write(struct file
*file
, const char __user
*buf
,
161 size_t count
, loff_t
*ppos
)
163 struct ufs_debugfs_attr
*attr
= file
->f_inode
->i_private
;
164 struct ufs_hba
*hba
= hba_from_file(file
);
165 char val_str
[16] = { };
168 if (count
> sizeof(val_str
))
170 if (copy_from_user(val_str
, buf
, count
))
172 ret
= kstrtoint(val_str
, 0, &val
);
176 spin_lock_irq(hba
->host
->host_lock
);
177 if (strcmp(attr
->name
, "saved_err") == 0) {
178 hba
->saved_err
= val
;
179 } else if (strcmp(attr
->name
, "saved_uic_err") == 0) {
180 hba
->saved_uic_err
= val
;
185 ufshcd_schedule_eh_work(hba
);
186 spin_unlock_irq(hba
->host
->host_lock
);
188 return ret
< 0 ? ret
: count
;
191 static int ufs_saved_err_open(struct inode
*inode
, struct file
*file
)
193 return single_open(file
, ufs_saved_err_show
, inode
->i_private
);
196 static const struct file_operations ufs_saved_err_fops
= {
197 .owner
= THIS_MODULE
,
198 .open
= ufs_saved_err_open
,
200 .write
= ufs_saved_err_write
,
202 .release
= single_release
,
205 static const struct ufs_debugfs_attr ufs_attrs
[] = {
206 { "stats", 0400, &ufs_debugfs_stats_fops
},
207 { "saved_err", 0600, &ufs_saved_err_fops
},
208 { "saved_uic_err", 0600, &ufs_saved_err_fops
},
212 void ufs_debugfs_hba_init(struct ufs_hba
*hba
)
214 const struct ufs_debugfs_attr
*attr
;
217 /* Set default exception event rate limit period to 20ms */
218 hba
->debugfs_ee_rate_limit_ms
= 20;
219 INIT_DELAYED_WORK(&hba
->debugfs_ee_work
, ufs_debugfs_restart_ee
);
221 root
= debugfs_create_dir(dev_name(hba
->dev
), ufs_debugfs_root
);
222 if (IS_ERR_OR_NULL(root
))
224 hba
->debugfs_root
= root
;
225 d_inode(root
)->i_private
= hba
;
226 for (attr
= ufs_attrs
; attr
->name
; attr
++)
227 debugfs_create_file(attr
->name
, attr
->mode
, root
, (void *)attr
,
229 debugfs_create_file("exception_event_mask", 0600, hba
->debugfs_root
,
230 hba
, &ee_usr_mask_fops
);
231 debugfs_create_u32("exception_event_rate_limit_ms", 0600, hba
->debugfs_root
,
232 &hba
->debugfs_ee_rate_limit_ms
);
235 void ufs_debugfs_hba_exit(struct ufs_hba
*hba
)
237 debugfs_remove_recursive(hba
->debugfs_root
);
238 cancel_delayed_work_sync(&hba
->debugfs_ee_work
);