Merge branch 'x86-bootmem-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.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 *applications_start(struct seq_file *seq, loff_t *pos)
143         __acquires(capi_controller_lock)
144 {
145         mutex_lock(&capi_controller_lock);
146
147         if (*pos < CAPI_MAXAPPL)
148                 return &capi_applications[*pos];
149
150         return NULL;
151 }
152
153 static void *
154 applications_next(struct seq_file *seq, void *v, loff_t *pos)
155 {
156         ++*pos;
157         if (*pos < CAPI_MAXAPPL)
158                 return &capi_applications[*pos];
159
160         return NULL;
161 }
162
163 static void applications_stop(struct seq_file *seq, void *v)
164         __releases(capi_controller_lock)
165 {
166         mutex_unlock(&capi_controller_lock);
167 }
168
169 static int
170 applications_show(struct seq_file *seq, void *v)
171 {
172         struct capi20_appl *ap = *(struct capi20_appl **) v;
173
174         if (!ap)
175                 return 0;
176
177         seq_printf(seq, "%u %d %d %d\n",
178                    ap->applid,
179                    ap->rparam.level3cnt,
180                    ap->rparam.datablkcnt,
181                    ap->rparam.datablklen);
182
183         return 0;
184 }
185
186 static int
187 applstats_show(struct seq_file *seq, void *v)
188 {
189         struct capi20_appl *ap = *(struct capi20_appl **) v;
190
191         if (!ap)
192                 return 0;
193
194         seq_printf(seq, "%u %lu %lu %lu %lu\n",
195                    ap->applid,
196                    ap->nrecvctlpkt,
197                    ap->nrecvdatapkt,
198                    ap->nsentctlpkt,
199                    ap->nsentdatapkt);
200
201         return 0;
202 }
203
204 static const struct seq_operations seq_applications_ops = {
205         .start  = applications_start,
206         .next   = applications_next,
207         .stop   = applications_stop,
208         .show   = applications_show,
209 };
210
211 static const struct seq_operations seq_applstats_ops = {
212         .start  = applications_start,
213         .next   = applications_next,
214         .stop   = applications_stop,
215         .show   = applstats_show,
216 };
217
218 static int
219 seq_applications_open(struct inode *inode, struct file *file)
220 {
221         return seq_open(file, &seq_applications_ops);
222 }
223
224 static int
225 seq_applstats_open(struct inode *inode, struct file *file)
226 {
227         return seq_open(file, &seq_applstats_ops);
228 }
229
230 static const struct file_operations proc_applications_ops = {
231         .owner          = THIS_MODULE,
232         .open           = seq_applications_open,
233         .read           = seq_read,
234         .llseek         = seq_lseek,
235         .release        = seq_release,
236 };
237
238 static const struct file_operations proc_applstats_ops = {
239         .owner          = THIS_MODULE,
240         .open           = seq_applstats_open,
241         .read           = seq_read,
242         .llseek         = seq_lseek,
243         .release        = seq_release,
244 };
245
246 // ---------------------------------------------------------------------------
247
248 static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
249         __acquires(&capi_drivers_lock)
250 {
251         mutex_lock(&capi_drivers_lock);
252         return seq_list_start(&capi_drivers, *pos);
253 }
254
255 static void *capi_driver_next(struct seq_file *seq, void *v, loff_t *pos)
256 {
257         return seq_list_next(v, &capi_drivers, pos);
258 }
259
260 static void capi_driver_stop(struct seq_file *seq, void *v)
261         __releases(&capi_drivers_lock)
262 {
263         mutex_unlock(&capi_drivers_lock);
264 }
265
266 static int capi_driver_show(struct seq_file *seq, void *v)
267 {
268         struct capi_driver *drv = list_entry(v, struct capi_driver, list);
269
270         seq_printf(seq, "%-32s %s\n", drv->name, drv->revision);
271         return 0;
272 }
273
274 static const struct seq_operations seq_capi_driver_ops = {
275         .start  = capi_driver_start,
276         .next   = capi_driver_next,
277         .stop   = capi_driver_stop,
278         .show   = capi_driver_show,
279 };
280
281 static int
282 seq_capi_driver_open(struct inode *inode, struct file *file)
283 {
284         int err;
285         err = seq_open(file, &seq_capi_driver_ops);
286         return err;
287 }
288
289 static const struct file_operations proc_driver_ops = {
290         .owner          = THIS_MODULE,
291         .open           = seq_capi_driver_open,
292         .read           = seq_read,
293         .llseek         = seq_lseek,
294         .release        = seq_release,
295 };
296
297 // ---------------------------------------------------------------------------
298
299 void __init 
300 kcapi_proc_init(void)
301 {
302         proc_mkdir("capi",             NULL);
303         proc_mkdir("capi/controllers", NULL);
304         proc_create("capi/controller",   0, NULL, &proc_controller_ops);
305         proc_create("capi/contrstats",   0, NULL, &proc_contrstats_ops);
306         proc_create("capi/applications", 0, NULL, &proc_applications_ops);
307         proc_create("capi/applstats",    0, NULL, &proc_applstats_ops);
308         proc_create("capi/driver",       0, NULL, &proc_driver_ops);
309 }
310
311 void __exit
312 kcapi_proc_exit(void)
313 {
314         remove_proc_entry("capi/driver",       NULL);
315         remove_proc_entry("capi/controller",   NULL);
316         remove_proc_entry("capi/contrstats",   NULL);
317         remove_proc_entry("capi/applications", NULL);
318         remove_proc_entry("capi/applstats",    NULL);
319         remove_proc_entry("capi/controllers",  NULL);
320         remove_proc_entry("capi",              NULL);
321 }