/* $Id: isdn_common.c,v 1.1.2.3 2004/02/10 01:07:13 keil Exp $
 *
 * Linux ISDN subsystem, common used functions (linklevel).
 *
 * Copyright 1994-1999  by Fritz Elfert (fritz@isdn4linux.de)
 * Copyright 1995,96    Thinking Objects Software GmbH Wuerzburg
 * Copyright 1995,96    by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de)
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/vmalloc.h>
#include <linux/isdn.h>
#include <linux/smp_lock.h>
#include "isdn_common.h"
#include "isdn_tty.h"
#include "isdn_net.h"
#include "isdn_ppp.h"
#ifdef CONFIG_ISDN_AUDIO
#include "isdn_audio.h"
#endif
#ifdef CONFIG_ISDN_DIVERSION_MODULE
#define CONFIG_ISDN_DIVERSION
#endif
#ifdef CONFIG_ISDN_DIVERSION
#include <linux/isdn_divertif.h>
#endif /* CONFIG_ISDN_DIVERSION */
#include "isdn_v110.h"

/* Debugflags */
#undef ISDN_DEBUG_STATCALLB

MODULE_DESCRIPTION("ISDN4Linux: link layer");
MODULE_AUTHOR("Fritz Elfert");
MODULE_LICENSE("GPL");

isdn_dev *dev;

static char *isdn_revision = "$Revision: 1.1.2.3 $";

extern char *isdn_net_revision;
extern char *isdn_tty_revision;
#ifdef CONFIG_ISDN_PPP
extern char *isdn_ppp_revision;
#else
static char *isdn_ppp_revision = ": none $";
#endif
#ifdef CONFIG_ISDN_AUDIO
extern char *isdn_audio_revision;
#else
static char *isdn_audio_revision = ": none $";
#endif
extern char *isdn_v110_revision;

#ifdef CONFIG_ISDN_DIVERSION
static isdn_divert_if *divert_if; /* = NULL */
#endif /* CONFIG_ISDN_DIVERSION */


static int isdn_writebuf_stub(int, int, const u_char __user *, int);
static void set_global_features(void);
static int isdn_wildmat(char *s, char *p);
static int isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding);

static inline void
isdn_lock_driver(isdn_driver_t *drv)
{
	try_module_get(drv->interface->owner);
	drv->locks++;
}

void
isdn_lock_drivers(void)
{
	int i;

	for (i = 0; i < ISDN_MAX_DRIVERS; i++) {
		if (!dev->drv[i])
			continue;
		isdn_lock_driver(dev->drv[i]);
	}
}

static inline void
isdn_unlock_driver(isdn_driver_t *drv)
{
	if (drv->locks > 0) {
		drv->locks--;
		module_put(drv->interface->owner);
	}
}

void
isdn_unlock_drivers(void)
{
	int i;

	for (i = 0; i < ISDN_MAX_DRIVERS; i++) {
		if (!dev->drv[i])
			continue;
		isdn_unlock_driver(dev->drv[i]);
	}
}

#if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
void
isdn_dumppkt(char *s, u_char * p, int len, int dumplen)
{
	int dumpc;

	printk(KERN_DEBUG "%s(%d) ", s, len);
	for (dumpc = 0; (dumpc < dumplen) && (len); len--, dumpc++)
		printk(" %02x", *p++);
	printk("\n");
}
#endif

/*
 * I picked the pattern-matching-functions from an old GNU-tar version (1.10)
 * It was originally written and put to PD by rs@mirror.TMC.COM (Rich Salz)
 */
static int
isdn_star(char *s, char *p)
{
	while (isdn_wildmat(s, p)) {
		if (*++s == '\0')
			return (2);
	}
	return (0);
}

/*
 * Shell-type Pattern-matching for incoming caller-Ids
 * This function gets a string in s and checks, if it matches the pattern
 * given in p.
 *
 * Return:
 *   0 = match.
 *   1 = no match.
 *   2 = no match. Would eventually match, if s would be longer.
 *
 * Possible Patterns:
 *
 * '?'     matches one character
 * '*'     matches zero or more characters
 * [xyz]   matches the set of characters in brackets.
 * [^xyz]  matches any single character not in the set of characters
 */

static int
isdn_wildmat(char *s, char *p)
{
	register int last;
	register int matched;
	register int reverse;
	register int nostar = 1;

	if (!(*s) && !(*p))
		return(1);
	for (; *p; s++, p++)
		switch (*p) {
			case '\\':
				/*
				 * Literal match with following character,
				 * fall through.
				 */
				p++;
			default:
				if (*s != *p)
					return (*s == '\0')?2:1;
				continue;
			case '?':
				/* Match anything. */
				if (*s == '\0')
					return (2);
				continue;
			case '*':
				nostar = 0;	
				/* Trailing star matches everything. */
				return (*++p ? isdn_star(s, p) : 0);
			case '[':
				/* [^....] means inverse character class. */
				if ((reverse = (p[1] == '^')))
					p++;
				for (last = 0, matched = 0; *++p && (*p != ']'); last = *p)
					/* This next line requires a good C compiler. */
					if (*p == '-' ? *s <= *++p && *s >= last : *s == *p)
						matched = 1;
				if (matched == reverse)
					return (1);
				continue;
		}
	return (*s == '\0')?0:nostar;
}

int isdn_msncmp( const char * msn1, const char * msn2 )
{
	char TmpMsn1[ ISDN_MSNLEN ];
	char TmpMsn2[ ISDN_MSNLEN ];
	char *p;

	for ( p = TmpMsn1; *msn1 && *msn1 != ':'; )  // Strip off a SPID
		*p++ = *msn1++;
	*p = '\0';

	for ( p = TmpMsn2; *msn2 && *msn2 != ':'; )  // Strip off a SPID
		*p++ = *msn2++;
	*p = '\0';

	return isdn_wildmat( TmpMsn1, TmpMsn2 );
}

int
isdn_dc2minor(int di, int ch)
{
	int i;
	for (i = 0; i < ISDN_MAX_CHANNELS; i++)
		if (dev->chanmap[i] == ch && dev->drvmap[i] == di)
			return i;
	return -1;
}

static int isdn_timer_cnt1 = 0;
static int isdn_timer_cnt2 = 0;
static int isdn_timer_cnt3 = 0;

static void
isdn_timer_funct(ulong dummy)
{
	int tf = dev->tflags;
	if (tf & ISDN_TIMER_FAST) {
		if (tf & ISDN_TIMER_MODEMREAD)
			isdn_tty_readmodem();
		if (tf & ISDN_TIMER_MODEMPLUS)
			isdn_tty_modem_escape();
		if (tf & ISDN_TIMER_MODEMXMIT)
			isdn_tty_modem_xmit();
	}
	if (tf & ISDN_TIMER_SLOW) {
		if (++isdn_timer_cnt1 >= ISDN_TIMER_02SEC) {
			isdn_timer_cnt1 = 0;
			if (tf & ISDN_TIMER_NETDIAL)
				isdn_net_dial();
		}
		if (++isdn_timer_cnt2 >= ISDN_TIMER_1SEC) {
			isdn_timer_cnt2 = 0;
			if (tf & ISDN_TIMER_NETHANGUP)
				isdn_net_autohup();
			if (++isdn_timer_cnt3 >= ISDN_TIMER_RINGING) {
				isdn_timer_cnt3 = 0;
				if (tf & ISDN_TIMER_MODEMRING)
					isdn_tty_modem_ring();
			}
			if (tf & ISDN_TIMER_CARRIER)
				isdn_tty_carrier_timeout();
		}
	}
	if (tf) 
		mod_timer(&dev->timer, jiffies+ISDN_TIMER_RES);
}

void
isdn_timer_ctrl(int tf, int onoff)
{
	unsigned long flags;
	int old_tflags;

	spin_lock_irqsave(&dev->timerlock, flags);
	if ((tf & ISDN_TIMER_SLOW) && (!(dev->tflags & ISDN_TIMER_SLOW))) {
		/* If the slow-timer wasn't activated until now */
		isdn_timer_cnt1 = 0;
		isdn_timer_cnt2 = 0;
	}
	old_tflags = dev->tflags;
	if (onoff)
		dev->tflags |= tf;
	else
		dev->tflags &= ~tf;
	if (dev->tflags && !old_tflags)
		mod_timer(&dev->timer, jiffies+ISDN_TIMER_RES);
	spin_unlock_irqrestore(&dev->timerlock, flags);
}

/*
 * Receive a packet from B-Channel. (Called from low-level-module)
 */
static void
isdn_receive_skb_callback(int di, int channel, struct sk_buff *skb)
{
	int i;

	if ((i = isdn_dc2minor(di, channel)) == -1) {
		dev_kfree_skb(skb);
		return;
	}
	/* Update statistics */
	dev->ibytes[i] += skb->len;
	
	/* First, try to deliver data to network-device */
	if (isdn_net_rcv_skb(i, skb))
		return;

	/* V.110 handling
	 * makes sense for async streams only, so it is
	 * called after possible net-device delivery.
	 */
	if (dev->v110[i]) {
		atomic_inc(&dev->v110use[i]);
		skb = isdn_v110_decode(dev->v110[i], skb);
		atomic_dec(&dev->v110use[i]);
		if (!skb)
			return;
	}

	/* No network-device found, deliver to tty or raw-channel */
	if (skb->len) {
		if (isdn_tty_rcv_skb(i, di, channel, skb))
			return;
		wake_up_interruptible(&dev->drv[di]->rcv_waitq[channel]);
	} else
		dev_kfree_skb(skb);
}

