scsi: ufs: core: Make it easier to add new debugfs attributes
authorBart Van Assche <bvanassche@acm.org>
Wed, 20 Oct 2021 21:40:20 +0000 (14:40 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 27 Oct 2021 03:24:50 +0000 (23:24 -0400)
Introduce an array for debugfs attributes to make it easier to add new
debugfs attributes. Change the value of the inode.i_private pointer for
debugfs attributes from a pointer to the HBA data structure to a pointer to
the attribute description for the stats attribute. Store the HBA pointer in
the private data of the parent inode instead.

Link: https://lore.kernel.org/r/20211020214024.2007615-7-bvanassche@acm.org
Acked-by: Avri Altman <Avri.Altman@wdc.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/ufs/ufs-debugfs.c

index 4e1ff209b9336e2a88b0c114ec60d7a7d357ca6c..1d4e5aa4b7627566997180432eca155d0f2fe7c0 100644 (file)
@@ -8,6 +8,18 @@
 
 static struct dentry *ufs_debugfs_root;
 
+struct ufs_debugfs_attr {
+       const char                      *name;
+       mode_t                          mode;
+       const struct file_operations    *fops;
+};
+
+/* @file corresponds to a debugfs attribute in directory hba->debugfs_root. */
+static inline struct ufs_hba *hba_from_file(const struct file *file)
+{
+       return d_inode(file->f_path.dentry->d_parent)->i_private;
+}
+
 void __init ufs_debugfs_init(void)
 {
        ufs_debugfs_root = debugfs_create_dir("ufshcd", NULL);
@@ -20,7 +32,7 @@ void ufs_debugfs_exit(void)
 
 static int ufs_debugfs_stats_show(struct seq_file *s, void *data)
 {
-       struct ufs_hba *hba = s->private;
+       struct ufs_hba *hba = hba_from_file(s->file);
        struct ufs_event_hist *e = hba->ufs_stats.event;
 
 #define PRT(fmt, typ) \
@@ -126,13 +138,28 @@ static void ufs_debugfs_restart_ee(struct work_struct *work)
        ufs_debugfs_put_user_access(hba);
 }
 
+static const struct ufs_debugfs_attr ufs_attrs[] = {
+       { "stats", 0400, &ufs_debugfs_stats_fops },
+       { }
+};
+
 void ufs_debugfs_hba_init(struct ufs_hba *hba)
 {
+       const struct ufs_debugfs_attr *attr;
+       struct dentry *root;
+
        /* Set default exception event rate limit period to 20ms */
        hba->debugfs_ee_rate_limit_ms = 20;
        INIT_DELAYED_WORK(&hba->debugfs_ee_work, ufs_debugfs_restart_ee);
-       hba->debugfs_root = debugfs_create_dir(dev_name(hba->dev), ufs_debugfs_root);
-       debugfs_create_file("stats", 0400, hba->debugfs_root, hba, &ufs_debugfs_stats_fops);
+
+       root = debugfs_create_dir(dev_name(hba->dev), ufs_debugfs_root);
+       if (IS_ERR_OR_NULL(root))
+               return;
+       hba->debugfs_root = root;
+       d_inode(root)->i_private = hba;
+       for (attr = ufs_attrs; attr->name; attr++)
+               debugfs_create_file(attr->name, attr->mode, root, (void *)attr,
+                                   attr->fops);
        debugfs_create_file("exception_event_mask", 0600, hba->debugfs_root,
                            hba, &ee_usr_mask_fops);
        debugfs_create_u32("exception_event_rate_limit_ms", 0600, hba->debugfs_root,