2446 lines
129 KiB
Plaintext
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&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() -> 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 >= 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() -> -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 >= 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<->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 >= 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_* -> queue_task
|
|
* clear/set_bit -> 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->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->users and skb->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> <linux/config.h>
|
|
<FONT COLOR=#A521F7>#include</FONT> <linux/module.h>
|
|
<FONT COLOR=#A521F7>#include</FONT> <linux/version.h>
|
|
<FONT COLOR=#A521F7>#include</FONT> <linux/poll.h>
|
|
<FONT COLOR=#A521F7>#include</FONT> <linux/isdn.h>
|
|
<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 < dumplen) && (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 && (*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 <= *++p && *s >= 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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++)
|
|
<FONT COLOR="#298C52">if</FONT> (dev->chanmap[i] == ch && dev->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->tflags;
|
|
<FONT COLOR="#298C52">if</FONT> (tf & <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_FAST">ISDN_TIMER_FAST</A>) {
|
|
<FONT COLOR="#298C52">if</FONT> (tf & <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 & <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 & <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 & <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_SLOW">ISDN_TIMER_SLOW</A>) {
|
|
<FONT COLOR="#298C52">if</FONT> (++isdn_timer_cnt1 >= <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_02SEC">ISDN_TIMER_02SEC</A>) {
|
|
isdn_timer_cnt1 = 0;
|
|
<FONT COLOR="#298C52">if</FONT> (tf & <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 >= <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_1SEC">ISDN_TIMER_1SEC</A>) {
|
|
isdn_timer_cnt2 = 0;
|
|
<FONT COLOR="#298C52">if</FONT> (tf & <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 > <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_RINGING">ISDN_TIMER_RINGING</A>) {
|
|
isdn_timer_cnt3 = 0;
|
|
<FONT COLOR="#298C52">if</FONT> (tf & <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 > <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_KEEPINT">ISDN_TIMER_KEEPINT</A>) {
|
|
isdn_timer_cnt4 = 0;
|
|
<FONT COLOR="#298C52">if</FONT> (tf & <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) && (defined CONFIG_ISDN_MPP)
|
|
<FONT COLOR="#298C52">if</FONT> (tf & <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(&dev->timer);
|
|
dev->timer.expires = jiffies + <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_RES">ISDN_TIMER_RES</A>;
|
|
add_timer(&dev->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 & <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_SLOW">ISDN_TIMER_SLOW</A>) && (!(dev->tflags & <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->tflags |= tf;
|
|
<FONT COLOR="#298C52">else</FONT>
|
|
dev->tflags &= ~tf;
|
|
<FONT COLOR="#298C52">if</FONT> (dev->tflags) {
|
|
<FONT COLOR="#298C52">if</FONT> (!del_timer(&dev->timer)) <FONT COLOR=#0000FF>/* del_timer is 1, when active */</FONT>
|
|
dev->timer.expires = jiffies + <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_RES">ISDN_TIMER_RES</A>;
|
|
add_timer(&dev->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->ibytes[i] += skb->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->v110[i]) {
|
|
atomic_inc(&dev->v110use[i]);
|
|
skb = <A HREF="isdn_v110.c.shtml#isdn_v110_decode">isdn_v110_decode</A>(dev->v110[i], skb);
|
|
atomic_dec(&dev->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->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(&dev->drv[di]->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->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-><A HREF="../includes/isdn.h.shtml#driver">driver</A>, cmd->arg & 255);
|
|
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">long</FONT> l2prot = (cmd->arg >> 8) & 255;
|
|
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">long</FONT> features = (dev->drv[cmd-><A HREF="../includes/isdn.h.shtml#driver">driver</A>]->interface->features
|
|
>> <A HREF="../includes/isdnif.h.shtml#ISDN_FEATURE_L2_SHIFT">ISDN_FEATURE_L2_SHIFT</A>) &
|
|
<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 << 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 & l2_feature)) {
|
|
dev->v110emu[idx] = l2prot;
|
|
cmd->arg = (cmd->arg & 255) |
|
|
(<A HREF="../includes/isdnif.h.shtml#ISDN_PROTO_L2_TRANS">ISDN_PROTO_L2_TRANS</A> << 8);
|
|
} <FONT COLOR="#298C52">else</FONT>
|
|
dev->v110emu[idx] = 0;
|
|
}
|
|
}
|
|
<FONT COLOR="#298C52">return</FONT> dev->drv[cmd-><A HREF="../includes/isdn.h.shtml#driver">driver</A>]->interface->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 < 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>(&cmd);
|
|
}
|
|
|
|
<FONT COLOR=#0000FF>/*
|
|
* Begin of a CAPI like LL<->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->adr.Controller & 0x7f) -1;
|
|
ch = <A HREF="#isdn_dc2minor">isdn_dc2minor</A>(di, (cm->adr.Controller>>8)& 0x7f);
|
|
<FONT COLOR="#298C52">switch</FONT>(cm->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-><A HREF="../includes/isdn.h.shtml#driver">driver</A>;
|
|
i = <A HREF="#isdn_dc2minor">isdn_dc2minor</A>(di, c->arg);
|
|
<FONT COLOR="#298C52">switch</FONT> (c->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 < 0)
|
|
<FONT COLOR="#298C52">return</FONT> -1;
|
|
<FONT COLOR="#298C52">if</FONT> (dev->global_flags & <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(&dev->drv[di]->snd_waitq[c->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->drv[di]->stavail += c->arg;
|
|
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
|
|
wake_up_interruptible(&dev->drv[di]->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->drv[di]->running = 1;
|
|
<FONT COLOR="#298C52">for</FONT> (i = 0; i < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++)
|
|
<FONT COLOR="#298C52">if</FONT> (dev->drvmap[i] == di)
|
|
<A HREF="#isdn_all_eaz">isdn_all_eaz</A>(di, dev->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->drv[di]->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 < 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->arg, c->parm.num);
|
|
<FONT COLOR=#A521F7>#endif</FONT>
|
|
<FONT COLOR="#298C52">if</FONT> (dev->global_flags & <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->arg;
|
|
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_HANGUP">ISDN_CMD_HANGUP</A>;
|
|
<A HREF="#isdn_command">isdn_command</A>(&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->arg;
|
|
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_LOCK">ISDN_CMD_LOCK</A>;
|
|
<A HREF="#isdn_command">isdn_command</A>(&cmd);
|
|
r = <A HREF="isdn_net.c.shtml#isdn_net_find_icall">isdn_net_find_icall</A>(di, c->arg, i, c->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->arg, c->parm.setup);
|
|
<FONT COLOR="#298C52">if</FONT> ((!retval) && dev->drv[di]->reject_bus) {
|
|
<FONT COLOR=#0000FF>/* No tty responding */</FONT>
|
|
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = di;
|
|
cmd.arg = c->arg;
|
|
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_HANGUP">ISDN_CMD_HANGUP</A>;
|
|
<A HREF="#isdn_command">isdn_command</A>(&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->arg;
|
|
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_ACCEPTD">ISDN_CMD_ACCEPTD</A>;
|
|
<A HREF="#isdn_command">isdn_command</A>(&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->arg;
|
|
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_HANGUP">ISDN_CMD_HANGUP</A>;
|
|
<A HREF="#isdn_command">isdn_command</A>(&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->arg;
|
|
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_UNLOCK">ISDN_CMD_UNLOCK</A>;
|
|
<A HREF="#isdn_command">isdn_command</A>(&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 < 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->arg, c->parm.num);
|
|
<FONT COLOR=#A521F7>#endif</FONT>
|
|
<FONT COLOR="#298C52">if</FONT> (dev->global_flags & <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->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->arg, c->parm.num);
|
|
<FONT COLOR=#A521F7>#endif</FONT>
|
|
printk(KERN_INFO <FONT COLOR="#FF0000">"isdn: %s,ch%ld cause: %s\n"</FONT>,
|
|
dev->drvid[di], c->arg, c->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 < 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->arg);
|
|
<FONT COLOR=#A521F7>#endif</FONT>
|
|
<FONT COLOR="#298C52">if</FONT> (dev->global_flags & <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->arg;
|
|
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_ACCEPTB">ISDN_CMD_ACCEPTB</A>;
|
|
<A HREF="#isdn_command">isdn_command</A>(&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 < 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->arg);
|
|
<FONT COLOR=#A521F7>#endif</FONT>
|
|
<FONT COLOR="#298C52">if</FONT> (dev->global_flags & <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A>)
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
dev->drv[di]->flags &= ~(1 << (c->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 < 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->arg);
|
|
<FONT COLOR=#A521F7>#endif</FONT>
|
|
<FONT COLOR=#0000FF>/* Signal B-channel-connect to network-devices */</FONT>
|
|
<FONT COLOR="#298C52">if</FONT> (dev->global_flags & <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A>)
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
dev->drv[di]->flags |= (1 << (c->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 < 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->arg);
|
|
<FONT COLOR=#A521F7>#endif</FONT>
|
|
<FONT COLOR="#298C52">if</FONT> (dev->global_flags & <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A>)
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
dev->drv[di]->flags &= ~(1 << (c->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 < 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->arg);
|
|
<FONT COLOR=#A521F7>#endif</FONT>
|
|
<FONT COLOR="#298C52">if</FONT> (dev->global_flags & <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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++)
|
|
<FONT COLOR="#298C52">if</FONT> (dev->drvmap[i] == di) {
|
|
dev->drvmap[i] = -1;
|
|
dev->chanmap[i] = -1;
|
|
}
|
|
dev->drivers--;
|
|
dev->channels -= dev->drv[di]->channels;
|
|
kfree(dev->drv[di]->rcverr);
|
|
kfree(dev->drv[di]->rcvcount);
|
|
<FONT COLOR="#298C52">for</FONT> (i = 0; i < dev->drv[di]->channels; i++)
|
|
<A HREF="#isdn_free_queue">isdn_free_queue</A>(&dev->drv[di]->rpqueue[i]);
|
|
kfree(dev->drv[di]->rpqueue);
|
|
kfree(dev->drv[di]->rcv_waitq);
|
|
kfree(dev->drv[di]->snd_waitq);
|
|
kfree(dev->drv[di]);
|
|
dev->drv[di] = NULL;
|
|
dev->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>(&c->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] >= <FONT COLOR="#FF0000">'0'</FONT> && *p[0] <= <FONT COLOR="#FF0000">'9'</FONT>)
|
|
v = ((v < 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)<->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->drv[di])
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
<FONT COLOR="#298C52">if</FONT> (skb_queue_empty(&dev->drv[di]->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->drv[di]->rcvcount[channel]);
|
|
cp = buf;
|
|
count = 0;
|
|
<FONT COLOR="#298C52">while</FONT> (left) {
|
|
<FONT COLOR="#298C52">if</FONT> (!(skb = skb_peek(&dev->drv[di]->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->data;
|
|
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">long</FONT> DLEmask = (1 << channel);
|
|
|
|
dflag = 0;
|
|
count_pull = count_put = 0;
|
|
<FONT COLOR="#298C52">while</FONT> ((count_pull < skb->len) && (left-- > 0)) {
|
|
<FONT COLOR="#298C52">if</FONT> (dev->drv[di]->DLEflag & DLEmask) {
|
|
*cp++ = <A HREF="#DLE">DLE</A>;
|
|
dev->drv[di]->DLEflag &= ~DLEmask;
|
|
} <FONT COLOR="#298C52">else</FONT> {
|
|
*cp++ = *p;
|
|
<FONT COLOR="#298C52">if</FONT> (*p == <A HREF="#DLE">DLE</A>) {
|
|
dev->drv[di]->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 >= skb->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->len) > left) {
|
|
count_pull = left;
|
|
dflag = 0;
|
|
}
|
|
count_put = count_pull;
|
|
memcpy(cp, skb->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(&dev->drv[di]->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->drv[di]->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->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->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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
|
|
sprintf(p, <FONT COLOR="#FF0000">"%s "</FONT>, (dev->drvmap[i] < 0) ? <FONT COLOR="#FF0000">"-"</FONT> : dev->drvid[dev->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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
|
|
sprintf(p, <FONT COLOR="#FF0000">"%d "</FONT>, dev->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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
|
|
sprintf(p, <FONT COLOR="#FF0000">"%d "</FONT>, dev->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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
|
|
sprintf(p, <FONT COLOR="#FF0000">"%d "</FONT>, dev->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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>; i++) {
|
|
<FONT COLOR="#298C52">if</FONT> (dev->drv[i]) {
|
|
sprintf(p, <FONT COLOR="#FF0000">"%ld "</FONT>, dev->drv[i]->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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
|
|
sprintf(p, <FONT COLOR="#FF0000">"%s "</FONT>, dev->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->infochain;
|
|
|
|
<FONT COLOR="#298C52">while</FONT> (p) {
|
|
*(p-><FONT COLOR="#298C52">private</FONT>) = 1;
|
|
p = (<A HREF="../includes/isdn.h.shtml#infostruct">infostruct</A> *) p->next;
|
|
}
|
|
wake_up_interruptible(&(dev->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->f_dentry->d_inode->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 != &file->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->private_data) {
|
|
<FONT COLOR="#298C52">if</FONT> (file->f_flags & O_NONBLOCK)
|
|
<FONT COLOR="#298C52">return</FONT> -EAGAIN;
|
|
interruptible_sleep_on(&(dev->info_waitq));
|
|
}
|
|
p = <A HREF="#isdn_statstr">isdn_statstr</A>();
|
|
file->private_data = 0;
|
|
<FONT COLOR="#298C52">if</FONT> ((len = strlen(p)) <= 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->drivers)
|
|
<FONT COLOR="#298C52">return</FONT> -ENODEV;
|
|
<FONT COLOR="#298C52">if</FONT> (minor < <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 < 0)
|
|
<FONT COLOR="#298C52">return</FONT> -ENODEV;
|
|
<FONT COLOR="#298C52">if</FONT> (!dev->drv[drvidx]->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,
|
|
&dev->drv[drvidx]->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 <= <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 < 0)
|
|
<FONT COLOR="#298C52">return</FONT> -ENODEV;
|
|
<FONT COLOR="#298C52">if</FONT> (!dev->drv[drvidx]->stavail) {
|
|
<FONT COLOR="#298C52">if</FONT> (file->f_flags & O_NONBLOCK)
|
|
<FONT COLOR="#298C52">return</FONT> -EAGAIN;
|
|
interruptible_sleep_on(&(dev->drv[drvidx]->st_waitq));
|
|
}
|
|
<FONT COLOR="#298C52">if</FONT> (dev->drv[drvidx]->interface->readstat)
|
|
len = dev->drv[drvidx]->interface->
|
|
readstat(buf, <A HREF="isdn_hybrid.c.shtml#MIN">MIN</A>(count, dev->drv[drvidx]->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->drv[drvidx]->stavail -= len;
|
|
<FONT COLOR="#298C52">else</FONT>
|
|
dev->drv[drvidx]->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 <= <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->f_dentry->d_inode->i_rdev);
|
|
<FONT COLOR="#298C52">int</FONT> drvidx;
|
|
<FONT COLOR="#298C52">int</FONT> chidx;
|
|
|
|
<FONT COLOR="#298C52">if</FONT> (off != &file->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->drivers)
|
|
<FONT COLOR="#298C52">return</FONT> -ENODEV;
|
|
<FONT COLOR="#298C52">if</FONT> (minor < <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 < 0)
|
|
<FONT COLOR="#298C52">return</FONT> -ENODEV;
|
|
<FONT COLOR="#298C52">if</FONT> (!dev->drv[drvidx]->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(&dev->drv[drvidx]->snd_waitq[chidx]);
|
|
<FONT COLOR="#298C52">return</FONT> count;
|
|
}
|
|
<FONT COLOR="#298C52">if</FONT> (minor <= <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 < 0)
|
|
<FONT COLOR="#298C52">return</FONT> -ENODEV;
|
|
<FONT COLOR=#0000FF>/*
|
|
* We want to use the isdnctrl device to load the firmware
|
|
*
|
|
if (!dev->drv[drvidx]->running)
|
|
return -ENODEV;
|
|
*/</FONT>
|
|
<FONT COLOR="#298C52">if</FONT> (dev->drv[drvidx]->interface->writecmd)
|
|
<FONT COLOR="#298C52">return</FONT> (dev->drv[drvidx]->interface->
|
|
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 <= <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->f_dentry->d_inode->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, &(dev->info_waitq), wait);
|
|
<FONT COLOR=#0000FF>/* mask = POLLOUT | POLLWRNORM; */</FONT>
|
|
<FONT COLOR="#298C52">if</FONT> (file->private_data) {
|
|
mask |= POLLIN | POLLRDNORM;
|
|
}
|
|
<FONT COLOR="#298C52">return</FONT> mask;
|
|
}
|
|
<FONT COLOR="#298C52">if</FONT> (minor >= <A HREF="../includes/isdn.h.shtml#ISDN_MINOR_CTRL">ISDN_MINOR_CTRL</A> && minor <= <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, &(dev->drv[drvidx]->st_waitq), wait);
|
|
<FONT COLOR="#298C52">if</FONT> (drvidx < 0) {
|
|
printk(KERN_ERR <FONT COLOR="#FF0000">"isdn_common: isdn_poll 1 -> what the hell\n"</FONT>);
|
|
<FONT COLOR="#298C52">return</FONT> POLLERR;
|
|
}
|
|
mask = POLLOUT | POLLWRNORM;
|
|
<FONT COLOR="#298C52">if</FONT> (dev->drv[drvidx]->stavail) {
|
|
mask |= POLLIN | POLLRDNORM;
|
|
}
|
|
<FONT COLOR="#298C52">return</FONT> mask;
|
|
}
|
|
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
|
|
<FONT COLOR="#298C52">if</FONT> (minor <= <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 -> 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->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> << 8) +
|
|
(<A HREF="../includes/isdn.h.shtml#INF_DV">INF_DV</A> << 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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
|
|
put_user(dev->ibytes[i], p++);
|
|
put_user(dev->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->drivers)
|
|
<FONT COLOR="#298C52">return</FONT> -ENODEV;
|
|
<FONT COLOR="#298C52">if</FONT> (minor < <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 < 0)
|
|
<FONT COLOR="#298C52">return</FONT> -ENODEV;
|
|
chidx = <A HREF="#isdn_minor2chan">isdn_minor2chan</A>(minor);
|
|
<FONT COLOR="#298C52">if</FONT> (!dev->drv[drvidx]->running)
|
|
<FONT COLOR="#298C52">return</FONT> -ENODEV;
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
}
|
|
<FONT COLOR="#298C52">if</FONT> (minor <= <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(&dev->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(&dev->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(&dev->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(&dev->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(&dev->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(&dev->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> *) &<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>(&<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> *) &<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>(&<A HREF="#cfg">cfg</A>))) {
|
|
<FONT COLOR="#298C52">if</FONT> (copy_to_user((<FONT COLOR="#298C52">char</FONT> *) arg, (<FONT COLOR="#298C52">char</FONT> *) &<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> *) &<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(&dev->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>(&<A HREF="#phone">phone</A>);
|
|
up(&dev->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> *) &<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(&dev->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>(&<A HREF="#phone">phone</A>, (<FONT COLOR="#298C52">char</FONT> *) arg);
|
|
up(&dev->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> *) &<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(&dev->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>(&<A HREF="#phone">phone</A>);
|
|
up(&dev->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> *) &<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>(&<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> *) &<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>(&<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> *)&<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>(&<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> *)&<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> *)&<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>(&<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> *)&<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->net_verbose = arg;
|
|
printk(KERN_INFO <FONT COLOR="#FF0000">"isdn: Verbose-Level is %d\n"</FONT>, dev->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->global_flags |= <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A>;
|
|
<FONT COLOR="#298C52">else</FONT>
|
|
dev->global_flags &= ~<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->global_flags & <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> *) &<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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>; i++)
|
|
<FONT COLOR="#298C52">if</FONT> (!(strcmp(dev->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->drv[drvidx]->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->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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
|
|
<FONT COLOR="#298C52">if</FONT> (copy_to_user(p, dev->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->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->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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
|
|
<FONT COLOR="#298C52">if</FONT> (copy_from_user(dev->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->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->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> *) &<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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>; i++)
|
|
<FONT COLOR="#298C52">if</FONT> (!(strcmp(dev->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->drv[drvidx]->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 >= <A HREF="../includes/isdn.h.shtml#ISDN_MSNLEN">ISDN_MSNLEN</A>)
|
|
<FONT COLOR="#298C52">break</FONT>;
|
|
}
|
|
<FONT COLOR="#298C52">if</FONT> (++i > 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 < 10; i++) {
|
|
sprintf(<A HREF="#bname">bname</A>, <FONT COLOR="#FF0000">"%s%s"</FONT>,
|
|
strlen(dev->drv[drvidx]->msn2eaz[i]) ?
|
|
dev->drv[drvidx]->msn2eaz[i] : <FONT COLOR="#FF0000">"-"</FONT>,
|
|
(i < 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> *) &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 & <A HREF="../includes/isdn.h.shtml#IIOCDRVCTL">IIOCDRVCTL</A>) == <A HREF="../includes/isdn.h.shtml#IIOCDRVCTL">IIOCDRVCTL</A>)
|
|
cmd = ((cmd >> _IOC_NRSHIFT) & _IOC_NRMASK) & <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> *) &<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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>; i++)
|
|
<FONT COLOR="#298C52">if</FONT> (!(strcmp(dev->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> *) &<A HREF="#iocts">iocts</A>.arg, <FONT COLOR="#298C52">sizeof</FONT>(ulong));
|
|
ret = <A HREF="#isdn_command">isdn_command</A>(&c);
|
|
memcpy((<FONT COLOR="#298C52">char</FONT> *) &<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, &<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 <= <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->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->next = (<FONT COLOR="#298C52">char</FONT> *) dev->infochain;
|
|
p-><FONT COLOR="#298C52">private</FONT> = (<FONT COLOR="#298C52">char</FONT> *) &(filep->private_data);
|
|
dev->infochain = p;
|
|
<FONT COLOR=#0000FF>/* At opening we allow a single update */</FONT>
|
|
filep->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->channels)
|
|
<FONT COLOR="#298C52">return</FONT> -ENODEV;
|
|
<FONT COLOR="#298C52">if</FONT> (minor < <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 < 0)
|
|
<FONT COLOR="#298C52">return</FONT> -ENODEV;
|
|
chidx = <A HREF="#isdn_minor2chan">isdn_minor2chan</A>(minor);
|
|
<FONT COLOR="#298C52">if</FONT> (!dev->drv[drvidx]->running)
|
|
<FONT COLOR="#298C52">return</FONT> -ENODEV;
|
|
<FONT COLOR="#298C52">if</FONT> (!(dev->drv[drvidx]->flags & (1 << 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>(&c);
|
|
MOD_INC_USE_COUNT;
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
}
|
|
<FONT COLOR="#298C52">if</FONT> (minor <= <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 < 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>(&c);
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
}
|
|
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
|
|
<FONT COLOR="#298C52">if</FONT> (minor <= <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->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->infochain;
|
|
<A HREF="../includes/isdn.h.shtml#infostruct">infostruct</A> *q = NULL;
|
|
<FONT COLOR="#298C52">while</FONT> (p) {
|
|
<FONT COLOR="#298C52">if</FONT> (p-><FONT COLOR="#298C52">private</FONT> == (<FONT COLOR="#298C52">char</FONT> *) &(filep->private_data)) {
|
|
<FONT COLOR="#298C52">if</FONT> (q)
|
|
q->next = p->next;
|
|
<FONT COLOR="#298C52">else</FONT>
|
|
dev->infochain = (<A HREF="../includes/isdn.h.shtml#infostruct">infostruct</A> *) (p->next);
|
|
kfree(p);
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
}
|
|
q = p;
|
|
p = (<A HREF="../includes/isdn.h.shtml#infostruct">infostruct</A> *) (p->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 < <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 < 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>(&c);
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
}
|
|
<FONT COLOR="#298C52">if</FONT> (minor <= <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 < 0)
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
<FONT COLOR="#298C52">if</FONT> (dev->profd == current)
|
|
dev->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>(&c);
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
}
|
|
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
|
|
<FONT COLOR="#298C52">if</FONT> (minor <= <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->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 >= 0) && (i <= 9))
|
|
<FONT COLOR="#298C52">if</FONT> (strlen(<FONT COLOR="#298C52">this</FONT>->msn2eaz[i]))
|
|
<FONT COLOR="#298C52">return</FONT> (<FONT COLOR="#298C52">this</FONT>->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 << l2_proto) | (0x10000 << l3_proto));
|
|
vfeatures = (((1 << l2_proto) | (0x10000 << l3_proto)) &
|
|
~(<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 < <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->usage[i]) &&
|
|
(dev->drvmap[i] != -1)) {
|
|
<FONT COLOR="#298C52">int</FONT> d = dev->drvmap[i];
|
|
<FONT COLOR="#298C52">if</FONT> ((dev->usage[i] & <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>) &&
|
|
((pre_dev != d) || (pre_chan != dev->chanmap[i])))
|
|
<FONT COLOR="#298C52">continue</FONT>;
|
|
<FONT COLOR="#298C52">if</FONT> ((dev->drv[d]->running)) {
|
|
<FONT COLOR="#298C52">if</FONT> (((dev->drv[d]->interface->features & features) == features) ||
|
|
(((dev->drv[d]->interface->features & vfeatures) == vfeatures) &&
|
|
(dev->drv[d]->interface->features & <A HREF="../includes/isdnif.h.shtml#ISDN_FEATURE_L2_TRANS">ISDN_FEATURE_L2_TRANS</A>))) {
|
|
<FONT COLOR="#298C52">if</FONT> ((pre_dev < 0) || (pre_chan < 0)) {
|
|
dev->usage[i] &= <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>;
|
|
dev->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>(&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) && (pre_chan == dev->chanmap[i])) {
|
|
dev->usage[i] &= <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>;
|
|
dev->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>(&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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++)
|
|
<FONT COLOR="#298C52">if</FONT> (((dev->usage[i] & <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_MASK">ISDN_USAGE_MASK</A>) == usage) &&
|
|
(dev->drvmap[i] == di) &&
|
|
(dev->chanmap[i] == ch)) {
|
|
dev->usage[i] &= (<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->num[i], <FONT COLOR="#FF0000">"???"</FONT>);
|
|
dev->ibytes[i] = 0;
|
|
dev->obytes[i] = 0;
|
|
<A HREF="#isdn_info_update">isdn_info_update</A>();
|
|
<A HREF="#isdn_free_queue">isdn_free_queue</A>(&dev->drv[di]->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>(&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 < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++)
|
|
<FONT COLOR="#298C52">if</FONT> ((dev->drvmap[i] == di) &&
|
|
(dev->chanmap[i] == ch)) {
|
|
dev->usage[i] &= ~<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->drv[drvidx]->interface->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->drv[drvidx]->interface->writebuf_skb(drvidx, chan, 1, skb);
|
|
<FONT COLOR="#298C52">if</FONT> (ret <= 0)
|
|
dev_kfree_skb(skb);
|
|
<FONT COLOR="#298C52">if</FONT> (ret > 0)
|
|
dev->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->len;
|
|
<FONT COLOR="#298C52">int</FONT> idx = <A HREF="#isdn_dc2minor">isdn_dc2minor</A>(drvidx, chan);
|
|
|
|
<FONT COLOR="#298C52">if</FONT> (dev->v110[idx]) {
|
|
atomic_inc(&dev->v110use[idx]);
|
|
nskb = <A HREF="isdn_v110.c.shtml#isdn_v110_encode">isdn_v110_encode</A>(dev->v110[idx], skb);
|
|
atomic_dec(&dev->v110use[idx]);
|
|
<FONT COLOR="#298C52">if</FONT> (!nskb)
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
v110_ret = *((<FONT COLOR="#298C52">int</FONT> *)nskb->data);
|
|
skb_pull(nskb, <FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">int</FONT>));
|
|
<FONT COLOR="#298C52">if</FONT> (!nskb->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->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, nskb);
|
|
} <FONT COLOR="#298C52">else</FONT>
|
|
ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, skb);
|
|
<FONT COLOR="#298C52">if</FONT> (ret > 0) {
|
|
dev->obytes[idx] += ret;
|
|
<FONT COLOR="#298C52">if</FONT> (dev->v110[idx]) {
|
|
atomic_inc(&dev->v110use[idx]);
|
|
dev->v110[idx]->skbuser++;
|
|
atomic_dec(&dev->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->len)
|
|
dev_kfree_skb(skb);
|
|
}
|
|
} <FONT COLOR="#298C52">else</FONT>
|
|
<FONT COLOR="#298C52">if</FONT> (dev->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 = &dev->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 && (*pp)->orig != m)
|
|
pp = &(*pp)->next;
|
|
<FONT COLOR="#298C52">if</FONT> (*pp != NULL) {
|
|
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn: Module %s already registered\n"</FONT>, m-><A HREF="#name">name</A>);
|
|
<FONT COLOR="#298C52">return</FONT> -1;
|
|
}
|
|
<FONT COLOR="#298C52">while</FONT> (*pp && ((*pp)->module.priority < m->priority))
|
|
pp = &(*pp)->next;
|
|
<FONT COLOR="#298C52">new</FONT>->next = *pp;
|
|
<FONT COLOR="#298C52">new</FONT>->orig = m;
|
|
<FONT COLOR="#298C52">new</FONT>->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 = &dev->modules;
|
|
|
|
<FONT COLOR="#298C52">while</FONT> (*pp && *pp != m)
|
|
pp = &(*pp)->next;
|
|
<FONT COLOR="#298C52">if</FONT> (*pp == NULL) {
|
|
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn: Module %s not found\n"</FONT>, m-><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->drivers >= <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->channels;
|
|
<FONT COLOR="#298C52">if</FONT> (dev->channels + n > <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->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->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->rcverr, 0, <FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">int</FONT>) * n);
|
|
<FONT COLOR="#298C52">if</FONT> (!(d->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->rcverr);
|
|
kfree(d);
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
}
|
|
memset((<FONT COLOR="#298C52">char</FONT> *) d->rcvcount, 0, <FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">int</FONT>) * n);
|
|
<FONT COLOR="#298C52">if</FONT> (!(d->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->rcvcount);
|
|
kfree(d->rcverr);
|
|
kfree(d);
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
}
|
|
<FONT COLOR="#298C52">for</FONT> (j = 0; j < n; j++) {
|
|
skb_queue_head_init(&d->rpqueue[j]);
|
|
}
|
|
<FONT COLOR="#298C52">if</FONT> (!(d->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->rpqueue);
|
|
kfree(d->rcvcount);
|
|
kfree(d->rcverr);
|
|
kfree(d);
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
}
|
|
memset((<FONT COLOR="#298C52">char</FONT> *) d->rcv_waitq, 0, <FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">struct</FONT> wait_queue *) * n);
|
|
<FONT COLOR="#298C52">if</FONT> (!(d->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->rcv_waitq);
|
|
kfree(d->rpqueue);
|
|
kfree(d->rcvcount);
|
|
kfree(d->rcverr);
|
|
kfree(d);
|
|
<FONT COLOR="#298C52">return</FONT> 0;
|
|
}
|
|
memset((<FONT COLOR="#298C52">char</FONT> *) d->snd_waitq, 0, <FONT COLOR="#298C52">sizeof</FONT>(<FONT COLOR="#298C52">struct</FONT> wait_queue *) * n);
|
|
d->channels = n;
|
|
d->loaded = 1;
|
|
d->maxbufsize = i->maxbufsize;
|
|
d->pktcount = 0;
|
|
d->stavail = 0;
|
|
d->running = 0;
|
|
d->flags = 0;
|
|
d->interface = i;
|
|
<FONT COLOR="#298C52">for</FONT> (drvidx = 0; drvidx < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>; drvidx++)
|
|
<FONT COLOR="#298C52">if</FONT> (!dev->drv[drvidx])
|
|
<FONT COLOR="#298C52">break</FONT>;
|
|
i->channels = drvidx;
|
|
|
|
i->rcvcallb_skb = <A HREF="#isdn_receive_skb_callback">isdn_receive_skb_callback</A>;
|
|
i->statcallb = <A HREF="#isdn_status_callback">isdn_status_callback</A>;
|
|
<FONT COLOR="#298C52">if</FONT> (!strlen(i->id))
|
|
sprintf(i->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 < drvidx; j++)
|
|
<FONT COLOR="#298C52">if</FONT> (!strcmp(i->id, dev->drvid[j]))
|
|
sprintf(i->id, <FONT COLOR="#FF0000">"line%d"</FONT>, drvidx);
|
|
<FONT COLOR="#298C52">for</FONT> (j = 0; j < n; j++)
|
|
<FONT COLOR="#298C52">for</FONT> (k = 0; k < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; k++)
|
|
<FONT COLOR="#298C52">if</FONT> (dev->chanmap[k] < 0) {
|
|
dev->chanmap[k] = j;
|
|
dev->drvmap[k] = drvidx;
|
|
<FONT COLOR="#298C52">break</FONT>;
|
|
}
|
|
dev->drv[drvidx] = d;
|
|
dev->channels += n;
|
|
strcpy(dev->drvid[drvidx], i->id);
|
|
<A HREF="#isdn_info_update">isdn_info_update</A>();
|
|
dev->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(&dev->timer);
|
|
dev->timer.function = <A HREF="#isdn_timer_funct">isdn_timer_funct</A>;
|
|
dev->sem = MUTEX;
|
|
<FONT COLOR="#298C52">for</FONT> (i = 0; i < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++) {
|
|
dev->drvmap[i] = -1;
|
|
dev->chanmap[i] = -1;
|
|
dev->m_idx[i] = -1;
|
|
strcpy(dev->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>, &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>()) < 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(&dev->mdm.cua_modem);
|
|
<FONT COLOR="#298C52">if</FONT> (i <= -2)
|
|
tty_unregister_driver(&dev->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>() < 0) {
|
|
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn: Could not create PPP-device-structs\n"</FONT>);
|
|
tty_unregister_driver(&dev->mdm.tty_modem);
|
|
tty_unregister_driver(&dev->mdm.cua_modem);
|
|
<FONT COLOR="#298C52">for</FONT> (i = 0; i < <A HREF="../includes/isdn.h.shtml#ISDN_MAX_CHANNELS">ISDN_MAX_CHANNELS</A>; i++)
|
|
kfree(dev->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>() < 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(&dev->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(&dev->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 < <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>(&dev->mdm.info[i]);
|
|
kfree(dev->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(&dev->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>
|