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