3e6e17a24389e5d6e3641dd7fe81fbe2cd69f7a2
[pandora-kernel.git] / drivers / isdn / capi / kcapi_proc.c
1 /*
2  * Kernel CAPI 2.0 Module - /proc/capi handling
3  * 
4  * Copyright 1999 by Carsten Paeth <calle@calle.de>
5  * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
6  * 
7  * This software may be used and distributed according to the terms
8  * of the GNU General Public License, incorporated herein by reference.
9  *
10  */
11
12
13 #include "kcapi.h"
14 #include <linux/proc_fs.h>
15 #include <linux/seq_file.h>
16 #include <linux/init.h>
17
18 static char *state2str(unsigned short state)
19 {
20         switch (state) {
21         case CAPI_CTR_DETECTED: return "detected";
22         case CAPI_CTR_LOADING:  return "loading";
23         case CAPI_CTR_RUNNING:  return "running";
24         default:                return "???";
25         }
26 }
27
28 // /proc/capi
29 // ===========================================================================
30
31 // /proc/capi/controller: 
32 //      cnr driver cardstate name driverinfo
33 // /proc/capi/contrstats:
34 //      cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
35 // ---------------------------------------------------------------------------
36
37 static void *controller_start(struct seq_file *seq, loff_t *pos)
38         __acquires(capi_controller_lock)
39 {
40         mutex_lock(&capi_controller_lock);
41
42         if (*pos < CAPI_MAXCONTR)
43                 return &capi_controller[*pos];
44
45         return NULL;
46 }
47
48 static void *controller_next(struct seq_file *seq, void *v, loff_t *pos)
49 {
50         ++*pos;
51         if (*pos < CAPI_MAXCONTR)
52                 return &capi_controller[*pos];
53
54         return NULL;
55 }
56
57 static void controller_stop(struct seq_file *seq, void *v)
58         __releases(capi_controller_lock)
59 {
60         mutex_unlock(&capi_controller_lock);
61 }
62
63 static int controller_show(struct seq_file *seq, void *v)
64 {
65         struct capi_ctr *ctr = *(struct capi_ctr **) v;
66
67         if (!ctr)
68                 return 0;
69
70         seq_printf(seq, "%d %-10s %-8s %-16s %s\n",
71                    ctr->cnr, ctr->driver_name,
72                    state2str(ctr->state),
73                    ctr->name,
74                    ctr->procinfo ?  ctr->procinfo(ctr) : "");
75
76         return 0;
77 }
78
79 static int contrstats_show(struct seq_file *seq, void *v)
80 {
81         struct capi_ctr *ctr = *(struct capi_ctr **) v;
82
83         if (!ctr)
84                 return 0;
85
86         seq_printf(seq, "%d %lu %lu %lu %lu\n",
87                    ctr->cnr, 
88                    ctr->nrecvctlpkt,
89                    ctr->nrecvdatapkt,
90                    ctr->nsentctlpkt,
91                    ctr->nsentdatapkt);
92
93         return 0;
94 }
95
96 static const struct seq_operations seq_controller_ops = {
97         .start  = controller_start,
98         .next   = controller_next,
99         .stop   = controller_stop,
100         .show   = controller_show,
101 };
102
103 static const struct seq_operations seq_contrstats_ops = {
104         .start  = controller_start,
105         .next   = controller_next,
106         .stop   = controller_stop,
107         .show   = contrstats_show,
108 };
109
110 static int seq_controller_open(struct inode *inode, struct file *file)
111 {
112         return seq_open(file, &seq_controller_ops);
113 }
114
115 static int seq_contrstats_open(struct inode *inode, struct file *file)
116 {
117         return seq_open(file, &seq_contrstats_ops);
118 }
119
120 static const struct file_operations proc_controller_ops = {
121         .owner          = THIS_MODULE,
122         .open           = seq_controller_open,
123         .read           = seq_read,
124         .llseek         = seq_lseek,
125         .release        = seq_release,
126 };
127
128 static const struct file_operations proc_contrstats_ops = {
129         .owner          = THIS_MODULE,
130         .open           = seq_contrstats_open,
131         .read           = seq_read,
132         .llseek         = seq_lseek,
133         .release        = seq_release,
134 };
135
136 // /proc/capi/applications: 
137 //      applid l3cnt dblkcnt dblklen #ncci recvqueuelen
138 // /proc/capi/applstats: 
139 //      applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
140 // ---------------------------------------------------------------------------
141
142 static void *
143 applications_start(struct seq_file *seq, loff_t *pos)
144 {
145         if (*pos < CAPI_MAXAPPL)
146                 return &capi_applications[*pos];
147
148         return NULL;
149 }
150
151 static void *
152 applications_next(struct seq_file *seq, void *v, loff_t *pos)
153 {
154         ++*pos;
155         if (*pos < CAPI_MAXAPPL)
156                 return &capi_applications[*pos];
157
158         return NULL;
159 }
160
161 static void
162 applications_stop(struct seq_file *seq, void *v)
163 {
164 }
165
166 static int
167 applications_show(struct seq_file *seq, void *v)
168 {
169         struct capi20_appl *ap = *(struct capi20_appl **) v;
170
171         if (!ap)
172                 return 0;
173
174         seq_printf(seq, "%u %d %d %d\n",
175                    ap->applid,
176                    ap->rparam.level3cnt,
177                    ap->rparam.datablkcnt,
178                    ap->rparam.datablklen);
179
180         return 0;
181 }
182
183 static int
184 applstats_show(struct seq_file *seq, void *v)
185 {
186         struct capi20_appl *ap = *(struct capi20_appl **) v;
187
188         if (!ap)
189                 return 0;
190
191         seq_printf(seq, "%u %lu %lu %lu %lu\n",
192                    ap->applid,
193                    ap->nrecvctlpkt,
194                    ap->nrecvdatapkt,
195                    ap->nsentctlpkt,
196                    ap->nsentdatapkt);
197
198         return 0;
199 }
200
201 static const struct seq_operations seq_applications_ops = {
202         .start  = applications_start,
203         .next   = applications_next,
204         .stop   = applications_stop,
205         .show   = applications_show,
206 };
207
208 static const struct seq_operations seq_applstats_ops = {
209         .start  = applications_start,
210         .next   = applications_next,
211         .stop   = applications_stop,
212         .show   = applstats_show,
213 };
214
215 static int
216 seq_applications_open(struct inode *inode, struct file *file)
217 {
218         return seq_open(file, &seq_applications_ops);
219 }
220
221 static int
222 seq_applstats_open(struct inode *inode, struct file *file)
223 {
224         return seq_open(file, &seq_applstats_ops);
225 }
226
227 static const struct file_operations proc_applications_ops = {
228         .owner          = THIS_MODULE,
229         .open           = seq_applications_open,
230         .read           = seq_read,
231         .llseek         = seq_lseek,
232         .release        = seq_release,
233 };
234
235 static const struct file_operations proc_applstats_ops = {
236         .owner          = THIS_MODULE,
237         .open           = seq_applstats_open,
238         .read           = seq_read,
239         .llseek         = seq_lseek,
240         .release        = seq_release,
241 };
242
243 // ---------------------------------------------------------------------------
244
245 static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
246         __acquires(&capi_drivers_lock)
247 {
248         mutex_lock(&capi_drivers_lock);
249         return seq_list_start(&capi_drivers, *pos);
250 }
251
252 static void *capi_driver_next(struct seq_file *seq, void *v, loff_t *pos)
253 {
254         return seq_list_next(v, &capi_drivers, pos);
255 }
256
257 static void capi_driver_stop(struct seq_file *seq, void *v)
258         __releases(&capi_drivers_lock)
259 {
260         mutex_unlock(&capi_drivers_lock);
261 }
262
263 static int capi_driver_show(struct seq_file *seq, void *v)
264 {
265         struct capi_driver *drv = list_entry(v, struct capi_driver, list);
266
267         seq_printf(seq, "%-32s %s\n", drv->name, drv->revision);
268         return 0;
269 }
270
271 static const struct seq_operations seq_capi_driver_ops = {
272         .start  = capi_driver_start,
273         .next   = capi_driver_next,
274         .stop   = capi_driver_stop,
275         .show   = capi_driver_show,
276 };
277
278 static int
279 seq_capi_driver_open(struct inode *inode, struct file *file)
280 {
281         int err;
282         err = seq_open(file, &seq_capi_driver_ops);
283         return err;
284 }
285
286 static const struct file_operations proc_driver_ops = {
287         .owner          = THIS_MODULE,
288         .open           = seq_capi_driver_open,
289         .read           = seq_read,
290         .llseek         = seq_lseek,
291         .release        = seq_release,
292 };
293
294 // ---------------------------------------------------------------------------
295
296 void __init 
297 kcapi_proc_init(void)
298 {
299         proc_mkdir("capi",             NULL);
300         proc_mkdir("capi/controllers", NULL);
301         proc_create("capi/controller",   0, NULL, &proc_controller_ops);
302         proc_create("capi/contrstats",   0, NULL, &proc_contrstats_ops);
303         proc_create("capi/applications", 0, NULL, &proc_applications_ops);
304         proc_create("capi/applstats",    0, NULL, &proc_applstats_ops);
305         proc_create("capi/driver",       0, NULL, &proc_driver_ops);
306 }
307
308 void __exit
309 kcapi_proc_exit(void)
310 {
311         remove_proc_entry("capi/driver",       NULL);
312         remove_proc_entry("capi/controller",   NULL);
313         remove_proc_entry("capi/contrstats",   NULL);
314         remove_proc_entry("capi/applications", NULL);
315         remove_proc_entry("capi/applstats",    NULL);
316         remove_proc_entry("capi/controllers",  NULL);
317         remove_proc_entry("capi",              NULL);
318 }