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