/*
 * Intercept command from Linklevel to Lowlevel.
 * If layer 2 protocol is V.110 and this is not supported by current
 * lowlevel-driver, use driver's transparent mode and handle V.110 in
 * linklevel instead.
 */
int
isdn_command(isdn_ctrl *cmd)
{
	if (cmd->driver == -1) {
		printk(KERN_WARNING "isdn_command command(%x) driver -1\n", cmd->command);
		return(1);
	}
	if (cmd->command == ISDN_CMD_SETL2) {
		int idx = isdn_dc2minor(cmd->driver, cmd->arg & 255);
		unsigned long l2prot = (cmd->arg >> 8) & 255;
		unsigned long features = (dev->drv[cmd->driver]->interface->features
						>> ISDN_FEATURE_L2_SHIFT) &
						ISDN_FEATURE_L2_MASK;
		unsigned long l2_feature = (1 << l2prot);

		switch (l2prot) {
			case ISDN_PROTO_L2_V11096:
			case ISDN_PROTO_L2_V11019:
			case ISDN_PROTO_L2_V11038:
			/* If V.110 requested, but not supported by
			 * HL-driver, set emulator-flag and change
			 * Layer-2 to transparent
			 */
				if (!(features & l2_feature)) {
					dev->v110emu[idx] = l2prot;
					cmd->arg = (cmd->arg & 255) |
						(ISDN_PROTO_L2_TRANS << 8);
				} else
					dev->v110emu[idx] = 0;
		}
	}
	return dev->drv[cmd->driver]->interface->command(cmd);
}

void
isdn_all_eaz(int di, int ch)
{
	isdn_ctrl cmd;

	if (di < 0)
		return;
	cmd.driver = di;
	cmd.arg = ch;
	cmd.command = ISDN_CMD_SETEAZ;
	cmd.parm.num[0] = '\0';
	isdn_command(&cmd);
}

/*
 * Begin of a CAPI like LL<->HL interface, currently used only for 
 * supplementary service (CAPI 2.0 part III)
 */
#include <linux/isdn/capicmd.h>

static int
isdn_capi_rec_hl_msg(capi_msg *cm) {
	
	int di;
	int ch;
	
	di = (cm->adr.Controller & 0x7f) -1;
	ch = isdn_dc2minor(di, (cm->adr.Controller>>8)& 0x7f);
	switch(cm->Command) {
		case CAPI_FACILITY:
			/* in the moment only handled in tty */
			return(isdn_tty_capi_facility(cm));
		default:
			return(-1);
	}
}

static int
isdn_status_callback(isdn_ctrl * c)
{
	int di;
	u_long flags;
	int i;
	int r;
	int retval = 0;
	isdn_ctrl cmd;
	isdn_net_dev *p;

	di = c->driver;
	i = isdn_dc2minor(di, c->arg);
	switch (c->command) {
		case ISDN_STAT_BSENT:
			if (i < 0)
				return -1;
			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
				return 0;
			if (isdn_net_stat_callback(i, c))
				return 0;
			if (isdn_v110_stat_callback(i, c))
				return 0;
			if (isdn_tty_stat_callback(i, c))
				return 0;
			wake_up_interruptible(&dev->drv[di]->snd_waitq[c->arg]);
			break;
		case ISDN_STAT_STAVAIL:
			dev->drv[di]->stavail += c->arg;
			wake_up_interruptible(&dev->drv[di]->st_waitq);
			break;
		case ISDN_STAT_RUN:
			dev->drv[di]->flags |= DRV_FLAG_RUNNING;
			for (i = 0; i < ISDN_MAX_CHANNELS; i++)
				if (dev->drvmap[i] == di)
					isdn_all_eaz(di, dev->chanmap[i]);
			set_global_features();
			break;
		case ISDN_STAT_STOP:
			dev->drv[di]->flags &= ~DRV_FLAG_RUNNING;
			break;
		case ISDN_STAT_ICALL:
			if (i < 0)
				return -1;
#ifdef ISDN_DEBUG_STATCALLB
			printk(KERN_DEBUG "ICALL (net): %d %ld %s\n", di, c->arg, c->parm.num);
#endif
			if (dev->global_flags & ISDN_GLOBAL_STOPPED) {
				cmd.driver = di;
				cmd.arg = c->arg;
				cmd.command = ISDN_CMD_HANGUP;
				isdn_command(&cmd);
				return 0;
			}
			/* Try to find a network-interface which will accept incoming call */
			r = ((c->command == ISDN_STAT_ICALLW) ? 0 : isdn_net_find_icall(di, c->arg, i, &c->parm.setup));
			switch (r) {
				case 0:
					/* No network-device replies.
					 * Try ttyI's.
					 * These return 0 on no match, 1 on match and
					 * 3 on eventually match, if CID is longer.
					 */
                                        if (c->command == ISDN_STAT_ICALL)
					  if ((retval = isdn_tty_find_icall(di, c->arg, &c->parm.setup))) return(retval);
#ifdef CONFIG_ISDN_DIVERSION 
                                         if (divert_if)
                 	                  if ((retval = divert_if->stat_callback(c))) 
					    return(retval); /* processed */
#endif /* CONFIG_ISDN_DIVERSION */                       
					if ((!retval) && (dev->drv[di]->flags & DRV_FLAG_REJBUS)) {
						/* No tty responding */
						cmd.driver = di;
						cmd.arg = c->arg;
						cmd.command = ISDN_CMD_HANGUP;
						isdn_command(&cmd);
						retval = 2;
					}
					break;
				case 1:
					/* Schedule connection-setup */
					isdn_net_dial();
					cmd.driver = di;
					cmd.arg = c->arg;
					cmd.command = ISDN_CMD_ACCEPTD;
					for ( p = dev->netdev; p; p = p->next )
						if ( p->local->isdn_channel == cmd.arg )
						{
							strcpy( cmd.parm.setup.eazmsn, p->local->msn );
							isdn_command(&cmd);
							retval = 1;
							break;
						}
					break;

				case 2:	/* For calling back, first reject incoming call ... */
				case 3:	/* Interface found, but down, reject call actively  */
					retval = 2;
					printk(KERN_INFO "isdn: Rejecting Call\n");
					cmd.driver = di;
					cmd.arg = c->arg;
					cmd.command = ISDN_CMD_HANGUP;
					isdn_command(&cmd);
					if (r == 3)
						break;
					/* Fall through */
				case 4:
					/* ... then start callback. */
					isdn_net_dial();
					break;
				case 5:
					/* Number would eventually match, if longer */
					retval = 3;
					break;
			}
#ifdef ISDN_DEBUG_STATCALLB
			printk(KERN_DEBUG "ICALL: ret=%d\n", retval);
#endif
			return retval;
			break;
		case ISDN_STAT_CINF:
			if (i < 0)
				return -1;
#ifdef ISDN_DEBUG_STATCALLB
			printk(KERN_DEBUG "CINF: %ld %s\n", c->arg, c->parm.num);
#endif
			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
				return 0;
			if (strcmp(c->parm.num, "0"))
				isdn_net_stat_callback(i, c);
			isdn_tty_stat_callback(i, c);
			break;
		case ISDN_STAT_CAUSE:
#ifdef ISDN_DEBUG_STATCALLB
			printk(KERN_DEBUG "CAUSE: %ld %s\n", c->arg, c->parm.num);
#endif
			printk(KERN_INFO "isdn: %s,ch%ld cause: %s\n",
			       dev->drvid[di], c->arg, c->parm.num);
			isdn_tty_stat_callback(i, c);
#ifdef CONFIG_ISDN_DIVERSION
                        if (divert_if)
                         divert_if->stat_callback(c); 
#endif /* CONFIG_ISDN_DIVERSION */
			break;
		case ISDN_STAT_DISPLAY:
#ifdef ISDN_DEBUG_STATCALLB
			printk(KERN_DEBUG "DISPLAY: %ld %s\n", c->arg, c->parm.display);
#endif
			isdn_tty_stat_callback(i, c);
#ifdef CONFIG_ISDN_DIVERSION
                        if (divert_if)
                         divert_if->stat_callback(c); 
#endif /* CONFIG_ISDN_DIVERSION */
			break;
		case ISDN_STAT_DCONN:
			if (i < 0)
				return -1;
#ifdef ISDN_DEBUG_STATCALLB
			printk(KERN_DEBUG "DCONN: %ld\n", c->arg);
#endif
			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
				return 0;
			/* Find any net-device, waiting for D-channel setup */
			if (isdn_net_stat_callback(i, c))
				break;
			isdn_v110_stat_callback(i, c);
			/* Find any ttyI, waiting for D-channel setup */
			if (isdn_tty_stat_callback(i, c)) {
				cmd.driver = di;
				cmd.arg = c->arg;
				cmd.command = ISDN_CMD_ACCEPTB;
				isdn_command(&cmd);
				break;
			}
			break;
		case ISDN_STAT_DHUP:
			if (i < 0)
				return -1;
#ifdef ISDN_DEBUG_STATCALLB
			printk(KERN_DEBUG "DHUP: %ld\n", c->arg);
#endif
			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
				return 0;
			dev->drv[di]->online &= ~(1 << (c->arg));
			isdn_info_update();
			/* Signal hangup to network-devices */
			if (isdn_net_stat_callback(i, c))
				break;
			isdn_v110_stat_callback(i, c);
			if (isdn_tty_stat_callback(i, c))
				break;
#ifdef CONFIG_ISDN_DIVERSION
                        if (divert_if)
                         divert_if->stat_callback(c); 
#endif /* CONFIG_ISDN_DIVERSION */
			break;
			break;
		case ISDN_STAT_BCONN:
			if (i < 0)
				return -1;
#ifdef ISDN_DEBUG_STATCALLB
			printk(KERN_DEBUG "BCONN: %ld\n", c->arg);
#endif
			/* Signal B-channel-connect to network-devices */
			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
				return 0;
			dev->drv[di]->online |= (1 << (c->arg));
			isdn_info_update();
			if (isdn_net_stat_callback(i, c))
				break;
			isdn_v110_stat_callback(i, c);
			if (isdn_tty_stat_callback(i, c))
				break;
			break;
		case ISDN_STAT_BHUP:
			if (i < 0)
				return -1;
#ifdef ISDN_DEBUG_STATCALLB
			printk(KERN_DEBUG "BHUP: %ld\n", c->arg);
#endif
			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
				return 0;
			dev->drv[di]->online &= ~(1 << (c->arg));
			isdn_info_update();
#ifdef CONFIG_ISDN_X25
			/* Signal hangup to network-devices */
			if (isdn_net_stat_callback(i, c))
				break;
#endif
			isdn_v110_stat_callback(i, c);
			if (isdn_tty_stat_callback(i, c))
				break;
			break;
		case ISDN_STAT_NODCH:
			if (i < 0)
				return -1;
#ifdef ISDN_DEBUG_STATCALLB
			printk(KERN_DEBUG "NODCH: %ld\n", c->arg);
#endif
			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
				return 0;
			if (isdn_net_stat_callback(i, c))
				break;
			if (isdn_tty_stat_callback(i, c))
				break;
			break;
		case ISDN_STAT_ADDCH:
			spin_lock_irqsave(&dev->lock, flags);
			if (isdn_add_channels(dev->drv[di], di, c->arg, 1)) {
				spin_unlock_irqrestore(&dev->lock, flags);
				return -1;
			}
			spin_unlock_irqrestore(&dev->lock, flags);
			isdn_info_update();
			break;
		case ISDN_STAT_DISCH:
			spin_lock_irqsave(&dev->lock, flags);
			for (i = 0; i < ISDN_MAX_CHANNELS; i++)
				if ((dev->drvmap[i] == di) &&
				    (dev->chanmap[i] == c->arg)) {
				    if (c->parm.num[0])
				      dev->usage[i] &= ~ISDN_USAGE_DISABLED;
				    else
				      if (USG_NONE(dev->usage[i])) {
					dev->usage[i] |= ISDN_USAGE_DISABLED;
				      }
				      else 
					retval = -1;
				    break;
				}
			spin_unlock_irqrestore(&dev->lock, flags);
			isdn_info_update();
			break;
		case ISDN_STAT_UNLOAD:
			while (dev->drv[di]->locks > 0) {
				isdn_unlock_driver(dev->drv[di]);
			}
			spin_lock_irqsave(&dev->lock, flags);
			isdn_tty_stat_callback(i, c);
			for (i = 0; i < ISDN_MAX_CHANNELS; i++)
				if (dev->drvmap[i] == di) {
					dev->drvmap[i] = -1;
					dev->chanmap[i] = -1;
					dev->usage[i] &= ~ISDN_USAGE_DISABLED;
				}
			dev->drivers--;
			dev->channels -= dev->drv[di]->channels;
			kfree(dev->drv[di]->rcverr);
			kfree(dev->drv[di]->rcvcount);
			for (i = 0; i < dev->drv[di]->channels; i++)
				skb_queue_purge(&dev->drv[di]->rpqueue[i]);
			kfree(dev->drv[di]->rpqueue);
			kfree(dev->drv[di]->rcv_waitq);
			kfree(dev->drv[di]);
			dev->drv[di] = NULL;
			dev->drvid[di][0] = '\0';
			isdn_info_update();
			set_global_features();
			spin_unlock_irqrestore(&dev->lock, flags);
			return 0;
		case ISDN_STAT_L1ERR:
			break;
		case CAPI_PUT_MESSAGE:
			return(isdn_capi_rec_hl_msg(&c->parm.cmsg));
#ifdef CONFIG_ISDN_TTY_FAX
		case ISDN_STAT_FAXIND:
			isdn_tty_stat_callback(i, c);
			break;
#endif
#ifdef CONFIG_ISDN_AUDIO
		case ISDN_STAT_AUDIO:
			isdn_tty_stat_callback(i, c);
			break;
#endif
#ifdef CONFIG_ISDN_DIVERSION
	        case ISDN_STAT_PROT:
	        case ISDN_STAT_REDIR:
                        if (divert_if)
                          return(divert_if->stat_callback(c));
#endif /* CONFIG_ISDN_DIVERSION */
		default:
			return -1;
	}
	return 0;
}

