File Index
Files and directories
Sign in
FILE

capi.c

File preview with syntax highlighting.

linux-6.19.14/drivers/isdn/capi/capi.c 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/compiler.h>
  13#include <linux/module.h>
  14#include <linux/ethtool.h>
  15#include <linux/errno.h>
  16#include <linux/kernel.h>
  17#include <linux/major.h>
  18#include <linux/sched.h>
  19#include <linux/slab.h>
  20#include <linux/fcntl.h>
  21#include <linux/fs.h>
  22#include <linux/signal.h>
  23#include <linux/mutex.h>
  24#include <linux/mm.h>
  25#include <linux/timer.h>
  26#include <linux/wait.h>
  27#include <linux/tty.h>
  28#include <linux/netdevice.h>
  29#include <linux/ppp_defs.h>
  30#include <linux/ppp-ioctl.h>
  31#include <linux/skbuff.h>
  32#include <linux/proc_fs.h>
  33#include <linux/seq_file.h>
  34#include <linux/poll.h>
  35#include <linux/capi.h>
  36#include <linux/kernelcapi.h>
  37#include <linux/init.h>
  38#include <linux/device.h>
  39#include <linux/moduleparam.h>
  40#include <linux/isdn/capiutil.h>
  41#include <linux/isdn/capicmd.h>
  42
  43#include "kcapi.h"
  44
  45MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer and /dev/capi20 interface");
  46MODULE_AUTHOR("Carsten Paeth");
  47MODULE_LICENSE("GPL");
  48
  49/* -------- driver information -------------------------------------- */
  50
  51static DEFINE_MUTEX(capi_mutex);
  52static const struct class capi_class = {
  53	.name = "capi",
  54};
  55static int capi_major = 68;		/* allocated */
  56
  57module_param_named(major, capi_major, uint, 0);
  58
  59#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
  60#define CAPINC_NR_PORTS		32
  61#define CAPINC_MAX_PORTS	256
  62
  63static int capi_ttyminors = CAPINC_NR_PORTS;
  64
  65module_param_named(ttyminors, capi_ttyminors, uint, 0);
  66#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
  67
  68/* -------- defines ------------------------------------------------- */
  69
  70#define CAPINC_MAX_RECVQUEUE	10
  71#define CAPINC_MAX_SENDQUEUE	10
  72#define CAPI_MAX_BLKSIZE	2048
  73
  74/* -------- data structures ----------------------------------------- */
  75
  76struct capidev;
  77struct capincci;
  78struct capiminor;
  79
  80struct ackqueue_entry {
  81	struct list_head	list;
  82	u16			datahandle;
  83};
  84
  85struct capiminor {
  86	unsigned int      minor;
  87
  88	struct capi20_appl	*ap;
  89	u32			ncci;
  90	atomic_t		datahandle;
  91	atomic_t		msgid;
  92
  93	struct tty_port port;
  94	int                ttyinstop;
  95	int                ttyoutstop;
  96
  97	struct sk_buff_head	inqueue;
  98
  99	struct sk_buff_head	outqueue;
 100	int			outbytes;
 101	struct sk_buff		*outskb;
 102	spinlock_t		outlock;
 103
 104	/* transmit path */
 105	struct list_head ackqueue;
 106	int nack;
 107	spinlock_t ackqlock;
 108};
 109
 110struct capincci {
 111	struct list_head list;
 112	u32		 ncci;
 113	struct capidev	*cdev;
 114#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 115	struct capiminor *minorp;
 116#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 117};
 118
 119struct capidev {
 120	struct list_head list;
 121	struct capi20_appl ap;
 122	u16		errcode;
 123	unsigned        userflags;
 124
 125	struct sk_buff_head recvqueue;
 126	wait_queue_head_t recvwait;
 127
 128	struct list_head nccis;
 129
 130	struct mutex lock;
 131};
 132
 133/* -------- global variables ---------------------------------------- */
 134
 135static DEFINE_MUTEX(capidev_list_lock);
 136static LIST_HEAD(capidev_list);
 137
 138#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 139
 140static DEFINE_SPINLOCK(capiminors_lock);
 141static struct capiminor **capiminors;
 142
 143static struct tty_driver *capinc_tty_driver;
 144
 145/* -------- datahandles --------------------------------------------- */
 146
 147static int capiminor_add_ack(struct capiminor *mp, u16 datahandle)
 148{
 149	struct ackqueue_entry *n;
 150
 151	n = kmalloc(sizeof(*n), GFP_ATOMIC);
 152	if (unlikely(!n)) {
 153		printk(KERN_ERR "capi: alloc datahandle failed\n");
 154		return -1;
 155	}
 156	n->datahandle = datahandle;
 157	INIT_LIST_HEAD(&n->list);
 158	spin_lock_bh(&mp->ackqlock);
 159	list_add_tail(&n->list, &mp->ackqueue);
 160	mp->nack++;
 161	spin_unlock_bh(&mp->ackqlock);
 162	return 0;
 163}
 164
 165static int capiminor_del_ack(struct capiminor *mp, u16 datahandle)
 166{
 167	struct ackqueue_entry *p, *tmp;
 168
 169	spin_lock_bh(&mp->ackqlock);
 170	list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
 171		if (p->datahandle == datahandle) {
 172			list_del(&p->list);
 173			mp->nack--;
 174			spin_unlock_bh(&mp->ackqlock);
 175			kfree(p);
 176			return 0;
 177		}
 178	}
 179	spin_unlock_bh(&mp->ackqlock);
 180	return -1;
 181}
 182
 183static void capiminor_del_all_ack(struct capiminor *mp)
 184{
 185	struct ackqueue_entry *p, *tmp;
 186
 187	list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
 188		list_del(&p->list);
 189		kfree(p);
 190		mp->nack--;
 191	}
 192}
 193
 194
 195/* -------- struct capiminor ---------------------------------------- */
 196
 197static void capiminor_destroy(struct tty_port *port)
 198{
 199	struct capiminor *mp = container_of(port, struct capiminor, port);
 200
 201	kfree_skb(mp->outskb);
 202	skb_queue_purge(&mp->inqueue);
 203	skb_queue_purge(&mp->outqueue);
 204	capiminor_del_all_ack(mp);
 205	kfree(mp);
 206}
 207
 208static const struct tty_port_operations capiminor_port_ops = {
 209	.destruct = capiminor_destroy,
 210};
 211
 212static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
 213{
 214	struct capiminor *mp;
 215	struct device *dev;
 216	unsigned int minor;
 217
 218	mp = kzalloc(sizeof(*mp), GFP_KERNEL);
 219	if (!mp) {
 220		printk(KERN_ERR "capi: can't alloc capiminor\n");
 221		return NULL;
 222	}
 223
 224	mp->ap = ap;
 225	mp->ncci = ncci;
 226	INIT_LIST_HEAD(&mp->ackqueue);
 227	spin_lock_init(&mp->ackqlock);
 228
 229	skb_queue_head_init(&mp->inqueue);
 230	skb_queue_head_init(&mp->outqueue);
 231	spin_lock_init(&mp->outlock);
 232
 233	tty_port_init(&mp->port);
 234	mp->port.ops = &capiminor_port_ops;
 235
 236	/* Allocate the least unused minor number. */
 237	spin_lock(&capiminors_lock);
 238	for (minor = 0; minor < capi_ttyminors; minor++)
 239		if (!capiminors[minor]) {
 240			capiminors[minor] = mp;
 241			break;
 242		}
 243	spin_unlock(&capiminors_lock);
 244
 245	if (minor == capi_ttyminors) {
 246		printk(KERN_NOTICE "capi: out of minors\n");
 247		goto err_out1;
 248	}
 249
 250	mp->minor = minor;
 251
 252	dev = tty_port_register_device(&mp->port, capinc_tty_driver, minor,
 253			NULL);
 254	if (IS_ERR(dev))
 255		goto err_out2;
 256
 257	return mp;
 258
 259err_out2:
 260	spin_lock(&capiminors_lock);
 261	capiminors[minor] = NULL;
 262	spin_unlock(&capiminors_lock);
 263
 264err_out1:
 265	tty_port_put(&mp->port);
 266	return NULL;
 267}
 268
 269static struct capiminor *capiminor_get(unsigned int minor)
 270{
 271	struct capiminor *mp;
 272
 273	spin_lock(&capiminors_lock);
 274	mp = capiminors[minor];
 275	if (mp)
 276		tty_port_get(&mp->port);
 277	spin_unlock(&capiminors_lock);
 278
 279	return mp;
 280}
 281
 282static inline void capiminor_put(struct capiminor *mp)
 283{
 284	tty_port_put(&mp->port);
 285}
 286
 287static void capiminor_free(struct capiminor *mp)
 288{
 289	tty_unregister_device(capinc_tty_driver, mp->minor);
 290
 291	spin_lock(&capiminors_lock);
 292	capiminors[mp->minor] = NULL;
 293	spin_unlock(&capiminors_lock);
 294
 295	capiminor_put(mp);
 296}
 297
 298/* -------- struct capincci ----------------------------------------- */
 299
 300static void capincci_alloc_minor(struct capidev *cdev, struct capincci *np)
 301{
 302	if (cdev->userflags & CAPIFLAG_HIGHJACKING)
 303		np->minorp = capiminor_alloc(&cdev->ap, np->ncci);
 304}
 305
 306static void capincci_free_minor(struct capincci *np)
 307{
 308	struct capiminor *mp = np->minorp;
 309
 310	if (mp) {
 311		tty_port_tty_vhangup(&mp->port);
 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	if (count < CAPIMSG_BASELEN)
 691		return -EINVAL;
 692
 693	skb = alloc_skb(count, GFP_USER);
 694	if (!skb)
 695		return -ENOMEM;
 696
 697	if (copy_from_user(skb_put(skb, count), buf, count)) {
 698		kfree_skb(skb);
 699		return -EFAULT;
 700	}
 701	mlen = CAPIMSG_LEN(skb->data);
 702	if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
 703		if (count < CAPI_DATA_B3_REQ_LEN ||
 704		    (size_t)(mlen + CAPIMSG_DATALEN(skb->data)) != count) {
 705			kfree_skb(skb);
 706			return -EINVAL;
 707		}
 708	} else {
 709		if (mlen != count) {
 710			kfree_skb(skb);
 711			return -EINVAL;
 712		}
 713	}
 714	CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);
 715
 716	if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) {
 717		if (count < CAPI_DISCONNECT_B3_RESP_LEN) {
 718			kfree_skb(skb);
 719			return -EINVAL;
 720		}
 721		mutex_lock(&cdev->lock);
 722		capincci_free(cdev, CAPIMSG_NCCI(skb->data));
 723		mutex_unlock(&cdev->lock);
 724	}
 725
 726	cdev->errcode = capi20_put_message(&cdev->ap, skb);
 727
 728	if (cdev->errcode) {
 729		kfree_skb(skb);
 730		return -EIO;
 731	}
 732	return count;
 733}
 734
 735static __poll_t
 736capi_poll(struct file *file, poll_table *wait)
 737{
 738	struct capidev *cdev = file->private_data;
 739	__poll_t mask = 0;
 740
 741	if (!cdev->ap.applid)
 742		return EPOLLERR;
 743
 744	poll_wait(file, &(cdev->recvwait), wait);
 745	mask = EPOLLOUT | EPOLLWRNORM;
 746	if (!skb_queue_empty_lockless(&cdev->recvqueue))
 747		mask |= EPOLLIN | EPOLLRDNORM;
 748	return mask;
 749}
 750
 751static int
 752capi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 753{
 754	struct capidev *cdev = file->private_data;
 755	capi_ioctl_struct data;
 756	int retval = -EINVAL;
 757	void __user *argp = (void __user *)arg;
 758
 759	switch (cmd) {
 760	case CAPI_REGISTER:
 761		mutex_lock(&cdev->lock);
 762
 763		if (cdev->ap.applid) {
 764			retval = -EEXIST;
 765			goto register_out;
 766		}
 767		if (copy_from_user(&cdev->ap.rparam, argp,
 768				   sizeof(struct capi_register_params))) {
 769			retval = -EFAULT;
 770			goto register_out;
 771		}
 772		cdev->ap.private = cdev;
 773		cdev->ap.recv_message = capi_recv_message;
 774		cdev->errcode = capi20_register(&cdev->ap);
 775		retval = (int)cdev->ap.applid;
 776		if (cdev->errcode) {
 777			cdev->ap.applid = 0;
 778			retval = -EIO;
 779		}
 780
 781register_out:
 782		mutex_unlock(&cdev->lock);
 783		return retval;
 784
 785	case CAPI_GET_VERSION:
 786		if (copy_from_user(&data.contr, argp,
 787				   sizeof(data.contr)))
 788			return -EFAULT;
 789		cdev->errcode = capi20_get_version(data.contr, &data.version);
 790		if (cdev->errcode)
 791			return -EIO;
 792		if (copy_to_user(argp, &data.version,
 793				 sizeof(data.version)))
 794			return -EFAULT;
 795		return 0;
 796
 797	case CAPI_GET_SERIAL:
 798		if (copy_from_user(&data.contr, argp,
 799				   sizeof(data.contr)))
 800			return -EFAULT;
 801		cdev->errcode = capi20_get_serial(data.contr, data.serial);
 802		if (cdev->errcode)
 803			return -EIO;
 804		if (copy_to_user(argp, data.serial,
 805				 sizeof(data.serial)))
 806			return -EFAULT;
 807		return 0;
 808
 809	case CAPI_GET_PROFILE:
 810		if (copy_from_user(&data.contr, argp,
 811				   sizeof(data.contr)))
 812			return -EFAULT;
 813
 814		if (data.contr == 0) {
 815			cdev->errcode = capi20_get_profile(data.contr, &data.profile);
 816			if (cdev->errcode)
 817				return -EIO;
 818
 819			retval = copy_to_user(argp,
 820					      &data.profile.ncontroller,
 821					      sizeof(data.profile.ncontroller));
 822
 823		} else {
 824			cdev->errcode = capi20_get_profile(data.contr, &data.profile);
 825			if (cdev->errcode)
 826				return -EIO;
 827
 828			retval = copy_to_user(argp, &data.profile,
 829					      sizeof(data.profile));
 830		}
 831		if (retval)
 832			return -EFAULT;
 833		return 0;
 834
 835	case CAPI_GET_MANUFACTURER:
 836		if (copy_from_user(&data.contr, argp,
 837				   sizeof(data.contr)))
 838			return -EFAULT;
 839		cdev->errcode = capi20_get_manufacturer(data.contr, data.manufacturer);
 840		if (cdev->errcode)
 841			return -EIO;
 842
 843		if (copy_to_user(argp, data.manufacturer,
 844				 sizeof(data.manufacturer)))
 845			return -EFAULT;
 846
 847		return 0;
 848
 849	case CAPI_GET_ERRCODE:
 850		data.errcode = cdev->errcode;
 851		cdev->errcode = CAPI_NOERROR;
 852		if (arg) {
 853			if (copy_to_user(argp, &data.errcode,
 854					 sizeof(data.errcode)))
 855				return -EFAULT;
 856		}
 857		return data.errcode;
 858
 859	case CAPI_INSTALLED:
 860		if (capi20_isinstalled() == CAPI_NOERROR)
 861			return 0;
 862		return -ENXIO;
 863
 864	case CAPI_MANUFACTURER_CMD: {
 865		struct capi_manufacturer_cmd mcmd;
 866		if (!capable(CAP_SYS_ADMIN))
 867			return -EPERM;
 868		if (copy_from_user(&mcmd, argp, sizeof(mcmd)))
 869			return -EFAULT;
 870		return capi20_manufacturer(mcmd.cmd, mcmd.data);
 871	}
 872	case CAPI_SET_FLAGS:
 873	case CAPI_CLR_FLAGS: {
 874		unsigned userflags;
 875
 876		if (copy_from_user(&userflags, argp, sizeof(userflags)))
 877			return -EFAULT;
 878
 879		mutex_lock(&cdev->lock);
 880		if (cmd == CAPI_SET_FLAGS)
 881			cdev->userflags |= userflags;
 882		else
 883			cdev->userflags &= ~userflags;
 884		mutex_unlock(&cdev->lock);
 885		return 0;
 886	}
 887	case CAPI_GET_FLAGS:
 888		if (copy_to_user(argp, &cdev->userflags,
 889				 sizeof(cdev->userflags)))
 890			return -EFAULT;
 891		return 0;
 892
 893#ifndef CONFIG_ISDN_CAPI_MIDDLEWARE
 894	case CAPI_NCCI_OPENCOUNT:
 895		return 0;
 896
 897#else /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 898	case CAPI_NCCI_OPENCOUNT: {
 899		struct capincci *nccip;
 900		unsigned ncci;
 901		int count = 0;
 902
 903		if (copy_from_user(&ncci, argp, sizeof(ncci)))
 904			return -EFAULT;
 905
 906		mutex_lock(&cdev->lock);
 907		nccip = capincci_find(cdev, (u32)ncci);
 908		if (nccip)
 909			count = capincci_minor_opencount(nccip);
 910		mutex_unlock(&cdev->lock);
 911		return count;
 912	}
 913
 914	case CAPI_NCCI_GETUNIT: {
 915		struct capincci *nccip;
 916		struct capiminor *mp;
 917		unsigned ncci;
 918		int unit = -ESRCH;
 919
 920		if (copy_from_user(&ncci, argp, sizeof(ncci)))
 921			return -EFAULT;
 922
 923		mutex_lock(&cdev->lock);
 924		nccip = capincci_find(cdev, (u32)ncci);
 925		if (nccip) {
 926			mp = nccip->minorp;
 927			if (mp)
 928				unit = mp->minor;
 929		}
 930		mutex_unlock(&cdev->lock);
 931		return unit;
 932	}
 933#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 934
 935	default:
 936		return -EINVAL;
 937	}
 938}
 939
 940static long
 941capi_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 942{
 943	int ret;
 944
 945	mutex_lock(&capi_mutex);
 946	ret = capi_ioctl(file, cmd, arg);
 947	mutex_unlock(&capi_mutex);
 948
 949	return ret;
 950}
 951
 952#ifdef CONFIG_COMPAT
 953static long
 954capi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 955{
 956	int ret;
 957
 958	if (cmd == CAPI_MANUFACTURER_CMD) {
 959		struct {
 960			compat_ulong_t cmd;
 961			compat_uptr_t data;
 962		} mcmd32;
 963
 964		if (!capable(CAP_SYS_ADMIN))
 965			return -EPERM;
 966		if (copy_from_user(&mcmd32, compat_ptr(arg), sizeof(mcmd32)))
 967			return -EFAULT;
 968
 969		mutex_lock(&capi_mutex);
 970		ret = capi20_manufacturer(mcmd32.cmd, compat_ptr(mcmd32.data));
 971		mutex_unlock(&capi_mutex);
 972
 973		return ret;
 974	}
 975
 976	return capi_unlocked_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
 977}
 978#endif
 979
 980static int capi_open(struct inode *inode, struct file *file)
 981{
 982	struct capidev *cdev;
 983
 984	cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
 985	if (!cdev)
 986		return -ENOMEM;
 987
 988	mutex_init(&cdev->lock);
 989	skb_queue_head_init(&cdev->recvqueue);
 990	init_waitqueue_head(&cdev->recvwait);
 991	INIT_LIST_HEAD(&cdev->nccis);
 992	file->private_data = cdev;
 993
 994	mutex_lock(&capidev_list_lock);
 995	list_add_tail(&cdev->list, &capidev_list);
 996	mutex_unlock(&capidev_list_lock);
 997
 998	return stream_open(inode, file);
 999}
