CAPI: Use atomics for capiminor's datahandle and msgid
[safe/jmp/linux-2.6] / drivers / isdn / capi / capi.c
1 /* $Id: capi.c,v 1.1.2.7 2004/04/28 09:48:59 armin Exp $
2  *
3  * CAPI 2.0 Interface for Linux
4  *
5  * Copyright 1996 by Carsten Paeth <calle@calle.de>
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 #include <linux/module.h>
13 #include <linux/errno.h>
14 #include <linux/kernel.h>
15 #include <linux/major.h>
16 #include <linux/sched.h>
17 #include <linux/slab.h>
18 #include <linux/fcntl.h>
19 #include <linux/fs.h>
20 #include <linux/signal.h>
21 #include <linux/mutex.h>
22 #include <linux/mm.h>
23 #include <linux/smp_lock.h>
24 #include <linux/timer.h>
25 #include <linux/wait.h>
26 #include <linux/tty.h>
27 #include <linux/netdevice.h>
28 #include <linux/ppp_defs.h>
29 #include <linux/if_ppp.h>
30 #include <linux/skbuff.h>
31 #include <linux/proc_fs.h>
32 #include <linux/seq_file.h>
33 #include <linux/poll.h>
34 #include <linux/capi.h>
35 #include <linux/kernelcapi.h>
36 #include <linux/init.h>
37 #include <linux/device.h>
38 #include <linux/moduleparam.h>
39 #include <linux/isdn/capiutil.h>
40 #include <linux/isdn/capicmd.h>
41
42 #include "capifs.h"
43
44 MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface");
45 MODULE_AUTHOR("Carsten Paeth");
46 MODULE_LICENSE("GPL");
47
48 #undef _DEBUG_TTYFUNCS          /* call to tty_driver */
49 #undef _DEBUG_DATAFLOW          /* data flow */
50
51 /* -------- driver information -------------------------------------- */
52
53 static struct class *capi_class;
54 static int capi_major = 68;             /* allocated */
55
56 module_param_named(major, capi_major, uint, 0);
57
58 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
59 #define CAPINC_NR_PORTS         32
60 #define CAPINC_MAX_PORTS        256
61
62 static int capi_ttyminors = CAPINC_NR_PORTS;
63
64 module_param_named(ttyminors, capi_ttyminors, uint, 0);
65 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
66
67 /* -------- defines ------------------------------------------------- */
68
69 #define CAPINC_MAX_RECVQUEUE    10
70 #define CAPINC_MAX_SENDQUEUE    10
71 #define CAPI_MAX_BLKSIZE        2048
72
73 /* -------- data structures ----------------------------------------- */
74
75 struct capidev;
76 struct capincci;
77 struct capiminor;
78
79 struct ackqueue_entry {
80         struct list_head        list;
81         u16                     datahandle;
82 };
83
84 struct capiminor {
85         struct kref kref;
86
87         unsigned int      minor;
88         struct dentry *capifs_dentry;
89
90         struct capi20_appl      *ap;
91         u32                     ncci;
92         atomic_t                datahandle;
93         atomic_t                msgid;
94
95         struct tty_port port;
96         int                ttyinstop;
97         int                ttyoutstop;
98         struct sk_buff    *ttyskb;
99
100         struct sk_buff_head inqueue;
101         int                 inbytes;
102         struct sk_buff_head outqueue;
103         int                 outbytes;
104
105         /* transmit path */
106         struct list_head ackqueue;
107         int nack;
108         spinlock_t ackqlock;
109 };
110
111 /* FIXME: The following lock is a sledgehammer-workaround to a
112  * locking issue with the capiminor (and maybe other) data structure(s).
113  * Access to this data is done in a racy way and crashes the machine with
114  * a FritzCard DSL driver; sooner or later. This is a workaround
115  * which trades scalability vs stability, so it doesn't crash the kernel anymore.
116  * The correct (and scalable) fix for the issue seems to require
117  * an API change to the drivers... . */
118 static DEFINE_SPINLOCK(workaround_lock);
119
120 struct capincci {
121         struct list_head list;
122         u32              ncci;
123         struct capidev  *cdev;
124 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
125         struct capiminor *minorp;
126 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
127 };
128
129 struct capidev {
130         struct list_head list;
131         struct capi20_appl ap;
132         u16             errcode;
133         unsigned        userflags;
134
135         struct sk_buff_head recvqueue;
136         wait_queue_head_t recvwait;
137
138         struct list_head nccis;
139
140         struct mutex lock;
141 };
142
143 /* -------- global variables ---------------------------------------- */
144
145 static DEFINE_MUTEX(capidev_list_lock);
146 static LIST_HEAD(capidev_list);
147
148 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
149
150 static DEFINE_SPINLOCK(capiminors_lock);
151 static struct capiminor **capiminors;
152
153 static struct tty_driver *capinc_tty_driver;
154
155 /* -------- datahandles --------------------------------------------- */
156
157 static int capiminor_add_ack(struct capiminor *mp, u16 datahandle)
158 {
159         struct ackqueue_entry *n;
160         unsigned long flags;
161
162         n = kmalloc(sizeof(*n), GFP_ATOMIC);
163         if (unlikely(!n)) {
164                 printk(KERN_ERR "capi: alloc datahandle failed\n");
165                 return -1;
166         }
167         n->datahandle = datahandle;
168         INIT_LIST_HEAD(&n->list);
169         spin_lock_irqsave(&mp->ackqlock, flags);
170         list_add_tail(&n->list, &mp->ackqueue);
171         mp->nack++;
172         spin_unlock_irqrestore(&mp->ackqlock, flags);
173         return 0;
174 }
175
176 static int capiminor_del_ack(struct capiminor *mp, u16 datahandle)
177 {
178         struct ackqueue_entry *p, *tmp;
179         unsigned long flags;
180
181         spin_lock_irqsave(&mp->ackqlock, flags);
182         list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
183                 if (p->datahandle == datahandle) {
184                         list_del(&p->list);
185                         kfree(p);
186                         mp->nack--;
187                         spin_unlock_irqrestore(&mp->ackqlock, flags);
188                         return 0;
189                 }
190         }
191         spin_unlock_irqrestore(&mp->ackqlock, flags);
192         return -1;
193 }
194
195 static void capiminor_del_all_ack(struct capiminor *mp)
196 {
197         struct ackqueue_entry *p, *tmp;
198         unsigned long flags;
199
200         spin_lock_irqsave(&mp->ackqlock, flags);
201         list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
202                 list_del(&p->list);
203                 kfree(p);
204                 mp->nack--;
205         }
206         spin_unlock_irqrestore(&mp->ackqlock, flags);
207 }
208
209
210 /* -------- struct capiminor ---------------------------------------- */
211
212 static const struct tty_port_operations capiminor_port_ops; /* we have none */
213
214 static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
215 {
216         struct capiminor *mp;
217         struct device *dev;
218         unsigned int minor;
219
220         mp = kzalloc(sizeof(*mp), GFP_KERNEL);
221         if (!mp) {
222                 printk(KERN_ERR "capi: can't alloc capiminor\n");
223                 return NULL;
224         }
225
226         kref_init(&mp->kref);
227
228         mp->ap = ap;
229         mp->ncci = ncci;
230         INIT_LIST_HEAD(&mp->ackqueue);
231         spin_lock_init(&mp->ackqlock);
232
233         skb_queue_head_init(&mp->inqueue);
234         skb_queue_head_init(&mp->outqueue);
235
236         tty_port_init(&mp->port);
237         mp->port.ops = &capiminor_port_ops;
238
239         /* Allocate the least unused minor number. */
240         spin_lock(&capiminors_lock);
241         for (minor = 0; minor < capi_ttyminors; minor++)
242                 if (!capiminors[minor]) {
243                         capiminors[minor] = mp;
244                         break;
245                 }
246         spin_unlock(&capiminors_lock);
247
248         if (minor == capi_ttyminors) {
249                 printk(KERN_NOTICE "capi: out of minors\n");
250                 goto err_out1;
251         }
252
253         mp->minor = minor;
254
255         dev = tty_register_device(capinc_tty_driver, minor, NULL);
256         if (IS_ERR(dev))
257                 goto err_out2;
258
259         return mp;
260
261 err_out2:
262         spin_lock(&capiminors_lock);
263         capiminors[minor] = NULL;
264         spin_unlock(&capiminors_lock);
265
266 err_out1:
267         kfree(mp);
268         return NULL;
269 }
270
271 static void capiminor_destroy(struct kref *kref)
272 {
273         struct capiminor *mp = container_of(kref, struct capiminor, kref);
274
275         kfree_skb(mp->ttyskb);
276         skb_queue_purge(&mp->inqueue);
277         skb_queue_purge(&mp->outqueue);
278         capiminor_del_all_ack(mp);
279         kfree(mp);
280 }
281
282 static struct capiminor *capiminor_get(unsigned int minor)
283 {
284         struct capiminor *mp;
285
286         spin_lock(&capiminors_lock);
287         mp = capiminors[minor];
288         if (mp)
289                 kref_get(&mp->kref);
290         spin_unlock(&capiminors_lock);
291
292         return mp;
293 }
294
295 static inline void capiminor_put(struct capiminor *mp)
296 {
297         kref_put(&mp->kref, capiminor_destroy);
298 }
299
300 static void capiminor_free(struct capiminor *mp)
301 {
302         tty_unregister_device(capinc_tty_driver, mp->minor);
303
304         spin_lock(&capiminors_lock);
305         capiminors[mp->minor] = NULL;
306         spin_unlock(&capiminors_lock);
307
308         capiminor_put(mp);
309 }
310
311 /* -------- struct capincci ----------------------------------------- */
312
313 static void capincci_alloc_minor(struct capidev *cdev, struct capincci *np)
314 {
315         struct capiminor *mp;
316         dev_t device;
317
318         if (!(cdev->userflags & CAPIFLAG_HIGHJACKING))
319                 return;
320
321         mp = np->minorp = capiminor_alloc(&cdev->ap, np->ncci);
322         if (mp) {
323                 device = MKDEV(capinc_tty_driver->major, mp->minor);
324                 mp->capifs_dentry = capifs_new_ncci(mp->minor, device);
325         }
326 }
327
328 static void capincci_free_minor(struct capincci *np)
329 {
330         struct capiminor *mp = np->minorp;
331         struct tty_struct *tty;
332
333         if (mp) {
334                 capifs_free_ncci(mp->capifs_dentry);
335
336                 tty = tty_port_tty_get(&mp->port);
337                 if (tty) {
338                         tty_vhangup(tty);
339                         tty_kref_put(tty);
340                 }
341
342                 capiminor_free(mp);
343         }
344 }
345
346 static inline unsigned int capincci_minor_opencount(struct capincci *np)
347 {
348         struct capiminor *mp = np->minorp;
349         unsigned int count = 0;
350         struct tty_struct *tty;
351
352         if (mp) {
353                 tty = tty_port_tty_get(&mp->port);
354                 if (tty) {
355                         count = tty->count;
356                         tty_kref_put(tty);
357                 }
358         }
359         return count;
360 }
361
362 #else /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
363
364 static inline void
365 capincci_alloc_minor(struct capidev *cdev, struct capincci *np) { }
366 static inline void capincci_free_minor(struct capincci *np) { }
367
368 static inline unsigned int capincci_minor_opencount(struct capincci *np)
369 {
370         return 0;
371 }
372
373 #endif /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
374
375 static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci)
376 {
377         struct capincci *np;
378
379         np = kzalloc(sizeof(*np), GFP_KERNEL);
380         if (!np)
381                 return NULL;
382         np->ncci = ncci;
383         np->cdev = cdev;
384
385         capincci_alloc_minor(cdev, np);
386
387         list_add_tail(&np->list, &cdev->nccis);
388
389         return np;
390 }
391
392 static void capincci_free(struct capidev *cdev, u32 ncci)
393 {
394         struct capincci *np, *tmp;
395
396         list_for_each_entry_safe(np, tmp, &cdev->nccis, list)
397                 if (ncci == 0xffffffff || np->ncci == ncci) {
398                         capincci_free_minor(np);
399                         list_del(&np->list);
400                         kfree(np);
401                 }
402 }
403
404 static struct capincci *capincci_find(struct capidev *cdev, u32 ncci)
405 {
406         struct capincci *np;
407
408         list_for_each_entry(np, &cdev->nccis, list)
409                 if (np->ncci == ncci)
410                         return np;
411         return NULL;
412 }
413
414 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
415 /* -------- handle data queue --------------------------------------- */
416
417 static struct sk_buff *
418 gen_data_b3_resp_for(struct capiminor *mp, struct sk_buff *skb)
419 {
420         struct sk_buff *nskb;
421         nskb = alloc_skb(CAPI_DATA_B3_RESP_LEN, GFP_ATOMIC);
422         if (nskb) {
423                 u16 datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4+4+2);
424                 unsigned char *s = skb_put(nskb, CAPI_DATA_B3_RESP_LEN);
425                 capimsg_setu16(s, 0, CAPI_DATA_B3_RESP_LEN);
426                 capimsg_setu16(s, 2, mp->ap->applid);
427                 capimsg_setu8 (s, 4, CAPI_DATA_B3);
428                 capimsg_setu8 (s, 5, CAPI_RESP);
429                 capimsg_setu16(s, 6, atomic_inc_return(&mp->msgid));
430                 capimsg_setu32(s, 8, mp->ncci);
431                 capimsg_setu16(s, 12, datahandle);
432         }
433         return nskb;
434 }
435
436 static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
437 {
438         unsigned int datalen = skb->len - CAPIMSG_LEN(skb->data);
439         struct tty_struct *tty;
440         struct sk_buff *nskb;
441         u16 errcode, datahandle;
442         struct tty_ldisc *ld;
443         int ret = -1;
444
445         tty = tty_port_tty_get(&mp->port);
446         if (!tty) {
447 #ifdef _DEBUG_DATAFLOW
448                 printk(KERN_DEBUG "capi: currently no receiver\n");
449 #endif
450                 return -1;
451         }
452         
453         ld = tty_ldisc_ref(tty);
454         if (!ld) {
455                 /* fatal error, do not requeue */
456                 ret = 0;
457                 kfree_skb(skb);
458                 goto deref_tty;
459         }
460
461         if (ld->ops->receive_buf == NULL) {
462 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
463                 printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n");
464 #endif
465                 /* fatal error, do not requeue */
466                 goto free_skb;
467         }
468         if (mp->ttyinstop) {
469 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
470                 printk(KERN_DEBUG "capi: recv tty throttled\n");
471 #endif
472                 goto deref_ldisc;
473         }
474
475         if (tty->receive_room < datalen) {
476 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
477                 printk(KERN_DEBUG "capi: no room in tty\n");
478 #endif
479                 goto deref_ldisc;
480         }
481
482         nskb = gen_data_b3_resp_for(mp, skb);
483         if (!nskb) {
484                 printk(KERN_ERR "capi: gen_data_b3_resp failed\n");
485                 goto deref_ldisc;
486         }
487
488         datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4);
489
490         errcode = capi20_put_message(mp->ap, nskb);
491
492         if (errcode == CAPI_NOERROR) {
493                 skb_pull(skb, CAPIMSG_LEN(skb->data));
494 #ifdef _DEBUG_DATAFLOW
495                 printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
496                                         datahandle, skb->len);
497 #endif
498                 ld->ops->receive_buf(tty, skb->data, NULL, skb->len);
499         } else {
500                 printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
501                                 errcode);
502                 kfree_skb(nskb);
503
504                 if (errcode == CAPI_SENDQUEUEFULL)
505                         goto deref_ldisc;
506         }
507
508 free_skb:
509         ret = 0;
510         kfree_skb(skb);
511
512 deref_ldisc:
513         tty_ldisc_deref(ld);
514
515 deref_tty:
516         tty_kref_put(tty);
517         return ret;
518 }
519
520 static void handle_minor_recv(struct capiminor *mp)
521 {
522         struct sk_buff *skb;
523         while ((skb = skb_dequeue(&mp->inqueue)) != NULL) {
524                 unsigned int len = skb->len;
525                 mp->inbytes -= len;
526                 if (handle_recv_skb(mp, skb) < 0) {
527                         skb_queue_head(&mp->inqueue, skb);
528                         mp->inbytes += len;
529                         return;
530                 }
531         }
532 }
533
534 static int handle_minor_send(struct capiminor *mp)
535 {
536         struct tty_struct *tty;
537         struct sk_buff *skb;
538         u16 len;
539         int count = 0;
540         u16 errcode;
541         u16 datahandle;
542
543         tty = tty_port_tty_get(&mp->port);
544         if (!tty)
545                 return 0;
546
547         if (mp->ttyoutstop) {
548 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
549                 printk(KERN_DEBUG "capi: send: tty stopped\n");
550 #endif
551                 tty_kref_put(tty);
552                 return 0;
553         }
554
555         while ((skb = skb_dequeue(&mp->outqueue)) != NULL) {
556                 datahandle = atomic_inc_return(&mp->datahandle);
557                 len = (u16)skb->len;
558                 skb_push(skb, CAPI_DATA_B3_REQ_LEN);
559                 memset(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
560                 capimsg_setu16(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
561                 capimsg_setu16(skb->data, 2, mp->ap->applid);
562                 capimsg_setu8 (skb->data, 4, CAPI_DATA_B3);
563                 capimsg_setu8 (skb->data, 5, CAPI_REQ);
564                 capimsg_setu16(skb->data, 6, atomic_inc_return(&mp->msgid));
565                 capimsg_setu32(skb->data, 8, mp->ncci); /* NCCI */
566                 capimsg_setu32(skb->data, 12, (u32)(long)skb->data);/* Data32 */
567                 capimsg_setu16(skb->data, 16, len);     /* Data length */
568                 capimsg_setu16(skb->data, 18, datahandle);
569                 capimsg_setu16(skb->data, 20, 0);       /* Flags */
570
571                 if (capiminor_add_ack(mp, datahandle) < 0) {
572                         skb_pull(skb, CAPI_DATA_B3_REQ_LEN);
573                         skb_queue_head(&mp->outqueue, skb);
574                         tty_kref_put(tty);
575                         return count;
576                 }
577                 errcode = capi20_put_message(mp->ap, skb);
578                 if (errcode == CAPI_NOERROR) {
579                         count++;
580                         mp->outbytes -= len;
581 #ifdef _DEBUG_DATAFLOW
582                         printk(KERN_DEBUG "capi: DATA_B3_REQ %u len=%u\n",
583                                                         datahandle, len);
584 #endif
585                         continue;
586                 }
587                 capiminor_del_ack(mp, datahandle);
588
589                 if (errcode == CAPI_SENDQUEUEFULL) {
590                         skb_pull(skb, CAPI_DATA_B3_REQ_LEN);
591                         skb_queue_head(&mp->outqueue, skb);
592                         break;
593                 }
594
595                 /* ups, drop packet */
596                 printk(KERN_ERR "capi: put_message = %x\n", errcode);
597                 mp->outbytes -= len;
598                 kfree_skb(skb);
599         }
600         tty_kref_put(tty);
601         return count;
602 }
603
604 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
605 /* -------- function called by lower level -------------------------- */
606
607 static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
608 {
609         struct capidev *cdev = ap->private;
610 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
611         struct tty_struct *tty;
612         struct capiminor *mp;
613         u16 datahandle;
614 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
615         struct capincci *np;
616         unsigned long flags;
617
618         mutex_lock(&cdev->lock);
619
620         if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) {
621                 u16 info = CAPIMSG_U16(skb->data, 12); // Info field
622                 if ((info & 0xff00) == 0)
623                         capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
624         }
625         if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND)
626                 capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
627
628         spin_lock_irqsave(&workaround_lock, flags);
629         if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) {
630                 skb_queue_tail(&cdev->recvqueue, skb);
631                 wake_up_interruptible(&cdev->recvwait);
632                 goto unlock_out;
633         }
634
635         np = capincci_find(cdev, CAPIMSG_CONTROL(skb->data));
636         if (!np) {
637                 printk(KERN_ERR "BUG: capi_signal: ncci not found\n");
638                 skb_queue_tail(&cdev->recvqueue, skb);
639                 wake_up_interruptible(&cdev->recvwait);
640                 goto unlock_out;
641         }
642
643 #ifndef CONFIG_ISDN_CAPI_MIDDLEWARE
644         skb_queue_tail(&cdev->recvqueue, skb);
645         wake_up_interruptible(&cdev->recvwait);
646
647 #else /* CONFIG_ISDN_CAPI_MIDDLEWARE */
648
649         mp = np->minorp;
650         if (!mp) {
651                 skb_queue_tail(&cdev->recvqueue, skb);
652                 wake_up_interruptible(&cdev->recvwait);
653                 goto unlock_out;
654         }
655         if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
656                 datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2);
657 #ifdef _DEBUG_DATAFLOW
658                 printk(KERN_DEBUG "capi_signal: DATA_B3_IND %u len=%d\n",
659                                 datahandle, skb->len-CAPIMSG_LEN(skb->data));
660 #endif
661                 skb_queue_tail(&mp->inqueue, skb);
662                 mp->inbytes += skb->len;
663                 handle_minor_recv(mp);
664
665         } else if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF) {
666
667                 datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4);
668 #ifdef _DEBUG_DATAFLOW
669                 printk(KERN_DEBUG "capi_signal: DATA_B3_CONF %u 0x%x\n",
670                                 datahandle,
671                                 CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2));
672 #endif
673                 kfree_skb(skb);
674                 (void)capiminor_del_ack(mp, datahandle);
675                 tty = tty_port_tty_get(&mp->port);
676                 if (tty) {
677                         tty_wakeup(tty);
678                         tty_kref_put(tty);
679                 }
680                 (void)handle_minor_send(mp);
681
682         } else {
683                 /* ups, let capi application handle it :-) */
684                 skb_queue_tail(&cdev->recvqueue, skb);
685                 wake_up_interruptible(&cdev->recvwait);
686         }
687 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
688
689 unlock_out:
690         spin_unlock_irqrestore(&workaround_lock, flags);
691         mutex_unlock(&cdev->lock);
692 }
693
694 /* -------- file_operations for capidev ----------------------------- */
695
696 static ssize_t
697 capi_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
698 {
699         struct capidev *cdev = (struct capidev *)file->private_data;
700         struct sk_buff *skb;
701         size_t copied;
702         int err;
703
704         if (!cdev->ap.applid)
705                 return -ENODEV;
706
707         skb = skb_dequeue(&cdev->recvqueue);
708         if (!skb) {
709                 if (file->f_flags & O_NONBLOCK)
710                         return -EAGAIN;
711                 err = wait_event_interruptible(cdev->recvwait,
712                                 (skb = skb_dequeue(&cdev->recvqueue)));
713                 if (err)
714                         return err;
715         }
716         if (skb->len > count) {
717                 skb_queue_head(&cdev->recvqueue, skb);
718                 return -EMSGSIZE;
719         }
720         if (copy_to_user(buf, skb->data, skb->len)) {
721                 skb_queue_head(&cdev->recvqueue, skb);
722                 return -EFAULT;
723         }
724         copied = skb->len;
725
726         kfree_skb(skb);
727
728         return copied;
729 }
730
731 static ssize_t
732 capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
733 {
734         struct capidev *cdev = (struct capidev *)file->private_data;
735         struct sk_buff *skb;
736         u16 mlen;
737
738         if (!cdev->ap.applid)
739                 return -ENODEV;
740
741         skb = alloc_skb(count, GFP_USER);
742         if (!skb)
743                 return -ENOMEM;
744
745         if (copy_from_user(skb_put(skb, count), buf, count)) {
746                 kfree_skb(skb);
747                 return -EFAULT;
748         }
749         mlen = CAPIMSG_LEN(skb->data);
750         if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
751                 if ((size_t)(mlen + CAPIMSG_DATALEN(skb->data)) != count) {
752                         kfree_skb(skb);
753                         return -EINVAL;
754                 }
755         } else {
756                 if (mlen != count) {
757                         kfree_skb(skb);
758                         return -EINVAL;
759                 }
760         }
761         CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);
762
763         if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) {
764                 mutex_lock(&cdev->lock);
765                 capincci_free(cdev, CAPIMSG_NCCI(skb->data));
766                 mutex_unlock(&cdev->lock);
767         }
768
769         cdev->errcode = capi20_put_message(&cdev->ap, skb);
770
771         if (cdev->errcode) {
772                 kfree_skb(skb);
773                 return -EIO;
774         }
775         return count;
776 }
777
778 static unsigned int
779 capi_poll(struct file *file, poll_table * wait)
780 {
781         struct capidev *cdev = (struct capidev *)file->private_data;
782         unsigned int mask = 0;
783
784         if (!cdev->ap.applid)
785                 return POLLERR;
786
787         poll_wait(file, &(cdev->recvwait), wait);
788         mask = POLLOUT | POLLWRNORM;
789         if (!skb_queue_empty(&cdev->recvqueue))
790                 mask |= POLLIN | POLLRDNORM;
791         return mask;
792 }
793
794 static int
795 capi_ioctl(struct inode *inode, struct file *file,
796            unsigned int cmd, unsigned long arg)
797 {
798         struct capidev *cdev = file->private_data;
799         capi_ioctl_struct data;
800         int retval = -EINVAL;
801         void __user *argp = (void __user *)arg;
802
803         switch (cmd) {
804         case CAPI_REGISTER:
805                 mutex_lock(&cdev->lock);
806
807                 if (cdev->ap.applid) {
808                         retval = -EEXIST;
809                         goto register_out;
810                 }
811                 if (copy_from_user(&cdev->ap.rparam, argp,
812                                    sizeof(struct capi_register_params))) {
813                         retval = -EFAULT;
814                         goto register_out;
815                 }
816                 cdev->ap.private = cdev;
817                 cdev->ap.recv_message = capi_recv_message;
818                 cdev->errcode = capi20_register(&cdev->ap);
819                 retval = (int)cdev->ap.applid;
820                 if (cdev->errcode) {
821                         cdev->ap.applid = 0;
822                         retval = -EIO;
823                 }
824
825 register_out:
826                 mutex_unlock(&cdev->lock);
827                 return retval;
828
829         case CAPI_GET_VERSION:
830                 {
831                         if (copy_from_user(&data.contr, argp,
832                                                 sizeof(data.contr)))
833                                 return -EFAULT;
834                         cdev->errcode = capi20_get_version(data.contr, &data.version);
835                         if (cdev->errcode)
836                                 return -EIO;
837                         if (copy_to_user(argp, &data.version,
838                                          sizeof(data.version)))
839                                 return -EFAULT;
840                 }
841                 return 0;
842
843         case CAPI_GET_SERIAL:
844                 {
845                         if (copy_from_user(&data.contr, argp,
846                                            sizeof(data.contr)))
847                                 return -EFAULT;
848                         cdev->errcode = capi20_get_serial (data.contr, data.serial);
849                         if (cdev->errcode)
850                                 return -EIO;
851                         if (copy_to_user(argp, data.serial,
852                                          sizeof(data.serial)))
853                                 return -EFAULT;
854                 }
855                 return 0;
856         case CAPI_GET_PROFILE:
857                 {
858                         if (copy_from_user(&data.contr, argp,
859                                            sizeof(data.contr)))
860                                 return -EFAULT;
861
862                         if (data.contr == 0) {
863                                 cdev->errcode = capi20_get_profile(data.contr, &data.profile);
864                                 if (cdev->errcode)
865                                         return -EIO;
866
867                                 retval = copy_to_user(argp,
868                                       &data.profile.ncontroller,
869                                        sizeof(data.profile.ncontroller));
870
871                         } else {
872                                 cdev->errcode = capi20_get_profile(data.contr, &data.profile);
873                                 if (cdev->errcode)
874                                         return -EIO;
875
876                                 retval = copy_to_user(argp, &data.profile,
877                                                    sizeof(data.profile));
878                         }
879                         if (retval)
880                                 return -EFAULT;
881                 }
882                 return 0;
883
884         case CAPI_GET_MANUFACTURER:
885                 {
886                         if (copy_from_user(&data.contr, argp,
887                                            sizeof(data.contr)))
888                                 return -EFAULT;
889                         cdev->errcode = capi20_get_manufacturer(data.contr, data.manufacturer);
890                         if (cdev->errcode)
891                                 return -EIO;
892
893                         if (copy_to_user(argp, data.manufacturer,
894                                          sizeof(data.manufacturer)))
895                                 return -EFAULT;
896
897                 }
898                 return 0;
899         case CAPI_GET_ERRCODE:
900                 data.errcode = cdev->errcode;
901                 cdev->errcode = CAPI_NOERROR;
902                 if (arg) {
903                         if (copy_to_user(argp, &data.errcode,
904                                          sizeof(data.errcode)))
905                                 return -EFAULT;
906                 }
907                 return data.errcode;
908
909         case CAPI_INSTALLED:
910                 if (capi20_isinstalled() == CAPI_NOERROR)
911                         return 0;
912                 return -ENXIO;
913
914         case CAPI_MANUFACTURER_CMD:
915                 {
916                         struct capi_manufacturer_cmd mcmd;
917                         if (!capable(CAP_SYS_ADMIN))
918                                 return -EPERM;
919                         if (copy_from_user(&mcmd, argp, sizeof(mcmd)))
920                                 return -EFAULT;
921                         return capi20_manufacturer(mcmd.cmd, mcmd.data);
922                 }
923                 return 0;
924
925         case CAPI_SET_FLAGS:
926         case CAPI_CLR_FLAGS: {
927                 unsigned userflags;
928
929                 if (copy_from_user(&userflags, argp, sizeof(userflags)))
930                         return -EFAULT;
931
932                 mutex_lock(&cdev->lock);
933                 if (cmd == CAPI_SET_FLAGS)
934                         cdev->userflags |= userflags;
935                 else
936                         cdev->userflags &= ~userflags;
937                 mutex_unlock(&cdev->lock);
938                 return 0;
939         }
940         case CAPI_GET_FLAGS:
941                 if (copy_to_user(argp, &cdev->userflags,
942                                  sizeof(cdev->userflags)))
943                         return -EFAULT;
944                 return 0;
945
946         case CAPI_NCCI_OPENCOUNT: {
947                 struct capincci *nccip;
948                 unsigned ncci;
949                 int count = 0;
950
951                 if (copy_from_user(&ncci, argp, sizeof(ncci)))
952                         return -EFAULT;
953
954                 mutex_lock(&cdev->lock);
955                 nccip = capincci_find(cdev, (u32)ncci);
956                 if (nccip)
957                         count = capincci_minor_opencount(nccip);
958                 mutex_unlock(&cdev->lock);
959                 return count;
960         }
961
962 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
963         case CAPI_NCCI_GETUNIT: {
964                 struct capincci *nccip;
965                 struct capiminor *mp;
966                 unsigned ncci;
967                 int unit = -ESRCH;
968
969                 if (copy_from_user(&ncci, argp, sizeof(ncci)))
970                         return -EFAULT;
971
972                 mutex_lock(&cdev->lock);
973                 nccip = capincci_find(cdev, (u32)ncci);
974                 if (nccip) {
975                         mp = nccip->minorp;
976                         if (mp)
977                                 unit = mp->minor;
978                 }
979                 mutex_unlock(&cdev->lock);
980                 return unit;
981         }
982 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
983
984         default:
985                 return -EINVAL;
986         }
987 }
988
989 static int capi_open(struct inode *inode, struct file *file)
990 {
991         struct capidev *cdev;
992
993         cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
994         if (!cdev)
995                 return -ENOMEM;
996
997         mutex_init(&cdev->lock);
998         skb_queue_head_init(&cdev->recvqueue);
999         init_waitqueue_head(&cdev->recvwait);
1000         INIT_LIST_HEAD(&cdev->nccis);
1001         file->private_data = cdev;
1002
1003         mutex_lock(&capidev_list_lock);
1004         list_add_tail(&cdev->list, &capidev_list);
1005         mutex_unlock(&capidev_list_lock);
1006
1007         return nonseekable_open(inode, file);
1008 }
1009
1010 static int capi_release(struct inode *inode, struct file *file)
1011 {
1012         struct capidev *cdev = file->private_data;
1013
1014         mutex_lock(&capidev_list_lock);
1015         list_del(&cdev->list);
1016         mutex_unlock(&capidev_list_lock);
1017
1018         if (cdev->ap.applid)
1019                 capi20_release(&cdev->ap);
1020         skb_queue_purge(&cdev->recvqueue);
1021         capincci_free(cdev, 0xffffffff);
1022
1023         kfree(cdev);
1024         return 0;
1025 }
1026
1027 static const struct file_operations capi_fops =
1028 {
1029         .owner          = THIS_MODULE,
1030         .llseek         = no_llseek,
1031         .read           = capi_read,
1032         .write          = capi_write,
1033         .poll           = capi_poll,
1034         .ioctl          = capi_ioctl,
1035         .open           = capi_open,
1036         .release        = capi_release,
1037 };
1038
1039 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
1040 /* -------- tty_operations for capincci ----------------------------- */
1041
1042 static int
1043 capinc_tty_install(struct tty_driver *driver, struct tty_struct *tty)
1044 {
1045         int idx = tty->index;
1046         struct capiminor *mp = capiminor_get(idx);
1047         int ret = tty_init_termios(tty);
1048
1049         if (ret == 0) {
1050                 tty_driver_kref_get(driver);
1051                 tty->count++;
1052                 tty->driver_data = mp;
1053                 driver->ttys[idx] = tty;
1054         } else
1055                 capiminor_put(mp);
1056         return ret;
1057 }
1058
1059 static void capinc_tty_cleanup(struct tty_struct *tty)
1060 {
1061         struct capiminor *mp = tty->driver_data;
1062         tty->driver_data = NULL;
1063         capiminor_put(mp);
1064 }
1065
1066 static int capinc_tty_open(struct tty_struct *tty, struct file *filp)
1067 {
1068         struct capiminor *mp = tty->driver_data;
1069         unsigned long flags;
1070         int err;
1071
1072         err = tty_port_open(&mp->port, tty, filp);
1073         if (err)
1074                 return err;
1075
1076         spin_lock_irqsave(&workaround_lock, flags);
1077         handle_minor_recv(mp);
1078         spin_unlock_irqrestore(&workaround_lock, flags);
1079         return 0;
1080 }
1081
1082 static void capinc_tty_close(struct tty_struct *tty, struct file *filp)
1083 {
1084         struct capiminor *mp = tty->driver_data;
1085
1086         tty_port_close(&mp->port, tty, filp);
1087 }
1088
1089 static int capinc_tty_write(struct tty_struct *tty,
1090                             const unsigned char *buf, int count)
1091 {
1092         struct capiminor *mp = tty->driver_data;
1093         struct sk_buff *skb;
1094         unsigned long flags;
1095
1096 #ifdef _DEBUG_TTYFUNCS
1097         printk(KERN_DEBUG "capinc_tty_write(count=%d)\n", count);
1098 #endif
1099
1100         spin_lock_irqsave(&workaround_lock, flags);
1101         skb = mp->ttyskb;
1102         if (skb) {
1103                 mp->ttyskb = NULL;
1104                 skb_queue_tail(&mp->outqueue, skb);
1105                 mp->outbytes += skb->len;
1106         }
1107
1108         skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+count, GFP_ATOMIC);
1109         if (!skb) {
1110                 printk(KERN_ERR "capinc_tty_write: alloc_skb failed\n");
1111                 spin_unlock_irqrestore(&workaround_lock, flags);
1112                 return -ENOMEM;
1113         }
1114
1115         skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
1116         memcpy(skb_put(skb, count), buf, count);
1117
1118         skb_queue_tail(&mp->outqueue, skb);
1119         mp->outbytes += skb->len;
1120         (void)handle_minor_send(mp);
1121         spin_unlock_irqrestore(&workaround_lock, flags);
1122         return count;
1123 }
1124
1125 static int capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
1126 {
1127         struct capiminor *mp = tty->driver_data;
1128         struct sk_buff *skb;
1129         unsigned long flags;
1130         int ret = 1;
1131
1132 #ifdef _DEBUG_TTYFUNCS
1133         printk(KERN_DEBUG "capinc_put_char(%u)\n", ch);
1134 #endif
1135
1136         spin_lock_irqsave(&workaround_lock, flags);
1137         skb = mp->ttyskb;
1138         if (skb) {
1139                 if (skb_tailroom(skb) > 0) {
1140                         *(skb_put(skb, 1)) = ch;
1141                         spin_unlock_irqrestore(&workaround_lock, flags);
1142                         return 1;
1143                 }
1144                 mp->ttyskb = NULL;
1145                 skb_queue_tail(&mp->outqueue, skb);
1146                 mp->outbytes += skb->len;
1147                 (void)handle_minor_send(mp);
1148         }
1149         skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+CAPI_MAX_BLKSIZE, GFP_ATOMIC);
1150         if (skb) {
1151                 skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
1152                 *(skb_put(skb, 1)) = ch;
1153                 mp->ttyskb = skb;
1154         } else {
1155                 printk(KERN_ERR "capinc_put_char: char %u lost\n", ch);
1156                 ret = 0;
1157         }
1158         spin_unlock_irqrestore(&workaround_lock, flags);
1159         return ret;
1160 }
1161
1162 static void capinc_tty_flush_chars(struct tty_struct *tty)
1163 {
1164         struct capiminor *mp = tty->driver_data;
1165         struct sk_buff *skb;
1166         unsigned long flags;
1167
1168 #ifdef _DEBUG_TTYFUNCS
1169         printk(KERN_DEBUG "capinc_tty_flush_chars\n");
1170 #endif
1171
1172         spin_lock_irqsave(&workaround_lock, flags);
1173         skb = mp->ttyskb;
1174         if (skb) {
1175                 mp->ttyskb = NULL;
1176                 skb_queue_tail(&mp->outqueue, skb);
1177                 mp->outbytes += skb->len;
1178                 (void)handle_minor_send(mp);
1179         }
1180         (void)handle_minor_recv(mp);
1181         spin_unlock_irqrestore(&workaround_lock, flags);
1182 }
1183
1184 static int capinc_tty_write_room(struct tty_struct *tty)
1185 {
1186         struct capiminor *mp = tty->driver_data;
1187         int room;
1188
1189         room = CAPINC_MAX_SENDQUEUE-skb_queue_len(&mp->outqueue);
1190         room *= CAPI_MAX_BLKSIZE;
1191 #ifdef _DEBUG_TTYFUNCS
1192         printk(KERN_DEBUG "capinc_tty_write_room = %d\n", room);
1193 #endif
1194         return room;
1195 }
1196
1197 static int capinc_tty_chars_in_buffer(struct tty_struct *tty)
1198 {
1199         struct capiminor *mp = tty->driver_data;
1200
1201 #ifdef _DEBUG_TTYFUNCS
1202         printk(KERN_DEBUG "capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%d\n",
1203                         mp->outbytes, mp->nack,
1204                         skb_queue_len(&mp->outqueue),
1205                         skb_queue_len(&mp->inqueue));
1206 #endif
1207         return mp->outbytes;
1208 }
1209
1210 static int capinc_tty_ioctl(struct tty_struct *tty, struct file * file,
1211                     unsigned int cmd, unsigned long arg)
1212 {
1213         int error = 0;
1214         switch (cmd) {
1215         default:
1216                 error = n_tty_ioctl_helper(tty, file, cmd, arg);
1217                 break;
1218         }
1219         return error;
1220 }
1221
1222 static void capinc_tty_set_termios(struct tty_struct *tty, struct ktermios * old)
1223 {
1224 #ifdef _DEBUG_TTYFUNCS
1225         printk(KERN_DEBUG "capinc_tty_set_termios\n");
1226 #endif
1227 }
1228
1229 static void capinc_tty_throttle(struct tty_struct *tty)
1230 {
1231         struct capiminor *mp = tty->driver_data;
1232 #ifdef _DEBUG_TTYFUNCS
1233         printk(KERN_DEBUG "capinc_tty_throttle\n");
1234 #endif
1235         mp->ttyinstop = 1;
1236 }
1237
1238 static void capinc_tty_unthrottle(struct tty_struct *tty)
1239 {
1240         struct capiminor *mp = tty->driver_data;
1241         unsigned long flags;
1242
1243 #ifdef _DEBUG_TTYFUNCS
1244         printk(KERN_DEBUG "capinc_tty_unthrottle\n");
1245 #endif
1246         spin_lock_irqsave(&workaround_lock, flags);
1247         mp->ttyinstop = 0;
1248         handle_minor_recv(mp);
1249         spin_unlock_irqrestore(&workaround_lock, flags);
1250 }
1251
1252 static void capinc_tty_stop(struct tty_struct *tty)
1253 {
1254         struct capiminor *mp = tty->driver_data;
1255
1256 #ifdef _DEBUG_TTYFUNCS
1257         printk(KERN_DEBUG "capinc_tty_stop\n");
1258 #endif
1259         mp->ttyoutstop = 1;
1260 }
1261
1262 static void capinc_tty_start(struct tty_struct *tty)
1263 {
1264         struct capiminor *mp = tty->driver_data;
1265         unsigned long flags;
1266
1267 #ifdef _DEBUG_TTYFUNCS
1268         printk(KERN_DEBUG "capinc_tty_start\n");
1269 #endif
1270         spin_lock_irqsave(&workaround_lock, flags);
1271         mp->ttyoutstop = 0;
1272         (void)handle_minor_send(mp);
1273         spin_unlock_irqrestore(&workaround_lock, flags);
1274 }
1275
1276 static void capinc_tty_hangup(struct tty_struct *tty)
1277 {
1278         struct capiminor *mp = tty->driver_data;
1279
1280 #ifdef _DEBUG_TTYFUNCS
1281         printk(KERN_DEBUG "capinc_tty_hangup\n");
1282 #endif
1283         tty_port_hangup(&mp->port);
1284 }
1285
1286 static int capinc_tty_break_ctl(struct tty_struct *tty, int state)
1287 {
1288 #ifdef _DEBUG_TTYFUNCS
1289         printk(KERN_DEBUG "capinc_tty_break_ctl(%d)\n", state);
1290 #endif
1291         return 0;
1292 }
1293
1294 static void capinc_tty_flush_buffer(struct tty_struct *tty)
1295 {
1296 #ifdef _DEBUG_TTYFUNCS
1297         printk(KERN_DEBUG "capinc_tty_flush_buffer\n");
1298 #endif
1299 }
1300
1301 static void capinc_tty_set_ldisc(struct tty_struct *tty)
1302 {
1303 #ifdef _DEBUG_TTYFUNCS
1304         printk(KERN_DEBUG "capinc_tty_set_ldisc\n");
1305 #endif
1306 }
1307
1308 static void capinc_tty_send_xchar(struct tty_struct *tty, char ch)
1309 {
1310 #ifdef _DEBUG_TTYFUNCS
1311         printk(KERN_DEBUG "capinc_tty_send_xchar(%d)\n", ch);
1312 #endif
1313 }
1314
1315 static const struct tty_operations capinc_ops = {
1316         .open = capinc_tty_open,
1317         .close = capinc_tty_close,
1318         .write = capinc_tty_write,
1319         .put_char = capinc_tty_put_char,
1320         .flush_chars = capinc_tty_flush_chars,
1321         .write_room = capinc_tty_write_room,
1322         .chars_in_buffer = capinc_tty_chars_in_buffer,
1323         .ioctl = capinc_tty_ioctl,
1324         .set_termios = capinc_tty_set_termios,
1325         .throttle = capinc_tty_throttle,
1326         .unthrottle = capinc_tty_unthrottle,
1327         .stop = capinc_tty_stop,
1328         .start = capinc_tty_start,
1329         .hangup = capinc_tty_hangup,
1330         .break_ctl = capinc_tty_break_ctl,
1331         .flush_buffer = capinc_tty_flush_buffer,
1332         .set_ldisc = capinc_tty_set_ldisc,
1333         .send_xchar = capinc_tty_send_xchar,
1334         .install = capinc_tty_install,
1335         .cleanup = capinc_tty_cleanup,
1336 };
1337
1338 static int __init capinc_tty_init(void)
1339 {
1340         struct tty_driver *drv;
1341         int err;
1342
1343         if (capi_ttyminors > CAPINC_MAX_PORTS)
1344                 capi_ttyminors = CAPINC_MAX_PORTS;
1345         if (capi_ttyminors <= 0)
1346                 capi_ttyminors = CAPINC_NR_PORTS;
1347
1348         capiminors = kzalloc(sizeof(struct capi_minor *) * capi_ttyminors,
1349                              GFP_KERNEL);
1350         if (!capiminors)
1351                 return -ENOMEM;
1352
1353         drv = alloc_tty_driver(capi_ttyminors);
1354         if (!drv) {
1355                 kfree(capiminors);
1356                 return -ENOMEM;
1357         }
1358         drv->owner = THIS_MODULE;
1359         drv->driver_name = "capi_nc";
1360         drv->name = "capi";
1361         drv->major = 0;
1362         drv->minor_start = 0;
1363         drv->type = TTY_DRIVER_TYPE_SERIAL;
1364         drv->subtype = SERIAL_TYPE_NORMAL;
1365         drv->init_termios = tty_std_termios;
1366         drv->init_termios.c_iflag = ICRNL;
1367         drv->init_termios.c_oflag = OPOST | ONLCR;
1368         drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1369         drv->init_termios.c_lflag = 0;
1370         drv->flags =
1371                 TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS |
1372                 TTY_DRIVER_DYNAMIC_DEV;
1373         tty_set_operations(drv, &capinc_ops);
1374
1375         err = tty_register_driver(drv);
1376         if (err) {
1377                 put_tty_driver(drv);
1378                 kfree(capiminors);
1379                 printk(KERN_ERR "Couldn't register capi_nc driver\n");
1380                 return err;
1381         }
1382         capinc_tty_driver = drv;
1383         return 0;
1384 }
1385
1386 static void __exit capinc_tty_exit(void)
1387 {
1388         tty_unregister_driver(capinc_tty_driver);
1389         put_tty_driver(capinc_tty_driver);
1390         kfree(capiminors);
1391 }
1392
1393 #else /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
1394
1395 static inline int capinc_tty_init(void)
1396 {
1397         return 0;
1398 }
1399
1400 static inline void capinc_tty_exit(void) { }
1401
1402 #endif /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
1403
1404 /* -------- /proc functions ----------------------------------------- */
1405
1406 /*
1407  * /proc/capi/capi20:
1408  *  minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
1409  */
1410 static int capi20_proc_show(struct seq_file *m, void *v)
1411 {
1412         struct capidev *cdev;
1413         struct list_head *l;
1414
1415         mutex_lock(&capidev_list_lock);
1416         list_for_each(l, &capidev_list) {
1417                 cdev = list_entry(l, struct capidev, list);
1418                 seq_printf(m, "0 %d %lu %lu %lu %lu\n",
1419                         cdev->ap.applid,
1420                         cdev->ap.nrecvctlpkt,
1421                         cdev->ap.nrecvdatapkt,
1422                         cdev->ap.nsentctlpkt,
1423                         cdev->ap.nsentdatapkt);
1424         }
1425         mutex_unlock(&capidev_list_lock);
1426         return 0;
1427 }
1428
1429 static int capi20_proc_open(struct inode *inode, struct file *file)
1430 {
1431         return single_open(file, capi20_proc_show, NULL);
1432 }
1433
1434 static const struct file_operations capi20_proc_fops = {
1435         .owner          = THIS_MODULE,
1436         .open           = capi20_proc_open,
1437         .read           = seq_read,
1438         .llseek         = seq_lseek,
1439         .release        = single_release,
1440 };
1441
1442 /*
1443  * /proc/capi/capi20ncci:
1444  *  applid ncci
1445  */
1446 static int capi20ncci_proc_show(struct seq_file *m, void *v)
1447 {
1448         struct capidev *cdev;
1449         struct capincci *np;
1450
1451         mutex_lock(&capidev_list_lock);
1452         list_for_each_entry(cdev, &capidev_list, list) {
1453                 mutex_lock(&cdev->lock);
1454                 list_for_each_entry(np, &cdev->nccis, list)
1455                         seq_printf(m, "%d 0x%x\n", cdev->ap.applid, np->ncci);
1456                 mutex_unlock(&cdev->lock);
1457         }
1458         mutex_unlock(&capidev_list_lock);
1459         return 0;
1460 }
1461
1462 static int capi20ncci_proc_open(struct inode *inode, struct file *file)
1463 {
1464         return single_open(file, capi20ncci_proc_show, NULL);
1465 }
1466
1467 static const struct file_operations capi20ncci_proc_fops = {
1468         .owner          = THIS_MODULE,
1469         .open           = capi20ncci_proc_open,
1470         .read           = seq_read,
1471         .llseek         = seq_lseek,
1472         .release        = single_release,
1473 };
1474
1475 static void __init proc_init(void)
1476 {
1477         proc_create("capi/capi20", 0, NULL, &capi20_proc_fops);
1478         proc_create("capi/capi20ncci", 0, NULL, &capi20ncci_proc_fops);
1479 }
1480
1481 static void __exit proc_exit(void)
1482 {
1483         remove_proc_entry("capi/capi20", NULL);
1484         remove_proc_entry("capi/capi20ncci", NULL);
1485 }
1486
1487 /* -------- init function and module interface ---------------------- */
1488
1489
1490 static int __init capi_init(void)
1491 {
1492         const char *compileinfo;
1493         int major_ret;
1494
1495         major_ret = register_chrdev(capi_major, "capi20", &capi_fops);
1496         if (major_ret < 0) {
1497                 printk(KERN_ERR "capi20: unable to get major %d\n", capi_major);
1498                 return major_ret;
1499         }
1500         capi_class = class_create(THIS_MODULE, "capi");
1501         if (IS_ERR(capi_class)) {
1502                 unregister_chrdev(capi_major, "capi20");
1503                 return PTR_ERR(capi_class);
1504         }
1505
1506         device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi");
1507
1508         if (capinc_tty_init() < 0) {
1509                 device_destroy(capi_class, MKDEV(capi_major, 0));
1510                 class_destroy(capi_class);
1511                 unregister_chrdev(capi_major, "capi20");
1512                 return -ENOMEM;
1513         }
1514
1515         proc_init();
1516
1517 #if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
1518         compileinfo = " (middleware+capifs)";
1519 #elif defined(CONFIG_ISDN_CAPI_MIDDLEWARE)
1520         compileinfo = " (no capifs)";
1521 #else
1522         compileinfo = " (no middleware)";
1523 #endif
1524         printk(KERN_NOTICE "CAPI 2.0 started up with major %d%s\n",
1525                capi_major, compileinfo);
1526
1527         return 0;
1528 }
1529
1530 static void __exit capi_exit(void)
1531 {
1532         proc_exit();
1533
1534         device_destroy(capi_class, MKDEV(capi_major, 0));
1535         class_destroy(capi_class);
1536         unregister_chrdev(capi_major, "capi20");
1537
1538         capinc_tty_exit();
1539 }
1540
1541 module_init(capi_init);
1542 module_exit(capi_exit);