/*
 * Get integer from char-pointer, set pointer to end of number
 */
int
isdn_getnum(char **p)
{
	int v = -1;

	while (*p[0] >= '0' && *p[0] <= '9')
		v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p[0]++) - '0');
	return v;
}

#define DLE 0x10

/*
 * isdn_readbchan() tries to get data from the read-queue.
 * It MUST be called with interrupts off.
 *
 * Be aware that this is not an atomic operation when sleep != 0, even though 
 * interrupts are turned off! Well, like that we are currently only called
 * on behalf of a read system call on raw device files (which are documented
 * to be dangerous and for for debugging purpose only). The inode semaphore
 * takes care that this is not called for the same minor device number while
 * we are sleeping, but access is not serialized against simultaneous read()
 * from the corresponding ttyI device. Can other ugly events, like changes
 * of the mapping (di,ch)<->minor, happen during the sleep? --he 
 */
int
isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_queue_head_t *sleep)
{
	int count;
	int count_pull;
	int count_put;
	int dflag;
	struct sk_buff *skb;
	u_char *cp;

	if (!dev->drv[di])
		return 0;
	if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) {
		if (sleep)
			interruptible_sleep_on(sleep);
		else
			return 0;
	}
	if (len > dev->drv[di]->rcvcount[channel])
		len = dev->drv[di]->rcvcount[channel];
	cp = buf;
	count = 0;
	while (len) {
		if (!(skb = skb_peek(&dev->drv[di]->rpqueue[channel])))
			break;
#ifdef CONFIG_ISDN_AUDIO
		if (ISDN_AUDIO_SKB_LOCK(skb))
			break;
		ISDN_AUDIO_SKB_LOCK(skb) = 1;
		if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->drv[di]->DLEflag & (1 << channel))) {
			char *p = skb->data;
			unsigned long DLEmask = (1 << channel);

			dflag = 0;
			count_pull = count_put = 0;
			while ((count_pull < skb->len) && (len > 0)) {
				len--;
				if (dev->drv[di]->DLEflag & DLEmask) {
					*cp++ = DLE;
					dev->drv[di]->DLEflag &= ~DLEmask;
				} else {
					*cp++ = *p;
					if (*p == DLE) {
						dev->drv[di]->DLEflag |= DLEmask;
						(ISDN_AUDIO_SKB_DLECOUNT(skb))--;
					}
					p++;
					count_pull++;
				}
				count_put++;
			}
			if (count_pull >= skb->len)
				dflag = 1;
		} else {
#endif
			/* No DLE's in buff, so simply copy it */
			dflag = 1;
			if ((count_pull = skb->len) > len) {
				count_pull = len;
				dflag = 0;
			}
			count_put = count_pull;
			memcpy(cp, skb->data, count_put);
			cp += count_put;
			len -= count_put;
#ifdef CONFIG_ISDN_AUDIO
		}
#endif
		count += count_put;
		if (fp) {
			memset(fp, 0, count_put);
			fp += count_put;
		}
		if (dflag) {
			/* We got all the data in this buff.
			 * Now we can dequeue it.
			 */
			if (fp)
				*(fp - 1) = 0xff;
#ifdef CONFIG_ISDN_AUDIO
			ISDN_AUDIO_SKB_LOCK(skb) = 0;
#endif
			skb = skb_dequeue(&dev->drv[di]->rpqueue[channel]);
			dev_kfree_skb(skb);
		} else {
			/* Not yet emptied this buff, so it
			 * must stay in the queue, for further calls
			 * but we pull off the data we got until now.
			 */
			skb_pull(skb, count_pull);
#ifdef CONFIG_ISDN_AUDIO
			ISDN_AUDIO_SKB_LOCK(skb) = 0;
#endif
		}
		dev->drv[di]->rcvcount[channel] -= count_put;
	}
	return count;
}

/*
 * isdn_readbchan_tty() tries to get data from the read-queue.
 * It MUST be called with interrupts off.
 *
 * Be aware that this is not an atomic operation when sleep != 0, even though
 * interrupts are turned off! Well, like that we are currently only called
 * on behalf of a read system call on raw device files (which are documented
 * to be dangerous and for for debugging purpose only). The inode semaphore
 * takes care that this is not called for the same minor device number while
 * we are sleeping, but access is not serialized against simultaneous read()
 * from the corresponding ttyI device. Can other ugly events, like changes
 * of the mapping (di,ch)<->minor, happen during the sleep? --he
 */
