Showing error 1278

User: Jiri Slaby
Error type: Leaving function in locked state
Error type description: Some lock is not unlocked on all paths of a function, so it is leaked
File location: drivers/isdn/capi/kcapi_proc.c
Line in file: 244
Project: Linux Kernel
Project version: 2.6.28
Tools: Stanse (1.2)
Entered: 2012-05-21 20:30:05 UTC


Source:

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