Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (C) 2020 Intel Corporation
0003 
0004 #include <linux/debugfs.h>
0005 
0006 #include "ufs-debugfs.h"
0007 #include <ufs/ufshcd.h>
0008 #include "ufshcd-priv.h"
0009 
0010 static struct dentry *ufs_debugfs_root;
0011 
0012 struct ufs_debugfs_attr {
0013     const char          *name;
0014     mode_t              mode;
0015     const struct file_operations    *fops;
0016 };
0017 
0018 /* @file corresponds to a debugfs attribute in directory hba->debugfs_root. */
0019 static inline struct ufs_hba *hba_from_file(const struct file *file)
0020 {
0021     return d_inode(file->f_path.dentry->d_parent)->i_private;
0022 }
0023 
0024 void __init ufs_debugfs_init(void)
0025 {
0026     ufs_debugfs_root = debugfs_create_dir("ufshcd", NULL);
0027 }
0028 
0029 void ufs_debugfs_exit(void)
0030 {
0031     debugfs_remove_recursive(ufs_debugfs_root);
0032 }
0033 
0034 static int ufs_debugfs_stats_show(struct seq_file *s, void *data)
0035 {
0036     struct ufs_hba *hba = hba_from_file(s->file);
0037     struct ufs_event_hist *e = hba->ufs_stats.event;
0038 
0039 #define PRT(fmt, typ) \
0040     seq_printf(s, fmt, e[UFS_EVT_ ## typ].cnt)
0041 
0042     PRT("PHY Adapter Layer errors (except LINERESET): %llu\n", PA_ERR);
0043     PRT("Data Link Layer errors: %llu\n", DL_ERR);
0044     PRT("Network Layer errors: %llu\n", NL_ERR);
0045     PRT("Transport Layer errors: %llu\n", TL_ERR);
0046     PRT("Generic DME errors: %llu\n", DME_ERR);
0047     PRT("Auto-hibernate errors: %llu\n", AUTO_HIBERN8_ERR);
0048     PRT("IS Fatal errors (CEFES, SBFES, HCFES, DFES): %llu\n", FATAL_ERR);
0049     PRT("DME Link Startup errors: %llu\n", LINK_STARTUP_FAIL);
0050     PRT("PM Resume errors: %llu\n", RESUME_ERR);
0051     PRT("PM Suspend errors : %llu\n", SUSPEND_ERR);
0052     PRT("Logical Unit Resets: %llu\n", DEV_RESET);
0053     PRT("Host Resets: %llu\n", HOST_RESET);
0054     PRT("SCSI command aborts: %llu\n", ABORT);
0055 #undef PRT
0056     return 0;
0057 }
0058 DEFINE_SHOW_ATTRIBUTE(ufs_debugfs_stats);
0059 
0060 static int ee_usr_mask_get(void *data, u64 *val)
0061 {
0062     struct ufs_hba *hba = data;
0063 
0064     *val = hba->ee_usr_mask;
0065     return 0;
0066 }
0067 
0068 static int ufs_debugfs_get_user_access(struct ufs_hba *hba)
0069 __acquires(&hba->host_sem)
0070 {
0071     down(&hba->host_sem);
0072     if (!ufshcd_is_user_access_allowed(hba)) {
0073         up(&hba->host_sem);
0074         return -EBUSY;
0075     }
0076     ufshcd_rpm_get_sync(hba);
0077     return 0;
0078 }
0079 
0080 static void ufs_debugfs_put_user_access(struct ufs_hba *hba)
0081 __releases(&hba->host_sem)
0082 {
0083     ufshcd_rpm_put_sync(hba);
0084     up(&hba->host_sem);
0085 }
0086 
0087 static int ee_usr_mask_set(void *data, u64 val)
0088 {
0089     struct ufs_hba *hba = data;
0090     int err;
0091 
0092     if (val & ~(u64)MASK_EE_STATUS)
0093         return -EINVAL;
0094     err = ufs_debugfs_get_user_access(hba);
0095     if (err)
0096         return err;
0097     err = ufshcd_update_ee_usr_mask(hba, val, MASK_EE_STATUS);
0098     ufs_debugfs_put_user_access(hba);
0099     return err;
0100 }
0101 
0102 DEFINE_DEBUGFS_ATTRIBUTE(ee_usr_mask_fops, ee_usr_mask_get, ee_usr_mask_set, "%#llx\n");
0103 
0104 void ufs_debugfs_exception_event(struct ufs_hba *hba, u16 status)
0105 {
0106     bool chgd = false;
0107     u16 ee_ctrl_mask;
0108     int err = 0;
0109 
0110     if (!hba->debugfs_ee_rate_limit_ms || !status)
0111         return;
0112 
0113     mutex_lock(&hba->ee_ctrl_mutex);
0114     ee_ctrl_mask = hba->ee_drv_mask | (hba->ee_usr_mask & ~status);
0115     chgd = ee_ctrl_mask != hba->ee_ctrl_mask;
0116     if (chgd) {
0117         err = __ufshcd_write_ee_control(hba, ee_ctrl_mask);
0118         if (err)
0119             dev_err(hba->dev, "%s: failed to write ee control %d\n",
0120                 __func__, err);
0121     }
0122     mutex_unlock(&hba->ee_ctrl_mutex);
0123 
0124     if (chgd && !err) {
0125         unsigned long delay = msecs_to_jiffies(hba->debugfs_ee_rate_limit_ms);
0126 
0127         queue_delayed_work(system_freezable_wq, &hba->debugfs_ee_work, delay);
0128     }
0129 }
0130 
0131 static void ufs_debugfs_restart_ee(struct work_struct *work)
0132 {
0133     struct ufs_hba *hba = container_of(work, struct ufs_hba, debugfs_ee_work.work);
0134 
0135     if (!hba->ee_usr_mask || pm_runtime_suspended(hba->dev) ||
0136         ufs_debugfs_get_user_access(hba))
0137         return;
0138     ufshcd_write_ee_control(hba);
0139     ufs_debugfs_put_user_access(hba);
0140 }
0141 
0142 static int ufs_saved_err_show(struct seq_file *s, void *data)
0143 {
0144     struct ufs_debugfs_attr *attr = s->private;
0145     struct ufs_hba *hba = hba_from_file(s->file);
0146     const int *p;
0147 
0148     if (strcmp(attr->name, "saved_err") == 0) {
0149         p = &hba->saved_err;
0150     } else if (strcmp(attr->name, "saved_uic_err") == 0) {
0151         p = &hba->saved_uic_err;
0152     } else {
0153         return -ENOENT;
0154     }
0155 
0156     seq_printf(s, "%d\n", *p);
0157     return 0;
0158 }
0159 
0160 static ssize_t ufs_saved_err_write(struct file *file, const char __user *buf,
0161                    size_t count, loff_t *ppos)
0162 {
0163     struct ufs_debugfs_attr *attr = file->f_inode->i_private;
0164     struct ufs_hba *hba = hba_from_file(file);
0165     char val_str[16] = { };
0166     int val, ret;
0167 
0168     if (count > sizeof(val_str))
0169         return -EINVAL;
0170     if (copy_from_user(val_str, buf, count))
0171         return -EFAULT;
0172     ret = kstrtoint(val_str, 0, &val);
0173     if (ret < 0)
0174         return ret;
0175 
0176     spin_lock_irq(hba->host->host_lock);
0177     if (strcmp(attr->name, "saved_err") == 0) {
0178         hba->saved_err = val;
0179     } else if (strcmp(attr->name, "saved_uic_err") == 0) {
0180         hba->saved_uic_err = val;
0181     } else {
0182         ret = -ENOENT;
0183     }
0184     if (ret == 0)
0185         ufshcd_schedule_eh_work(hba);
0186     spin_unlock_irq(hba->host->host_lock);
0187 
0188     return ret < 0 ? ret : count;
0189 }
0190 
0191 static int ufs_saved_err_open(struct inode *inode, struct file *file)
0192 {
0193     return single_open(file, ufs_saved_err_show, inode->i_private);
0194 }
0195 
0196 static const struct file_operations ufs_saved_err_fops = {
0197     .owner      = THIS_MODULE,
0198     .open       = ufs_saved_err_open,
0199     .read       = seq_read,
0200     .write      = ufs_saved_err_write,
0201     .llseek     = seq_lseek,
0202     .release    = single_release,
0203 };
0204 
0205 static const struct ufs_debugfs_attr ufs_attrs[] = {
0206     { "stats", 0400, &ufs_debugfs_stats_fops },
0207     { "saved_err", 0600, &ufs_saved_err_fops },
0208     { "saved_uic_err", 0600, &ufs_saved_err_fops },
0209     { }
0210 };
0211 
0212 void ufs_debugfs_hba_init(struct ufs_hba *hba)
0213 {
0214     const struct ufs_debugfs_attr *attr;
0215     struct dentry *root;
0216 
0217     /* Set default exception event rate limit period to 20ms */
0218     hba->debugfs_ee_rate_limit_ms = 20;
0219     INIT_DELAYED_WORK(&hba->debugfs_ee_work, ufs_debugfs_restart_ee);
0220 
0221     root = debugfs_create_dir(dev_name(hba->dev), ufs_debugfs_root);
0222     if (IS_ERR_OR_NULL(root))
0223         return;
0224     hba->debugfs_root = root;
0225     d_inode(root)->i_private = hba;
0226     for (attr = ufs_attrs; attr->name; attr++)
0227         debugfs_create_file(attr->name, attr->mode, root, (void *)attr,
0228                     attr->fops);
0229     debugfs_create_file("exception_event_mask", 0600, hba->debugfs_root,
0230                 hba, &ee_usr_mask_fops);
0231     debugfs_create_u32("exception_event_rate_limit_ms", 0600, hba->debugfs_root,
0232                &hba->debugfs_ee_rate_limit_ms);
0233 }
0234 
0235 void ufs_debugfs_hba_exit(struct ufs_hba *hba)
0236 {
0237     debugfs_remove_recursive(hba->debugfs_root);
0238     cancel_delayed_work_sync(&hba->debugfs_ee_work);
0239 }