int
isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack)
{
	int count;
	int count_pull;
	int count_put;
	int dflag;
	struct sk_buff *skb;
	char last = 0;
	int len;

	if (!dev->drv[di])
		return 0;
	if (skb_queue_empty(&dev->drv[di]->rpqueue[channel]))
			return 0;

	len = tty_buffer_request_room(tty, dev->drv[di]->rcvcount[channel]);
	if(len == 0)
		return len;

	count = 0;
	while (len) {
		if (!(skb = skb_peek(&dev->drv[di]->rpqueue[channel])))
			break;
#ifdef CONFIG_ISDN_AUDIO
		if (ISDN_AUDIO_SKB_LOCK(skb))
			break;
		ISDN_AUDIO_SKB_LOCK(skb) = 1;
		if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->drv[di]->DLEflag & (1 << channel))) {
			char *p = skb->data;
			unsigned long DLEmask = (1 << channel);

			dflag = 0;
			count_pull = count_put = 0;
			while ((count_pull < skb->len) && (len > 0)) {
				len--;
				if (dev->drv[di]->DLEflag & DLEmask) {
					last = DLE;
					dev->drv[di]->DLEflag &= ~DLEmask;
				} else {
					last = *p;
					if (last == DLE) {
						dev->drv[di]->DLEflag |= DLEmask;
						(ISDN_AUDIO_SKB_DLECOUNT(skb))--;
					}
					p++;
					count_pull++;
				}
				count_put++;
			}
			if (count_pull >= skb->len)
				dflag = 1;
		} else {
#endif
			/* No DLE's in buff, so simply copy it */
			dflag = 1;
			if ((count_pull = skb->len) > len) {
				count_pull = len;
				dflag = 0;
			}
			count_put = count_pull;
			if(count_put > 1)
				tty_insert_flip_string(tty, skb->data, count_put - 1);
			last = skb->data[count_put] - 1;
			len -= count_put;
#ifdef CONFIG_ISDN_AUDIO
		}
#endif
		count += count_put;
		if (dflag) {
			/* We got all the data in this buff.
			 * Now we can dequeue it.
			 */
			if(cisco_hack)
				tty_insert_flip_char(tty, last, 0xFF);
			else
				tty_insert_flip_char(tty, last, TTY_NORMAL);
#ifdef CONFIG_ISDN_AUDIO
			ISDN_AUDIO_SKB_LOCK(skb) = 0;
#endif
			skb = skb_dequeue(&dev->drv[di]->rpqueue[channel]);
			dev_kfree_skb(skb);
		} else {
			tty_insert_flip_char(tty, last, TTY_NORMAL);
			/* Not yet emptied this buff, so it
			 * must stay in the queue, for further calls
			 * but we pull off the data we got until now.
			 */
			skb_pull(skb, count_pull);
#ifdef CONFIG_ISDN_AUDIO
			ISDN_AUDIO_SKB_LOCK(skb) = 0;
#endif
		}
		dev->drv[di]->rcvcount[channel] -= count_put;
	}
	return count;
}


static __inline int
isdn_minor2drv(int minor)
{
	return (dev->drvmap[minor]);
}

static __inline int
isdn_minor2chan(int minor)
{
	return (dev->chanmap[minor]);
}

static char *
isdn_statstr(void)
{
	static char istatbuf[2048];
	char *p;
	int i;

	sprintf(istatbuf, "idmap:\t");
	p = istatbuf + strlen(istatbuf);
	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
		sprintf(p, "%s ", (dev->drvmap[i] < 0) ? "-" : dev->drvid[dev->drvmap[i]]);
		p = istatbuf + strlen(istatbuf);
	}
	sprintf(p, "\nchmap:\t");
	p = istatbuf + strlen(istatbuf);
	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
		sprintf(p, "%d ", dev->chanmap[i]);
		p = istatbuf + strlen(istatbuf);
	}
	sprintf(p, "\ndrmap:\t");
	p = istatbuf + strlen(istatbuf);
	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
		sprintf(p, "%d ", dev->drvmap[i]);
		p = istatbuf + strlen(istatbuf);
	}
	sprintf(p, "\nusage:\t");
	p = istatbuf + strlen(istatbuf);
	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
		sprintf(p, "%d ", dev->usage[i]);
		p = istatbuf + strlen(istatbuf);
	}
	sprintf(p, "\nflags:\t");
	p = istatbuf + strlen(istatbuf);
	for (i = 0; i < ISDN_MAX_DRIVERS; i++) {
		if (dev->drv[i]) {
			sprintf(p, "%ld ", dev->drv[i]->online);
			p = istatbuf + strlen(istatbuf);
		} else {
			sprintf(p, "? ");
			p = istatbuf + strlen(istatbuf);
		}
	}
	sprintf(p, "\nphone:\t");
	p = istatbuf + strlen(istatbuf);
	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
		sprintf(p, "%s ", dev->num[i]);
		p = istatbuf + strlen(istatbuf);
	}
	sprintf(p, "\n");
	return istatbuf;
}

/* Module interface-code */

void
isdn_info_update(void)
{
	infostruct *p = dev->infochain;

	while (p) {
		*(p->private) = 1;
		p = (infostruct *) p->next;
	}
	wake_up_interruptible(&(dev->info_waitq));
}

static ssize_t
isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off)
{
	uint minor = MINOR(file->f_dentry->d_inode->i_rdev);
	int len = 0;
	int drvidx;
	int chidx;
	int retval;
	char *p;

	lock_kernel();
	if (minor == ISDN_MINOR_STATUS) {
		if (!file->private_data) {
			if (file->f_flags & O_NONBLOCK) {
				retval = -EAGAIN;
				goto out;
			}
			interruptible_sleep_on(&(dev->info_waitq));
		}
		p = isdn_statstr();
		file->private_data = NULL;
		if ((len = strlen(p)) <= count) {
			if (copy_to_user(buf, p, len)) {
				retval = -EFAULT;
				goto out;
			}
			*off += len;
			retval = len;
			goto out;
		}
		retval = 0;
		goto out;
	}
	if (!dev->drivers) {
		retval = -ENODEV;
		goto out;
	}
	if (minor <= ISDN_MINOR_BMAX) {
		printk(KERN_WARNING "isdn_read minor %d obsolete!\n", minor);
		drvidx = isdn_minor2drv(minor);
		if (drvidx < 0) {
			retval = -ENODEV;
			goto out;
		}
		if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING)) {
			retval = -ENODEV;
			goto out;
		}
		chidx = isdn_minor2chan(minor);
		if (!(p = kmalloc(count, GFP_KERNEL))) {
			retval = -ENOMEM;
			goto out;
		}
		len = isdn_readbchan(drvidx, chidx, p, NULL, count,
				     &dev->drv[drvidx]->rcv_waitq[chidx]);
		*off += len;
		if (copy_to_user(buf,p,len)) 
			len = -EFAULT;
		kfree(p);
		retval = len;
		goto out;
	}
	if (minor <= ISDN_MINOR_CTRLMAX) {
		drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
		if (drvidx < 0) {
			retval = -ENODEV;
			goto out;
		}
		if (!dev->drv[drvidx]->stavail) {
			if (file->f_flags & O_NONBLOCK) {
				retval = -EAGAIN;
				goto out;
			}
			interruptible_sleep_on(&(dev->drv[drvidx]->st_waitq));
		}
		if (dev->drv[drvidx]->interface->readstat) {
			if (count > dev->drv[drvidx]->stavail)
				count = dev->drv[drvidx]->stavail;
			len = dev->drv[drvidx]->interface->
				readstat(buf, count, drvidx,
					 isdn_minor2chan(minor));
		} else {
			len = 0;
		}
		if (len)
			dev->drv[drvidx]->stavail -= len;
		else
			dev->drv[drvidx]->stavail = 0;
		*off += len;
		retval = len;
		goto out;
	}
#ifdef CONFIG_ISDN_PPP
	if (minor <= ISDN_MINOR_PPPMAX) {
		retval = isdn_ppp_read(minor - ISDN_MINOR_PPP, file, buf, count);
		goto out;
	}
#endif
	retval = -ENODEV;
 out:
	unlock_kernel();
	return retval;
}

static ssize_t
isdn_write(struct file *file, const char __user *buf, size_t count, loff_t * off)
{
	uint minor = MINOR(file->f_dentry->d_inode->i_rdev);
	int drvidx;
	int chidx;
	int retval;

	if (minor == ISDN_MINOR_STATUS)
		return -EPERM;
	if (!dev->drivers)
		return -ENODEV;

	lock_kernel();
	if (minor <= ISDN_MINOR_BMAX) {
		printk(KERN_WARNING "isdn_write minor %d obsolete!\n", minor);
		drvidx = isdn_minor2drv(minor);
		if (drvidx < 0) {
			retval = -ENODEV;
			goto out;
		}
		if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING)) {
			retval = -ENODEV;
			goto out;
		}
		chidx = isdn_minor2chan(minor);
		while (isdn_writebuf_stub(drvidx, chidx, buf, count) != count)
			interruptible_sleep_on(&dev->drv[drvidx]->snd_waitq[chidx]);
		retval = count;
		goto out;
	}
	if (minor <= ISDN_MINOR_CTRLMAX) {
		drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
		if (drvidx < 0) {
			retval = -ENODEV;
			goto out;
		}
		/*
		 * We want to use the isdnctrl device to load the firmware
		 *
		 if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING))
		 return -ENODEV;
		 */
		if (dev->drv[drvidx]->interface->writecmd)
			retval = dev->drv[drvidx]->interface->
				writecmd(buf, count, drvidx, isdn_minor2chan(minor));
		else
			retval = count;
		goto out;
	}
