patch-2.0.1 linux/drivers/isdn/isdn_net.c

Next file: linux/drivers/isdn/isdn_ppp.c
Previous file: linux/drivers/isdn/isdn_common.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.0/linux/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.c,v 1.13 1996/06/06 14:25:44 fritz Exp $
+/* $Id: isdn_net.c,v 1.17 1996/06/25 18:37:37 fritz Exp $
  *
  * Linux ISDN subsystem, network interfaces and related functions (linklevel).
  *
@@ -21,6 +21,22 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: isdn_net.c,v $
+ * 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->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.
@@ -105,7 +121,7 @@
  
 extern void dev_purge_queues(struct device *dev);	/* move this to net/core/dev.c */
 
-char *isdn_net_revision = "$Revision: 1.13 $";
+char *isdn_net_revision = "$Revision: 1.17 $";
 
  /*
   * Code for raw-networking over ISDN
@@ -133,9 +149,9 @@
 	isdn_net_reset(dev);
 	dev->start = 1;
 	/* Fill in the MAC-level header. */
-	for (i = 0; i < ETH_ALEN - sizeof(ulong); i++)
+	for (i = 0; i < ETH_ALEN - sizeof(u32); i++)
 		dev->dev_addr[i] = 0xfc;
-	memcpy(&(dev->dev_addr[i]), &dev->pa_addr, sizeof(ulong));
+	memcpy(&(dev->dev_addr[i]), &dev->pa_addr, sizeof(u32));
 
         /* If this interface has slaves, start them also */
 
@@ -182,6 +198,10 @@
                 dev_kfree_skb(lp->first_skb,FREE_WRITE);
                 lp->first_skb = NULL;
         }
+	if(lp->sav_skb) {
+                dev_kfree_skb(lp->sav_skb,FREE_WRITE);
+		lp->sav_skb = NULL;
+	}
 	dev_purge_queues(&lp->netdev->dev);
 	lp->dialstate = 0;
 	dev->rx_netdev[isdn_dc2minor(lp->isdn_device,lp->isdn_channel)] = NULL;
