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