Contents of /alx-src/trunk/kernel26-alx/linux/Documentation/DocBook/procfs_example.c
Parent Directory | Revision Log
Revision 628 -
(show annotations)
(download)
Wed Mar 4 10:48:58 2009 UTC (15 years, 2 months ago) by niro
File MIME type: text/plain
File size: 5243 byte(s)
Wed Mar 4 10:48:58 2009 UTC (15 years, 2 months ago) by niro
File MIME type: text/plain
File size: 5243 byte(s)
import linux sources based on 2.6.12-alx-r9: -using linux-2.6.12.6 -using 2.6.12-ck6 patch set -using fbsplash-0.9.2-r3 -using vesafb-tng-0.9-rc7 -using squashfs-2.2 -added cddvd-cmdfilter-drop.patch as ck dropped it -added via-epia-dri (cle266) patch -added zd1211-svn-32 wlan driver (http://zd1211.ath.cx/download/) -added debian patches to zd1211 for wep256 etc
1 | /* |
2 | * procfs_example.c: an example proc interface |
3 | * |
4 | * Copyright (C) 2001, Erik Mouw (J.A.K.Mouw@its.tudelft.nl) |
5 | * |
6 | * This file accompanies the procfs-guide in the Linux kernel |
7 | * source. Its main use is to demonstrate the concepts and |
8 | * functions described in the guide. |
9 | * |
10 | * This software has been developed while working on the LART |
11 | * computing board (http://www.lart.tudelft.nl/), which is |
12 | * sponsored by the Mobile Multi-media Communications |
13 | * (http://www.mmc.tudelft.nl/) and Ubiquitous Communications |
14 | * (http://www.ubicom.tudelft.nl/) projects. |
15 | * |
16 | * The author can be reached at: |
17 | * |
18 | * Erik Mouw |
19 | * Information and Communication Theory Group |
20 | * Faculty of Information Technology and Systems |
21 | * Delft University of Technology |
22 | * P.O. Box 5031 |
23 | * 2600 GA Delft |
24 | * The Netherlands |
25 | * |
26 | * |
27 | * This program is free software; you can redistribute |
28 | * it and/or modify it under the terms of the GNU General |
29 | * Public License as published by the Free Software |
30 | * Foundation; either version 2 of the License, or (at your |
31 | * option) any later version. |
32 | * |
33 | * This program is distributed in the hope that it will be |
34 | * useful, but WITHOUT ANY WARRANTY; without even the implied |
35 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
36 | * PURPOSE. See the GNU General Public License for more |
37 | * details. |
38 | * |
39 | * You should have received a copy of the GNU General Public |
40 | * License along with this program; if not, write to the |
41 | * Free Software Foundation, Inc., 59 Temple Place, |
42 | * Suite 330, Boston, MA 02111-1307 USA |
43 | * |
44 | */ |
45 | |
46 | #include <linux/module.h> |
47 | #include <linux/kernel.h> |
48 | #include <linux/init.h> |
49 | #include <linux/proc_fs.h> |
50 | #include <linux/jiffies.h> |
51 | #include <asm/uaccess.h> |
52 | |
53 | |
54 | #define MODULE_VERS "1.0" |
55 | #define MODULE_NAME "procfs_example" |
56 | |
57 | #define FOOBAR_LEN 8 |
58 | |
59 | struct fb_data_t { |
60 | char name[FOOBAR_LEN + 1]; |
61 | char value[FOOBAR_LEN + 1]; |
62 | }; |
63 | |
64 | |
65 | static struct proc_dir_entry *example_dir, *foo_file, |
66 | *bar_file, *jiffies_file, *symlink; |
67 | |
68 | |
69 | struct fb_data_t foo_data, bar_data; |
70 | |
71 | |
72 | static int proc_read_jiffies(char *page, char **start, |
73 | off_t off, int count, |
74 | int *eof, void *data) |
75 | { |
76 | int len; |
77 | |
78 | len = sprintf(page, "jiffies = %ld\n", |
79 | jiffies); |
80 | |
81 | return len; |
82 | } |
83 | |
84 | |
85 | static int proc_read_foobar(char *page, char **start, |
86 | off_t off, int count, |
87 | int *eof, void *data) |
88 | { |
89 | int len; |
90 | struct fb_data_t *fb_data = (struct fb_data_t *)data; |
91 | |
92 | /* DON'T DO THAT - buffer overruns are bad */ |
93 | len = sprintf(page, "%s = '%s'\n", |
94 | fb_data->name, fb_data->value); |
95 | |
96 | return len; |
97 | } |
98 | |
99 | |
100 | static int proc_write_foobar(struct file *file, |
101 | const char *buffer, |
102 | unsigned long count, |
103 | void *data) |
104 | { |
105 | int len; |
106 | struct fb_data_t *fb_data = (struct fb_data_t *)data; |
107 | |
108 | if(count > FOOBAR_LEN) |
109 | len = FOOBAR_LEN; |
110 | else |
111 | len = count; |
112 | |
113 | if(copy_from_user(fb_data->value, buffer, len)) |
114 | return -EFAULT; |
115 | |
116 | fb_data->value[len] = '\0'; |
117 | |
118 | return len; |
119 | } |
120 | |
121 | |
122 | static int __init init_procfs_example(void) |
123 | { |
124 | int rv = 0; |
125 | |
126 | /* create directory */ |
127 | example_dir = proc_mkdir(MODULE_NAME, NULL); |
128 | if(example_dir == NULL) { |
129 | rv = -ENOMEM; |
130 | goto out; |
131 | } |
132 | |
133 | example_dir->owner = THIS_MODULE; |
134 | |
135 | /* create jiffies using convenience function */ |
136 | jiffies_file = create_proc_read_entry("jiffies", |
137 | 0444, example_dir, |
138 | proc_read_jiffies, |
139 | NULL); |
140 | if(jiffies_file == NULL) { |
141 | rv = -ENOMEM; |
142 | goto no_jiffies; |
143 | } |
144 | |
145 | jiffies_file->owner = THIS_MODULE; |
146 | |
147 | /* create foo and bar files using same callback |
148 | * functions |
149 | */ |
150 | foo_file = create_proc_entry("foo", 0644, example_dir); |
151 | if(foo_file == NULL) { |
152 | rv = -ENOMEM; |
153 | goto no_foo; |
154 | } |
155 | |
156 | strcpy(foo_data.name, "foo"); |
157 | strcpy(foo_data.value, "foo"); |
158 | foo_file->data = &foo_data; |
159 | foo_file->read_proc = proc_read_foobar; |
160 | foo_file->write_proc = proc_write_foobar; |
161 | foo_file->owner = THIS_MODULE; |
162 | |
163 | bar_file = create_proc_entry("bar", 0644, example_dir); |
164 | if(bar_file == NULL) { |
165 | rv = -ENOMEM; |
166 | goto no_bar; |
167 | } |
168 | |
169 | strcpy(bar_data.name, "bar"); |
170 | strcpy(bar_data.value, "bar"); |
171 | bar_file->data = &bar_data; |
172 | bar_file->read_proc = proc_read_foobar; |
173 | bar_file->write_proc = proc_write_foobar; |
174 | bar_file->owner = THIS_MODULE; |
175 | |
176 | /* create symlink */ |
177 | symlink = proc_symlink("jiffies_too", example_dir, |
178 | "jiffies"); |
179 | if(symlink == NULL) { |
180 | rv = -ENOMEM; |
181 | goto no_symlink; |
182 | } |
183 | |
184 | symlink->owner = THIS_MODULE; |
185 | |
186 | /* everything OK */ |
187 | printk(KERN_INFO "%s %s initialised\n", |
188 | MODULE_NAME, MODULE_VERS); |
189 | return 0; |
190 | |
191 | no_symlink: |
192 | remove_proc_entry("tty", example_dir); |
193 | no_tty: |
194 | remove_proc_entry("bar", example_dir); |
195 | no_bar: |
196 | remove_proc_entry("foo", example_dir); |
197 | no_foo: |
198 | remove_proc_entry("jiffies", example_dir); |
199 | no_jiffies: |
200 | remove_proc_entry(MODULE_NAME, NULL); |
201 | out: |
202 | return rv; |
203 | } |
204 | |
205 | |
206 | static void __exit cleanup_procfs_example(void) |
207 | { |
208 | remove_proc_entry("jiffies_too", example_dir); |
209 | remove_proc_entry("tty", example_dir); |
210 | remove_proc_entry("bar", example_dir); |
211 | remove_proc_entry("foo", example_dir); |
212 | remove_proc_entry("jiffies", example_dir); |
213 | remove_proc_entry(MODULE_NAME, NULL); |
214 | |
215 | printk(KERN_INFO "%s %s removed\n", |
216 | MODULE_NAME, MODULE_VERS); |
217 | } |
218 | |
219 | |
220 | module_init(init_procfs_example); |
221 | module_exit(cleanup_procfs_example); |
222 | |
223 | MODULE_AUTHOR("Erik Mouw"); |
224 | MODULE_DESCRIPTION("procfs examples"); |