1/* $Id: isdn_common.c,v 1.1.1.1 2007/08/03 18:52:36 Exp $ 2 * 3 * Linux ISDN subsystem, common used functions (linklevel). 4 * 5 * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de) 6 * Copyright 1995,96 Thinking Objects Software GmbH Wuerzburg 7 * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) 8 * 9 * This software may be used and distributed according to the terms 10 * of the GNU General Public License, incorporated herein by reference. 11 * 12 */ 13 14#include <linux/module.h> 15#include <linux/init.h> 16#include <linux/poll.h> 17#include <linux/vmalloc.h> 18#include <linux/isdn.h> 19#include <linux/smp_lock.h> 20#include "isdn_common.h" 21#include "isdn_tty.h" 22#include "isdn_net.h" 23#include "isdn_ppp.h" 24#ifdef CONFIG_ISDN_AUDIO 25#include "isdn_audio.h" 26#endif 27#ifdef CONFIG_ISDN_DIVERSION_MODULE 28#define CONFIG_ISDN_DIVERSION 29#endif 30#ifdef CONFIG_ISDN_DIVERSION 31#include <linux/isdn_divertif.h> 32#endif /* CONFIG_ISDN_DIVERSION */ 33#include "isdn_v110.h" 34 35/* Debugflags */ 36#undef ISDN_DEBUG_STATCALLB 37 38MODULE_DESCRIPTION("ISDN4Linux: link layer"); 39MODULE_AUTHOR("Fritz Elfert"); 40MODULE_LICENSE("GPL"); 41 42isdn_dev *dev; 43 44static char *isdn_revision = "$Revision: 1.1.1.1 $"; 45 46extern char *isdn_net_revision; 47extern char *isdn_tty_revision; 48#ifdef CONFIG_ISDN_PPP 49extern char *isdn_ppp_revision; 50#else 51static char *isdn_ppp_revision = ": none $"; 52#endif 53#ifdef CONFIG_ISDN_AUDIO 54extern char *isdn_audio_revision; 55#else 56static char *isdn_audio_revision = ": none $"; 57#endif 58extern char *isdn_v110_revision; 59 60#ifdef CONFIG_ISDN_DIVERSION 61static isdn_divert_if *divert_if; /* = NULL */ 62#endif /* CONFIG_ISDN_DIVERSION */ 63 64 65static int isdn_writebuf_stub(int, int, const u_char __user *, int); 66static void set_global_features(void); 67static int isdn_wildmat(char *s, char *p); 68static int isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding); 69 70static inline void 71isdn_lock_driver(isdn_driver_t *drv) 72{ 73 try_module_get(drv->interface->owner); 74 drv->locks++; 75} 76 77void 78isdn_lock_drivers(void) 79{ 80 int i; 81 82 for (i = 0; i < ISDN_MAX_DRIVERS; i++) { 83 if (!dev->drv[i]) 84 continue; 85 isdn_lock_driver(dev->drv[i]); 86 } 87} 88 89static inline void 90isdn_unlock_driver(isdn_driver_t *drv) 91{ 92 if (drv->locks > 0) { 93 drv->locks--; 94 module_put(drv->interface->owner); 95 } 96} 97 98void 99isdn_unlock_drivers(void) 100{ 101 int i; 102 103 for (i = 0; i < ISDN_MAX_DRIVERS; i++) { 104 if (!dev->drv[i]) 105 continue; 106 isdn_unlock_driver(dev->drv[i]); 107 } 108} 109 110#if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP) 111void 112isdn_dumppkt(char *s, u_char * p, int len, int dumplen) 113{ 114 int dumpc; 115 116 printk(KERN_DEBUG "%s(%d) ", s, len); 117 for (dumpc = 0; (dumpc < dumplen) && (len); len--, dumpc++) 118 printk(" %02x", *p++); 119 printk("\n"); 120} 121#endif 122 123/* 124 * I picked the pattern-matching-functions from an old GNU-tar version (1.10) 125 * It was originally written and put to PD by rs@mirror.TMC.COM (Rich Salz) 126 */ 127static int 128isdn_star(char *s, char *p) 129{ 130 while (isdn_wildmat(s, p)) { 131 if (*++s == '\0') 132 return (2); 133 } 134 return (0); 135} 136 137/* 138 * Shell-type Pattern-matching for incoming caller-Ids 139 * This function gets a string in s and checks, if it matches the pattern 140 * given in p. 141 * 142 * Return: 143 * 0 = match. 144 * 1 = no match. 145 * 2 = no match. Would eventually match, if s would be longer. 146 * 147 * Possible Patterns: 148 * 149 * '?' matches one character 150 * '*' matches zero or more characters 151 * [xyz] matches the set of characters in brackets. 152 * [^xyz] matches any single character not in the set of characters 153 */ 154 155static int 156isdn_wildmat(char *s, char *p) 157{ 158 register int last; 159 register int matched; 160 register int reverse; 161 register int nostar = 1; 162 163 if (!(*s) && !(*p)) 164 return(1); 165 for (; *p; s++, p++) 166 switch (*p) { 167 case '\\': 168 /* 169 * Literal match with following character, 170 * fall through. 171 */ 172 p++; 173 default: 174 if (*s != *p) 175 return (*s == '\0')?2:1; 176 continue; 177 case '?': 178 /* Match anything. */ 179 if (*s == '\0') 180 return (2); 181 continue; 182 case '*': 183 nostar = 0; 184 /* Trailing star matches everything. */ 185 return (*++p ? isdn_star(s, p) : 0); 186 case '[': 187 /* [^....] means inverse character class. */ 188 if ((reverse = (p[1] == '^'))) 189 p++; 190 for (last = 0, matched = 0; *++p && (*p != ']'); last = *p) 191 /* This next line requires a good C compiler. */ 192 if (*p == '-' ? *s <= *++p && *s >= last : *s == *p) 193 matched = 1; 194 if (matched == reverse) 195 return (1); 196 continue; 197 } 198 return (*s == '\0')?0:nostar; 199} 200 201int isdn_msncmp( const char * msn1, const char * msn2 ) 202{ 203 char TmpMsn1[ ISDN_MSNLEN ]; 204 char TmpMsn2[ ISDN_MSNLEN ]; 205 char *p; 206 207 for ( p = TmpMsn1; *msn1 && *msn1 != ':'; ) // Strip off a SPID 208 *p++ = *msn1++; 209 *p = '\0'; 210 211 for ( p = TmpMsn2; *msn2 && *msn2 != ':'; ) // Strip off a SPID 212 *p++ = *msn2++; 213 *p = '\0'; 214 215 return isdn_wildmat( TmpMsn1, TmpMsn2 ); 216} 217 218int 219isdn_dc2minor(int di, int ch) 220{ 221 int i; 222 for (i = 0; i < ISDN_MAX_CHANNELS; i++) 223 if (dev->chanmap[i] == ch && dev->drvmap[i] == di) 224 return i; 225 return -1; 226} 227 228static int isdn_timer_cnt1 = 0; 229static int isdn_timer_cnt2 = 0; 230static int isdn_timer_cnt3 = 0; 231 232static void 233isdn_timer_funct(ulong dummy) 234{ 235 int tf = dev->tflags; 236 if (tf & ISDN_TIMER_FAST) { 237 if (tf & ISDN_TIMER_MODEMREAD) 238 isdn_tty_readmodem(); 239 if (tf & ISDN_TIMER_MODEMPLUS) 240 isdn_tty_modem_escape(); 241 if (tf & ISDN_TIMER_MODEMXMIT) 242 isdn_tty_modem_xmit(); 243 } 244 if (tf & ISDN_TIMER_SLOW) { 245 if (++isdn_timer_cnt1 >= ISDN_TIMER_02SEC) { 246 isdn_timer_cnt1 = 0; 247 if (tf & ISDN_TIMER_NETDIAL) 248 isdn_net_dial(); 249 } 250 if (++isdn_timer_cnt2 >= ISDN_TIMER_1SEC) { 251 isdn_timer_cnt2 = 0; 252 if (tf & ISDN_TIMER_NETHANGUP) 253 isdn_net_autohup(); 254 if (++isdn_timer_cnt3 >= ISDN_TIMER_RINGING) { 255 isdn_timer_cnt3 = 0; 256 if (tf & ISDN_TIMER_MODEMRING) 257 isdn_tty_modem_ring(); 258 } 259 if (tf & ISDN_TIMER_CARRIER) 260 isdn_tty_carrier_timeout(); 261 } 262 } 263 if (tf) 264 mod_timer(&dev->timer, jiffies+ISDN_TIMER_RES); 265} 266 267void 268isdn_timer_ctrl(int tf, int onoff) 269{ 270 unsigned long flags; 271 int old_tflags; 272 273 spin_lock_irqsave(&dev->timerlock, flags); 274 if ((tf & ISDN_TIMER_SLOW) && (!(dev->tflags & ISDN_TIMER_SLOW))) { 275 /* If the slow-timer wasn't activated until now */ 276 isdn_timer_cnt1 = 0; 277 isdn_timer_cnt2 = 0; 278 } 279 old_tflags = dev->tflags; 280 if (onoff) 281 dev->tflags |= tf; 282 else 283 dev->tflags &= ~tf; 284 if (dev->tflags && !old_tflags) 285 mod_timer(&dev->timer, jiffies+ISDN_TIMER_RES); 286 spin_unlock_irqrestore(&dev->timerlock, flags); 287} 288 289/* 290 * Receive a packet from B-Channel. (Called from low-level-module) 291 */ 292static void 293isdn_receive_skb_callback(int di, int channel, struct sk_buff *skb) 294{ 295 int i; 296 297 if ((i = isdn_dc2minor(di, channel)) == -1) { 298 dev_kfree_skb(skb); 299 return; 300 } 301 /* Update statistics */ 302 dev->ibytes[i] += skb->len; 303 304 /* First, try to deliver data to network-device */ 305 if (isdn_net_rcv_skb(i, skb)) 306 return; 307 308 /* V.110 handling 309 * makes sense for async streams only, so it is 310 * called after possible net-device delivery. 311 */ 312 if (dev->v110[i]) { 313 atomic_inc(&dev->v110use[i]); 314 skb = isdn_v110_decode(dev->v110[i], skb); 315 atomic_dec(&dev->v110use[i]); 316 if (!skb) 317 return; 318 } 319 320 /* No network-device found, deliver to tty or raw-channel */ 321 if (skb->len) { 322 if (isdn_tty_rcv_skb(i, di, channel, skb)) 323 return; 324 wake_up_interruptible(&dev->drv[di]->rcv_waitq[channel]); 325 } else 326 dev_kfree_skb(skb); 327} 328 329/* 330 * Intercept command from Linklevel to Lowlevel. 331 * If layer 2 protocol is V.110 and this is not supported by current 332 * lowlevel-driver, use driver's transparent mode and handle V.110 in 333 * linklevel instead. 334 */ 335int 336isdn_command(isdn_ctrl *cmd) 337{ 338 if (cmd->driver == -1) { 339 printk(KERN_WARNING "isdn_command command(%x) driver -1\n", cmd->command); 340 return(1); 341 } 342 if (!dev->drv[cmd->driver]) { 343 printk(KERN_WARNING "isdn_command command(%x) dev->drv[%d] NULL\n", 344 cmd->command, cmd->driver); 345 return(1); 346 } 347 if (!dev->drv[cmd->driver]->interface) { 348 printk(KERN_WARNING "isdn_command command(%x) dev->drv[%d]->interface NULL\n", 349 cmd->command, cmd->driver); 350 return(1); 351 } 352 if (cmd->command == ISDN_CMD_SETL2) { 353 int idx = isdn_dc2minor(cmd->driver, cmd->arg & 255); 354 unsigned long l2prot = (cmd->arg >> 8) & 255; 355 unsigned long features = (dev->drv[cmd->driver]->interface->features 356 >> ISDN_FEATURE_L2_SHIFT) & 357 ISDN_FEATURE_L2_MASK; 358 unsigned long l2_feature = (1 << l2prot); 359 360 switch (l2prot) { 361 case ISDN_PROTO_L2_V11096: 362 case ISDN_PROTO_L2_V11019: 363 case ISDN_PROTO_L2_V11038: 364 /* If V.110 requested, but not supported by 365 * HL-driver, set emulator-flag and change 366 * Layer-2 to transparent 367 */ 368 if (!(features & l2_feature)) { 369 dev->v110emu[idx] = l2prot; 370 cmd->arg = (cmd->arg & 255) | 371 (ISDN_PROTO_L2_TRANS << 8); 372 } else 373 dev->v110emu[idx] = 0; 374 } 375 } 376 return dev->drv[cmd->driver]->interface->command(cmd); 377} 378 379void 380isdn_all_eaz(int di, int ch) 381{ 382 isdn_ctrl cmd; 383 384 if (di < 0) 385 return; 386 cmd.driver = di; 387 cmd.arg = ch; 388 cmd.command = ISDN_CMD_SETEAZ; 389 cmd.parm.num[0] = '\0'; 390 isdn_command(&cmd); 391} 392 393/* 394 * Begin of a CAPI like LL<->HL interface, currently used only for 395 * supplementary service (CAPI 2.0 part III) 396 */ 397#include <linux/isdn/capicmd.h> 398 399static int 400isdn_capi_rec_hl_msg(capi_msg *cm) { 401 402 int di; 403 int ch; 404 405 di = (cm->adr.Controller & 0x7f) -1; 406 ch = isdn_dc2minor(di, (cm->adr.Controller>>8)& 0x7f); 407 switch(cm->Command) { 408 case CAPI_FACILITY: 409 /* in the moment only handled in tty */ 410 return(isdn_tty_capi_facility(cm)); 411 default: 412 return(-1); 413 } 414} 415 416static int 417isdn_status_callback(isdn_ctrl * c) 418{ 419 int di; 420 u_long flags; 421 int i; 422 int r; 423 int retval = 0; 424 isdn_ctrl cmd; 425 isdn_net_dev *p; 426 427 di = c->driver; 428 i = isdn_dc2minor(di, c->arg); 429 switch (c->command) { 430 case ISDN_STAT_BSENT: 431 if (i < 0) 432 return -1; 433 if (dev->global_flags & ISDN_GLOBAL_STOPPED) 434 return 0; 435 if (isdn_net_stat_callback(i, c)) 436 return 0; 437 if (isdn_v110_stat_callback(i, c)) 438 return 0; 439 if (isdn_tty_stat_callback(i, c)) 440 return 0; 441 wake_up_interruptible(&dev->drv[di]->snd_waitq[c->arg]); 442 break; 443 case ISDN_STAT_STAVAIL: 444 dev->drv[di]->stavail += c->arg; 445 wake_up_interruptible(&dev->drv[di]->st_waitq); 446 break; 447 case ISDN_STAT_RUN: 448 dev->drv[di]->flags |= DRV_FLAG_RUNNING; 449 for (i = 0; i < ISDN_MAX_CHANNELS; i++) 450 if (dev->drvmap[i] == di) 451 isdn_all_eaz(di, dev->chanmap[i]); 452 set_global_features(); 453 break; 454 case ISDN_STAT_STOP: 455 dev->drv[di]->flags &= ~DRV_FLAG_RUNNING; 456 break; 457 case ISDN_STAT_ICALL: 458 if (i < 0) 459 return -1; 460#ifdef ISDN_DEBUG_STATCALLB 461 printk(KERN_DEBUG "ICALL (net): %d %ld %s\n", di, c->arg, c->parm.num); 462#endif 463 if (dev->global_flags & ISDN_GLOBAL_STOPPED) { 464 cmd.driver = di; 465 cmd.arg = c->arg; 466 cmd.command = ISDN_CMD_HANGUP; 467 isdn_command(&cmd); 468 return 0; 469 } 470 /* Try to find a network-interface which will accept incoming call */ 471 r = ((c->command == ISDN_STAT_ICALLW) ? 0 : isdn_net_find_icall(di, c->arg, i, &c->parm.setup)); 472 switch (r) { 473 case 0: 474 /* No network-device replies. 475 * Try ttyI's. 476 * These return 0 on no match, 1 on match and 477 * 3 on eventually match, if CID is longer. 478 */ 479 if (c->command == ISDN_STAT_ICALL) 480 if ((retval = isdn_tty_find_icall(di, c->arg, &c->parm.setup))) return(retval); 481#ifdef CONFIG_ISDN_DIVERSION 482 if (divert_if) 483 if ((retval = divert_if->stat_callback(c))) 484 return(retval); /* processed */ 485#endif /* CONFIG_ISDN_DIVERSION */ 486 if ((!retval) && (dev->drv[di]->flags & DRV_FLAG_REJBUS)) { 487 /* No tty responding */ 488 cmd.driver = di; 489 cmd.arg = c->arg; 490 cmd.command = ISDN_CMD_HANGUP; 491 isdn_command(&cmd); 492 retval = 2; 493 } 494 break; 495 case 1: 496 /* Schedule connection-setup */ 497 isdn_net_dial(); 498 cmd.driver = di; 499 cmd.arg = c->arg; 500 cmd.command = ISDN_CMD_ACCEPTD; 501 for ( p = dev->netdev; p; p = p->next ) 502 if ( p->local->isdn_channel == cmd.arg ) 503 { 504 strcpy( cmd.parm.setup.eazmsn, p->local->msn ); 505 isdn_command(&cmd); 506 retval = 1; 507 break; 508 } 509 break; 510 511 case 2: /* For calling back, first reject incoming call ... */ 512 case 3: /* Interface found, but down, reject call actively */ 513 retval = 2; 514 printk(KERN_INFO "isdn: Rejecting Call\n"); 515 cmd.driver = di; 516 cmd.arg = c->arg; 517 cmd.command = ISDN_CMD_HANGUP; 518 isdn_command(&cmd); 519 if (r == 3) 520 break; 521 /* Fall through */ 522 case 4: 523 /* ... then start callback. */ 524 isdn_net_dial(); 525 break; 526 case 5: 527 /* Number would eventually match, if longer */ 528 retval = 3; 529 break; 530 } 531#ifdef ISDN_DEBUG_STATCALLB 532 printk(KERN_DEBUG "ICALL: ret=%d\n", retval); 533#endif 534 return retval; 535 break; 536 case ISDN_STAT_CINF: 537 if (i < 0) 538 return -1; 539#ifdef ISDN_DEBUG_STATCALLB 540 printk(KERN_DEBUG "CINF: %ld %s\n", c->arg, c->parm.num); 541#endif 542 if (dev->global_flags & ISDN_GLOBAL_STOPPED) 543 return 0; 544 if (strcmp(c->parm.num, "0")) 545 isdn_net_stat_callback(i, c); 546 isdn_tty_stat_callback(i, c); 547 break; 548 case ISDN_STAT_CAUSE: 549#ifdef ISDN_DEBUG_STATCALLB 550 printk(KERN_DEBUG "CAUSE: %ld %s\n", c->arg, c->parm.num); 551#endif 552 printk(KERN_INFO "isdn: %s,ch%ld cause: %s\n", 553 dev->drvid[di], c->arg, c->parm.num); 554 isdn_tty_stat_callback(i, c); 555#ifdef CONFIG_ISDN_DIVERSION 556 if (divert_if) 557 divert_if->stat_callback(c); 558#endif /* CONFIG_ISDN_DIVERSION */ 559 break; 560 case ISDN_STAT_DISPLAY: 561#ifdef ISDN_DEBUG_STATCALLB 562 printk(KERN_DEBUG "DISPLAY: %ld %s\n", c->arg, c->parm.display); 563#endif 564 isdn_tty_stat_callback(i, c); 565#ifdef CONFIG_ISDN_DIVERSION 566 if (divert_if) 567 divert_if->stat_callback(c); 568#endif /* CONFIG_ISDN_DIVERSION */ 569 break; 570 case ISDN_STAT_DCONN: 571 if (i < 0) 572 return -1; 573#ifdef ISDN_DEBUG_STATCALLB 574 printk(KERN_DEBUG "DCONN: %ld\n", c->arg); 575#endif 576 if (dev->global_flags & ISDN_GLOBAL_STOPPED) 577 return 0; 578 /* Find any net-device, waiting for D-channel setup */ 579 if (isdn_net_stat_callback(i, c)) 580 break; 581 isdn_v110_stat_callback(i, c); 582 /* Find any ttyI, waiting for D-channel setup */ 583 if (isdn_tty_stat_callback(i, c)) { 584 cmd.driver = di; 585 cmd.arg = c->arg; 586 cmd.command = ISDN_CMD_ACCEPTB; 587 isdn_command(&cmd); 588 break; 589 } 590 break; 591 case ISDN_STAT_DHUP: 592 if (i < 0) 593 return -1; 594#ifdef ISDN_DEBUG_STATCALLB 595 printk(KERN_DEBUG "DHUP: %ld\n", c->arg); 596#endif 597 if (dev->global_flags & ISDN_GLOBAL_STOPPED) 598 return 0; 599 dev->drv[di]->online &= ~(1 << (c->arg)); 600 isdn_info_update(); 601 /* Signal hangup to network-devices */ 602 if (isdn_net_stat_callback(i, c)) 603 break; 604 isdn_v110_stat_callback(i, c); 605 if (isdn_tty_stat_callback(i, c)) 606 break; 607#ifdef CONFIG_ISDN_DIVERSION 608 if (divert_if) 609 divert_if->stat_callback(c); 610#endif /* CONFIG_ISDN_DIVERSION */ 611 break; 612 break; 613 case ISDN_STAT_BCONN: 614 if (i < 0) 615 return -1; 616#ifdef ISDN_DEBUG_STATCALLB 617 printk(KERN_DEBUG "BCONN: %ld\n", c->arg); 618#endif 619 /* Signal B-channel-connect to network-devices */ 620 if (dev->global_flags & ISDN_GLOBAL_STOPPED) 621 return 0; 622 dev->drv[di]->online |= (1 << (c->arg)); 623 isdn_info_update(); 624 if (isdn_net_stat_callback(i, c)) 625 break; 626 isdn_v110_stat_callback(i, c); 627 if (isdn_tty_stat_callback(i, c)) 628 break; 629 break; 630 case ISDN_STAT_BHUP: 631 if (i < 0) 632 return -1; 633#ifdef ISDN_DEBUG_STATCALLB 634 printk(KERN_DEBUG "BHUP: %ld\n", c->arg); 635#endif 636 if (dev->global_flags & ISDN_GLOBAL_STOPPED) 637 return 0; 638 dev->drv[di]->online &= ~(1 << (c->arg)); 639 isdn_info_update(); 640#ifdef CONFIG_ISDN_X25 641 /* Signal hangup to network-devices */ 642 if (isdn_net_stat_callback(i, c)) 643 break; 644#endif 645 isdn_v110_stat_callback(i, c); 646 if (isdn_tty_stat_callback(i, c)) 647 break; 648 break; 649 case ISDN_STAT_NODCH: 650 if (i < 0) 651 return -1; 652#ifdef ISDN_DEBUG_STATCALLB 653 printk(KERN_DEBUG "NODCH: %ld\n", c->arg); 654#endif 655 if (dev->global_flags & ISDN_GLOBAL_STOPPED) 656 return 0; 657 if (isdn_net_stat_callback(i, c)) 658 break; 659 if (isdn_tty_stat_callback(i, c)) 660 break; 661 break; 662 case ISDN_STAT_ADDCH: 663 spin_lock_irqsave(&dev->lock, flags); 664 if (isdn_add_channels(dev->drv[di], di, c->arg, 1)) { 665 spin_unlock_irqrestore(&dev->lock, flags); 666 return -1; 667 } 668 spin_unlock_irqrestore(&dev->lock, flags); 669 isdn_info_update(); 670 break; 671 case ISDN_STAT_DISCH: 672 spin_lock_irqsave(&dev->lock, flags); 673 for (i = 0; i < ISDN_MAX_CHANNELS; i++) 674 if ((dev->drvmap[i] == di) && 675 (dev->chanmap[i] == c->arg)) { 676 if (c->parm.num[0]) 677 dev->usage[i] &= ~ISDN_USAGE_DISABLED; 678 else 679 if (USG_NONE(dev->usage[i])) { 680 dev->usage[i] |= ISDN_USAGE_DISABLED; 681 } 682 else 683 retval = -1; 684 break; 685 } 686 spin_unlock_irqrestore(&dev->lock, flags); 687 isdn_info_update(); 688 break; 689 case ISDN_STAT_UNLOAD: 690 while (dev->drv[di]->locks > 0) { 691 isdn_unlock_driver(dev->drv[di]); 692 } 693 spin_lock_irqsave(&dev->lock, flags); 694 isdn_tty_stat_callback(i, c); 695 for (i = 0; i < ISDN_MAX_CHANNELS; i++) 696 if (dev->drvmap[i] == di) { 697 dev->drvmap[i] = -1; 698 dev->chanmap[i] = -1; 699 dev->usage[i] &= ~ISDN_USAGE_DISABLED; 700 } 701 dev->drivers--; 702 dev->channels -= dev->drv[di]->channels; 703 kfree(dev->drv[di]->rcverr); 704 kfree(dev->drv[di]->rcvcount); 705 for (i = 0; i < dev->drv[di]->channels; i++) 706 skb_queue_purge(&dev->drv[di]->rpqueue[i]); 707 kfree(dev->drv[di]->rpqueue); 708 kfree(dev->drv[di]->rcv_waitq); 709 kfree(dev->drv[di]); 710 dev->drv[di] = NULL; 711 dev->drvid[di][0] = '\0'; 712 isdn_info_update(); 713 set_global_features(); 714 spin_unlock_irqrestore(&dev->lock, flags); 715 return 0; 716 case ISDN_STAT_L1ERR: 717 break; 718 case CAPI_PUT_MESSAGE: 719 return(isdn_capi_rec_hl_msg(&c->parm.cmsg)); 720#ifdef CONFIG_ISDN_TTY_FAX 721 case ISDN_STAT_FAXIND: 722 isdn_tty_stat_callback(i, c); 723 break; 724#endif 725#ifdef CONFIG_ISDN_AUDIO 726 case ISDN_STAT_AUDIO: 727 isdn_tty_stat_callback(i, c); 728 break; 729#endif 730#ifdef CONFIG_ISDN_DIVERSION 731 case ISDN_STAT_PROT: 732 case ISDN_STAT_REDIR: 733 if (divert_if) 734 return(divert_if->stat_callback(c)); 735#endif /* CONFIG_ISDN_DIVERSION */ 736 default: 737 return -1; 738 } 739 return 0; 740} 741 742/* 743 * Get integer from char-pointer, set pointer to end of number 744 */ 745int 746isdn_getnum(char **p) 747{ 748 int v = -1; 749 750 while (*p[0] >= '0' && *p[0] <= '9') 751 v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p[0]++) - '0'); 752 return v; 753} 754 755#define DLE 0x10 756 757/* 758 * isdn_readbchan() tries to get data from the read-queue. 759 * It MUST be called with interrupts off. 760 * 761 * Be aware that this is not an atomic operation when sleep != 0, even though 762 * interrupts are turned off! Well, like that we are currently only called 763 * on behalf of a read system call on raw device files (which are documented 764 * to be dangerous and for for debugging purpose only). The inode semaphore 765 * takes care that this is not called for the same minor device number while 766 * we are sleeping, but access is not serialized against simultaneous read() 767 * from the corresponding ttyI device. Can other ugly events, like changes 768 * of the mapping (di,ch)<->minor, happen during the sleep? --he 769 */ 770int 771isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_queue_head_t *sleep) 772{ 773 int count; 774 int count_pull; 775 int count_put; 776 int dflag; 777 struct sk_buff *skb; 778 u_char *cp; 779 780 if (!dev->drv[di]) 781 return 0; 782 if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) { 783 if (sleep) 784 interruptible_sleep_on(sleep); 785 else 786 return 0; 787 } 788 if (len > dev->drv[di]->rcvcount[channel]) 789 len = dev->drv[di]->rcvcount[channel]; 790 cp = buf; 791 count = 0; 792 while (len) { 793 if (!(skb = skb_peek(&dev->drv[di]->rpqueue[channel]))) 794 break; 795#ifdef CONFIG_ISDN_AUDIO 796 if (ISDN_AUDIO_SKB_LOCK(skb)) 797 break; 798 ISDN_AUDIO_SKB_LOCK(skb) = 1; 799 if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->drv[di]->DLEflag & (1 << channel))) { 800 char *p = skb->data; 801 unsigned long DLEmask = (1 << channel); 802 803 dflag = 0; 804 count_pull = count_put = 0; 805 while ((count_pull < skb->len) && (len > 0)) { 806 len--; 807 if (dev->drv[di]->DLEflag & DLEmask) { 808 *cp++ = DLE; 809 dev->drv[di]->DLEflag &= ~DLEmask; 810 } else { 811 *cp++ = *p; 812 if (*p == DLE) { 813 dev->drv[di]->DLEflag |= DLEmask; 814 (ISDN_AUDIO_SKB_DLECOUNT(skb))--; 815 } 816 p++; 817 count_pull++; 818 } 819 count_put++; 820 } 821 if (count_pull >= skb->len) 822 dflag = 1; 823 } else { 824#endif 825 /* No DLE's in buff, so simply copy it */ 826 dflag = 1; 827 if ((count_pull = skb->len) > len) { 828 count_pull = len; 829 dflag = 0; 830 } 831 count_put = count_pull; 832 skb_copy_from_linear_data(skb, cp, count_put); 833 cp += count_put; 834 len -= count_put; 835#ifdef CONFIG_ISDN_AUDIO 836 } 837#endif 838 count += count_put; 839 if (fp) { 840 memset(fp, 0, count_put); 841 fp += count_put; 842 } 843 if (dflag) { 844 /* We got all the data in this buff. 845 * Now we can dequeue it. 846 */ 847 if (fp) 848 *(fp - 1) = 0xff; 849#ifdef CONFIG_ISDN_AUDIO 850 ISDN_AUDIO_SKB_LOCK(skb) = 0; 851#endif 852 skb = skb_dequeue(&dev->drv[di]->rpqueue[channel]); 853 dev_kfree_skb(skb); 854 } else { 855 /* Not yet emptied this buff, so it 856 * must stay in the queue, for further calls 857 * but we pull off the data we got until now. 858 */ 859 skb_pull(skb, count_pull); 860#ifdef CONFIG_ISDN_AUDIO 861 ISDN_AUDIO_SKB_LOCK(skb) = 0; 862#endif 863 } 864 dev->drv[di]->rcvcount[channel] -= count_put; 865 } 866 return count; 867} 868 869/* 870 * isdn_readbchan_tty() tries to get data from the read-queue. 871 * It MUST be called with interrupts off. 872 * 873 * Be aware that this is not an atomic operation when sleep != 0, even though 874 * interrupts are turned off! Well, like that we are currently only called 875 * on behalf of a read system call on raw device files (which are documented 876 * to be dangerous and for for debugging purpose only). The inode semaphore 877 * takes care that this is not called for the same minor device number while 878 * we are sleeping, but access is not serialized against simultaneous read() 879 * from the corresponding ttyI device. Can other ugly events, like changes 880 * of the mapping (di,ch)<->minor, happen during the sleep? --he 881 */ 882int 883isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) 884{ 885 int count; 886 int count_pull; 887 int count_put; 888 int dflag; 889 struct sk_buff *skb; 890 char last = 0; 891 int len; 892 893 if (!dev->drv[di]) 894 return 0; 895 if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) 896 return 0; 897 898 len = tty_buffer_request_room(tty, dev->drv[di]->rcvcount[channel]); 899 if(len == 0) 900 return len; 901 902 count = 0; 903 while (len) { 904 if (!(skb = skb_peek(&dev->drv[di]->rpqueue[channel]))) 905 break; 906#ifdef CONFIG_ISDN_AUDIO 907 if (ISDN_AUDIO_SKB_LOCK(skb)) 908 break; 909 ISDN_AUDIO_SKB_LOCK(skb) = 1; 910 if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->drv[di]->DLEflag & (1 << channel))) { 911 char *p = skb->data; 912 unsigned long DLEmask = (1 << channel); 913 914 dflag = 0; 915 count_pull = count_put = 0; 916 while ((count_pull < skb->len) && (len > 0)) { 917 len--; 918 if (dev->drv[di]->DLEflag & DLEmask) { 919 last = DLE; 920 dev->drv[di]->DLEflag &= ~DLEmask; 921 } else { 922 last = *p; 923 if (last == DLE) { 924 dev->drv[di]->DLEflag |= DLEmask; 925 (ISDN_AUDIO_SKB_DLECOUNT(skb))--; 926 } 927 p++; 928 count_pull++; 929 } 930 count_put++; 931 } 932 if (count_pull >= skb->len) 933 dflag = 1; 934 } else { 935#endif 936 /* No DLE's in buff, so simply copy it */ 937 dflag = 1; 938 if ((count_pull = skb->len) > len) { 939 count_pull = len; 940 dflag = 0; 941 } 942 count_put = count_pull; 943 if(count_put > 1) 944 tty_insert_flip_string(tty, skb->data, count_put - 1); 945 last = skb->data[count_put - 1]; 946 len -= count_put; 947#ifdef CONFIG_ISDN_AUDIO 948 } 949#endif 950 count += count_put; 951 if (dflag) { 952 /* We got all the data in this buff. 953 * Now we can dequeue it. 954 */ 955 if(cisco_hack) 956 tty_insert_flip_char(tty, last, 0xFF); 957 else 958 tty_insert_flip_char(tty, last, TTY_NORMAL); 959#ifdef CONFIG_ISDN_AUDIO 960 ISDN_AUDIO_SKB_LOCK(skb) = 0; 961#endif 962 skb = skb_dequeue(&dev->drv[di]->rpqueue[channel]); 963 dev_kfree_skb(skb); 964 } else { 965 tty_insert_flip_char(tty, last, TTY_NORMAL); 966 /* Not yet emptied this buff, so it 967 * must stay in the queue, for further calls 968 * but we pull off the data we got until now. 969 */ 970 skb_pull(skb, count_pull); 971#ifdef CONFIG_ISDN_AUDIO 972 ISDN_AUDIO_SKB_LOCK(skb) = 0; 973#endif 974 } 975 dev->drv[di]->rcvcount[channel] -= count_put; 976 } 977 return count; 978} 979 980 981static __inline int 982isdn_minor2drv(int minor) 983{ 984 return (dev->drvmap[minor]); 985} 986 987static __inline int 988isdn_minor2chan(int minor) 989{ 990 return (dev->chanmap[minor]); 991} 992 993static char * 994isdn_statstr(void) 995{ 996 static char istatbuf[2048]; 997 char *p; 998 int i; 999 1000 sprintf(istatbuf, "idmap:\t"); 1001 p = istatbuf + strlen(istatbuf); 1002 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 1003 sprintf(p, "%s ", (dev->drvmap[i] < 0) ? "-" : dev->drvid[dev->drvmap[i]]); 1004 p = istatbuf + strlen(istatbuf); 1005 } 1006 sprintf(p, "\nchmap:\t"); 1007 p = istatbuf + strlen(istatbuf); 1008 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 1009 sprintf(p, "%d ", dev->chanmap[i]); 1010 p = istatbuf + strlen(istatbuf); 1011 } 1012 sprintf(p, "\ndrmap:\t"); 1013 p = istatbuf + strlen(istatbuf); 1014 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 1015 sprintf(p, "%d ", dev->drvmap[i]); 1016 p = istatbuf + strlen(istatbuf); 1017 } 1018 sprintf(p, "\nusage:\t"); 1019 p = istatbuf + strlen(istatbuf); 1020 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 1021 sprintf(p, "%d ", dev->usage[i]); 1022 p = istatbuf + strlen(istatbuf); 1023 } 1024 sprintf(p, "\nflags:\t"); 1025 p = istatbuf + strlen(istatbuf); 1026 for (i = 0; i < ISDN_MAX_DRIVERS; i++) { 1027 if (dev->drv[i]) { 1028 sprintf(p, "%ld ", dev->drv[i]->online); 1029 p = istatbuf + strlen(istatbuf); 1030 } else { 1031 sprintf(p, "? "); 1032 p = istatbuf + strlen(istatbuf); 1033 } 1034 } 1035 sprintf(p, "\nphone:\t"); 1036 p = istatbuf + strlen(istatbuf); 1037 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 1038 sprintf(p, "%s ", dev->num[i]); 1039 p = istatbuf + strlen(istatbuf); 1040 } 1041 sprintf(p, "\n"); 1042 return istatbuf; 1043} 1044 1045/* Module interface-code */ 1046 1047void 1048isdn_info_update(void) 1049{ 1050 infostruct *p = dev->infochain; 1051 1052 while (p) { 1053 *(p->private) = 1; 1054 p = (infostruct *) p->next; 1055 } 1056 wake_up_interruptible(&(dev->info_waitq)); 1057} 1058 1059static ssize_t 1060isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off) 1061{ 1062 uint minor = iminor(file->f_path.dentry->d_inode); 1063 int len = 0; 1064 int drvidx; 1065 int chidx; 1066 int retval; 1067 char *p; 1068 1069 lock_kernel(); 1070 if (minor == ISDN_MINOR_STATUS) { 1071 if (!file->private_data) { 1072 if (file->f_flags & O_NONBLOCK) { 1073 retval = -EAGAIN; 1074 goto out; 1075 } 1076 interruptible_sleep_on(&(dev->info_waitq)); 1077 } 1078 p = isdn_statstr(); 1079 file->private_data = NULL; 1080 if ((len = strlen(p)) <= count) { 1081 if (copy_to_user(buf, p, len)) { 1082 retval = -EFAULT; 1083 goto out; 1084 } 1085 *off += len; 1086 retval = len; 1087 goto out; 1088 } 1089 retval = 0; 1090 goto out; 1091 } 1092 if (!dev->drivers) { 1093 retval = -ENODEV; 1094 goto out; 1095 } 1096 if (minor <= ISDN_MINOR_BMAX) { 1097 printk(KERN_WARNING "isdn_read minor %d obsolete!\n", minor); 1098 drvidx = isdn_minor2drv(minor); 1099 if (drvidx < 0) { 1100 retval = -ENODEV; 1101 goto out; 1102 } 1103 if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING)) { 1104 retval = -ENODEV; 1105 goto out; 1106 } 1107 chidx = isdn_minor2chan(minor); 1108 if (!(p = kmalloc(count, GFP_KERNEL))) { 1109 retval = -ENOMEM; 1110 goto out; 1111 } 1112 len = isdn_readbchan(drvidx, chidx, p, NULL, count, 1113 &dev->drv[drvidx]->rcv_waitq[chidx]); 1114 *off += len; 1115 if (copy_to_user(buf,p,len)) 1116 len = -EFAULT; 1117 kfree(p); 1118 retval = len; 1119 goto out; 1120 } 1121 if (minor <= ISDN_MINOR_CTRLMAX) { 1122 drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL); 1123 if (drvidx < 0) { 1124 retval = -ENODEV; 1125 goto out; 1126 } 1127 if (!dev->drv[drvidx]->stavail) { 1128 if (file->f_flags & O_NONBLOCK) { 1129 retval = -EAGAIN; 1130 goto out; 1131 } 1132 interruptible_sleep_on(&(dev->drv[drvidx]->st_waitq)); 1133 } 1134 if (dev->drv[drvidx]->interface->readstat) { 1135 if (count > dev->drv[drvidx]->stavail) 1136 count = dev->drv[drvidx]->stavail; 1137 len = dev->drv[drvidx]->interface->readstat(buf, count, 1138 drvidx, isdn_minor2chan(minor)); 1139 if (len < 0) { 1140 retval = len; 1141 goto out; 1142 } 1143 } else { 1144 len = 0; 1145 } 1146 if (len) 1147 dev->drv[drvidx]->stavail -= len; 1148 else 1149 dev->drv[drvidx]->stavail = 0; 1150 *off += len; 1151 retval = len; 1152 goto out; 1153 } 1154#ifdef CONFIG_ISDN_PPP 1155 if (minor <= ISDN_MINOR_PPPMAX) { 1156 retval = isdn_ppp_read(minor - ISDN_MINOR_PPP, file, buf, count); 1157 goto out; 1158 } 1159#endif 1160 retval = -ENODEV; 1161 out: 1162 unlock_kernel(); 1163 return retval; 1164} 1165 1166static ssize_t 1167isdn_write(struct file *file, const char __user *buf, size_t count, loff_t * off) 1168{ 1169 uint minor = iminor(file->f_path.dentry->d_inode); 1170 int drvidx; 1171 int chidx; 1172 int retval; 1173 1174 if (minor == ISDN_MINOR_STATUS) 1175 return -EPERM; 1176 if (!dev->drivers) 1177 return -ENODEV; 1178 1179 lock_kernel(); 1180 if (minor <= ISDN_MINOR_BMAX) { 1181 printk(KERN_WARNING "isdn_write minor %d obsolete!\n", minor); 1182 drvidx = isdn_minor2drv(minor); 1183 if (drvidx < 0) { 1184 retval = -ENODEV; 1185 goto out; 1186 } 1187 if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING)) { 1188 retval = -ENODEV; 1189 goto out; 1190 } 1191 chidx = isdn_minor2chan(minor); 1192 while ((retval = isdn_writebuf_stub(drvidx, chidx, buf, count)) == 0) 1193 interruptible_sleep_on(&dev->drv[drvidx]->snd_waitq[chidx]); 1194 goto out; 1195 } 1196 if (minor <= ISDN_MINOR_CTRLMAX) { 1197 drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL); 1198 if (drvidx < 0) { 1199 retval = -ENODEV; 1200 goto out; 1201 } 1202 /* 1203 * We want to use the isdnctrl device to load the firmware 1204 * 1205 if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING)) 1206 return -ENODEV; 1207 */ 1208 if (dev->drv[drvidx]->interface->writecmd) 1209 retval = dev->drv[drvidx]->interface-> 1210 writecmd(buf, count, drvidx, isdn_minor2chan(minor)); 1211 else 1212 retval = count; 1213 goto out; 1214 } 1215#ifdef CONFIG_ISDN_PPP 1216 if (minor <= ISDN_MINOR_PPPMAX) { 1217 retval = isdn_ppp_write(minor - ISDN_MINOR_PPP, file, buf, count); 1218 goto out; 1219 } 1220#endif 1221 retval = -ENODEV; 1222 out: 1223 unlock_kernel(); 1224 return retval; 1225} 1226 1227static unsigned int 1228isdn_poll(struct file *file, poll_table * wait) 1229{ 1230 unsigned int mask = 0; 1231 unsigned int minor = iminor(file->f_path.dentry->d_inode); 1232 int drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL); 1233 1234 lock_kernel(); 1235 if (minor == ISDN_MINOR_STATUS) { 1236 poll_wait(file, &(dev->info_waitq), wait); 1237 /* mask = POLLOUT | POLLWRNORM; */ 1238 if (file->private_data) { 1239 mask |= POLLIN | POLLRDNORM; 1240 } 1241 goto out; 1242 } 1243 if (minor >= ISDN_MINOR_CTRL && minor <= ISDN_MINOR_CTRLMAX) { 1244 if (drvidx < 0) { 1245 /* driver deregistered while file open */ 1246 mask = POLLHUP; 1247 goto out; 1248 } 1249 poll_wait(file, &(dev->drv[drvidx]->st_waitq), wait); 1250 mask = POLLOUT | POLLWRNORM; 1251 if (dev->drv[drvidx]->stavail) { 1252 mask |= POLLIN | POLLRDNORM; 1253 } 1254 goto out; 1255 } 1256#ifdef CONFIG_ISDN_PPP 1257 if (minor <= ISDN_MINOR_PPPMAX) { 1258 mask = isdn_ppp_poll(file, wait); 1259 goto out; 1260 } 1261#endif 1262 mask = POLLERR; 1263 out: 1264 unlock_kernel(); 1265 return mask; 1266} 1267 1268 1269static int 1270isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) 1271{ 1272 uint minor = iminor(inode); 1273 isdn_ctrl c; 1274 int drvidx; 1275 int chidx; 1276 int ret; 1277 int i; 1278 char __user *p; 1279 char *s; 1280 union iocpar { 1281 char name[10]; 1282 char bname[22]; 1283 isdn_ioctl_struct iocts; 1284 isdn_net_ioctl_phone phone; 1285 isdn_net_ioctl_cfg cfg; 1286 } iocpar; 1287 void __user *argp = (void __user *)arg; 1288 1289#define name iocpar.name 1290#define bname iocpar.bname 1291#define iocts iocpar.iocts 1292#define phone iocpar.phone 1293#define cfg iocpar.cfg 1294 1295 if (minor == ISDN_MINOR_STATUS) { 1296 switch (cmd) { 1297 case IIOCGETDVR: 1298 return (TTY_DV + 1299 (NET_DV << 8) + 1300 (INF_DV << 16)); 1301 case IIOCGETCPS: 1302 if (arg) { 1303 ulong __user *p = argp; 1304 int i; 1305 if (!access_ok(VERIFY_WRITE, p, 1306 sizeof(ulong) * ISDN_MAX_CHANNELS * 2)) 1307 return -EFAULT; 1308 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 1309 put_user(dev->ibytes[i], p++); 1310 put_user(dev->obytes[i], p++); 1311 } 1312 return 0; 1313 } else 1314 return -EINVAL; 1315 break; 1316#ifdef CONFIG_NETDEVICES 1317 case IIOCNETGPN: 1318 /* Get peer phone number of a connected 1319 * isdn network interface */ 1320 if (arg) { 1321 if (copy_from_user(&phone, argp, sizeof(phone))) 1322 return -EFAULT; 1323 return isdn_net_getpeer(&phone, argp); 1324 } else 1325 return -EINVAL; 1326#endif 1327 default: 1328 return -EINVAL; 1329 } 1330 } 1331 if (!dev->drivers) 1332 return -ENODEV; 1333 if (minor <= ISDN_MINOR_BMAX) { 1334 drvidx = isdn_minor2drv(minor); 1335 if (drvidx < 0) 1336 return -ENODEV; 1337 chidx = isdn_minor2chan(minor); 1338 if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING)) 1339 return -ENODEV; 1340 return 0; 1341 } 1342 if (minor <= ISDN_MINOR_CTRLMAX) { 1343/* 1344 * isdn net devices manage lots of configuration variables as linked lists. 1345 * Those lists must only be manipulated from user space. Some of the ioctl's 1346 * service routines access user space and are not atomic. Therefor, ioctl's 1347 * manipulating the lists and ioctl's sleeping while accessing the lists 1348 * are serialized by means of a semaphore. 1349 */ 1350 switch (cmd) { 1351 case IIOCNETDWRSET: 1352 printk(KERN_INFO "INFO: ISDN_DW_ABC_EXTENSION not enabled\n"); 1353 return(-EINVAL); 1354 case IIOCNETLCR: 1355 printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n"); 1356 return -ENODEV; 1357#ifdef CONFIG_NETDEVICES 1358 case IIOCNETAIF: 1359 /* Add a network-interface */ 1360 if (arg) { 1361 if (copy_from_user(name, argp, sizeof(name))) 1362 return -EFAULT; 1363 s = name; 1364 } else { 1365 s = NULL; 1366 } 1367 ret = down_interruptible(&dev->sem); 1368 if( ret ) return ret; 1369 if ((s = isdn_net_new(s, NULL))) { 1370 if (copy_to_user(argp, s, strlen(s) + 1)){ 1371 ret = -EFAULT; 1372 } else { 1373 ret = 0; 1374 } 1375 } else 1376 ret = -ENODEV; 1377 up(&dev->sem); 1378 return ret; 1379 case IIOCNETASL: 1380 /* Add a slave to a network-interface */ 1381 if (arg) { 1382 if (copy_from_user(bname, argp, sizeof(bname) - 1)) 1383 return -EFAULT; 1384 } else 1385 return -EINVAL; 1386 ret = down_interruptible(&dev->sem); 1387 if( ret ) return ret; 1388 if ((s = isdn_net_newslave(bname))) { 1389 if (copy_to_user(argp, s, strlen(s) + 1)){ 1390 ret = -EFAULT; 1391 } else { 1392 ret = 0; 1393 } 1394 } else 1395 ret = -ENODEV; 1396 up(&dev->sem); 1397 return ret; 1398 case IIOCNETDIF: 1399 /* Delete a network-interface */ 1400 if (arg) { 1401 if (copy_from_user(name, argp, sizeof(name))) 1402 return -EFAULT; 1403 ret = down_interruptible(&dev->sem); 1404 if( ret ) return ret; 1405 ret = isdn_net_rm(name); 1406 up(&dev->sem); 1407 return ret; 1408 } else 1409 return -EINVAL; 1410 case IIOCNETSCF: 1411 /* Set configurable parameters of a network-interface */ 1412 if (arg) { 1413 if (copy_from_user(&cfg, argp, sizeof(cfg))) 1414 return -EFAULT; 1415 return isdn_net_setcfg(&cfg); 1416 } else 1417 return -EINVAL; 1418 case IIOCNETGCF: 1419 /* Get configurable parameters of a network-interface */ 1420 if (arg) { 1421 if (copy_from_user(&cfg, argp, sizeof(cfg))) 1422 return -EFAULT; 1423 if (!(ret = isdn_net_getcfg(&cfg))) { 1424 if (copy_to_user(argp, &cfg, sizeof(cfg))) 1425 return -EFAULT; 1426 } 1427 return ret; 1428 } else 1429 return -EINVAL; 1430 case IIOCNETANM: 1431 /* Add a phone-number to a network-interface */ 1432 if (arg) { 1433 if (copy_from_user(&phone, argp, sizeof(phone))) 1434 return -EFAULT; 1435 ret = down_interruptible(&dev->sem); 1436 if( ret ) return ret; 1437 ret = isdn_net_addphone(&phone); 1438 up(&dev->sem); 1439 return ret; 1440 } else 1441 return -EINVAL; 1442 case IIOCNETGNM: 1443 /* Get list of phone-numbers of a network-interface */ 1444 if (arg) { 1445 if (copy_from_user(&phone, argp, sizeof(phone))) 1446 return -EFAULT; 1447 ret = down_interruptible(&dev->sem); 1448 if( ret ) return ret; 1449 ret = isdn_net_getphones(&phone, argp); 1450 up(&dev->sem); 1451 return ret; 1452 } else 1453 return -EINVAL; 1454 case IIOCNETDNM: 1455 /* Delete a phone-number of a network-interface */ 1456 if (arg) { 1457 if (copy_from_user(&phone, argp, sizeof(phone))) 1458 return -EFAULT; 1459 ret = down_interruptible(&dev->sem); 1460 if( ret ) return ret; 1461 ret = isdn_net_delphone(&phone); 1462 up(&dev->sem); 1463 return ret; 1464 } else 1465 return -EINVAL; 1466 case IIOCNETDIL: 1467 /* Force dialing of a network-interface */ 1468 if (arg) { 1469 if (copy_from_user(name, argp, sizeof(name))) 1470 return -EFAULT; 1471 return isdn_net_force_dial(name); 1472 } else 1473 return -EINVAL; 1474#ifdef CONFIG_ISDN_PPP 1475 case IIOCNETALN: 1476 if (!arg) 1477 return -EINVAL; 1478 if (copy_from_user(name, argp, sizeof(name))) 1479 return -EFAULT; 1480 return isdn_ppp_dial_slave(name); 1481 case IIOCNETDLN: 1482 if (!arg) 1483 return -EINVAL; 1484 if (copy_from_user(name, argp, sizeof(name))) 1485 return -EFAULT; 1486 return isdn_ppp_hangup_slave(name); 1487#endif 1488 case IIOCNETHUP: 1489 /* Force hangup of a network-interface */ 1490 if (!arg) 1491 return -EINVAL; 1492 if (copy_from_user(name, argp, sizeof(name))) 1493 return -EFAULT; 1494 return isdn_net_force_hangup(name); 1495 break; 1496#endif /* CONFIG_NETDEVICES */ 1497 case IIOCSETVER: 1498 dev->net_verbose = arg; 1499 printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose); 1500 return 0; 1501 case IIOCSETGST: 1502 if (arg) 1503 dev->global_flags |= ISDN_GLOBAL_STOPPED; 1504 else 1505 dev->global_flags &= ~ISDN_GLOBAL_STOPPED; 1506 printk(KERN_INFO "isdn: Global Mode %s\n", 1507 (dev->global_flags & ISDN_GLOBAL_STOPPED) ? "stopped" : "running"); 1508 return 0; 1509 case IIOCSETBRJ: 1510 drvidx = -1; 1511 if (arg) { 1512 int i; 1513 char *p; 1514 if (copy_from_user(&iocts, argp, 1515 sizeof(isdn_ioctl_struct))) 1516 return -EFAULT; 1517 if (strlen(iocts.drvid)) { 1518 if ((p = strchr(iocts.drvid, ','))) 1519 *p = 0; 1520 drvidx = -1; 1521 for (i = 0; i < ISDN_MAX_DRIVERS; i++) 1522 if (!(strcmp(dev->drvid[i], iocts.drvid))) { 1523 drvidx = i; 1524 break; 1525 } 1526 } 1527 } 1528 if (drvidx == -1) 1529 return -ENODEV; 1530 if (iocts.arg) 1531 dev->drv[drvidx]->flags |= DRV_FLAG_REJBUS; 1532 else 1533 dev->drv[drvidx]->flags &= ~DRV_FLAG_REJBUS; 1534 return 0; 1535 case IIOCSIGPRF: 1536 dev->profd = current; 1537 return 0; 1538 break; 1539 case IIOCGETPRF: 1540 /* Get all Modem-Profiles */ 1541 if (arg) { 1542 char __user *p = argp; 1543 int i; 1544 1545 if (!access_ok(VERIFY_WRITE, argp, 1546 (ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN) 1547 * ISDN_MAX_CHANNELS)) 1548 return -EFAULT; 1549 1550 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 1551 if (copy_to_user(p, dev->mdm.info[i].emu.profile, 1552 ISDN_MODEM_NUMREG)) 1553 return -EFAULT; 1554 p += ISDN_MODEM_NUMREG; 1555 if (copy_to_user(p, dev->mdm.info[i].emu.pmsn, ISDN_MSNLEN)) 1556 return -EFAULT; 1557 p += ISDN_MSNLEN; 1558 if (copy_to_user(p, dev->mdm.info[i].emu.plmsn, ISDN_LMSNLEN)) 1559 return -EFAULT; 1560 p += ISDN_LMSNLEN; 1561 } 1562 return (ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN) * ISDN_MAX_CHANNELS; 1563 } else 1564 return -EINVAL; 1565 break; 1566 case IIOCSETPRF: 1567 /* Set all Modem-Profiles */ 1568 if (arg) { 1569 char __user *p = argp; 1570 int i; 1571 1572 if (!access_ok(VERIFY_READ, argp, 1573 (ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN) 1574 * ISDN_MAX_CHANNELS)) 1575 return -EFAULT; 1576 1577 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 1578 if (copy_from_user(dev->mdm.info[i].emu.profile, p, 1579 ISDN_MODEM_NUMREG)) 1580 return -EFAULT; 1581 p += ISDN_MODEM_NUMREG; 1582 if (copy_from_user(dev->mdm.info[i].emu.plmsn, p, ISDN_LMSNLEN)) 1583 return -EFAULT; 1584 p += ISDN_LMSNLEN; 1585 if (copy_from_user(dev->mdm.info[i].emu.pmsn, p, ISDN_MSNLEN)) 1586 return -EFAULT; 1587 p += ISDN_MSNLEN; 1588 } 1589 return 0; 1590 } else 1591 return -EINVAL; 1592 break; 1593 case IIOCSETMAP: 1594 case IIOCGETMAP: 1595 /* Set/Get MSN->EAZ-Mapping for a driver */ 1596 if (arg) { 1597 1598 if (copy_from_user(&iocts, argp, 1599 sizeof(isdn_ioctl_struct))) 1600 return -EFAULT; 1601 if (strlen(iocts.drvid)) { 1602 drvidx = -1; 1603 for (i = 0; i < ISDN_MAX_DRIVERS; i++) 1604 if (!(strcmp(dev->drvid[i], iocts.drvid))) { 1605 drvidx = i; 1606 break; 1607 } 1608 } else 1609 drvidx = 0; 1610 if (drvidx == -1) 1611 return -ENODEV; 1612 if (cmd == IIOCSETMAP) { 1613 int loop = 1; 1614 1615 p = (char __user *) iocts.arg; 1616 i = 0; 1617 while (loop) { 1618 int j = 0; 1619 1620 while (1) { 1621 if (!access_ok(VERIFY_READ, p, 1)) 1622 return -EFAULT; 1623 get_user(bname[j], p++); 1624 switch (bname[j]) { 1625 case '\0': 1626 loop = 0; 1627 /* Fall through */ 1628 case ',': 1629 bname[j] = '\0'; 1630 strcpy(dev->drv[drvidx]->msn2eaz[i], bname); 1631 j = ISDN_MSNLEN; 1632 break; 1633 default: 1634 j++; 1635 } 1636 if (j >= ISDN_MSNLEN) 1637 break; 1638 } 1639 if (++i > 9) 1640 break; 1641 } 1642 } else { 1643 p = (char __user *) iocts.arg; 1644 for (i = 0; i < 10; i++) { 1645 sprintf(bname, "%s%s", 1646 strlen(dev->drv[drvidx]->msn2eaz[i]) ? 1647 dev->drv[drvidx]->msn2eaz[i] : "_", 1648 (i < 9) ? "," : "\0"); 1649 if (copy_to_user(p, bname, strlen(bname) + 1)) 1650 return -EFAULT; 1651 p += strlen(bname); 1652 } 1653 } 1654 return 0; 1655 } else 1656 return -EINVAL; 1657 case IIOCDBGVAR: 1658 if (arg) { 1659 if (copy_to_user(argp, &dev, sizeof(ulong))) 1660 return -EFAULT; 1661 return 0; 1662 } else 1663 return -EINVAL; 1664 break; 1665 default: 1666 if ((cmd & IIOCDRVCTL) == IIOCDRVCTL) 1667 cmd = ((cmd >> _IOC_NRSHIFT) & _IOC_NRMASK) & ISDN_DRVIOCTL_MASK; 1668 else 1669 return -EINVAL; 1670 if (arg) { 1671 int i; 1672 char *p; 1673 if (copy_from_user(&iocts, argp, sizeof(isdn_ioctl_struct))) 1674 return -EFAULT; 1675 if (strlen(iocts.drvid)) { 1676 if ((p = strchr(iocts.drvid, ','))) 1677 *p = 0; 1678 drvidx = -1; 1679 for (i = 0; i < ISDN_MAX_DRIVERS; i++) 1680 if (!(strcmp(dev->drvid[i], iocts.drvid))) { 1681 drvidx = i; 1682 break; 1683 } 1684 } else 1685 drvidx = 0; 1686 if (drvidx == -1) 1687 return -ENODEV; 1688 if (!access_ok(VERIFY_WRITE, argp, 1689 sizeof(isdn_ioctl_struct))) 1690 return -EFAULT; 1691 c.driver = drvidx; 1692 c.command = ISDN_CMD_IOCTL; 1693 c.arg = cmd; 1694 memcpy(c.parm.num, &iocts.arg, sizeof(ulong)); 1695 ret = isdn_command(&c); 1696 memcpy(&iocts.arg, c.parm.num, sizeof(ulong)); 1697 if (copy_to_user(argp, &iocts, sizeof(isdn_ioctl_struct))) 1698 return -EFAULT; 1699 return ret; 1700 } else 1701 return -EINVAL; 1702 } 1703 } 1704#ifdef CONFIG_ISDN_PPP 1705 if (minor <= ISDN_MINOR_PPPMAX) 1706 return (isdn_ppp_ioctl(minor - ISDN_MINOR_PPP, file, cmd, arg)); 1707#endif 1708 return -ENODEV; 1709 1710#undef name 1711#undef bname 1712#undef iocts 1713#undef phone 1714#undef cfg 1715} 1716 1717/* 1718 * Open the device code. 1719 */ 1720static int 1721isdn_open(struct inode *ino, struct file *filep) 1722{ 1723 uint minor = iminor(ino); 1724 int drvidx; 1725 int chidx; 1726 int retval = -ENODEV; 1727 1728 1729 if (minor == ISDN_MINOR_STATUS) { 1730 infostruct *p; 1731 1732 if ((p = kmalloc(sizeof(infostruct), GFP_KERNEL))) { 1733 p->next = (char *) dev->infochain; 1734 p->private = (char *) &(filep->private_data); 1735 dev->infochain = p; 1736 /* At opening we allow a single update */ 1737 filep->private_data = (char *) 1; 1738 retval = 0; 1739 goto out; 1740 } else { 1741 retval = -ENOMEM; 1742 goto out; 1743 } 1744 } 1745 if (!dev->channels) 1746 goto out; 1747 if (minor <= ISDN_MINOR_BMAX) { 1748 printk(KERN_WARNING "isdn_open minor %d obsolete!\n", minor); 1749 drvidx = isdn_minor2drv(minor); 1750 if (drvidx < 0) 1751 goto out; 1752 chidx = isdn_minor2chan(minor); 1753 if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING)) 1754 goto out; 1755 if (!(dev->drv[drvidx]->online & (1 << chidx))) 1756 goto out; 1757 isdn_lock_drivers(); 1758 retval = 0; 1759 goto out; 1760 } 1761 if (minor <= ISDN_MINOR_CTRLMAX) { 1762 drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL); 1763 if (drvidx < 0) 1764 goto out; 1765 isdn_lock_drivers(); 1766 retval = 0; 1767 goto out; 1768 } 1769#ifdef CONFIG_ISDN_PPP 1770 if (minor <= ISDN_MINOR_PPPMAX) { 1771 retval = isdn_ppp_open(minor - ISDN_MINOR_PPP, filep); 1772 if (retval == 0) 1773 isdn_lock_drivers(); 1774 goto out; 1775 } 1776#endif 1777 out: 1778 nonseekable_open(ino, filep); 1779 return retval; 1780} 1781 1782static int 1783isdn_close(struct inode *ino, struct file *filep) 1784{ 1785 uint minor = iminor(ino); 1786 1787 lock_kernel(); 1788 if (minor == ISDN_MINOR_STATUS) { 1789 infostruct *p = dev->infochain; 1790 infostruct *q = NULL; 1791 1792 while (p) { 1793 if (p->private == (char *) &(filep->private_data)) { 1794 if (q) 1795 q->next = p->next; 1796 else 1797 dev->infochain = (infostruct *) (p->next); 1798 kfree(p); 1799 goto out; 1800 } 1801 q = p; 1802 p = (infostruct *) (p->next); 1803 } 1804 printk(KERN_WARNING "isdn: No private data while closing isdnctrl\n"); 1805 goto out; 1806 } 1807 isdn_unlock_drivers(); 1808 if (minor <= ISDN_MINOR_BMAX) 1809 goto out; 1810 if (minor <= ISDN_MINOR_CTRLMAX) { 1811 if (dev->profd == current) 1812 dev->profd = NULL; 1813 goto out; 1814 } 1815#ifdef CONFIG_ISDN_PPP 1816 if (minor <= ISDN_MINOR_PPPMAX) 1817 isdn_ppp_release(minor - ISDN_MINOR_PPP, filep); 1818#endif 1819 1820 out: 1821 unlock_kernel(); 1822 return 0; 1823} 1824 1825static const struct file_operations isdn_fops = 1826{ 1827 .owner = THIS_MODULE, 1828 .llseek = no_llseek, 1829 .read = isdn_read, 1830 .write = isdn_write, 1831 .poll = isdn_poll, 1832 .ioctl = isdn_ioctl, 1833 .open = isdn_open, 1834 .release = isdn_close, 1835}; 1836 1837char * 1838isdn_map_eaz2msn(char *msn, int di) 1839{ 1840 isdn_driver_t *this = dev->drv[di]; 1841 int i; 1842 1843 if (strlen(msn) == 1) { 1844 i = msn[0] - '0'; 1845 if ((i >= 0) && (i <= 9)) 1846 if (strlen(this->msn2eaz[i])) 1847 return (this->msn2eaz[i]); 1848 } 1849 return (msn); 1850} 1851 1852/* 1853 * Find an unused ISDN-channel, whose feature-flags match the 1854 * given L2- and L3-protocols. 1855 */ 1856#define L2V (~(ISDN_FEATURE_L2_V11096|ISDN_FEATURE_L2_V11019|ISDN_FEATURE_L2_V11038)) 1857 1858/* 1859 * This function must be called with holding the dev->lock. 1860 */ 1861int 1862isdn_get_free_channel(int usage, int l2_proto, int l3_proto, int pre_dev 1863 ,int pre_chan, char *msn) 1864{ 1865 int i; 1866 ulong features; 1867 ulong vfeatures; 1868 1869 features = ((1 << l2_proto) | (0x10000 << l3_proto)); 1870 vfeatures = (((1 << l2_proto) | (0x10000 << l3_proto)) & 1871 ~(ISDN_FEATURE_L2_V11096|ISDN_FEATURE_L2_V11019|ISDN_FEATURE_L2_V11038)); 1872 /* If Layer-2 protocol is V.110, accept drivers with 1873 * transparent feature even if these don't support V.110 1874 * because we can emulate this in linklevel. 1875 */ 1876 for (i = 0; i < ISDN_MAX_CHANNELS; i++) 1877 if (USG_NONE(dev->usage[i]) && 1878 (dev->drvmap[i] != -1)) { 1879 int d = dev->drvmap[i]; 1880 if ((dev->usage[i] & ISDN_USAGE_EXCLUSIVE) && 1881 ((pre_dev != d) || (pre_chan != dev->chanmap[i]))) 1882 continue; 1883 if (!strcmp(isdn_map_eaz2msn(msn, d), "-")) 1884 continue; 1885 if (dev->usage[i] & ISDN_USAGE_DISABLED) 1886 continue; /* usage not allowed */ 1887 if (dev->drv[d]->flags & DRV_FLAG_RUNNING) { 1888 if (((dev->drv[d]->interface->features & features) == features) || 1889 (((dev->drv[d]->interface->features & vfeatures) == vfeatures) && 1890 (dev->drv[d]->interface->features & ISDN_FEATURE_L2_TRANS))) { 1891 if ((pre_dev < 0) || (pre_chan < 0)) { 1892 dev->usage[i] &= ISDN_USAGE_EXCLUSIVE; 1893 dev->usage[i] |= usage; 1894 isdn_info_update(); 1895 return i; 1896 } else { 1897 if ((pre_dev == d) && (pre_chan == dev->chanmap[i])) { 1898 dev->usage[i] &= ISDN_USAGE_EXCLUSIVE; 1899 dev->usage[i] |= usage; 1900 isdn_info_update(); 1901 return i; 1902 } 1903 } 1904 } 1905 } 1906 } 1907 return -1; 1908} 1909 1910/* 1911 * Set state of ISDN-channel to 'unused' 1912 */ 1913void 1914isdn_free_channel(int di, int ch, int usage) 1915{ 1916 int i; 1917 1918 if ((di < 0) || (ch < 0)) { 1919 printk(KERN_WARNING "%s: called with invalid drv(%d) or channel(%d)\n", 1920 __FUNCTION__, di, ch); 1921 return; 1922 } 1923 for (i = 0; i < ISDN_MAX_CHANNELS; i++) 1924 if (((!usage) || ((dev->usage[i] & ISDN_USAGE_MASK) == usage)) && 1925 (dev->drvmap[i] == di) && 1926 (dev->chanmap[i] == ch)) { 1927 dev->usage[i] &= (ISDN_USAGE_NONE | ISDN_USAGE_EXCLUSIVE); 1928 strcpy(dev->num[i], "???"); 1929 dev->ibytes[i] = 0; 1930 dev->obytes[i] = 0; 1931// 20.10.99 JIM, try to reinitialize v110 ! 1932 dev->v110emu[i] = 0; 1933 atomic_set(&(dev->v110use[i]), 0); 1934 isdn_v110_close(dev->v110[i]); 1935 dev->v110[i] = NULL; 1936// 20.10.99 JIM, try to reinitialize v110 ! 1937 isdn_info_update(); 1938 if (dev->drv[di]) 1939 skb_queue_purge(&dev->drv[di]->rpqueue[ch]); 1940 } 1941} 1942 1943/* 1944 * Cancel Exclusive-Flag for ISDN-channel 1945 */ 1946void 1947isdn_unexclusive_channel(int di, int ch) 1948{ 1949 int i; 1950 1951 for (i = 0; i < ISDN_MAX_CHANNELS; i++) 1952 if ((dev->drvmap[i] == di) && 1953 (dev->chanmap[i] == ch)) { 1954 dev->usage[i] &= ~ISDN_USAGE_EXCLUSIVE; 1955 isdn_info_update(); 1956 return; 1957 } 1958} 1959 1960/* 1961 * writebuf replacement for SKB_ABLE drivers 1962 */ 1963static int 1964isdn_writebuf_stub(int drvidx, int chan, const u_char __user * buf, int len) 1965{ 1966 int ret; 1967 int hl = dev->drv[drvidx]->interface->hl_hdrlen; 1968 struct sk_buff *skb = alloc_skb(hl + len, GFP_ATOMIC); 1969 1970 if (!skb) 1971 return -ENOMEM; 1972 skb_reserve(skb, hl); 1973 if (copy_from_user(skb_put(skb, len), buf, len)) 1974 return -EFAULT; 1975 ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, 1, skb); 1976 if (ret <= 0) 1977 dev_kfree_skb(skb); 1978 if (ret > 0) 1979 dev->obytes[isdn_dc2minor(drvidx, chan)] += ret; 1980 return ret; 1981} 1982 1983/* 1984 * Return: length of data on success, -ERRcode on failure. 1985 */ 1986int 1987isdn_writebuf_skb_stub(int drvidx, int chan, int ack, struct sk_buff *skb) 1988{ 1989 int ret; 1990 struct sk_buff *nskb = NULL; 1991 int v110_ret = skb->len; 1992 int idx = isdn_dc2minor(drvidx, chan); 1993 1994 if (dev->v110[idx]) { 1995 atomic_inc(&dev->v110use[idx]); 1996 nskb = isdn_v110_encode(dev->v110[idx], skb); 1997 atomic_dec(&dev->v110use[idx]); 1998 if (!nskb) 1999 return 0; 2000 v110_ret = *((int *)nskb->data); 2001 skb_pull(nskb, sizeof(int)); 2002 if (!nskb->len) { 2003 dev_kfree_skb(nskb); 2004 return v110_ret; 2005 } 2006 /* V.110 must always be acknowledged */ 2007 ack = 1; 2008 ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, nskb); 2009 } else { 2010 int hl = dev->drv[drvidx]->interface->hl_hdrlen; 2011 2012 if( skb_headroom(skb) < hl ){ 2013 /* 2014 * This should only occur when new HL driver with 2015 * increased hl_hdrlen was loaded after netdevice 2016 * was created and connected to the new driver. 2017 * 2018 * The V.110 branch (re-allocates on its own) does 2019 * not need this 2020 */ 2021 struct sk_buff * skb_tmp; 2022 2023 skb_tmp = skb_realloc_headroom(skb, hl); 2024 printk(KERN_DEBUG "isdn_writebuf_skb_stub: reallocating headroom%s\n", skb_tmp ? "" : " failed"); 2025 if (!skb_tmp) return -ENOMEM; /* 0 better? */ 2026 ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, skb_tmp); 2027 if( ret > 0 ){ 2028 dev_kfree_skb(skb); 2029 } else { 2030 dev_kfree_skb(skb_tmp); 2031 } 2032 } else { 2033 ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, skb); 2034 } 2035 } 2036 if (ret > 0) { 2037 dev->obytes[idx] += ret; 2038 if (dev->v110[idx]) { 2039 atomic_inc(&dev->v110use[idx]); 2040 dev->v110[idx]->skbuser++; 2041 atomic_dec(&dev->v110use[idx]); 2042 /* For V.110 return unencoded data length */ 2043 ret = v110_ret; 2044 /* if the complete frame was send we free the skb; 2045 if not upper function will requeue the skb */ 2046 if (ret == skb->len) 2047 dev_kfree_skb(skb); 2048 } 2049 } else 2050 if (dev->v110[idx]) 2051 dev_kfree_skb(nskb); 2052 return ret; 2053} 2054 2055static int 2056isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding) 2057{ 2058 int j, k, m; 2059 2060 init_waitqueue_head(&d->st_waitq); 2061 if (d->flags & DRV_FLAG_RUNNING) 2062 return -1; 2063 if (n < 1) return 0; 2064 2065 m = (adding) ? d->channels + n : n; 2066 2067 if (dev->channels + n > ISDN_MAX_CHANNELS) { 2068 printk(KERN_WARNING "register_isdn: Max. %d channels supported\n", 2069 ISDN_MAX_CHANNELS); 2070 return -1; 2071 } 2072 2073 if ((adding) && (d->rcverr)) 2074 kfree(d->rcverr); 2075 if (!(d->rcverr = kzalloc(sizeof(int) * m, GFP_ATOMIC))) { 2076 printk(KERN_WARNING "register_isdn: Could not alloc rcverr\n"); 2077 return -1; 2078 } 2079 2080 if ((adding) && (d->rcvcount)) 2081 kfree(d->rcvcount); 2082 if (!(d->rcvcount = kzalloc(sizeof(int) * m, GFP_ATOMIC))) { 2083 printk(KERN_WARNING "register_isdn: Could not alloc rcvcount\n"); 2084 if (!adding) 2085 kfree(d->rcverr); 2086 return -1; 2087 } 2088 2089 if ((adding) && (d->rpqueue)) { 2090 for (j = 0; j < d->channels; j++) 2091 skb_queue_purge(&d->rpqueue[j]); 2092 kfree(d->rpqueue); 2093 } 2094 if (!(d->rpqueue = kmalloc(sizeof(struct sk_buff_head) * m, GFP_ATOMIC))) { 2095 printk(KERN_WARNING "register_isdn: Could not alloc rpqueue\n"); 2096 if (!adding) { 2097 kfree(d->rcvcount); 2098 kfree(d->rcverr); 2099 } 2100 return -1; 2101 } 2102 for (j = 0; j < m; j++) { 2103 skb_queue_head_init(&d->rpqueue[j]); 2104 } 2105 2106 if ((adding) && (d->rcv_waitq)) 2107 kfree(d->rcv_waitq); 2108 d->rcv_waitq = kmalloc(sizeof(wait_queue_head_t) * 2 * m, GFP_ATOMIC); 2109 if (!d->rcv_waitq) { 2110 printk(KERN_WARNING "register_isdn: Could not alloc rcv_waitq\n"); 2111 if (!adding) { 2112 kfree(d->rpqueue); 2113 kfree(d->rcvcount); 2114 kfree(d->rcverr); 2115 } 2116 return -1; 2117 } 2118 d->snd_waitq = d->rcv_waitq + m; 2119 for (j = 0; j < m; j++) { 2120 init_waitqueue_head(&d->rcv_waitq[j]); 2121 init_waitqueue_head(&d->snd_waitq[j]); 2122 } 2123 2124 dev->channels += n; 2125 for (j = d->channels; j < m; j++) 2126 for (k = 0; k < ISDN_MAX_CHANNELS; k++) 2127 if (dev->chanmap[k] < 0) { 2128 dev->chanmap[k] = j; 2129 dev->drvmap[k] = drvidx; 2130 break; 2131 } 2132 d->channels = m; 2133 return 0; 2134} 2135 2136/* 2137 * Low-level-driver registration 2138 */ 2139 2140static void 2141set_global_features(void) 2142{ 2143 int drvidx; 2144 2145 dev->global_features = 0; 2146 for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) { 2147 if (!dev->drv[drvidx]) 2148 continue; 2149 if (dev->drv[drvidx]->interface) 2150 dev->global_features |= dev->drv[drvidx]->interface->features; 2151 } 2152} 2153 2154#ifdef CONFIG_ISDN_DIVERSION 2155 2156static char *map_drvname(int di) 2157{ 2158 if ((di < 0) || (di >= ISDN_MAX_DRIVERS)) 2159 return(NULL); 2160 return(dev->drvid[di]); /* driver name */ 2161} /* map_drvname */ 2162 2163static int map_namedrv(char *id) 2164{ int i; 2165 2166 for (i = 0; i < ISDN_MAX_DRIVERS; i++) 2167 { if (!strcmp(dev->drvid[i],id)) 2168 return(i); 2169 } 2170 return(-1); 2171} /* map_namedrv */ 2172 2173int DIVERT_REG_NAME(isdn_divert_if *i_div) 2174{ 2175 if (i_div->if_magic != DIVERT_IF_MAGIC) 2176 return(DIVERT_VER_ERR); 2177 switch (i_div->cmd) 2178 { 2179 case DIVERT_CMD_REL: 2180 if (divert_if != i_div) 2181 return(DIVERT_REL_ERR); 2182 divert_if = NULL; /* free interface */ 2183 return(DIVERT_NO_ERR); 2184 2185 case DIVERT_CMD_REG: 2186 if (divert_if) 2187 return(DIVERT_REG_ERR); 2188 i_div->ll_cmd = isdn_command; /* set command function */ 2189 i_div->drv_to_name = map_drvname; 2190 i_div->name_to_drv = map_namedrv; 2191 divert_if = i_div; /* remember interface */ 2192 return(DIVERT_NO_ERR); 2193 2194 default: 2195 return(DIVERT_CMD_ERR); 2196 } 2197} /* DIVERT_REG_NAME */ 2198 2199EXPORT_SYMBOL(DIVERT_REG_NAME); 2200 2201#endif /* CONFIG_ISDN_DIVERSION */ 2202 2203 2204EXPORT_SYMBOL(register_isdn); 2205#ifdef CONFIG_ISDN_PPP 2206EXPORT_SYMBOL(isdn_ppp_register_compressor); 2207EXPORT_SYMBOL(isdn_ppp_unregister_compressor); 2208#endif 2209 2210int 2211register_isdn(isdn_if * i) 2212{ 2213 isdn_driver_t *d; 2214 int j; 2215 ulong flags; 2216 int drvidx; 2217 2218 if (dev->drivers >= ISDN_MAX_DRIVERS) { 2219 printk(KERN_WARNING "register_isdn: Max. %d drivers supported\n", 2220 ISDN_MAX_DRIVERS); 2221 return 0; 2222 } 2223 if (!i->writebuf_skb) { 2224 printk(KERN_WARNING "register_isdn: No write routine given.\n"); 2225 return 0; 2226 } 2227 if (!(d = kzalloc(sizeof(isdn_driver_t), GFP_KERNEL))) { 2228 printk(KERN_WARNING "register_isdn: Could not alloc driver-struct\n"); 2229 return 0; 2230 } 2231 2232 d->maxbufsize = i->maxbufsize; 2233 d->pktcount = 0; 2234 d->stavail = 0; 2235 d->flags = DRV_FLAG_LOADED; 2236 d->online = 0; 2237 d->interface = i; 2238 d->channels = 0; 2239 spin_lock_irqsave(&dev->lock, flags); 2240 for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) 2241 if (!dev->drv[drvidx]) 2242 break; 2243 if (isdn_add_channels(d, drvidx, i->channels, 0)) { 2244 spin_unlock_irqrestore(&dev->lock, flags); 2245 kfree(d); 2246 return 0; 2247 } 2248 i->channels = drvidx; 2249 i->rcvcallb_skb = isdn_receive_skb_callback; 2250 i->statcallb = isdn_status_callback; 2251 if (!strlen(i->id)) 2252 sprintf(i->id, "line%d", drvidx); 2253 for (j = 0; j < drvidx; j++) 2254 if (!strcmp(i->id, dev->drvid[j])) 2255 sprintf(i->id, "line%d", drvidx); 2256 dev->drv[drvidx] = d; 2257 strcpy(dev->drvid[drvidx], i->id); 2258 isdn_info_update(); 2259 dev->drivers++; 2260 set_global_features(); 2261 spin_unlock_irqrestore(&dev->lock, flags); 2262 return 1; 2263} 2264 2265/* 2266 ***************************************************************************** 2267 * And now the modules code. 2268 ***************************************************************************** 2269 */ 2270 2271static char * 2272isdn_getrev(const char *revision) 2273{ 2274 char *rev; 2275 char *p; 2276 2277 if ((p = strchr(revision, ':'))) { 2278 rev = p + 2; 2279 p = strchr(rev, '$'); 2280 *--p = 0; 2281 } else 2282 rev = "???"; 2283 return rev; 2284} 2285 2286/* 2287 * Allocate and initialize all data, register modem-devices 2288 */ 2289static int __init isdn_init(void) 2290{ 2291 int i; 2292 char tmprev[50]; 2293 2294 if (!(dev = (isdn_dev *) vmalloc(sizeof(isdn_dev)))) { 2295 printk(KERN_WARNING "isdn: Could not allocate device-struct.\n"); 2296 return -EIO; 2297 } 2298 memset((char *) dev, 0, sizeof(isdn_dev)); 2299 init_timer(&dev->timer); 2300 dev->timer.function = isdn_timer_funct; 2301 spin_lock_init(&dev->lock); 2302 spin_lock_init(&dev->timerlock); 2303#ifdef MODULE 2304 dev->owner = THIS_MODULE; 2305#endif 2306 init_MUTEX(&dev->sem); 2307 init_waitqueue_head(&dev->info_waitq); 2308 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 2309 dev->drvmap[i] = -1; 2310 dev->chanmap[i] = -1; 2311 dev->m_idx[i] = -1; 2312 strcpy(dev->num[i], "???"); 2313 init_waitqueue_head(&dev->mdm.info[i].open_wait); 2314 init_waitqueue_head(&dev->mdm.info[i].close_wait); 2315 } 2316 if (register_chrdev(ISDN_MAJOR, "isdn", &isdn_fops)) { 2317 printk(KERN_WARNING "isdn: Could not register control devices\n"); 2318 vfree(dev); 2319 return -EIO; 2320 } 2321 if ((isdn_tty_modem_init()) < 0) { 2322 printk(KERN_WARNING "isdn: Could not register tty devices\n"); 2323 vfree(dev); 2324 unregister_chrdev(ISDN_MAJOR, "isdn"); 2325 return -EIO; 2326 } 2327#ifdef CONFIG_ISDN_PPP 2328 if (isdn_ppp_init() < 0) { 2329 printk(KERN_WARNING "isdn: Could not create PPP-device-structs\n"); 2330 isdn_tty_exit(); 2331 unregister_chrdev(ISDN_MAJOR, "isdn"); 2332 vfree(dev); 2333 return -EIO; 2334 } 2335#endif /* CONFIG_ISDN_PPP */ 2336 2337 strcpy(tmprev, isdn_revision); 2338 printk(KERN_NOTICE "ISDN subsystem Rev: %s/", isdn_getrev(tmprev)); 2339 strcpy(tmprev, isdn_tty_revision); 2340 printk("%s/", isdn_getrev(tmprev)); 2341 strcpy(tmprev, isdn_net_revision); 2342 printk("%s/", isdn_getrev(tmprev)); 2343 strcpy(tmprev, isdn_ppp_revision); 2344 printk("%s/", isdn_getrev(tmprev)); 2345 strcpy(tmprev, isdn_audio_revision); 2346 printk("%s/", isdn_getrev(tmprev)); 2347 strcpy(tmprev, isdn_v110_revision); 2348 printk("%s", isdn_getrev(tmprev)); 2349 2350#ifdef MODULE 2351 printk(" loaded\n"); 2352#else 2353 printk("\n"); 2354#endif 2355 isdn_info_update(); 2356 return 0; 2357} 2358 2359/* 2360 * Unload module 2361 */ 2362static void __exit isdn_exit(void) 2363{ 2364#ifdef CONFIG_ISDN_PPP 2365 isdn_ppp_cleanup(); 2366#endif 2367 if (isdn_net_rmall() < 0) { 2368 printk(KERN_WARNING "isdn: net-device busy, remove cancelled\n"); 2369 return; 2370 } 2371 isdn_tty_exit(); 2372 unregister_chrdev(ISDN_MAJOR, "isdn"); 2373 del_timer(&dev->timer); 2374 /* call vfree with interrupts enabled, else it will hang */ 2375 vfree(dev); 2376 printk(KERN_NOTICE "ISDN-subsystem unloaded\n"); 2377} 2378 2379module_init(isdn_init); 2380module_exit(isdn_exit); 2381