aboutsummaryrefslogtreecommitdiffstats
path: root/fs/debugfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/debugfs/file.c')
-rw-r--r--fs/debugfs/file.c262
1 files changed, 262 insertions, 0 deletions
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
new file mode 100644
index 000000000000..548556ff2506
--- /dev/null
+++ b/fs/debugfs/file.c
@@ -0,0 +1,262 @@
1/*
2 * file.c - part of debugfs, a tiny little debug file system
3 *
4 * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
5 * Copyright (C) 2004 IBM Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version
9 * 2 as published by the Free Software Foundation.
10 *
11 * debugfs is for people to use instead of /proc or /sys.
12 * See Documentation/DocBook/kernel-api for more details.
13 *
14 */
15
16#include <linux/config.h>
17#include <linux/module.h>
18#include <linux/fs.h>
19#include <linux/pagemap.h>
20#include <linux/debugfs.h>
21
22static ssize_t default_read_file(struct file *file, char __user *buf,
23 size_t count, loff_t *ppos)
24{
25 return 0;
26}
27
28static ssize_t default_write_file(struct file *file, const char __user *buf,
29 size_t count, loff_t *ppos)
30{
31 return count;
32}
33
34static int default_open(struct inode *inode, struct file *file)
35{
36 if (inode->u.generic_ip)
37 file->private_data = inode->u.generic_ip;
38
39 return 0;
40}
41
42struct file_operations debugfs_file_operations = {
43 .read = default_read_file,
44 .write = default_write_file,
45 .open = default_open,
46};
47
48#define simple_type(type, format, temptype, strtolfn) \
49static ssize_t read_file_##type(struct file *file, char __user *user_buf, \
50 size_t count, loff_t *ppos) \
51{ \
52 char buf[32]; \
53 type *val = file->private_data; \
54 \
55 snprintf(buf, sizeof(buf), format "\n", *val); \
56 return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));\
57} \
58static ssize_t write_file_##type(struct file *file, const char __user *user_buf,\
59 size_t count, loff_t *ppos) \
60{ \
61 char *endp; \
62 char buf[32]; \
63 int buf_size; \
64 type *val = file->private_data; \
65 temptype tmp; \
66 \
67 memset(buf, 0x00, sizeof(buf)); \
68 buf_size = min(count, (sizeof(buf)-1)); \
69 if (copy_from_user(buf, user_buf, buf_size)) \
70 return -EFAULT; \
71 \
72 tmp = strtolfn(buf, &endp, 0); \
73 if ((endp == buf) || ((type)tmp != tmp)) \
74 return -EINVAL; \
75 *val = tmp; \
76 return count; \
77} \
78static struct file_operations fops_##type = { \
79 .read = read_file_##type, \
80 .write = write_file_##type, \
81 .open = default_open, \
82};
83simple_type(u8, "%c", unsigned long, simple_strtoul);
84simple_type(u16, "%hi", unsigned long, simple_strtoul);
85simple_type(u32, "%i", unsigned long, simple_strtoul);
86
87/**
88 * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
89 *
90 * @name: a pointer to a string containing the name of the file to create.
91 * @mode: the permission that the file should have
92 * @parent: a pointer to the parent dentry for this file. This should be a
93 * directory dentry if set. If this paramater is NULL, then the
94 * file will be created in the root of the debugfs filesystem.
95 * @value: a pointer to the variable that the file should read to and write
96 * from.
97 *
98 * This function creates a file in debugfs with the given name that
99 * contains the value of the variable @value. If the @mode variable is so
100 * set, it can be read from, and written to.
101 *
102 * This function will return a pointer to a dentry if it succeeds. This
103 * pointer must be passed to the debugfs_remove() function when the file is
104 * to be removed (no automatic cleanup happens if your module is unloaded,
105 * you are responsible here.) If an error occurs, NULL will be returned.
106 *
107 * If debugfs is not enabled in the kernel, the value -ENODEV will be
108 * returned. It is not wise to check for this value, but rather, check for
109 * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
110 * code.
111 */
112struct dentry *debugfs_create_u8(const char *name, mode_t mode,
113 struct dentry *parent, u8 *value)
114{
115 return debugfs_create_file(name, mode, parent, value, &fops_u8);
116}
117EXPORT_SYMBOL_GPL(debugfs_create_u8);
118
119/**
120 * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
121 *
122 * @name: a pointer to a string containing the name of the file to create.
123 * @mode: the permission that the file should have
124 * @parent: a pointer to the parent dentry for this file. This should be a
125 * directory dentry if set. If this paramater is NULL, then the
126 * file will be created in the root of the debugfs filesystem.
127 * @value: a pointer to the variable that the file should read to and write
128 * from.
129 *
130 * This function creates a file in debugfs with the given name that
131 * contains the value of the variable @value. If the @mode variable is so
132 * set, it can be read from, and written to.
133 *
134 * This function will return a pointer to a dentry if it succeeds. This
135 * pointer must be passed to the debugfs_remove() function when the file is
136 * to be removed (no automatic cleanup happens if your module is unloaded,
137 * you are responsible here.) If an error occurs, NULL will be returned.
138 *
139 * If debugfs is not enabled in the kernel, the value -ENODEV will be
140 * returned. It is not wise to check for this value, but rather, check for
141 * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
142 * code.
143 */
144struct dentry *debugfs_create_u16(const char *name, mode_t mode,
145 struct dentry *parent, u16 *value)
146{
147 return debugfs_create_file(name, mode, parent, value, &fops_u16);
148}
149EXPORT_SYMBOL_GPL(debugfs_create_u16);
150
151/**
152 * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
153 *
154 * @name: a pointer to a string containing the name of the file to create.
155 * @mode: the permission that the file should have
156 * @parent: a pointer to the parent dentry for this file. This should be a
157 * directory dentry if set. If this paramater is NULL, then the
158 * file will be created in the root of the debugfs filesystem.
159 * @value: a pointer to the variable that the file should read to and write
160 * from.
161 *
162 * This function creates a file in debugfs with the given name that
163 * contains the value of the variable @value. If the @mode variable is so
164 * set, it can be read from, and written to.
165 *
166 * This function will return a pointer to a dentry if it succeeds. This
167 * pointer must be passed to the debugfs_remove() function when the file is
168 * to be removed (no automatic cleanup happens if your module is unloaded,
169 * you are responsible here.) If an error occurs, NULL will be returned.
170 *
171 * If debugfs is not enabled in the kernel, the value -ENODEV will be
172 * returned. It is not wise to check for this value, but rather, check for
173 * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
174 * code.
175 */
176struct dentry *debugfs_create_u32(const char *name, mode_t mode,
177 struct dentry *parent, u32 *value)
178{
179 return debugfs_create_file(name, mode, parent, value, &fops_u32);
180}
181EXPORT_SYMBOL_GPL(debugfs_create_u32);
182
183static ssize_t read_file_bool(struct file *file, char __user *user_buf,
184 size_t count, loff_t *ppos)
185{
186 char buf[3];
187 u32 *val = file->private_data;
188
189 if (*val)
190 buf[0] = 'Y';
191 else
192 buf[0] = 'N';
193 buf[1] = '\n';
194 buf[2] = 0x00;
195 return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
196}
197
198static ssize_t write_file_bool(struct file *file, const char __user *user_buf,
199 size_t count, loff_t *ppos)
200{
201 char buf[32];
202 int buf_size;
203 u32 *val = file->private_data;
204
205 buf_size = min(count, (sizeof(buf)-1));
206 if (copy_from_user(buf, user_buf, buf_size))
207 return -EFAULT;
208
209 switch (buf[0]) {
210 case 'y':
211 case 'Y':
212 case '1':
213 *val = 1;
214 break;
215 case 'n':
216 case 'N':
217 case '0':
218 *val = 0;
219 break;
220 }
221
222 return count;
223}
224
225static struct file_operations fops_bool = {
226 .read = read_file_bool,
227 .write = write_file_bool,
228 .open = default_open,
229};
230
231/**
232 * debugfs_create_bool - create a file in the debugfs filesystem that is used to read and write a boolean value.
233 *
234 * @name: a pointer to a string containing the name of the file to create.
235 * @mode: the permission that the file should have
236 * @parent: a pointer to the parent dentry for this file. This should be a
237 * directory dentry if set. If this paramater is NULL, then the
238 * file will be created in the root of the debugfs filesystem.
239 * @value: a pointer to the variable that the file should read to and write
240 * from.
241 *
242 * This function creates a file in debugfs with the given name that
243 * contains the value of the variable @value. If the @mode variable is so
244 * set, it can be read from, and written to.
245 *
246 * This function will return a pointer to a dentry if it succeeds. This
247 * pointer must be passed to the debugfs_remove() function when the file is
248 * to be removed (no automatic cleanup happens if your module is unloaded,
249 * you are responsible here.) If an error occurs, NULL will be returned.
250 *
251 * If debugfs is not enabled in the kernel, the value -ENODEV will be
252 * returned. It is not wise to check for this value, but rather, check for
253 * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
254 * code.
255 */
256struct dentry *debugfs_create_bool(const char *name, mode_t mode,
257 struct dentry *parent, u32 *value)
258{
259 return debugfs_create_file(name, mode, parent, value, &fops_bool);
260}
261EXPORT_SYMBOL_GPL(debugfs_create_bool);
262