Import 2.2.6pre3
[davej-history.git] / net / irda / irproc.c
blob6d7537e1fbbd7f8bf9608249450d6162e30b10c4
1 /*********************************************************************
2 *
3 * Filename: irproc.c
4 * Version: 1.0
5 * Description: Various entries in the /proc file system
6 * Status: Experimental.
7 * Author: Thomas Davis, <ratbert@radiks.net>
8 * Created at: Sat Feb 21 21:33:24 1998
9 * Modified at: Tue Apr 6 19:07:06 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
12 * Copyright (c) 1998, Thomas Davis, <ratbert@radiks.net>,
13 * All Rights Reserved.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
20 * I, Thomas Davis, provide no warranty for any of this software.
21 * This material is provided "AS-IS" and at no charge.
23 * Portions lifted from the linux/fs/procfs/ files.
25 ********************************************************************/
27 #include <linux/miscdevice.h>
28 #include <linux/proc_fs.h>
30 #include <net/irda/irda.h>
31 #include <net/irda/irmod.h>
32 #include <net/irda/irlap.h>
33 #include <net/irda/irlmp.h>
35 static int proc_irda_lookup(struct inode * dir, struct dentry *dentry);
37 static int proc_irda_readdir(struct file *filp, void *dirent,
38 filldir_t filldir);
40 extern int irda_device_proc_read(char *buf, char **start, off_t offset,
41 int len, int unused);
42 extern int irlap_proc_read(char *buf, char **start, off_t offset, int len,
43 int unused);
44 extern int irlmp_proc_read(char *buf, char **start, off_t offset, int len,
45 int unused);
46 extern int irttp_proc_read(char *buf, char **start, off_t offset, int len,
47 int unused);
48 extern int irias_proc_read(char *buf, char **start, off_t offset, int len,
49 int unused);
50 extern int discovery_proc_read(char *buf, char **start, off_t offset, int len,
51 int unused);
53 static int proc_discovery_read(char *buf, char **start, off_t offset, int len,
54 int unused);
56 enum irda_directory_inos {
57 PROC_IRDA_LAP = 1,
58 PROC_IRDA_LMP,
59 PROC_IRDA_TTP,
60 PROC_IRDA_LPT,
61 PROC_IRDA_COMM,
62 PROC_IRDA_IRDA_DEVICE,
63 PROC_IRDA_IRIAS
66 static struct file_operations proc_irda_dir_operations = {
67 NULL, /* lseek - default */
68 NULL, /* read - bad */
69 NULL, /* write - bad */
70 proc_irda_readdir, /* readdir */
71 NULL, /* select - default */
72 NULL, /* ioctl - default */
73 NULL, /* mmap */
74 NULL, /* no special open code */
75 NULL, /* no special release code */
76 NULL /* can't fsync */
80 * proc directories can do almost nothing..
82 struct inode_operations proc_irda_dir_inode_operations = {
83 &proc_irda_dir_operations, /* default net directory file-ops */
84 NULL, /* create */
85 proc_irda_lookup,
86 NULL, /* link */
87 NULL, /* unlink */
88 NULL, /* symlink */
89 NULL, /* mkdir */
90 NULL, /* rmdir */
91 NULL, /* mknod */
92 NULL, /* rename */
93 NULL, /* readlink */
94 NULL, /* follow_link */
95 NULL, /* readpage */
96 NULL, /* writepage */
97 NULL, /* bmap */
98 NULL, /* truncate */
99 NULL /* permission */
102 struct proc_dir_entry proc_irda = {
103 0, 4, "irda",
104 S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0,
105 0, &proc_irda_dir_inode_operations,
106 NULL, NULL,
107 NULL,
108 NULL, NULL
111 #if 0
112 struct proc_dir_entry proc_lpt = {
113 0, 3, "lpt",
114 S_IFREG | S_IRUGO, 1, 0, 0,
115 0, NULL /* ops -- default to array */,
116 &irlpt_proc_read /* get_info */,
118 #endif
120 struct proc_dir_entry proc_discovery = {
121 0, 9, "discovery",
122 S_IFREG | S_IRUGO, 1, 0, 0,
123 0, NULL /* ops -- default to array */,
124 &discovery_proc_read /* get_info */,
127 struct proc_dir_entry proc_irda_device = {
128 0, 11, "irda_device",
129 S_IFREG | S_IRUGO, 1, 0, 0,
130 0, NULL,
131 &irda_device_proc_read,
134 struct proc_dir_entry proc_ttp = {
135 0, 5, "irttp",
136 S_IFREG | S_IRUGO, 1, 0, 0,
137 0, NULL /* ops -- default to array */,
138 &irttp_proc_read /* get_info */,
141 struct proc_dir_entry proc_lmp = {
142 0, 5, "irlmp",
143 S_IFREG | S_IRUGO, 1, 0, 0,
144 0, NULL /* ops -- default to array */,
145 &irlmp_proc_read /* get_info */,
148 struct proc_dir_entry proc_lap = {
149 0, 5, "irlap",
150 S_IFREG | S_IRUGO, 1, 0, 0,
151 0, NULL /* ops -- default to array */,
152 &irlap_proc_read /* get_info */,
155 struct proc_dir_entry proc_ias = {
156 0, 5, "irias",
157 S_IFREG | S_IRUGO, 1, 0, 0,
158 0, NULL /* ops -- default to array */,
159 &irias_proc_read /* get_info */,
163 * Function proc_delete_dentry (dentry)
165 * Copy of proc/root.c because this function is invisible to the irda
166 * module
169 static void proc_delete_dentry(struct dentry * dentry)
171 d_drop(dentry);
174 static struct dentry_operations proc_dentry_operations =
176 NULL, /* revalidate */
177 NULL, /* d_hash */
178 NULL, /* d_compare */
179 proc_delete_dentry /* d_delete(struct dentry *) */
183 * Function irda_proc_register (void)
185 * Register irda entry in /proc file system
188 void irda_proc_register(void) {
189 proc_net_register(&proc_irda);
190 #ifdef MODULE
191 proc_irda.fill_inode = &irda_proc_modcount;
192 #endif /* MODULE */
193 proc_register(&proc_irda, &proc_lap);
194 proc_register(&proc_irda, &proc_lmp);
195 proc_register(&proc_irda, &proc_ttp);
196 proc_register(&proc_irda, &proc_ias);
197 proc_register(&proc_irda, &proc_irda_device);
198 proc_register(&proc_irda, &proc_discovery);
202 * Function irda_proc_unregister (void)
204 * Unregister irda entry in /proc file system
207 void irda_proc_unregister(void) {
208 proc_unregister(&proc_irda, proc_discovery.low_ino);
209 proc_unregister(&proc_irda, proc_irda_device.low_ino);
210 proc_unregister(&proc_irda, proc_ias.low_ino);
211 proc_unregister(&proc_irda, proc_ttp.low_ino);
212 proc_unregister(&proc_irda, proc_lmp.low_ino);
213 proc_unregister(&proc_irda, proc_lap.low_ino);
214 proc_unregister(proc_net, proc_irda.low_ino);
218 * Function proc_irda_lookup (dir, dentry)
220 * This is a copy of proc_lookup from the linux-2.2.x kernel
223 int proc_irda_lookup(struct inode * dir, struct dentry *dentry)
225 struct inode *inode;
226 struct proc_dir_entry * de;
227 int error;
229 error = -ENOTDIR;
230 if (!dir || !S_ISDIR(dir->i_mode))
231 goto out;
233 error = -ENOENT;
234 inode = NULL;
235 de = (struct proc_dir_entry *) dir->u.generic_ip;
236 if (de) {
237 for (de = de->subdir; de ; de = de->next) {
238 if (!de || !de->low_ino)
239 continue;
240 if (de->namelen != dentry->d_name.len)
241 continue;
242 if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
243 int ino = de->low_ino | (dir->i_ino & ~(0xffff));
244 error = -EINVAL;
245 inode = proc_get_inode(dir->i_sb, ino, de);
246 break;
251 if (inode) {
252 dentry->d_op = &proc_dentry_operations;
253 d_add(dentry, inode);
254 error = 0;
256 out:
257 return error;
261 * Function proc_irda_readdir (filp, dirent, filldir)
263 * This is a copy from linux/fs/proc because the function is invisible
264 * to the irda module
267 static int proc_irda_readdir(struct file *filp, void *dirent,
268 filldir_t filldir)
270 struct proc_dir_entry * de;
271 unsigned int ino;
272 int i;
274 struct inode *inode = filp->f_dentry->d_inode;
275 if (!inode || !S_ISDIR(inode->i_mode))
276 return -ENOTDIR;
277 ino = inode->i_ino;
278 de = (struct proc_dir_entry *) inode->u.generic_ip;
279 if (!de)
280 return -EINVAL;
281 i = filp->f_pos;
282 switch (i) {
283 case 0:
284 if (filldir(dirent, ".", 1, i, ino) < 0)
285 return 0;
286 i++;
287 filp->f_pos++;
288 /* fall through */
289 case 1:
290 if (filldir(dirent, "..", 2, i, de->parent->low_ino) < 0)
291 return 0;
292 i++;
293 filp->f_pos++;
294 /* fall through */
295 default:
296 ino &= ~0xffff;
297 de = de->subdir;
298 i -= 2;
299 for (;;) {
300 if (!de)
301 return 1;
302 if (!i)
303 break;
304 de = de->next;
305 i--;
308 do {
309 if (filldir(dirent, de->name, de->namelen, filp->f_pos,
310 ino | de->low_ino) < 0)
311 return 0;
312 filp->f_pos++;
313 de = de->next;
314 } while (de);
316 return 1;