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. Signed-off-by: Bart Van Assche <bvanassche@xxxxxxx> --- drivers/scsi/ufs/ufs-debugfs.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ufs/ufs-debugfs.c b/drivers/scsi/ufs/ufs-debugfs.c index 4e1ff209b933..1d4e5aa4b762 100644 --- a/drivers/scsi/ufs/ufs-debugfs.c +++ b/drivers/scsi/ufs/ufs-debugfs.c @@ -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,