Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / fs / debugfs / file.c
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
22 static ssize_t default_read_file(struct file *file, char __user *buf,
23                                  size_t count, loff_t *ppos)
24 {
25         return 0;
26 }
27
28 static 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
34 static 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
42 struct 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)                           \
49 static 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 }                                                                               \
58 static 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 }                                                                               \
78 static struct file_operations fops_##type = {                                   \
79         .read =         read_file_##type,                                       \
80         .write =        write_file_##type,                                      \
81         .open =         default_open,                                           \
82 };
83 simple_type(u8, "%c", unsigned long, simple_strtoul);
84 simple_type(u16, "%hi", unsigned long, simple_strtoul);
85 simple_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  */
112 struct 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 }
117 EXPORT_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  */
144 struct 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 }
149 EXPORT_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  */
176 struct 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 }
181 EXPORT_SYMBOL_GPL(debugfs_create_u32);
182
183 static 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
198 static 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
225 static 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  */
256 struct 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 }
261 EXPORT_SYMBOL_GPL(debugfs_create_bool);
262