File: /usr/src/linux/drivers/isdn/isdn_common.c

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