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