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