Fix ISDN Net for 2.1.42

Joerg Lehrke (Joerg.Lehrke@ecrc.de)
Wed, 11 Jun 1997 15:04:04 +0200


This is a multipart MIME message.

--==_Exmh_-12084234140
Content-Type: text/plain; charset=us-ascii

Hi!

My Linux box running 2.1.42 paniced every time I used ISDN
for network connetions. Now I did cleanups in isdn_net.c
and everything works stable again.
The following patch also uses the new features of the netdevices
device structure.

Regards,

-- 
  ``---         J"org Lehrke                            Tel. +49 89 926 99185
     ||_        European Computer Research Centre       email: jlehrke@ECRC.de
ECRC || |@  ,,  Arabellastr 17, 81925 Munich, Germany
BUSINESS-NET    Protect your freedom! http://www.fsf.org       Yes, I use PGP.

--==_Exmh_-12084234140 Content-Type: application/x-patch ; name="21-isdn_net.patch" Content-Description: 21-isdn_net.patch Content-Disposition: attachment; filename="21-isdn_net.patch"

diff -u --recursive --new-file linux-2.1.42/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c --- linux-2.1.42/drivers/isdn/isdn_common.c Wed May 28 19:49:09 1997 +++ linux/drivers/isdn/isdn_common.c Wed Jun 11 09:59:48 1997 @@ -417,6 +417,11 @@ isdn_ctrl cmd; di = c->driver; + if (!dev->drv[di]) { + printk(KERN_WARNING + "Try to access unregistered isdn device %d\n", di); + return -1; + } i = isdn_dc2minor(di, c->arg); switch (c->command) { case ISDN_STAT_BSENT: @@ -1069,9 +1074,9 @@ return ret; } src += sizeof(cfg); - if (!isdn_net_new(cfg.name, NULL)) { + if ((ret = isdn_net_new(cfg.name, NULL))) { restore_flags(flags); - return -EIO; + return ret; } if ((ret = isdn_net_setcfg(&cfg))) { restore_flags(flags); @@ -1247,12 +1252,11 @@ s = name; } else s = NULL; - if ((s = isdn_net_new(s, NULL))) { - if ((ret = copy_to_user((char *) arg, s, strlen(s) + 1))) - return ret; - return 0; - } else - return -ENODEV; + + if (!(ret = isdn_net_new(s, NULL))) + ret = copy_to_user((char *) arg, s, strlen(s) + 1); + return ret; + case IIOCNETASL: /* Add a slave to a network-interface */ if (arg) { @@ -1260,12 +1264,13 @@ return ret; } else return -EINVAL; - if ((s = isdn_net_newslave(bname))) { - if ((ret = copy_to_user((char *) arg, s, strlen(s) + 1))) - return ret; - return 0; - } else - return -ENODEV; + + s = bname; + + if (!(ret = isdn_net_newslave(s))) + ret = copy_to_user((char *) arg, s, strlen(s) + 1); + return ret; + case IIOCNETDIF: /* Delete a network-interface */ if (arg) { diff -u --recursive --new-file linux-2.1.42/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c --- linux-2.1.42/drivers/isdn/isdn_net.c Wed May 28 19:49:09 1997 +++ linux/drivers/isdn/isdn_net.c Wed Jun 11 11:25:59 1997 @@ -209,6 +209,7 @@ static int isdn_net_wildmat(char *s, char *p); static int isdn_net_start_xmit(struct sk_buff *, struct device *); static int isdn_net_xmit(struct device *, isdn_net_local *, struct sk_buff *); +static int isdn_change_mtu(struct device *, int); static void dev_purge_queues(struct device *dev); /* move this to net/core/dev.c */ char *isdn_net_revision = "$Revision: 1.44 $"; @@ -251,19 +252,18 @@ isdn_net_reset(dev); dev->start = 1; /* Fill in the MAC-level header. */ - for (i = 0; i < ETH_ALEN - sizeof(u32); i++) + for (i = 0; i < ETH_ALEN - sizeof(dev->pa_addr); i++) dev->dev_addr[i] = 0xfc; - memcpy(&(dev->dev_addr[i]), &dev->pa_addr, sizeof(u32)); + memcpy(&(dev->dev_addr[i]), &dev->pa_addr, sizeof(dev->pa_addr)); /* If this interface has slaves, start them also */ - - if ((p = (((isdn_net_local *) dev->priv)->slave))) { - while (p) { - isdn_net_reset(p); - p->start = 1; - p = (((isdn_net_local *) p->priv)->slave); - } + p = dev->slave; + while (p) { + isdn_net_reset(p); + p->start = 1; + p = p->slave; } + isdn_MOD_INC_USE_COUNT(); return 0; } @@ -399,7 +399,6 @@ /* A packet has successfully been sent out */ if ((lp->flags & ISDN_NET_CONNECTED) && (!lp->dialstate)) { - lp->stats.tx_packets++; if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP && lp->sav_skb) { struct device *mdev; if (lp->master) @@ -889,7 +888,14 @@ ret = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, skb); if (ret == len) { - lp->transcount += len; + lp->stats.tx_packets++; + lp->stats.tx_bytes += len; + if (lp->master) { + /* Bundling: handle master's statistics */ + isdn_net_local *mlp = (isdn_net_local *) lp->master->priv; + mlp->stats.tx_packets++; + mlp->stats.tx_bytes += len; + } clear_bit(0, (void *) &(ndev->tbusy)); return 0; } @@ -897,6 +903,11 @@ SET_SKB_FREE(skb); dev_kfree_skb(skb, FREE_WRITE); lp->stats.tx_errors++; + if (lp->master) { + /* Bundling: handle master's statistics */ + isdn_net_local *mlp = (isdn_net_local *) lp->master->priv; + mlp->stats.tx_errors++; + } clear_bit(0, (void *) &(ndev->tbusy)); return 0; } @@ -945,13 +956,13 @@ ret = isdn_net_send_skb(ndev, lp, skb); else ret = ndev->tbusy = isdn_net_start_xmit(skb, lp->srobin); - lp->srobin = (slp->slave) ? slp->slave : ndev; + lp->srobin = (slp->netdev->dev.slave) ? slp->netdev->dev.slave : ndev; slp = (isdn_net_local *) (lp->srobin->priv); if (!((slp->flags & ISDN_NET_CONNECTED) && (slp->dialstate == 0))) lp->srobin = ndev; } /* Slave-startup using delay-variable */ - if (lp->slave) { + if (lp->netdev->dev.slave) { if (!lp->sqfull) { /* First time overload: set timestamp only */ lp->sqfull = 1; @@ -959,7 +970,7 @@ } else { /* subsequent overload: if slavedelay exceeded, start dialing */ if ((jiffies - lp->sqfull_stamp) > lp->slavedelay) - isdn_net_force_dial_lp((isdn_net_local *) lp->slave->priv); + isdn_net_force_dial_lp((isdn_net_local *) lp->netdev->dev.slave->priv); } } } else { @@ -1101,15 +1112,16 @@ dev->tbusy = 1; dev->start = 0; - if ((p = (((isdn_net_local *) dev->priv)->slave))) { - /* If this interface has slaves, stop them also */ - while (p) { - isdn_net_hangup(p); - p->tbusy = 1; - p->start = 0; - p = (((isdn_net_local *) p->priv)->slave); - } + + /* If this interface has slaves, stop them also */ + p = dev->slave; + while (p) { + isdn_net_hangup(p); + p->tbusy = 1; + p->start = 0; + p = p->slave; } + isdn_net_hangup(dev); isdn_MOD_DEC_USE_COUNT(); return 0; @@ -1118,7 +1130,7 @@ /* * Get statistics */ -static struct enet_statistics * +static struct net_device_stats * isdn_net_get_stats(struct device *dev) { isdn_net_local *lp = (isdn_net_local *) dev->priv; @@ -1191,6 +1203,7 @@ lp->transcount += skb->len; lp->stats.rx_packets++; + lp->stats.rx_bytes += skb->len; #ifdef CONFIG_ISDN_PPP /* * If encapsulation is syncppp, don't reset @@ -1208,6 +1221,7 @@ ndev = lp->master; lp = (isdn_net_local *) ndev->priv; lp->stats.rx_packets++; + lp->stats.rx_bytes += skb->len; #ifdef CONFIG_ISDN_PPP /* * If encapsulation is syncppp, don't reset @@ -1436,9 +1450,7 @@ isdn_net_init(struct device *ndev) { ushort max_hlhdr_len = 0; - isdn_net_local *lp = (isdn_net_local *) ndev->priv; - int drvidx, - i; + int drvidx; if (ndev == NULL) { printk(KERN_WARNING "isdn_net_init: dev = NULL!\n"); @@ -1448,42 +1460,39 @@ printk(KERN_WARNING "isdn_net_init: dev->priv = NULL!\n"); return -ENODEV; } - ether_setup(ndev); -#if (LINUX_VERSION_CODE < 0x02010F) - lp->org_hcb = ndev->header_cache_bind; -#else - lp->org_hhc = ndev->hard_header_cache; -#endif - lp->org_hcu = ndev->header_cache_update; - /* Setup the generic properties */ + dev_init_buffers(ndev); - ndev->hard_header = NULL; -#if (LINUX_VERSION_CODE < 0x02010F) - ndev->header_cache_bind = NULL; -#else - ndev->hard_header_cache = NULL; -#endif - ndev->header_cache_update = NULL; + /* Setup the generic properties */ + ndev->get_stats = isdn_net_get_stats; + + ndev->type = ARPHRD_ETHER; ndev->mtu = 1500; + ndev->addr_len = ETH_ALEN; + ndev->tx_queue_len = 100; /* ISDN wants good queues */ + + memset(ndev->broadcast,0xFF, ETH_ALEN); + + /* New-style flags. */ ndev->flags = IFF_NOARP; ndev->family = AF_INET; - ndev->type = ARPHRD_ETHER; - ndev->addr_len = ETH_ALEN; ndev->pa_addr = 0; ndev->pa_brdaddr = 0; ndev->pa_mask = 0; ndev->pa_alen = 4; - for (i = 0; i < ETH_ALEN; i++) - ndev->broadcast[i] = 0xff; - - for (i = 0; i < DEV_NUMBUFFS; i++) - skb_queue_head_init(&ndev->buffs[i]); - /* The ISDN-specific entries in the device structure. */ - ndev->open = &isdn_net_open; - ndev->hard_start_xmit = &isdn_net_start_xmit; + ndev->open = isdn_net_open; + ndev->stop = isdn_net_close; + ndev->hard_start_xmit = isdn_net_start_xmit; + ndev->hard_header = NULL; + ndev->rebuild_header = isdn_net_rebuild_header; + ndev->set_multicast_list = NULL; + ndev->set_mac_address = NULL; +#ifdef CONFIG_ISDN_PPP + ndev->do_ioctl = isdn_ppp_dev_ioctl; +#endif + ndev->change_mtu = isdn_change_mtu; /* * up till binding we ask the protocol layer to reserve as much @@ -1497,13 +1506,6 @@ ndev->hard_header_len = ETH_HLEN + max_hlhdr_len; - ndev->stop = &isdn_net_close; - ndev->get_stats = &isdn_net_get_stats; - ndev->rebuild_header = &isdn_net_rebuild_header; - -#ifdef CONFIG_ISDN_PPP - ndev->do_ioctl = isdn_ppp_dev_ioctl; -#endif return 0; } @@ -1805,10 +1807,10 @@ if (mlp->flags & ISDN_NET_CONNECTED) { printk(KERN_DEBUG "master online\n"); /* Master is online, find parent-slave (master if first slave) */ - while (mlp->slave) { - if ((isdn_net_local *) mlp->slave->priv == lp) + while (mlp->netdev->dev.slave) { + if ((isdn_net_local *) mlp->netdev->dev.slave->priv == lp) break; - mlp = (isdn_net_local *) mlp->slave->priv; + mlp = (isdn_net_local *) mlp->netdev->dev.slave->priv; } } else printk(KERN_DEBUG "master offline\n"); @@ -1982,19 +1984,20 @@ /* * Allocate a new network-interface and initialize its data structures. */ -char * +int isdn_net_new(char *name, struct device *master) { isdn_net_dev *netdev; + int ret; /* Avoid creating an existing interface */ if (isdn_net_findif(name)) { printk(KERN_WARNING "isdn_net: interface %s already exists\n", name); - return NULL; + return -EEXIST; } if (!(netdev = (isdn_net_dev *) kmalloc(sizeof(isdn_net_dev), GFP_KERNEL))) { printk(KERN_WARNING "isdn_net: Could not allocate net-device\n"); - return NULL; + return -ENOMEM; } memset(netdev, 0, sizeof(isdn_net_dev)); if (name == NULL) @@ -2004,29 +2007,48 @@ netdev->dev.name = netdev->local.name; netdev->dev.priv = &netdev->local; netdev->dev.init = isdn_net_init; - netdev->local.p_encap = ISDN_NET_ENCAP_RAWIP; if (master) { /* Device shall be a slave */ - struct device *p = (((isdn_net_local *) master->priv)->slave); - struct device *q = master; - + struct device *p = master; + isdn_net_local *mlp = (isdn_net_local *) master->priv; netdev->local.master = master; + netdev->local.p_encap = mlp->p_encap; + netdev->local.l2_proto = mlp->l2_proto; + netdev->local.l3_proto = mlp->l3_proto; + netdev->local.hupflags = mlp->hupflags; + netdev->local.onhtime = mlp->onhtime; + netdev->local.dialmax = mlp->dialmax; + netdev->local.flags = mlp->flags; + netdev->local.cbdelay = mlp->cbdelay; + /* Put device at end of slave-chain */ - while (p) { - q = p; - p = (((isdn_net_local *) p->priv)->slave); - } - ((isdn_net_local *) q->priv)->slave = &(netdev->dev); - q->interrupt = 0; - q->tbusy = 0; - q->start = master->start; + while (p->slave) { + p = p->slave; + } + p->slave = &netdev->dev; + p->interrupt = 0; + p->tbusy = 0; + p->start = master->start; } else { /* Device shall be a master */ - if (register_netdev(&netdev->dev) != 0) { + if ((ret = register_netdev(&netdev->dev)) != 0) { printk(KERN_WARNING "isdn_net: Could not register net-device\n"); kfree(netdev); - return NULL; + return ret; } + netdev->local.p_encap = ISDN_NET_ENCAP_RAWIP; + netdev->local.l2_proto = ISDN_PROTO_L2_X75I; + netdev->local.l3_proto = ISDN_PROTO_L3_TRANS; + /* Do hangup even on incoming calls */ + netdev->local.hupflags = ISDN_INHUP; + /* Default hangup-time for saving costs + of those who forget configuring this */ + netdev->local.onhtime = 10; + netdev->local.dialmax = 1; + /* Hangup before Callback */ + netdev->local.flags = ISDN_NET_CBHUP; + /* Wait 5 secs before Callback */ + netdev->local.cbdelay = 25; } netdev->local.magic = ISDN_NET_MAGIC; @@ -2049,23 +2071,16 @@ netdev->local.pppbind = -1; netdev->local.sav_skb = NULL; netdev->local.first_skb = NULL; - netdev->local.l2_proto = ISDN_PROTO_L2_X75I; - netdev->local.l3_proto = ISDN_PROTO_L3_TRANS; netdev->local.slavedelay = 10 * HZ; netdev->local.srobin = &netdev->dev; - netdev->local.hupflags = ISDN_INHUP; /* Do hangup even on incoming calls */ - netdev->local.onhtime = 10; /* Default hangup-time for saving costs - of those who forget configuring this */ - netdev->local.dialmax = 1; - netdev->local.flags = ISDN_NET_CBHUP; /* Hangup before Callback */ - netdev->local.cbdelay = 25; /* Wait 5 secs before Callback */ /* Put into to netdev-chain */ netdev->next = (void *) dev->netdev; dev->netdev = netdev; - return netdev->dev.name; + name = netdev->dev.name; + return 0; } -char * +int isdn_net_newslave(char *parm) { char *p = strchr(parm, ','); @@ -2075,21 +2090,21 @@ if (p) { /* Slave-Name MUST not be empty */ if (!strlen(p + 1)) - return NULL; + return -EINVAL; strcpy(newname, p + 1); *p = 0; /* Master must already exist */ if (!(n = isdn_net_findif(parm))) - return NULL; + return -ENODEV; /* Master must be a real interface, not a slave */ if (n->local.master) - return NULL; + return -EPERM; /* Master must not be started yet */ if (n->dev.start) - return NULL; + return -EBUSY; return (isdn_net_new(newname, &(n->dev))); } - return NULL; + return -EINVAL; } /* @@ -2170,6 +2185,7 @@ /* If binding is exclusive, try to grab the channel */ save_flags(flags); + cli(); if ((i = isdn_get_free_channel(ISDN_USAGE_NET, p->local.l2_proto, p->local.l3_proto, drvidx, @@ -2239,37 +2255,29 @@ p->local.chargeint = cfg->chargeint * HZ; } if (cfg->p_encap != p->local.p_encap) { - if (cfg->p_encap == ISDN_NET_ENCAP_RAWIP) { + if (cfg->p_encap == ISDN_NET_ENCAP_RAWIP) p->dev.hard_header = NULL; + else + p->dev.hard_header = isdn_net_header; + if (cfg->p_encap == ISDN_NET_ENCAP_ETHER) { #if (LINUX_VERSION_CODE < 0x02010F) - p->dev.header_cache_bind = NULL; + p->dev.header_cache_bind = eth_header_cache; #else - p->dev.hard_header_cache = NULL; + p->dev.hard_header_cache = eth_header_cache; #endif - p->dev.header_cache_update = NULL; - p->dev.flags = IFF_NOARP; + p->dev.header_cache_update = eth_header_cache_update; + p->dev.flags = IFF_BROADCAST | IFF_MULTICAST; } else { - p->dev.hard_header = isdn_net_header; - if (cfg->p_encap == ISDN_NET_ENCAP_ETHER) { -#if (LINUX_VERSION_CODE < 0x02010F) - p->dev.header_cache_bind = p->local.org_hcb; -#else - p->dev.hard_header_cache = p->local.org_hhc; -#endif - p->dev.header_cache_update = p->local.org_hcu; - p->dev.flags = IFF_BROADCAST | IFF_MULTICAST; - } else { #if (LINUX_VERSION_CODE < 0x02010F) - p->dev.header_cache_bind = NULL; + p->dev.header_cache_bind = NULL; #else - p->dev.hard_header_cache = NULL; + p->dev.hard_header_cache = NULL; #endif - p->dev.header_cache_update = NULL; - p->dev.flags = IFF_NOARP; - } + p->dev.header_cache_update = NULL; + p->dev.flags = IFF_NOARP; } + p->local.p_encap = cfg->p_encap; } - p->local.p_encap = cfg->p_encap; return 0; } return -ENODEV; @@ -2311,12 +2319,12 @@ cfg->chargeint = (p->local.hupflags & ISDN_CHARGEHUP) ? (p->local.chargeint / HZ) : 0; cfg->pppbind = p->local.pppbind; - if (p->local.slave) - strcpy(cfg->slave, ((isdn_net_local *) p->local.slave->priv)->name); + if (p->dev.slave) + strcpy(cfg->slave, p->dev.slave->name); else cfg->slave[0] = '\0'; if (p->local.master) - strcpy(cfg->master, ((isdn_net_local *) p->local.master->priv)->name); + strcpy(cfg->master, p->local.master->name); else cfg->master[0] = '\0'; return 0; @@ -2461,13 +2469,12 @@ if (p) { if (p->local.isdn_device < 0) return 1; - q = p->local.slave; + q = &p->dev; /* If this interface has slaves, do a hangup for them also. */ - while (q) { + do { isdn_net_hangup(q); - q = (((isdn_net_local *) q->priv)->slave); - } - isdn_net_hangup(&p->dev); + } while ((q = q->slave)); + return 0; } return -ENODEV; @@ -2477,7 +2484,7 @@ * Helper-function for isdn_net_rm: Do the real work. */ static int -isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q) +isdn_net_realrm(isdn_net_dev *p) { int flags; @@ -2500,30 +2507,29 @@ if (p->local.exclusive != -1) isdn_unexclusive_channel(p->local.pre_device, p->local.pre_channel); if (p->local.master) { - /* It's a slave-device, so update master's slave-pointer if necessary */ - if (((isdn_net_local *) (p->local.master->priv))->slave == &p->dev) - ((isdn_net_local *) (p->local.master->priv))->slave = p->local.slave; + /* It's a slave-device, so update master's pointer-list */ + struct device *q = p->local.master; + while(q && (q->slave != &p->dev)) + q = q->slave; + if (q) + q->slave = p->dev.slave; } else /* Unregister only if it's a master-device */ unregister_netdev(&p->dev); /* Unlink device from chain */ - if (q) - q->next = p->next; - else - dev->netdev = p->next; - if (p->local.slave) { - /* If this interface has a slave, remove it also */ - char *slavename = ((isdn_net_local *) (p->local.slave->priv))->name; + if (p == dev->netdev) + dev->netdev = (isdn_net_dev *) p->next; + else { isdn_net_dev *n = dev->netdev; - q = NULL; - while (n) { - if (!strcmp(n->local.name, slavename)) { - isdn_net_realrm(n, q); - break; - } - q = n; + while (n && ((isdn_net_dev *) n->next != p)) n = (isdn_net_dev *) n->next; - } + if (n) + n->next = p->next; + } + if (!p->local.master && p->dev.slave) { + /* If this interface has slaves, remove them also */ + while(p->dev.slave) + isdn_net_realrm(((isdn_net_local *) p->dev.slave->priv)->netdev); } /* If no more net-devices remain, disable auto-hangup timer */ if (dev->netdev == NULL) @@ -2542,15 +2548,12 @@ isdn_net_rm(char *name) { isdn_net_dev *p; - isdn_net_dev *q; /* Search name in netdev-chain */ p = dev->netdev; - q = NULL; while (p) { if (!strcmp(p->local.name, name)) - return (isdn_net_realrm(p, q)); - q = p; + return (isdn_net_realrm(p)); p = (isdn_net_dev *) p->next; } /* If no more net-devices remain, disable auto-hangup timer */ @@ -2574,7 +2577,7 @@ while (dev->netdev) { if (!dev->netdev->local.master) { /* Remove master-devices only, slaves get removed with their master */ - if ((ret = isdn_net_realrm(dev->netdev, NULL))) { + if ((ret = isdn_net_realrm(dev->netdev))) { restore_flags(flags); return ret; } @@ -2599,4 +2602,12 @@ dev_kfree_skb(skb, FREE_WRITE); } +} + +static int isdn_change_mtu(struct device *dev, int new_mtu) +{ + if ((new_mtu < 68) || (new_mtu > 1500)) + return -EINVAL; + dev->mtu = new_mtu; + return 0; } diff -u --recursive --new-file linux-2.1.42/drivers/isdn/isdn_net.h linux/drivers/isdn/isdn_net.h --- linux-2.1.42/drivers/isdn/isdn_net.h Wed Feb 26 02:12:50 1997 +++ linux/drivers/isdn/isdn_net.h Wed Jun 11 09:47:55 1997 @@ -45,8 +45,8 @@ #define ISDN_INHUP 8 /* Even if incoming, close after huptimeout */ #define ISDN_MANCHARGE 16 /* Charge Interval manually set */ -extern char *isdn_net_new(char *, struct device *); -extern char *isdn_net_newslave(char *); +extern int isdn_net_new(char *, struct device *); +extern int isdn_net_newslave(char *); extern int isdn_net_rm(char *); extern int isdn_net_rmall(void); extern int isdn_net_stat_callback(int, int); diff -u --recursive --new-file linux-2.1.42/drivers/isdn/isdn_ppp.c linux/drivers/isdn/isdn_ppp.c --- linux-2.1.42/drivers/isdn/isdn_ppp.c Wed May 28 19:49:09 1997 +++ linux/drivers/isdn/isdn_ppp.c Wed Jun 11 09:16:23 1997 @@ -1857,12 +1857,12 @@ if (!(lp->flags & ISDN_NET_CONNECTED)) return 5; - sdev = lp->slave; + sdev = lp->netdev->dev.slave; while (sdev) { isdn_net_local *mlp = (isdn_net_local *) sdev->priv; if (!(mlp->flags & ISDN_NET_CONNECTED)) break; - sdev = mlp->slave; + sdev = mlp->netdev->dev.slave; } if (!sdev) return 2; @@ -1888,12 +1888,12 @@ if (!(lp->flags & ISDN_NET_CONNECTED)) return 5; - sdev = lp->slave; + sdev = lp->netdev->dev.slave; while (sdev) { isdn_net_local *mlp = (isdn_net_local *) sdev->priv; if ((mlp->flags & ISDN_NET_CONNECTED)) break; - sdev = mlp->slave; + sdev = mlp->netdev->dev.slave; } if (!sdev) return 2; diff -u --recursive --new-file linux-2.1.42/include/linux/isdn.h linux/include/linux/isdn.h --- linux-2.1.42/include/linux/isdn.h Wed May 28 19:49:11 1997 +++ linux/include/linux/isdn.h Wed Jun 11 10:56:04 1997 @@ -366,7 +366,7 @@ typedef struct isdn_net_local_s { ulong magic; char name[10]; /* Name of device */ - struct enet_statistics stats; /* Ethernet Statistics */ + struct net_device_stats stats; /* Device Statistics */ int isdn_device; /* Index to isdn-device */ int isdn_channel; /* Index to isdn-channel */ int ppp_slot; /* PPPD device slot number */ @@ -419,35 +419,11 @@ /* phone[1] = Outgoing Numbers */ isdn_net_phone *dial; /* Pointer to dialed number */ struct device *master; /* Ptr to Master device for slaves */ - struct device *slave; /* Ptr to Slave device for masters */ struct isdn_net_local_s *next; /* Ptr to next link in bundle */ struct isdn_net_local_s *last; /* Ptr to last link in bundle */ struct isdn_net_dev_s *netdev; /* Ptr to netdev */ struct sk_buff *first_skb; /* Ptr to skb that triggers dialing */ struct sk_buff *sav_skb; /* Ptr to skb, rejected by LL-driver*/ -#if (LINUX_VERSION_CODE < 0x02010F) - /* Ptr to orig. header_cache_bind */ - void (*org_hcb)(struct hh_cache **, - struct device *, - unsigned short, - __u32); -#else -#if (LINUX_VERSION_CODE < 0x2011E) - /* Ptr to orig. hard_header_cache */ - int (*org_hhc)(struct dst_entry *dst, - struct dst_entry *neigh, - struct hh_cache *hh); -#else - /* Ptr to orig. hard_header_cache */ - int (*org_hhc)(struct dst_entry *dst, - struct neighbour *neigh, - struct hh_cache *hh); -#endif -#endif - /* Ptr to orig. header_cache_update */ - void (*org_hcu)(struct hh_cache *, - struct device *, - unsigned char *); int pppbind; /* ippp device for bindings */ } isdn_net_local; diff -u --recursive --new-file linux-2.1.42/net/netsyms.c linux/net/netsyms.c --- linux-2.1.42/net/netsyms.c Wed May 28 19:49:12 1997 +++ linux/net/netsyms.c Sun Jun 8 22:09:34 1997 @@ -294,6 +294,8 @@ EXPORT_SYMBOL(register_netdev); EXPORT_SYMBOL(unregister_netdev); EXPORT_SYMBOL(ether_setup); +EXPORT_SYMBOL(eth_header_cache); +EXPORT_SYMBOL(eth_header_cache_update); EXPORT_SYMBOL(dev_new_index); EXPORT_SYMBOL(dev_get_by_index); EXPORT_SYMBOL(eth_type_trans);

--==_Exmh_-12084234140--