1000
1001static int capi_release(struct inode *inode, struct file *file)
1002{
1003	struct capidev *cdev = file->private_data;
1004
1005	mutex_lock(&capidev_list_lock);
1006	list_del(&cdev->list);
1007	mutex_unlock(&capidev_list_lock);
1008
1009	if (cdev->ap.applid)
1010		capi20_release(&cdev->ap);
1011	skb_queue_purge(&cdev->recvqueue);
1012	capincci_free(cdev, 0xffffffff);
1013
1014	kfree(cdev);
1015	return 0;
1016}
1017
1018static const struct file_operations capi_fops =
1019{
1020	.owner		= THIS_MODULE,
1021	.read		= capi_read,
1022	.write		= capi_write,
1023	.poll		= capi_poll,
1024	.unlocked_ioctl	= capi_unlocked_ioctl,
1025#ifdef CONFIG_COMPAT
1026	.compat_ioctl	= capi_compat_ioctl,
1027#endif
1028	.open		= capi_open,
1029	.release	= capi_release,
1030};
1031
1032#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
1033/* -------- tty_operations for capincci ----------------------------- */
1034
1035static int
1036capinc_tty_install(struct tty_driver *driver, struct tty_struct *tty)
1037{
1038	struct capiminor *mp = capiminor_get(tty->index);
1039	int ret = tty_standard_install(driver, tty);
1040
1041	if (ret == 0)
1042		tty->driver_data = mp;
1043	else
1044		capiminor_put(mp);
1045	return ret;
1046}
1047
1048static void capinc_tty_cleanup(struct tty_struct *tty)
1049{
1050	struct capiminor *mp = tty->driver_data;
1051	tty->driver_data = NULL;
1052	capiminor_put(mp);
1053}
1054
1055static int capinc_tty_open(struct tty_struct *tty, struct file *filp)
1056{
1057	struct capiminor *mp = tty->driver_data;
1058	int err;
1059
1060	err = tty_port_open(&mp->port, tty, filp);
1061	if (err)
1062		return err;
1063
1064	handle_minor_recv(mp);
1065	return 0;
1066}
1067
1068static void capinc_tty_close(struct tty_struct *tty, struct file *filp)
1069{
1070	struct capiminor *mp = tty->driver_data;
1071
1072	tty_port_close(&mp->port, tty, filp);
1073}
1074
1075static ssize_t capinc_tty_write(struct tty_struct *tty, const u8 *buf,
1076				size_t count)
1077{
1078	struct capiminor *mp = tty->driver_data;
1079	struct sk_buff *skb;
1080
1081	pr_debug("capinc_tty_write(count=%zu)\n", count);
1082
1083	spin_lock_bh(&mp->outlock);
1084	skb = mp->outskb;
1085	if (skb) {
1086		mp->outskb = NULL;
1087		__skb_queue_tail(&mp->outqueue, skb);
1088		mp->outbytes += skb->len;
1089	}
1090
1091	skb = alloc_skb(CAPI_DATA_B3_REQ_LEN + count, GFP_ATOMIC);
1092	if (!skb) {
1093		printk(KERN_ERR "capinc_tty_write: alloc_skb failed\n");
1094		spin_unlock_bh(&mp->outlock);
1095		return -ENOMEM;
1096	}
1097
1098	skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
1099	skb_put_data(skb, buf, count);
1100
1101	__skb_queue_tail(&mp->outqueue, skb);
1102	mp->outbytes += skb->len;
1103	spin_unlock_bh(&mp->outlock);
1104
1105	handle_minor_send(mp);
1106
1107	return count;
1108}
1109
1110static int capinc_tty_put_char(struct tty_struct *tty, u8 ch)
1111{
1112	struct capiminor *mp = tty->driver_data;
1113	bool invoke_send = false;
1114	struct sk_buff *skb;
1115	int ret = 1;
1116
1117	pr_debug("capinc_put_char(%u)\n", ch);
1118
1119	spin_lock_bh(&mp->outlock);
1120	skb = mp->outskb;
1121	if (skb) {
1122		if (skb_tailroom(skb) > 0) {
1123			skb_put_u8(skb, ch);
1124			goto unlock_out;
1125		}
1126		mp->outskb = NULL;
1127		__skb_queue_tail(&mp->outqueue, skb);
1128		mp->outbytes += skb->len;
1129		invoke_send = true;
1130	}
1131
1132	skb = alloc_skb(CAPI_DATA_B3_REQ_LEN + CAPI_MAX_BLKSIZE, GFP_ATOMIC);
1133	if (skb) {
1134		skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
1135		skb_put_u8(skb, ch);
1136		mp->outskb = skb;
1137	} else {
1138		printk(KERN_ERR "capinc_put_char: char %u lost\n", ch);
1139		ret = 0;
1140	}
1141
1142unlock_out:
1143	spin_unlock_bh(&mp->outlock);
1144
1145	if (invoke_send)
1146		handle_minor_send(mp);
1147
1148	return ret;
1149}
1150
1151static void capinc_tty_flush_chars(struct tty_struct *tty)
1152{
1153	struct capiminor *mp = tty->driver_data;
1154	struct sk_buff *skb;
1155
1156	spin_lock_bh(&mp->outlock);
1157	skb = mp->outskb;
1158	if (skb) {
1159		mp->outskb = NULL;
1160		__skb_queue_tail(&mp->outqueue, skb);
1161		mp->outbytes += skb->len;
1162		spin_unlock_bh(&mp->outlock);
1163
1164		handle_minor_send(mp);
1165	} else
1166		spin_unlock_bh(&mp->outlock);
1167
1168	handle_minor_recv(mp);
1169}
1170
1171static unsigned int capinc_tty_write_room(struct tty_struct *tty)
1172{
1173	struct capiminor *mp = tty->driver_data;
1174	unsigned int room;
1175
1176	room = CAPINC_MAX_SENDQUEUE-skb_queue_len(&mp->outqueue);
1177	room *= CAPI_MAX_BLKSIZE;
1178	pr_debug("capinc_tty_write_room = %u\n", room);
1179	return room;
1180}
1181
1182static unsigned int capinc_tty_chars_in_buffer(struct tty_struct *tty)
1183{
1184	struct capiminor *mp = tty->driver_data;
1185
1186	pr_debug("capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%d\n",
1187		 mp->outbytes, mp->nack,
1188		 skb_queue_len(&mp->outqueue),
1189		 skb_queue_len(&mp->inqueue));
1190	return mp->outbytes;
1191}
1192
1193static void capinc_tty_throttle(struct tty_struct *tty)
1194{
1195	struct capiminor *mp = tty->driver_data;
1196	mp->ttyinstop = 1;
1197}
1198
1199static void capinc_tty_unthrottle(struct tty_struct *tty)
1200{
1201	struct capiminor *mp = tty->driver_data;
1202
1203	mp->ttyinstop = 0;
1204	handle_minor_recv(mp);
1205}
1206
1207static void capinc_tty_stop(struct tty_struct *tty)
1208{
1209	struct capiminor *mp = tty->driver_data;
1210
1211	mp->ttyoutstop = 1;
1212}
1213
1214static void capinc_tty_start(struct tty_struct *tty)
1215{
1216	struct capiminor *mp = tty->driver_data;
1217
1218	mp->ttyoutstop = 0;
1219	handle_minor_send(mp);
1220}
1221
1222static void capinc_tty_hangup(struct tty_struct *tty)
1223{
1224	struct capiminor *mp = tty->driver_data;
1225
1226	tty_port_hangup(&mp->port);
1227}
1228
1229static void capinc_tty_send_xchar(struct tty_struct *tty, u8 ch)
1230{
1231	pr_debug("capinc_tty_send_xchar(%u)\n", ch);
1232}
1233
1234static const struct tty_operations capinc_ops = {
1235	.open = capinc_tty_open,
1236	.close = capinc_tty_close,
1237	.write = capinc_tty_write,
1238	.put_char = capinc_tty_put_char,
1239	.flush_chars = capinc_tty_flush_chars,
1240	.write_room = capinc_tty_write_room,
1241	.chars_in_buffer = capinc_tty_chars_in_buffer,
1242	.throttle = capinc_tty_throttle,
1243	.unthrottle = capinc_tty_unthrottle,
1244	.stop = capinc_tty_stop,
1245	.start = capinc_tty_start,
1246	.hangup = capinc_tty_hangup,
1247	.send_xchar = capinc_tty_send_xchar,
1248	.install = capinc_tty_install,
1249	.cleanup = capinc_tty_cleanup,
1250};
1251
1252static int __init capinc_tty_init(void)
1253{
1254	struct tty_driver *drv;
1255	int err;
1256
1257	if (capi_ttyminors > CAPINC_MAX_PORTS)
1258		capi_ttyminors = CAPINC_MAX_PORTS;
1259	if (capi_ttyminors <= 0)
1260		capi_ttyminors = CAPINC_NR_PORTS;
1261
1262	capiminors = kcalloc(capi_ttyminors, sizeof(struct capiminor *),
1263			     GFP_KERNEL);
1264	if (!capiminors)
1265		return -ENOMEM;
1266
1267	drv = tty_alloc_driver(capi_ttyminors, TTY_DRIVER_REAL_RAW |
1268			TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_DYNAMIC_DEV);
1269	if (IS_ERR(drv)) {
1270		kfree(capiminors);
1271		return PTR_ERR(drv);
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	tty_set_operations(drv, &capinc_ops);
1285
1286	err = tty_register_driver(drv);
1287	if (err) {
1288		tty_driver_kref_put(drv);
1289		kfree(capiminors);
1290		printk(KERN_ERR "Couldn't register capi_nc driver\n");
1291		return err;
1292	}
1293	capinc_tty_driver = drv;
1294	return 0;
1295}
1296
1297static void __exit capinc_tty_exit(void)
1298{
1299	tty_unregister_driver(capinc_tty_driver);
1300	tty_driver_kref_put(capinc_tty_driver);
1301	kfree(capiminors);
1302}
1303
1304#else /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
1305
1306static inline int capinc_tty_init(void)
1307{
1308	return 0;
1309}
1310
1311static inline void capinc_tty_exit(void) { }
1312
1313#endif /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
1314
1315/* -------- /proc functions ----------------------------------------- */
1316
1317/*
1318 * /proc/capi/capi20:
1319 *  minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
1320 */
1321static int __maybe_unused capi20_proc_show(struct seq_file *m, void *v)
1322{
1323	struct capidev *cdev;
1324	struct list_head *l;
1325
1326	mutex_lock(&capidev_list_lock);
1327	list_for_each(l, &capidev_list) {
1328		cdev = list_entry(l, struct capidev, list);
1329		seq_printf(m, "0 %d %lu %lu %lu %lu\n",
1330			   cdev->ap.applid,
1331			   cdev->ap.nrecvctlpkt,
1332			   cdev->ap.nrecvdatapkt,
1333			   cdev->ap.nsentctlpkt,
1334			   cdev->ap.nsentdatapkt);
1335	}
1336	mutex_unlock(&capidev_list_lock);
1337	return 0;
1338}
1339
1340/*
1341 * /proc/capi/capi20ncci:
1342 *  applid ncci
1343 */
1344static int __maybe_unused capi20ncci_proc_show(struct seq_file *m, void *v)
1345{
1346	struct capidev *cdev;
1347	struct capincci *np;
1348
1349	mutex_lock(&capidev_list_lock);
1350	list_for_each_entry(cdev, &capidev_list, list) {
1351		mutex_lock(&cdev->lock);
1352		list_for_each_entry(np, &cdev->nccis, list)
1353			seq_printf(m, "%d 0x%x\n", cdev->ap.applid, np->ncci);
1354		mutex_unlock(&cdev->lock);
1355	}
1356	mutex_unlock(&capidev_list_lock);
1357	return 0;
1358}
1359
1360static void __init proc_init(void)
1361{
1362	proc_create_single("capi/capi20", 0, NULL, capi20_proc_show);
1363	proc_create_single("capi/capi20ncci", 0, NULL, capi20ncci_proc_show);
1364}
1365
1366static void __exit proc_exit(void)
1367{
1368	remove_proc_entry("capi/capi20", NULL);
1369	remove_proc_entry("capi/capi20ncci", NULL);
1370}
1371
1372/* -------- init function and module interface ---------------------- */
1373
1374
1375static int __init capi_init(void)
1376{
1377	const char *compileinfo;
1378	int major_ret;
1379	int ret;
1380
1381	ret = kcapi_init();
1382	if (ret)
1383		return ret;
1384
1385	major_ret = register_chrdev(capi_major, "capi20", &capi_fops);
1386	if (major_ret < 0) {
1387		printk(KERN_ERR "capi20: unable to get major %d\n", capi_major);
1388		kcapi_exit();
1389		return major_ret;
1390	}
1391
1392	ret = class_register(&capi_class);
1393	if (ret) {
1394		unregister_chrdev(capi_major, "capi20");
1395		kcapi_exit();
1396		return ret;
1397	}
1398
1399	device_create(&capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi20");
1400
1401	if (capinc_tty_init() < 0) {
1402		device_destroy(&capi_class, MKDEV(capi_major, 0));
1403		class_unregister(&capi_class);
1404		unregister_chrdev(capi_major, "capi20");
1405		kcapi_exit();
1406		return -ENOMEM;
1407	}
1408
1409	proc_init();
1410
1411#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
1412	compileinfo = " (middleware)";
1413#else
1414	compileinfo = " (no middleware)";
1415#endif
1416	printk(KERN_NOTICE "CAPI 2.0 started up with major %d%s\n",
1417	       capi_major, compileinfo);
1418
1419	return 0;
1420}
1421
1422static void __exit capi_exit(void)
1423{
1424	proc_exit();
1425
1426	device_destroy(&capi_class, MKDEV(capi_major, 0));
1427	class_unregister(&capi_class);
1428	unregister_chrdev(capi_major, "capi20");
1429
1430	capinc_tty_exit();
1431
1432	kcapi_exit();
1433}
1434
1435module_init(capi_init);
1436module_exit(capi_exit);
~/ Read-only file preview.