#ifdef CONFIG_ISDN_PPP
	if (minor <= ISDN_MINOR_PPPMAX) {
		retval = isdn_ppp_write(minor - ISDN_MINOR_PPP, file, buf, count);
		goto out;
	}
#endif
	retval = -ENODEV;
 out:
	unlock_kernel();
	return retval;
}

static unsigned int
isdn_poll(struct file *file, poll_table * wait)
{
	unsigned int mask = 0;
	unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
	int drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);

	lock_kernel();
	if (minor == ISDN_MINOR_STATUS) {
		poll_wait(file, &(dev->info_waitq), wait);
		/* mask = POLLOUT | POLLWRNORM; */
		if (file->private_data) {
			mask |= POLLIN | POLLRDNORM;
		}
		goto out;
	}
	if (minor >= ISDN_MINOR_CTRL && minor <= ISDN_MINOR_CTRLMAX) {
		if (drvidx < 0) {
			/* driver deregistered while file open */
			mask = POLLHUP;
			goto out;
		}
		poll_wait(file, &(dev->drv[drvidx]->st_waitq), wait);
		mask = POLLOUT | POLLWRNORM;
		if (dev->drv[drvidx]->stavail) {
			mask |= POLLIN | POLLRDNORM;
		}
		goto out;
	}
#ifdef CONFIG_ISDN_PPP
	if (minor <= ISDN_MINOR_PPPMAX) {
		mask = isdn_ppp_poll(file, wait);
		goto out;
	}
#endif
	mask = POLLERR;
 out:
	unlock_kernel();
	return mask;
}


static int
isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
{
	uint minor = MINOR(inode->i_rdev);
	isdn_ctrl c;
	int drvidx;
	int chidx;
	int ret;
	int i;
	char __user *p;
	char *s;
	union iocpar {
		char name[10];
		char bname[22];
		isdn_ioctl_struct iocts;
		isdn_net_ioctl_phone phone;
		isdn_net_ioctl_cfg cfg;
	} iocpar;
	void __user *argp = (void __user *)arg;

#define name  iocpar.name
#define bname iocpar.bname
#define iocts iocpar.iocts
#define phone iocpar.phone
#define cfg   iocpar.cfg

	if (minor == ISDN_MINOR_STATUS) {
		switch (cmd) {
			case IIOCGETDVR:
				return (TTY_DV +
					(NET_DV << 8) +
					(INF_DV << 16));
			case IIOCGETCPS:
				if (arg) {
					ulong __user *p = argp;
					int i;
					if (!access_ok(VERIFY_WRITE, p,
							sizeof(ulong) * ISDN_MAX_CHANNELS * 2))
						return -EFAULT;
					for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
						put_user(dev->ibytes[i], p++);
						put_user(dev->obytes[i], p++);
					}
					return 0;
				} else
					return -EINVAL;
				break;
#ifdef CONFIG_NETDEVICES
			case IIOCNETGPN:
				/* Get peer phone number of a connected 
				 * isdn network interface */
				if (arg) {
					if (copy_from_user(&phone, argp, sizeof(phone)))
						return -EFAULT;
					return isdn_net_getpeer(&phone, argp);
				} else
					return -EINVAL;
#endif
			default:
				return -EINVAL;
		}
	}
	if (!dev->drivers)
		return -ENODEV;
	if (minor <= ISDN_MINOR_BMAX) {
		drvidx = isdn_minor2drv(minor);
		if (drvidx < 0)
			return -ENODEV;
		chidx = isdn_minor2chan(minor);
		if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING))
			return -ENODEV;
		return 0;
	}
	if (minor <= ISDN_MINOR_CTRLMAX) {
/*
 * isdn net devices manage lots of configuration variables as linked lists.
 * Those lists must only be manipulated from user space. Some of the ioctl's
 * service routines access user space and are not atomic. Therefor, ioctl's
 * manipulating the lists and ioctl's sleeping while accessing the lists
 * are serialized by means of a semaphore.
 */
		switch (cmd) {
			case IIOCNETDWRSET:
				printk(KERN_INFO "INFO: ISDN_DW_ABC_EXTENSION not enabled\n");
				return(-EINVAL);
			case IIOCNETLCR:
				printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n");
				return -ENODEV;
#ifdef CONFIG_NETDEVICES
			case IIOCNETAIF:
				/* Add a network-interface */
				if (arg) {
					if (copy_from_user(name, argp, sizeof(name)))
						return -EFAULT;
					s = name;
				} else {
					s = NULL;
				}
				ret = down_interruptible(&dev->sem);
				if( ret ) return ret;
				if ((s = isdn_net_new(s, NULL))) {
					if (copy_to_user(argp, s, strlen(s) + 1)){
						ret = -EFAULT;
					} else {
						ret = 0;
					}
				} else
					ret = -ENODEV;
				up(&dev->sem);
				return ret;
			case IIOCNETASL:
				/* Add a slave to a network-interface */
				if (arg) {
					if (copy_from_user(bname, argp, sizeof(bname) - 1))
						return -EFAULT;
				} else
					return -EINVAL;
				ret = down_interruptible(&dev->sem);
				if( ret ) return ret;
				if ((s = isdn_net_newslave(bname))) {
					if (copy_to_user(argp, s, strlen(s) + 1)){
						ret = -EFAULT;
					} else {
						ret = 0;
					}
				} else
					ret = -ENODEV;
				up(&dev->sem);
				return ret;
			case IIOCNETDIF:
				/* Delete a network-interface */
				if (arg) {
					if (copy_from_user(name, argp, sizeof(name)))
						return -EFAULT;
					ret = down_interruptible(&dev->sem);
					if( ret ) return ret;
					ret = isdn_net_rm(name);
					up(&dev->sem);
					return ret;
				} else
					return -EINVAL;
			case IIOCNETSCF:
				/* Set configurable parameters of a network-interface */
				if (arg) {
					if (copy_from_user(&cfg, argp, sizeof(cfg)))
						return -EFAULT;
					return isdn_net_setcfg(&cfg);
				} else
					return -EINVAL;
			case IIOCNETGCF:
				/* Get configurable parameters of a network-interface */
				if (arg) {
					if (copy_from_user(&cfg, argp, sizeof(cfg)))
						return -EFAULT;
					if (!(ret = isdn_net_getcfg(&cfg))) {
						if (copy_to_user(argp, &cfg, sizeof(cfg)))
							return -EFAULT;
					}
					return ret;
				} else
					return -EINVAL;
			case IIOCNETANM:
				/* Add a phone-number to a network-interface */
				if (arg) {
					if (copy_from_user(&phone, argp, sizeof(phone)))
						return -EFAULT;
					ret = down_interruptible(&dev->sem);
					if( ret ) return ret;
					ret = isdn_net_addphone(&phone);
					up(&dev->sem);
					return ret;
				} else
					return -EINVAL;
			case IIOCNETGNM:
				/* Get list of phone-numbers of a network-interface */
				if (arg) {
					if (copy_from_user(&phone, argp, sizeof(phone)))
						return -EFAULT;
					ret = down_interruptible(&dev->sem);
					if( ret ) return ret;
					ret = isdn_net_getphones(&phone, argp);
					up(&dev->sem);
					return ret;
				} else
					return -EINVAL;
			case IIOCNETDNM:
				/* Delete a phone-number of a network-interface */
				if (arg) {
					if (copy_from_user(&phone, argp, sizeof(phone)))
						return -EFAULT;
					ret = down_interruptible(&dev->sem);
					if( ret ) return ret;
					ret = isdn_net_delphone(&phone);
					up(&dev->sem);
					return ret;
				} else
					return -EINVAL;
			case IIOCNETDIL:
				/* Force dialing of a network-interface */
				if (arg) {
					if (copy_from_user(name, argp, sizeof(name)))
						return -EFAULT;
					return isdn_net_force_dial(name);
				} else
					return -EINVAL;
#ifdef CONFIG_ISDN_PPP
			case IIOCNETALN:
				if (!arg)
					return -EINVAL;
				if (copy_from_user(name, argp, sizeof(name)))
					return -EFAULT;
				return isdn_ppp_dial_slave(name);
			case IIOCNETDLN:
				if (!arg)
					return -EINVAL;
				if (copy_from_user(name, argp, sizeof(name)))
					return -EFAULT;
				return isdn_ppp_hangup_slave(name);
#endif
			case IIOCNETHUP:
				/* Force hangup of a network-interface */
				if (!arg)
					return -EINVAL;
				if (copy_from_user(name, argp, sizeof(name)))
					return -EFAULT;
				return isdn_net_force_hangup(name);
				break;
#endif                          /* CONFIG_NETDEVICES */
			case IIOCSETVER:
				dev->net_verbose = arg;
				printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose);
				return 0;
			case IIOCSETGST:
				if (arg)
					dev->global_flags |= ISDN_GLOBAL_STOPPED;
				else
					dev->global_flags &= ~ISDN_GLOBAL_STOPPED;
				printk(KERN_INFO "isdn: Global Mode %s\n",
				       (dev->global_flags & ISDN_GLOBAL_STOPPED) ? "stopped" : "running");
				return 0;
			case IIOCSETBRJ:
				drvidx = -1;
				if (arg) {
					int i;
					char *p;
					if (copy_from_user(&iocts, argp,
					     sizeof(isdn_ioctl_struct)))
						return -EFAULT;
					if (strlen(iocts.drvid)) {
						if ((p = strchr(iocts.drvid, ',')))
							*p = 0;
						drvidx = -1;
						for (i = 0; i < ISDN_MAX_DRIVERS; i++)
							if (!(strcmp(dev->drvid[i], iocts.drvid))) {
								drvidx = i;
								break;
							}
					}
				}
				if (drvidx == -1)
					return -ENODEV;
				if (iocts.arg)
					dev->drv[drvidx]->flags |= DRV_FLAG_REJBUS;
				else
					dev->drv[drvidx]->flags &= ~DRV_FLAG_REJBUS;
				return 0;
			case IIOCSIGPRF:
				dev->profd = current;
				return 0;
				break;
			case IIOCGETPRF:
				/* Get all Modem-Profiles */
				if (arg) {
					char __user *p = argp;
					int i;

					if (!access_ok(VERIFY_WRITE, argp,
					(ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN)
						   * ISDN_MAX_CHANNELS))
						return -EFAULT;

					for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
						if (copy_to_user(p, dev->mdm.info[i].emu.profile,
						      ISDN_MODEM_NUMREG))
							return -EFAULT;
						p += ISDN_MODEM_NUMREG;
						if (copy_to_user(p, dev->mdm.info[i].emu.pmsn, ISDN_MSNLEN))
							return -EFAULT;
						p += ISDN_MSNLEN;
						if (copy_to_user(p, dev->mdm.info[i].emu.plmsn, ISDN_LMSNLEN))
							return -EFAULT;
						p += ISDN_LMSNLEN;
					}
					return (ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN) * ISDN_MAX_CHANNELS;
				} else
					return -EINVAL;
				break;
			case IIOCSETPRF:
				/* Set all Modem-Profiles */
				if (arg) {
					char __user *p = argp;
					int i;

					if (!access_ok(VERIFY_READ, argp,
					(ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN)
						   * ISDN_MAX_CHANNELS))
						return -EFAULT;

					for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
						if (copy_from_user(dev->mdm.info[i].emu.profile, p,
						     ISDN_MODEM_NUMREG))
							return -EFAULT;
						p += ISDN_MODEM_NUMREG;
						if (copy_from_user(dev->mdm.info[i].emu.plmsn, p, ISDN_LMSNLEN))
							return -EFAULT;
						p += ISDN_LMSNLEN;
						if (copy_from_user(dev->mdm.info[i].emu.pmsn, p, ISDN_MSNLEN))
							return -EFAULT;
						p += ISDN_MSNLEN;
					}
					return 0;
				} else
					return -EINVAL;
				break;
			case IIOCSETMAP:
			case IIOCGETMAP:
				/* Set/Get MSN->EAZ-Mapping for a driver */
				if (arg) {

					if (copy_from_user(&iocts, argp,
					     sizeof(isdn_ioctl_struct)))
						return -EFAULT;
					if (strlen(iocts.drvid)) {
						drvidx = -1;
						for (i = 0; i < ISDN_MAX_DRIVERS; i++)
							if (!(strcmp(dev->drvid[i], iocts.drvid))) {
								drvidx = i;
								break;
							}
					} else
						drvidx = 0;
					if (drvidx == -1)
						return -ENODEV;
					if (cmd == IIOCSETMAP) {
						int loop = 1;

						p = (char __user *) iocts.arg;
						i = 0;
						while (loop) {
							int j = 0;

							while (1) {
								if (!access_ok(VERIFY_READ, p, 1))
									return -EFAULT;
								get_user(bname[j], p++);
								switch (bname[j]) {
									case '\0':
										loop = 0;
										/* Fall through */
									case ',':
										bname[j] = '\0';
										strcpy(dev->drv[drvidx]->msn2eaz[i], bname);
										j = ISDN_MSNLEN;
										break;
									default:
										j++;
								}
								if (j >= ISDN_MSNLEN)
									break;
							}
							if (++i > 9)
								break;
						}
					} else {
						p = (char __user *) iocts.arg;
						for (i = 0; i < 10; i++) {
							sprintf(bname, "%s%s",
								strlen(dev->drv[drvidx]->msn2eaz[i]) ?
								dev->drv[drvidx]->msn2eaz[i] : "_",
								(i < 9) ? "," : "\0");
							if (copy_to_user(p, bname, strlen(bname) + 1))
								return -EFAULT;
							p += strlen(bname);
						}
					}
					return 0;
				} else
					return -EINVAL;
			case IIOCDBGVAR:
				if (arg) {
					if (copy_to_user(argp, &dev, sizeof(ulong)))
						return -EFAULT;
					return 0;
				} else
					return -EINVAL;
				break;
			default:
				if ((cmd & IIOCDRVCTL) == IIOCDRVCTL)
					cmd = ((cmd >> _IOC_NRSHIFT) & _IOC_NRMASK) & ISDN_DRVIOCTL_MASK;
				else
					return -EINVAL;
				if (arg) {
					int i;
					char *p;
					if (copy_from_user(&iocts, argp, sizeof(isdn_ioctl_struct)))
						return -EFAULT;
					if (strlen(iocts.drvid)) {
						if ((p = strchr(iocts.drvid, ',')))
							*p = 0;
						drvidx = -1;
						for (i = 0; i < ISDN_MAX_DRIVERS; i++)
							if (!(strcmp(dev->drvid[i], iocts.drvid))) {
								drvidx = i;
								break;
							}
					} else
						drvidx = 0;
					if (drvidx == -1)
						return -ENODEV;
					if (!access_ok(VERIFY_WRITE, argp,
					     sizeof(isdn_ioctl_struct)))
						return -EFAULT;
					c.driver = drvidx;
					c.command = ISDN_CMD_IOCTL;
					c.arg = cmd;
					memcpy(c.parm.num, &iocts.arg, sizeof(ulong));
					ret = isdn_command(&c);
					memcpy(&iocts.arg, c.parm.num, sizeof(ulong));
					if (copy_to_user(argp, &iocts, sizeof(isdn_ioctl_struct)))
						return -EFAULT;
					return ret;
				} else
					return -EINVAL;
		}
	}
