patch-pre2.0.6 linux/drivers/isdn/isdn_net.c
Next file: linux/drivers/isdn/isdn_ppp.c
Previous file: linux/drivers/isdn/isdn_common.h
Back to the patch index
Back to the overall index
- Lines: 288
- Date:
Sun May 19 15:29:29 1996
- Orig file:
pre2.0.5/linux/drivers/isdn/isdn_net.c
- Orig date:
Tue May 7 16:22:26 1996
diff -u --recursive --new-file pre2.0.5/linux/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.c,v 1.5 1996/04/20 16:28:38 fritz Exp $
+/* $Id: isdn_net.c,v 1.11 1996/05/18 01:36:59 fritz Exp $
*
* Linux ISDN subsystem, network interfaces and related functions (linklevel).
*
@@ -21,6 +21,25 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: isdn_net.c,v $
+ * 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.
@@ -55,9 +74,7 @@
*
*/
-#ifndef STANDALONE
#include <linux/config.h>
-#endif
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/isdn.h>
@@ -79,7 +96,9 @@
static int isdn_net_start_xmit(struct sk_buff *, struct device *);
static int isdn_net_xmit(struct device *, isdn_net_local *, struct sk_buff *);
-char *isdn_net_revision = "$Revision: 1.5 $";
+extern void dev_purge_queues(struct device *dev); /* move this to net/core/dev.c */
+
+char *isdn_net_revision = "$Revision: 1.11 $";
/*
* Code for raw-networking over ISDN
@@ -143,6 +162,32 @@
}
/*
+ * unbind a net-interface (resets interface after an error)
+ */
+static void
+isdn_net_unbind_channel(isdn_net_local * lp)
+{
+ ulong flags;
+
+ save_flags(flags);
+ cli();
+ if (lp->first_skb) {
+ dev_kfree_skb(lp->first_skb,FREE_WRITE);
+ lp->first_skb = NULL;
+ }
+ dev_purge_queues(&lp->netdev->dev);
+ lp->dialstate = 0;
+ dev->rx_netdev[isdn_dc2minor(lp->isdn_device,lp->isdn_channel)] = NULL;
+ dev->st_netdev[isdn_dc2minor(lp->isdn_device,lp->isdn_channel)] = NULL;
+ isdn_free_channel(lp->isdn_device, lp->isdn_channel, ISDN_USAGE_NET);
+ lp->flags &= ~ISDN_NET_CONNECTED;
+ lp->isdn_device = -1;
+ lp->isdn_channel = -1;
+
+ restore_flags(flags);
+}
+
+/*
* Perform auto-hangup and cps-calculation for net-interfaces.
*
* auto-hangup:
@@ -232,6 +277,8 @@
/* Either D-Channel-hangup or error during dialout */
if ((!lp->dialstate) && (lp->flags & ISDN_NET_CONNECTED)) {
lp->flags &= ~ISDN_NET_CONNECTED;
+ if(lp->first_skb)
+ dev_kfree_skb(lp->first_skb,FREE_WRITE);
isdn_free_channel(lp->isdn_device, lp->isdn_channel,
ISDN_USAGE_NET);
#ifdef CONFIG_ISDN_PPP
@@ -541,6 +588,7 @@
dev_kfree_skb(lp->first_skb,FREE_WRITE);
lp->first_skb = NULL;
}
+ dev_purge_queues(d);
if (lp->flags & ISDN_NET_CONNECTED) {
printk(KERN_INFO "isdn_net: local hangup %s\n", lp->name);
lp->dialstate = 0;
@@ -695,8 +743,10 @@
/* For the other encaps the header has already been built */
#ifdef CONFIG_ISDN_PPP
- if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
- return (isdn_ppp_xmit(skb, ndev));
+ if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
+ ndev->tbusy = ret = isdn_ppp_xmit(skb, ndev);
+ return ret;
+ }
#endif
/* Reset hangup-timeout */
lp->huptimer = 0;
@@ -755,7 +805,6 @@
{
isdn_net_local *lp = (isdn_net_local *) ndev->priv;
-
if (ndev->tbusy) {
if (jiffies - ndev->trans_start < 20)
return 1;
@@ -795,6 +844,8 @@
"isdn_net_start_xmit: No channel for %s\n",
ndev->name);
restore_flags(flags);
+ /* we probably should drop the skb here and return 0 to omit
+ 'socket destroy delayed' messages */
return 1;
}
/* Log packet, which triggered dialing */
@@ -805,15 +856,18 @@
/* Connect interface with channel */
isdn_net_bind_channel(lp, chi);
#ifdef CONFIG_ISDN_PPP
- if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
+ if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
+ /* no 'first_skb' handling for syncPPP */
if (isdn_ppp_bind(lp) < 0) {
- lp->dialstate = 0;
- isdn_free_channel(lp->isdn_device,
- lp->isdn_channel,
- ISDN_USAGE_NET);
+ lp->first_skb = skb; /* net_unbind will free skb */
+ isdn_net_unbind_channel(lp);
restore_flags(flags);
- return 1;
+ return 0; /* STN (skb to nirvana) ;) */
}
+ isdn_net_dial(); /* Initiate dialing */
+ restore_flags(flags);
+ return 1; /* let upper layer requeue skb packet */
+ }
#endif
/* remember first skb to speed up arp
* when using encap ETHER
@@ -1630,9 +1684,7 @@
#ifdef CONFIG_ISDN_PPP
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
if (isdn_ppp_bind(lp) < 0) {
- isdn_free_channel(p->local.isdn_device, p->local.isdn_channel,
- ISDN_USAGE_NET);
- lp->dialstate = 0;
+ isdn_net_unbind_channel(lp);
restore_flags(flags);
return 0;
}
@@ -1647,15 +1699,6 @@
} else {
printk(KERN_DEBUG "%s: call from %s -> %s accepted\n", lp->name, nr,
eaz);
-#if 0
-/* why is this a CONFIG_ISDN_PPP feature ??? */
-#ifdef CONFIG_ISDN_PPP
- if (p->local.isdn_device != -1) {
- isdn_free_channel(p->local.isdn_device, p->local.isdn_channel,
- ISDN_USAGE_NET);
- }
-#endif
-#endif
/* if this interface is dialing, it does it probably on a different
device, so free this device */
if ((p->local.dialstate == 4) || (p->local.dialstate == 12))
@@ -1669,6 +1712,7 @@
p->local.isdn_device = di;
p->local.isdn_channel = ch;
p->local.ppp_minor = -1;
+ p->local.pppbind = -1;
p->local.flags |= ISDN_NET_CONNECTED;
p->local.dialstate = 7;
p->local.dtimer = 0;
@@ -1679,9 +1723,7 @@
#ifdef CONFIG_ISDN_PPP
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
if (isdn_ppp_bind(lp) < 0) {
- isdn_free_channel(p->local.isdn_device, p->local.isdn_channel,
- ISDN_USAGE_NET);
- lp->dialstate = 0;
+ isdn_net_unbind_channel(lp);
restore_flags(flags);
return 0;
}
@@ -1745,9 +1787,9 @@
#ifdef CONFIG_ISDN_PPP
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
if (isdn_ppp_bind(lp) < 0) {
- lp->dialstate = 0;
- isdn_free_channel(lp->isdn_device, lp->isdn_channel, ISDN_USAGE_NET);
- return 1;
+ isdn_net_unbind_channel(lp);
+ restore_flags(flags);
+ return -EAGAIN;
}
#endif
/* Initiate dialing */
@@ -1841,6 +1883,7 @@
netdev->local.pre_channel = -1;
netdev->local.exclusive = -1;
netdev->local.ppp_minor = -1;
+ netdev->local.pppbind = -1;
netdev->local.l2_proto = ISDN_PROTO_L2_X75I;
netdev->local.l3_proto = ISDN_PROTO_L3_TRANS;
netdev->local.slavedelay = 10 * HZ;
@@ -1987,6 +2030,7 @@
p->local.cbdelay = cfg->cbdelay;
p->local.dialmax = cfg->dialmax;
p->local.slavedelay = cfg->slavedelay * HZ;
+ p->local.pppbind = cfg->pppbind;
if (cfg->secure)
p->local.flags |= ISDN_NET_SECURE;
else
@@ -2062,14 +2106,16 @@
cfg->l3_proto = p->local.l3_proto;
cfg->p_encap = p->local.p_encap;
cfg->secure = (p->local.flags & ISDN_NET_SECURE) ? 1 : 0;
- cfg->callback = (p->local.flags & ISDN_NET_CALLBACK) ? 1 : 0;
- cfg->callback = (p->local.flags & ISDN_NET_CBOUT) ? 2 : 0;
+ cfg->callback = 0;
+ if (p->local.flags & ISDN_NET_CALLBACK)
+ cfg->callback = (p->local.flags & ISDN_NET_CBOUT)?2:1;
cfg->cbhup = (p->local.flags & ISDN_NET_CBHUP) ? 1 : 0;
cfg->chargehup = (p->local.hupflags & 4) ? 1 : 0;
cfg->ihup = (p->local.hupflags & 8) ? 1 : 0;
cfg->cbdelay = p->local.cbdelay;
cfg->dialmax = p->local.dialmax;
cfg->slavedelay = p->local.slavedelay / HZ;
+ cfg->pppbind = p->local.pppbind;
if (p->local.slave)
strcpy(cfg->slave, ((isdn_net_local *) p->local.slave->priv)->name);
else
@@ -2287,7 +2333,7 @@
restore_flags(flags);
#ifdef CONFIG_ISDN_PPP
- isdn_ppp_free_mpqueue(p);
+ isdn_ppp_free_mpqueue(p); /* still necessary? */
#endif
kfree(p);
@@ -2341,6 +2387,26 @@
restore_flags(flags);
return 0;
}
+
+/*
+ * helper function to flush device queues
+ * the better place would be net/core/dev.c
+ */
+void dev_purge_queues(struct device *dev)
+{
+ int i;
+ for(i=0;i<DEV_NUMBUFFS;i++) {
+ struct sk_buff *skb;
+ while((skb=skb_dequeue(&dev->buffs[i])))
+ if(skb->free)
+ kfree_skb(skb,FREE_WRITE);
+ }
+
+}
+
+
+
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this