isdn4linux-web/workshop/linklevel/isdn_common.c.shtml

2446 lines
129 KiB
Plaintext

<HTML>
<!-- Generated by c2html-1.0, Copyright 1998 by Dave Whittington -->
<HEAD>
<TITLE>isdn_common.c</TITLE>
<!--#include virtual="/ssi/js.shtml" -->
<!--#include virtual="/ssi/buttondefs.shtml" -->
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<TABLE WIDTH="100%">
<TR>
<TD ALIGN=LEFT WIDTH="90"><!--#include virtual="/ssi/b_home.shtml" --></TD>
<TD ALIGN=RIGHT WIDTH="90"><!--#include virtual="/ssi/b_index.shtml" --></TD>
</TR>
</TABLE>
<CENTER><H1>isdn_common.c</H1></CENTER>
<HR>
<PRE>
<FONT COLOR=#0000FF>/* $Id$
* Linux ISDN subsystem, common used functions (linklevel).
*
* Copyright 1994,95,96 by Fritz Elfert (fritz@wuemaus.franken.de)
* Copyright 1995,96 Thinking Objects Software GmbH Wuerzburg
* Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log$
* Revision 1.67 1998/06/26 15:12:21 fritz
* Added handling of STAT_ICALL with incomplete CPN.
* Added AT&amp;L for ttyI emulator.
* Added more locking stuff in tty_write.
*
* Revision 1.66 1998/06/17 19:50:41 he
* merged with 2.1.10[34] (cosmetics and udelay() -&gt; mdelay())
* brute force fix to avoid Ugh's in isdn_tty_write()
* cleaned up some dead code
*
* Revision 1.65 1998/06/07 00:20:00 fritz
* abc cleanup.
*
* Revision 1.64 1998/06/02 12:10:03 detabc
* wegen einer einstweiliger verfuegung gegen DW ist zur zeit
* die abc-extension bis zur klaerung der rechtslage nicht verfuegbar
*
* Revision 1.63 1998/05/03 17:40:38 detabc
* Include abc-extension-support for &gt;= 2.1.x Kernels in
* isdn_net.c and isdn_common.c. alpha-test OK and running !
*
* Revision 1.62 1998/04/14 16:28:43 he
* Fixed user space access with interrupts off and remaining
* copy_{to,from}_user() -&gt; -EFAULT return codes
*
* Revision 1.61 1998/03/22 18:50:46 hipp
* Added BSD Compression for syncPPP .. UNTESTED at the moment
*
* Revision 1.60 1998/03/19 13:18:18 keil
* Start of a CAPI like interface for supplementary Service
* first service: SUSPEND
*
* Revision 1.59 1998/03/09 17:46:23 he
* merged in 2.1.89 changes
*
* Revision 1.58 1998/03/07 22:35:24 fritz
* Starting generic module support (Nothing usable yet).
*
* Revision 1.57 1998/03/07 18:21:01 cal
* Dynamic Timeout-Rule-Handling vs. 971110 included
*
* Revision 1.56 1998/02/25 17:49:38 he
* Changed return codes caused be failing copy_{to,from}_user to -EFAULT
*
* Revision 1.55 1998/02/23 23:35:32 fritz
* Eliminated some compiler warnings.
*
* Revision 1.54 1998/02/22 19:44:19 fritz
* Bugfixes and improvements regarding V.110, V.110 now running.
*
* Revision 1.53 1998/02/20 17:18:05 fritz
* Changes for recent kernels.
* Added common stub for sending commands to lowlevel.
* Added V.110.
*
* Revision 1.52 1998/01/31 22:05:57 keil
* Lots of changes for X.25 support:
* Added generic support for connection-controlling encapsulation protocols
* Added support of BHUP status message
* Added support for additional p_encap X25IFACE
* Added support for kernels &gt;= 2.1.72
*
* Revision 1.51 1998/01/31 19:17:29 calle
* merged changes from and for 2.1.82
*
* Revision 1.50 1997/12/12 06:12:11 calle
* moved EXPORT_SYMBOL(register_isdn) from isdn_syms.c to isdn_common.c
*
* Revision 1.49 1997/11/06 17:16:52 keil
* Sync to 2.1.62 changes
*
* Revision 1.48 1997/11/02 23:55:50 keil
* Andi Kleen's changes for 2.1.60
* without it the isdninfo and isdnctrl devices won't work
*
* Revision 1.47 1997/10/09 21:28:46 fritz
* New HL&lt;-&gt;LL interface:
* New BSENT callback with nr. of bytes included.
* Sending without ACK.
* New L1 error status (not yet in use).
* Cleaned up obsolete structures.
* Implemented Cisco-SLARP.
* Changed local net-interface data to be dynamically allocated.
* Removed old 2.0 compatibility stuff.
*
* Revision 1.46 1997/10/01 09:20:27 fritz
* Removed old compatibility stuff for 2.0.X kernels.
* From now on, this code is for 2.1.X ONLY!
* Old stuff is still in the separate branch.
*
* Revision 1.45 1997/08/21 23:11:41 fritz
* Added changes for kernels &gt;= 2.1.45
*
* Revision 1.44 1997/05/27 15:17:23 fritz
* Added changes for recent 2.1.x kernels:
* changed return type of isdn_close
* queue_task_* -&gt; queue_task
* clear/set_bit -&gt; test_and_... where apropriate.
* changed type of hard_header_cache parameter.
*
* Revision 1.43 1997/03/31 14:09:43 fritz
* Fixed memory leak in isdn_close().
*
* Revision 1.42 1997/03/30 16:51:08 calle
* changed calls to copy_from_user/copy_to_user and removed verify_area
* were possible.
*
* Revision 1.41 1997/03/24 22:54:41 fritz
* Some small fixes in debug code.
*
* Revision 1.40 1997/03/08 08:13:51 fritz
* Bugfix: IIOCSETMAP (Set mapping) was broken.
*
* Revision 1.39 1997/03/07 01:32:54 fritz
* Added proper ifdef's for CONFIG_ISDN_AUDIO
*
* Revision 1.38 1997/03/05 21:15:02 fritz
* Fix: reduced stack usage of isdn_ioctl() and isdn_set_allcfg()
*
* Revision 1.37 1997/03/02 14:29:18 fritz
* More ttyI related cleanup.
*
* Revision 1.36 1997/02/28 02:32:40 fritz
* Cleanup: Moved some tty related stuff from isdn_common.c
* to isdn_tty.c
* Bugfix: Bisync protocol did not behave like documented.
*
* Revision 1.35 1997/02/21 13:01:19 fritz
* Changes CAUSE message output in kernel log.
*
* Revision 1.34 1997/02/10 20:12:43 fritz
* Changed interface for reporting incoming calls.
*
* Revision 1.33 1997/02/10 10:05:42 fritz
* More changes for Kernel 2.1.X
* Symbol information moved to isdn_syms.c
*
* Revision 1.32 1997/02/03 22:55:26 fritz
* Reformatted according CodingStyle.
* Changed isdn_writebuf_stub static.
* Slow down tty-RING counter.
* skb-&gt;free stuff replaced by macro.
* Bugfix in audio-skb locking.
* Bugfix in HL-driver locking.
*
* Revision 1.31 1997/01/17 01:19:18 fritz
* Applied chargeint patch.
*
* Revision 1.30 1997/01/14 01:27:47 fritz
* Changed audio receive not to rely on skb-&gt;users and skb-&gt;lock.
* Added ATI2 and related variables.
* Started adding full-duplex audio capability.
*
* Revision 1.29 1997/01/12 23:33:03 fritz
* Made isdn_all_eaz foolproof.
*
* Revision 1.28 1996/11/13 02:33:19 fritz
* Fixed a race condition.
*
* Revision 1.27 1996/10/27 22:02:41 keil
* return codes for ISDN_STAT_ICALL
*
* Revision 1.26 1996/10/23 11:59:40 fritz
* More compatibility changes.
*
* Revision 1.25 1996/10/22 23:13:54 fritz
* Changes for compatibility to 2.0.X and 2.1.X kernels.
*
* Revision 1.24 1996/10/11 14:02:03 fritz
* Bugfix: call to isdn_ppp_timer_timeout() never compiled, because of
* typo in #ifdef.
*
* Revision 1.23 1996/06/25 18:35:38 fritz
* Fixed bogus memory access in isdn_set_allcfg().
*
* Revision 1.22 1996/06/24 17:37:37 fritz
* Bugfix: isdn_timer_ctrl() did restart timer, even if it
* was already running.
* lowlevel driver locking did use wrong parameters.
*
* Revision 1.21 1996/06/15 14:58:20 fritz
* Added version signatures for data structures used
* by userlevel programs.
*
* Revision 1.20 1996/06/12 16:01:49 fritz
* Bugfix: Remote B-channel hangup sometimes did not result
* in a NO CARRIER on tty.
*
* Revision 1.19 1996/06/11 14:52:04 hipp
* minor bugfix in isdn_writebuf_skb_stub()
*
* Revision 1.18 1996/06/06 14:51:51 fritz
* Changed to support DTMF decoding on audio playback also.
*
* Revision 1.17 1996/06/05 02:24:10 fritz
* Added DTMF decoder for audio mode.
*
* Revision 1.16 1996/06/03 20:09:05 fritz
* Bugfix: called wrong function pointer for locking in
* isdn_get_free_channel().
*
* Revision 1.15 1996/05/31 01:10:54 fritz
* Bugfixes:
* Lowlevel modules did not get locked correctly.
* Did show wrong revision when initializing.
* Minor fixes in ioctl code.
* sk_buff did not get freed, if error in writebuf_stub.
*
* Revision 1.14 1996/05/18 01:36:55 fritz
* Added spelling corrections and some minor changes
* to stay in sync with kernel.
*
* Revision 1.13 1996/05/17 15:43:30 fritz
* Bugfix: decrement of rcvcount in readbchan() corrected.
*
* Revision 1.12 1996/05/17 03:55:43 fritz
* Changed DLE handling for audio receive.
* Some cleanup.
* Added display of isdn_audio_revision.
*
* Revision 1.11 1996/05/11 21:51:32 fritz
* Changed queue management to use sk_buffs.
*
* Revision 1.10 1996/05/10 08:49:16 fritz
* Checkin before major changes of tty-code.
*
* Revision 1.9 1996/05/07 09:19:41 fritz
* Adapted to changes in isdn_tty.c
*
* Revision 1.8 1996/05/06 11:34:51 hipp
* fixed a few bugs
*
* Revision 1.7 1996/05/02 03:55:17 fritz
* Bugfixes:
* - B-channel connect message for modem devices
* sometimes did not result in a CONNECT-message.
* - register_isdn did not check for driverId-conflicts.
*
* Revision 1.6 1996/04/30 20:57:21 fritz
* Commit test
*
* Revision 1.5 1996/04/20 16:19:07 fritz
* Changed slow timer handlers to increase accuracy.
* Added statistic information for usage by xisdnload.
* Fixed behaviour of isdnctrl-device on non-blocked io.
* Fixed all io to go through generic writebuf-function without
* bypassing. Same for incoming data.
* Fixed bug: Last channel had been unusable.
* Fixed kfree of tty xmit_buf on ppp initialization failure.
*
* Revision 1.4 1996/02/11 02:33:26 fritz
* Fixed bug in main timer-dispatcher.
* Bugfix: Lot of tty-callbacks got called regardless of the events already
* been handled by network-devices.
* Changed ioctl-names.
*
* Revision 1.3 1996/01/22 05:16:11 fritz
* Changed ioctl-names.
* Fixed bugs in isdn_open and isdn_close regarding PPP_MINOR.
*
* Revision 1.2 1996/01/21 16:52:40 fritz
* Support for sk_buffs added, changed header-stuffing.
*
* Revision 1.1 1996/01/09 04:12:52 fritz
* Initial revision
*
*/</FONT>
<FONT COLOR=#A521F7>#include</FONT> &lt;linux/config.h&gt;
<FONT COLOR=#A521F7>#include</FONT> &lt;linux/module.h&gt;
<FONT COLOR=#A521F7>#include</FONT> &lt;linux/version.h&gt;
<FONT COLOR=#A521F7>#include</FONT> &lt;linux/poll.h&gt;
<FONT COLOR=#A521F7>#include</FONT> &lt;linux/isdn.h&gt;
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"isdn_common.h"</FONT>
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"isdn_tty.h"</FONT>
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"isdn_net.h"</FONT>
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"isdn_ppp.h"</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_AUDIO
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"isdn_audio.h"</FONT>
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"isdn_v110.h"</FONT>
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"isdn_cards.h"</FONT>
<FONT COLOR=#0000FF>/* Debugflags */</FONT>
<FONT COLOR=#A521F7>#undef</FONT> ISDN_DEBUG_STATCALLB
<A HREF="../includes/isdn.h.shtml#isdn_dev">isdn_dev</A> *dev = (<A HREF="../includes/isdn.h.shtml#isdn_dev">isdn_dev</A> *) 0;
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">char</FONT> *isdn_revision = <FONT COLOR="#FF0000">"$Revision$"</FONT>;
<FONT COLOR="#298C52">extern</FONT> <FONT COLOR="#298C52">char</FONT> *isdn_net_revision;
<FONT COLOR="#298C52">extern</FONT> <FONT COLOR="#298C52">char</FONT> *isdn_tty_revision;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">extern</FONT> <FONT COLOR="#298C52">char</FONT> *isdn_ppp_revision;
<FONT COLOR=#A521F7>#else</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">char</FONT> *isdn_ppp_revision = <FONT COLOR="#FF0000">": none $"</FONT>;
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_AUDIO
<FONT COLOR="#298C52">extern</FONT> <FONT COLOR="#298C52">char</FONT> *isdn_audio_revision;
<FONT COLOR=#A521F7>#else</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">char</FONT> *isdn_audio_revision = <FONT COLOR="#FF0000">": none $"</FONT>;
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">extern</FONT> <FONT COLOR="#298C52">char</FONT> *isdn_v110_revision;
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT> <A HREF="#isdn_writebuf_stub">isdn_writebuf_stub</A>(<FONT COLOR="#298C52">int</FONT>, <FONT COLOR="#298C52">int</FONT>, <FONT COLOR="#298C52">const</FONT> u_char *, <FONT COLOR="#298C52">int</FONT>, <FONT COLOR="#298C52">int</FONT>);
<FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_MOD_INC_USE_COUNT">isdn_MOD_INC_USE_COUNT</A>(<FONT COLOR="#298C52">void</FONT>)
{
MOD_INC_USE_COUNT;
}
<FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_MOD_DEC_USE_COUNT">isdn_MOD_DEC_USE_COUNT</A>(<FONT COLOR="#298C52">void</FONT>)
{
MOD_DEC_USE_COUNT;
}
<FONT COLOR=#A521F7>#if</FONT> defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP) || defined(CONFIG_ISDN_TIMEOUT_RULES)
<FONT COLOR="#298C52">void</FONT>
<A HREF="#isdn_dumppkt">isdn_dumppkt</A>(<FONT COLOR="#298C52">char</FONT> *s, u_char * p, <FONT COLOR="#298C52">int</FONT> len, <FONT COLOR="#298C52">int</FONT> dumplen)
{
<FONT COLOR="#298C52">int</FONT> dumpc;
printk(KERN_DEBUG <FONT COLOR="#FF0000">"%s(%d) "</FONT>, s, len);
<FONT COLOR="#298C52">for</FONT> (dumpc = 0; (dumpc &lt; dumplen) &amp;&amp; (len); len--, dumpc++)
printk(<FONT COLOR="#FF0000">" %02x"</FONT>, *p++);
printk(<FONT COLOR="#FF0000">"\n"</FONT>);
}
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#0000FF>/*
* 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)
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_star">isdn_star</A>(<FONT COLOR="#298C52">char</FONT> *s, <FONT COLOR="#298C52">char</FONT> *p)
{
<FONT COLOR="#298C52">while</FONT> (<A HREF="#isdn_wildmat">isdn_wildmat</A>(s, p)) {
<FONT COLOR="#298C52">if</FONT> (*++s == <FONT COLOR="#FF0000">'\0'</FONT>)
<FONT COLOR="#298C52">return</FONT> (2);
}
<FONT COLOR="#298C52">return</FONT> (0);
}
<FONT COLOR=#0000FF>/*
* 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
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_wildmat">isdn_wildmat</A>(<FONT COLOR="#298C52">char</FONT> *s, <FONT COLOR="#298C52">char</FONT> *p)
{
<FONT COLOR="#298C52">register</FONT> <FONT COLOR="#298C52">int</FONT> last;
<FONT COLOR="#298C52">register</FONT> <FONT COLOR="#298C52">int</FONT> matched;
<FONT COLOR="#298C52">register</FONT> <FONT COLOR="#298C52">int</FONT> reverse;
<FONT COLOR="#298C52">register</FONT> <FONT COLOR="#298C52">int</FONT> nostar = 1;
<FONT COLOR="#298C52">for</FONT> (; *p; s++, p++)
<FONT COLOR="#298C52">switch</FONT> (*p) {
<FONT COLOR="#298C52">case</FONT> <FONT COLOR="#FF0000">'\\'</FONT>:
<FONT COLOR=#0000FF>/*
* Literal match with following character,
* fall through.
*/</FONT>
p++;
<FONT COLOR="#298C52">default</FONT>:
<FONT COLOR="#298C52">if</FONT> (*s != *p)
<FONT COLOR="#298C52">return</FONT> (*s == <FONT COLOR="#FF0000">'\0'</FONT>)?2:1;
<FONT COLOR="#298C52">continue</FONT>;
<FONT COLOR="#298C52">case</FONT> <FONT COLOR="#FF0000">'?'</FONT>:
<FONT COLOR=#0000FF>/* Match anything. */</FONT>
<FONT COLOR="#298C52">if</FONT> (*s == <FONT COLOR="#FF0000">'\0'</FONT>)
<FONT COLOR="#298C52">return</FONT> (2);
<FONT COLOR="#298C52">continue</FONT>;
<FONT COLOR="#298C52">case</FONT> <FONT COLOR="#FF0000">'*'</FONT>:
nostar = 0;
<FONT COLOR=#0000FF>/* Trailing star matches everything. */</FONT>
<FONT COLOR="#298C52">return</FONT> (*++p ? <A HREF="#isdn_star">isdn_star</A>(s, p) : 0);
<FONT COLOR="#298C52">case</FONT> <FONT COLOR="#FF0000">'['</FONT>:
<FONT COLOR=#0000FF>/* [^....] means inverse character class. */</FONT>
<FONT COLOR="#298C52">if</FONT> ((reverse = (p[1] == <FONT COLOR="#FF0000">'^'</FONT>)))
p++;
<FONT COLOR="#298C52">for</FONT> (last = 0, matched = 0; *++p &amp;&amp; (*p != <FONT COLOR="#FF0000">']'</FONT>); last = *p)
<FONT COLOR=#0000FF>/* This next line requires a good C compiler. */</FONT>
<FONT COLOR="#298C52">if</FONT> (*p == <FONT COLOR="#FF0000">'-'</FONT> ? *s &lt;= *++p &amp;&amp; *s &gt;= last : *s == *p)
matched = 1;
<FONT COLOR="#298C52">if</FONT> (matched == reverse)
<FONT COLOR="#298C52">return</FONT> (1);
<FONT COLOR="#298C52">continue</FONT>;
}
<FONT COLOR="#298C52">return</FONT> (*s == <FONT COLOR="#FF0000">'\0'</FONT>)?0:nostar;
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_free_queue">isdn_free_queue</A>(<FONT COLOR="#298C52">struct</FONT> sk_buff_head *queue)
{
<FONT COLOR="#298C52">struct</FONT> sk_buff *skb;
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">long</FONT> flags;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<FONT COLOR="#298C52">if</FONT> (skb_queue_len(queue))
<FONT COLOR="#298C52">while</FONT> ((skb = skb_dequeue(queue)))
dev_kfree_skb(skb);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
}
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_dc2minor">isdn_dc2minor</A>(<FONT COLOR="#298C52">int</FONT> di, <FONT COLOR="#298C52">int</FONT> ch)
{
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++)
<FONT COLOR="#298C52">if</FONT> (dev-&gt;chanmap[i] == ch &amp;&amp; dev-&gt;drvmap[i] == di)
<FONT COLOR="#298C52">return</FONT> i;
<FONT COLOR="#298C52">return</FONT> -1;
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT> isdn_timer_cnt1 = 0;
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT> isdn_timer_cnt2 = 0;
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT> isdn_timer_cnt3 = 0;
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT> isdn_timer_cnt4 = 0;
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_timer_funct">isdn_timer_funct</A>(ulong dummy)
{
<FONT COLOR="#298C52">int</FONT> tf = dev-&gt;tflags;
<FONT COLOR="#298C52">if</FONT> (tf &amp; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_FAST">ISDN_TIMER_FAST</A>) {
<FONT COLOR="#298C52">if</FONT> (tf &amp; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_MODEMREAD">ISDN_TIMER_MODEMREAD</A>)
<A HREF="isdn_tty.c.shtml#isdn_tty_readmodem">isdn_tty_readmodem</A>();
<FONT COLOR="#298C52">if</FONT> (tf &amp; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_MODEMPLUS">ISDN_TIMER_MODEMPLUS</A>)
<A HREF="isdn_tty.c.shtml#isdn_tty_modem_escape">isdn_tty_modem_escape</A>();
<FONT COLOR="#298C52">if</FONT> (tf &amp; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_MODEMXMIT">ISDN_TIMER_MODEMXMIT</A>)
<A HREF="isdn_tty.c.shtml#isdn_tty_modem_xmit">isdn_tty_modem_xmit</A>();
}
<FONT COLOR="#298C52">if</FONT> (tf &amp; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_SLOW">ISDN_TIMER_SLOW</A>) {
<FONT COLOR="#298C52">if</FONT> (++isdn_timer_cnt1 &gt;= <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_02SEC">ISDN_TIMER_02SEC</A>) {
isdn_timer_cnt1 = 0;
<FONT COLOR="#298C52">if</FONT> (tf &amp; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_NETDIAL">ISDN_TIMER_NETDIAL</A>)
<A HREF="isdn_net.c.shtml#isdn_net_dial">isdn_net_dial</A>();
}
<FONT COLOR="#298C52">if</FONT> (++isdn_timer_cnt2 &gt;= <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_1SEC">ISDN_TIMER_1SEC</A>) {
isdn_timer_cnt2 = 0;
<FONT COLOR="#298C52">if</FONT> (tf &amp; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_NETHANGUP">ISDN_TIMER_NETHANGUP</A>)
<A HREF="isdn_net.c.shtml#isdn_net_autohup">isdn_net_autohup</A>();
<FONT COLOR="#298C52">if</FONT> (++isdn_timer_cnt3 &gt; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_RINGING">ISDN_TIMER_RINGING</A>) {
isdn_timer_cnt3 = 0;
<FONT COLOR="#298C52">if</FONT> (tf &amp; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_MODEMRING">ISDN_TIMER_MODEMRING</A>)
<A HREF="isdn_tty.c.shtml#isdn_tty_modem_ring">isdn_tty_modem_ring</A>();
}
<FONT COLOR="#298C52">if</FONT> (++isdn_timer_cnt4 &gt; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_KEEPINT">ISDN_TIMER_KEEPINT</A>) {
isdn_timer_cnt4 = 0;
<FONT COLOR="#298C52">if</FONT> (tf &amp; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_KEEPALIVE">ISDN_TIMER_KEEPALIVE</A>)
<A HREF="isdn_net.c.shtml#isdn_net_slarp_out">isdn_net_slarp_out</A>();
}
<FONT COLOR=#A521F7>#if</FONT> (defined CONFIG_ISDN_PPP) &amp;&amp; (defined CONFIG_ISDN_MPP)
<FONT COLOR="#298C52">if</FONT> (tf &amp; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_IPPP">ISDN_TIMER_IPPP</A>)
<A HREF="isdn_ppp.c.shtml#isdn_ppp_timer_timeout">isdn_ppp_timer_timeout</A>();
<FONT COLOR=#A521F7>#endif</FONT>
}
}
<FONT COLOR="#298C52">if</FONT> (tf)
{
<FONT COLOR="#298C52">int</FONT> flags;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
del_timer(&amp;dev-&gt;timer);
dev-&gt;timer.expires = jiffies + <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_RES">ISDN_TIMER_RES</A>;
add_timer(&amp;dev-&gt;timer);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
}
}
<FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_timer_ctrl">isdn_timer_ctrl</A>(<FONT COLOR="#298C52">int</FONT> tf, <FONT COLOR="#298C52">int</FONT> onoff)
{
<FONT COLOR="#298C52">int</FONT> flags;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<FONT COLOR="#298C52">if</FONT> ((tf &amp; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_SLOW">ISDN_TIMER_SLOW</A>) &amp;&amp; (!(dev-&gt;tflags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_SLOW">ISDN_TIMER_SLOW</A>))) {
<FONT COLOR=#0000FF>/* If the slow-timer wasn't activated until now */</FONT>
isdn_timer_cnt1 = 0;
isdn_timer_cnt2 = 0;
}
<FONT COLOR="#298C52">if</FONT> (onoff)
dev-&gt;tflags |= tf;
<FONT COLOR="#298C52">else</FONT>
dev-&gt;tflags &amp;= ~tf;
<FONT COLOR="#298C52">if</FONT> (dev-&gt;tflags) {
<FONT COLOR="#298C52">if</FONT> (!del_timer(&amp;dev-&gt;timer)) <FONT COLOR=#0000FF>/* del_timer is 1, when active */</FONT>
dev-&gt;timer.expires = jiffies + <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_RES">ISDN_TIMER_RES</A>;
add_timer(&amp;dev-&gt;timer);
}
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
}
<FONT COLOR=#0000FF>/*
* Receive a packet from B-Channel. (Called from low-level-module)
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
<A HREF="#isdn_receive_skb_callback">isdn_receive_skb_callback</A>(<FONT COLOR="#298C52">int</FONT> di, <FONT COLOR="#298C52">int</FONT> channel, <FONT COLOR="#298C52">struct</FONT> sk_buff *skb)
{
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">if</FONT> ((i = <A HREF="#isdn_dc2minor">isdn_dc2minor</A>(di, channel)) == -1) {
dev_kfree_skb(skb);
<FONT COLOR="#298C52">return</FONT>;
}
<FONT COLOR=#0000FF>/* Update statistics */</FONT>
dev-&gt;ibytes[i] += skb-&gt;len;
<FONT COLOR=#0000FF>/* First, try to deliver data to network-device */</FONT>
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_net.c.shtml#isdn_net_rcv_skb">isdn_net_rcv_skb</A>(i, skb))
<FONT COLOR="#298C52">return</FONT>;
<FONT COLOR=#0000FF>/* V.110 handling
* makes sense for async streams only, so it is
* called after possible net-device delivery.
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;v110[i]) {
atomic_inc(&amp;dev-&gt;v110use[i]);
skb = <A HREF="isdn_v110.c.shtml#isdn_v110_decode">isdn_v110_decode</A>(dev-&gt;v110[i], skb);
atomic_dec(&amp;dev-&gt;v110use[i]);
<FONT COLOR="#298C52">if</FONT> (!skb)
<FONT COLOR="#298C52">return</FONT>;
}
<FONT COLOR=#0000FF>/* No network-device found, deliver to tty or raw-channel */</FONT>
<FONT COLOR="#298C52">if</FONT> (skb-&gt;len) {
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_tty.c.shtml#isdn_tty_rcv_skb">isdn_tty_rcv_skb</A>(i, di, channel, skb))
<FONT COLOR="#298C52">return</FONT>;
wake_up_interruptible(&amp;dev-&gt;drv[di]-&gt;rcv_waitq[channel]);
} <FONT COLOR="#298C52">else</FONT>
dev_kfree_skb(skb);
}
<FONT COLOR=#0000FF>/*
* 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.
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_command">isdn_command</A>(<A HREF="../includes/isdnif.h.shtml#isdn_ctrl">isdn_ctrl</A> *cmd)
{
<FONT COLOR="#298C52">if</FONT> (cmd-&gt;command == <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_SETL2">ISDN_CMD_SETL2</A>) {
<FONT COLOR="#298C52">int</FONT> idx = <A HREF="#isdn_dc2minor">isdn_dc2minor</A>(cmd-&gt;<A HREF="../includes/isdn.h.shtml#driver">driver</A>, cmd-&gt;arg &amp; 255);
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">long</FONT> l2prot = (cmd-&gt;arg &gt;&gt; 8) &amp; 255;
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">long</FONT> features = (dev-&gt;drv[cmd-&gt;<A HREF="../includes/isdn.h.shtml#driver">driver</A>]-&gt;interface-&gt;features
&gt;&gt; <A HREF="../includes/isdnif.h.shtml#ISDN_FEATURE_L2_SHIFT">ISDN_FEATURE_L2_SHIFT</A>) &amp;
<A HREF="../includes/isdnif.h.shtml#ISDN_FEATURE_L2_MASK">ISDN_FEATURE_L2_MASK</A>;
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">long</FONT> l2_feature = (1 &lt;&lt; l2prot);
<FONT COLOR="#298C52">switch</FONT> (l2prot) {
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_PROTO_L2_V11096">ISDN_PROTO_L2_V11096</A>:
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_PROTO_L2_V11019">ISDN_PROTO_L2_V11019</A>:
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_PROTO_L2_V11038">ISDN_PROTO_L2_V11038</A>:
<FONT COLOR=#0000FF>/* If V.110 requested, but not supported by
* HL-driver, set emulator-flag and change
* Layer-2 to transparent
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (!(features &amp; l2_feature)) {
dev-&gt;v110emu[idx] = l2prot;
cmd-&gt;arg = (cmd-&gt;arg &amp; 255) |
(<A HREF="../includes/isdnif.h.shtml#ISDN_PROTO_L2_TRANS">ISDN_PROTO_L2_TRANS</A> &lt;&lt; 8);
} <FONT COLOR="#298C52">else</FONT>
dev-&gt;v110emu[idx] = 0;
}
}
<FONT COLOR="#298C52">return</FONT> dev-&gt;drv[cmd-&gt;<A HREF="../includes/isdn.h.shtml#driver">driver</A>]-&gt;interface-&gt;command(cmd);
}
<FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_all_eaz">isdn_all_eaz</A>(<FONT COLOR="#298C52">int</FONT> di, <FONT COLOR="#298C52">int</FONT> ch)
{
<A HREF="../includes/isdnif.h.shtml#isdn_ctrl">isdn_ctrl</A> cmd;
<FONT COLOR="#298C52">if</FONT> (di &lt; 0)
<FONT COLOR="#298C52">return</FONT>;
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = di;
cmd.arg = ch;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_SETEAZ">ISDN_CMD_SETEAZ</A>;
cmd.parm.num[0] = <FONT COLOR="#FF0000">'\0'</FONT>;
<A HREF="#isdn_command">isdn_command</A>(&amp;cmd);
}
<FONT COLOR=#0000FF>/*
* Begin of a CAPI like LL&lt;-&gt;HL interface, currently used only for
* supplementary service (CAPI 2.0 part III)
*/</FONT>
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"avmb1/capicmd.h"</FONT> <FONT COLOR=#0000FF>/* this should be moved in a common place */</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_capi_rec_hl_msg">isdn_capi_rec_hl_msg</A>(<A HREF="../includes/isdnif.h.shtml#capi_msg">capi_msg</A> *cm) {
<FONT COLOR="#298C52">int</FONT> di;
<FONT COLOR="#298C52">int</FONT> ch;
di = (cm-&gt;adr.Controller &amp; 0x7f) -1;
ch = <A HREF="#isdn_dc2minor">isdn_dc2minor</A>(di, (cm-&gt;adr.Controller&gt;&gt;8)&amp; 0x7f);
<FONT COLOR="#298C52">switch</FONT>(cm-&gt;Command) {
<FONT COLOR="#298C52">case</FONT> CAPI_FACILITY:
<FONT COLOR=#0000FF>/* in the moment only handled in tty */</FONT>
<FONT COLOR="#298C52">return</FONT>(<A HREF="isdn_tty.c.shtml#isdn_tty_capi_facility">isdn_tty_capi_facility</A>(cm));
<FONT COLOR="#298C52">default</FONT>:
<FONT COLOR="#298C52">return</FONT>(-1);
}
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_status_callback">isdn_status_callback</A>(<A HREF="../includes/isdnif.h.shtml#isdn_ctrl">isdn_ctrl</A> * c)
{
<FONT COLOR="#298C52">int</FONT> di;
ulong flags;
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">int</FONT> r;
<FONT COLOR="#298C52">int</FONT> retval = 0;
<A HREF="../includes/isdnif.h.shtml#isdn_ctrl">isdn_ctrl</A> cmd;
di = c-&gt;<A HREF="../includes/isdn.h.shtml#driver">driver</A>;
i = <A HREF="#isdn_dc2minor">isdn_dc2minor</A>(di, c-&gt;arg);
<FONT COLOR="#298C52">switch</FONT> (c-&gt;command) {
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_BSENT">ISDN_STAT_BSENT</A>:
<FONT COLOR="#298C52">if</FONT> (i &lt; 0)
<FONT COLOR="#298C52">return</FONT> -1;
<FONT COLOR="#298C52">if</FONT> (dev-&gt;global_flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A>)
<FONT COLOR="#298C52">return</FONT> 0;
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_net.c.shtml#isdn_net_stat_callback">isdn_net_stat_callback</A>(i, c))
<FONT COLOR="#298C52">return</FONT> 0;
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_v110.c.shtml#isdn_v110_stat_callback">isdn_v110_stat_callback</A>(i, c))
<FONT COLOR="#298C52">return</FONT> 0;
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_tty.c.shtml#isdn_tty_stat_callback">isdn_tty_stat_callback</A>(i, c))
<FONT COLOR="#298C52">return</FONT> 0;
wake_up_interruptible(&amp;dev-&gt;drv[di]-&gt;snd_waitq[c-&gt;arg]);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_STAVAIL">ISDN_STAT_STAVAIL</A>:
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
dev-&gt;drv[di]-&gt;stavail += c-&gt;arg;
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
wake_up_interruptible(&amp;dev-&gt;drv[di]-&gt;st_waitq);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_RUN">ISDN_STAT_RUN</A>:
dev-&gt;drv[di]-&gt;running = 1;
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++)
<FONT COLOR="#298C52">if</FONT> (dev-&gt;drvmap[i] == di)
<A HREF="#isdn_all_eaz">isdn_all_eaz</A>(di, dev-&gt;chanmap[i]);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_STOP">ISDN_STAT_STOP</A>:
dev-&gt;drv[di]-&gt;running = 0;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_ICALL">ISDN_STAT_ICALL</A>:
<FONT COLOR="#298C52">if</FONT> (i &lt; 0)
<FONT COLOR="#298C52">return</FONT> -1;
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_STATCALLB
printk(KERN_DEBUG <FONT COLOR="#FF0000">"ICALL (net): %d %ld %s\n"</FONT>, di, c-&gt;arg, c-&gt;parm.num);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;global_flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A>) {
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = di;
cmd.arg = c-&gt;arg;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_HANGUP">ISDN_CMD_HANGUP</A>;
<A HREF="#isdn_command">isdn_command</A>(&amp;cmd);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#0000FF>/* Try to find a network-interface which will accept incoming call */</FONT>
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = di;
cmd.arg = c-&gt;arg;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_LOCK">ISDN_CMD_LOCK</A>;
<A HREF="#isdn_command">isdn_command</A>(&amp;cmd);
r = <A HREF="isdn_net.c.shtml#isdn_net_find_icall">isdn_net_find_icall</A>(di, c-&gt;arg, i, c-&gt;parm.setup);
<FONT COLOR="#298C52">switch</FONT> (r) {
<FONT COLOR="#298C52">case</FONT> 0:
<FONT COLOR=#0000FF>/* 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.
*/</FONT>
retval = <A HREF="isdn_tty.c.shtml#isdn_tty_find_icall">isdn_tty_find_icall</A>(di, c-&gt;arg, c-&gt;parm.setup);
<FONT COLOR="#298C52">if</FONT> ((!retval) &amp;&amp; dev-&gt;drv[di]-&gt;reject_bus) {
<FONT COLOR=#0000FF>/* No tty responding */</FONT>
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = di;
cmd.arg = c-&gt;arg;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_HANGUP">ISDN_CMD_HANGUP</A>;
<A HREF="#isdn_command">isdn_command</A>(&amp;cmd);
retval = 2;
}
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 1:
<FONT COLOR=#0000FF>/* Schedule connection-setup */</FONT>
<A HREF="isdn_net.c.shtml#isdn_net_dial">isdn_net_dial</A>();
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = di;
cmd.arg = c-&gt;arg;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_ACCEPTD">ISDN_CMD_ACCEPTD</A>;
<A HREF="#isdn_command">isdn_command</A>(&amp;cmd);
retval = 1;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 2: <FONT COLOR=#0000FF>/* For calling back, first reject incoming call ... */</FONT>
<FONT COLOR="#298C52">case</FONT> 3: <FONT COLOR=#0000FF>/* Interface found, but down, reject call actively */</FONT>
retval = 2;
printk(KERN_INFO <FONT COLOR="#FF0000">"isdn: Rejecting Call\n"</FONT>);
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = di;
cmd.arg = c-&gt;arg;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_HANGUP">ISDN_CMD_HANGUP</A>;
<A HREF="#isdn_command">isdn_command</A>(&amp;cmd);
<FONT COLOR="#298C52">if</FONT> (r == 3)
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR=#0000FF>/* Fall through */</FONT>
<FONT COLOR="#298C52">case</FONT> 4:
<FONT COLOR=#0000FF>/* ... then start callback. */</FONT>
<A HREF="isdn_net.c.shtml#isdn_net_dial">isdn_net_dial</A>();
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 5:
<FONT COLOR=#0000FF>/* Number would eventually match, if longer */</FONT>
retval = 3;
<FONT COLOR="#298C52">break</FONT>;
}
<FONT COLOR="#298C52">if</FONT> (retval != 1) {
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = di;
cmd.arg = c-&gt;arg;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_UNLOCK">ISDN_CMD_UNLOCK</A>;
<A HREF="#isdn_command">isdn_command</A>(&amp;cmd);
}
printk(KERN_DEBUG <FONT COLOR="#FF0000">"ICALL: ret=%d\n"</FONT>, retval);
<FONT COLOR="#298C52">return</FONT> retval;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_CINF">ISDN_STAT_CINF</A>:
<FONT COLOR="#298C52">if</FONT> (i &lt; 0)
<FONT COLOR="#298C52">return</FONT> -1;
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_STATCALLB
printk(KERN_DEBUG <FONT COLOR="#FF0000">"CINF: %ld %s\n"</FONT>, c-&gt;arg, c-&gt;parm.num);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;global_flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A>)
<FONT COLOR="#298C52">return</FONT> 0;
<FONT COLOR="#298C52">if</FONT> (strcmp(c-&gt;parm.num, <FONT COLOR="#FF0000">"0"</FONT>))
<A HREF="isdn_net.c.shtml#isdn_net_stat_callback">isdn_net_stat_callback</A>(i, c);
<A HREF="isdn_tty.c.shtml#isdn_tty_stat_callback">isdn_tty_stat_callback</A>(i, c);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_CAUSE">ISDN_STAT_CAUSE</A>:
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_STATCALLB
printk(KERN_DEBUG <FONT COLOR="#FF0000">"CAUSE: %ld %s\n"</FONT>, c-&gt;arg, c-&gt;parm.num);
<FONT COLOR=#A521F7>#endif</FONT>
printk(KERN_INFO <FONT COLOR="#FF0000">"isdn: %s,ch%ld cause: %s\n"</FONT>,
dev-&gt;drvid[di], c-&gt;arg, c-&gt;parm.num);
<A HREF="isdn_tty.c.shtml#isdn_tty_stat_callback">isdn_tty_stat_callback</A>(i, c);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_DCONN">ISDN_STAT_DCONN</A>:
<FONT COLOR="#298C52">if</FONT> (i &lt; 0)
<FONT COLOR="#298C52">return</FONT> -1;
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_STATCALLB
printk(KERN_DEBUG <FONT COLOR="#FF0000">"DCONN: %ld\n"</FONT>, c-&gt;arg);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;global_flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A>)
<FONT COLOR="#298C52">return</FONT> 0;
<FONT COLOR=#0000FF>/* Find any net-device, waiting for D-channel setup */</FONT>
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_net.c.shtml#isdn_net_stat_callback">isdn_net_stat_callback</A>(i, c))
<FONT COLOR="#298C52">break</FONT>;
<A HREF="isdn_v110.c.shtml#isdn_v110_stat_callback">isdn_v110_stat_callback</A>(i, c);
<FONT COLOR=#0000FF>/* Find any ttyI, waiting for D-channel setup */</FONT>
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_tty.c.shtml#isdn_tty_stat_callback">isdn_tty_stat_callback</A>(i, c)) {
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = di;
cmd.arg = c-&gt;arg;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_ACCEPTB">ISDN_CMD_ACCEPTB</A>;
<A HREF="#isdn_command">isdn_command</A>(&amp;cmd);
<FONT COLOR="#298C52">break</FONT>;
}
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_DHUP">ISDN_STAT_DHUP</A>:
<FONT COLOR="#298C52">if</FONT> (i &lt; 0)
<FONT COLOR="#298C52">return</FONT> -1;
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_STATCALLB
printk(KERN_DEBUG <FONT COLOR="#FF0000">"DHUP: %ld\n"</FONT>, c-&gt;arg);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;global_flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A>)
<FONT COLOR="#298C52">return</FONT> 0;
dev-&gt;drv[di]-&gt;flags &amp;= ~(1 &lt;&lt; (c-&gt;arg));
<A HREF="#isdn_info_update">isdn_info_update</A>();
<FONT COLOR=#0000FF>/* Signal hangup to network-devices */</FONT>
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_net.c.shtml#isdn_net_stat_callback">isdn_net_stat_callback</A>(i, c))
<FONT COLOR="#298C52">break</FONT>;
<A HREF="isdn_v110.c.shtml#isdn_v110_stat_callback">isdn_v110_stat_callback</A>(i, c);
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_tty.c.shtml#isdn_tty_stat_callback">isdn_tty_stat_callback</A>(i, c))
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_BCONN">ISDN_STAT_BCONN</A>:
<FONT COLOR="#298C52">if</FONT> (i &lt; 0)
<FONT COLOR="#298C52">return</FONT> -1;
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_STATCALLB
printk(KERN_DEBUG <FONT COLOR="#FF0000">"BCONN: %ld\n"</FONT>, c-&gt;arg);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#0000FF>/* Signal B-channel-connect to network-devices */</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;global_flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A>)
<FONT COLOR="#298C52">return</FONT> 0;
dev-&gt;drv[di]-&gt;flags |= (1 &lt;&lt; (c-&gt;arg));
<A HREF="#isdn_info_update">isdn_info_update</A>();
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_net.c.shtml#isdn_net_stat_callback">isdn_net_stat_callback</A>(i, c))
<FONT COLOR="#298C52">break</FONT>;
<A HREF="isdn_v110.c.shtml#isdn_v110_stat_callback">isdn_v110_stat_callback</A>(i, c);
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_tty.c.shtml#isdn_tty_stat_callback">isdn_tty_stat_callback</A>(i, c))
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_BHUP">ISDN_STAT_BHUP</A>:
<FONT COLOR="#298C52">if</FONT> (i &lt; 0)
<FONT COLOR="#298C52">return</FONT> -1;
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_STATCALLB
printk(KERN_DEBUG <FONT COLOR="#FF0000">"BHUP: %ld\n"</FONT>, c-&gt;arg);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;global_flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A>)
<FONT COLOR="#298C52">return</FONT> 0;
dev-&gt;drv[di]-&gt;flags &amp;= ~(1 &lt;&lt; (c-&gt;arg));
<A HREF="#isdn_info_update">isdn_info_update</A>();
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR=#0000FF>/* Signal hangup to network-devices */</FONT>
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_net.c.shtml#isdn_net_stat_callback">isdn_net_stat_callback</A>(i, c))
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR=#A521F7>#endif</FONT>
<A HREF="isdn_v110.c.shtml#isdn_v110_stat_callback">isdn_v110_stat_callback</A>(i, c);
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_tty.c.shtml#isdn_tty_stat_callback">isdn_tty_stat_callback</A>(i, c))
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_NODCH">ISDN_STAT_NODCH</A>:
<FONT COLOR="#298C52">if</FONT> (i &lt; 0)
<FONT COLOR="#298C52">return</FONT> -1;
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_STATCALLB
printk(KERN_DEBUG <FONT COLOR="#FF0000">"NODCH: %ld\n"</FONT>, c-&gt;arg);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;global_flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A>)
<FONT COLOR="#298C52">return</FONT> 0;
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_net.c.shtml#isdn_net_stat_callback">isdn_net_stat_callback</A>(i, c))
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_tty.c.shtml#isdn_tty_stat_callback">isdn_tty_stat_callback</A>(i, c))
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_ADDCH">ISDN_STAT_ADDCH</A>:
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_UNLOAD">ISDN_STAT_UNLOAD</A>:
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<A HREF="isdn_tty.c.shtml#isdn_tty_stat_callback">isdn_tty_stat_callback</A>(i, c);
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++)
<FONT COLOR="#298C52">if</FONT> (dev-&gt;drvmap[i] == di) {
dev-&gt;drvmap[i] = -1;
dev-&gt;chanmap[i] = -1;
}
dev-&gt;drivers--;
dev-&gt;channels -= dev-&gt;drv[di]-&gt;channels;
kfree(dev-&gt;drv[di]-&gt;rcverr);
kfree(dev-&gt;drv[di]-&gt;rcvcount);
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; dev-&gt;drv[di]-&gt;channels; i++)
<A HREF="#isdn_free_queue">isdn_free_queue</A>(&amp;dev-&gt;drv[di]-&gt;rpqueue[i]);
kfree(dev-&gt;drv[di]-&gt;rpqueue);
kfree(dev-&gt;drv[di]-&gt;rcv_waitq);
kfree(dev-&gt;drv[di]-&gt;snd_waitq);
kfree(dev-&gt;drv[di]);
dev-&gt;drv[di] = NULL;
dev-&gt;drvid[di][0] = <FONT COLOR="#FF0000">'\0'</FONT>;
<A HREF="#isdn_info_update">isdn_info_update</A>();
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> 0;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_L1ERR">ISDN_STAT_L1ERR</A>:
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#CAPI_PUT_MESSAGE">CAPI_PUT_MESSAGE</A>:
<FONT COLOR="#298C52">return</FONT>(<A HREF="#isdn_capi_rec_hl_msg">isdn_capi_rec_hl_msg</A>(&amp;c-&gt;parm.cmsg));
<FONT COLOR="#298C52">default</FONT>:
<FONT COLOR="#298C52">return</FONT> -1;
}
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#0000FF>/*
* Get integer from char-pointer, set pointer to end of number
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_getnum">isdn_getnum</A>(<FONT COLOR="#298C52">char</FONT> **p)
{
<FONT COLOR="#298C52">int</FONT> v = -1;
<FONT COLOR="#298C52">while</FONT> (*p[0] &gt;= <FONT COLOR="#FF0000">'0'</FONT> &amp;&amp; *p[0] &lt;= <FONT COLOR="#FF0000">'9'</FONT>)
v = ((v &lt; 0) ? 0 : (v * 10)) + (<FONT COLOR="#298C52">int</FONT>) ((*p[0]++) - <FONT COLOR="#FF0000">'0'</FONT>);
<FONT COLOR="#298C52">return</FONT> v;
}
<FONT COLOR=#A521F7>#define</FONT> <A NAME="DLE">DLE</A> 0x10
<FONT COLOR=#0000FF>/*
* 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)&lt;-&gt;minor, happen during the sleep? --he
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A HREF="#isdn_readbchan">isdn_readbchan</A>(<FONT COLOR="#298C52">int</FONT> di, <FONT COLOR="#298C52">int</FONT> channel, u_char * buf, u_char * fp, <FONT COLOR="#298C52">int</FONT> len, <FONT COLOR="#298C52">struct</FONT> wait_queue **sleep)
{
<FONT COLOR="#298C52">int</FONT> left;
<FONT COLOR="#298C52">int</FONT> count;
<FONT COLOR="#298C52">int</FONT> count_pull;
<FONT COLOR="#298C52">int</FONT> count_put;
<FONT COLOR="#298C52">int</FONT> dflag;
<FONT COLOR="#298C52">struct</FONT> sk_buff *skb;
u_char *cp;
<FONT COLOR="#298C52">if</FONT> (!dev-&gt;drv[di])
<FONT COLOR="#298C52">return</FONT> 0;
<FONT COLOR="#298C52">if</FONT> (skb_queue_empty(&amp;dev-&gt;drv[di]-&gt;rpqueue[channel])) {
<FONT COLOR="#298C52">if</FONT> (sleep)
interruptible_sleep_on(sleep);
<FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> 0;
}
left = <A HREF="isdn_hybrid.c.shtml#MIN">MIN</A>(len, dev-&gt;drv[di]-&gt;rcvcount[channel]);
cp = buf;
count = 0;
<FONT COLOR="#298C52">while</FONT> (left) {
<FONT COLOR="#298C52">if</FONT> (!(skb = skb_peek(&amp;dev-&gt;drv[di]-&gt;rpqueue[channel])))
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_AUDIO
<FONT COLOR="#298C52">if</FONT> (<A HREF="../includes/isdn.h.shtml#ISDN_AUDIO_SKB_LOCK">ISDN_AUDIO_SKB_LOCK</A>(skb))
<FONT COLOR="#298C52">break</FONT>;
<A HREF="../includes/isdn.h.shtml#ISDN_AUDIO_SKB_LOCK">ISDN_AUDIO_SKB_LOCK</A>(skb) = 1;
<FONT COLOR="#298C52">if</FONT> (<A HREF="../includes/isdn.h.shtml#ISDN_AUDIO_SKB_DLECOUNT">ISDN_AUDIO_SKB_DLECOUNT</A>(skb)) {
<FONT COLOR="#298C52">char</FONT> *p = skb-&gt;data;
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">long</FONT> DLEmask = (1 &lt;&lt; channel);
dflag = 0;
count_pull = count_put = 0;
<FONT COLOR="#298C52">while</FONT> ((count_pull &lt; skb-&gt;len) &amp;&amp; (left-- &gt; 0)) {
<FONT COLOR="#298C52">if</FONT> (dev-&gt;drv[di]-&gt;DLEflag &amp; DLEmask) {
*cp++ = <A HREF="#DLE">DLE</A>;
dev-&gt;drv[di]-&gt;DLEflag &amp;= ~DLEmask;
} <FONT COLOR="#298C52">else</FONT> {
*cp++ = *p;
<FONT COLOR="#298C52">if</FONT> (*p == <A HREF="#DLE">DLE</A>) {
dev-&gt;drv[di]-&gt;DLEflag |= DLEmask;
(<A HREF="../includes/isdn.h.shtml#ISDN_AUDIO_SKB_DLECOUNT">ISDN_AUDIO_SKB_DLECOUNT</A>(skb))--;
}
p++;
count_pull++;
}
count_put++;
}
<FONT COLOR="#298C52">if</FONT> (count_pull &gt;= skb-&gt;len)
dflag = 1;
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#0000FF>/* No DLE's in buff, so simply copy it */</FONT>
dflag = 1;
<FONT COLOR="#298C52">if</FONT> ((count_pull = skb-&gt;len) &gt; left) {
count_pull = left;
dflag = 0;
}
count_put = count_pull;
memcpy(cp, skb-&gt;data, count_put);
cp += count_put;
left -= count_put;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_AUDIO
}
<FONT COLOR=#A521F7>#endif</FONT>
count += count_put;
<FONT COLOR="#298C52">if</FONT> (fp) {
memset(fp, 0, count_put);
fp += count_put;
}
<FONT COLOR="#298C52">if</FONT> (dflag) {
<FONT COLOR=#0000FF>/* We got all the data in this buff.
* Now we can dequeue it.
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (fp)
*(fp - 1) = 0xff;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_AUDIO
<A HREF="../includes/isdn.h.shtml#ISDN_AUDIO_SKB_LOCK">ISDN_AUDIO_SKB_LOCK</A>(skb) = 0;
<FONT COLOR=#A521F7>#endif</FONT>
skb = skb_dequeue(&amp;dev-&gt;drv[di]-&gt;rpqueue[channel]);
dev_kfree_skb(skb);
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR=#0000FF>/* 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.
*/</FONT>
skb_pull(skb, count_pull);
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_AUDIO
<A HREF="../includes/isdn.h.shtml#ISDN_AUDIO_SKB_LOCK">ISDN_AUDIO_SKB_LOCK</A>(skb) = 0;
<FONT COLOR=#A521F7>#endif</FONT>
}
dev-&gt;drv[di]-&gt;rcvcount[channel] -= count_put;
}
<FONT COLOR="#298C52">return</FONT> count;
}
<FONT COLOR="#298C52">static</FONT> __inline <FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_minor2drv">isdn_minor2drv</A>(<FONT COLOR="#298C52">int</FONT> minor)
{
<FONT COLOR="#298C52">return</FONT> (dev-&gt;drvmap[minor]);
}
<FONT COLOR="#298C52">static</FONT> __inline <FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_minor2chan">isdn_minor2chan</A>(<FONT COLOR="#298C52">int</FONT> minor)
{
<FONT COLOR="#298C52">return</FONT> (dev-&gt;chanmap[minor]);
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">char</FONT> *
<A NAME="isdn_statstr">isdn_statstr</A>(<FONT COLOR="#298C52">void</FONT>)
{
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">char</FONT> istatbuf[2048];
<FONT COLOR="#298C52">char</FONT> *p;
<FONT COLOR="#298C52">int</FONT> i;
sprintf(istatbuf, <FONT COLOR="#FF0000">"idmap:\t"</FONT>);
p = istatbuf + strlen(istatbuf);
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
sprintf(p, <FONT COLOR="#FF0000">"%s "</FONT>, (dev-&gt;drvmap[i] &lt; 0) ? <FONT COLOR="#FF0000">"-"</FONT> : dev-&gt;drvid[dev-&gt;drvmap[i]]);
p = istatbuf + strlen(istatbuf);
}
sprintf(p, <FONT COLOR="#FF0000">"\nchmap:\t"</FONT>);
p = istatbuf + strlen(istatbuf);
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
sprintf(p, <FONT COLOR="#FF0000">"%d "</FONT>, dev-&gt;chanmap[i]);
p = istatbuf + strlen(istatbuf);
}
sprintf(p, <FONT COLOR="#FF0000">"\ndrmap:\t"</FONT>);
p = istatbuf + strlen(istatbuf);
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
sprintf(p, <FONT COLOR="#FF0000">"%d "</FONT>, dev-&gt;drvmap[i]);
p = istatbuf + strlen(istatbuf);
}
sprintf(p, <FONT COLOR="#FF0000">"\nusage:\t"</FONT>);
p = istatbuf + strlen(istatbuf);
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
sprintf(p, <FONT COLOR="#FF0000">"%d "</FONT>, dev-&gt;usage[i]);
p = istatbuf + strlen(istatbuf);
}
sprintf(p, <FONT COLOR="#FF0000">"\nflags:\t"</FONT>);
p = istatbuf + strlen(istatbuf);
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>; i++) {
<FONT COLOR="#298C52">if</FONT> (dev-&gt;drv[i]) {
sprintf(p, <FONT COLOR="#FF0000">"%ld "</FONT>, dev-&gt;drv[i]-&gt;flags);
p = istatbuf + strlen(istatbuf);
} <FONT COLOR="#298C52">else</FONT> {
sprintf(p, <FONT COLOR="#FF0000">"? "</FONT>);
p = istatbuf + strlen(istatbuf);
}
}
sprintf(p, <FONT COLOR="#FF0000">"\nphone:\t"</FONT>);
p = istatbuf + strlen(istatbuf);
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
sprintf(p, <FONT COLOR="#FF0000">"%s "</FONT>, dev-&gt;num[i]);
p = istatbuf + strlen(istatbuf);
}
sprintf(p, <FONT COLOR="#FF0000">"\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> istatbuf;
}
<FONT COLOR=#0000FF>/* Module interface-code */</FONT>
<FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_info_update">isdn_info_update</A>(<FONT COLOR="#298C52">void</FONT>)
{
<A HREF="../includes/isdn.h.shtml#infostruct">infostruct</A> *p = dev-&gt;infochain;
<FONT COLOR="#298C52">while</FONT> (p) {
*(p-&gt;<FONT COLOR="#298C52">private</FONT>) = 1;
p = (<A HREF="../includes/isdn.h.shtml#infostruct">infostruct</A> *) p-&gt;next;
}
wake_up_interruptible(&amp;(dev-&gt;info_waitq));
}
<FONT COLOR="#298C52">static</FONT> ssize_t
<A HREF="#isdn_read">isdn_read</A>(<FONT COLOR="#298C52">struct</FONT> file *file, <FONT COLOR="#298C52">char</FONT> *buf, size_t count, loff_t * off)
{
uint minor = MINOR(file-&gt;f_dentry-&gt;d_inode-&gt;i_rdev);
<FONT COLOR="#298C52">int</FONT> len = 0;
ulong flags;
<FONT COLOR="#298C52">int</FONT> drvidx;
<FONT COLOR="#298C52">int</FONT> chidx;
<FONT COLOR="#298C52">char</FONT> *p;
<FONT COLOR="#298C52">if</FONT> (off != &amp;file-&gt;f_pos)
<FONT COLOR="#298C52">return</FONT> -ESPIPE;
<FONT COLOR="#298C52">if</FONT> (minor == <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_STATUS">ISDN_MINOR_STATUS</A>) {
<FONT COLOR="#298C52">if</FONT> (!file-&gt;private_data) {
<FONT COLOR="#298C52">if</FONT> (file-&gt;f_flags &amp; O_NONBLOCK)
<FONT COLOR="#298C52">return</FONT> -EAGAIN;
interruptible_sleep_on(&amp;(dev-&gt;info_waitq));
}
p = <A HREF="#isdn_statstr">isdn_statstr</A>();
file-&gt;private_data = 0;
<FONT COLOR="#298C52">if</FONT> ((len = strlen(p)) &lt;= count) {
<FONT COLOR="#298C52">if</FONT> (copy_to_user(buf, p, len))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
*off += len;
<FONT COLOR="#298C52">return</FONT> len;
}
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">if</FONT> (!dev-&gt;drivers)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
<FONT COLOR="#298C52">if</FONT> (minor &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRL">ISDN_MINOR_CTRL</A>) {
drvidx = <A HREF="#isdn_minor2drv">isdn_minor2drv</A>(minor);
<FONT COLOR="#298C52">if</FONT> (drvidx &lt; 0)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
<FONT COLOR="#298C52">if</FONT> (!dev-&gt;drv[drvidx]-&gt;running)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
chidx = <A HREF="#isdn_minor2chan">isdn_minor2chan</A>(minor);
<FONT COLOR="#298C52">if</FONT>( ! (p = kmalloc(count,GFP_KERNEL)) ) <FONT COLOR="#298C52">return</FONT> -ENOMEM;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
len = <A HREF="#isdn_readbchan">isdn_readbchan</A>(drvidx, chidx, p, 0, count,
&amp;dev-&gt;drv[drvidx]-&gt;rcv_waitq[chidx]);
*off += len;
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">if</FONT>( copy_to_user(buf,p,len) ) len = -EFAULT;
kfree(p);
<FONT COLOR="#298C52">return</FONT> len;
}
<FONT COLOR="#298C52">if</FONT> (minor &lt;= <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRLMAX">ISDN_MINOR_CTRLMAX</A>) {
drvidx = <A HREF="#isdn_minor2drv">isdn_minor2drv</A>(minor - <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRL">ISDN_MINOR_CTRL</A>);
<FONT COLOR="#298C52">if</FONT> (drvidx &lt; 0)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
<FONT COLOR="#298C52">if</FONT> (!dev-&gt;drv[drvidx]-&gt;stavail) {
<FONT COLOR="#298C52">if</FONT> (file-&gt;f_flags &amp; O_NONBLOCK)
<FONT COLOR="#298C52">return</FONT> -EAGAIN;
interruptible_sleep_on(&amp;(dev-&gt;drv[drvidx]-&gt;st_waitq));
}
<FONT COLOR="#298C52">if</FONT> (dev-&gt;drv[drvidx]-&gt;interface-&gt;readstat)
len = dev-&gt;drv[drvidx]-&gt;interface-&gt;
readstat(buf, <A HREF="isdn_hybrid.c.shtml#MIN">MIN</A>(count, dev-&gt;drv[drvidx]-&gt;stavail),
1, drvidx, <A HREF="#isdn_minor2chan">isdn_minor2chan</A>(minor));
<FONT COLOR="#298C52">else</FONT>
len = 0;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<FONT COLOR="#298C52">if</FONT> (len)
dev-&gt;drv[drvidx]-&gt;stavail -= len;
<FONT COLOR="#298C52">else</FONT>
dev-&gt;drv[drvidx]-&gt;stavail = 0;
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
*off += len;
<FONT COLOR="#298C52">return</FONT> len;
}
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">if</FONT> (minor &lt;= <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_PPPMAX">ISDN_MINOR_PPPMAX</A>)
<FONT COLOR="#298C52">return</FONT> (<A HREF="isdn_ppp.c.shtml#isdn_ppp_read">isdn_ppp_read</A>(minor - <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_PPP">ISDN_MINOR_PPP</A>, file, buf, count));
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">return</FONT> -ENODEV;
}
<FONT COLOR="#298C52">static</FONT> loff_t
<A HREF="#isdn_lseek">isdn_lseek</A>(<FONT COLOR="#298C52">struct</FONT> file *file, loff_t offset, <FONT COLOR="#298C52">int</FONT> orig)
{
<FONT COLOR="#298C52">return</FONT> -ESPIPE;
}
<FONT COLOR="#298C52">static</FONT> ssize_t
<A HREF="#isdn_write">isdn_write</A>(<FONT COLOR="#298C52">struct</FONT> file *file, <FONT COLOR="#298C52">const</FONT> <FONT COLOR="#298C52">char</FONT> *buf, size_t count, loff_t * off)
{
uint minor = MINOR(file-&gt;f_dentry-&gt;d_inode-&gt;i_rdev);
<FONT COLOR="#298C52">int</FONT> drvidx;
<FONT COLOR="#298C52">int</FONT> chidx;
<FONT COLOR="#298C52">if</FONT> (off != &amp;file-&gt;f_pos)
<FONT COLOR="#298C52">return</FONT> -ESPIPE;
<FONT COLOR="#298C52">if</FONT> (minor == <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_STATUS">ISDN_MINOR_STATUS</A>)
<FONT COLOR="#298C52">return</FONT> -EPERM;
<FONT COLOR="#298C52">if</FONT> (!dev-&gt;drivers)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
<FONT COLOR="#298C52">if</FONT> (minor &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRL">ISDN_MINOR_CTRL</A>) {
drvidx = <A HREF="#isdn_minor2drv">isdn_minor2drv</A>(minor);
<FONT COLOR="#298C52">if</FONT> (drvidx &lt; 0)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
<FONT COLOR="#298C52">if</FONT> (!dev-&gt;drv[drvidx]-&gt;running)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
chidx = <A HREF="#isdn_minor2chan">isdn_minor2chan</A>(minor);
<FONT COLOR="#298C52">while</FONT> (<A HREF="#isdn_writebuf_stub">isdn_writebuf_stub</A>(drvidx, chidx, buf, count, 1) != count)
interruptible_sleep_on(&amp;dev-&gt;drv[drvidx]-&gt;snd_waitq[chidx]);
<FONT COLOR="#298C52">return</FONT> count;
}
<FONT COLOR="#298C52">if</FONT> (minor &lt;= <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRLMAX">ISDN_MINOR_CTRLMAX</A>) {
drvidx = <A HREF="#isdn_minor2drv">isdn_minor2drv</A>(minor - <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRL">ISDN_MINOR_CTRL</A>);
<FONT COLOR="#298C52">if</FONT> (drvidx &lt; 0)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
<FONT COLOR=#0000FF>/*
* We want to use the isdnctrl device to load the firmware
*
if (!dev-&gt;drv[drvidx]-&gt;running)
return -ENODEV;
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;drv[drvidx]-&gt;interface-&gt;writecmd)
<FONT COLOR="#298C52">return</FONT> (dev-&gt;drv[drvidx]-&gt;interface-&gt;
writecmd(buf, count, 1, drvidx, <A HREF="#isdn_minor2chan">isdn_minor2chan</A>(minor)));
<FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> count;
}
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">if</FONT> (minor &lt;= <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_PPPMAX">ISDN_MINOR_PPPMAX</A>)
<FONT COLOR="#298C52">return</FONT> (<A HREF="isdn_ppp.c.shtml#isdn_ppp_write">isdn_ppp_write</A>(minor - <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_PPP">ISDN_MINOR_PPP</A>, file, buf, count));
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">return</FONT> -ENODEV;
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_poll">isdn_poll</A>(<FONT COLOR="#298C52">struct</FONT> file *file, poll_table * wait)
{
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">int</FONT> mask = 0;
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">int</FONT> minor = MINOR(file-&gt;f_dentry-&gt;d_inode-&gt;i_rdev);
<FONT COLOR="#298C52">int</FONT> drvidx = <A HREF="#isdn_minor2drv">isdn_minor2drv</A>(minor - <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRL">ISDN_MINOR_CTRL</A>);
<FONT COLOR="#298C52">if</FONT> (minor == <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_STATUS">ISDN_MINOR_STATUS</A>) {
<A HREF="../includes/isdn.h.shtml#poll_wait">poll_wait</A>(file, &amp;(dev-&gt;info_waitq), wait);
<FONT COLOR=#0000FF>/* mask = POLLOUT | POLLWRNORM; */</FONT>
<FONT COLOR="#298C52">if</FONT> (file-&gt;private_data) {
mask |= POLLIN | POLLRDNORM;
}
<FONT COLOR="#298C52">return</FONT> mask;
}
<FONT COLOR="#298C52">if</FONT> (minor &gt;= <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRL">ISDN_MINOR_CTRL</A> &amp;&amp; minor &lt;= <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRLMAX">ISDN_MINOR_CTRLMAX</A>) {
<A HREF="../includes/isdn.h.shtml#poll_wait">poll_wait</A>(file, &amp;(dev-&gt;drv[drvidx]-&gt;st_waitq), wait);
<FONT COLOR="#298C52">if</FONT> (drvidx &lt; 0) {
printk(KERN_ERR <FONT COLOR="#FF0000">"isdn_common: isdn_poll 1 -&gt; what the hell\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> POLLERR;
}
mask = POLLOUT | POLLWRNORM;
<FONT COLOR="#298C52">if</FONT> (dev-&gt;drv[drvidx]-&gt;stavail) {
mask |= POLLIN | POLLRDNORM;
}
<FONT COLOR="#298C52">return</FONT> mask;
}
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">if</FONT> (minor &lt;= <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_PPPMAX">ISDN_MINOR_PPPMAX</A>)
<FONT COLOR="#298C52">return</FONT> (<A HREF="isdn_ppp.c.shtml#isdn_ppp_poll">isdn_ppp_poll</A>(file, wait));
<FONT COLOR=#A521F7>#endif</FONT>
printk(KERN_ERR <FONT COLOR="#FF0000">"isdn_common: isdn_poll 2 -&gt; what the hell\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> POLLERR;
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A HREF="#isdn_ioctl">isdn_ioctl</A>(<FONT COLOR="#298C52">struct</FONT> inode *inode, <FONT COLOR="#298C52">struct</FONT> file *file, uint cmd, ulong arg)
{
uint minor = MINOR(inode-&gt;i_rdev);
<A HREF="../includes/isdnif.h.shtml#isdn_ctrl">isdn_ctrl</A> c;
<FONT COLOR="#298C52">int</FONT> drvidx;
<FONT COLOR="#298C52">int</FONT> chidx;
<FONT COLOR="#298C52">int</FONT> ret;
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">char</FONT> *p;
<FONT COLOR="#298C52">char</FONT> *s;
<FONT COLOR="#298C52">union</FONT> iocpar {
<FONT COLOR="#298C52">char</FONT> <A HREF="#name">name</A>[10];
<FONT COLOR="#298C52">char</FONT> <A HREF="#bname">bname</A>[22];
<A HREF="../includes/isdn.h.shtml#isdn_ioctl_struct">isdn_ioctl_struct</A> <A HREF="#iocts">iocts</A>;
<A HREF="../includes/isdn.h.shtml#isdn_net_ioctl_phone">isdn_net_ioctl_phone</A> <A HREF="#phone">phone</A>;
<A HREF="../includes/isdn.h.shtml#isdn_net_ioctl_cfg">isdn_net_ioctl_cfg</A> <A HREF="#cfg">cfg</A>;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_TIMEOUT_RULES
<A HREF="../includes/isdn_timru.h.shtml#isdn_ioctl_timeout_rule">isdn_ioctl_timeout_rule</A> <A HREF="#timru">timru</A>;
<FONT COLOR=#A521F7>#endif</FONT> <FONT COLOR=#0000FF>/* CONFIG_ISDN_TIMEOUT_RULES */</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_BUDGET
<A HREF="../includes/isdn_budget.h.shtml#isdn_ioctl_budget">isdn_ioctl_budget</A> <A HREF="#budget">budget</A>;
<FONT COLOR=#A521F7>#endif</FONT> <FONT COLOR=#0000FF>/* CONFIG_ISDN_BUDGET */</FONT>
} iocpar;
<FONT COLOR=#A521F7>#define</FONT> <A NAME="name">name</A> iocpar.<A NAME="name">name</A>
<FONT COLOR=#A521F7>#define</FONT> <A NAME="bname">bname</A> iocpar.<A NAME="bname">bname</A>
<FONT COLOR=#A521F7>#define</FONT> <A NAME="iocts">iocts</A> iocpar.<A NAME="iocts">iocts</A>
<FONT COLOR=#A521F7>#define</FONT> <A NAME="phone">phone</A> iocpar.<A NAME="phone">phone</A>
<FONT COLOR=#A521F7>#define</FONT> <A NAME="cfg">cfg</A> iocpar.<A NAME="cfg">cfg</A>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_TIMEOUT_RULES
<FONT COLOR=#A521F7># define</FONT> <A NAME="timru">timru</A> iocpar.<A NAME="timru">timru</A>
<FONT COLOR=#A521F7>#endif</FONT> <FONT COLOR=#0000FF>/* CONFIG_ISDN_TIMEOUT_RULES */</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_BUDGET
<FONT COLOR=#A521F7># define</FONT> <A NAME="budget">budget</A> iocpar.<A NAME="budget">budget</A>
<FONT COLOR=#A521F7>#endif</FONT> <FONT COLOR=#0000FF>/* CONFIG_ISDN_BUDGET */</FONT>
<FONT COLOR="#298C52">if</FONT> (minor == <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_STATUS">ISDN_MINOR_STATUS</A>) {
<FONT COLOR="#298C52">switch</FONT> (cmd) {
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCGETDVR">IIOCGETDVR</A>:
<FONT COLOR="#298C52">return</FONT> (<A HREF="../includes/isdn.h.shtml#TTY_DV">TTY_DV</A> +
(<A HREF="../includes/isdn.h.shtml#NET_DV">NET_DV</A> &lt;&lt; 8) +
(<A HREF="../includes/isdn.h.shtml#INF_DV">INF_DV</A> &lt;&lt; 16));
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCGETCPS">IIOCGETCPS</A>:
<FONT COLOR="#298C52">if</FONT> (arg) {
ulong *p = (ulong *) arg;
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">if</FONT> ((ret = verify_area(VERIFY_WRITE, (<FONT COLOR="#298C52">void</FONT> *) arg,
<FONT COLOR="#298C52">sizeof</FONT>(ulong) * <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A> * 2)))
<FONT COLOR="#298C52">return</FONT> ret;
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
put_user(dev-&gt;ibytes[i], p++);
put_user(dev-&gt;obytes[i], p++);
}
<FONT COLOR="#298C52">return</FONT> 0;
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">default</FONT>:
<FONT COLOR="#298C52">return</FONT> -EINVAL;
}
}
<FONT COLOR="#298C52">if</FONT> (!dev-&gt;drivers)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
<FONT COLOR="#298C52">if</FONT> (minor &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRL">ISDN_MINOR_CTRL</A>) {
drvidx = <A HREF="#isdn_minor2drv">isdn_minor2drv</A>(minor);
<FONT COLOR="#298C52">if</FONT> (drvidx &lt; 0)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
chidx = <A HREF="#isdn_minor2chan">isdn_minor2chan</A>(minor);
<FONT COLOR="#298C52">if</FONT> (!dev-&gt;drv[drvidx]-&gt;running)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">if</FONT> (minor &lt;= <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRLMAX">ISDN_MINOR_CTRLMAX</A>) {
<FONT COLOR=#0000FF>/*
* 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.
*/</FONT>
<FONT COLOR="#298C52">switch</FONT> (cmd) {
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_NETDEVICES
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETAIF">IIOCNETAIF</A>:
<FONT COLOR=#0000FF>/* Add a network-interface */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">if</FONT> (copy_from_user(<A HREF="#name">name</A>, (<FONT COLOR="#298C52">char</FONT> *) arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#name">name</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
s = <A HREF="#name">name</A>;
} <FONT COLOR="#298C52">else</FONT> {
s = NULL;
}
ret = down_interruptible(&amp;dev-&gt;sem);
<FONT COLOR="#298C52">if</FONT>( ret ) <FONT COLOR="#298C52">return</FONT> ret;
<FONT COLOR="#298C52">if</FONT> ((s = <A HREF="isdn_net.c.shtml#isdn_net_new">isdn_net_new</A>(s, NULL))) {
<FONT COLOR="#298C52">if</FONT> (copy_to_user((<FONT COLOR="#298C52">char</FONT> *) arg, s, strlen(s) + 1)){
ret = -EFAULT;
} <FONT COLOR="#298C52">else</FONT> {
ret = 0;
}
} <FONT COLOR="#298C52">else</FONT>
ret = -ENODEV;
up(&amp;dev-&gt;sem);
<FONT COLOR="#298C52">return</FONT> ret;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETASL">IIOCNETASL</A>:
<FONT COLOR=#0000FF>/* Add a slave to a network-interface */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">if</FONT> (copy_from_user(<A HREF="#bname">bname</A>, (<FONT COLOR="#298C52">char</FONT> *) arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#bname">bname</A>) - 1))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
ret = down_interruptible(&amp;dev-&gt;sem);
<FONT COLOR="#298C52">if</FONT>( ret ) <FONT COLOR="#298C52">return</FONT> ret;
<FONT COLOR="#298C52">if</FONT> ((s = <A HREF="isdn_net.c.shtml#isdn_net_newslave">isdn_net_newslave</A>(<A HREF="#bname">bname</A>))) {
<FONT COLOR="#298C52">if</FONT> (copy_to_user((<FONT COLOR="#298C52">char</FONT> *) arg, s, strlen(s) + 1)){
ret = -EFAULT;
} <FONT COLOR="#298C52">else</FONT> {
ret = 0;
}
} <FONT COLOR="#298C52">else</FONT>
ret = -ENODEV;
up(&amp;dev-&gt;sem);
<FONT COLOR="#298C52">return</FONT> ret;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETDIF">IIOCNETDIF</A>:
<FONT COLOR=#0000FF>/* Delete a network-interface */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">if</FONT> (copy_from_user(<A HREF="#name">name</A>, (<FONT COLOR="#298C52">char</FONT> *) arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#name">name</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
ret = down_interruptible(&amp;dev-&gt;sem);
<FONT COLOR="#298C52">if</FONT>( ret ) <FONT COLOR="#298C52">return</FONT> ret;
ret = <A HREF="isdn_net.c.shtml#isdn_net_rm">isdn_net_rm</A>(<A HREF="#name">name</A>);
up(&amp;dev-&gt;sem);
<FONT COLOR="#298C52">return</FONT> ret;
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETSCF">IIOCNETSCF</A>:
<FONT COLOR=#0000FF>/* Set configurable parameters of a network-interface */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">if</FONT> (copy_from_user((<FONT COLOR="#298C52">char</FONT> *) &amp;<A HREF="#cfg">cfg</A>, (<FONT COLOR="#298C52">char</FONT> *) arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#cfg">cfg</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">return</FONT> <A HREF="isdn_net.c.shtml#isdn_net_setcfg">isdn_net_setcfg</A>(&amp;<A HREF="#cfg">cfg</A>);
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETGCF">IIOCNETGCF</A>:
<FONT COLOR=#0000FF>/* Get configurable parameters of a network-interface */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">if</FONT> (copy_from_user((<FONT COLOR="#298C52">char</FONT> *) &amp;<A HREF="#cfg">cfg</A>, (<FONT COLOR="#298C52">char</FONT> *) arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#cfg">cfg</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">if</FONT> (!(ret = <A HREF="isdn_net.c.shtml#isdn_net_getcfg">isdn_net_getcfg</A>(&amp;<A HREF="#cfg">cfg</A>))) {
<FONT COLOR="#298C52">if</FONT> (copy_to_user((<FONT COLOR="#298C52">char</FONT> *) arg, (<FONT COLOR="#298C52">char</FONT> *) &amp;<A HREF="#cfg">cfg</A>, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#cfg">cfg</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
}
<FONT COLOR="#298C52">return</FONT> ret;
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETANM">IIOCNETANM</A>:
<FONT COLOR=#0000FF>/* Add a phone-number to a network-interface */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">if</FONT> (copy_from_user((<FONT COLOR="#298C52">char</FONT> *) &amp;<A HREF="#phone">phone</A>, (<FONT COLOR="#298C52">char</FONT> *) arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#phone">phone</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
ret = down_interruptible(&amp;dev-&gt;sem);
<FONT COLOR="#298C52">if</FONT>( ret ) <FONT COLOR="#298C52">return</FONT> ret;
ret = <A HREF="isdn_net.c.shtml#isdn_net_addphone">isdn_net_addphone</A>(&amp;<A HREF="#phone">phone</A>);
up(&amp;dev-&gt;sem);
<FONT COLOR="#298C52">return</FONT> ret;
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETGNM">IIOCNETGNM</A>:
<FONT COLOR=#0000FF>/* Get list of phone-numbers of a network-interface */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">if</FONT> (copy_from_user((<FONT COLOR="#298C52">char</FONT> *) &amp;<A HREF="#phone">phone</A>, (<FONT COLOR="#298C52">char</FONT> *) arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#phone">phone</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
ret = down_interruptible(&amp;dev-&gt;sem);
<FONT COLOR="#298C52">if</FONT>( ret ) <FONT COLOR="#298C52">return</FONT> ret;
ret = <A HREF="isdn_net.c.shtml#isdn_net_getphones">isdn_net_getphones</A>(&amp;<A HREF="#phone">phone</A>, (<FONT COLOR="#298C52">char</FONT> *) arg);
up(&amp;dev-&gt;sem);
<FONT COLOR="#298C52">return</FONT> ret;
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETDNM">IIOCNETDNM</A>:
<FONT COLOR=#0000FF>/* Delete a phone-number of a network-interface */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">if</FONT> (copy_from_user((<FONT COLOR="#298C52">char</FONT> *) &amp;<A HREF="#phone">phone</A>, (<FONT COLOR="#298C52">char</FONT> *) arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#phone">phone</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
ret = down_interruptible(&amp;dev-&gt;sem);
<FONT COLOR="#298C52">if</FONT>( ret ) <FONT COLOR="#298C52">return</FONT> ret;
ret = <A HREF="isdn_net.c.shtml#isdn_net_delphone">isdn_net_delphone</A>(&amp;<A HREF="#phone">phone</A>);
up(&amp;dev-&gt;sem);
<FONT COLOR="#298C52">return</FONT> ret;
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETDIL">IIOCNETDIL</A>:
<FONT COLOR=#0000FF>/* Force dialing of a network-interface */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">if</FONT> (copy_from_user(<A HREF="#name">name</A>, (<FONT COLOR="#298C52">char</FONT> *) arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#name">name</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">return</FONT> <A HREF="isdn_net.c.shtml#isdn_net_force_dial">isdn_net_force_dial</A>(<A HREF="#name">name</A>);
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETALN">IIOCNETALN</A>:
<FONT COLOR="#298C52">if</FONT> (!arg)
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">if</FONT> (copy_from_user(<A HREF="#name">name</A>, (<FONT COLOR="#298C52">char</FONT> *) arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#name">name</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">return</FONT> <A HREF="isdn_ppp.c.shtml#isdn_ppp_dial_slave">isdn_ppp_dial_slave</A>(<A HREF="#name">name</A>);
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETDLN">IIOCNETDLN</A>:
<FONT COLOR="#298C52">if</FONT> (!arg)
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">if</FONT> (copy_from_user(<A HREF="#name">name</A>, (<FONT COLOR="#298C52">char</FONT> *) arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#name">name</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">return</FONT> <A HREF="isdn_ppp.c.shtml#isdn_ppp_hangup_slave">isdn_ppp_hangup_slave</A>(<A HREF="#name">name</A>);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETHUP">IIOCNETHUP</A>:
<FONT COLOR=#0000FF>/* Force hangup of a network-interface */</FONT>
<FONT COLOR="#298C52">if</FONT> (!arg)
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">if</FONT> (copy_from_user(<A HREF="#name">name</A>, (<FONT COLOR="#298C52">char</FONT> *) arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#name">name</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">return</FONT> <A HREF="isdn_net.c.shtml#isdn_net_force_hangup">isdn_net_force_hangup</A>(<A HREF="#name">name</A>);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_TIMEOUT_RULES
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETARU">IIOCNETARU</A>:
<FONT COLOR=#0000FF>/* Add a rule to a network-interface */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">if</FONT>(copy_from_user((<FONT COLOR="#298C52">char</FONT> *) &amp;<A HREF="#timru">timru</A>, (<FONT COLOR="#298C52">char</FONT> *) arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#timru">timru</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">return</FONT>(<A HREF="isdn_timru.c.shtml#isdn_timru_ioctl_add_rule">isdn_timru_ioctl_add_rule</A>(&amp;<A HREF="#timru">timru</A>));
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT>(-EINVAL);
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETDRU">IIOCNETDRU</A>:
<FONT COLOR=#0000FF>/* Delete a rule from a network-interface */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">if</FONT>(copy_from_user((<FONT COLOR="#298C52">char</FONT> *) &amp;<A HREF="#timru">timru</A>, (<FONT COLOR="#298C52">char</FONT> *) arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#timru">timru</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">return</FONT>(<A HREF="isdn_timru.c.shtml#isdn_timru_ioctl_del_rule">isdn_timru_ioctl_del_rule</A>(&amp;<A HREF="#timru">timru</A>));
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT>(-EINVAL);
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETGRU">IIOCNETGRU</A>:
<FONT COLOR=#0000FF>/* Get a rule of a network-interface */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">if</FONT>(copy_from_user((<FONT COLOR="#298C52">char</FONT> *)&amp;<A HREF="#timru">timru</A>, (<FONT COLOR="#298C52">char</FONT> *)arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#timru">timru</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">if</FONT>((ret = <A HREF="isdn_timru.c.shtml#isdn_timru_ioctl_get_rule">isdn_timru_ioctl_get_rule</A>(&amp;<A HREF="#timru">timru</A>)))
<FONT COLOR="#298C52">return</FONT>(ret);
<FONT COLOR="#298C52">if</FONT>(copy_to_user((<FONT COLOR="#298C52">char</FONT> *)arg, (<FONT COLOR="#298C52">char</FONT> *)&amp;<A HREF="#timru">timru</A>, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#timru">timru</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">return</FONT>(0);
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT>(-EINVAL);
<FONT COLOR=#A521F7>#endif</FONT> <FONT COLOR=#0000FF>/* CONFIG_ISDN_TIMEOUT_RULES */</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_BUDGET
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCNETBUD">IIOCNETBUD</A>:
<FONT COLOR=#0000FF>/* handle budget-accounting of a network-interface */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">if</FONT>(copy_from_user((<FONT COLOR="#298C52">char</FONT> *)&amp;<A HREF="#budget">budget</A>, (<FONT COLOR="#298C52">char</FONT> *)arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#budget">budget</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">if</FONT>((ret = <A HREF="isdn_budget.c.shtml#isdn_budget_ioctl">isdn_budget_ioctl</A>(&amp;<A HREF="#budget">budget</A>)))
<FONT COLOR="#298C52">return</FONT>(ret);
<FONT COLOR="#298C52">if</FONT>(copy_to_user((<FONT COLOR="#298C52">char</FONT> *)arg, (<FONT COLOR="#298C52">char</FONT> *)&amp;<A HREF="#budget">budget</A>, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="#budget">budget</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">return</FONT>(0);
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT>(-EINVAL);
<FONT COLOR=#A521F7>#endif</FONT> <FONT COLOR=#0000FF>/* CONFIG_ISDN_BUDGET */</FONT>
<FONT COLOR=#A521F7>#endif</FONT> <FONT COLOR=#0000FF>/* CONFIG_NETDEVICES */</FONT>
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCSETVER">IIOCSETVER</A>:
dev-&gt;net_verbose = arg;
printk(KERN_INFO <FONT COLOR="#FF0000">"isdn: Verbose-Level is %d\n"</FONT>, dev-&gt;net_verbose);
<FONT COLOR="#298C52">return</FONT> 0;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCSETGST">IIOCSETGST</A>:
<FONT COLOR="#298C52">if</FONT> (arg)
dev-&gt;global_flags |= <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A>;
<FONT COLOR="#298C52">else</FONT>
dev-&gt;global_flags &amp;= ~<A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A>;
printk(KERN_INFO <FONT COLOR="#FF0000">"isdn: Global Mode %s\n"</FONT>,
(dev-&gt;global_flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A>) ? <FONT COLOR="#FF0000">"stopped"</FONT> : <FONT COLOR="#FF0000">"running"</FONT>);
<FONT COLOR="#298C52">return</FONT> 0;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCSETBRJ">IIOCSETBRJ</A>:
drvidx = -1;
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">char</FONT> *p;
<FONT COLOR="#298C52">if</FONT> (copy_from_user((<FONT COLOR="#298C52">char</FONT> *) &amp;<A HREF="#iocts">iocts</A>, (<FONT COLOR="#298C52">char</FONT> *) arg,
<FONT COLOR="#298C52">sizeof</FONT>(<A HREF="../includes/isdn.h.shtml#isdn_ioctl_struct">isdn_ioctl_struct</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">if</FONT> (strlen(<A HREF="#iocts">iocts</A>.drvid)) {
<FONT COLOR="#298C52">if</FONT> ((p = strchr(<A HREF="#iocts">iocts</A>.drvid, <FONT COLOR="#FF0000">','</FONT>)))
*p = 0;
drvidx = -1;
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>; i++)
<FONT COLOR="#298C52">if</FONT> (!(strcmp(dev-&gt;drvid[i], <A HREF="#iocts">iocts</A>.drvid))) {
drvidx = i;
<FONT COLOR="#298C52">break</FONT>;
}
}
}
<FONT COLOR="#298C52">if</FONT> (drvidx == -1)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
dev-&gt;drv[drvidx]-&gt;reject_bus = <A HREF="#iocts">iocts</A>.arg;
<FONT COLOR="#298C52">return</FONT> 0;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCSIGPRF">IIOCSIGPRF</A>:
dev-&gt;profd = current;
<FONT COLOR="#298C52">return</FONT> 0;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCGETPRF">IIOCGETPRF</A>:
<FONT COLOR=#0000FF>/* Get all Modem-Profiles */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">char</FONT> *p = (<FONT COLOR="#298C52">char</FONT> *) arg;
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">if</FONT> ((ret = verify_area(VERIFY_WRITE, (<FONT COLOR="#298C52">void</FONT> *) arg,
(<A HREF="../includes/isdn.h.shtml#ISDN_MODEM_ANZREG">ISDN_MODEM_ANZREG</A> + <A HREF="../includes/isdn.h.shtml#ISDN_MSNLEN">ISDN_MSNLEN</A> + <A HREF="../includes/isdn.h.shtml#ISDN_LMSNLEN">ISDN_LMSNLEN</A>)
* <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>)))
<FONT COLOR="#298C52">return</FONT> ret;
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
<FONT COLOR="#298C52">if</FONT> (copy_to_user(p, dev-&gt;mdm.info[i].emu.profile,
<A HREF="../includes/isdn.h.shtml#ISDN_MODEM_ANZREG">ISDN_MODEM_ANZREG</A>))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
p += <A HREF="../includes/isdn.h.shtml#ISDN_MODEM_ANZREG">ISDN_MODEM_ANZREG</A>;
<FONT COLOR="#298C52">if</FONT> (copy_to_user(p, dev-&gt;mdm.info[i].emu.pmsn, <A HREF="../includes/isdn.h.shtml#ISDN_MSNLEN">ISDN_MSNLEN</A>))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
p += <A HREF="../includes/isdn.h.shtml#ISDN_MSNLEN">ISDN_MSNLEN</A>;
<FONT COLOR="#298C52">if</FONT> (copy_to_user(p, dev-&gt;mdm.info[i].emu.plmsn, <A HREF="../includes/isdn.h.shtml#ISDN_LMSNLEN">ISDN_LMSNLEN</A>))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
p += <A HREF="../includes/isdn.h.shtml#ISDN_LMSNLEN">ISDN_LMSNLEN</A>;
}
<FONT COLOR="#298C52">return</FONT> (<A HREF="../includes/isdn.h.shtml#ISDN_MODEM_ANZREG">ISDN_MODEM_ANZREG</A> + <A HREF="../includes/isdn.h.shtml#ISDN_MSNLEN">ISDN_MSNLEN</A> + <A HREF="../includes/isdn.h.shtml#ISDN_LMSNLEN">ISDN_LMSNLEN</A>) * <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>;
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCSETPRF">IIOCSETPRF</A>:
<FONT COLOR=#0000FF>/* Set all Modem-Profiles */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">char</FONT> *p = (<FONT COLOR="#298C52">char</FONT> *) arg;
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">if</FONT> ((ret = verify_area(VERIFY_READ, (<FONT COLOR="#298C52">void</FONT> *) arg,
(<A HREF="../includes/isdn.h.shtml#ISDN_MODEM_ANZREG">ISDN_MODEM_ANZREG</A> + <A HREF="../includes/isdn.h.shtml#ISDN_MSNLEN">ISDN_MSNLEN</A>)
* <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>)))
<FONT COLOR="#298C52">return</FONT> ret;
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
<FONT COLOR="#298C52">if</FONT> (copy_from_user(dev-&gt;mdm.info[i].emu.profile, p,
<A HREF="../includes/isdn.h.shtml#ISDN_MODEM_ANZREG">ISDN_MODEM_ANZREG</A>))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
p += <A HREF="../includes/isdn.h.shtml#ISDN_MODEM_ANZREG">ISDN_MODEM_ANZREG</A>;
<FONT COLOR="#298C52">if</FONT> (copy_from_user(dev-&gt;mdm.info[i].emu.pmsn, p, <A HREF="../includes/isdn.h.shtml#ISDN_MSNLEN">ISDN_MSNLEN</A>))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
p += <A HREF="../includes/isdn.h.shtml#ISDN_MSNLEN">ISDN_MSNLEN</A>;
}
<FONT COLOR="#298C52">return</FONT> 0;
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCSETMAP">IIOCSETMAP</A>:
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCGETMAP">IIOCGETMAP</A>:
<FONT COLOR=#0000FF>/* Set/Get MSN-&gt;EAZ-Mapping for a driver */</FONT>
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">if</FONT> (copy_from_user((<FONT COLOR="#298C52">char</FONT> *) &amp;<A HREF="#iocts">iocts</A>,
(<FONT COLOR="#298C52">char</FONT> *) arg,
<FONT COLOR="#298C52">sizeof</FONT>(<A HREF="../includes/isdn.h.shtml#isdn_ioctl_struct">isdn_ioctl_struct</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">if</FONT> (strlen(<A HREF="#iocts">iocts</A>.drvid)) {
drvidx = -1;
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>; i++)
<FONT COLOR="#298C52">if</FONT> (!(strcmp(dev-&gt;drvid[i], <A HREF="#iocts">iocts</A>.drvid))) {
drvidx = i;
<FONT COLOR="#298C52">break</FONT>;
}
} <FONT COLOR="#298C52">else</FONT>
drvidx = 0;
<FONT COLOR="#298C52">if</FONT> (drvidx == -1)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
<FONT COLOR="#298C52">if</FONT> (cmd == <A HREF="../includes/isdn.h.shtml#IIOCSETMAP">IIOCSETMAP</A>) {
<FONT COLOR="#298C52">int</FONT> loop = 1;
p = (<FONT COLOR="#298C52">char</FONT> *) <A HREF="#iocts">iocts</A>.arg;
i = 0;
<FONT COLOR="#298C52">while</FONT> (loop) {
<FONT COLOR="#298C52">int</FONT> j = 0;
<FONT COLOR="#298C52">while</FONT> (1) {
<FONT COLOR="#298C52">if</FONT> ((ret = verify_area(VERIFY_READ, p, 1)))
<FONT COLOR="#298C52">return</FONT> ret;
get_user(<A HREF="#bname">bname</A>[j], p++);
<FONT COLOR="#298C52">switch</FONT> (<A HREF="#bname">bname</A>[j]) {
<FONT COLOR="#298C52">case</FONT> <FONT COLOR="#FF0000">'\0'</FONT>:
loop = 0;
<FONT COLOR=#0000FF>/* Fall through */</FONT>
<FONT COLOR="#298C52">case</FONT> <FONT COLOR="#FF0000">','</FONT>:
<A HREF="#bname">bname</A>[j] = <FONT COLOR="#FF0000">'\0'</FONT>;
strcpy(dev-&gt;drv[drvidx]-&gt;msn2eaz[i], <A HREF="#bname">bname</A>);
j = <A HREF="../includes/isdn.h.shtml#ISDN_MSNLEN">ISDN_MSNLEN</A>;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">default</FONT>:
j++;
}
<FONT COLOR="#298C52">if</FONT> (j &gt;= <A HREF="../includes/isdn.h.shtml#ISDN_MSNLEN">ISDN_MSNLEN</A>)
<FONT COLOR="#298C52">break</FONT>;
}
<FONT COLOR="#298C52">if</FONT> (++i &gt; 9)
<FONT COLOR="#298C52">break</FONT>;
}
} <FONT COLOR="#298C52">else</FONT> {
p = (<FONT COLOR="#298C52">char</FONT> *) <A HREF="#iocts">iocts</A>.arg;
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; 10; i++) {
sprintf(<A HREF="#bname">bname</A>, <FONT COLOR="#FF0000">"%s%s"</FONT>,
strlen(dev-&gt;drv[drvidx]-&gt;msn2eaz[i]) ?
dev-&gt;drv[drvidx]-&gt;msn2eaz[i] : <FONT COLOR="#FF0000">"-"</FONT>,
(i &lt; 9) ? <FONT COLOR="#FF0000">","</FONT> : <FONT COLOR="#FF0000">"\0"</FONT>);
<FONT COLOR="#298C52">if</FONT> (copy_to_user(p, <A HREF="#bname">bname</A>, strlen(<A HREF="#bname">bname</A>) + 1))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
p += strlen(<A HREF="#bname">bname</A>);
}
}
<FONT COLOR="#298C52">return</FONT> 0;
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#IIOCDBGVAR">IIOCDBGVAR</A>:
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">if</FONT> (copy_to_user((<FONT COLOR="#298C52">char</FONT> *) arg, (<FONT COLOR="#298C52">char</FONT> *) &amp;dev, <FONT COLOR="#298C52">sizeof</FONT>(ulong)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">return</FONT> 0;
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">default</FONT>:
<FONT COLOR="#298C52">if</FONT> ((cmd &amp; <A HREF="../includes/isdn.h.shtml#IIOCDRVCTL">IIOCDRVCTL</A>) == <A HREF="../includes/isdn.h.shtml#IIOCDRVCTL">IIOCDRVCTL</A>)
cmd = ((cmd &gt;&gt; _IOC_NRSHIFT) &amp; _IOC_NRMASK) &amp; <A HREF="../includes/isdn.h.shtml#ISDN_DRVIOCTL_MASK">ISDN_DRVIOCTL_MASK</A>;
<FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">if</FONT> (arg) {
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">char</FONT> *p;
<FONT COLOR="#298C52">if</FONT> (copy_from_user((<FONT COLOR="#298C52">char</FONT> *) &amp;<A HREF="#iocts">iocts</A>, (<FONT COLOR="#298C52">char</FONT> *) arg, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="../includes/isdn.h.shtml#isdn_ioctl_struct">isdn_ioctl_struct</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">if</FONT> (strlen(<A HREF="#iocts">iocts</A>.drvid)) {
<FONT COLOR="#298C52">if</FONT> ((p = strchr(<A HREF="#iocts">iocts</A>.drvid, <FONT COLOR="#FF0000">','</FONT>)))
*p = 0;
drvidx = -1;
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>; i++)
<FONT COLOR="#298C52">if</FONT> (!(strcmp(dev-&gt;drvid[i], <A HREF="#iocts">iocts</A>.drvid))) {
drvidx = i;
<FONT COLOR="#298C52">break</FONT>;
}
} <FONT COLOR="#298C52">else</FONT>
drvidx = 0;
<FONT COLOR="#298C52">if</FONT> (drvidx == -1)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
<FONT COLOR="#298C52">if</FONT> ((ret = verify_area(VERIFY_WRITE, (<FONT COLOR="#298C52">void</FONT> *) arg,
<FONT COLOR="#298C52">sizeof</FONT>(<A HREF="../includes/isdn.h.shtml#isdn_ioctl_struct">isdn_ioctl_struct</A>))))
<FONT COLOR="#298C52">return</FONT> ret;
c.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = drvidx;
c.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_IOCTL">ISDN_CMD_IOCTL</A>;
c.arg = cmd;
memcpy(c.parm.num, (<FONT COLOR="#298C52">char</FONT> *) &amp;<A HREF="#iocts">iocts</A>.arg, <FONT COLOR="#298C52">sizeof</FONT>(ulong));
ret = <A HREF="#isdn_command">isdn_command</A>(&amp;c);
memcpy((<FONT COLOR="#298C52">char</FONT> *) &amp;<A HREF="#iocts">iocts</A>.arg, c.parm.num, <FONT COLOR="#298C52">sizeof</FONT>(ulong));
<FONT COLOR="#298C52">if</FONT> (copy_to_user((<FONT COLOR="#298C52">char</FONT> *) arg, &amp;<A HREF="#iocts">iocts</A>, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="../includes/isdn.h.shtml#isdn_ioctl_struct">isdn_ioctl_struct</A>)))
<FONT COLOR="#298C52">return</FONT> -EFAULT;
<FONT COLOR="#298C52">return</FONT> ret;
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
}
}
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">if</FONT> (minor &lt;= <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_PPPMAX">ISDN_MINOR_PPPMAX</A>)
<FONT COLOR="#298C52">return</FONT> (<A HREF="isdn_ppp.c.shtml#isdn_ppp_ioctl">isdn_ppp_ioctl</A>(minor - <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_PPP">ISDN_MINOR_PPP</A>, file, cmd, arg));
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">return</FONT> -ENODEV;
<FONT COLOR=#A521F7>#undef</FONT> <A HREF="#name">name</A>
<FONT COLOR=#A521F7>#undef</FONT> <A HREF="#bname">bname</A>
<FONT COLOR=#A521F7>#undef</FONT> <A HREF="#iocts">iocts</A>
<FONT COLOR=#A521F7>#undef</FONT> <A HREF="#phone">phone</A>
<FONT COLOR=#A521F7>#undef</FONT> <A HREF="#cfg">cfg</A>
}
<FONT COLOR=#0000FF>/*
* Open the device code.
* MOD_INC_USE_COUNT make sure that the driver memory is not freed
* while the device is in use.
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_open">isdn_open</A>(<FONT COLOR="#298C52">struct</FONT> inode *ino, <FONT COLOR="#298C52">struct</FONT> file *filep)
{
uint minor = MINOR(ino-&gt;i_rdev);
<FONT COLOR="#298C52">int</FONT> drvidx;
<FONT COLOR="#298C52">int</FONT> chidx;
<A HREF="../includes/isdnif.h.shtml#isdn_ctrl">isdn_ctrl</A> c;
<FONT COLOR="#298C52">if</FONT> (minor == <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_STATUS">ISDN_MINOR_STATUS</A>) {
<A HREF="../includes/isdn.h.shtml#infostruct">infostruct</A> *p;
<FONT COLOR="#298C52">if</FONT> ((p = (<A HREF="../includes/isdn.h.shtml#infostruct">infostruct</A> *) kmalloc(<FONT COLOR="#298C52">sizeof</FONT>(<A HREF="../includes/isdn.h.shtml#infostruct">infostruct</A>), GFP_KERNEL))) {
MOD_INC_USE_COUNT;
p-&gt;next = (<FONT COLOR="#298C52">char</FONT> *) dev-&gt;infochain;
p-&gt;<FONT COLOR="#298C52">private</FONT> = (<FONT COLOR="#298C52">char</FONT> *) &amp;(filep-&gt;private_data);
dev-&gt;infochain = p;
<FONT COLOR=#0000FF>/* At opening we allow a single update */</FONT>
filep-&gt;private_data = (<FONT COLOR="#298C52">char</FONT> *) 1;
<FONT COLOR="#298C52">return</FONT> 0;
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -ENOMEM;
}
<FONT COLOR="#298C52">if</FONT> (!dev-&gt;channels)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
<FONT COLOR="#298C52">if</FONT> (minor &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRL">ISDN_MINOR_CTRL</A>) {
drvidx = <A HREF="#isdn_minor2drv">isdn_minor2drv</A>(minor);
<FONT COLOR="#298C52">if</FONT> (drvidx &lt; 0)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
chidx = <A HREF="#isdn_minor2chan">isdn_minor2chan</A>(minor);
<FONT COLOR="#298C52">if</FONT> (!dev-&gt;drv[drvidx]-&gt;running)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
<FONT COLOR="#298C52">if</FONT> (!(dev-&gt;drv[drvidx]-&gt;flags &amp; (1 &lt;&lt; chidx)))
<FONT COLOR="#298C52">return</FONT> -ENODEV;
c.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_LOCK">ISDN_CMD_LOCK</A>;
c.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = drvidx;
<A HREF="#isdn_command">isdn_command</A>(&amp;c);
MOD_INC_USE_COUNT;
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">if</FONT> (minor &lt;= <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRLMAX">ISDN_MINOR_CTRLMAX</A>) {
drvidx = <A HREF="#isdn_minor2drv">isdn_minor2drv</A>(minor - <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRL">ISDN_MINOR_CTRL</A>);
<FONT COLOR="#298C52">if</FONT> (drvidx &lt; 0)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
c.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_LOCK">ISDN_CMD_LOCK</A>;
c.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = drvidx;
MOD_INC_USE_COUNT;
<A HREF="#isdn_command">isdn_command</A>(&amp;c);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">if</FONT> (minor &lt;= <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_PPPMAX">ISDN_MINOR_PPPMAX</A>) {
<FONT COLOR="#298C52">int</FONT> ret;
<FONT COLOR="#298C52">if</FONT> (!(ret = <A HREF="isdn_ppp.c.shtml#isdn_ppp_open">isdn_ppp_open</A>(minor - <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_PPP">ISDN_MINOR_PPP</A>, filep)))
MOD_INC_USE_COUNT;
<FONT COLOR="#298C52">return</FONT> ret;
}
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">return</FONT> -ENODEV;
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_close">isdn_close</A>(<FONT COLOR="#298C52">struct</FONT> inode *ino, <FONT COLOR="#298C52">struct</FONT> file *filep)
{
uint minor = MINOR(ino-&gt;i_rdev);
<FONT COLOR="#298C52">int</FONT> drvidx;
<A HREF="../includes/isdnif.h.shtml#isdn_ctrl">isdn_ctrl</A> c;
MOD_DEC_USE_COUNT;
<FONT COLOR="#298C52">if</FONT> (minor == <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_STATUS">ISDN_MINOR_STATUS</A>) {
<A HREF="../includes/isdn.h.shtml#infostruct">infostruct</A> *p = dev-&gt;infochain;
<A HREF="../includes/isdn.h.shtml#infostruct">infostruct</A> *q = NULL;
<FONT COLOR="#298C52">while</FONT> (p) {
<FONT COLOR="#298C52">if</FONT> (p-&gt;<FONT COLOR="#298C52">private</FONT> == (<FONT COLOR="#298C52">char</FONT> *) &amp;(filep-&gt;private_data)) {
<FONT COLOR="#298C52">if</FONT> (q)
q-&gt;next = p-&gt;next;
<FONT COLOR="#298C52">else</FONT>
dev-&gt;infochain = (<A HREF="../includes/isdn.h.shtml#infostruct">infostruct</A> *) (p-&gt;next);
kfree(p);
<FONT COLOR="#298C52">return</FONT> 0;
}
q = p;
p = (<A HREF="../includes/isdn.h.shtml#infostruct">infostruct</A> *) (p-&gt;next);
}
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn: No private data while closing isdnctrl\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">if</FONT> (minor &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRL">ISDN_MINOR_CTRL</A>) {
drvidx = <A HREF="#isdn_minor2drv">isdn_minor2drv</A>(minor);
<FONT COLOR="#298C52">if</FONT> (drvidx &lt; 0)
<FONT COLOR="#298C52">return</FONT> 0;
c.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_UNLOCK">ISDN_CMD_UNLOCK</A>;
c.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = drvidx;
<A HREF="#isdn_command">isdn_command</A>(&amp;c);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">if</FONT> (minor &lt;= <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRLMAX">ISDN_MINOR_CTRLMAX</A>) {
drvidx = <A HREF="#isdn_minor2drv">isdn_minor2drv</A>(minor - <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRL">ISDN_MINOR_CTRL</A>);
<FONT COLOR="#298C52">if</FONT> (drvidx &lt; 0)
<FONT COLOR="#298C52">return</FONT> 0;
<FONT COLOR="#298C52">if</FONT> (dev-&gt;profd == current)
dev-&gt;profd = NULL;
c.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_UNLOCK">ISDN_CMD_UNLOCK</A>;
c.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = drvidx;
<A HREF="#isdn_command">isdn_command</A>(&amp;c);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">if</FONT> (minor &lt;= <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_PPPMAX">ISDN_MINOR_PPPMAX</A>)
<A HREF="isdn_ppp.c.shtml#isdn_ppp_release">isdn_ppp_release</A>(minor - <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_PPP">ISDN_MINOR_PPP</A>, filep);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">struct</FONT> file_operations isdn_fops =
{
<A HREF="#isdn_lseek">isdn_lseek</A>,
<A HREF="#isdn_read">isdn_read</A>,
<A HREF="#isdn_write">isdn_write</A>,
NULL, <FONT COLOR=#0000FF>/* isdn_readdir */</FONT>
<A HREF="#isdn_poll">isdn_poll</A>, <FONT COLOR=#0000FF>/* isdn_poll */</FONT>
<A HREF="#isdn_ioctl">isdn_ioctl</A>, <FONT COLOR=#0000FF>/* isdn_ioctl */</FONT>
NULL, <FONT COLOR=#0000FF>/* isdn_mmap */</FONT>
<A HREF="#isdn_open">isdn_open</A>,
<A HREF="#isdn_close">isdn_close</A>,
NULL <FONT COLOR=#0000FF>/* fsync */</FONT>
};
<FONT COLOR="#298C52">char</FONT> *
<A NAME="isdn_map_eaz2msn">isdn_map_eaz2msn</A>(<FONT COLOR="#298C52">char</FONT> *msn, <FONT COLOR="#298C52">int</FONT> di)
{
<A HREF="../includes/isdn.h.shtml#driver">driver</A> *<FONT COLOR="#298C52">this</FONT> = dev-&gt;drv[di];
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">if</FONT> (strlen(msn) == 1) {
i = msn[0] - <FONT COLOR="#FF0000">'0'</FONT>;
<FONT COLOR="#298C52">if</FONT> ((i &gt;= 0) &amp;&amp; (i &lt;= 9))
<FONT COLOR="#298C52">if</FONT> (strlen(<FONT COLOR="#298C52">this</FONT>-&gt;msn2eaz[i]))
<FONT COLOR="#298C52">return</FONT> (<FONT COLOR="#298C52">this</FONT>-&gt;msn2eaz[i]);
}
<FONT COLOR="#298C52">return</FONT> (msn);
}
<FONT COLOR=#0000FF>/*
* Find an unused ISDN-channel, whose feature-flags match the
* given L2- and L3-protocols.
*/</FONT>
<FONT COLOR=#A521F7>#define</FONT> <A NAME="L2V">L2V</A> (~(<A HREF="../includes/isdnif.h.shtml#ISDN_FEATURE_L2_V11096">ISDN_FEATURE_L2_V11096</A>|<A HREF="../includes/isdnif.h.shtml#ISDN_FEATURE_L2_V11019">ISDN_FEATURE_L2_V11019</A>|<A HREF="../includes/isdnif.h.shtml#ISDN_FEATURE_L2_V11038">ISDN_FEATURE_L2_V11038</A>))
<FONT COLOR="#298C52">int</FONT>
<A HREF="#isdn_get_free_channel">isdn_get_free_channel</A>(<FONT COLOR="#298C52">int</FONT> usage, <FONT COLOR="#298C52">int</FONT> l2_proto, <FONT COLOR="#298C52">int</FONT> l3_proto, <FONT COLOR="#298C52">int</FONT> pre_dev
,<FONT COLOR="#298C52">int</FONT> pre_chan)
{
<FONT COLOR="#298C52">int</FONT> i;
ulong flags;
ulong features;
ulong vfeatures;
<A HREF="../includes/isdnif.h.shtml#isdn_ctrl">isdn_ctrl</A> cmd;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
features = ((1 &lt;&lt; l2_proto) | (0x10000 &lt;&lt; l3_proto));
vfeatures = (((1 &lt;&lt; l2_proto) | (0x10000 &lt;&lt; l3_proto)) &amp;
~(<A HREF="../includes/isdnif.h.shtml#ISDN_FEATURE_L2_V11096">ISDN_FEATURE_L2_V11096</A>|<A HREF="../includes/isdnif.h.shtml#ISDN_FEATURE_L2_V11019">ISDN_FEATURE_L2_V11019</A>|<A HREF="../includes/isdnif.h.shtml#ISDN_FEATURE_L2_V11038">ISDN_FEATURE_L2_V11038</A>));
<FONT COLOR=#0000FF>/* 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.
*/</FONT>
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++)
<FONT COLOR="#298C52">if</FONT> (<A HREF="../includes/isdn.h.shtml#USG_NONE">USG_NONE</A>(dev-&gt;usage[i]) &amp;&amp;
(dev-&gt;drvmap[i] != -1)) {
<FONT COLOR="#298C52">int</FONT> d = dev-&gt;drvmap[i];
<FONT COLOR="#298C52">if</FONT> ((dev-&gt;usage[i] &amp; <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>) &amp;&amp;
((pre_dev != d) || (pre_chan != dev-&gt;chanmap[i])))
<FONT COLOR="#298C52">continue</FONT>;
<FONT COLOR="#298C52">if</FONT> ((dev-&gt;drv[d]-&gt;running)) {
<FONT COLOR="#298C52">if</FONT> (((dev-&gt;drv[d]-&gt;interface-&gt;features &amp; features) == features) ||
(((dev-&gt;drv[d]-&gt;interface-&gt;features &amp; vfeatures) == vfeatures) &amp;&amp;
(dev-&gt;drv[d]-&gt;interface-&gt;features &amp; <A HREF="../includes/isdnif.h.shtml#ISDN_FEATURE_L2_TRANS">ISDN_FEATURE_L2_TRANS</A>))) {
<FONT COLOR="#298C52">if</FONT> ((pre_dev &lt; 0) || (pre_chan &lt; 0)) {
dev-&gt;usage[i] &amp;= <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>;
dev-&gt;usage[i] |= usage;
<A HREF="#isdn_info_update">isdn_info_update</A>();
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = d;
cmd.arg = 0;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_LOCK">ISDN_CMD_LOCK</A>;
<A HREF="#isdn_command">isdn_command</A>(&amp;cmd);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> i;
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR="#298C52">if</FONT> ((pre_dev == d) &amp;&amp; (pre_chan == dev-&gt;chanmap[i])) {
dev-&gt;usage[i] &amp;= <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>;
dev-&gt;usage[i] |= usage;
<A HREF="#isdn_info_update">isdn_info_update</A>();
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = d;
cmd.arg = 0;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_LOCK">ISDN_CMD_LOCK</A>;
<A HREF="#isdn_command">isdn_command</A>(&amp;cmd);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> i;
}
}
}
}
}
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> -1;
}
<FONT COLOR=#0000FF>/*
* Set state of ISDN-channel to 'unused'
*/</FONT>
<FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_free_channel">isdn_free_channel</A>(<FONT COLOR="#298C52">int</FONT> di, <FONT COLOR="#298C52">int</FONT> ch, <FONT COLOR="#298C52">int</FONT> usage)
{
<FONT COLOR="#298C52">int</FONT> i;
ulong flags;
<A HREF="../includes/isdnif.h.shtml#isdn_ctrl">isdn_ctrl</A> cmd;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++)
<FONT COLOR="#298C52">if</FONT> (((dev-&gt;usage[i] &amp; <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_MASK">ISDN_USAGE_MASK</A>) == usage) &amp;&amp;
(dev-&gt;drvmap[i] == di) &amp;&amp;
(dev-&gt;chanmap[i] == ch)) {
dev-&gt;usage[i] &amp;= (<A HREF="../includes/isdn.h.shtml#ISDN_USAGE_NONE">ISDN_USAGE_NONE</A> | <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>);
strcpy(dev-&gt;num[i], <FONT COLOR="#FF0000">"???"</FONT>);
dev-&gt;ibytes[i] = 0;
dev-&gt;obytes[i] = 0;
<A HREF="#isdn_info_update">isdn_info_update</A>();
<A HREF="#isdn_free_queue">isdn_free_queue</A>(&amp;dev-&gt;drv[di]-&gt;rpqueue[ch]);
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = di;
cmd.arg = ch;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_UNLOCK">ISDN_CMD_UNLOCK</A>;
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<A HREF="#isdn_command">isdn_command</A>(&amp;cmd);
<FONT COLOR="#298C52">return</FONT>;
}
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
}
<FONT COLOR=#0000FF>/*
* Cancel Exclusive-Flag for ISDN-channel
*/</FONT>
<FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_unexclusive_channel">isdn_unexclusive_channel</A>(<FONT COLOR="#298C52">int</FONT> di, <FONT COLOR="#298C52">int</FONT> ch)
{
<FONT COLOR="#298C52">int</FONT> i;
ulong flags;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++)
<FONT COLOR="#298C52">if</FONT> ((dev-&gt;drvmap[i] == di) &amp;&amp;
(dev-&gt;chanmap[i] == ch)) {
dev-&gt;usage[i] &amp;= ~<A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>;
<A HREF="#isdn_info_update">isdn_info_update</A>();
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT>;
}
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
}
<FONT COLOR=#0000FF>/*
* writebuf replacement for SKB_ABLE drivers
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A HREF="#isdn_writebuf_stub">isdn_writebuf_stub</A>(<FONT COLOR="#298C52">int</FONT> drvidx, <FONT COLOR="#298C52">int</FONT> chan, <FONT COLOR="#298C52">const</FONT> u_char * buf, <FONT COLOR="#298C52">int</FONT> len,
<FONT COLOR="#298C52">int</FONT> user)
{
<FONT COLOR="#298C52">int</FONT> ret;
<FONT COLOR="#298C52">int</FONT> hl = dev-&gt;drv[drvidx]-&gt;interface-&gt;hl_hdrlen;
<FONT COLOR="#298C52">struct</FONT> sk_buff *skb = alloc_skb(hl + len, GFP_ATOMIC);
<FONT COLOR="#298C52">if</FONT> (!skb)
<FONT COLOR="#298C52">return</FONT> 0;
skb_reserve(skb, hl);
<FONT COLOR="#298C52">if</FONT> (user)
copy_from_user(skb_put(skb, len), buf, len);
<FONT COLOR="#298C52">else</FONT>
memcpy(skb_put(skb, len), buf, len);
ret = dev-&gt;drv[drvidx]-&gt;interface-&gt;writebuf_skb(drvidx, chan, 1, skb);
<FONT COLOR="#298C52">if</FONT> (ret &lt;= 0)
dev_kfree_skb(skb);
<FONT COLOR="#298C52">if</FONT> (ret &gt; 0)
dev-&gt;obytes[<A HREF="#isdn_dc2minor">isdn_dc2minor</A>(drvidx, chan)] += ret;
<FONT COLOR="#298C52">return</FONT> ret;
}
<FONT COLOR=#0000FF>/*
* Return: length of data on success, -ERRcode on failure.
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A HREF="#isdn_writebuf_skb_stub">isdn_writebuf_skb_stub</A>(<FONT COLOR="#298C52">int</FONT> drvidx, <FONT COLOR="#298C52">int</FONT> chan, <FONT COLOR="#298C52">int</FONT> ack, <FONT COLOR="#298C52">struct</FONT> sk_buff *skb)
{
<FONT COLOR="#298C52">int</FONT> ret;
<FONT COLOR="#298C52">struct</FONT> sk_buff *nskb = NULL;
<FONT COLOR="#298C52">int</FONT> v110_ret = skb-&gt;len;
<FONT COLOR="#298C52">int</FONT> idx = <A HREF="#isdn_dc2minor">isdn_dc2minor</A>(drvidx, chan);
<FONT COLOR="#298C52">if</FONT> (dev-&gt;v110[idx]) {
atomic_inc(&amp;dev-&gt;v110use[idx]);
nskb = <A HREF="isdn_v110.c.shtml#isdn_v110_encode">isdn_v110_encode</A>(dev-&gt;v110[idx], skb);
atomic_dec(&amp;dev-&gt;v110use[idx]);
<FONT COLOR="#298C52">if</FONT> (!nskb)
<FONT COLOR="#298C52">return</FONT> 0;
v110_ret = *((<FONT COLOR="#298C52">int</FONT> *)nskb-&gt;data);
skb_pull(nskb, <FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">int</FONT>));
<FONT COLOR="#298C52">if</FONT> (!nskb-&gt;len) {
dev_kfree_skb(nskb);
dev_kfree_skb(skb);
<FONT COLOR="#298C52">return</FONT> v110_ret;
}
<FONT COLOR=#0000FF>/* V.110 must always be acknowledged */</FONT>
ack = 1;
ret = dev-&gt;drv[drvidx]-&gt;interface-&gt;writebuf_skb(drvidx, chan, ack, nskb);
} <FONT COLOR="#298C52">else</FONT>
ret = dev-&gt;drv[drvidx]-&gt;interface-&gt;writebuf_skb(drvidx, chan, ack, skb);
<FONT COLOR="#298C52">if</FONT> (ret &gt; 0) {
dev-&gt;obytes[idx] += ret;
<FONT COLOR="#298C52">if</FONT> (dev-&gt;v110[idx]) {
atomic_inc(&amp;dev-&gt;v110use[idx]);
dev-&gt;v110[idx]-&gt;skbuser++;
atomic_dec(&amp;dev-&gt;v110use[idx]);
dev_kfree_skb(skb);
<FONT COLOR=#0000FF>/* For V.110 return unencoded data length */</FONT>
ret = v110_ret;
<FONT COLOR="#298C52">if</FONT> (ret == skb-&gt;len)
dev_kfree_skb(skb);
}
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;v110[idx])
dev_kfree_skb(nskb);
<FONT COLOR="#298C52">return</FONT> ret;
}
<FONT COLOR="#298C52">int</FONT>
<A NAME="register_isdn_module">register_isdn_module</A>(<A HREF="../includes/isdn.h.shtml#isdn_module">isdn_module</A> *m) {
<FONT COLOR=#A521F7>#if</FONT> 0
isdn_module_list **pp = &amp;dev-&gt;modules;
<A HREF="../includes/isdn.h.shtml#isdn_module">isdn_module</A> *<FONT COLOR="#298C52">new</FONT> = kmalloc(<FONT COLOR="#298C52">sizeof</FONT>(isdn_module_list), GFP_KERNEL);
<FONT COLOR="#298C52">if</FONT> (!<FONT COLOR="#298C52">new</FONT>) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn: Out of memory in register_isdn_module\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> -1;
}
<FONT COLOR="#298C52">while</FONT> (*pp &amp;&amp; (*pp)-&gt;orig != m)
pp = &amp;(*pp)-&gt;next;
<FONT COLOR="#298C52">if</FONT> (*pp != NULL) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn: Module %s already registered\n"</FONT>, m-&gt;<A HREF="#name">name</A>);
<FONT COLOR="#298C52">return</FONT> -1;
}
<FONT COLOR="#298C52">while</FONT> (*pp &amp;&amp; ((*pp)-&gt;module.priority &lt; m-&gt;priority))
pp = &amp;(*pp)-&gt;next;
<FONT COLOR="#298C52">new</FONT>-&gt;next = *pp;
<FONT COLOR="#298C52">new</FONT>-&gt;orig = m;
<FONT COLOR="#298C52">new</FONT>-&gt;module = *m;
*pp = <FONT COLOR="#298C52">new</FONT>;
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">int</FONT>
<A NAME="unregister_isdn_module">unregister_isdn_module</A>(<A HREF="../includes/isdn.h.shtml#isdn_module">isdn_module</A> *m) {
<FONT COLOR=#A521F7>#if</FONT> 0
isdn_module_list **pp = &amp;dev-&gt;modules;
<FONT COLOR="#298C52">while</FONT> (*pp &amp;&amp; *pp != m)
pp = &amp;(*pp)-&gt;next;
<FONT COLOR="#298C52">if</FONT> (*pp == NULL) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn: Module %s not found\n"</FONT>, m-&gt;<A HREF="#name">name</A>);
<FONT COLOR="#298C52">return</FONT> -1;
}
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#0000FF>/*
* Low-level-driver registration
*/</FONT>
<A HREF="kdebug.h.shtml#EXPORT_SYMBOL">EXPORT_SYMBOL</A>(<A HREF="#register_isdn">register_isdn</A>);
<A HREF="kdebug.h.shtml#EXPORT_SYMBOL">EXPORT_SYMBOL</A>(<A HREF="#register_isdn_module">register_isdn_module</A>);
<A HREF="kdebug.h.shtml#EXPORT_SYMBOL">EXPORT_SYMBOL</A>(<A HREF="#unregister_isdn_module">unregister_isdn_module</A>);
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<A HREF="kdebug.h.shtml#EXPORT_SYMBOL">EXPORT_SYMBOL</A>(<A HREF="isdn_ppp.c.shtml#isdn_ppp_register_compressor">isdn_ppp_register_compressor</A>);
<A HREF="kdebug.h.shtml#EXPORT_SYMBOL">EXPORT_SYMBOL</A>(<A HREF="isdn_ppp.c.shtml#isdn_ppp_unregister_compressor">isdn_ppp_unregister_compressor</A>);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="register_isdn">register_isdn</A>(<A HREF="../includes/isdnif.h.shtml#isdn_if">isdn_if</A> * i)
{
<A HREF="../includes/isdn.h.shtml#driver">driver</A> *d;
<FONT COLOR="#298C52">int</FONT> n,
j,
k;
ulong flags;
<FONT COLOR="#298C52">int</FONT> drvidx;
<FONT COLOR="#298C52">if</FONT> (dev-&gt;drivers &gt;= <A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"register_isdn: Max. %d drivers supported\n"</FONT>,
<A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>);
<FONT COLOR="#298C52">return</FONT> 0;
}
n = i-&gt;channels;
<FONT COLOR="#298C52">if</FONT> (dev-&gt;channels + n &gt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"register_isdn: Max. %d channels supported\n"</FONT>,
<A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">if</FONT> (!i-&gt;writebuf_skb) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"register_isdn: No write routine given.\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">if</FONT> (!(d = (<A HREF="../includes/isdn.h.shtml#driver">driver</A> *) kmalloc(<FONT COLOR="#298C52">sizeof</FONT>(<A HREF="../includes/isdn.h.shtml#driver">driver</A>), GFP_KERNEL))) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"register_isdn: Could not alloc driver-struct\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> 0;
}
memset((<FONT COLOR="#298C52">char</FONT> *) d, 0, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="../includes/isdn.h.shtml#driver">driver</A>));
<FONT COLOR="#298C52">if</FONT> (!(d-&gt;rcverr = (<FONT COLOR="#298C52">int</FONT> *) kmalloc(<FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">int</FONT>) * n, GFP_KERNEL))) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"register_isdn: Could not alloc rcverr\n"</FONT>);
kfree(d);
<FONT COLOR="#298C52">return</FONT> 0;
}
memset((<FONT COLOR="#298C52">char</FONT> *) d-&gt;rcverr, 0, <FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">int</FONT>) * n);
<FONT COLOR="#298C52">if</FONT> (!(d-&gt;rcvcount = (<FONT COLOR="#298C52">int</FONT> *) kmalloc(<FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">int</FONT>) * n, GFP_KERNEL))) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"register_isdn: Could not alloc rcvcount\n"</FONT>);
kfree(d-&gt;rcverr);
kfree(d);
<FONT COLOR="#298C52">return</FONT> 0;
}
memset((<FONT COLOR="#298C52">char</FONT> *) d-&gt;rcvcount, 0, <FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">int</FONT>) * n);
<FONT COLOR="#298C52">if</FONT> (!(d-&gt;rpqueue =
(<FONT COLOR="#298C52">struct</FONT> sk_buff_head *) kmalloc(<FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">struct</FONT> sk_buff_head) * n, GFP_KERNEL))) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"register_isdn: Could not alloc rpqueue\n"</FONT>);
kfree(d-&gt;rcvcount);
kfree(d-&gt;rcverr);
kfree(d);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">for</FONT> (j = 0; j &lt; n; j++) {
skb_queue_head_init(&amp;d-&gt;rpqueue[j]);
}
<FONT COLOR="#298C52">if</FONT> (!(d-&gt;rcv_waitq = (<FONT COLOR="#298C52">struct</FONT> wait_queue **)
kmalloc(<FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">struct</FONT> wait_queue *) * n, GFP_KERNEL))) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"register_isdn: Could not alloc rcv_waitq\n"</FONT>);
kfree(d-&gt;rpqueue);
kfree(d-&gt;rcvcount);
kfree(d-&gt;rcverr);
kfree(d);
<FONT COLOR="#298C52">return</FONT> 0;
}
memset((<FONT COLOR="#298C52">char</FONT> *) d-&gt;rcv_waitq, 0, <FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">struct</FONT> wait_queue *) * n);
<FONT COLOR="#298C52">if</FONT> (!(d-&gt;snd_waitq = (<FONT COLOR="#298C52">struct</FONT> wait_queue **)
kmalloc(<FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">struct</FONT> wait_queue *) * n, GFP_KERNEL))) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"register_isdn: Could not alloc snd_waitq\n"</FONT>);
kfree(d-&gt;rcv_waitq);
kfree(d-&gt;rpqueue);
kfree(d-&gt;rcvcount);
kfree(d-&gt;rcverr);
kfree(d);
<FONT COLOR="#298C52">return</FONT> 0;
}
memset((<FONT COLOR="#298C52">char</FONT> *) d-&gt;snd_waitq, 0, <FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">struct</FONT> wait_queue *) * n);
d-&gt;channels = n;
d-&gt;loaded = 1;
d-&gt;maxbufsize = i-&gt;maxbufsize;
d-&gt;pktcount = 0;
d-&gt;stavail = 0;
d-&gt;running = 0;
d-&gt;flags = 0;
d-&gt;interface = i;
<FONT COLOR="#298C52">for</FONT> (drvidx = 0; drvidx &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>; drvidx++)
<FONT COLOR="#298C52">if</FONT> (!dev-&gt;drv[drvidx])
<FONT COLOR="#298C52">break</FONT>;
i-&gt;channels = drvidx;
i-&gt;rcvcallb_skb = <A HREF="#isdn_receive_skb_callback">isdn_receive_skb_callback</A>;
i-&gt;statcallb = <A HREF="#isdn_status_callback">isdn_status_callback</A>;
<FONT COLOR="#298C52">if</FONT> (!strlen(i-&gt;id))
sprintf(i-&gt;id, <FONT COLOR="#FF0000">"line%d"</FONT>, drvidx);
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<FONT COLOR="#298C52">for</FONT> (j = 0; j &lt; drvidx; j++)
<FONT COLOR="#298C52">if</FONT> (!strcmp(i-&gt;id, dev-&gt;drvid[j]))
sprintf(i-&gt;id, <FONT COLOR="#FF0000">"line%d"</FONT>, drvidx);
<FONT COLOR="#298C52">for</FONT> (j = 0; j &lt; n; j++)
<FONT COLOR="#298C52">for</FONT> (k = 0; k &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; k++)
<FONT COLOR="#298C52">if</FONT> (dev-&gt;chanmap[k] &lt; 0) {
dev-&gt;chanmap[k] = j;
dev-&gt;drvmap[k] = drvidx;
<FONT COLOR="#298C52">break</FONT>;
}
dev-&gt;drv[drvidx] = d;
dev-&gt;channels += n;
strcpy(dev-&gt;drvid[drvidx], i-&gt;id);
<A HREF="#isdn_info_update">isdn_info_update</A>();
dev-&gt;drivers++;
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> 1;
}
<FONT COLOR=#0000FF>/*
*****************************************************************************
* And now the modules code.
*****************************************************************************
*/</FONT>
<FONT COLOR="#298C52">extern</FONT> <FONT COLOR="#298C52">int</FONT> printk(<FONT COLOR="#298C52">const</FONT> <FONT COLOR="#298C52">char</FONT> *fmt,...);
<FONT COLOR=#A521F7>#ifdef</FONT> MODULE
<FONT COLOR=#A521F7>#define</FONT> <A NAME="isdn_init">isdn_init</A> <A HREF="isdn_bsdcomp.c.shtml#init_module">init_module</A>
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">char</FONT> *
<A NAME="isdn_getrev">isdn_getrev</A>(<FONT COLOR="#298C52">const</FONT> <FONT COLOR="#298C52">char</FONT> *revision)
{
<FONT COLOR="#298C52">char</FONT> *rev;
<FONT COLOR="#298C52">char</FONT> *p;
<FONT COLOR="#298C52">if</FONT> ((p = strchr(revision, <FONT COLOR="#FF0000">':'</FONT>))) {
rev = p + 2;
p = strchr(rev, <FONT COLOR="#FF0000">'$'</FONT>);
*--p = 0;
} <FONT COLOR="#298C52">else</FONT>
rev = <FONT COLOR="#FF0000">"???"</FONT>;
<FONT COLOR="#298C52">return</FONT> rev;
}
<FONT COLOR=#0000FF>/*
* Allocate and initialize all data, register modem-devices
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A HREF="#isdn_init">isdn_init</A>(<FONT COLOR="#298C52">void</FONT>)
{
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">char</FONT> tmprev[50];
<A HREF="kdebug.h.shtml#sti">sti</A>();
<FONT COLOR="#298C52">if</FONT> (!(dev = (<A HREF="../includes/isdn.h.shtml#isdn_dev">isdn_dev</A> *) kmalloc(<FONT COLOR="#298C52">sizeof</FONT>(<A HREF="../includes/isdn.h.shtml#isdn_dev">isdn_dev</A>), GFP_KERNEL))) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn: Could not allocate device-struct.\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> -EIO;
}
memset((<FONT COLOR="#298C52">char</FONT> *) dev, 0, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="../includes/isdn.h.shtml#isdn_dev">isdn_dev</A>));
init_timer(&amp;dev-&gt;timer);
dev-&gt;timer.function = <A HREF="#isdn_timer_funct">isdn_timer_funct</A>;
dev-&gt;sem = MUTEX;
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
dev-&gt;drvmap[i] = -1;
dev-&gt;chanmap[i] = -1;
dev-&gt;m_idx[i] = -1;
strcpy(dev-&gt;num[i], <FONT COLOR="#FF0000">"???"</FONT>);
}
<FONT COLOR="#298C52">if</FONT> (register_chrdev(<A HREF="../includes/isdn.h.shtml#ISDN_MAJOR">ISDN_MAJOR</A>, <FONT COLOR="#FF0000">"isdn"</FONT>, &amp;isdn_fops)) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn: Could not register control devices\n"</FONT>);
kfree(dev);
<FONT COLOR="#298C52">return</FONT> -EIO;
}
<FONT COLOR="#298C52">if</FONT> ((i = <A HREF="isdn_tty.c.shtml#isdn_tty_modem_init">isdn_tty_modem_init</A>()) &lt; 0) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn: Could not register tty devices\n"</FONT>);
<FONT COLOR="#298C52">if</FONT> (i == -3)
tty_unregister_driver(&amp;dev-&gt;mdm.cua_modem);
<FONT COLOR="#298C52">if</FONT> (i &lt;= -2)
tty_unregister_driver(&amp;dev-&gt;mdm.tty_modem);
kfree(dev);
unregister_chrdev(<A HREF="../includes/isdn.h.shtml#ISDN_MAJOR">ISDN_MAJOR</A>, <FONT COLOR="#FF0000">"isdn"</FONT>);
<FONT COLOR="#298C52">return</FONT> -EIO;
}
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_ppp.c.shtml#isdn_ppp_init">isdn_ppp_init</A>() &lt; 0) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn: Could not create PPP-device-structs\n"</FONT>);
tty_unregister_driver(&amp;dev-&gt;mdm.tty_modem);
tty_unregister_driver(&amp;dev-&gt;mdm.cua_modem);
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++)
kfree(dev-&gt;mdm.info[i].xmit_buf - 4);
unregister_chrdev(<A HREF="../includes/isdn.h.shtml#ISDN_MAJOR">ISDN_MAJOR</A>, <FONT COLOR="#FF0000">"isdn"</FONT>);
kfree(dev);
<FONT COLOR="#298C52">return</FONT> -EIO;
}
<FONT COLOR=#A521F7>#endif</FONT> <FONT COLOR=#0000FF>/* CONFIG_ISDN_PPP */</FONT>
strcpy(tmprev, isdn_revision);
printk(KERN_NOTICE <FONT COLOR="#FF0000">"ISDN subsystem Rev: %s/"</FONT>, <A HREF="#isdn_getrev">isdn_getrev</A>(tmprev));
strcpy(tmprev, isdn_tty_revision);
printk(<FONT COLOR="#FF0000">"%s/"</FONT>, <A HREF="#isdn_getrev">isdn_getrev</A>(tmprev));
strcpy(tmprev, isdn_net_revision);
printk(<FONT COLOR="#FF0000">"%s/"</FONT>, <A HREF="#isdn_getrev">isdn_getrev</A>(tmprev));
strcpy(tmprev, isdn_ppp_revision);
printk(<FONT COLOR="#FF0000">"%s/"</FONT>, <A HREF="#isdn_getrev">isdn_getrev</A>(tmprev));
strcpy(tmprev, isdn_audio_revision);
printk(<FONT COLOR="#FF0000">"%s/"</FONT>, <A HREF="#isdn_getrev">isdn_getrev</A>(tmprev));
strcpy(tmprev, isdn_v110_revision);
printk(<FONT COLOR="#FF0000">"%s"</FONT>, <A HREF="#isdn_getrev">isdn_getrev</A>(tmprev));
<FONT COLOR=#A521F7>#ifdef</FONT> MODULE
printk(<FONT COLOR="#FF0000">" loaded\n"</FONT>);
<FONT COLOR=#A521F7>#else</FONT>
printk(<FONT COLOR="#FF0000">"\n"</FONT>);
<A HREF="isdn_cards.c.shtml#isdn_cards_init">isdn_cards_init</A>();
<FONT COLOR=#A521F7>#endif</FONT>
<A HREF="#isdn_info_update">isdn_info_update</A>();
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#A521F7>#ifdef</FONT> MODULE
<FONT COLOR=#0000FF>/*
* Unload module
*/</FONT>
<FONT COLOR="#298C52">void</FONT>
<A HREF="isdn_bsdcomp.c.shtml#cleanup_module">cleanup_module</A>(<FONT COLOR="#298C52">void</FONT>)
{
<FONT COLOR="#298C52">int</FONT> flags;
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<A HREF="isdn_ppp.c.shtml#isdn_ppp_cleanup">isdn_ppp_cleanup</A>();
<FONT COLOR=#A521F7>#endif</FONT>
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_net.c.shtml#isdn_net_rmall">isdn_net_rmall</A>() &lt; 0) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn: net-device busy, remove cancelled\n"</FONT>);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT>;
}
<FONT COLOR="#298C52">if</FONT> (tty_unregister_driver(&amp;dev-&gt;mdm.tty_modem)) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn: ttyI-device busy, remove cancelled\n"</FONT>);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT>;
}
<FONT COLOR="#298C52">if</FONT> (tty_unregister_driver(&amp;dev-&gt;mdm.cua_modem)) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn: cui-device busy, remove cancelled\n"</FONT>);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT>;
}
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
<A HREF="isdn_tty.c.shtml#isdn_tty_cleanup_xmit">isdn_tty_cleanup_xmit</A>(&amp;dev-&gt;mdm.info[i]);
kfree(dev-&gt;mdm.info[i].xmit_buf - 4);
}
<FONT COLOR="#298C52">if</FONT> (unregister_chrdev(<A HREF="../includes/isdn.h.shtml#ISDN_MAJOR">ISDN_MAJOR</A>, <FONT COLOR="#FF0000">"isdn"</FONT>) != 0) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn: controldevice busy, remove cancelled\n"</FONT>);
} <FONT COLOR="#298C52">else</FONT> {
del_timer(&amp;dev-&gt;timer);
kfree(dev);
printk(KERN_NOTICE <FONT COLOR="#FF0000">"ISDN-subsystem unloaded\n"</FONT>);
}
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
}
<FONT COLOR=#A521F7>#endif</FONT>
</BODY>
</HTML>