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