#ifdef CONFIG_ISDN_PPP
	if (minor <= ISDN_MINOR_PPPMAX)
		return (isdn_ppp_ioctl(minor - ISDN_MINOR_PPP, file, cmd, arg));
#endif
	return -ENODEV;

#undef name
#undef bname
#undef iocts
#undef phone
#undef cfg
}

/*
 * Open the device code.
 */
static int
isdn_open(struct inode *ino, struct file *filep)
{
	uint minor = MINOR(ino->i_rdev);
	int drvidx;
	int chidx;
	int retval = -ENODEV;


	if (minor == ISDN_MINOR_STATUS) {
		infostruct *p;

		if ((p = kmalloc(sizeof(infostruct), GFP_KERNEL))) {
			p->next = (char *) dev->infochain;
			p->private = (char *) &(filep->private_data);
			dev->infochain = p;
			/* At opening we allow a single update */
			filep->private_data = (char *) 1;
			retval = 0;
			goto out;
		} else {
			retval = -ENOMEM;
			goto out;
		}
	}
	if (!dev->channels)
		goto out;
	if (minor <= ISDN_MINOR_BMAX) {
		printk(KERN_WARNING "isdn_open minor %d obsolete!\n", minor);
		drvidx = isdn_minor2drv(minor);
		if (drvidx < 0)
			goto out;
		chidx = isdn_minor2chan(minor);
		if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING))
			goto out;
		if (!(dev->drv[drvidx]->online & (1 << chidx)))
			goto out;
		isdn_lock_drivers();
		retval = 0;
		goto out;
	}
	if (minor <= ISDN_MINOR_CTRLMAX) {
		drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
		if (drvidx < 0)
			goto out;
		isdn_lock_drivers();
		retval = 0;
		goto out;
	}
#ifdef CONFIG_ISDN_PPP
	if (minor <= ISDN_MINOR_PPPMAX) {
		retval = isdn_ppp_open(minor - ISDN_MINOR_PPP, filep);
		if (retval == 0)
			isdn_lock_drivers();
		goto out;
	}
#endif
 out:
	nonseekable_open(ino, filep);
	return retval;
}

static int
isdn_close(struct inode *ino, struct file *filep)
{
	uint minor = MINOR(ino->i_rdev);

	lock_kernel();
	if (minor == ISDN_MINOR_STATUS) {
		infostruct *p = dev->infochain;
		infostruct *q = NULL;

		while (p) {
			if (p->private == (char *) &(filep->private_data)) {
				if (q)
					q->next = p->next;
				else
					dev->infochain = (infostruct *) (p->next);
				kfree(p);
				goto out;
			}
			q = p;
			p = (infostruct *) (p->next);
		}
		printk(KERN_WARNING "isdn: No private data while closing isdnctrl\n");
		goto out;
	}
	isdn_unlock_drivers();
	if (minor <= ISDN_MINOR_BMAX)
		goto out;
	if (minor <= ISDN_MINOR_CTRLMAX) {
		if (dev->profd == current)
			dev->profd = NULL;
		goto out;
	}
#ifdef CONFIG_ISDN_PPP
	if (minor <= ISDN_MINOR_PPPMAX)
		isdn_ppp_release(minor - ISDN_MINOR_PPP, filep);
#endif

 out:
	unlock_kernel();
	return 0;
}

static struct file_operations isdn_fops =
{
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.read		= isdn_read,
	.write		= isdn_write,
	.poll		= isdn_poll,
	.ioctl		= isdn_ioctl,
	.open		= isdn_open,
	.release	= isdn_close,
};

char *
isdn_map_eaz2msn(char *msn, int di)
{
	isdn_driver_t *this = dev->drv[di];
	int i;

	if (strlen(msn) == 1) {
		i = msn[0] - '0';
		if ((i >= 0) && (i <= 9))
			if (strlen(this->msn2eaz[i]))
				return (this->msn2eaz[i]);
	}
	return (msn);
}

/*
 * Find an unused ISDN-channel, whose feature-flags match the
 * given L2- and L3-protocols.
 */
#define L2V (~(ISDN_FEATURE_L2_V11096|ISDN_FEATURE_L2_V11019|ISDN_FEATURE_L2_V11038))

/*
 * This function must be called with holding the dev->lock.
 */
int
isdn_get_free_channel(int usage, int l2_proto, int l3_proto, int pre_dev
		      ,int pre_chan, char *msn)
{
	int i;
	ulong features;
	ulong vfeatures;

	features = ((1 << l2_proto) | (0x10000 << l3_proto));
	vfeatures = (((1 << l2_proto) | (0x10000 << l3_proto)) &
		     ~(ISDN_FEATURE_L2_V11096|ISDN_FEATURE_L2_V11019|ISDN_FEATURE_L2_V11038));
	/* If Layer-2 protocol is V.110, accept drivers with
	 * transparent feature even if these don't support V.110
	 * because we can emulate this in linklevel.
	 */
	for (i = 0; i < ISDN_MAX_CHANNELS; i++)
		if (USG_NONE(dev->usage[i]) &&
		    (dev->drvmap[i] != -1)) {
			int d = dev->drvmap[i];
			if ((dev->usage[i] & ISDN_USAGE_EXCLUSIVE) &&
			((pre_dev != d) || (pre_chan != dev->chanmap[i])))
				continue;
			if (!strcmp(isdn_map_eaz2msn(msn, d), "-"))
				continue;
			if (dev->usage[i] & ISDN_USAGE_DISABLED)
			        continue; /* usage not allowed */
			if (dev->drv[d]->flags & DRV_FLAG_RUNNING) {
				if (((dev->drv[d]->interface->features & features) == features) ||
				    (((dev->drv[d]->interface->features & vfeatures) == vfeatures) &&
				     (dev->drv[d]->interface->features & ISDN_FEATURE_L2_TRANS))) {
					if ((pre_dev < 0) || (pre_chan < 0)) {
						dev->usage[i] &= ISDN_USAGE_EXCLUSIVE;
						dev->usage[i] |= usage;
						isdn_info_update();
						return i;
					} else {
						if ((pre_dev == d) && (pre_chan == dev->chanmap[i])) {
							dev->usage[i] &= ISDN_USAGE_EXCLUSIVE;
							dev->usage[i] |= usage;
							isdn_info_update();
							return i;
						}
					}
				}
			}
		}
	return -1;
}

/*
 * Set state of ISDN-channel to 'unused'
 */
void
isdn_free_channel(int di, int ch, int usage)
{
	int i;

	for (i = 0; i < ISDN_MAX_CHANNELS; i++)
		if (((!usage) || ((dev->usage[i] & ISDN_USAGE_MASK) == usage)) &&
		    (dev->drvmap[i] == di) &&
		    (dev->chanmap[i] == ch)) {
			dev->usage[i] &= (ISDN_USAGE_NONE | ISDN_USAGE_EXCLUSIVE);
			strcpy(dev->num[i], "???");
			dev->ibytes[i] = 0;
			dev->obytes[i] = 0;
// 20.10.99 JIM, try to reinitialize v110 !
			dev->v110emu[i] = 0;
			atomic_set(&(dev->v110use[i]), 0);
			isdn_v110_close(dev->v110[i]);
			dev->v110[i] = NULL;
// 20.10.99 JIM, try to reinitialize v110 !
			isdn_info_update();
			skb_queue_purge(&dev->drv[di]->rpqueue[ch]);
		}
}

/*
 * Cancel Exclusive-Flag for ISDN-channel
 */
void
isdn_unexclusive_channel(int di, int ch)
{
	int i;

	for (i = 0; i < ISDN_MAX_CHANNELS; i++)
		if ((dev->drvmap[i] == di) &&
		    (dev->chanmap[i] == ch)) {
			dev->usage[i] &= ~ISDN_USAGE_EXCLUSIVE;
			isdn_info_update();
			return;
		}
}

/*
 *  writebuf replacement for SKB_ABLE drivers
 */
static int
isdn_writebuf_stub(int drvidx, int chan, const u_char __user * buf, int len)
{
	int ret;
	int hl = dev->drv[drvidx]->interface->hl_hdrlen;
	struct sk_buff *skb = alloc_skb(hl + len, GFP_ATOMIC);

	if (!skb)
		return 0;
	skb_reserve(skb, hl);
	copy_from_user(skb_put(skb, len), buf, len);
	ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, 1, skb);
	if (ret <= 0)
		dev_kfree_skb(skb);
	if (ret > 0)
		dev->obytes[isdn_dc2minor(drvidx, chan)] += ret;
	return ret;
}

/*
 * Return: length of data on success, -ERRcode on failure.
 */
int
isdn_writebuf_skb_stub(int drvidx, int chan, int ack, struct sk_buff *skb)
{
	int ret;
	struct sk_buff *nskb = NULL;
	int v110_ret = skb->len;
	int idx = isdn_dc2minor(drvidx, chan);

	if (dev->v110[idx]) {
		atomic_inc(&dev->v110use[idx]);
		nskb = isdn_v110_encode(dev->v110[idx], skb);
		atomic_dec(&dev->v110use[idx]);
		if (!nskb)
			return 0;
		v110_ret = *((int *)nskb->data);
		skb_pull(nskb, sizeof(int));
		if (!nskb->len) {
			dev_kfree_skb(nskb);
			return v110_ret;
		}
		/* V.110 must always be acknowledged */
		ack = 1;
		ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, nskb);
	} else {
		int hl = dev->drv[drvidx]->interface->hl_hdrlen;

		if( skb_headroom(skb) < hl ){
			/* 
			 * This should only occur when new HL driver with
			 * increased hl_hdrlen was loaded after netdevice
			 * was created and connected to the new driver.
			 *
			 * The V.110 branch (re-allocates on its own) does
			 * not need this
			 */
			struct sk_buff * skb_tmp;

			skb_tmp = skb_realloc_headroom(skb, hl);
			printk(KERN_DEBUG "isdn_writebuf_skb_stub: reallocating headroom%s\n", skb_tmp ? "" : " failed");
			if (!skb_tmp) return -ENOMEM; /* 0 better? */
			ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, skb_tmp);
			if( ret > 0 ){
				dev_kfree_skb(skb);
			} else {
				dev_kfree_skb(skb_tmp);
			}
		} else {
			ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, skb);
		}
	}
	if (ret > 0) {
		dev->obytes[idx] += ret;
		if (dev->v110[idx]) {
			atomic_inc(&dev->v110use[idx]);
			dev->v110[idx]->skbuser++;
			atomic_dec(&dev->v110use[idx]);
			/* For V.110 return unencoded data length */
			ret = v110_ret;
			/* if the complete frame was send we free the skb;
			   if not upper function will requeue the skb */ 
			if (ret == skb->len)
				dev_kfree_skb(skb);
		}
	} else
		if (dev->v110[idx])
			dev_kfree_skb(nskb);
	return ret;
}

