1  // SPDX-License-Identifier: GPL-2.0
2  /*
3   *  debugfs.h - a tiny little debug file system
4   *
5   *  Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
6   *  Copyright (C) 2004 IBM Inc.
7   *
8   *  debugfs is for people to use instead of /proc or /sys.
9   *  See Documentation/filesystems/ for more details.
10   */
11  
12  #ifndef _DEBUGFS_H_
13  #define _DEBUGFS_H_
14  
15  #include <linux/fs.h>
16  #include <linux/seq_file.h>
17  
18  #include <linux/types.h>
19  #include <linux/compiler.h>
20  
21  struct device;
22  struct file_operations;
23  
24  struct debugfs_blob_wrapper {
25  	void *data;
26  	unsigned long size;
27  };
28  
29  struct debugfs_reg32 {
30  	char *name;
31  	unsigned long offset;
32  };
33  
34  struct debugfs_regset32 {
35  	const struct debugfs_reg32 *regs;
36  	int nregs;
37  	void __iomem *base;
38  	struct device *dev;	/* Optional device for Runtime PM */
39  };
40  
41  struct debugfs_u32_array {
42  	u32 *array;
43  	u32 n_elements;
44  };
45  
46  extern struct dentry *arch_debugfs_dir;
47  
48  #define DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, __is_signed)	\
49  static int __fops ## _open(struct inode *inode, struct file *file)	\
50  {									\
51  	__simple_attr_check_format(__fmt, 0ull);			\
52  	return simple_attr_open(inode, file, __get, __set, __fmt);	\
53  }									\
54  static const struct file_operations __fops = {				\
55  	.owner	 = THIS_MODULE,						\
56  	.open	 = __fops ## _open,					\
57  	.release = simple_attr_release,					\
58  	.read	 = debugfs_attr_read,					\
59  	.write	 = (__is_signed) ? debugfs_attr_write_signed : debugfs_attr_write,	\
60  }
61  
62  #define DEFINE_DEBUGFS_ATTRIBUTE(__fops, __get, __set, __fmt)		\
63  	DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, false)
64  
65  #define DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(__fops, __get, __set, __fmt)	\
66  	DEFINE_DEBUGFS_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, true)
67  
68  typedef struct vfsmount *(*debugfs_automount_t)(struct dentry *, void *);
69  
70  #if defined(CONFIG_DEBUG_FS)
71  
72  struct dentry *debugfs_lookup(const char *name, struct dentry *parent);
73  
74  struct dentry *debugfs_create_file(const char *name, umode_t mode,
75  				   struct dentry *parent, void *data,
76  				   const struct file_operations *fops);
77  struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode,
78  				   struct dentry *parent, void *data,
79  				   const struct file_operations *fops);
80  
81  void debugfs_create_file_size(const char *name, umode_t mode,
82  			      struct dentry *parent, void *data,
83  			      const struct file_operations *fops,
84  			      loff_t file_size);
85  
86  struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);
87  
88  struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
89  				      const char *dest);
90  
91  struct dentry *debugfs_create_automount(const char *name,
92  					struct dentry *parent,
93  					debugfs_automount_t f,
94  					void *data);
95  
96  void debugfs_remove(struct dentry *dentry);
97  #define debugfs_remove_recursive debugfs_remove
98  
99  void debugfs_lookup_and_remove(const char *name, struct dentry *parent);
100  
101  const struct file_operations *debugfs_real_fops(const struct file *filp);
102  
103  int debugfs_file_get(struct dentry *dentry);
104  void debugfs_file_put(struct dentry *dentry);
105  
106  ssize_t debugfs_attr_read(struct file *file, char __user *buf,
107  			size_t len, loff_t *ppos);
108  ssize_t debugfs_attr_write(struct file *file, const char __user *buf,
109  			size_t len, loff_t *ppos);
110  ssize_t debugfs_attr_write_signed(struct file *file, const char __user *buf,
111  			size_t len, loff_t *ppos);
112  
113  struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
114                  struct dentry *new_dir, const char *new_name);
115  
116  void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent,
117  		       u8 *value);
118  void debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent,
119  			u16 *value);
120  void debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent,
121  			u32 *value);
122  void debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent,
123  			u64 *value);
124  void debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent,
125  			  unsigned long *value);
126  void debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent,
127  		       u8 *value);
128  void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent,
129  			u16 *value);
130  void debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent,
131  			u32 *value);
132  void debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent,
133  			u64 *value);
134  void debugfs_create_size_t(const char *name, umode_t mode,
135  			   struct dentry *parent, size_t *value);
136  void debugfs_create_atomic_t(const char *name, umode_t mode,
137  			     struct dentry *parent, atomic_t *value);
138  void debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent,
139  			 bool *value);
140  void debugfs_create_str(const char *name, umode_t mode,
141  			struct dentry *parent, char **value);
142  
143  struct dentry *debugfs_create_blob(const char *name, umode_t mode,
144  				  struct dentry *parent,
145  				  struct debugfs_blob_wrapper *blob);
146  
147  void debugfs_create_regset32(const char *name, umode_t mode,
148  			     struct dentry *parent,
149  			     struct debugfs_regset32 *regset);
150  
151  void debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs,
152  			  int nregs, void __iomem *base, char *prefix);
153  
154  void debugfs_create_u32_array(const char *name, umode_t mode,
155  			      struct dentry *parent,
156  			      struct debugfs_u32_array *array);
157  
158  void debugfs_create_devm_seqfile(struct device *dev, const char *name,
159  				 struct dentry *parent,
160  				 int (*read_fn)(struct seq_file *s, void *data));
161  
162  bool debugfs_initialized(void);
163  
164  ssize_t debugfs_read_file_bool(struct file *file, char __user *user_buf,
165  			       size_t count, loff_t *ppos);
166  
167  ssize_t debugfs_write_file_bool(struct file *file, const char __user *user_buf,
168  				size_t count, loff_t *ppos);
169  
170  ssize_t debugfs_read_file_str(struct file *file, char __user *user_buf,
171  			      size_t count, loff_t *ppos);
172  
173  /**
174   * struct debugfs_cancellation - cancellation data
175   * @list: internal, for keeping track
176   * @cancel: callback to call
177   * @cancel_data: extra data for the callback to call
178   */
179  struct debugfs_cancellation {
180  	struct list_head list;
181  	void (*cancel)(struct dentry *, void *);
182  	void *cancel_data;
183  };
184  
185  void __acquires(cancellation)
186  debugfs_enter_cancellation(struct file *file,
187  			   struct debugfs_cancellation *cancellation);
188  void __releases(cancellation)
189  debugfs_leave_cancellation(struct file *file,
190  			   struct debugfs_cancellation *cancellation);
191  
192  #else
193  
194  #include <linux/err.h>
195  
196  /*
197   * We do not return NULL from these functions if CONFIG_DEBUG_FS is not enabled
198   * so users have a chance to detect if there was a real error or not.  We don't
199   * want to duplicate the design decision mistakes of procfs and devfs again.
200   */
201  
debugfs_lookup(const char * name,struct dentry * parent)202  static inline struct dentry *debugfs_lookup(const char *name,
203  					    struct dentry *parent)
204  {
205  	return ERR_PTR(-ENODEV);
206  }
207  
debugfs_create_file(const char * name,umode_t mode,struct dentry * parent,void * data,const struct file_operations * fops)208  static inline struct dentry *debugfs_create_file(const char *name, umode_t mode,
209  					struct dentry *parent, void *data,
210  					const struct file_operations *fops)
211  {
212  	return ERR_PTR(-ENODEV);
213  }
214  
debugfs_create_file_unsafe(const char * name,umode_t mode,struct dentry * parent,void * data,const struct file_operations * fops)215  static inline struct dentry *debugfs_create_file_unsafe(const char *name,
216  					umode_t mode, struct dentry *parent,
217  					void *data,
218  					const struct file_operations *fops)
219  {
220  	return ERR_PTR(-ENODEV);
221  }
222  
debugfs_create_file_size(const char * name,umode_t mode,struct dentry * parent,void * data,const struct file_operations * fops,loff_t file_size)223  static inline void debugfs_create_file_size(const char *name, umode_t mode,
224  					    struct dentry *parent, void *data,
225  					    const struct file_operations *fops,
226  					    loff_t file_size)
227  { }
228  
debugfs_create_dir(const char * name,struct dentry * parent)229  static inline struct dentry *debugfs_create_dir(const char *name,
230  						struct dentry *parent)
231  {
232  	return ERR_PTR(-ENODEV);
233  }
234  
debugfs_create_symlink(const char * name,struct dentry * parent,const char * dest)235  static inline struct dentry *debugfs_create_symlink(const char *name,
236  						    struct dentry *parent,
237  						    const char *dest)
238  {
239  	return ERR_PTR(-ENODEV);
240  }
241  
debugfs_create_automount(const char * name,struct dentry * parent,debugfs_automount_t f,void * data)242  static inline struct dentry *debugfs_create_automount(const char *name,
243  					struct dentry *parent,
244  					debugfs_automount_t f,
245  					void *data)
246  {
247  	return ERR_PTR(-ENODEV);
248  }
249  
debugfs_remove(struct dentry * dentry)250  static inline void debugfs_remove(struct dentry *dentry)
251  { }
252  
debugfs_remove_recursive(struct dentry * dentry)253  static inline void debugfs_remove_recursive(struct dentry *dentry)
254  { }
255  
debugfs_lookup_and_remove(const char * name,struct dentry * parent)256  static inline void debugfs_lookup_and_remove(const char *name,
257  					     struct dentry *parent)
258  { }
259  
260  const struct file_operations *debugfs_real_fops(const struct file *filp);
261  
debugfs_file_get(struct dentry * dentry)262  static inline int debugfs_file_get(struct dentry *dentry)
263  {
264  	return 0;
265  }
266  
debugfs_file_put(struct dentry * dentry)267  static inline void debugfs_file_put(struct dentry *dentry)
268  { }
269  
debugfs_attr_read(struct file * file,char __user * buf,size_t len,loff_t * ppos)270  static inline ssize_t debugfs_attr_read(struct file *file, char __user *buf,
271  					size_t len, loff_t *ppos)
272  {
273  	return -ENODEV;
274  }
275  
debugfs_attr_write(struct file * file,const char __user * buf,size_t len,loff_t * ppos)276  static inline ssize_t debugfs_attr_write(struct file *file,
277  					const char __user *buf,
278  					size_t len, loff_t *ppos)
279  {
280  	return -ENODEV;
281  }
282  
debugfs_attr_write_signed(struct file * file,const char __user * buf,size_t len,loff_t * ppos)283  static inline ssize_t debugfs_attr_write_signed(struct file *file,
284  					const char __user *buf,
285  					size_t len, loff_t *ppos)
286  {
287  	return -ENODEV;
288  }
289  
debugfs_rename(struct dentry * old_dir,struct dentry * old_dentry,struct dentry * new_dir,char * new_name)290  static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
291                  struct dentry *new_dir, char *new_name)
292  {
293  	return ERR_PTR(-ENODEV);
294  }
295  
debugfs_create_u8(const char * name,umode_t mode,struct dentry * parent,u8 * value)296  static inline void debugfs_create_u8(const char *name, umode_t mode,
297  				     struct dentry *parent, u8 *value) { }
298  
debugfs_create_u16(const char * name,umode_t mode,struct dentry * parent,u16 * value)299  static inline void debugfs_create_u16(const char *name, umode_t mode,
300  				      struct dentry *parent, u16 *value) { }
301  
debugfs_create_u32(const char * name,umode_t mode,struct dentry * parent,u32 * value)302  static inline void debugfs_create_u32(const char *name, umode_t mode,
303  				      struct dentry *parent, u32 *value) { }
304  
debugfs_create_u64(const char * name,umode_t mode,struct dentry * parent,u64 * value)305  static inline void debugfs_create_u64(const char *name, umode_t mode,
306  				      struct dentry *parent, u64 *value) { }
307  
debugfs_create_ulong(const char * name,umode_t mode,struct dentry * parent,unsigned long * value)308  static inline void debugfs_create_ulong(const char *name, umode_t mode,
309  					struct dentry *parent,
310  					unsigned long *value) { }
311  
debugfs_create_x8(const char * name,umode_t mode,struct dentry * parent,u8 * value)312  static inline void debugfs_create_x8(const char *name, umode_t mode,
313  				     struct dentry *parent, u8 *value) { }
314  
debugfs_create_x16(const char * name,umode_t mode,struct dentry * parent,u16 * value)315  static inline void debugfs_create_x16(const char *name, umode_t mode,
316  				      struct dentry *parent, u16 *value) { }
317  
debugfs_create_x32(const char * name,umode_t mode,struct dentry * parent,u32 * value)318  static inline void debugfs_create_x32(const char *name, umode_t mode,
319  				      struct dentry *parent, u32 *value) { }
320  
debugfs_create_x64(const char * name,umode_t mode,struct dentry * parent,u64 * value)321  static inline void debugfs_create_x64(const char *name, umode_t mode,
322  				      struct dentry *parent, u64 *value) { }
323  
debugfs_create_size_t(const char * name,umode_t mode,struct dentry * parent,size_t * value)324  static inline void debugfs_create_size_t(const char *name, umode_t mode,
325  					 struct dentry *parent, size_t *value)
326  { }
327  
debugfs_create_atomic_t(const char * name,umode_t mode,struct dentry * parent,atomic_t * value)328  static inline void debugfs_create_atomic_t(const char *name, umode_t mode,
329  					   struct dentry *parent,
330  					   atomic_t *value)
331  { }
332  
debugfs_create_bool(const char * name,umode_t mode,struct dentry * parent,bool * value)333  static inline void debugfs_create_bool(const char *name, umode_t mode,
334  				       struct dentry *parent, bool *value) { }
335  
debugfs_create_str(const char * name,umode_t mode,struct dentry * parent,char ** value)336  static inline void debugfs_create_str(const char *name, umode_t mode,
337  				      struct dentry *parent,
338  				      char **value)
339  { }
340  
debugfs_create_blob(const char * name,umode_t mode,struct dentry * parent,struct debugfs_blob_wrapper * blob)341  static inline struct dentry *debugfs_create_blob(const char *name, umode_t mode,
342  				  struct dentry *parent,
343  				  struct debugfs_blob_wrapper *blob)
344  {
345  	return ERR_PTR(-ENODEV);
346  }
347  
debugfs_create_regset32(const char * name,umode_t mode,struct dentry * parent,struct debugfs_regset32 * regset)348  static inline void debugfs_create_regset32(const char *name, umode_t mode,
349  					   struct dentry *parent,
350  					   struct debugfs_regset32 *regset)
351  {
352  }
353  
debugfs_print_regs32(struct seq_file * s,const struct debugfs_reg32 * regs,int nregs,void __iomem * base,char * prefix)354  static inline void debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs,
355  			 int nregs, void __iomem *base, char *prefix)
356  {
357  }
358  
debugfs_initialized(void)359  static inline bool debugfs_initialized(void)
360  {
361  	return false;
362  }
363  
debugfs_create_u32_array(const char * name,umode_t mode,struct dentry * parent,struct debugfs_u32_array * array)364  static inline void debugfs_create_u32_array(const char *name, umode_t mode,
365  					    struct dentry *parent,
366  					    struct debugfs_u32_array *array)
367  {
368  }
369  
debugfs_create_devm_seqfile(struct device * dev,const char * name,struct dentry * parent,int (* read_fn)(struct seq_file * s,void * data))370  static inline void debugfs_create_devm_seqfile(struct device *dev,
371  					       const char *name,
372  					       struct dentry *parent,
373  					       int (*read_fn)(struct seq_file *s,
374  							      void *data))
375  {
376  }
377  
debugfs_read_file_bool(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)378  static inline ssize_t debugfs_read_file_bool(struct file *file,
379  					     char __user *user_buf,
380  					     size_t count, loff_t *ppos)
381  {
382  	return -ENODEV;
383  }
384  
debugfs_write_file_bool(struct file * file,const char __user * user_buf,size_t count,loff_t * ppos)385  static inline ssize_t debugfs_write_file_bool(struct file *file,
386  					      const char __user *user_buf,
387  					      size_t count, loff_t *ppos)
388  {
389  	return -ENODEV;
390  }
391  
debugfs_read_file_str(struct file * file,char __user * user_buf,size_t count,loff_t * ppos)392  static inline ssize_t debugfs_read_file_str(struct file *file,
393  					    char __user *user_buf,
394  					    size_t count, loff_t *ppos)
395  {
396  	return -ENODEV;
397  }
398  
399  #endif
400  
401  /**
402   * debugfs_create_xul - create a debugfs file that is used to read and write an
403   * unsigned long value, formatted in hexadecimal
404   * @name: a pointer to a string containing the name of the file to create.
405   * @mode: the permission that the file should have
406   * @parent: a pointer to the parent dentry for this file.  This should be a
407   *          directory dentry if set.  If this parameter is %NULL, then the
408   *          file will be created in the root of the debugfs filesystem.
409   * @value: a pointer to the variable that the file should read to and write
410   *         from.
411   */
debugfs_create_xul(const char * name,umode_t mode,struct dentry * parent,unsigned long * value)412  static inline void debugfs_create_xul(const char *name, umode_t mode,
413  				      struct dentry *parent,
414  				      unsigned long *value)
415  {
416  	if (sizeof(*value) == sizeof(u32))
417  		debugfs_create_x32(name, mode, parent, (u32 *)value);
418  	else
419  		debugfs_create_x64(name, mode, parent, (u64 *)value);
420  }
421  
422  #endif
423