@@ -263,14 +283,19 @@
 				if ((lp->flags & ISDN_NET_CONNECTED) &&
 				    (!lp->dialstate)) {
 					lp->stats.tx_packets++;
-					if(lp->p_encap == ISDN_NET_ENCAP_SYNCPPP && lp->first_skb) {
-						if(!isdn_net_send_skb(&lp->netdev->dev,lp,lp->first_skb)) {
-							dev_kfree_skb(lp->first_skb,FREE_WRITE);
-							lp->first_skb = NULL;
+					if(lp->p_encap == ISDN_NET_ENCAP_SYNCPPP && lp->sav_skb) {
+						struct device *mdev;
+						if(lp->master)
+							mdev = lp->master;
+						else
+							mdev = &lp->netdev->dev;
+						if(!isdn_net_send_skb(mdev,lp,lp->sav_skb)) {
+							lp->sav_skb = NULL;
 							mark_bh(NET_BH);
 						}
-						else
+						else {
 							return 1;
+						}
 					}
                                         if (clear_bit(0,(void*)&(p->dev.tbusy)))
                                                 mark_bh(NET_BH);
@@ -293,8 +318,14 @@
 				/* 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)
+					if(lp->first_skb) {
 						dev_kfree_skb(lp->first_skb,FREE_WRITE);
+						lp->first_skb = NULL;
+					}
+					if(lp->sav_skb) {
+						dev_kfree_skb(lp->sav_skb,FREE_WRITE);
+						lp->sav_skb = NULL;
+					}
 					isdn_free_channel(lp->isdn_device, lp->isdn_channel,
                                                           ISDN_USAGE_NET);
 #ifdef CONFIG_ISDN_PPP
@@ -596,35 +627,20 @@
 {
 	isdn_net_local *lp = (isdn_net_local *) d->priv;
 	isdn_ctrl cmd;
-	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(d);
 	if (lp->flags & ISDN_NET_CONNECTED) {
 		printk(KERN_INFO "isdn_net: local hangup %s\n", lp->name);
-		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);
 #ifdef CONFIG_ISDN_PPP
 		isdn_ppp_free(lp);
 #endif
-		lp->flags &= ~ISDN_NET_CONNECTED;
 		cmd.driver = lp->isdn_device;
 		cmd.command = ISDN_CMD_HANGUP;
 		cmd.arg = lp->isdn_channel;
 		(void) dev->drv[cmd.driver]->interface->command(&cmd);
 		printk(KERN_INFO "%s: Chargesum is %d\n", lp->name, lp->charge);
 		isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
-		lp->isdn_device = -1;
-		lp->isdn_channel = -1;
 	}
-	restore_flags(flags);
+        isdn_net_unbind_channel(lp);
 }
 
 typedef struct {
@@ -732,13 +748,21 @@
                   struct sk_buff *skb)
 {
 	int ret;
+	int len = skb->len;	/* save len */
 	
-	lp->transcount += skb->len;
         ret = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, skb);
-	if (ret == skb->len) {
+	if (ret == len) {
+		lp->transcount += len;
 		clear_bit(0, (void *)&(ndev->tbusy));
 		return 0;
 	}
+        if (ret < 0) {
+                skb->free = 1;
+                dev_kfree_skb(skb, FREE_WRITE);
+                lp->stats.tx_errors++;
+                clear_bit(0, (void *)&(ndev->tbusy));
+                return 0;
+        }
 	return 1;
 }                                      
 	
@@ -762,8 +786,7 @@
 	/* For the other encaps the header has already been built */
 #ifdef CONFIG_ISDN_PPP
 	if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
-		ndev->tbusy = ret = isdn_ppp_xmit(skb, ndev);
-		return ret;
+		return isdn_ppp_xmit(skb, ndev);
 	}
 #endif		
 	/* Reset hangup-timeout */
@@ -877,7 +900,7 @@
 				if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
 					/* no 'first_skb' handling for syncPPP */
 					if (isdn_ppp_bind(lp) < 0) {
-						lp->first_skb = skb;	/* net_unbind will free skb */
+                                        	dev_kfree_skb(skb,FREE_WRITE);
 						isdn_net_unbind_channel(lp);
                                                 restore_flags(flags);
 						return 0;	/* STN (skb to nirvana) ;) */
@@ -1241,7 +1264,7 @@
                          * guaranteed to be invalid. Need that to check
                          * for already compressed packets in isdn_ppp_xmit().
                          */
-                        *((unsigned long *)skb_push(skb, len)) = 0;
+                        *((u32 *)skb_push(skb, len)) = 0;
                         break;
 #endif
 	}
@@ -1251,7 +1274,7 @@
 /* We don't need to send arp, because we have point-to-point connections. */
 
 static int
-isdn_net_rebuild_header(void *buff, struct device *dev, ulong dst,
+isdn_net_rebuild_header(void *buff, struct device *dev, unsigned long dst,
                         struct sk_buff *skb)
 {
 	isdn_net_local *lp = dev->priv;
@@ -1266,8 +1289,8 @@
                 
                 if(eth->h_proto != htons(ETH_P_IP)) {
                         printk(KERN_WARNING
-                               "isdn_net_rebuild_header: Don't know how to resolve type %d addresses?\n",
-                               (int)eth->h_proto);
+                               "isdn_net: %s don't know how to resolve type %d addresses?\n",
+                               dev->name, (int)eth->h_proto);
                         memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
                         return 0;
                 }
@@ -1275,7 +1298,7 @@
                  *      Try to get ARP to resolve the header.
                  */
 #ifdef CONFIG_INET       
-                ret = arp_find((unsigned char *)&(eth->h_dest), dst, dev, dev->pa_addr,skb)? 1 : 0;
+                ret = arp_find(eth->h_dest, dst, dev, dev->pa_addr, skb)? 1 : 0;
 #endif  
         }
 	return ret;
@@ -2034,6 +2057,7 @@
 			p->local.exclusive = -1;
 			if ((p->local.pre_device != -1) && (cfg->exclusive == -1)) {
 				isdn_unexclusive_channel(p->local.pre_device, p->local.pre_channel);
+                                isdn_free_channel(p->local.pre_device, p->local.pre_channel,ISDN_USAGE_NET);
 				drvidx = -1;
 				chidx = -1;
 			}
@@ -2059,7 +2083,7 @@
 			p->local.flags &= ~ISDN_NET_CBHUP;
 		switch (cfg->callback) {
                         case 0:
-                                p->local.flags &= ~(ISDN_NET_CALLBACK&ISDN_NET_CBOUT);
+                                p->local.flags &= ~(ISDN_NET_CALLBACK|ISDN_NET_CBOUT);
                                 break;
                         case 1:
                                 p->local.flags |= ISDN_NET_CALLBACK;
@@ -2126,7 +2150,9 @@
 		cfg->secure = (p->local.flags & ISDN_NET_SECURE) ? 1 : 0;
 		cfg->callback = 0;
                 if (p->local.flags & ISDN_NET_CALLBACK)
-                        cfg->callback = (p->local.flags & ISDN_NET_CBOUT)?2:1;
+                        cfg->callback = 1;
+                if (p->local.flags & ISDN_NET_CBOUT)
+                        cfg->callback = 2;
 		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;
@@ -2186,10 +2212,7 @@
 	save_flags(flags);
 	cli();
 	inout &= 1;
-	n = p->local.phone[inout];
-        if (n)
-                count++;
-	while (n) {
+        for (n = p->local.phone[inout]; n; n = n->next) {
 		if (more) {
 			put_fs_byte(' ', phones++);
 			count++;
@@ -2201,10 +2224,10 @@
 		memcpy_tofs(phones, n->num, strlen(n->num) + 1);
 		phones += strlen(n->num);
 		count += strlen(n->num);
-		n = n->next;
 		more = 1;
 	}
         put_fs_byte(0,phones);
+        count++;
 	restore_flags(flags);
 	return count;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov