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

3152 lines
161 KiB
Plaintext

<HTML>
<!-- Generated by c2html-1.0, Copyright 1998 by Dave Whittington -->
<HEAD>
<TITLE>isdn_net.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_net.c</H1></CENTER>
<HR>
<PRE>
<FONT COLOR=#0000FF>/* $Id$
* Linux ISDN subsystem, network interfaces and related functions (linklevel).
*
* Copyright 1994,95,96 by Fritz Elfert (fritz@wuemaus.franken.de)
* Copyright 1995,96 by 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.73 1998/06/26 22:01:37 keil
* tx_queue_len = 5 was too small
*
* Revision 1.72 1998/06/26 15:12:31 fritz
* Added handling of STAT_ICALL with incomplete CPN.
* Added AT&amp;L for ttyI emulator.
* Added more locking stuff in tty_write.
*
* Revision 1.71 1998/06/18 22:43:08 fritz
* Bugfix: Setting ndev-&gt;do_ioctl had beed accidetly removed at abc-cleanup.
*
* Revision 1.70 1998/06/17 19:50:49 he
* merged with 2.1.10[34] (cosmetics and udelay() -&gt; mdelay())
* brute force fix to avoid Ugh's in isdn_tty_write()
* cleaned up some dead code
*
* Revision 1.69 1998/06/09 12:27:37 cal
* Changed default of local netdev flags: ISDN_NET_STOPPED is default now,
* so autodial is suppressed for that device until it is switched on using
* 'isdnctrl status dev-name on'.
*
* Revision 1.68 1998/06/07 00:20:05 fritz
* abc cleanup.
*
* Revision 1.67 1998/06/02 12:10:08 detabc
* wegen einer einstweiliger verfuegung gegen DW ist zur zeit
* die abc-extension bis zur klaerung der rechtslage nicht verfuegbar
*
* Revision 1.66 1998/05/26 22:39:24 he
* sync'ed with 2.1.102 where appropriate (CAPABILITY changes)
* concap typo
* cleared dev.tbusy in isdn_net BCONN status callback
*
* Revision 1.65 1998/05/22 10:01:11 detabc
* in case of a icmp-unreach condition the tcp-keepalive-entrys
* will be dropped from the internal double-link-list (only abc-extension).
* send icmp unreach only if the skb-&gt;protocol == ETH_P_IP
* speedup abc-no-dchan redial
*
* Revision 1.64 1998/05/07 19:58:39 detabc
* bugfix in abc_delayed_hangup
* optimize keepalive-tests for abc_rawip
*
* Revision 1.63 1998/05/05 23:23:36 detabc
* change ICMP_HOST_UNREACH to ICMP_NET_UNREACH (only abc-ext.)
* set dev-&gt;tbusy to zero in isdn_net_unreachable() (only abc-ext.)
* drop all new packets and send ICMP_NET_UNREACH for
* min. dialwait to max. dialwait * 6 time. (only abc-ext.)
* change random-deliver of packets (small first) from all emcapsulation
* to only rawip with ABC-Router-Flag enabled.
*
* Revision 1.62 1998/05/03 17:40:42 detabc
* Include abc-extension-support for &gt;= 2.1.x Kernels in
* isdn_net.c and isdn_common.c. alpha-test OK and running !
*
* Revision 1.61 1998/04/16 19:19:42 keil
* Fix from vger (tx max qlength)
*
* Revision 1.60 1998/04/14 16:28:49 he
* Fixed user space access with interrupts off and remaining
* copy_{to,from}_user() -&gt; -EFAULT return codes
*
* Revision 1.59 1998/03/07 22:37:33 fritz
* Bugfix: restore_flags missing.
*
* Revision 1.58 1998/03/07 18:21:05 cal
* Dynamic Timeout-Rule-Handling vs. 971110 included
*
* Revision 1.57 1998/02/25 18:31:13 fritz
* Added debugging output in adjust_header.
*
* Revision 1.56 1998/02/25 17:49:42 he
* Changed return codes caused be failing copy_{to,from}_user to -EFAULT
*
* Revision 1.55 1998/02/23 19:38:22 fritz
* Corrected check for modified feature-flags.
*
* Revision 1.54 1998/02/20 17:15:07 fritz
* Changes for recent kernels.
* Ugly workaround for adjusting Ethernet frames with recent kernels.
* replaced direct calls to lowlevel-driver command by common hook.
*
* Revision 1.53 1998/01/31 22:05:54 keil
* Lots of changes for X.25 support:
* Added generic support for connection-controlling encapsulation protocols
* Added support of BHUP status message
* Added support for additional p_encap X25IFACE
* Added support for kernels &gt;= 2.1.72
*
* Revision 1.52 1998/01/31 19:29:51 calle
* Merged changes from and for 2.1.82, not tested only compiled ...
*
* Revision 1.51 1997/10/09 21:28:50 fritz
* New HL&lt;-&gt;LL interface:
* New BSENT callback with nr. of bytes included.
* Sending without ACK.
* New L1 error status (not yet in use).
* Cleaned up obsolete structures.
* Implemented Cisco-SLARP.
* Changed local net-interface data to be dynamically allocated.
* Removed old 2.0 compatibility stuff.
*
* Revision 1.50 1997/10/01 09:20:32 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.49 1997/08/21 14:38:13 fritz
* Bugfix: Did not compile without SyncPPP.
*
* Revision 1.48 1997/06/22 11:57:15 fritz
* Added ability to adjust slave triggerlevel.
*
* Revision 1.47 1997/06/21 10:52:05 fritz
* Removed wrong SET_SKB_FREE in isdn_net_send_skb()
*
* Revision 1.46 1997/06/17 13:05:24 hipp
* Applied Eric's underflow-patches (slightly modified)
*
* Revision 1.45 1997/06/10 16:24:22 hipp
* hard_header changes for syncPPP (now behaves like RAWIP)
*
* Revision 1.44 1997/05/27 15:17:26 fritz
* Added changes for recent 2.1.x kernels:
* changed return type of isdn_close
* queue_task_* -&gt; queue_task
* clear/set_bit -&gt; test_and_... where apropriate.
* changed type of hard_header_cache parameter.
*
* Revision 1.43 1997/03/30 16:51:13 calle
* changed calls to copy_from_user/copy_to_user and removed verify_area
* were possible.
*
* Revision 1.42 1997/03/11 08:43:51 fritz
* Perform a hangup if number is deleted while dialing.
*
* Revision 1.41 1997/03/08 08:16:31 fritz
* Bugfix: Deleting a phone number during dial gave unpredictable results.
*
* Revision 1.40 1997/03/05 21:16:08 fritz
* Fix: did not compile with 2.1.27
*
* Revision 1.39 1997/03/04 21:36:52 fritz
* Added sending ICMP messages when no connetion is possible.
*
* Revision 1.38 1997/02/23 23:41:14 fritz
* Bugfix: Slave interfaces have to be hung up before master.
*
* Revision 1.37 1997/02/11 18:32:51 fritz
* Bugfix in isdn_ppp_free_mpqueue().
*
* Revision 1.36 1997/02/10 21:31:11 fritz
* Changed setup-interface (incoming and outgoing).
*
* Revision 1.35 1997/02/10 20:12:45 fritz
* Changed interface for reporting incoming calls.
*
* Revision 1.34 1997/02/03 23:15:07 fritz
* Reformatted according CodingStyle.
* replaced arp_find prototype by proper include.
* made dev_purge_queues static.
* Bugfix in bogocps calculation.
* removed isdn_net_receive_callback - was never used ;-)
* Misc. fixes for Kernel 2.1.X comaptibility.
*
* Revision 1.33 1997/01/17 01:19:25 fritz
* Applied chargeint patch.
*
* Revision 1.32 1997/01/14 01:29:31 fritz
* Bugfix: isdn_net_hangup() did not reset ISDN_NET_CONNECTED.
*
* Revision 1.31 1997/01/11 23:30:42 fritz
* Speed up dial statemachine.
*
* Revision 1.30 1996/11/25 17:20:50 hipp
* fixed pppbind bug in isdn_net_find_icall()
*
* Revision 1.29 1996/11/13 02:31:38 fritz
* Minor cleanup.
*
* Revision 1.28 1996/10/27 20:49:06 keil
* bugfix to compile without MPP
*
* Revision 1.27 1996/10/25 18:46:01 fritz
* Another bugfix in isdn_net_autohup()
*
* Revision 1.26 1996/10/23 23:05:36 fritz
* Bugfix: Divide by zero in isdn_net_autohup()
*
* Revision 1.25 1996/10/22 23:13:58 fritz
* Changes for compatibility to 2.0.X and 2.1.X kernels.
*
* Revision 1.24 1996/10/11 13:57:40 fritz
* Bugfix: Error in BogoCPS calculation.
*
* Revision 1.23 1996/09/23 01:58:08 fritz
* Fix: With syncPPP encapsulation, discard LCP packets
* when calculating hangup timeout.
*
* Revision 1.22 1996/09/23 00:03:37 fritz
* Fix: did not compile without CONFIG_ISDN_PPP
*
* Revision 1.21 1996/09/07 12:44:50 hipp
* (hopefully) fixed callback problem with syncPPP
* syncPPP network devices now show PPP link encap
*
* Revision 1.20 1996/08/29 20:06:03 fritz
* Bugfix: Transmission timeout had been much to low.
*
* Revision 1.19 1996/08/12 16:24:32 hipp
* removed some (now) obsolete functions for syncPPP in rebuild_header etc.
*
* Revision 1.18 1996/07/03 13:48:51 hipp
* bugfix: Call dev_purge_queues() only for master device
*
* Revision 1.17 1996/06/25 18:37:37 fritz
* Fixed return count for empty return string in isdn_net_getphones().
*
* Revision 1.16 1996/06/24 17:48:08 fritz
* Bugfixes:
* - Did not free channel on unbinding.
* - ioctl returned wrong callback settings.
*
* Revision 1.15 1996/06/16 17:42:54 tsbogend
* fixed problem with IP addresses on Linux/Alpha (long is 8 byte there)
*
* Revision 1.14 1996/06/11 14:54:08 hipp
* minor bugfix in isdn_net_send_skb
* changes in BSENT callback handler for syncPPP
* added lp-&gt;sav_skb stuff
*
* Revision 1.13 1996/06/06 14:25:44 fritz
* Changed loglevel of "incoming ... without OAD" message, since
* with audio support this is quite normal.
*
* Revision 1.12 1996/06/05 02:36:45 fritz
* Minor bugfixes by M. Hipp.
*
* Revision 1.11 1996/05/18 01:36:59 fritz
* Added spelling corrections and some minor changes
* to stay in sync with kernel.
*
* Revision 1.10 1996/05/17 03:49:01 fritz
* Some cleanup.
*
* Revision 1.9 1996/05/06 11:34:57 hipp
* fixed a few bugs
*
* Revision 1.8 1996/04/30 21:04:40 fritz
* Test commit
*
* Revision 1.7 1996/04/30 11:10:42 fritz
* Added Michael's ippp-bind patch.
*
* Revision 1.6 1996/04/30 09:34:35 fritz
* Removed compatibility-macros.
*
* Revision 1.5 1996/04/20 16:28:38 fritz
* Made more parameters of the dial statemachine user-configurable and
* added hangup after dial for more reliability using callback.
* Changed all io going through generic routines in isdn_common.c
* Added missing call to dev_free_skb on failed dialing.
* Added uihdlc encapsulation.
* Fixed isdn_net_setcfg not to destroy interface-flags anymore.
* Misc. typos.
*
* Revision 1.4 1996/02/19 15:23:38 fritz
* Bugfix: Sync-PPP packets got compressed twice, when resent due to
* send-queue-full reject.
*
* Revision 1.3 1996/02/11 02:22:28 fritz
* Changed status- receive-callbacks to use pointer-arrays for finding
* a corresponding interface instead of looping over all interfaces.
* Activate Auto-hangup-timer only when interface is online.
* Some bugfixes in the dialing-statemachine.
* Lot of bugfixes in sk_buff'ized encapsulation handling.
* For speedup connection-setup after dialing, remember sk_buf that triggered
* dialing.
* Fixed isdn_net_log_packet according to different encapsulations.
* Correct ARP-handling for ETHERNET-encapsulation.
*
* Revision 1.2 1996/01/22 05:05:12 fritz
* Changed returncode-logic for isdn_net_start_xmit() and its
* helper-functions.
* Changed handling of buildheader for RAWIP and ETHERNET-encapsulation.
*
* Revision 1.1 1996/01/09 04:12:34 fritz
* Initial revision
*
*/</FONT>
<FONT COLOR=#A521F7>#include</FONT> &lt;linux/config.h&gt;
<FONT COLOR=#A521F7>#define</FONT> <A HREF="isdn_audio.c.shtml#__NO_VERSION__">__NO_VERSION__</A>
<FONT COLOR=#A521F7>#include</FONT> &lt;linux/module.h&gt;
<FONT COLOR=#A521F7>#include</FONT> &lt;linux/isdn.h&gt;
<FONT COLOR=#A521F7>#include</FONT> &lt;net/arp.h&gt;
<FONT COLOR=#A521F7>#include</FONT> &lt;net/icmp.h&gt;
<FONT COLOR=#A521F7>#include</FONT> &lt;net/pkt_sched.h&gt;
<FONT COLOR=#A521F7>#include</FONT> &lt;linux/inetdevice.h&gt;
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"isdn_common.h"</FONT>
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"isdn_net.h"</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"isdn_ppp.h"</FONT>
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR=#A521F7>#include</FONT> &lt;linux/concap.h&gt;
<FONT COLOR=#A521F7>#include</FONT> <FONT COLOR="#FF0000">"isdn_concap.h"</FONT>
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#0000FF>/* Prototypes */</FONT>
<FONT COLOR="#298C52">int</FONT> <A HREF="#isdn_net_force_dial_lp">isdn_net_force_dial_lp</A>(isdn_net_local *);
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT> <A HREF="#isdn_net_start_xmit">isdn_net_start_xmit</A>(<FONT COLOR="#298C52">struct</FONT> sk_buff *, <FONT COLOR="#298C52">struct</FONT> device *);
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT> <A HREF="#isdn_net_xmit">isdn_net_xmit</A>(<FONT COLOR="#298C52">struct</FONT> device *, isdn_net_local *, <FONT COLOR="#298C52">struct</FONT> sk_buff *);
<FONT COLOR="#298C52">char</FONT> *isdn_net_revision = <FONT COLOR="#FF0000">"$Revision$"</FONT>;
<FONT COLOR=#0000FF>/*
* Code for raw-networking over ISDN
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
<A HREF="#isdn_net_unreachable">isdn_net_unreachable</A>(<FONT COLOR="#298C52">struct</FONT> device *dev, <FONT COLOR="#298C52">struct</FONT> sk_buff *skb, <FONT COLOR="#298C52">char</FONT> *reason)
{
<FONT COLOR="#298C52">if</FONT>(skb) {
u_short proto = ntohs(skb-&gt;protocol);
printk(KERN_DEBUG <FONT COLOR="#FF0000">"isdn_net: %s: %s, send ICMP %s\n"</FONT>,
dev-&gt;<A HREF="isdn_common.c.shtml#name">name</A>,
(reason != NULL) ? reason : <FONT COLOR="#FF0000">"unknown"</FONT>,
(proto != ETH_P_IP) ? <FONT COLOR="#FF0000">"Protcol != ETH_P_IP"</FONT> : <FONT COLOR="#FF0000">""</FONT>);
<FONT COLOR="#298C52">if</FONT>(proto == ETH_P_IP) {
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
}
}
<FONT COLOR=#A521F7>#if</FONT> 0
{
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">for</FONT>(i = 0; i &lt; DEV_NUMBUFFS; i++) {
<FONT COLOR="#298C52">struct</FONT> sk_buff *skb;
<FONT COLOR="#298C52">while</FONT>((skb = skb_dequeue(&amp;dev-&gt;buffs[i]))) {
<FONT COLOR="#298C52">if</FONT>(ntohs(skb-&gt;protocol) == ETH_P_IP)
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
dev_kfree_skb(skb);
}
}
}
<FONT COLOR=#A521F7>#endif</FONT>
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_net_reset">isdn_net_reset</A>(<FONT COLOR="#298C52">struct</FONT> device *dev)
{
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR="#298C52">struct</FONT> concap_device_ops * dops =
( (isdn_net_local *) dev-&gt;priv ) -&gt; dops;
<FONT COLOR="#298C52">struct</FONT> concap_proto * cprot =
( (isdn_net_local *) dev-&gt;priv ) -&gt; netdev -&gt; cprot;
<FONT COLOR=#A521F7>#endif</FONT>
ulong flags;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>(); <FONT COLOR=#0000FF>/* Avoid glitch on writes to CMD regs */</FONT>
dev-&gt;interrupt = 0;
dev-&gt;tbusy = 0;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR="#298C52">if</FONT>( cprot &amp;&amp; cprot -&gt; pops &amp;&amp; dops )
cprot -&gt; pops -&gt; restart ( cprot, dev, dops );
<FONT COLOR=#A521F7>#endif</FONT>
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
}
<FONT COLOR=#0000FF>/* Open/initialize the board. */</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_open">isdn_net_open</A>(<FONT COLOR="#298C52">struct</FONT> device *dev)
{
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">struct</FONT> device *p;
<FONT COLOR="#298C52">struct</FONT> in_device *in_dev;
<A HREF="#isdn_net_reset">isdn_net_reset</A>(dev);
dev-&gt;start = 1;
<FONT COLOR=#0000FF>/* Fill in the MAC-level header (not needed, but for compatibility... */</FONT>
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; ETH_ALEN - <FONT COLOR="#298C52">sizeof</FONT>(u32); i++)
dev-&gt;dev_addr[i] = 0xfc;
<FONT COLOR="#298C52">if</FONT> ((in_dev = dev-&gt;ip_ptr) != NULL) {
<FONT COLOR=#0000FF>/*
* Any address will do - we take the first
*/</FONT>
<FONT COLOR="#298C52">struct</FONT> in_ifaddr *ifa = in_dev-&gt;ifa_list;
<FONT COLOR="#298C52">if</FONT> (ifa != NULL)
memcpy(dev-&gt;dev_addr+2, &amp;ifa-&gt;ifa_local, 4);
}
<FONT COLOR=#0000FF>/* If this interface has slaves, start them also */</FONT>
<FONT COLOR="#298C52">if</FONT> ((p = (((isdn_net_local *) dev-&gt;priv)-&gt;slave))) {
<FONT COLOR="#298C52">while</FONT> (p) {
<A HREF="#isdn_net_reset">isdn_net_reset</A>(p);
p-&gt;start = 1;
p = (((isdn_net_local *) p-&gt;priv)-&gt;slave);
}
}
<A HREF="isdn_common.c.shtml#isdn_MOD_INC_USE_COUNT">isdn_MOD_INC_USE_COUNT</A>();
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#0000FF>/*
* Assign an ISDN-channel to a net-interface
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
<A HREF="#isdn_net_bind_channel">isdn_net_bind_channel</A>(isdn_net_local * lp, <FONT COLOR="#298C52">int</FONT> idx)
{
ulong flags;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
lp-&gt;isdn_device = dev-&gt;drvmap[idx];
lp-&gt;isdn_channel = dev-&gt;chanmap[idx];
dev-&gt;rx_netdev[idx] = lp-&gt;netdev;
dev-&gt;st_netdev[idx] = lp-&gt;netdev;
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
}
<FONT COLOR=#0000FF>/*
* unbind a net-interface (resets interface after an error)
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_net_unbind_channel">isdn_net_unbind_channel</A>(isdn_net_local * lp)
{
ulong flags;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<FONT COLOR="#298C52">if</FONT> (lp-&gt;first_skb) {
dev_kfree_skb(lp-&gt;first_skb);
lp-&gt;first_skb = NULL;
}
<FONT COLOR="#298C52">if</FONT> (lp-&gt;sav_skb) {
dev_kfree_skb(lp-&gt;sav_skb);
lp-&gt;sav_skb = NULL;
}
<FONT COLOR="#298C52">if</FONT> (!lp-&gt;master) { <FONT COLOR=#0000FF>/* reset only master device */</FONT>
<FONT COLOR=#0000FF>/* Moral equivalent of dev_purge_queues():
BEWARE! This chunk of code cannot be called from hardware
interrupt handler. I hope it is true. --ANK
*/</FONT>
qdisc_reset(lp-&gt;netdev-&gt;dev.qdisc);
}
lp-&gt;dialstate = 0;
dev-&gt;rx_netdev[<A HREF="isdn_common.c.shtml#isdn_dc2minor">isdn_dc2minor</A>(lp-&gt;isdn_device, lp-&gt;isdn_channel)] = NULL;
dev-&gt;st_netdev[<A HREF="isdn_common.c.shtml#isdn_dc2minor">isdn_dc2minor</A>(lp-&gt;isdn_device, lp-&gt;isdn_channel)] = NULL;
<A HREF="isdn_common.c.shtml#isdn_free_channel">isdn_free_channel</A>(lp-&gt;isdn_device, lp-&gt;isdn_channel, <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_NET">ISDN_USAGE_NET</A>);
lp-&gt;flags &amp;= ~<A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>;
lp-&gt;isdn_device = -1;
lp-&gt;isdn_channel = -1;
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
}
<FONT COLOR=#0000FF>/*
* Perform auto-hangup and cps-calculation for net-interfaces.
*
* auto-hangup:
* Increment idle-counter (this counter is reset on any incoming or
* outgoing packet), if counter exceeds configured limit either do a
* hangup immediately or - if configured - wait until just before the next
* charge-info.
*
* cps-calculation (needed for dynamic channel-bundling):
* Since this function is called every second, simply reset the
* byte-counter of the interface after copying it to the cps-variable.
*/</FONT>
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">long</FONT> last_jiffies = -HZ;
<FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_net_autohup">isdn_net_autohup</A>()
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p = dev-&gt;netdev;
<FONT COLOR="#298C52">int</FONT> anymore;
anymore = 0;
<FONT COLOR="#298C52">while</FONT> (p) {
isdn_net_local *l = p-&gt;local;
<FONT COLOR="#298C52">if</FONT> ((jiffies - last_jiffies) == 0)
l-&gt;cps = l-&gt;transcount;
<FONT COLOR="#298C52">else</FONT>
l-&gt;cps = (l-&gt;transcount * HZ) / (jiffies - last_jiffies);
l-&gt;transcount = 0;
<FONT COLOR="#298C52">if</FONT> (dev-&gt;net_verbose &gt; 3)
printk(KERN_DEBUG <FONT COLOR="#FF0000">"%s: %d bogocps\n"</FONT>, l-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, l-&gt;cps);
<FONT COLOR="#298C52">if</FONT> ((l-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>) &amp;&amp; (!l-&gt;dialstate)) {
anymore = 1;
l-&gt;huptimer++;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_TIMEOUT_RULES
<FONT COLOR="#298C52">if</FONT> ((l-&gt;timeout_rules || l-&gt;huptimeout) &amp;&amp; l-&gt;huptimer &gt; l-&gt;huptimeout)
<FONT COLOR=#A521F7>#else</FONT>
<FONT COLOR="#298C52">if</FONT> ((l-&gt;onhtime) &amp;&amp; (l-&gt;huptimer &gt; l-&gt;onhtime))
<FONT COLOR=#A521F7>#endif</FONT>
{
<FONT COLOR="#298C52">if</FONT> (l-&gt;hupflags &amp; <A HREF="isdn_net.h.shtml#ISDN_MANCHARGE">ISDN_MANCHARGE</A> &amp;&amp;
l-&gt;hupflags &amp; <A HREF="isdn_net.h.shtml#ISDN_CHARGEHUP">ISDN_CHARGEHUP</A>) {
<FONT COLOR="#298C52">while</FONT> (jiffies - l-&gt;chargetime &gt; l-&gt;chargeint)
l-&gt;chargetime += l-&gt;chargeint;
<FONT COLOR="#298C52">if</FONT> (jiffies - l-&gt;chargetime &gt;= l-&gt;chargeint - 2 * HZ)
<FONT COLOR="#298C52">if</FONT> (l-&gt;outgoing || l-&gt;hupflags &amp; <A HREF="isdn_net.h.shtml#ISDN_INHUP">ISDN_INHUP</A>)
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
} <FONT COLOR="#298C52">else</FONT> <FONT COLOR="#298C52">if</FONT> (l-&gt;outgoing) {
<FONT COLOR="#298C52">if</FONT> (l-&gt;hupflags &amp; <A HREF="isdn_net.h.shtml#ISDN_CHARGEHUP">ISDN_CHARGEHUP</A>) {
<FONT COLOR="#298C52">if</FONT> (l-&gt;hupflags &amp; <A HREF="isdn_net.h.shtml#ISDN_WAITCHARGE">ISDN_WAITCHARGE</A>) {
printk(KERN_DEBUG <FONT COLOR="#FF0000">"isdn_net: Hupflags of %s are %X\n"</FONT>,
l-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, l-&gt;hupflags);
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
} <FONT COLOR="#298C52">else</FONT> <FONT COLOR="#298C52">if</FONT> (jiffies - l-&gt;chargetime &gt; l-&gt;chargeint) {
printk(KERN_DEBUG
<FONT COLOR="#FF0000">"isdn_net: %s: chtime = %d, chint = %d\n"</FONT>,
l-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, l-&gt;chargetime, l-&gt;chargeint);
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
}
} <FONT COLOR="#298C52">else</FONT>
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
} <FONT COLOR="#298C52">else</FONT> <FONT COLOR="#298C52">if</FONT> (l-&gt;hupflags &amp; <A HREF="isdn_net.h.shtml#ISDN_INHUP">ISDN_INHUP</A>)
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
}
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_BUDGET
<FONT COLOR="#298C52">if</FONT>(<A HREF="isdn_budget.c.shtml#isdn_net_budget">isdn_net_budget</A>(<A HREF="../includes/isdn_budget.h.shtml#ISDN_BUDGET_CHECK_ONLINE">ISDN_BUDGET_CHECK_ONLINE</A>, &amp;p-&gt;dev)) {
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
}
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT>(dev-&gt;global_flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A> || l-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_STOPPED">ISDN_NET_STOPPED</A>) {
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
<FONT COLOR="#298C52">break</FONT>;
}
}
p = (<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *) p-&gt;next;
}
last_jiffies = jiffies;
<A HREF="isdn_common.c.shtml#isdn_timer_ctrl">isdn_timer_ctrl</A>(<A HREF="../includes/isdn.h.shtml#ISDN_TIMER_NETHANGUP">ISDN_TIMER_NETHANGUP</A>, anymore);
}
<FONT COLOR=#0000FF>/*
* Handle status-messages from ISDN-interfacecard.
* This function is called from within the main-status-dispatcher
* isdn_status_callback, which itself is called from the low-level driver.
* Return: 1 = Event handled, 0 = not for us or unknown Event.
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_stat_callback">isdn_net_stat_callback</A>(<FONT COLOR="#298C52">int</FONT> idx, <A HREF="../includes/isdnif.h.shtml#isdn_ctrl">isdn_ctrl</A> *c)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p = dev-&gt;st_netdev[idx];
<FONT COLOR="#298C52">int</FONT> cmd = c-&gt;command;
<FONT COLOR="#298C52">if</FONT> (p) {
isdn_net_local *lp = p-&gt;local;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR="#298C52">struct</FONT> concap_proto *cprot = lp -&gt; netdev -&gt; cprot;
<FONT COLOR="#298C52">struct</FONT> concap_proto_ops *pops = cprot ? cprot -&gt; pops : 0;
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">switch</FONT> (cmd) {
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_BSENT">ISDN_STAT_BSENT</A>:
<FONT COLOR=#0000FF>/* A packet has successfully been sent out */</FONT>
<FONT COLOR="#298C52">if</FONT> ((lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>) &amp;&amp;
(!lp-&gt;dialstate)) {
lp-&gt;stats.tx_packets++;
lp-&gt;stats.tx_bytes += c-&gt;parm.length;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;p_encap == <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_SYNCPPP">ISDN_NET_ENCAP_SYNCPPP</A> &amp;&amp; lp-&gt;sav_skb) {
<FONT COLOR="#298C52">struct</FONT> device *mdev;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;master)
mdev = lp-&gt;master;
<FONT COLOR="#298C52">else</FONT>
mdev = &amp;lp-&gt;netdev-&gt;dev;
<FONT COLOR="#298C52">if</FONT> (!<A HREF="#isdn_net_send_skb">isdn_net_send_skb</A>(mdev, lp, lp-&gt;sav_skb)) {
lp-&gt;sav_skb = NULL;
mark_bh(NET_BH);
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR="#298C52">return</FONT> 1;
}
}
<FONT COLOR="#298C52">if</FONT> (test_and_clear_bit(0, (<FONT COLOR="#298C52">void</FONT> *) &amp;(p-&gt;dev.tbusy)))
mark_bh(NET_BH);
}
<FONT COLOR="#298C52">return</FONT> 1;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_DCONN">ISDN_STAT_DCONN</A>:
<FONT COLOR=#0000FF>/* D-Channel is up */</FONT>
<FONT COLOR="#298C52">switch</FONT> (lp-&gt;dialstate) {
<FONT COLOR="#298C52">case</FONT> 4:
<FONT COLOR="#298C52">case</FONT> 7:
<FONT COLOR="#298C52">case</FONT> 8:
lp-&gt;dialstate++;
<FONT COLOR="#298C52">return</FONT> 1;
<FONT COLOR="#298C52">case</FONT> 12:
lp-&gt;dialstate = 5;
<FONT COLOR="#298C52">return</FONT> 1;
}
<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=#0000FF>/* Either D-Channel-hangup or error during dialout */</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR=#0000FF>/* If we are not connencted then dialing had
failed. If there are generic encap protocol
receiver routines signal the closure of
the link*/</FONT>
<FONT COLOR="#298C52">if</FONT>( !(lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>)
&amp;&amp; pops &amp;&amp; pops -&gt; disconn_ind )
pops -&gt; disconn_ind(cprot);
<FONT COLOR=#A521F7>#endif</FONT> <FONT COLOR=#0000FF>/* CONFIG_ISDN_X25 */</FONT>
<FONT COLOR="#298C52">if</FONT> ((!lp-&gt;dialstate) &amp;&amp; (lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>)) {
lp-&gt;flags &amp;= ~<A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;first_skb) {
dev_kfree_skb(lp-&gt;first_skb);
lp-&gt;first_skb = NULL;
}
<FONT COLOR="#298C52">if</FONT> (lp-&gt;sav_skb) {
dev_kfree_skb(lp-&gt;sav_skb);
lp-&gt;sav_skb = NULL;
}
<A HREF="isdn_common.c.shtml#isdn_free_channel">isdn_free_channel</A>(lp-&gt;isdn_device, lp-&gt;isdn_channel,
<A HREF="../includes/isdn.h.shtml#ISDN_USAGE_NET">ISDN_USAGE_NET</A>);
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<A HREF="isdn_ppp.c.shtml#isdn_ppp_free">isdn_ppp_free</A>(lp);
<FONT COLOR=#A521F7>#endif</FONT>
<A HREF="isdn_common.c.shtml#isdn_all_eaz">isdn_all_eaz</A>(lp-&gt;isdn_device, lp-&gt;isdn_channel);
printk(KERN_INFO <FONT COLOR="#FF0000">"%s: remote hangup\n"</FONT>, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
printk(KERN_INFO <FONT COLOR="#FF0000">"%s: Chargesum is %d\n"</FONT>, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>,
lp-&gt;charge);
lp-&gt;isdn_device = -1;
lp-&gt;isdn_channel = -1;
dev-&gt;st_netdev[idx] = NULL;
dev-&gt;rx_netdev[idx] = NULL;
<FONT COLOR="#298C52">return</FONT> 1;
}
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_BHUP">ISDN_STAT_BHUP</A>:
<FONT COLOR=#0000FF>/* B-Channel-hangup */</FONT>
<FONT COLOR=#0000FF>/* try if there are generic encap protocol
receiver routines and signal the closure of
the link */</FONT>
<FONT COLOR="#298C52">if</FONT>( pops &amp;&amp; pops -&gt; disconn_ind ){
pops -&gt; disconn_ind(cprot);
<FONT COLOR="#298C52">return</FONT> 1;
}
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR=#A521F7>#endif</FONT> <FONT COLOR=#0000FF>/* CONFIG_ISDN_X25 */</FONT>
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdnif.h.shtml#ISDN_STAT_BCONN">ISDN_STAT_BCONN</A>:
<FONT COLOR=#0000FF>/* B-Channel is up */</FONT>
<FONT COLOR="#298C52">switch</FONT> (lp-&gt;dialstate) {
<FONT COLOR="#298C52">case</FONT> 5:
<FONT COLOR="#298C52">case</FONT> 6:
<FONT COLOR="#298C52">case</FONT> 7:
<FONT COLOR="#298C52">case</FONT> 8:
<FONT COLOR="#298C52">case</FONT> 9:
<FONT COLOR="#298C52">case</FONT> 10:
<FONT COLOR="#298C52">case</FONT> 12:
<FONT COLOR="#298C52">if</FONT> (lp-&gt;dialstate &lt;= 6) {
dev-&gt;usage[idx] |= <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_OUTGOING">ISDN_USAGE_OUTGOING</A>;
<A HREF="isdn_common.c.shtml#isdn_info_update">isdn_info_update</A>();
} <FONT COLOR="#298C52">else</FONT>
dev-&gt;rx_netdev[idx] = p;
lp-&gt;dialstate = 0;
<A HREF="isdn_common.c.shtml#isdn_timer_ctrl">isdn_timer_ctrl</A>(<A HREF="../includes/isdn.h.shtml#ISDN_TIMER_NETHANGUP">ISDN_TIMER_NETHANGUP</A>, 1);
<FONT COLOR="#298C52">if</FONT> (lp-&gt;p_encap == <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_CISCOHDLCK">ISDN_NET_ENCAP_CISCOHDLCK</A>)
<A HREF="isdn_common.c.shtml#isdn_timer_ctrl">isdn_timer_ctrl</A>(<A HREF="../includes/isdn.h.shtml#ISDN_TIMER_KEEPALIVE">ISDN_TIMER_KEEPALIVE</A>, 1);
printk(KERN_INFO <FONT COLOR="#FF0000">"isdn_net: %s connected\n"</FONT>, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR=#0000FF>/* If first Chargeinfo comes before B-Channel connect,
* we correct the timestamp here.
*/</FONT>
lp-&gt;chargetime = jiffies;
printk(KERN_DEBUG <FONT COLOR="#FF0000">"isdn_net: chargetime of %s now %d\n"</FONT>,
lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, lp-&gt;chargetime);
<FONT COLOR=#0000FF>/* reset dial-timeout */</FONT>
lp-&gt;dialstarted = 0;
lp-&gt;dialwait_timer = 0;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_BUDGET
(<FONT COLOR="#298C52">void</FONT>)<A HREF="isdn_budget.c.shtml#isdn_net_budget">isdn_net_budget</A>(<A HREF="../includes/isdn_budget.h.shtml#ISDN_BUDGET_START_ONLINE">ISDN_BUDGET_START_ONLINE</A>, &amp;p-&gt;dev);
(<FONT COLOR="#298C52">void</FONT>)<A HREF="isdn_budget.c.shtml#isdn_net_budget">isdn_net_budget</A>(<A HREF="../includes/isdn_budget.h.shtml#ISDN_BUDGET_CHECK_CHARGE">ISDN_BUDGET_CHECK_CHARGE</A>, &amp;p-&gt;dev);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#0000FF>/* Immediately send first skb to speed up arp */</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">if</FONT> (lp-&gt;p_encap == <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_SYNCPPP">ISDN_NET_ENCAP_SYNCPPP</A>)
<A HREF="isdn_ppp.c.shtml#isdn_ppp_wakeup_daemon">isdn_ppp_wakeup_daemon</A>(lp);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR=#0000FF>/* try if there are generic concap receiver routines */</FONT>
<FONT COLOR="#298C52">if</FONT>( pops )
<FONT COLOR="#298C52">if</FONT>( pops-&gt;connect_ind)
pops-&gt;connect_ind(cprot);
<FONT COLOR=#A521F7>#endif</FONT> <FONT COLOR=#0000FF>/* CONFIG_ISDN_X25 */</FONT>
<FONT COLOR="#298C52">if</FONT> (lp-&gt;first_skb) {
<FONT COLOR="#298C52">if</FONT> (!(<A HREF="#isdn_net_xmit">isdn_net_xmit</A>(&amp;p-&gt;dev, lp, lp-&gt;first_skb)))
lp-&gt;first_skb = NULL;
}
<FONT COLOR="#298C52">else</FONT> {
<FONT COLOR=#0000FF>/*
* dev.tbusy is usually cleared implicitly by isdn_net_xmit(,,lp-&gt;first_skb).
* With an empty lp-&gt;first_skb, we need to do this ourselves
*/</FONT>
lp-&gt;netdev-&gt;dev.tbusy = 0;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_TIMEOUT_RULES
<FONT COLOR=#0000FF>/* recalc initial huptimeout,
there is no packet to match the rules. */</FONT>
<A HREF="isdn_timru.c.shtml#isdn_net_recalc_timeout">isdn_net_recalc_timeout</A>(<A HREF="../includes/isdn_timru.h.shtml#ISDN_TIMRU_BRINGUP">ISDN_TIMRU_BRINGUP</A>, <A HREF="../includes/isdn_timru.h.shtml#ISDN_TIMRU_PACKET_NONE">ISDN_TIMRU_PACKET_NONE</A>, &amp;p-&gt;dev, NULL, 0);
<FONT COLOR=#A521F7>#endif</FONT>
}
<FONT COLOR="#298C52">return</FONT> 1;
}
<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=#0000FF>/* No D-Channel avail. */</FONT>
<FONT COLOR="#298C52">if</FONT> (lp-&gt;dialstate == 4) {
lp-&gt;dialstate--;
<FONT COLOR="#298C52">return</FONT> 1;
}
<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=#0000FF>/* Charge-info from TelCo. Calculate interval between
* charge-infos and set timestamp for last info for
* usage by isdn_net_autohup()
*/</FONT>
lp-&gt;charge++;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;hupflags &amp; <A HREF="isdn_net.h.shtml#ISDN_HAVECHARGE">ISDN_HAVECHARGE</A>) {
lp-&gt;hupflags &amp;= ~<A HREF="isdn_net.h.shtml#ISDN_WAITCHARGE">ISDN_WAITCHARGE</A>;
lp-&gt;chargeint = jiffies - lp-&gt;chargetime - (2 * HZ);
}
<FONT COLOR="#298C52">if</FONT> (lp-&gt;hupflags &amp; <A HREF="isdn_net.h.shtml#ISDN_WAITCHARGE">ISDN_WAITCHARGE</A>)
lp-&gt;hupflags |= <A HREF="isdn_net.h.shtml#ISDN_HAVECHARGE">ISDN_HAVECHARGE</A>;
lp-&gt;chargetime = jiffies;
printk(KERN_DEBUG <FONT COLOR="#FF0000">"isdn_net: Got CINF chargetime of %s now %d\n"</FONT>,
lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, lp-&gt;chargetime);
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_BUDGET
<FONT COLOR="#298C52">if</FONT>(<A HREF="isdn_budget.c.shtml#isdn_net_budget">isdn_net_budget</A>(<A HREF="../includes/isdn_budget.h.shtml#ISDN_BUDGET_CHECK_CHARGE">ISDN_BUDGET_CHECK_CHARGE</A>, &amp;p-&gt;dev)) {
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
}
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">return</FONT> 1;
}
}
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#0000FF>/*
* Check, if a number contains wildcard-characters, in which case it
* is for incoming purposes only.
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_checkwild">isdn_net_checkwild</A>(<FONT COLOR="#298C52">char</FONT> *num)
{
<FONT COLOR="#298C52">return</FONT> ((strchr(num, <FONT COLOR="#FF0000">'?'</FONT>)) ||
(strchr(num, <FONT COLOR="#FF0000">'*'</FONT>)) ||
(strchr(num, <FONT COLOR="#FF0000">'['</FONT>)) ||
(strchr(num, <FONT COLOR="#FF0000">']'</FONT>)) ||
(strchr(num, <FONT COLOR="#FF0000">'^'</FONT>)));
}
<FONT COLOR=#0000FF>/*
* Perform dialout for net-interfaces and timeout-handling for
* D-Channel-up and B-Channel-up Messages.
* This function is initially called from within isdn_net_start_xmit() or
* or isdn_net_find_icall() after initializing the dialstate for an
* interface. If further calls are needed, the function schedules itself
* for a timer-callback via isdn_timer_function().
* The dialstate is also affected by incoming status-messages from
* the ISDN-Channel which are handled in isdn_net_stat_callback() above.
*/</FONT>
<FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_net_dial">isdn_net_dial</A>(<FONT COLOR="#298C52">void</FONT>)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p = dev-&gt;netdev;
<FONT COLOR="#298C52">int</FONT> anymore = 0;
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">int</FONT> flags;
<A HREF="../includes/isdnif.h.shtml#isdn_ctrl">isdn_ctrl</A> cmd;
<FONT COLOR="#298C52">while</FONT> (p) {
isdn_net_local *lp = p-&gt;local;
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_DIAL
<FONT COLOR="#298C52">if</FONT> (lp-&gt;dialstate)
printk(KERN_DEBUG <FONT COLOR="#FF0000">"%s: dialstate=%d\n"</FONT>, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, lp-&gt;dialstate);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">switch</FONT> (lp-&gt;dialstate) {
<FONT COLOR="#298C52">case</FONT> 0:
<FONT COLOR=#0000FF>/* Nothing to do for this interface */</FONT>
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 1:
<FONT COLOR=#0000FF>/* Initiate dialout. Set phone-number-pointer to first number
* of interface.
*/</FONT>
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
lp-&gt;dial = lp-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>[1];
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">if</FONT> (!lp-&gt;dial) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"%s: phone number deleted?\n"</FONT>,
lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
<FONT COLOR="#298C52">break</FONT>;
}
anymore = 1;
<FONT COLOR="#298C52">if</FONT>(lp-&gt;dialtimeout &gt; 0)
<FONT COLOR="#298C52">if</FONT>(lp-&gt;dialstarted == 0 || jiffies &gt; (lp-&gt;dialstarted + lp-&gt;dialtimeout + lp-&gt;dialwait)) {
lp-&gt;dialstarted = jiffies;
lp-&gt;dialwait_timer = 0;
}
lp-&gt;dialstate++;
<FONT COLOR=#0000FF>/* Fall through */</FONT>
<FONT COLOR="#298C52">case</FONT> 2:
<FONT COLOR=#0000FF>/* Prepare dialing. Clear EAZ, then set EAZ. */</FONT>
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = lp-&gt;isdn_device;
cmd.arg = lp-&gt;isdn_channel;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_CLREAZ">ISDN_CMD_CLREAZ</A>;
<A HREF="isdn_common.c.shtml#isdn_command">isdn_command</A>(&amp;cmd);
sprintf(cmd.parm.num, <FONT COLOR="#FF0000">"%s"</FONT>, <A HREF="isdn_common.c.shtml#isdn_map_eaz2msn">isdn_map_eaz2msn</A>(lp-&gt;msn, cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A>));
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_SETEAZ">ISDN_CMD_SETEAZ</A>;
<A HREF="isdn_common.c.shtml#isdn_command">isdn_command</A>(&amp;cmd);
lp-&gt;dialretry = 0;
anymore = 1;
lp-&gt;dialstate++;
<FONT COLOR=#0000FF>/* Falls through */</FONT>
<FONT COLOR="#298C52">case</FONT> 3:
<FONT COLOR=#0000FF>/* Setup interface, dial current phone-number, switch to next number.
* If list of phone-numbers is exhausted, increment
* retry-counter.
*/</FONT>
<FONT COLOR="#298C52">if</FONT>(dev-&gt;global_flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_GLOBAL_STOPPED">ISDN_GLOBAL_STOPPED</A> || lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_STOPPED">ISDN_NET_STOPPED</A>) {
<A HREF="#isdn_net_unreachable">isdn_net_unreachable</A>(&amp;p-&gt;dev, lp-&gt;first_skb, <FONT COLOR="#FF0000">"dial suppressed: isdn stopped"</FONT>);
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
<FONT COLOR="#298C52">break</FONT>;
}
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = lp-&gt;isdn_device;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_SETL2">ISDN_CMD_SETL2</A>;
cmd.arg = lp-&gt;isdn_channel + (lp-&gt;l2_proto &lt;&lt; 8);
<A HREF="isdn_common.c.shtml#isdn_command">isdn_command</A>(&amp;cmd);
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = lp-&gt;isdn_device;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_SETL3">ISDN_CMD_SETL3</A>;
cmd.arg = lp-&gt;isdn_channel + (lp-&gt;l3_proto &lt;&lt; 8);
<A HREF="isdn_common.c.shtml#isdn_command">isdn_command</A>(&amp;cmd);
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = lp-&gt;isdn_device;
cmd.arg = lp-&gt;isdn_channel;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<FONT COLOR="#298C52">if</FONT> (!lp-&gt;dial) {
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
printk(KERN_WARNING <FONT COLOR="#FF0000">"%s: phone number deleted?\n"</FONT>,
lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
<FONT COLOR="#298C52">break</FONT>;
}
<FONT COLOR="#298C52">if</FONT> (!strcmp(lp-&gt;dial-&gt;num, <FONT COLOR="#FF0000">"LEASED"</FONT>)) {
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
lp-&gt;dialstate = 4;
printk(KERN_INFO <FONT COLOR="#FF0000">"%s: Open leased line ...\n"</FONT>, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_BUDGET
<FONT COLOR="#298C52">if</FONT>(<A HREF="isdn_budget.c.shtml#isdn_net_budget">isdn_net_budget</A>(<A HREF="../includes/isdn_budget.h.shtml#ISDN_BUDGET_CHECK_DIAL">ISDN_BUDGET_CHECK_DIAL</A>, &amp;p-&gt;dev)) {
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<A HREF="#isdn_net_unreachable">isdn_net_unreachable</A>(&amp;p-&gt;dev, lp-&gt;first_skb, <FONT COLOR="#FF0000">"dial: budget(s) used up"</FONT>);
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
<FONT COLOR="#298C52">break</FONT>;
}
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT>(lp-&gt;dialtimeout &gt; 0)
<FONT COLOR="#298C52">if</FONT>(jiffies &gt; (lp-&gt;dialstarted + lp-&gt;dialtimeout)) {
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
lp-&gt;dialwait_timer = jiffies + lp-&gt;dialwait;
lp-&gt;dialstarted = 0;
<A HREF="#isdn_net_unreachable">isdn_net_unreachable</A>(&amp;p-&gt;dev, lp-&gt;first_skb, <FONT COLOR="#FF0000">"dial: timed out"</FONT>);
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
<FONT COLOR="#298C52">break</FONT>;
}
sprintf(cmd.parm.setup.<A HREF="isdn_common.c.shtml#phone">phone</A>, <FONT COLOR="#FF0000">"%s"</FONT>, lp-&gt;dial-&gt;num);
<FONT COLOR=#0000FF>/*
* Switch to next number or back to start if at end of list.
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (!(lp-&gt;dial = (<A HREF="../includes/isdn.h.shtml#isdn_net_phone">isdn_net_phone</A> *) lp-&gt;dial-&gt;next)) {
lp-&gt;dial = lp-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>[1];
lp-&gt;dialretry++;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;dialretry &gt; lp-&gt;dialmax) {
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">if</FONT> (lp-&gt;dialtimeout == 0) {
lp-&gt;dialwait_timer = jiffies + lp-&gt;dialwait;
lp-&gt;dialstarted = 0;
<A HREF="#isdn_net_unreachable">isdn_net_unreachable</A>(&amp;p-&gt;dev, lp-&gt;first_skb, <FONT COLOR="#FF0000">"dial: tried all numbers dialmax times"</FONT>);
}
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
<FONT COLOR="#298C52">break</FONT>;
}
}
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = lp-&gt;isdn_device;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_DIAL">ISDN_CMD_DIAL</A>;
cmd.parm.setup.si1 = 7;
cmd.parm.setup.si2 = 0;
sprintf(cmd.parm.setup.eazmsn, <FONT COLOR="#FF0000">"%s"</FONT>,
<A HREF="isdn_common.c.shtml#isdn_map_eaz2msn">isdn_map_eaz2msn</A>(lp-&gt;msn, cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A>));
i = <A HREF="isdn_common.c.shtml#isdn_dc2minor">isdn_dc2minor</A>(lp-&gt;isdn_device, lp-&gt;isdn_channel);
<FONT COLOR="#298C52">if</FONT> (i &gt;= 0) {
strcpy(dev-&gt;num[i], cmd.parm.setup.<A HREF="isdn_common.c.shtml#phone">phone</A>);
<A HREF="isdn_common.c.shtml#isdn_info_update">isdn_info_update</A>();
}
printk(KERN_INFO <FONT COLOR="#FF0000">"%s: dialing %d %s...\n"</FONT>, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>,
lp-&gt;dialretry, cmd.parm.setup.<A HREF="isdn_common.c.shtml#phone">phone</A>);
lp-&gt;dtimer = 0;
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_DIAL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"dial: d=%d c=%d\n"</FONT>, lp-&gt;isdn_device,
lp-&gt;isdn_channel);
<FONT COLOR=#A521F7>#endif</FONT>
<A HREF="isdn_common.c.shtml#isdn_command">isdn_command</A>(&amp;cmd);
}
lp-&gt;huptimer = 0;
lp-&gt;outgoing = 1;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;chargeint) {
lp-&gt;hupflags |= <A HREF="isdn_net.h.shtml#ISDN_HAVECHARGE">ISDN_HAVECHARGE</A>;
lp-&gt;hupflags &amp;= ~<A HREF="isdn_net.h.shtml#ISDN_WAITCHARGE">ISDN_WAITCHARGE</A>;
} <FONT COLOR="#298C52">else</FONT> {
lp-&gt;hupflags |= <A HREF="isdn_net.h.shtml#ISDN_WAITCHARGE">ISDN_WAITCHARGE</A>;
lp-&gt;hupflags &amp;= ~<A HREF="isdn_net.h.shtml#ISDN_HAVECHARGE">ISDN_HAVECHARGE</A>;
}
anymore = 1;
lp-&gt;dialstate =
(lp-&gt;cbdelay &amp;&amp;
(lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CBOUT">ISDN_NET_CBOUT</A>)) ? 12 : 4;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 4:
<FONT COLOR=#0000FF>/* Wait for D-Channel-connect.
* If timeout, switch back to state 3.
* Dialmax-handling moved to state 3.
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (lp-&gt;dtimer++ &gt; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_DTIMEOUT10">ISDN_TIMER_DTIMEOUT10</A>)
lp-&gt;dialstate = 3;
anymore = 1;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 5:
<FONT COLOR=#0000FF>/* Got D-Channel-Connect, send B-Channel-request */</FONT>
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = lp-&gt;isdn_device;
cmd.arg = lp-&gt;isdn_channel;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_ACCEPTB">ISDN_CMD_ACCEPTB</A>;
anymore = 1;
lp-&gt;dtimer = 0;
lp-&gt;dialstate++;
<A HREF="isdn_common.c.shtml#isdn_command">isdn_command</A>(&amp;cmd);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 6:
<FONT COLOR=#0000FF>/* Wait for B- or D-Channel-connect. If timeout,
* switch back to state 3.
*/</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_DIAL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"dialtimer2: %d\n"</FONT>, lp-&gt;dtimer);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (lp-&gt;dtimer++ &gt; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_DTIMEOUT10">ISDN_TIMER_DTIMEOUT10</A>)
lp-&gt;dialstate = 3;
anymore = 1;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 7:
<FONT COLOR=#0000FF>/* Got incoming Call, setup L2 and L3 protocols,
* then wait for D-Channel-connect
*/</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_DIAL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"dialtimer4: %d\n"</FONT>, lp-&gt;dtimer);
<FONT COLOR=#A521F7>#endif</FONT>
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = lp-&gt;isdn_device;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_SETL2">ISDN_CMD_SETL2</A>;
cmd.arg = lp-&gt;isdn_channel + (lp-&gt;l2_proto &lt;&lt; 8);
<A HREF="isdn_common.c.shtml#isdn_command">isdn_command</A>(&amp;cmd);
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = lp-&gt;isdn_device;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_SETL3">ISDN_CMD_SETL3</A>;
cmd.arg = lp-&gt;isdn_channel + (lp-&gt;l3_proto &lt;&lt; 8);
<A HREF="isdn_common.c.shtml#isdn_command">isdn_command</A>(&amp;cmd);
<FONT COLOR="#298C52">if</FONT> (lp-&gt;dtimer++ &gt; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_DTIMEOUT15">ISDN_TIMER_DTIMEOUT15</A>)
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
<FONT COLOR="#298C52">else</FONT> {
anymore = 1;
lp-&gt;dialstate++;
}
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 9:
<FONT COLOR=#0000FF>/* Got incoming D-Channel-Connect, send B-Channel-request */</FONT>
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = lp-&gt;isdn_device;
cmd.arg = lp-&gt;isdn_channel;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_ACCEPTB">ISDN_CMD_ACCEPTB</A>;
<A HREF="isdn_common.c.shtml#isdn_command">isdn_command</A>(&amp;cmd);
anymore = 1;
lp-&gt;dtimer = 0;
lp-&gt;dialstate++;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 8:
<FONT COLOR="#298C52">case</FONT> 10:
<FONT COLOR=#0000FF>/* Wait for B- or D-channel-connect */</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_DIAL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"dialtimer4: %d\n"</FONT>, lp-&gt;dtimer);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (lp-&gt;dtimer++ &gt; <A HREF="../includes/isdn.h.shtml#ISDN_TIMER_DTIMEOUT10">ISDN_TIMER_DTIMEOUT10</A>)
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
<FONT COLOR="#298C52">else</FONT>
anymore = 1;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 11:
<FONT COLOR=#0000FF>/* Callback Delay */</FONT>
<FONT COLOR="#298C52">if</FONT> (lp-&gt;dtimer++ &gt; lp-&gt;cbdelay)
lp-&gt;dialstate = 1;
anymore = 1;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 12:
<FONT COLOR=#0000FF>/* Remote does callback. Hangup after cbdelay, then wait for incoming
* call (in state 4).
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (lp-&gt;dtimer++ &gt; lp-&gt;cbdelay)
{
printk(KERN_INFO <FONT COLOR="#FF0000">"%s: hangup waiting for callback ...\n"</FONT>, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
lp-&gt;dtimer = 0;
lp-&gt;dialstate = 4;
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = lp-&gt;isdn_device;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_HANGUP">ISDN_CMD_HANGUP</A>;
cmd.arg = lp-&gt;isdn_channel;
<A HREF="isdn_common.c.shtml#isdn_command">isdn_command</A>(&amp;cmd);
<A HREF="isdn_common.c.shtml#isdn_all_eaz">isdn_all_eaz</A>(lp-&gt;isdn_device, lp-&gt;isdn_channel);
}
anymore = 1;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">default</FONT>:
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn_net: Illegal dialstate %d for device %s\n"</FONT>,
lp-&gt;dialstate, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
}
p = (<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *) p-&gt;next;
}
<A HREF="isdn_common.c.shtml#isdn_timer_ctrl">isdn_timer_ctrl</A>(<A HREF="../includes/isdn.h.shtml#ISDN_TIMER_NETDIAL">ISDN_TIMER_NETDIAL</A>, anymore);
}
<FONT COLOR=#0000FF>/*
* Perform hangup for a net-interface.
*/</FONT>
<FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_net_hangup">isdn_net_hangup</A>(<FONT COLOR="#298C52">struct</FONT> device *d)
{
isdn_net_local *lp = (isdn_net_local *) d-&gt;priv;
<A HREF="../includes/isdnif.h.shtml#isdn_ctrl">isdn_ctrl</A> cmd;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR="#298C52">struct</FONT> concap_proto *cprot = lp -&gt; netdev -&gt; cprot;
<FONT COLOR="#298C52">struct</FONT> concap_proto_ops *pops = cprot ? cprot -&gt; pops : 0;
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>) {
lp-&gt;flags &amp;= ~<A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>;
printk(KERN_INFO <FONT COLOR="#FF0000">"isdn_net: local hangup %s\n"</FONT>, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<A HREF="isdn_ppp.c.shtml#isdn_ppp_free">isdn_ppp_free</A>(lp);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR=#0000FF>/* try if there are generic encap protocol
receiver routines and signal the closure of
the link */</FONT>
<FONT COLOR="#298C52">if</FONT>( pops &amp;&amp; pops -&gt; disconn_ind )
pops -&gt; disconn_ind(cprot);
<FONT COLOR=#A521F7>#endif</FONT> <FONT COLOR=#0000FF>/* CONFIG_ISDN_X25 */</FONT>
cmd.<A HREF="../includes/isdn.h.shtml#driver">driver</A> = lp-&gt;isdn_device;
cmd.command = <A HREF="../includes/isdnif.h.shtml#ISDN_CMD_HANGUP">ISDN_CMD_HANGUP</A>;
cmd.arg = lp-&gt;isdn_channel;
<A HREF="isdn_common.c.shtml#isdn_command">isdn_command</A>(&amp;cmd);
printk(KERN_INFO <FONT COLOR="#FF0000">"%s: Chargesum is %d\n"</FONT>, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, lp-&gt;charge);
<A HREF="isdn_common.c.shtml#isdn_all_eaz">isdn_all_eaz</A>(lp-&gt;isdn_device, lp-&gt;isdn_channel);
}
<A HREF="#isdn_net_unbind_channel">isdn_net_unbind_channel</A>(lp);
}
<FONT COLOR="#298C52">typedef</FONT> <FONT COLOR="#298C52">struct</FONT> {
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">short</FONT> source;
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">short</FONT> dest;
} <A NAME="ip_ports">ip_ports</A>;
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
<A HREF="#isdn_net_log_skb">isdn_net_log_skb</A>(<FONT COLOR="#298C52">struct</FONT> sk_buff * skb, isdn_net_local * lp)
{
u_char *p = skb-&gt;nh.raw; <FONT COLOR=#0000FF>/* hopefully, this was set correctly */</FONT>
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">short</FONT> proto = ntohs(skb-&gt;protocol);
<FONT COLOR="#298C52">int</FONT> data_ofs;
<A HREF="#ip_ports">ip_ports</A> *ipp;
<FONT COLOR="#298C52">char</FONT> addinfo[100];
addinfo[0] = <FONT COLOR="#FF0000">'\0'</FONT>;
<FONT COLOR=#0000FF>/* This check stolen from 2.1.72 dev_queue_xmit_nit() */</FONT>
<FONT COLOR="#298C52">if</FONT> (skb-&gt;nh.raw &lt; skb-&gt;data || skb-&gt;nh.raw &gt;= skb-&gt;tail) {
<FONT COLOR=#0000FF>/* fall back to old isdn_net_log_packet method() */</FONT>
<FONT COLOR="#298C52">char</FONT> * buf = skb-&gt;data;
printk(KERN_DEBUG <FONT COLOR="#FF0000">"isdn_net: protocol %04x is buggy, dev %s\n"</FONT>, skb-&gt;protocol, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
p = buf;
proto = ETH_P_IP;
<FONT COLOR="#298C52">switch</FONT> (lp-&gt;p_encap) {
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_IPTYP">ISDN_NET_ENCAP_IPTYP</A>:
proto = ntohs(*(<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">short</FONT> *) &amp;buf[0]);
p = &amp;buf[2];
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_ETHER">ISDN_NET_ENCAP_ETHER</A>:
proto = ntohs(*(<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">short</FONT> *) &amp;buf[12]);
p = &amp;buf[14];
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_CISCOHDLC">ISDN_NET_ENCAP_CISCOHDLC</A>:
proto = ntohs(*(<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">short</FONT> *) &amp;buf[2]);
p = &amp;buf[4];
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_SYNCPPP">ISDN_NET_ENCAP_SYNCPPP</A>:
proto = ntohs(skb-&gt;protocol);
p = &amp;buf[<A HREF="isdn_ppp.h.shtml#IPPP_MAX_HEADER">IPPP_MAX_HEADER</A>];
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR=#A521F7>#endif</FONT>
}
}
data_ofs = ((p[0] &amp; 15) * 4);
<FONT COLOR="#298C52">switch</FONT> (proto) {
<FONT COLOR="#298C52">case</FONT> ETH_P_IP:
<FONT COLOR="#298C52">switch</FONT> (p[9]) {
<FONT COLOR="#298C52">case</FONT> 1:
strcpy(addinfo, <FONT COLOR="#FF0000">" ICMP"</FONT>);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 2:
strcpy(addinfo, <FONT COLOR="#FF0000">" IGMP"</FONT>);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 4:
strcpy(addinfo, <FONT COLOR="#FF0000">" IPIP"</FONT>);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 6:
ipp = (<A HREF="#ip_ports">ip_ports</A> *) (&amp;p[data_ofs]);
sprintf(addinfo, <FONT COLOR="#FF0000">" TCP, port: %d -&gt; %d"</FONT>, ntohs(ipp-&gt;source),
ntohs(ipp-&gt;dest));
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 8:
strcpy(addinfo, <FONT COLOR="#FF0000">" EGP"</FONT>);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 12:
strcpy(addinfo, <FONT COLOR="#FF0000">" PUP"</FONT>);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 17:
ipp = (<A HREF="#ip_ports">ip_ports</A> *) (&amp;p[data_ofs]);
sprintf(addinfo, <FONT COLOR="#FF0000">" UDP, port: %d -&gt; %d"</FONT>, ntohs(ipp-&gt;source),
ntohs(ipp-&gt;dest));
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 22:
strcpy(addinfo, <FONT COLOR="#FF0000">" IDP"</FONT>);
<FONT COLOR="#298C52">break</FONT>;
}
printk(KERN_INFO <FONT COLOR="#FF0000">"OPEN: %d.%d.%d.%d -&gt; %d.%d.%d.%d%s\n"</FONT>,
p[12], p[13], p[14], p[15],
p[16], p[17], p[18], p[19],
addinfo);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> ETH_P_ARP:
printk(KERN_INFO <FONT COLOR="#FF0000">"OPEN: ARP %d.%d.%d.%d -&gt; *.*.*.* ?%d.%d.%d.%d\n"</FONT>,
p[14], p[15], p[16], p[17],
p[24], p[25], p[26], p[27]);
<FONT COLOR="#298C52">break</FONT>;
}
}
<FONT COLOR=#0000FF>/*
* Generic routine to send out an skbuf.
* If lowlevel-device does not support support skbufs, use
* standard send-routine, else send directly.
*
* Return: 0 on success, !0 on failure.
* Side-effects: ndev-&gt;tbusy is cleared on success.
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A HREF="#isdn_net_send_skb">isdn_net_send_skb</A>(<FONT COLOR="#298C52">struct</FONT> device *ndev, isdn_net_local * lp,
<FONT COLOR="#298C52">struct</FONT> sk_buff *skb)
{
<FONT COLOR="#298C52">int</FONT> ret;
<FONT COLOR="#298C52">int</FONT> len = skb-&gt;len; <FONT COLOR=#0000FF>/* save len */</FONT>
ret = <A HREF="isdn_common.c.shtml#isdn_writebuf_skb_stub">isdn_writebuf_skb_stub</A>(lp-&gt;isdn_device, lp-&gt;isdn_channel, 1, skb);
<FONT COLOR="#298C52">if</FONT> (ret == len) {
lp-&gt;transcount += len;
clear_bit(0, (<FONT COLOR="#298C52">void</FONT> *) &amp;(ndev-&gt;tbusy));
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">if</FONT> (ret &lt; 0) {
dev_kfree_skb(skb);
lp-&gt;stats.tx_errors++;
clear_bit(0, (<FONT COLOR="#298C52">void</FONT> *) &amp;(ndev-&gt;tbusy));
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">return</FONT> 1;
}
<FONT COLOR=#0000FF>/*
* Helper function for isdn_net_start_xmit.
* When called, the connection is already established.
* Based on cps-calculation, check if device is overloaded.
* If so, and if a slave exists, trigger dialing for it.
* If any slave is online, deliver packets using a simple round robin
* scheme.
*
* Return: 0 on success, !0 on failure.
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A HREF="#isdn_net_xmit">isdn_net_xmit</A>(<FONT COLOR="#298C52">struct</FONT> device *ndev, isdn_net_local * lp, <FONT COLOR="#298C52">struct</FONT> sk_buff *skb)
{
<FONT COLOR="#298C52">int</FONT> ret;
<FONT COLOR=#A521F7>#if</FONT> CONFIG_ISDN_TIMEOUT_RULES
(<FONT COLOR="#298C52">void</FONT>)<A HREF="isdn_timru.c.shtml#isdn_net_recalc_timeout">isdn_net_recalc_timeout</A>(<A HREF="../includes/isdn_timru.h.shtml#ISDN_TIMRU_KEEPUP_OUT">ISDN_TIMRU_KEEPUP_OUT</A>,
<A HREF="../includes/isdn_timru.h.shtml#ISDN_TIMRU_PACKET_SKB">ISDN_TIMRU_PACKET_SKB</A>, ndev, skb, 0);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#0000FF>/* For the other encaps the header has already been built */</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">if</FONT> (lp-&gt;p_encap == <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_SYNCPPP">ISDN_NET_ENCAP_SYNCPPP</A>) {
<FONT COLOR="#298C52">return</FONT> <A HREF="isdn_ppp.c.shtml#isdn_ppp_xmit">isdn_ppp_xmit</A>(skb, ndev);
}
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#A521F7>#ifndef</FONT> CONFIG_ISDN_TIMEOUT_RULES
<FONT COLOR=#0000FF>/* Reset hangup-timeout */</FONT>
lp-&gt;huptimer = 0;
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (lp-&gt;cps &gt; lp-&gt;triggercps) {
<FONT COLOR=#0000FF>/* Device overloaded */</FONT>
<FONT COLOR=#0000FF>/*
* Packet-delivery via round-robin over master
* and all connected slaves.
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (lp-&gt;master)
<FONT COLOR=#0000FF>/* Slaves always deliver themselves */</FONT>
ret = <A HREF="#isdn_net_send_skb">isdn_net_send_skb</A>(ndev, lp, skb);
<FONT COLOR="#298C52">else</FONT> {
isdn_net_local *slp = (isdn_net_local *) (lp-&gt;srobin-&gt;priv);
<FONT COLOR=#0000FF>/* Master delivers via srobin and maintains srobin */</FONT>
<FONT COLOR="#298C52">if</FONT> (lp-&gt;srobin == ndev)
ret = <A HREF="#isdn_net_send_skb">isdn_net_send_skb</A>(ndev, lp, skb);
<FONT COLOR="#298C52">else</FONT>
ret = ndev-&gt;tbusy = <A HREF="#isdn_net_start_xmit">isdn_net_start_xmit</A>(skb, lp-&gt;srobin);
lp-&gt;srobin = (slp-&gt;slave) ? slp-&gt;slave : ndev;
slp = (isdn_net_local *) (lp-&gt;srobin-&gt;priv);
<FONT COLOR="#298C52">if</FONT> (!((slp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>) &amp;&amp; (slp-&gt;dialstate == 0)))
lp-&gt;srobin = ndev;
}
<FONT COLOR=#0000FF>/* Slave-startup using delay-variable */</FONT>
<FONT COLOR="#298C52">if</FONT> (lp-&gt;slave) {
<FONT COLOR="#298C52">if</FONT> (!lp-&gt;sqfull) {
<FONT COLOR=#0000FF>/* First time overload: set timestamp only */</FONT>
lp-&gt;sqfull = 1;
lp-&gt;sqfull_stamp = jiffies;
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR=#0000FF>/* subsequent overload: if slavedelay exceeded, start dialing */</FONT>
<FONT COLOR="#298C52">if</FONT> ((jiffies - lp-&gt;sqfull_stamp) &gt; lp-&gt;slavedelay)
<A HREF="#isdn_net_force_dial_lp">isdn_net_force_dial_lp</A>((isdn_net_local *) lp-&gt;slave-&gt;priv);
}
}
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR=#0000FF>/* Not overloaded, deliver locally */</FONT>
ret = <A HREF="#isdn_net_send_skb">isdn_net_send_skb</A>(ndev, lp, skb);
<FONT COLOR="#298C52">if</FONT> (lp-&gt;sqfull &amp;&amp; ((jiffies - lp-&gt;sqfull_stamp) &gt; (lp-&gt;slavedelay + (10 * HZ))))
lp-&gt;sqfull = 0;
}
<FONT COLOR="#298C52">return</FONT> ret;
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
<A HREF="#isdn_net_adjust_hdr">isdn_net_adjust_hdr</A>(<FONT COLOR="#298C52">struct</FONT> sk_buff *skb, <FONT COLOR="#298C52">struct</FONT> device *dev)
{
isdn_net_local *lp = (isdn_net_local *) dev-&gt;priv;
<FONT COLOR="#298C52">if</FONT> (!skb)
<FONT COLOR="#298C52">return</FONT>;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;p_encap == <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_ETHER">ISDN_NET_ENCAP_ETHER</A>) {
<FONT COLOR="#298C52">int</FONT> pullsize = (ulong)skb-&gt;nh.raw - (ulong)skb-&gt;data - ETH_HLEN;
<FONT COLOR="#298C52">if</FONT> (pullsize &gt; 0) {
printk(KERN_DEBUG <FONT COLOR="#FF0000">"isdn_net: Pull junk %d\n"</FONT>, pullsize);
skb_pull(skb, pullsize);
}
}
}
<FONT COLOR=#0000FF>/*
* Try sending a packet.
* If this interface isn't connected to a ISDN-Channel, find a free channel,
* and start dialing.
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A HREF="#isdn_net_start_xmit">isdn_net_start_xmit</A>(<FONT COLOR="#298C52">struct</FONT> sk_buff *skb, <FONT COLOR="#298C52">struct</FONT> device *ndev)
{
isdn_net_local *lp = (isdn_net_local *) ndev-&gt;priv;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR="#298C52">struct</FONT> concap_proto * cprot = lp -&gt; netdev -&gt; cprot;
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (ndev-&gt;tbusy) {
<FONT COLOR="#298C52">if</FONT> (jiffies - ndev-&gt;trans_start &lt; (2 * HZ))
<FONT COLOR="#298C52">return</FONT> 1;
<FONT COLOR="#298C52">if</FONT> (!lp-&gt;dialstate)
lp-&gt;stats.tx_errors++;
ndev-&gt;trans_start = jiffies;
}
ndev-&gt;tbusy = 1; <FONT COLOR=#0000FF>/* left instead of obsolete test_and_set_bit() */</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR=#0000FF>/* At this point hard_start_xmit() passes control to the encapsulation
protocol (if present).
For X.25 auto-dialing is completly bypassed because:
- It does not conform with the semantics of a reliable datalink
service as needed by X.25 PLP.
- I don't want that the interface starts dialing when the network layer
sends a message which requests to disconnect the lapb link (or if it
sends any other message not resulting in data transmission).
Instead, dialing will be initiated by the encapsulation protocol entity
when a dl_establish request is received from the upper layer.
*/</FONT>
<FONT COLOR="#298C52">if</FONT>( cprot ) {
<FONT COLOR="#298C52">return</FONT> cprot -&gt; pops -&gt; encap_and_xmit ( cprot , skb);
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#0000FF>/* auto-dialing xmit function */</FONT>
{
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_DUMP
u_char *buf;
<FONT COLOR=#A521F7>#endif</FONT>
<A HREF="#isdn_net_adjust_hdr">isdn_net_adjust_hdr</A>(skb, ndev);
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_DUMP
buf = skb-&gt;data;
<A HREF="isdn_common.c.shtml#isdn_dumppkt">isdn_dumppkt</A>(<FONT COLOR="#FF0000">"S:"</FONT>, buf, skb-&gt;len, 40);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (!(lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>)) {
<FONT COLOR="#298C52">int</FONT> chi;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>[1]) {
ulong flags;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_TIMEOUT_RULES
<FONT COLOR="#298C52">if</FONT>(<A HREF="isdn_timru.c.shtml#isdn_net_recalc_timeout">isdn_net_recalc_timeout</A>(<A HREF="../includes/isdn_timru.h.shtml#ISDN_TIMRU_BRINGUP">ISDN_TIMRU_BRINGUP</A>,
<A HREF="../includes/isdn_timru.h.shtml#ISDN_TIMRU_PACKET_SKB">ISDN_TIMRU_PACKET_SKB</A>, ndev, skb, 0) &lt;= 0) {
<A HREF="#isdn_net_unreachable">isdn_net_unreachable</A>(ndev, skb, <FONT COLOR="#FF0000">"dial rejected: packet may not bring up connection"</FONT>);
dev_kfree_skb(skb);
ndev-&gt;tbusy = 0;
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT>(lp-&gt;dialwait_timer &lt;= 0)
<FONT COLOR="#298C52">if</FONT>(lp-&gt;dialstarted &gt; 0 &amp;&amp; lp-&gt;dialtimeout &gt; 0 &amp;&amp; jiffies &lt; lp-&gt;dialstarted + lp-&gt;dialtimeout + lp-&gt;dialwait)
lp-&gt;dialwait_timer = lp-&gt;dialstarted + lp-&gt;dialtimeout + lp-&gt;dialwait;
<FONT COLOR="#298C52">if</FONT>(lp-&gt;dialwait_timer &gt; 0) {
<FONT COLOR="#298C52">if</FONT>(jiffies &lt; lp-&gt;dialwait_timer) {
<A HREF="#isdn_net_unreachable">isdn_net_unreachable</A>(ndev, skb, <FONT COLOR="#FF0000">"dial rejected: retry-time not reached"</FONT>);
dev_kfree_skb(skb);
ndev-&gt;tbusy = 0;
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> 0;
} <FONT COLOR="#298C52">else</FONT>
lp-&gt;dialwait_timer = 0;
}
<FONT COLOR=#0000FF>/* Grab a free ISDN-Channel */</FONT>
<FONT COLOR="#298C52">if</FONT> ((chi =
<A HREF="isdn_common.c.shtml#isdn_get_free_channel">isdn_get_free_channel</A>(<A HREF="../includes/isdn.h.shtml#ISDN_USAGE_NET">ISDN_USAGE_NET</A>,
lp-&gt;l2_proto,
lp-&gt;l3_proto,
lp-&gt;pre_device,
lp-&gt;pre_channel)) &lt; 0) {
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<A HREF="#isdn_net_unreachable">isdn_net_unreachable</A>(ndev, skb,
<FONT COLOR="#FF0000">"No channel"</FONT>);
dev_kfree_skb(skb);
ndev-&gt;tbusy = 0;
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#0000FF>/* Log packet, which triggered dialing */</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;net_verbose)
<A HREF="#isdn_net_log_skb">isdn_net_log_skb</A>(skb, lp);
lp-&gt;dialstate = 1;
lp-&gt;flags |= <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>;
<FONT COLOR=#0000FF>/* Connect interface with channel */</FONT>
<A HREF="#isdn_net_bind_channel">isdn_net_bind_channel</A>(lp, chi);
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">if</FONT> (lp-&gt;p_encap == <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_SYNCPPP">ISDN_NET_ENCAP_SYNCPPP</A>) {
<FONT COLOR=#0000FF>/* no 'first_skb' handling for syncPPP */</FONT>
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_ppp.c.shtml#isdn_ppp_bind">isdn_ppp_bind</A>(lp) &lt; 0) {
dev_kfree_skb(skb);
<A HREF="#isdn_net_unbind_channel">isdn_net_unbind_channel</A>(lp);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> 0; <FONT COLOR=#0000FF>/* STN (skb to nirvana) ;) */</FONT>
}
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<A HREF="#isdn_net_dial">isdn_net_dial</A>(); <FONT COLOR=#0000FF>/* Initiate dialing */</FONT>
<FONT COLOR="#298C52">return</FONT> 1; <FONT COLOR=#0000FF>/* let upper layer requeue skb packet */</FONT>
}
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#0000FF>/* remember first skb to speed up arp
* when using encap ETHER
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (lp-&gt;first_skb) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn_net_start_xmit: First skb already set!\n"</FONT>);
dev_kfree_skb(lp-&gt;first_skb);
lp-&gt;first_skb = NULL;
}
lp-&gt;first_skb = skb;
<FONT COLOR=#0000FF>/* Initiate dialing */</FONT>
ndev-&gt;tbusy = 0;
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<A HREF="#isdn_net_dial">isdn_net_dial</A>();
<FONT COLOR="#298C52">return</FONT> 0;
} <FONT COLOR="#298C52">else</FONT> {
<A HREF="#isdn_net_unreachable">isdn_net_unreachable</A>(ndev, skb,
<FONT COLOR="#FF0000">"No phone number"</FONT>);
dev_kfree_skb(skb);
ndev-&gt;tbusy = 0;
<FONT COLOR="#298C52">return</FONT> 0;
}
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR=#0000FF>/* Connection is established, try sending */</FONT>
ndev-&gt;trans_start = jiffies;
<FONT COLOR="#298C52">if</FONT> (!lp-&gt;dialstate) {
<FONT COLOR="#298C52">if</FONT> (lp-&gt;first_skb) {
<FONT COLOR="#298C52">if</FONT> (<A HREF="#isdn_net_xmit">isdn_net_xmit</A>(ndev, lp, lp-&gt;first_skb))
<FONT COLOR="#298C52">return</FONT> 1;
lp-&gt;first_skb = NULL;
}
<FONT COLOR="#298C52">return</FONT> (<A HREF="#isdn_net_xmit">isdn_net_xmit</A>(ndev, lp, skb));
} <FONT COLOR="#298C52">else</FONT>
ndev-&gt;tbusy = 1;
}
}
<FONT COLOR="#298C52">return</FONT> 1;
}
<FONT COLOR=#0000FF>/*
* Shutdown a net-interface.
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_close">isdn_net_close</A>(<FONT COLOR="#298C52">struct</FONT> device *dev)
{
<FONT COLOR="#298C52">struct</FONT> device *p;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR="#298C52">struct</FONT> concap_proto * cprot =
( (isdn_net_local *) dev-&gt;priv ) -&gt; netdev -&gt; cprot;
<FONT COLOR=#0000FF>/* printk(KERN_DEBUG "isdn_net_close %s\n" , dev-&gt; name ); */</FONT>
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR="#298C52">if</FONT>( cprot &amp;&amp; cprot -&gt; pops ) cprot -&gt; pops -&gt; close( cprot );
<FONT COLOR=#A521F7>#endif</FONT>
dev-&gt;tbusy = 1;
dev-&gt;start = 0;
<FONT COLOR="#298C52">if</FONT> ((p = (((isdn_net_local *) dev-&gt;priv)-&gt;slave))) {
<FONT COLOR=#0000FF>/* If this interface has slaves, stop them also */</FONT>
<FONT COLOR="#298C52">while</FONT> (p) {
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
cprot = ( (isdn_net_local *) p-&gt;priv )
-&gt; netdev -&gt; cprot;
<FONT COLOR="#298C52">if</FONT>( cprot &amp;&amp; cprot -&gt; pops )
cprot -&gt; pops -&gt; close( cprot );
<FONT COLOR=#A521F7>#endif</FONT>
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(p);
p-&gt;tbusy = 1;
p-&gt;start = 0;
p = (((isdn_net_local *) p-&gt;priv)-&gt;slave);
}
}
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(dev);
<A HREF="isdn_common.c.shtml#isdn_MOD_DEC_USE_COUNT">isdn_MOD_DEC_USE_COUNT</A>();
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#0000FF>/*
* Get statistics
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">struct</FONT> enet_statistics *
<A NAME="isdn_net_get_stats">isdn_net_get_stats</A>(<FONT COLOR="#298C52">struct</FONT> device *dev)
{
isdn_net_local *lp = (isdn_net_local *) dev-&gt;priv;
<FONT COLOR="#298C52">return</FONT> &amp;lp-&gt;stats;
}
<FONT COLOR=#0000FF>/* This is simply a copy from std. eth.c EXCEPT we pull ETH_HLEN
* instead of dev-&gt;hard_header_len off. This is done because the
* lowlevel-driver has already pulled off its stuff when we get
* here and this routine only gets called with p_encap == ETHER.
* Determine the packet's protocol ID. The rule here is that we
* assume 802.3 if the type field is short enough to be a length.
* This is normal practice and works for any 'now in use' protocol.
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">short</FONT>
<A HREF="#isdn_net_type_trans">isdn_net_type_trans</A>(<FONT COLOR="#298C52">struct</FONT> sk_buff *skb, <FONT COLOR="#298C52">struct</FONT> device *dev)
{
<FONT COLOR="#298C52">struct</FONT> ethhdr *eth;
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">char</FONT> *rawp;
skb-&gt;mac.raw = skb-&gt;data;
skb_pull(skb, ETH_HLEN);
eth = skb-&gt;mac.ethernet;
<FONT COLOR="#298C52">if</FONT> (*eth-&gt;h_dest &amp; 1) {
<FONT COLOR="#298C52">if</FONT> (memcmp(eth-&gt;h_dest, dev-&gt;broadcast, ETH_ALEN) == 0)
skb-&gt;pkt_type = PACKET_BROADCAST;
<FONT COLOR="#298C52">else</FONT>
skb-&gt;pkt_type = PACKET_MULTICAST;
}
<FONT COLOR=#0000FF>/*
* This ALLMULTI check should be redundant by 1.4
* so don't forget to remove it.
*/</FONT>
<FONT COLOR="#298C52">else</FONT> <FONT COLOR="#298C52">if</FONT> (dev-&gt;flags &amp; (IFF_PROMISC <FONT COLOR=#0000FF>/*| IFF_ALLMULTI*/</FONT>)) {
<FONT COLOR="#298C52">if</FONT> (memcmp(eth-&gt;h_dest, dev-&gt;dev_addr, ETH_ALEN))
skb-&gt;pkt_type = PACKET_OTHERHOST;
}
<FONT COLOR="#298C52">if</FONT> (ntohs(eth-&gt;h_proto) &gt;= 1536)
<FONT COLOR="#298C52">return</FONT> eth-&gt;h_proto;
rawp = skb-&gt;data;
<FONT COLOR=#0000FF>/*
* This is a magic hack to spot IPX packets. Older Novell breaks
* the protocol design and runs IPX over 802.3 without an 802.2 LLC
* layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
* won't work for fault tolerant netware but does for the rest.
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (*(<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">short</FONT> *) rawp == 0xFFFF)
<FONT COLOR="#298C52">return</FONT> htons(ETH_P_802_3);
<FONT COLOR=#0000FF>/*
* Real 802.2 LLC
*/</FONT>
<FONT COLOR="#298C52">return</FONT> htons(ETH_P_802_2);
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
<A HREF="#isdn_net_slarp_send">isdn_net_slarp_send</A>(isdn_net_local *lp, <FONT COLOR="#298C52">int</FONT> is_reply)
{
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">short</FONT> hl = dev-&gt;drv[lp-&gt;isdn_device]-&gt;interface-&gt;hl_hdrlen;
<FONT COLOR="#298C52">struct</FONT> sk_buff *skb = dev_alloc_skb(hl + <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="isdn_net.h.shtml#cisco_hdr">cisco_hdr</A>) + <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="isdn_net.h.shtml#cisco_slarp">cisco_slarp</A>));
<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">long</FONT> t = (jiffies / HZ * 1000000);
<FONT COLOR="#298C52">int</FONT> len;
<A HREF="isdn_net.h.shtml#cisco_hdr">cisco_hdr</A> *ch;
<A HREF="isdn_net.h.shtml#cisco_slarp">cisco_slarp</A> *s;
<FONT COLOR="#298C52">if</FONT> (!skb) {
printk(KERN_WARNING
<FONT COLOR="#FF0000">"%s: Could not allocate SLARP reply\n"</FONT>, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR="#298C52">return</FONT>;
}
skb_reserve(skb, hl);
ch = (<A HREF="isdn_net.h.shtml#cisco_hdr">cisco_hdr</A> *)skb_put(skb, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="isdn_net.h.shtml#cisco_hdr">cisco_hdr</A>));
ch-&gt;addr = <A HREF="isdn_net.h.shtml#CISCO_ADDR_UNICAST">CISCO_ADDR_UNICAST</A>;
ch-&gt;ctrl = 0;
ch-&gt;type = htons(<A HREF="isdn_net.h.shtml#CISCO_TYPE_SLARP">CISCO_TYPE_SLARP</A>);
s = (<A HREF="isdn_net.h.shtml#cisco_slarp">cisco_slarp</A> *)skb_put(skb, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="isdn_net.h.shtml#cisco_slarp">cisco_slarp</A>));
<FONT COLOR="#298C52">if</FONT> (is_reply) {
s-&gt;code = htonl(<A HREF="isdn_net.h.shtml#CISCO_SLARP_REPLY">CISCO_SLARP_REPLY</A>);
memset(&amp;s-&gt;slarp.reply.ifaddr, 0, <FONT COLOR="#298C52">sizeof</FONT>(__u32));
memset(&amp;s-&gt;slarp.reply.netmask, 0, <FONT COLOR="#298C52">sizeof</FONT>(__u32));
} <FONT COLOR="#298C52">else</FONT> {
lp-&gt;cisco_myseq++;
s-&gt;code = htonl(<A HREF="isdn_net.h.shtml#CISCO_SLARP_KEEPALIVE">CISCO_SLARP_KEEPALIVE</A>);
s-&gt;slarp.keepalive.my_seq = htonl(lp-&gt;cisco_myseq);
s-&gt;slarp.keepalive.your_seq = htonl(lp-&gt;cisco_yourseq);
}
s-&gt;rel = 0xffff;
s-&gt;t1 = t &gt;&gt; 16;
s-&gt;t0 = t &amp; 0xffff;
len = skb-&gt;len;
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_common.c.shtml#isdn_writebuf_skb_stub">isdn_writebuf_skb_stub</A>(lp-&gt;isdn_device, lp-&gt;isdn_channel, 0, skb) != len)
dev_kfree_skb(skb);
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
<A HREF="#isdn_net_slarp_in">isdn_net_slarp_in</A>(isdn_net_local *lp, <FONT COLOR="#298C52">struct</FONT> sk_buff *skb)
{
<A HREF="isdn_net.h.shtml#cisco_slarp">cisco_slarp</A> *s = (<A HREF="isdn_net.h.shtml#cisco_slarp">cisco_slarp</A> *)skb-&gt;data;
<FONT COLOR="#298C52">switch</FONT> (ntohl(s-&gt;code)) {
<FONT COLOR="#298C52">case</FONT> <A HREF="isdn_net.h.shtml#CISCO_SLARP_REQUEST">CISCO_SLARP_REQUEST</A>:
<A HREF="#isdn_net_slarp_send">isdn_net_slarp_send</A>(lp, 1);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="isdn_net.h.shtml#CISCO_SLARP_REPLY">CISCO_SLARP_REPLY</A>:
<FONT COLOR=#0000FF>/* Ignore replies */</FONT>
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="isdn_net.h.shtml#CISCO_SLARP_KEEPALIVE">CISCO_SLARP_KEEPALIVE</A>:
lp-&gt;cisco_yourseq = s-&gt;slarp.keepalive.my_seq;
<FONT COLOR="#298C52">if</FONT> (ntohl(s-&gt;slarp.keepalive.my_seq == lp-&gt;cisco_myseq)) {
<FONT COLOR="#298C52">if</FONT> (lp-&gt;cisco_loop++ == 2) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"%s: Keepalive Loop\n"</FONT>,
lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
lp-&gt;cisco_myseq ^= jiffies;
}
} <FONT COLOR="#298C52">else</FONT>
lp-&gt;cisco_loop = 0;
<FONT COLOR="#298C52">break</FONT>;
}
kfree_skb(skb);
}
<FONT COLOR=#0000FF>/*
* Called every 10 sec. via timer-interrupt if
* any network-interface has Cisco-Keepalive-Encapsulation
* and is online.
* Send Keepalive-Packet and re-schedule.
*/</FONT>
<FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_net_slarp_out">isdn_net_slarp_out</A>(<FONT COLOR="#298C52">void</FONT>)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p = dev-&gt;netdev;
<FONT COLOR="#298C52">int</FONT> anymore = 0;
<FONT COLOR="#298C52">while</FONT> (p) {
isdn_net_local *l = p-&gt;local;
<FONT COLOR="#298C52">if</FONT> ((l-&gt;p_encap == <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_CISCOHDLCK">ISDN_NET_ENCAP_CISCOHDLCK</A>) &amp;&amp;
(l-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>) &amp;&amp;
(!l-&gt;dialstate) ) {
anymore = 1;
<A HREF="#isdn_net_slarp_send">isdn_net_slarp_send</A>(l, 0);
}
p = (<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *) p-&gt;next;
}
<A HREF="isdn_common.c.shtml#isdn_timer_ctrl">isdn_timer_ctrl</A>(<A HREF="../includes/isdn.h.shtml#ISDN_TIMER_KEEPALIVE">ISDN_TIMER_KEEPALIVE</A>, anymore);
}
<FONT COLOR=#0000FF>/*
* Got a packet from ISDN-Channel.
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
<A HREF="#isdn_net_receive">isdn_net_receive</A>(<FONT COLOR="#298C52">struct</FONT> device *ndev, <FONT COLOR="#298C52">struct</FONT> sk_buff *skb)
{
isdn_net_local *lp = (isdn_net_local *) ndev-&gt;priv;
isdn_net_local *olp = lp; <FONT COLOR=#0000FF>/* original 'lp' */</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR=#A521F7>#ifndef</FONT> CONFIG_ISDN_TIMEOUT_RULES
<FONT COLOR="#298C52">int</FONT> proto = PPP_PROTOCOL(skb-&gt;data);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR="#298C52">struct</FONT> concap_proto *cprot = lp -&gt; netdev -&gt; cprot;
<FONT COLOR=#A521F7>#endif</FONT>
<A HREF="isdn_net.h.shtml#cisco_hdr">cisco_hdr</A> *ch;
lp-&gt;transcount += skb-&gt;len;
lp-&gt;stats.rx_packets++;
lp-&gt;stats.rx_bytes += skb-&gt;len;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;master) {
<FONT COLOR=#0000FF>/* Bundling: If device is a slave-device, deliver to master, also
* handle master's statistics and hangup-timeout
*/</FONT>
ndev = lp-&gt;master;
lp = (isdn_net_local *) ndev-&gt;priv;
lp-&gt;stats.rx_packets++;
lp-&gt;stats.rx_bytes += skb-&gt;len;
}
skb-&gt;dev = ndev;
skb-&gt;pkt_type = PACKET_HOST;
skb-&gt;mac.raw = skb-&gt;data;
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_DUMP
<A HREF="isdn_common.c.shtml#isdn_dumppkt">isdn_dumppkt</A>(<FONT COLOR="#FF0000">"R:"</FONT>, skb-&gt;data, skb-&gt;len, 40);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">switch</FONT> (lp-&gt;p_encap) {
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_ETHER">ISDN_NET_ENCAP_ETHER</A>:
<FONT COLOR=#0000FF>/* Ethernet over ISDN */</FONT>
<FONT COLOR=#A521F7>#ifndef</FONT> CONFIG_ISDN_TIMEOUT_RULES
olp-&gt;huptimer = 0;
lp-&gt;huptimer = 0;
<FONT COLOR=#A521F7>#endif</FONT>
skb-&gt;protocol = <A HREF="#isdn_net_type_trans">isdn_net_type_trans</A>(skb, ndev);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_UIHDLC">ISDN_NET_ENCAP_UIHDLC</A>:
<FONT COLOR=#0000FF>/* HDLC with UI-frame (for ispa with -h1 option) */</FONT>
<FONT COLOR=#A521F7>#ifndef</FONT> CONFIG_ISDN_TIMEOUT_RULES
olp-&gt;huptimer = 0;
lp-&gt;huptimer = 0;
<FONT COLOR=#A521F7>#endif</FONT>
skb_pull(skb, 2);
<FONT COLOR=#0000FF>/* Fall through */</FONT>
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_RAWIP">ISDN_NET_ENCAP_RAWIP</A>:
<FONT COLOR=#0000FF>/* RAW-IP without MAC-Header */</FONT>
<FONT COLOR=#A521F7>#ifndef</FONT> CONFIG_ISDN_TIMEOUT_RULES
olp-&gt;huptimer = 0;
lp-&gt;huptimer = 0;
<FONT COLOR=#A521F7>#endif</FONT>
skb-&gt;protocol = htons(ETH_P_IP);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_CISCOHDLCK">ISDN_NET_ENCAP_CISCOHDLCK</A>:
ch = (<A HREF="isdn_net.h.shtml#cisco_hdr">cisco_hdr</A> *)skb-&gt;data;
<FONT COLOR="#298C52">if</FONT> ((ch-&gt;addr != <A HREF="isdn_net.h.shtml#CISCO_ADDR_UNICAST">CISCO_ADDR_UNICAST</A>) &amp;&amp;
(ch-&gt;addr != <A HREF="isdn_net.h.shtml#CISCO_ADDR_BROADCAST">CISCO_ADDR_BROADCAST</A>) ) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"%s: Unknown Cisco addr 0x%02x\n"</FONT>,
lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, ch-&gt;addr);
kfree_skb(skb);
<FONT COLOR="#298C52">return</FONT>;
}
<FONT COLOR="#298C52">if</FONT> (ch-&gt;ctrl != 0) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"%s: Unknown Cisco ctrl 0x%02x\n"</FONT>,
lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, ch-&gt;ctrl);
kfree_skb(skb);
<FONT COLOR="#298C52">return</FONT>;
}
<FONT COLOR="#298C52">switch</FONT> (ntohs(ch-&gt;type)) {
<FONT COLOR="#298C52">case</FONT> <A HREF="isdn_net.h.shtml#CISCO_TYPE_INET">CISCO_TYPE_INET</A>:
skb_pull(skb, 4);
skb-&gt;protocol = htons(ETH_P_IP);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="isdn_net.h.shtml#CISCO_TYPE_SLARP">CISCO_TYPE_SLARP</A>:
skb_pull(skb, 4);
<A HREF="#isdn_net_slarp_in">isdn_net_slarp_in</A>(olp, skb);
<FONT COLOR="#298C52">return</FONT>;
<FONT COLOR="#298C52">default</FONT>:
printk(KERN_WARNING <FONT COLOR="#FF0000">"%s: Unknown Cisco type 0x%04x\n"</FONT>,
lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, ch-&gt;type);
kfree_skb(skb);
<FONT COLOR="#298C52">return</FONT>;
}
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_CISCOHDLC">ISDN_NET_ENCAP_CISCOHDLC</A>:
<FONT COLOR=#0000FF>/* CISCO-HDLC IP with type field and fake I-frame-header */</FONT>
skb_pull(skb, 2);
<FONT COLOR=#0000FF>/* Fall through */</FONT>
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_IPTYP">ISDN_NET_ENCAP_IPTYP</A>:
<FONT COLOR=#0000FF>/* IP with type field */</FONT>
<FONT COLOR=#A521F7>#ifndef</FONT> CONFIG_ISDN_TIMEOUT_RULES
olp-&gt;huptimer = 0;
lp-&gt;huptimer = 0;
<FONT COLOR=#A521F7>#endif</FONT>
skb-&gt;protocol = *(<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">short</FONT> *) &amp;(skb-&gt;data[0]);
skb_pull(skb, 2);
<FONT COLOR="#298C52">if</FONT> (*(<FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">short</FONT> *) skb-&gt;data == 0xFFFF)
skb-&gt;protocol = htons(ETH_P_802_3);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_SYNCPPP">ISDN_NET_ENCAP_SYNCPPP</A>:
<FONT COLOR=#A521F7>#ifndef</FONT> CONFIG_ISDN_TIMEOUT_RULES
<FONT COLOR=#0000FF>/*
* If encapsulation is syncppp, don't reset
* huptimer on LCP packets.
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (proto != PPP_LCP) {
olp-&gt;huptimer = 0;
lp-&gt;huptimer = 0;
}
<FONT COLOR=#A521F7>#endif</FONT>
<A HREF="isdn_ppp.c.shtml#isdn_ppp_receive">isdn_ppp_receive</A>(lp-&gt;netdev, olp, skb);
<FONT COLOR="#298C52">return</FONT>;
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">default</FONT>:
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR=#0000FF>/* try if there are generic sync_device receiver routines */</FONT>
<FONT COLOR="#298C52">if</FONT>(cprot) <FONT COLOR="#298C52">if</FONT>(cprot -&gt; pops)
<FONT COLOR="#298C52">if</FONT>( cprot -&gt; pops -&gt; data_ind){
cprot -&gt; pops -&gt; data_ind(cprot,skb);
<FONT COLOR="#298C52">return</FONT>;
};
<FONT COLOR=#A521F7>#endif</FONT> <FONT COLOR=#0000FF>/* CONFIG_ISDN_X25 */</FONT>
printk(KERN_WARNING <FONT COLOR="#FF0000">"%s: unknown encapsulation, dropping\n"</FONT>,
lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
kfree_skb(skb);
<FONT COLOR="#298C52">return</FONT>;
}
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_TIMEOUT_RULES
<A HREF="isdn_timru.c.shtml#isdn_net_recalc_timeout">isdn_net_recalc_timeout</A>(<A HREF="../includes/isdn_timru.h.shtml#ISDN_TIMRU_KEEPUP_IN">ISDN_TIMRU_KEEPUP_IN</A>,
<A HREF="../includes/isdn_timru.h.shtml#ISDN_TIMRU_PACKET_SKB">ISDN_TIMRU_PACKET_SKB</A>, ndev, skb, 0);
<FONT COLOR=#0000FF>/* FIXME: olp-&gt;huptimer = lp-&gt;huptimer ? */</FONT>
<FONT COLOR=#A521F7>#endif</FONT>
netif_rx(skb);
<FONT COLOR="#298C52">return</FONT>;
}
<FONT COLOR=#0000FF>/*
* A packet arrived via ISDN. Search interface-chain for a corresponding
* interface. If found, deliver packet to receiver-function and return 1,
* else return 0.
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_rcv_skb">isdn_net_rcv_skb</A>(<FONT COLOR="#298C52">int</FONT> idx, <FONT COLOR="#298C52">struct</FONT> sk_buff *skb)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p = dev-&gt;rx_netdev[idx];
<FONT COLOR="#298C52">if</FONT> (p) {
isdn_net_local *lp = p-&gt;local;
<FONT COLOR="#298C52">if</FONT> ((lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>) &amp;&amp;
(!lp-&gt;dialstate)) {
<A HREF="#isdn_net_receive">isdn_net_receive</A>(&amp;p-&gt;dev, skb);
<FONT COLOR="#298C52">return</FONT> 1;
}
}
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A HREF="#my_eth_header">my_eth_header</A>(<FONT COLOR="#298C52">struct</FONT> sk_buff *skb, <FONT COLOR="#298C52">struct</FONT> device *dev, <FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">short</FONT> type,
<FONT COLOR="#298C52">void</FONT> *daddr, <FONT COLOR="#298C52">void</FONT> *saddr, <FONT COLOR="#298C52">unsigned</FONT> len)
{
<FONT COLOR="#298C52">struct</FONT> ethhdr *eth = (<FONT COLOR="#298C52">struct</FONT> ethhdr *) skb_push(skb, ETH_HLEN);
<FONT COLOR=#0000FF>/*
* Set the protocol type. For a packet of type ETH_P_802_3 we
* put the length here instead. It is up to the 802.2 layer to
* carry protocol information.
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (type != ETH_P_802_3)
eth-&gt;h_proto = htons(type);
<FONT COLOR="#298C52">else</FONT>
eth-&gt;h_proto = htons(len);
<FONT COLOR=#0000FF>/*
* Set the source hardware address.
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (saddr)
memcpy(eth-&gt;h_source, saddr, dev-&gt;addr_len);
<FONT COLOR="#298C52">else</FONT>
memcpy(eth-&gt;h_source, dev-&gt;dev_addr, dev-&gt;addr_len);
<FONT COLOR=#0000FF>/*
* Anyway, the loopback-device should never use this function...
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;flags &amp; (IFF_LOOPBACK | IFF_NOARP)) {
memset(eth-&gt;h_dest, 0, dev-&gt;addr_len);
<FONT COLOR="#298C52">return</FONT> ETH_HLEN <FONT COLOR=#0000FF>/*(dev-&gt;hard_header_len)*/</FONT>;
}
<FONT COLOR="#298C52">if</FONT> (daddr) {
memcpy(eth-&gt;h_dest, daddr, dev-&gt;addr_len);
<FONT COLOR="#298C52">return</FONT> ETH_HLEN <FONT COLOR=#0000FF>/*dev-&gt;hard_header_len*/</FONT>;
}
<FONT COLOR="#298C52">return</FONT> -ETH_HLEN <FONT COLOR=#0000FF>/*dev-&gt;hard_header_len*/</FONT>;
}
<FONT COLOR=#0000FF>/*
* build an header
* depends on encaps that is being used.
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A HREF="#isdn_net_header">isdn_net_header</A>(<FONT COLOR="#298C52">struct</FONT> sk_buff *skb, <FONT COLOR="#298C52">struct</FONT> device *dev, <FONT COLOR="#298C52">unsigned</FONT> <FONT COLOR="#298C52">short</FONT> type,
<FONT COLOR="#298C52">void</FONT> *daddr, <FONT COLOR="#298C52">void</FONT> *saddr, <FONT COLOR="#298C52">unsigned</FONT> plen)
{
isdn_net_local *lp = dev-&gt;priv;
ushort len = 0;
<FONT COLOR="#298C52">switch</FONT> (lp-&gt;p_encap) {
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_ETHER">ISDN_NET_ENCAP_ETHER</A>:
len = <A HREF="#my_eth_header">my_eth_header</A>(skb, dev, type, daddr, saddr, plen);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_SYNCPPP">ISDN_NET_ENCAP_SYNCPPP</A>:
<FONT COLOR=#0000FF>/* stick on a fake header to keep fragmentation code happy. */</FONT>
len = <A HREF="isdn_ppp.h.shtml#IPPP_MAX_HEADER">IPPP_MAX_HEADER</A>;
skb_push(skb,len);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_RAWIP">ISDN_NET_ENCAP_RAWIP</A>:
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn_net_header called with RAW_IP!\n"</FONT>);
len = 0;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_IPTYP">ISDN_NET_ENCAP_IPTYP</A>:
<FONT COLOR=#0000FF>/* ethernet type field */</FONT>
*((ushort *) skb_push(skb, 2)) = htons(type);
len = 2;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_UIHDLC">ISDN_NET_ENCAP_UIHDLC</A>:
<FONT COLOR=#0000FF>/* HDLC with UI-Frames (for ispa with -h1 option) */</FONT>
*((ushort *) skb_push(skb, 2)) = htons(0x0103);
len = 2;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_CISCOHDLC">ISDN_NET_ENCAP_CISCOHDLC</A>:
skb_push(skb, 4);
skb-&gt;data[0] = 0x0f;
skb-&gt;data[1] = 0x00;
*((ushort *) &amp; skb-&gt;data[2]) = htons(type);
len = 4;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR="#298C52">default</FONT>:
<FONT COLOR=#0000FF>/* try if there are generic concap protocol routines */</FONT>
<FONT COLOR="#298C52">if</FONT>( lp-&gt; netdev -&gt; cprot ){
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn_net_header called with concap_proto!\n"</FONT>);
len = 0;
<FONT COLOR="#298C52">break</FONT>;
}
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR=#A521F7>#endif</FONT> <FONT COLOR=#0000FF>/* CONFIG_ISDN_X25 */</FONT>
}
<FONT COLOR="#298C52">return</FONT> len;
}
<FONT COLOR=#0000FF>/* We don't need to send arp, because we have point-to-point connections. */</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_rebuild_header">isdn_net_rebuild_header</A>(<FONT COLOR="#298C52">struct</FONT> sk_buff *skb)
{
<FONT COLOR="#298C52">struct</FONT> device *dev = skb-&gt;dev;
isdn_net_local *lp = dev-&gt;priv;
<FONT COLOR="#298C52">int</FONT> ret = 0;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;p_encap == <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_ETHER">ISDN_NET_ENCAP_ETHER</A>) {
<FONT COLOR="#298C52">struct</FONT> ethhdr *eth = (<FONT COLOR="#298C52">struct</FONT> ethhdr *) skb-&gt;data;
<FONT COLOR=#0000FF>/*
* Only ARP/IP is currently supported
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (eth-&gt;h_proto != htons(ETH_P_IP)) {
printk(KERN_WARNING
<FONT COLOR="#FF0000">"isdn_net: %s don't know how to resolve type %d addresses?\n"</FONT>,
dev-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, (<FONT COLOR="#298C52">int</FONT>) eth-&gt;h_proto);
memcpy(eth-&gt;h_source, dev-&gt;dev_addr, dev-&gt;addr_len);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#0000FF>/*
* Try to get ARP to resolve the header.
*/</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_INET
ret = arp_find(eth-&gt;h_dest, skb);
<FONT COLOR=#A521F7>#endif</FONT>
}
<FONT COLOR="#298C52">return</FONT> ret;
}
<FONT COLOR=#0000FF>/*
* Interface-setup. (called just after registering a new interface)
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_init">isdn_net_init</A>(<FONT COLOR="#298C52">struct</FONT> device *ndev)
{
ushort max_hlhdr_len = 0;
isdn_net_local *lp = (isdn_net_local *) ndev-&gt;priv;
<FONT COLOR="#298C52">int</FONT> drvidx,
i;
<FONT COLOR="#298C52">if</FONT> (ndev == NULL) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn_net_init: dev = NULL!\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> -ENODEV;
}
<FONT COLOR="#298C52">if</FONT> (ndev-&gt;priv == NULL) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn_net_init: dev-&gt;priv = NULL!\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> -ENODEV;
}
ether_setup(ndev);
lp-&gt;org_hhc = ndev-&gt;hard_header_cache;
lp-&gt;org_hcu = ndev-&gt;header_cache_update;
<FONT COLOR=#0000FF>/* Setup the generic properties */</FONT>
ndev-&gt;hard_header = NULL;
ndev-&gt;hard_header_cache = NULL;
ndev-&gt;header_cache_update = NULL;
ndev-&gt;mtu = 1500;
ndev-&gt;flags = IFF_NOARP|IFF_POINTOPOINT;
ndev-&gt;type = ARPHRD_ETHER;
ndev-&gt;addr_len = ETH_ALEN;
<FONT COLOR=#0000FF>/* for clients with MPPP maybe higher values better */</FONT>
ndev-&gt;tx_queue_len = 30;
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; ETH_ALEN; i++)
ndev-&gt;broadcast[i] = 0xff;
<FONT COLOR=#0000FF>/* The ISDN-specific entries in the device structure. */</FONT>
ndev-&gt;open = &amp;<A HREF="#isdn_net_open">isdn_net_open</A>;
ndev-&gt;hard_start_xmit = &amp;<A HREF="#isdn_net_start_xmit">isdn_net_start_xmit</A>;
<FONT COLOR=#0000FF>/*
* up till binding we ask the protocol layer to reserve as much
* as we might need for HL layer
*/</FONT>
<FONT COLOR="#298C52">for</FONT> (drvidx = 0; drvidx &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>; drvidx++)
<FONT COLOR="#298C52">if</FONT> (dev-&gt;drv[drvidx])
<FONT COLOR="#298C52">if</FONT> (max_hlhdr_len &lt; dev-&gt;drv[drvidx]-&gt;interface-&gt;hl_hdrlen)
max_hlhdr_len = dev-&gt;drv[drvidx]-&gt;interface-&gt;hl_hdrlen;
ndev-&gt;hard_header_len = ETH_HLEN + max_hlhdr_len;
ndev-&gt;stop = &amp;<A HREF="#isdn_net_close">isdn_net_close</A>;
ndev-&gt;get_stats = &amp;<A HREF="#isdn_net_get_stats">isdn_net_get_stats</A>;
ndev-&gt;rebuild_header = &amp;<A HREF="#isdn_net_rebuild_header">isdn_net_rebuild_header</A>;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
ndev-&gt;do_ioctl = <A HREF="isdn_ppp.c.shtml#isdn_ppp_dev_ioctl">isdn_ppp_dev_ioctl</A>;
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_net_swapbind">isdn_net_swapbind</A>(<FONT COLOR="#298C52">int</FONT> drvidx)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p;
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_ICALL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"n_fi: swapping ch of %d\n"</FONT>, drvidx);
<FONT COLOR=#A521F7>#endif</FONT>
p = dev-&gt;netdev;
<FONT COLOR="#298C52">while</FONT> (p) {
<FONT COLOR="#298C52">if</FONT> (p-&gt;local-&gt;pre_device == drvidx)
<FONT COLOR="#298C52">switch</FONT> (p-&gt;local-&gt;pre_channel) {
<FONT COLOR="#298C52">case</FONT> 0:
p-&gt;local-&gt;pre_channel = 1;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 1:
p-&gt;local-&gt;pre_channel = 0;
<FONT COLOR="#298C52">break</FONT>;
}
p = (<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *) p-&gt;next;
}
}
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
<A NAME="isdn_net_swap_usage">isdn_net_swap_usage</A>(<FONT COLOR="#298C52">int</FONT> i1, <FONT COLOR="#298C52">int</FONT> i2)
{
<FONT COLOR="#298C52">int</FONT> u1 = dev-&gt;usage[i1] &amp; <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>;
<FONT COLOR="#298C52">int</FONT> u2 = dev-&gt;usage[i2] &amp; <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>;
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_ICALL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"n_fi: usage of %d and %d\n"</FONT>, i1, i2);
<FONT COLOR=#A521F7>#endif</FONT>
dev-&gt;usage[i1] &amp;= ~<A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>;
dev-&gt;usage[i1] |= u2;
dev-&gt;usage[i2] &amp;= ~<A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>;
dev-&gt;usage[i2] |= u1;
<A HREF="isdn_common.c.shtml#isdn_info_update">isdn_info_update</A>();
}
<FONT COLOR=#0000FF>/*
* An incoming call-request has arrived.
* Search the interface-chain for an appropriate interface.
* If found, connect the interface to the ISDN-channel and initiate
* D- and B-Channel-setup. If secure-flag is set, accept only
* configured phone-numbers. If callback-flag is set, initiate
* callback-dialing.
*
* Return-Value: 0 = No appropriate interface for this call.
* 1 = Call accepted
* 2 = Reject call, wait cbdelay, then call back
* 3 = Reject call
* 4 = Wait cbdelay, then call back
* 5 = No appropriate interface for this call,
* would eventually match if CID was longer.
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A HREF="#isdn_net_find_icall">isdn_net_find_icall</A>(<FONT COLOR="#298C52">int</FONT> di, <FONT COLOR="#298C52">int</FONT> ch, <FONT COLOR="#298C52">int</FONT> idx, <A HREF="../includes/isdnif.h.shtml#setup_parm">setup_parm</A> setup)
{
<FONT COLOR="#298C52">char</FONT> *eaz;
<FONT COLOR="#298C52">int</FONT> si1;
<FONT COLOR="#298C52">int</FONT> si2;
<FONT COLOR="#298C52">int</FONT> ematch;
<FONT COLOR="#298C52">int</FONT> wret;
<FONT COLOR="#298C52">int</FONT> swapped;
<FONT COLOR="#298C52">int</FONT> sidx = 0;
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p;
<A HREF="../includes/isdn.h.shtml#isdn_net_phone">isdn_net_phone</A> *n;
ulong flags;
<FONT COLOR="#298C52">char</FONT> nr[32];
<FONT COLOR=#0000FF>/* Search name in netdev-chain */</FONT>
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<FONT COLOR="#298C52">if</FONT> (!setup.<A HREF="isdn_common.c.shtml#phone">phone</A>[0]) {
nr[0] = <FONT COLOR="#FF0000">'0'</FONT>;
nr[1] = <FONT COLOR="#FF0000">'\0'</FONT>;
printk(KERN_INFO <FONT COLOR="#FF0000">"isdn_net: Incoming call without OAD, assuming '0'\n"</FONT>);
} <FONT COLOR="#298C52">else</FONT>
strcpy(nr, setup.<A HREF="isdn_common.c.shtml#phone">phone</A>);
si1 = (<FONT COLOR="#298C52">int</FONT>) setup.si1;
si2 = (<FONT COLOR="#298C52">int</FONT>) setup.si2;
<FONT COLOR="#298C52">if</FONT> (!setup.eazmsn[0]) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn_net: Incoming call without CPN, assuming '0'\n"</FONT>);
eaz = <FONT COLOR="#FF0000">"0"</FONT>;
} <FONT COLOR="#298C52">else</FONT>
eaz = setup.eazmsn;
<FONT COLOR="#298C52">if</FONT> (dev-&gt;net_verbose &gt; 1)
printk(KERN_INFO <FONT COLOR="#FF0000">"isdn_net: call from %s,%d,%d -&gt; %s\n"</FONT>, nr, si1, si2, eaz);
<FONT COLOR=#0000FF>/* Accept only calls with Si1 = 7 (Data-Transmission) */</FONT>
<FONT COLOR="#298C52">if</FONT> (si1 != 7) {
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">if</FONT> (dev-&gt;net_verbose &gt; 1)
printk(KERN_INFO <FONT COLOR="#FF0000">"isdn_net: Service-Indicator not 7, ignored\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> 0;
}
n = (<A HREF="../includes/isdn.h.shtml#isdn_net_phone">isdn_net_phone</A> *) 0;
p = dev-&gt;netdev;
ematch = wret = swapped = 0;
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_ICALL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"n_fi: di=%d ch=%d idx=%d usg=%d\n"</FONT>, di, ch, idx,
dev-&gt;usage[idx]);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">while</FONT> (p) {
<FONT COLOR="#298C52">int</FONT> matchret;
isdn_net_local *lp = p-&gt;local;
<FONT COLOR=#0000FF>/* If last check has triggered as binding-swap, revert it */</FONT>
<FONT COLOR="#298C52">switch</FONT> (swapped) {
<FONT COLOR="#298C52">case</FONT> 2:
<A HREF="#isdn_net_swap_usage">isdn_net_swap_usage</A>(idx, sidx);
<FONT COLOR=#0000FF>/* fall through */</FONT>
<FONT COLOR="#298C52">case</FONT> 1:
<A HREF="#isdn_net_swapbind">isdn_net_swapbind</A>(di);
<FONT COLOR="#298C52">break</FONT>;
}
swapped = 0;
<FONT COLOR="#298C52">if</FONT> (!(matchret = <A HREF="isdn_common.c.shtml#isdn_wildmat">isdn_wildmat</A>(eaz, <A HREF="isdn_common.c.shtml#isdn_map_eaz2msn">isdn_map_eaz2msn</A>(lp-&gt;msn, di))))
ematch = 1;
<FONT COLOR=#0000FF>/* Remember if more numbers eventually can match */</FONT>
<FONT COLOR="#298C52">if</FONT> (matchret &gt; wret)
wret = matchret;
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_ICALL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"n_fi: if='%s', l.msn=%s, l.flags=%d, l.dstate=%d\n"</FONT>,
lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, lp-&gt;msn, lp-&gt;flags, lp-&gt;dialstate);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> ((!matchret) &amp;&amp; <FONT COLOR=#0000FF>/* EAZ is matching */</FONT>
(((!(lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>)) &amp;&amp; <FONT COLOR=#0000FF>/* but not connected */</FONT>
(<A HREF="../includes/isdn.h.shtml#USG_NONE">USG_NONE</A>(dev-&gt;usage[idx]))) || <FONT COLOR=#0000FF>/* and ch. unused or */</FONT>
((((lp-&gt;dialstate == 4) || (lp-&gt;dialstate == 12)) &amp;&amp; <FONT COLOR=#0000FF>/* if dialing */</FONT>
(!(lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CALLBACK">ISDN_NET_CALLBACK</A>))) <FONT COLOR=#0000FF>/* but no callback */</FONT>
)))
{
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_ICALL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"n_fi: match1, pdev=%d pch=%d\n"</FONT>,
lp-&gt;pre_device, lp-&gt;pre_channel);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;usage[idx] &amp; <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>) {
<FONT COLOR="#298C52">if</FONT> ((lp-&gt;pre_channel != ch) ||
(lp-&gt;pre_device != di)) {
<FONT COLOR=#0000FF>/* Here we got a problem:
* If using an ICN-Card, an incoming call is always signaled on
* on the first channel of the card, if both channels are
* down. However this channel may be bound exclusive. If the
* second channel is free, this call should be accepted.
* The solution is horribly but it runs, so what:
* We exchange the exclusive bindings of the two channels, the
* corresponding variables in the interface-structs.
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (ch == 0) {
sidx = <A HREF="isdn_common.c.shtml#isdn_dc2minor">isdn_dc2minor</A>(di, 1);
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_ICALL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"n_fi: ch is 0\n"</FONT>);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (<A HREF="../includes/isdn.h.shtml#USG_NONE">USG_NONE</A>(dev-&gt;usage[sidx])) {
<FONT COLOR=#0000FF>/* Second Channel is free, now see if it is bound
* exclusive too. */</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;usage[sidx] &amp; <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>) {
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_ICALL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"n_fi: 2nd channel is down and bound\n"</FONT>);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#0000FF>/* Yes, swap bindings only, if the original
* binding is bound to channel 1 of this driver */</FONT>
<FONT COLOR="#298C52">if</FONT> ((lp-&gt;pre_device == di) &amp;&amp;
(lp-&gt;pre_channel == 1)) {
<A HREF="#isdn_net_swapbind">isdn_net_swapbind</A>(di);
swapped = 1;
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR=#0000FF>/* ... else iterate next device */</FONT>
p = (<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *) p-&gt;next;
<FONT COLOR="#298C52">continue</FONT>;
}
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_ICALL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"n_fi: 2nd channel is down and unbound\n"</FONT>);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#0000FF>/* No, swap always and swap excl-usage also */</FONT>
<A HREF="#isdn_net_swap_usage">isdn_net_swap_usage</A>(idx, sidx);
<A HREF="#isdn_net_swapbind">isdn_net_swapbind</A>(di);
swapped = 2;
}
<FONT COLOR=#0000FF>/* Now check for exclusive binding again */</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_ICALL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"n_fi: final check\n"</FONT>);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> ((dev-&gt;usage[idx] &amp; <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>) &amp;&amp;
((lp-&gt;pre_channel != ch) ||
(lp-&gt;pre_device != di))) {
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_ICALL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"n_fi: final check failed\n"</FONT>);
<FONT COLOR=#A521F7>#endif</FONT>
p = (<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *) p-&gt;next;
<FONT COLOR="#298C52">continue</FONT>;
}
}
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR=#0000FF>/* We are already on the second channel, so nothing to do */</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_ICALL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"n_fi: already on 2nd channel\n"</FONT>);
<FONT COLOR=#A521F7>#endif</FONT>
p = (<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *) p-&gt;next;
<FONT COLOR="#298C52">continue</FONT>;
}
}
}
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_ICALL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"n_fi: match2\n"</FONT>);
<FONT COLOR=#A521F7>#endif</FONT>
n = lp-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>[0];
<FONT COLOR="#298C52">if</FONT> (lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_SECURE">ISDN_NET_SECURE</A>) {
<FONT COLOR="#298C52">while</FONT> (n) {
<FONT COLOR="#298C52">if</FONT> (!<A HREF="isdn_common.c.shtml#isdn_wildmat">isdn_wildmat</A>(nr, n-&gt;num))
<FONT COLOR="#298C52">break</FONT>;
n = (<A HREF="../includes/isdn.h.shtml#isdn_net_phone">isdn_net_phone</A> *) n-&gt;next;
}
}
<FONT COLOR="#298C52">if</FONT> (n || (!(lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_SECURE">ISDN_NET_SECURE</A>))) {
<FONT COLOR=#A521F7>#ifdef</FONT> ISDN_DEBUG_NET_ICALL
printk(KERN_DEBUG <FONT COLOR="#FF0000">"n_fi: match3\n"</FONT>);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#0000FF>/* Here we got an interface matched, now see if it is up.
* If not, reject the call actively.
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (!p-&gt;dev.start) {
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
printk(KERN_INFO <FONT COLOR="#FF0000">"%s: incoming call, interface down -&gt; rejected\n"</FONT>,
lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR="#298C52">return</FONT> 3;
}
<FONT COLOR=#0000FF>/* Interface is up, now see if it's a slave. If so, see if
* it's master and parent slave is online. If not, reject the call.
*/</FONT>
<FONT COLOR="#298C52">if</FONT> (lp-&gt;master) {
isdn_net_local *mlp = (isdn_net_local *) lp-&gt;master-&gt;priv;
printk(KERN_DEBUG <FONT COLOR="#FF0000">"ICALLslv: %s\n"</FONT>, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
printk(KERN_DEBUG <FONT COLOR="#FF0000">"master=%s\n"</FONT>, mlp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR="#298C52">if</FONT> (mlp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>) {
printk(KERN_DEBUG <FONT COLOR="#FF0000">"master online\n"</FONT>);
<FONT COLOR=#0000FF>/* Master is online, find parent-slave (master if first slave) */</FONT>
<FONT COLOR="#298C52">while</FONT> (mlp-&gt;slave) {
<FONT COLOR="#298C52">if</FONT> ((isdn_net_local *) mlp-&gt;slave-&gt;priv == lp)
<FONT COLOR="#298C52">break</FONT>;
mlp = (isdn_net_local *) mlp-&gt;slave-&gt;priv;
}
} <FONT COLOR="#298C52">else</FONT>
printk(KERN_DEBUG <FONT COLOR="#FF0000">"master offline\n"</FONT>);
<FONT COLOR=#0000FF>/* Found parent, if it's offline iterate next device */</FONT>
printk(KERN_DEBUG <FONT COLOR="#FF0000">"mlpf: %d\n"</FONT>, mlp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>);
<FONT COLOR="#298C52">if</FONT> (!(mlp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>)) {
p = (<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *) p-&gt;next;
<FONT COLOR="#298C52">continue</FONT>;
}
}
<FONT COLOR="#298C52">if</FONT> (lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CALLBACK">ISDN_NET_CALLBACK</A>) {
<FONT COLOR="#298C52">int</FONT> chi;
printk(KERN_DEBUG <FONT COLOR="#FF0000">"%s: call from %s -&gt; %s, start callback\n"</FONT>,
lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, nr, eaz);
<FONT COLOR="#298C52">if</FONT> (lp-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>[1]) {
<FONT COLOR=#0000FF>/* Grab a free ISDN-Channel */</FONT>
<FONT COLOR="#298C52">if</FONT> ((chi = <A HREF="isdn_common.c.shtml#isdn_get_free_channel">isdn_get_free_channel</A>(<A HREF="../includes/isdn.h.shtml#ISDN_USAGE_NET">ISDN_USAGE_NET</A>, lp-&gt;l2_proto,
lp-&gt;l3_proto,
lp-&gt;pre_device,
lp-&gt;pre_channel)) &lt; 0) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn_net_find_icall: No channel for %s\n"</FONT>, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#0000FF>/* Setup dialstate. */</FONT>
lp-&gt;dtimer = 0;
lp-&gt;dialstate = 11;
lp-&gt;flags |= <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>;
<FONT COLOR=#0000FF>/* Connect interface with channel */</FONT>
<A HREF="#isdn_net_bind_channel">isdn_net_bind_channel</A>(lp, chi);
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">if</FONT> (lp-&gt;p_encap == <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_SYNCPPP">ISDN_NET_ENCAP_SYNCPPP</A>)
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_ppp.c.shtml#isdn_ppp_bind">isdn_ppp_bind</A>(lp) &lt; 0) {
<A HREF="#isdn_net_unbind_channel">isdn_net_unbind_channel</A>(lp);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#0000FF>/* Initiate dialing by returning 2 or 4 */</FONT>
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> (lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CBHUP">ISDN_NET_CBHUP</A>) ? 2 : 4;
} <FONT COLOR="#298C52">else</FONT>
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn_net: %s: No phone number\n"</FONT>, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> 0;
} <FONT COLOR="#298C52">else</FONT> {
printk(KERN_DEBUG <FONT COLOR="#FF0000">"%s: call from %s -&gt; %s accepted\n"</FONT>, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, nr,
eaz);
<FONT COLOR=#0000FF>/* if this interface is dialing, it does it probably on a different
device, so free this device */</FONT>
<FONT COLOR="#298C52">if</FONT> ((lp-&gt;dialstate == 4) || (lp-&gt;dialstate == 12)) {
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">if</FONT> (lp-&gt;p_encap == <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_SYNCPPP">ISDN_NET_ENCAP_SYNCPPP</A>)
<A HREF="isdn_ppp.c.shtml#isdn_ppp_free">isdn_ppp_free</A>(lp);
<FONT COLOR=#A521F7>#endif</FONT>
<A HREF="isdn_common.c.shtml#isdn_free_channel">isdn_free_channel</A>(lp-&gt;isdn_device, lp-&gt;isdn_channel,
<A HREF="../includes/isdn.h.shtml#ISDN_USAGE_NET">ISDN_USAGE_NET</A>);
}
dev-&gt;usage[idx] &amp;= <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>;
dev-&gt;usage[idx] |= <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_NET">ISDN_USAGE_NET</A>;
strcpy(dev-&gt;num[idx], nr);
<A HREF="isdn_common.c.shtml#isdn_info_update">isdn_info_update</A>();
dev-&gt;st_netdev[idx] = lp-&gt;netdev;
lp-&gt;isdn_device = di;
lp-&gt;isdn_channel = ch;
lp-&gt;ppp_slot = -1;
lp-&gt;flags |= <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>;
lp-&gt;dialstate = 7;
lp-&gt;dtimer = 0;
lp-&gt;outgoing = 0;
lp-&gt;huptimer = 0;
lp-&gt;hupflags |= <A HREF="isdn_net.h.shtml#ISDN_WAITCHARGE">ISDN_WAITCHARGE</A>;
lp-&gt;hupflags &amp;= ~<A HREF="isdn_net.h.shtml#ISDN_HAVECHARGE">ISDN_HAVECHARGE</A>;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">if</FONT> (lp-&gt;p_encap == <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_SYNCPPP">ISDN_NET_ENCAP_SYNCPPP</A>)
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_ppp.c.shtml#isdn_ppp_bind">isdn_ppp_bind</A>(lp) &lt; 0) {
<A HREF="#isdn_net_unbind_channel">isdn_net_unbind_channel</A>(lp);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#A521F7>#endif</FONT>
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> 1;
}
}
}
p = (<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *) p-&gt;next;
}
<FONT COLOR=#0000FF>/* If none of configured EAZ/MSN matched and not verbose, be silent */</FONT>
<FONT COLOR="#298C52">if</FONT> (ematch || dev-&gt;net_verbose)
printk(KERN_INFO <FONT COLOR="#FF0000">"isdn_net: call from %s -&gt; %d %s ignored\n"</FONT>, nr, di, eaz);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> (wret == 2)?5:0;
}
<FONT COLOR=#0000FF>/*
* Search list of net-interfaces for an interface with given name.
*/</FONT>
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *
<A NAME="isdn_net_findif">isdn_net_findif</A>(<FONT COLOR="#298C52">char</FONT> *<A HREF="isdn_common.c.shtml#name">name</A>)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p = dev-&gt;netdev;
<FONT COLOR="#298C52">while</FONT> (p) {
<FONT COLOR="#298C52">if</FONT> (!strcmp(p-&gt;local-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, <A HREF="isdn_common.c.shtml#name">name</A>))
<FONT COLOR="#298C52">return</FONT> p;
p = (<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *) p-&gt;next;
}
<FONT COLOR="#298C52">return</FONT> (<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *) NULL;
}
<FONT COLOR=#0000FF>/*
* Force a net-interface to dial out.
* This is called from the userlevel-routine below or
* from isdn_net_start_xmit().
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_force_dial_lp">isdn_net_force_dial_lp</A>(isdn_net_local * lp)
{
<FONT COLOR="#298C52">if</FONT> ((!(lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>)) &amp;&amp; !lp-&gt;dialstate) {
<FONT COLOR="#298C52">int</FONT> chi;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>[1]) {
ulong flags;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<FONT COLOR=#0000FF>/* Grab a free ISDN-Channel */</FONT>
<FONT COLOR="#298C52">if</FONT> ((chi = <A HREF="isdn_common.c.shtml#isdn_get_free_channel">isdn_get_free_channel</A>(<A HREF="../includes/isdn.h.shtml#ISDN_USAGE_NET">ISDN_USAGE_NET</A>, lp-&gt;l2_proto,
lp-&gt;l3_proto,
lp-&gt;pre_device,
lp-&gt;pre_channel)) &lt; 0) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn_net_force_dial: No channel for %s\n"</FONT>, lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> -EAGAIN;
}
lp-&gt;dialstate = 1;
lp-&gt;flags |= <A HREF="../includes/isdn.h.shtml#ISDN_NET_CONNECTED">ISDN_NET_CONNECTED</A>;
<FONT COLOR=#0000FF>/* Connect interface with channel */</FONT>
<A HREF="#isdn_net_bind_channel">isdn_net_bind_channel</A>(lp, chi);
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
<FONT COLOR="#298C52">if</FONT> (lp-&gt;p_encap == <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_SYNCPPP">ISDN_NET_ENCAP_SYNCPPP</A>)
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_ppp.c.shtml#isdn_ppp_bind">isdn_ppp_bind</A>(lp) &lt; 0) {
<A HREF="#isdn_net_unbind_channel">isdn_net_unbind_channel</A>(lp);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> -EAGAIN;
}
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#0000FF>/* Initiate dialing */</FONT>
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<A HREF="#isdn_net_dial">isdn_net_dial</A>();
<FONT COLOR="#298C52">return</FONT> 0;
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EINVAL;
} <FONT COLOR="#298C52">else</FONT>
<FONT COLOR="#298C52">return</FONT> -EBUSY;
}
<FONT COLOR=#0000FF>/*
* Force a net-interface to dial out.
* This is always called from within userspace (ISDN_IOCTL_NET_DIAL).
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_force_dial">isdn_net_force_dial</A>(<FONT COLOR="#298C52">char</FONT> *<A HREF="isdn_common.c.shtml#name">name</A>)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p = <A HREF="#isdn_net_findif">isdn_net_findif</A>(<A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR="#298C52">if</FONT> (!p)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
<FONT COLOR="#298C52">return</FONT> (<A HREF="#isdn_net_force_dial_lp">isdn_net_force_dial_lp</A>(p-&gt;local));
}
<FONT COLOR=#0000FF>/*
* Allocate a new network-interface and initialize its data structures.
*/</FONT>
<FONT COLOR="#298C52">char</FONT> *
<A NAME="isdn_net_new">isdn_net_new</A>(<FONT COLOR="#298C52">char</FONT> *<A HREF="isdn_common.c.shtml#name">name</A>, <FONT COLOR="#298C52">struct</FONT> device *master)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *netdev;
<FONT COLOR=#0000FF>/* Avoid creating an existing interface */</FONT>
<FONT COLOR="#298C52">if</FONT> (<A HREF="#isdn_net_findif">isdn_net_findif</A>(<A HREF="isdn_common.c.shtml#name">name</A>)) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn_net: interface %s already exists\n"</FONT>, <A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR="#298C52">return</FONT> NULL;
}
<FONT COLOR="#298C52">if</FONT> (!(netdev = (<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *) kmalloc(<FONT COLOR="#298C52">sizeof</FONT>(<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A>), GFP_KERNEL))) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn_net: Could not allocate net-device\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> NULL;
}
memset(netdev, 0, <FONT COLOR="#298C52">sizeof</FONT>(<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A>));
<FONT COLOR="#298C52">if</FONT> (!(netdev-&gt;local = (isdn_net_local *) kmalloc(<FONT COLOR="#298C52">sizeof</FONT>(isdn_net_local), GFP_KERNEL))) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn_net: Could not allocate device locals\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> NULL;
}
memset(netdev-&gt;local, 0, <FONT COLOR="#298C52">sizeof</FONT>(isdn_net_local));
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_common.c.shtml#name">name</A> == NULL)
strcpy(netdev-&gt;local-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, <FONT COLOR="#FF0000">" "</FONT>);
<FONT COLOR="#298C52">else</FONT>
strcpy(netdev-&gt;local-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, <A HREF="isdn_common.c.shtml#name">name</A>);
netdev-&gt;dev.<A HREF="isdn_common.c.shtml#name">name</A> = netdev-&gt;local-&gt;<A HREF="isdn_common.c.shtml#name">name</A>;
netdev-&gt;dev.priv = netdev-&gt;local;
netdev-&gt;dev.init = <A HREF="#isdn_net_init">isdn_net_init</A>;
netdev-&gt;local-&gt;p_encap = <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_RAWIP">ISDN_NET_ENCAP_RAWIP</A>;
<FONT COLOR="#298C52">if</FONT> (master) {
<FONT COLOR=#0000FF>/* Device shall be a slave */</FONT>
<FONT COLOR="#298C52">struct</FONT> device *p = (((isdn_net_local *) master-&gt;priv)-&gt;slave);
<FONT COLOR="#298C52">struct</FONT> device *q = master;
netdev-&gt;local-&gt;master = master;
<FONT COLOR=#0000FF>/* Put device at end of slave-chain */</FONT>
<FONT COLOR="#298C52">while</FONT> (p) {
q = p;
p = (((isdn_net_local *) p-&gt;priv)-&gt;slave);
}
((isdn_net_local *) q-&gt;priv)-&gt;slave = &amp;(netdev-&gt;dev);
q-&gt;interrupt = 0;
q-&gt;tbusy = 0;
q-&gt;start = master-&gt;start;
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR=#0000FF>/* Device shall be a master */</FONT>
<FONT COLOR="#298C52">if</FONT> (register_netdev(&amp;netdev-&gt;dev) != 0) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn_net: Could not register net-device\n"</FONT>);
kfree(netdev-&gt;local);
kfree(netdev);
<FONT COLOR="#298C52">return</FONT> NULL;
}
}
netdev-&gt;local-&gt;magic = <A HREF="../includes/isdn.h.shtml#ISDN_NET_MAGIC">ISDN_NET_MAGIC</A>;
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_PPP
netdev-&gt;mp_last = NULL; <FONT COLOR=#0000FF>/* mpqueue is empty */</FONT>
netdev-&gt;ib.next_num = 0;
netdev-&gt;ib.last = NULL;
<FONT COLOR=#A521F7>#endif</FONT>
netdev-&gt;queue = netdev-&gt;local;
netdev-&gt;local-&gt;last = netdev-&gt;local;
netdev-&gt;local-&gt;netdev = netdev;
netdev-&gt;local-&gt;next = netdev-&gt;local;
netdev-&gt;local-&gt;isdn_device = -1;
netdev-&gt;local-&gt;isdn_channel = -1;
netdev-&gt;local-&gt;pre_device = -1;
netdev-&gt;local-&gt;pre_channel = -1;
netdev-&gt;local-&gt;exclusive = -1;
netdev-&gt;local-&gt;ppp_slot = -1;
netdev-&gt;local-&gt;pppbind = -1;
netdev-&gt;local-&gt;sav_skb = NULL;
netdev-&gt;local-&gt;first_skb = NULL;
netdev-&gt;local-&gt;l2_proto = <A HREF="../includes/isdnif.h.shtml#ISDN_PROTO_L2_X75I">ISDN_PROTO_L2_X75I</A>;
netdev-&gt;local-&gt;l3_proto = <A HREF="../includes/isdnif.h.shtml#ISDN_PROTO_L3_TRANS">ISDN_PROTO_L3_TRANS</A>;
netdev-&gt;local-&gt;triggercps = 6000;
netdev-&gt;local-&gt;slavedelay = 10 * HZ;
netdev-&gt;local-&gt;srobin = &amp;netdev-&gt;dev;
netdev-&gt;local-&gt;hupflags = <A HREF="isdn_net.h.shtml#ISDN_INHUP">ISDN_INHUP</A>; <FONT COLOR=#0000FF>/* Do hangup even on incoming calls */</FONT>
netdev-&gt;local-&gt;onhtime = 10; <FONT COLOR=#0000FF>/* Default hangup-time for saving costs
of those who forget configuring this */</FONT>
netdev-&gt;local-&gt;dialmax = 1;
netdev-&gt;local-&gt;flags = <A HREF="../includes/isdn.h.shtml#ISDN_NET_CBHUP">ISDN_NET_CBHUP</A> | <A HREF="../includes/isdn.h.shtml#ISDN_NET_STOPPED">ISDN_NET_STOPPED</A>; <FONT COLOR=#0000FF>/* Hangup before Callback, autodial suppressed */</FONT>
netdev-&gt;local-&gt;cbdelay = 25; <FONT COLOR=#0000FF>/* Wait 5 secs before Callback */</FONT>
netdev-&gt;local-&gt;dialtimeout = -1; <FONT COLOR=#0000FF>/* Infinite Dial-Timeout */</FONT>
netdev-&gt;local-&gt;dialwait = 5 * HZ; <FONT COLOR=#0000FF>/* Wait 5 sec. after failed dial */</FONT>
netdev-&gt;local-&gt;dialstarted = 0; <FONT COLOR=#0000FF>/* Jiffies of last dial-start */</FONT>
netdev-&gt;local-&gt;dialwait_timer = 0; <FONT COLOR=#0000FF>/* Jiffies of earliest next dial-start */</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_TIMEOUT_RULES
netdev-&gt;local-&gt;timeout_rules = NULL;
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_BUDGET
(<FONT COLOR="#298C52">void</FONT>)<A HREF="isdn_budget.c.shtml#isdn_net_budget">isdn_net_budget</A>(<A HREF="../includes/isdn_budget.h.shtml#ISDN_BUDGET_INIT">ISDN_BUDGET_INIT</A>, &amp;netdev-&gt;dev);
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#0000FF>/* Put into to netdev-chain */</FONT>
netdev-&gt;next = (<FONT COLOR="#298C52">void</FONT> *) dev-&gt;netdev;
dev-&gt;netdev = netdev;
<FONT COLOR="#298C52">return</FONT> netdev-&gt;dev.<A HREF="isdn_common.c.shtml#name">name</A>;
}
<FONT COLOR="#298C52">char</FONT> *
<A NAME="isdn_net_newslave">isdn_net_newslave</A>(<FONT COLOR="#298C52">char</FONT> *parm)
{
<FONT COLOR="#298C52">char</FONT> *p = strchr(parm, <FONT COLOR="#FF0000">','</FONT>);
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *n;
<FONT COLOR="#298C52">char</FONT> newname[10];
<FONT COLOR="#298C52">if</FONT> (p) {
<FONT COLOR=#0000FF>/* Slave-Name MUST not be empty */</FONT>
<FONT COLOR="#298C52">if</FONT> (!strlen(p + 1))
<FONT COLOR="#298C52">return</FONT> NULL;
strcpy(newname, p + 1);
*p = 0;
<FONT COLOR=#0000FF>/* Master must already exist */</FONT>
<FONT COLOR="#298C52">if</FONT> (!(n = <A HREF="#isdn_net_findif">isdn_net_findif</A>(parm)))
<FONT COLOR="#298C52">return</FONT> NULL;
<FONT COLOR=#0000FF>/* Master must be a real interface, not a slave */</FONT>
<FONT COLOR="#298C52">if</FONT> (n-&gt;local-&gt;master)
<FONT COLOR="#298C52">return</FONT> NULL;
<FONT COLOR=#0000FF>/* Master must not be started yet */</FONT>
<FONT COLOR="#298C52">if</FONT> (n-&gt;dev.start)
<FONT COLOR="#298C52">return</FONT> NULL;
<FONT COLOR="#298C52">return</FONT> (<A HREF="#isdn_net_new">isdn_net_new</A>(newname, &amp;(n-&gt;dev)));
}
<FONT COLOR="#298C52">return</FONT> NULL;
}
<FONT COLOR=#0000FF>/*
* Set interface-parameters.
* Always set all parameters, so the user-level application is responsible
* for not overwriting existing setups. It has to get the current
* setup first, if only selected parameters are to be changed.
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_setcfg">isdn_net_setcfg</A>(<A HREF="../includes/isdn.h.shtml#isdn_net_ioctl_cfg">isdn_net_ioctl_cfg</A> * <A HREF="isdn_common.c.shtml#cfg">cfg</A>)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p = <A HREF="#isdn_net_findif">isdn_net_findif</A>(<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
ulong features;
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">int</FONT> drvidx;
<FONT COLOR="#298C52">int</FONT> chidx;
<FONT COLOR="#298C52">char</FONT> drvid[25];
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
ulong flags;
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (p) {
isdn_net_local *lp = p-&gt;local;
<FONT COLOR=#0000FF>/* See if any registered driver supports the features we want */</FONT>
features = ((1 &lt;&lt; <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;l2_proto) &lt;&lt; <A HREF="../includes/isdnif.h.shtml#ISDN_FEATURE_L2_SHIFT">ISDN_FEATURE_L2_SHIFT</A>) |
((1 &lt;&lt; <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;l3_proto) &lt;&lt; <A HREF="../includes/isdnif.h.shtml#ISDN_FEATURE_L3_SHIFT">ISDN_FEATURE_L3_SHIFT</A>);
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>; i++)
<FONT COLOR="#298C52">if</FONT> (dev-&gt;drv[i])
<FONT COLOR="#298C52">if</FONT> ((dev-&gt;drv[i]-&gt;interface-&gt;features &amp; features) == features)
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">if</FONT> (i == <A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>) {
printk(KERN_WARNING <FONT COLOR="#FF0000">"isdn_net: No driver with selected features\n"</FONT>);
<FONT COLOR="#298C52">return</FONT> -ENODEV;
}
<FONT COLOR="#298C52">if</FONT> (lp-&gt;p_encap != <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;p_encap){
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR="#298C52">struct</FONT> concap_proto * cprot = p -&gt; cprot;
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">if</FONT> (p-&gt;dev.start) {
printk(KERN_WARNING
<FONT COLOR="#FF0000">"%s: cannot change encap when if is up\n"</FONT>,
lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR="#298C52">return</FONT> -EBUSY;
}
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR=#0000FF>/* delete old encapsulation protocol if present ... */</FONT>
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>(); <FONT COLOR=#0000FF>/* avoid races with incoming events trying to
call cprot-&gt;pops methods */</FONT>
<FONT COLOR="#298C52">if</FONT>( cprot &amp;&amp; cprot -&gt; pops )
cprot -&gt; pops -&gt; proto_del ( cprot );
p -&gt; cprot = NULL;
lp -&gt; dops = NULL;
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR=#0000FF>/* ... , prepare for configuration of new one ... */</FONT>
<FONT COLOR="#298C52">switch</FONT> ( <A HREF="isdn_common.c.shtml#cfg">cfg</A> -&gt; p_encap ){
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_X25IFACE">ISDN_NET_ENCAP_X25IFACE</A>:
lp -&gt; dops = &amp;isdn_concap_reliable_dl_dops;
}
<FONT COLOR=#0000FF>/* ... and allocate new one ... */</FONT>
p -&gt; cprot = <A HREF="isdn_concap.c.shtml#isdn_concap_new">isdn_concap_new</A>( <A HREF="isdn_common.c.shtml#cfg">cfg</A> -&gt; p_encap );
<FONT COLOR=#0000FF>/* p -&gt; cprot == NULL now if p_encap is not supported
by means of the concap_proto mechanism */</FONT>
<FONT COLOR=#0000FF>/* the protocol is not configured yet; this will
happen later when isdn_net_reset() is called */</FONT>
<FONT COLOR=#A521F7>#endif</FONT>
}
<FONT COLOR="#298C52">switch</FONT> ( <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;p_encap ) {
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_SYNCPPP">ISDN_NET_ENCAP_SYNCPPP</A>:
<FONT COLOR=#A521F7>#ifndef</FONT> CONFIG_ISDN_PPP
printk(KERN_WARNING <FONT COLOR="#FF0000">"%s: SyncPPP support not configured\n"</FONT>,
lp-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR=#A521F7>#else</FONT>
p-&gt;dev.type = ARPHRD_PPP; <FONT COLOR=#0000FF>/* change ARP type */</FONT>
p-&gt;dev.addr_len = 0;
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_X25IFACE">ISDN_NET_ENCAP_X25IFACE</A>:
<FONT COLOR=#A521F7>#ifndef</FONT> CONFIG_ISDN_X25
printk(KERN_WARNING <FONT COLOR="#FF0000">"%s: isdn-x25 support not configured\n"</FONT>,
p-&gt;local-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR=#A521F7>#else</FONT>
p-&gt;dev.type = ARPHRD_X25; <FONT COLOR=#0000FF>/* change ARP type */</FONT>
p-&gt;dev.addr_len = 0;
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">default</FONT>:
<FONT COLOR="#298C52">if</FONT>( <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;p_encap &gt;= 0 &amp;&amp;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;p_encap &lt;= <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_MAX_ENCAP">ISDN_NET_ENCAP_MAX_ENCAP</A> )
<FONT COLOR="#298C52">break</FONT>;
printk(KERN_WARNING
<FONT COLOR="#FF0000">"%s: encapsulation protocol %d not supported\n"</FONT>,
p-&gt;local-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;p_encap);
<FONT COLOR="#298C52">return</FONT> -EINVAL;
}
<FONT COLOR="#298C52">if</FONT> (strlen(<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;drvid)) {
<FONT COLOR=#0000FF>/* A bind has been requested ... */</FONT>
<FONT COLOR="#298C52">char</FONT> *c,
*e;
drvidx = -1;
chidx = -1;
strcpy(drvid, <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;drvid);
<FONT COLOR="#298C52">if</FONT> ((c = strchr(drvid, <FONT COLOR="#FF0000">','</FONT>))) {
<FONT COLOR=#0000FF>/* The channel-number is appended to the driver-Id with a comma */</FONT>
chidx = (<FONT COLOR="#298C52">int</FONT>) simple_strtoul(c + 1, &amp;e, 10);
<FONT COLOR="#298C52">if</FONT> (e == c)
chidx = -1;
*c = <FONT COLOR="#FF0000">'\0'</FONT>;
}
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; <A HREF="../includes/isdn.h.shtml#ISDN_MAX_DRIVERS">ISDN_MAX_DRIVERS</A>; i++)
<FONT COLOR=#0000FF>/* Lookup driver-Id in array */</FONT>
<FONT COLOR="#298C52">if</FONT> (!(strcmp(dev-&gt;drvid[i], drvid))) {
drvidx = i;
<FONT COLOR="#298C52">break</FONT>;
}
<FONT COLOR="#298C52">if</FONT> ((drvidx == -1) || (chidx == -1))
<FONT COLOR=#0000FF>/* Either driver-Id or channel-number invalid */</FONT>
<FONT COLOR="#298C52">return</FONT> -ENODEV;
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR=#0000FF>/* Parameters are valid, so get them */</FONT>
drvidx = lp-&gt;pre_device;
chidx = lp-&gt;pre_channel;
}
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;exclusive &gt; 0) {
<FONT COLOR="#298C52">int</FONT> flags;
<FONT COLOR=#0000FF>/* If binding is exclusive, try to grab the channel */</FONT>
save_flags(flags);
<FONT COLOR="#298C52">if</FONT> ((i = <A HREF="isdn_common.c.shtml#isdn_get_free_channel">isdn_get_free_channel</A>(<A HREF="../includes/isdn.h.shtml#ISDN_USAGE_NET">ISDN_USAGE_NET</A>, lp-&gt;l2_proto,
lp-&gt;l3_proto,
drvidx,
chidx)) &lt; 0) {
<FONT COLOR=#0000FF>/* Grab failed, because desired channel is in use */</FONT>
lp-&gt;exclusive = -1;
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> -EBUSY;
}
<FONT COLOR=#0000FF>/* All went ok, so update isdninfo */</FONT>
dev-&gt;usage[i] = <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_EXCLUSIVE">ISDN_USAGE_EXCLUSIVE</A>;
<A HREF="isdn_common.c.shtml#isdn_info_update">isdn_info_update</A>();
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
lp-&gt;exclusive = i;
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR=#0000FF>/* Non-exclusive binding or unbind. */</FONT>
lp-&gt;exclusive = -1;
<FONT COLOR="#298C52">if</FONT> ((lp-&gt;pre_device != -1) &amp;&amp; (<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;exclusive == -1)) {
<A HREF="isdn_common.c.shtml#isdn_unexclusive_channel">isdn_unexclusive_channel</A>(lp-&gt;pre_device, lp-&gt;pre_channel);
<A HREF="isdn_common.c.shtml#isdn_free_channel">isdn_free_channel</A>(lp-&gt;pre_device, lp-&gt;pre_channel, <A HREF="../includes/isdn.h.shtml#ISDN_USAGE_NET">ISDN_USAGE_NET</A>);
drvidx = -1;
chidx = -1;
}
}
strcpy(lp-&gt;msn, <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;eaz);
lp-&gt;pre_device = drvidx;
lp-&gt;pre_channel = chidx;
lp-&gt;onhtime = <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;onhtime;
lp-&gt;charge = <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;charge;
lp-&gt;l2_proto = <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;l2_proto;
lp-&gt;l3_proto = <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;l3_proto;
lp-&gt;cbdelay = <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;cbdelay;
lp-&gt;dialmax = <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;dialmax;
lp-&gt;triggercps = <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;triggercps;
lp-&gt;slavedelay = <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;slavedelay * HZ;
lp-&gt;pppbind = <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;pppbind;
lp-&gt;dialtimeout = <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;dialtimeout &gt;= 0 ? <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;dialtimeout * HZ : -1;
lp-&gt;dialwait = <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;dialwait * HZ;
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;secure)
lp-&gt;flags |= <A HREF="../includes/isdn.h.shtml#ISDN_NET_SECURE">ISDN_NET_SECURE</A>;
<FONT COLOR="#298C52">else</FONT>
lp-&gt;flags &amp;= ~<A HREF="../includes/isdn.h.shtml#ISDN_NET_SECURE">ISDN_NET_SECURE</A>;
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;cbhup)
lp-&gt;flags |= <A HREF="../includes/isdn.h.shtml#ISDN_NET_CBHUP">ISDN_NET_CBHUP</A>;
<FONT COLOR="#298C52">else</FONT>
lp-&gt;flags &amp;= ~<A HREF="../includes/isdn.h.shtml#ISDN_NET_CBHUP">ISDN_NET_CBHUP</A>;
<FONT COLOR="#298C52">switch</FONT> (<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;callback) {
<FONT COLOR="#298C52">case</FONT> 0:
lp-&gt;flags &amp;= ~(<A HREF="../includes/isdn.h.shtml#ISDN_NET_CALLBACK">ISDN_NET_CALLBACK</A> | <A HREF="../includes/isdn.h.shtml#ISDN_NET_CBOUT">ISDN_NET_CBOUT</A>);
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 1:
lp-&gt;flags |= <A HREF="../includes/isdn.h.shtml#ISDN_NET_CALLBACK">ISDN_NET_CALLBACK</A>;
lp-&gt;flags &amp;= ~<A HREF="../includes/isdn.h.shtml#ISDN_NET_CBOUT">ISDN_NET_CBOUT</A>;
<FONT COLOR="#298C52">break</FONT>;
<FONT COLOR="#298C52">case</FONT> 2:
lp-&gt;flags |= <A HREF="../includes/isdn.h.shtml#ISDN_NET_CBOUT">ISDN_NET_CBOUT</A>;
lp-&gt;flags &amp;= ~<A HREF="../includes/isdn.h.shtml#ISDN_NET_CALLBACK">ISDN_NET_CALLBACK</A>;
<FONT COLOR="#298C52">break</FONT>;
}
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;stopped)
lp-&gt;flags |= <A HREF="../includes/isdn.h.shtml#ISDN_NET_STOPPED">ISDN_NET_STOPPED</A>;
<FONT COLOR="#298C52">else</FONT>
lp-&gt;flags &amp;= ~<A HREF="../includes/isdn.h.shtml#ISDN_NET_STOPPED">ISDN_NET_STOPPED</A>;
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;chargehup)
lp-&gt;hupflags |= <A HREF="isdn_net.h.shtml#ISDN_CHARGEHUP">ISDN_CHARGEHUP</A>;
<FONT COLOR="#298C52">else</FONT>
lp-&gt;hupflags &amp;= ~<A HREF="isdn_net.h.shtml#ISDN_CHARGEHUP">ISDN_CHARGEHUP</A>;
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;ihup)
lp-&gt;hupflags |= <A HREF="isdn_net.h.shtml#ISDN_INHUP">ISDN_INHUP</A>;
<FONT COLOR="#298C52">else</FONT>
lp-&gt;hupflags &amp;= ~<A HREF="isdn_net.h.shtml#ISDN_INHUP">ISDN_INHUP</A>;
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;chargeint &gt; 10) {
lp-&gt;hupflags |= <A HREF="isdn_net.h.shtml#ISDN_CHARGEHUP">ISDN_CHARGEHUP</A> | <A HREF="isdn_net.h.shtml#ISDN_HAVECHARGE">ISDN_HAVECHARGE</A> | <A HREF="isdn_net.h.shtml#ISDN_MANCHARGE">ISDN_MANCHARGE</A>;
lp-&gt;chargeint = <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;chargeint * HZ;
}
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;p_encap != lp-&gt;p_encap) {
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;p_encap == <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_RAWIP">ISDN_NET_ENCAP_RAWIP</A>) {
p-&gt;dev.hard_header = NULL;
p-&gt;dev.hard_header_cache = NULL;
p-&gt;dev.header_cache_update = NULL;
p-&gt;dev.flags = IFF_NOARP|IFF_POINTOPOINT;
} <FONT COLOR="#298C52">else</FONT> {
p-&gt;dev.hard_header = <A HREF="#isdn_net_header">isdn_net_header</A>;
<FONT COLOR="#298C52">if</FONT> (<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;p_encap == <A HREF="../includes/isdn.h.shtml#ISDN_NET_ENCAP_ETHER">ISDN_NET_ENCAP_ETHER</A>) {
p-&gt;dev.hard_header_cache = lp-&gt;org_hhc;
p-&gt;dev.header_cache_update = lp-&gt;org_hcu;
p-&gt;dev.flags = IFF_BROADCAST | IFF_MULTICAST;
} <FONT COLOR="#298C52">else</FONT> {
p-&gt;dev.hard_header_cache = NULL;
p-&gt;dev.header_cache_update = NULL;
p-&gt;dev.flags = IFF_NOARP|IFF_POINTOPOINT;
}
}
}
lp-&gt;p_encap = <A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;p_encap;
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">return</FONT> -ENODEV;
}
<FONT COLOR=#0000FF>/*
* Perform get-interface-parameters.ioctl
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_getcfg">isdn_net_getcfg</A>(<A HREF="../includes/isdn.h.shtml#isdn_net_ioctl_cfg">isdn_net_ioctl_cfg</A> * <A HREF="isdn_common.c.shtml#cfg">cfg</A>)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p = <A HREF="#isdn_net_findif">isdn_net_findif</A>(<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR="#298C52">if</FONT> (p) {
isdn_net_local *lp = p-&gt;local;
strcpy(<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;eaz, lp-&gt;msn);
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;exclusive = lp-&gt;exclusive;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;pre_device &gt;= 0) {
sprintf(<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;drvid, <FONT COLOR="#FF0000">"%s,%d"</FONT>, dev-&gt;drvid[lp-&gt;pre_device],
lp-&gt;pre_channel);
} <FONT COLOR="#298C52">else</FONT>
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;drvid[0] = <FONT COLOR="#FF0000">'\0'</FONT>;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;onhtime = lp-&gt;onhtime;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;charge = lp-&gt;charge;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;l2_proto = lp-&gt;l2_proto;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;l3_proto = lp-&gt;l3_proto;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;p_encap = lp-&gt;p_encap;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;secure = (lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_SECURE">ISDN_NET_SECURE</A>) ? 1 : 0;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;callback = 0;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CALLBACK">ISDN_NET_CALLBACK</A>)
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;callback = 1;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CBOUT">ISDN_NET_CBOUT</A>)
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;callback = 2;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;cbhup = (lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_CBHUP">ISDN_NET_CBHUP</A>) ? 1 : 0;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;stopped = (lp-&gt;flags &amp; <A HREF="../includes/isdn.h.shtml#ISDN_NET_STOPPED">ISDN_NET_STOPPED</A>) ? 1 : 0;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;chargehup = (lp-&gt;hupflags &amp; 4) ? 1 : 0;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;ihup = (lp-&gt;hupflags &amp; 8) ? 1 : 0;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;cbdelay = lp-&gt;cbdelay;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;dialmax = lp-&gt;dialmax;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;triggercps = lp-&gt;triggercps;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;slavedelay = lp-&gt;slavedelay / HZ;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;chargeint = (lp-&gt;hupflags &amp; <A HREF="isdn_net.h.shtml#ISDN_CHARGEHUP">ISDN_CHARGEHUP</A>) ?
(lp-&gt;chargeint / HZ) : 0;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;pppbind = lp-&gt;pppbind;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;dialtimeout = lp-&gt;dialtimeout &gt;= 0 ? lp-&gt;dialtimeout / HZ : -1;
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;dialwait = lp-&gt;dialwait / HZ;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;slave)
strcpy(<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;slave, ((isdn_net_local *) lp-&gt;slave-&gt;priv)-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR="#298C52">else</FONT>
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;slave[0] = <FONT COLOR="#FF0000">'\0'</FONT>;
<FONT COLOR="#298C52">if</FONT> (lp-&gt;master)
strcpy(<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;master, ((isdn_net_local *) lp-&gt;master-&gt;priv)-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR="#298C52">else</FONT>
<A HREF="isdn_common.c.shtml#cfg">cfg</A>-&gt;master[0] = <FONT COLOR="#FF0000">'\0'</FONT>;
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">return</FONT> -ENODEV;
}
<FONT COLOR=#0000FF>/*
* Add a phone-number to an interface.
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_addphone">isdn_net_addphone</A>(<A HREF="../includes/isdn.h.shtml#isdn_net_ioctl_phone">isdn_net_ioctl_phone</A> * <A HREF="isdn_common.c.shtml#phone">phone</A>)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p = <A HREF="#isdn_net_findif">isdn_net_findif</A>(<A HREF="isdn_common.c.shtml#phone">phone</A>-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<A HREF="../includes/isdn.h.shtml#isdn_net_phone">isdn_net_phone</A> *n;
<FONT COLOR="#298C52">if</FONT> (<A HREF="#isdn_net_checkwild">isdn_net_checkwild</A>(<A HREF="isdn_common.c.shtml#phone">phone</A>-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>) &amp;&amp; (<A HREF="isdn_common.c.shtml#phone">phone</A>-&gt;outgoing &amp; 1))
<FONT COLOR="#298C52">return</FONT> -EINVAL;
<FONT COLOR="#298C52">if</FONT> (p) {
<FONT COLOR="#298C52">if</FONT> (!(n = (<A HREF="../includes/isdn.h.shtml#isdn_net_phone">isdn_net_phone</A> *) kmalloc(<FONT COLOR="#298C52">sizeof</FONT>(<A HREF="../includes/isdn.h.shtml#isdn_net_phone">isdn_net_phone</A>), GFP_KERNEL)))
<FONT COLOR="#298C52">return</FONT> -ENOMEM;
strcpy(n-&gt;num, <A HREF="isdn_common.c.shtml#phone">phone</A>-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>);
n-&gt;next = p-&gt;local-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>[<A HREF="isdn_common.c.shtml#phone">phone</A>-&gt;outgoing &amp; 1];
p-&gt;local-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>[<A HREF="isdn_common.c.shtml#phone">phone</A>-&gt;outgoing &amp; 1] = n;
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">return</FONT> -ENODEV;
}
<FONT COLOR=#0000FF>/*
* Copy a string of all phone-numbers of an interface to user space.
* This might sleep and must be called with the isdn semaphore down.
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A HREF="#isdn_net_getphones">isdn_net_getphones</A>(<A HREF="../includes/isdn.h.shtml#isdn_net_ioctl_phone">isdn_net_ioctl_phone</A> * <A HREF="isdn_common.c.shtml#phone">phone</A>, <FONT COLOR="#298C52">char</FONT> *phones)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p = <A HREF="#isdn_net_findif">isdn_net_findif</A>(<A HREF="isdn_common.c.shtml#phone">phone</A>-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR="#298C52">int</FONT> inout = <A HREF="isdn_common.c.shtml#phone">phone</A>-&gt;outgoing &amp; 1;
<FONT COLOR="#298C52">int</FONT> more = 0;
<FONT COLOR="#298C52">int</FONT> count = 0;
<A HREF="../includes/isdn.h.shtml#isdn_net_phone">isdn_net_phone</A> *n;
<FONT COLOR="#298C52">if</FONT> (!p)
<FONT COLOR="#298C52">return</FONT> -ENODEV;
inout &amp;= 1;
<FONT COLOR="#298C52">for</FONT> (n = p-&gt;local-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>[inout]; n; n = n-&gt;next) {
<FONT COLOR="#298C52">if</FONT> (more) {
put_user(<FONT COLOR="#FF0000">' '</FONT>, phones++);
count++;
}
<FONT COLOR="#298C52">if</FONT> (copy_to_user(phones, n-&gt;num, strlen(n-&gt;num) + 1)) {
<FONT COLOR="#298C52">return</FONT> -EFAULT;
}
phones += strlen(n-&gt;num);
count += strlen(n-&gt;num);
more = 1;
}
put_user(0, phones);
count++;
<FONT COLOR="#298C52">return</FONT> count;
}
<FONT COLOR=#0000FF>/*
* Delete a phone-number from an interface.
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_delphone">isdn_net_delphone</A>(<A HREF="../includes/isdn.h.shtml#isdn_net_ioctl_phone">isdn_net_ioctl_phone</A> * <A HREF="isdn_common.c.shtml#phone">phone</A>)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p = <A HREF="#isdn_net_findif">isdn_net_findif</A>(<A HREF="isdn_common.c.shtml#phone">phone</A>-&gt;<A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR="#298C52">int</FONT> inout = <A HREF="isdn_common.c.shtml#phone">phone</A>-&gt;outgoing &amp; 1;
<A HREF="../includes/isdn.h.shtml#isdn_net_phone">isdn_net_phone</A> *n;
<A HREF="../includes/isdn.h.shtml#isdn_net_phone">isdn_net_phone</A> *m;
<FONT COLOR="#298C52">int</FONT> flags;
<FONT COLOR="#298C52">if</FONT> (p) {
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
n = p-&gt;local-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>[inout];
m = NULL;
<FONT COLOR="#298C52">while</FONT> (n) {
<FONT COLOR="#298C52">if</FONT> (!strcmp(n-&gt;num, <A HREF="isdn_common.c.shtml#phone">phone</A>-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>)) {
<FONT COLOR="#298C52">if</FONT> (p-&gt;local-&gt;dial == n)
p-&gt;local-&gt;dial = n-&gt;next;
<FONT COLOR="#298C52">if</FONT> (m)
m-&gt;next = n-&gt;next;
<FONT COLOR="#298C52">else</FONT>
p-&gt;local-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>[inout] = n-&gt;next;
kfree(n);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> 0;
}
m = n;
n = (<A HREF="../includes/isdn.h.shtml#isdn_net_phone">isdn_net_phone</A> *) n-&gt;next;
}
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> -EINVAL;
}
<FONT COLOR="#298C52">return</FONT> -ENODEV;
}
<FONT COLOR=#0000FF>/*
* Delete all phone-numbers of an interface.
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_rmallphone">isdn_net_rmallphone</A>(<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> * p)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_phone">isdn_net_phone</A> *n;
<A HREF="../includes/isdn.h.shtml#isdn_net_phone">isdn_net_phone</A> *m;
<FONT COLOR="#298C52">int</FONT> flags;
<FONT COLOR="#298C52">int</FONT> i;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; 2; i++) {
n = p-&gt;local-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>[i];
<FONT COLOR="#298C52">while</FONT> (n) {
m = n-&gt;next;
kfree(n);
n = m;
}
p-&gt;local-&gt;<A HREF="isdn_common.c.shtml#phone">phone</A>[i] = NULL;
}
p-&gt;local-&gt;dial = NULL;
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#0000FF>/*
* Force a hangup of a network-interface.
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_force_hangup">isdn_net_force_hangup</A>(<FONT COLOR="#298C52">char</FONT> *<A HREF="isdn_common.c.shtml#name">name</A>)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p = <A HREF="#isdn_net_findif">isdn_net_findif</A>(<A HREF="isdn_common.c.shtml#name">name</A>);
<FONT COLOR="#298C52">struct</FONT> device *q;
<FONT COLOR="#298C52">if</FONT> (p) {
<FONT COLOR="#298C52">if</FONT> (p-&gt;local-&gt;isdn_device &lt; 0)
<FONT COLOR="#298C52">return</FONT> 1;
q = p-&gt;local-&gt;slave;
<FONT COLOR=#0000FF>/* If this interface has slaves, do a hangup for them also. */</FONT>
<FONT COLOR="#298C52">while</FONT> (q) {
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(q);
q = (((isdn_net_local *) q-&gt;priv)-&gt;slave);
}
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR="#298C52">return</FONT> -ENODEV;
}
<FONT COLOR=#0000FF>/*
* Helper-function for isdn_net_rm: Do the real work.
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">int</FONT>
<A HREF="#isdn_net_realrm">isdn_net_realrm</A>(<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> * p, <A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> * q)
{
<FONT COLOR="#298C52">int</FONT> flags;
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<FONT COLOR="#298C52">if</FONT> (p-&gt;local-&gt;master) {
<FONT COLOR=#0000FF>/* If it's a slave, it may be removed even if it is busy. However
* it has to be hung up first.
*/</FONT>
<A HREF="#isdn_net_hangup">isdn_net_hangup</A>(&amp;p-&gt;dev);
p-&gt;dev.start = 0;
}
<FONT COLOR="#298C52">if</FONT> (p-&gt;dev.start) {
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> -EBUSY;
}
<FONT COLOR=#A521F7>#ifdef</FONT> CONFIG_ISDN_X25
<FONT COLOR="#298C52">if</FONT>( p -&gt; cprot &amp;&amp; p -&gt; cprot -&gt; pops )
p -&gt; cprot -&gt; pops -&gt; proto_del ( p -&gt; cprot );
<FONT COLOR=#A521F7>#endif</FONT>
<FONT COLOR=#0000FF>/* Free all phone-entries */</FONT>
<A HREF="#isdn_net_rmallphone">isdn_net_rmallphone</A>(p);
<FONT COLOR=#0000FF>/* If interface is bound exclusive, free channel-usage */</FONT>
<FONT COLOR="#298C52">if</FONT> (p-&gt;local-&gt;exclusive != -1)
<A HREF="isdn_common.c.shtml#isdn_unexclusive_channel">isdn_unexclusive_channel</A>(p-&gt;local-&gt;pre_device, p-&gt;local-&gt;pre_channel);
<FONT COLOR="#298C52">if</FONT> (p-&gt;local-&gt;master) {
<FONT COLOR=#0000FF>/* It's a slave-device, so update master's slave-pointer if necessary */</FONT>
<FONT COLOR="#298C52">if</FONT> (((isdn_net_local *) (p-&gt;local-&gt;master-&gt;priv))-&gt;slave == &amp;p-&gt;dev)
((isdn_net_local *) (p-&gt;local-&gt;master-&gt;priv))-&gt;slave = p-&gt;local-&gt;slave;
} <FONT COLOR="#298C52">else</FONT> {
<FONT COLOR=#0000FF>/* Unregister only if it's a master-device */</FONT>
p-&gt;dev.hard_header_cache = p-&gt;local-&gt;org_hhc;
p-&gt;dev.header_cache_update = p-&gt;local-&gt;org_hcu;
unregister_netdev(&amp;p-&gt;dev);
}
<FONT COLOR=#0000FF>/* Unlink device from chain */</FONT>
<FONT COLOR="#298C52">if</FONT> (q)
q-&gt;next = p-&gt;next;
<FONT COLOR="#298C52">else</FONT>
dev-&gt;netdev = p-&gt;next;
<FONT COLOR="#298C52">if</FONT> (p-&gt;local-&gt;slave) {
<FONT COLOR=#0000FF>/* If this interface has a slave, remove it also */</FONT>
<FONT COLOR="#298C52">char</FONT> *slavename = ((isdn_net_local *) (p-&gt;local-&gt;slave-&gt;priv))-&gt;<A HREF="isdn_common.c.shtml#name">name</A>;
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *n = dev-&gt;netdev;
q = NULL;
<FONT COLOR="#298C52">while</FONT> (n) {
<FONT COLOR="#298C52">if</FONT> (!strcmp(n-&gt;local-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, slavename)) {
<A HREF="#isdn_net_realrm">isdn_net_realrm</A>(n, q);
<FONT COLOR="#298C52">break</FONT>;
}
q = n;
n = (<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *) n-&gt;next;
}
}
<FONT COLOR=#0000FF>/* If no more net-devices remain, disable auto-hangup timer */</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;netdev == NULL)
<A HREF="isdn_common.c.shtml#isdn_timer_ctrl">isdn_timer_ctrl</A>(<A HREF="../includes/isdn.h.shtml#ISDN_TIMER_NETHANGUP">ISDN_TIMER_NETHANGUP</A>, 0);
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
kfree(p-&gt;local);
kfree(p);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#0000FF>/*
* Remove a single network-interface.
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_rm">isdn_net_rm</A>(<FONT COLOR="#298C52">char</FONT> *<A HREF="isdn_common.c.shtml#name">name</A>)
{
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *p;
<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *q;
<FONT COLOR=#0000FF>/* Search name in netdev-chain */</FONT>
p = dev-&gt;netdev;
q = NULL;
<FONT COLOR="#298C52">while</FONT> (p) {
<FONT COLOR="#298C52">if</FONT> (!strcmp(p-&gt;local-&gt;<A HREF="isdn_common.c.shtml#name">name</A>, <A HREF="isdn_common.c.shtml#name">name</A>))
<FONT COLOR="#298C52">return</FONT> (<A HREF="#isdn_net_realrm">isdn_net_realrm</A>(p, q));
q = p;
p = (<A HREF="../includes/isdn.h.shtml#isdn_net_dev">isdn_net_dev</A> *) p-&gt;next;
}
<FONT COLOR=#0000FF>/* If no more net-devices remain, disable auto-hangup timer */</FONT>
<FONT COLOR="#298C52">if</FONT> (dev-&gt;netdev == NULL)
<A HREF="isdn_common.c.shtml#isdn_timer_ctrl">isdn_timer_ctrl</A>(<A HREF="../includes/isdn.h.shtml#ISDN_TIMER_NETHANGUP">ISDN_TIMER_NETHANGUP</A>, 0);
<FONT COLOR="#298C52">return</FONT> -ENODEV;
}
<FONT COLOR=#0000FF>/*
* Remove all network-interfaces
*/</FONT>
<FONT COLOR="#298C52">int</FONT>
<A NAME="isdn_net_rmall">isdn_net_rmall</A>(<FONT COLOR="#298C52">void</FONT>)
{
<FONT COLOR="#298C52">int</FONT> flags;
<FONT COLOR="#298C52">int</FONT> ret;
<FONT COLOR=#0000FF>/* Walk through netdev-chain */</FONT>
save_flags(flags);
<A HREF="kdebug.h.shtml#cli">cli</A>();
<FONT COLOR="#298C52">while</FONT> (dev-&gt;netdev) {
<FONT COLOR="#298C52">if</FONT> (!dev-&gt;netdev-&gt;local-&gt;master) {
<FONT COLOR=#0000FF>/* Remove master-devices only, slaves get removed with their master */</FONT>
<FONT COLOR="#298C52">if</FONT> ((ret = <A HREF="#isdn_net_realrm">isdn_net_realrm</A>(dev-&gt;netdev, NULL))) {
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> ret;
}
}
}
dev-&gt;netdev = NULL;
<A HREF="kdebug.h.shtml#restore_flags">restore_flags</A>(flags);
<FONT COLOR="#298C52">return</FONT> 0;
}
<FONT COLOR=#A521F7>#ifdef</FONT> DEV_NUMBUFFS
<FONT COLOR=#0000FF>/*
* helper function to flush device queues
* the better place would be net/core/dev.c
*/</FONT>
<FONT COLOR="#298C52">static</FONT> <FONT COLOR="#298C52">void</FONT>
<A NAME="dev_purge_queues">dev_purge_queues</A>(<FONT COLOR="#298C52">struct</FONT> device *dev)
{
<FONT COLOR="#298C52">int</FONT> i;
<FONT COLOR="#298C52">for</FONT> (i = 0; i &lt; DEV_NUMBUFFS; i++) {
<FONT COLOR="#298C52">struct</FONT> sk_buff *skb;
<FONT COLOR="#298C52">while</FONT> ((skb = skb_dequeue(&amp;dev-&gt;buffs[i])))
dev_kfree_skb(skb);
}
}
<FONT COLOR=#A521F7>#endif</FONT>
</BODY>
</HTML>