static int
isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding)
{
	int j, k, m;

	init_waitqueue_head(&d->st_waitq);
	if (d->flags & DRV_FLAG_RUNNING)
		return -1;
       	if (n < 1) return 0;

	m = (adding) ? d->channels + n : n;

	if (dev->channels + n > ISDN_MAX_CHANNELS) {
		printk(KERN_WARNING "register_isdn: Max. %d channels supported\n",
		       ISDN_MAX_CHANNELS);
		return -1;
	}

	if ((adding) && (d->rcverr))
		kfree(d->rcverr);
	if (!(d->rcverr = kmalloc(sizeof(int) * m, GFP_ATOMIC))) {
		printk(KERN_WARNING "register_isdn: Could not alloc rcverr\n");
		return -1;
	}
	memset((char *) d->rcverr, 0, sizeof(int) * m);

	if ((adding) && (d->rcvcount))
		kfree(d->rcvcount);
	if (!(d->rcvcount = kmalloc(sizeof(int) * m, GFP_ATOMIC))) {
		printk(KERN_WARNING "register_isdn: Could not alloc rcvcount\n");
		if (!adding)
			kfree(d->rcverr);
		return -1;
	}
	memset((char *) d->rcvcount, 0, sizeof(int) * m);

	if ((adding) && (d->rpqueue)) {
		for (j = 0; j < d->channels; j++)
			skb_queue_purge(&d->rpqueue[j]);
		kfree(d->rpqueue);
	}
	if (!(d->rpqueue = kmalloc(sizeof(struct sk_buff_head) * m, GFP_ATOMIC))) {
		printk(KERN_WARNING "register_isdn: Could not alloc rpqueue\n");
		if (!adding) {
			kfree(d->rcvcount);
			kfree(d->rcverr);
		}
		return -1; 
	}
	for (j = 0; j < m; j++) {
		skb_queue_head_init(&d->rpqueue[j]);
	}

	if ((adding) && (d->rcv_waitq))
		kfree(d->rcv_waitq);
	d->rcv_waitq = kmalloc(sizeof(wait_queue_head_t) * 2 * m, GFP_ATOMIC);
	if (!d->rcv_waitq) {
		printk(KERN_WARNING "register_isdn: Could not alloc rcv_waitq\n");
		if (!adding) {
			kfree(d->rpqueue);
			kfree(d->rcvcount);
			kfree(d->rcverr);
		}
		return -1;
	}
	d->snd_waitq = d->rcv_waitq + m;
	for (j = 0; j < m; j++) {
		init_waitqueue_head(&d->rcv_waitq[j]);
		init_waitqueue_head(&d->snd_waitq[j]);
	}

	dev->channels += n;
	for (j = d->channels; j < m; j++)
		for (k = 0; k < ISDN_MAX_CHANNELS; k++)
			if (dev->chanmap[k] < 0) {
				dev->chanmap[k] = j;
				dev->drvmap[k] = drvidx;
				break;
			}
	d->channels = m;
	return 0;
}

/*
 * Low-level-driver registration
 */

static void
set_global_features(void)
{
	int drvidx;

	dev->global_features = 0;
	for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) {
		if (!dev->drv[drvidx])
			continue;
		if (dev->drv[drvidx]->interface)
			dev->global_features |= dev->drv[drvidx]->interface->features;
	}
}

#ifdef CONFIG_ISDN_DIVERSION

static char *map_drvname(int di)
{
  if ((di < 0) || (di >= ISDN_MAX_DRIVERS)) 
    return(NULL);
  return(dev->drvid[di]); /* driver name */
} /* map_drvname */

static int map_namedrv(char *id)
{  int i;

   for (i = 0; i < ISDN_MAX_DRIVERS; i++)
    { if (!strcmp(dev->drvid[i],id)) 
        return(i);
    }
   return(-1);
} /* map_namedrv */

int DIVERT_REG_NAME(isdn_divert_if *i_div)
{
  if (i_div->if_magic != DIVERT_IF_MAGIC) 
    return(DIVERT_VER_ERR);
  switch (i_div->cmd)
    {
      case DIVERT_CMD_REL:
        if (divert_if != i_div) 
          return(DIVERT_REL_ERR);
        divert_if = NULL; /* free interface */
        return(DIVERT_NO_ERR);

      case DIVERT_CMD_REG:
        if (divert_if) 
          return(DIVERT_REG_ERR);
        i_div->ll_cmd = isdn_command; /* set command function */
        i_div->drv_to_name = map_drvname; 
        i_div->name_to_drv = map_namedrv; 
        divert_if = i_div; /* remember interface */
        return(DIVERT_NO_ERR);

      default:
        return(DIVERT_CMD_ERR);   
    }
} /* DIVERT_REG_NAME */

EXPORT_SYMBOL(DIVERT_REG_NAME);

#endif /* CONFIG_ISDN_DIVERSION */


EXPORT_SYMBOL(register_isdn);
#ifdef CONFIG_ISDN_PPP
EXPORT_SYMBOL(isdn_ppp_register_compressor);
EXPORT_SYMBOL(isdn_ppp_unregister_compressor);
#endif

int
register_isdn(isdn_if * i)
{
	isdn_driver_t *d;
	int j;
	ulong flags;
	int drvidx;

	if (dev->drivers >= ISDN_MAX_DRIVERS) {
		printk(KERN_WARNING "register_isdn: Max. %d drivers supported\n",
		       ISDN_MAX_DRIVERS);
		return 0;
	}
	if (!i->writebuf_skb) {
		printk(KERN_WARNING "register_isdn: No write routine given.\n");
		return 0;
	}
	if (!(d = kmalloc(sizeof(isdn_driver_t), GFP_KERNEL))) {
		printk(KERN_WARNING "register_isdn: Could not alloc driver-struct\n");
		return 0;
	}
	memset((char *) d, 0, sizeof(isdn_driver_t));

	d->maxbufsize = i->maxbufsize;
	d->pktcount = 0;
	d->stavail = 0;
	d->flags = DRV_FLAG_LOADED;
	d->online = 0;
	d->interface = i;
	d->channels = 0;
	spin_lock_irqsave(&dev->lock, flags);
	for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++)
		if (!dev->drv[drvidx])
			break;
	if (isdn_add_channels(d, drvidx, i->channels, 0)) {
		spin_unlock_irqrestore(&dev->lock, flags);
		kfree(d);
		return 0;
	}
	i->channels = drvidx;
	i->rcvcallb_skb = isdn_receive_skb_callback;
	i->statcallb = isdn_status_callback;
	if (!strlen(i->id))
		sprintf(i->id, "line%d", drvidx);
	for (j = 0; j < drvidx; j++)
		if (!strcmp(i->id, dev->drvid[j]))
			sprintf(i->id, "line%d", drvidx);
	dev->drv[drvidx] = d;
	strcpy(dev->drvid[drvidx], i->id);
	isdn_info_update();
	dev->drivers++;
	set_global_features();
	spin_unlock_irqrestore(&dev->lock, flags);
	return 1;
}

/*
 *****************************************************************************
 * And now the modules code.
 *****************************************************************************
 */

static char *
isdn_getrev(const char *revision)
{
	char *rev;
	char *p;

	if ((p = strchr(revision, ':'))) {
		rev = p + 2;
		p = strchr(rev, '$');
		*--p = 0;
	} else
		rev = "???";
	return rev;
}

/*
 * Allocate and initialize all data, register modem-devices
 */
static int __init isdn_init(void)
{
	int i;
	char tmprev[50];

	if (!(dev = (isdn_dev *) vmalloc(sizeof(isdn_dev)))) {
		printk(KERN_WARNING "isdn: Could not allocate device-struct.\n");
		return -EIO;
	}
	memset((char *) dev, 0, sizeof(isdn_dev));
	init_timer(&dev->timer);
	dev->timer.function = isdn_timer_funct;
	spin_lock_init(&dev->lock);
	spin_lock_init(&dev->timerlock);
#ifdef MODULE
	dev->owner = THIS_MODULE;
#endif
	init_MUTEX(&dev->sem);
	init_waitqueue_head(&dev->info_waitq);
	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
		dev->drvmap[i] = -1;
		dev->chanmap[i] = -1;
		dev->m_idx[i] = -1;
		strcpy(dev->num[i], "???");
		init_waitqueue_head(&dev->mdm.info[i].open_wait);
		init_waitqueue_head(&dev->mdm.info[i].close_wait);
	}
	if (register_chrdev(ISDN_MAJOR, "isdn", &isdn_fops)) {
		printk(KERN_WARNING "isdn: Could not register control devices\n");
		vfree(dev);
		return -EIO;
	}
	if ((isdn_tty_modem_init()) < 0) {
		printk(KERN_WARNING "isdn: Could not register tty devices\n");
		vfree(dev);
		unregister_chrdev(ISDN_MAJOR, "isdn");
		return -EIO;
	}
#ifdef CONFIG_ISDN_PPP
	if (isdn_ppp_init() < 0) {
		printk(KERN_WARNING "isdn: Could not create PPP-device-structs\n");
		isdn_tty_exit();
		unregister_chrdev(ISDN_MAJOR, "isdn");
		vfree(dev);
		return -EIO;
	}
#endif                          /* CONFIG_ISDN_PPP */

	strcpy(tmprev, isdn_revision);
	printk(KERN_NOTICE "ISDN subsystem Rev: %s/", isdn_getrev(tmprev));
	strcpy(tmprev, isdn_tty_revision);
	printk("%s/", isdn_getrev(tmprev));
	strcpy(tmprev, isdn_net_revision);
	printk("%s/", isdn_getrev(tmprev));
	strcpy(tmprev, isdn_ppp_revision);
	printk("%s/", isdn_getrev(tmprev));
	strcpy(tmprev, isdn_audio_revision);
	printk("%s/", isdn_getrev(tmprev));
	strcpy(tmprev, isdn_v110_revision);
	printk("%s", isdn_getrev(tmprev));

#ifdef MODULE
	printk(" loaded\n");
#else
	printk("\n");
#endif
	isdn_info_update();
	return 0;
}

/*
 * Unload module
 */
static void __exit isdn_exit(void)
{
#ifdef CONFIG_ISDN_PPP
	isdn_ppp_cleanup();
#endif
	if (isdn_net_rmall() < 0) {
		printk(KERN_WARNING "isdn: net-device busy, remove cancelled\n");
		return;
	}
	isdn_tty_exit();
	unregister_chrdev(ISDN_MAJOR, "isdn");
	del_timer(&dev->timer);
	/* call vfree with interrupts enabled, else it will hang */
	vfree(dev);
	printk(KERN_NOTICE "ISDN-subsystem unloaded\n");
}

module_init(isdn_init);
module_exit(isdn_exit);
