Loading drivers/net/slip.c +178 −189 Original line number Diff line number Diff line Loading @@ -11,9 +11,11 @@ * Fixes: * Alan Cox : Sanity checks and avoid tx overruns. * Has a new sl->mtu field. * Alan Cox : Found cause of overrun. ifconfig sl0 mtu upwards. * Driver now spots this and grows/shrinks its buffers(hack!). * Memory leak if you run out of memory setting up a slip driver fixed. * Alan Cox : Found cause of overrun. ifconfig sl0 * mtu upwards. Driver now spots this * and grows/shrinks its buffers(hack!). * Memory leak if you run out of memory * setting up a slip driver fixed. * Matt Dillon : Printable slip (borrowed from NET2E) * Pauline Middelink : Slip driver fixes. * Alan Cox : Honours the old SL_COMPRESSED flag Loading @@ -29,7 +31,8 @@ * buffering from 4096 to 256 bytes. * Improving SLIP response time. * CONFIG_SLIP_MODE_SLIP6. * ifconfig sl? up & down now works correctly. * ifconfig sl? up & down now works * correctly. * Modularization. * Alan Cox : Oops - fix AX.25 buffer lengths * Dmitry Gorodchanin : Even more cleanups. Preserve CSLIP Loading @@ -43,15 +46,18 @@ * device entries, just reg./unreg. them * as they are needed. We kfree() them * at module cleanup. * With MODULE-loading ``insmod'', user can * issue parameter: slip_maxdev=1024 * (Or how much he/she wants.. Default is 256) * * Stanislav Voronyi : Slip line checking, with ideas taken * from multislip BSDI driver which was written * by Igor Chechik, RELCOM Corp. Only algorithms * have been ported to Linux SLIP driver. * With MODULE-loading ``insmod'', user * can issue parameter: slip_maxdev=1024 * (Or how much he/she wants.. Default * is 256) * Stanislav Voronyi : Slip line checking, with ideas taken * from multislip BSDI driver which was * written by Igor Chechik, RELCOM Corp. * Only algorithms have been ported to * Linux SLIP driver. * Vitaly E. Lavrov : Sane behaviour on tty hangup. * Alexey Kuznetsov : Cleanup interfaces to tty&netdevice modules. * Alexey Kuznetsov : Cleanup interfaces to tty & netdevice * modules. */ #define SL_CHECK_TRANSMIT Loading Loading @@ -117,8 +123,7 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd); Allocate channel buffers. */ static int sl_alloc_bufs(struct slip *sl, int mtu) static int sl_alloc_bufs(struct slip *sl, int mtu) { int err = -ENOBUFS; unsigned long len; Loading Loading @@ -195,8 +200,7 @@ sl_alloc_bufs(struct slip *sl, int mtu) } /* Free a SLIP channel buffers. */ static void sl_free_bufs(struct slip *sl) static void sl_free_bufs(struct slip *sl) { /* Free all SLIP frame buffers. */ kfree(xchg(&sl->rbuff, NULL)); Loading Loading @@ -248,7 +252,6 @@ static int sl_realloc_bufs(struct slip *sl, int mtu) } goto done; } spin_lock_bh(&sl->lock); err = -ENODEV; Loading Loading @@ -298,23 +301,20 @@ static int sl_realloc_bufs(struct slip *sl, int mtu) /* Set the "sending" flag. This must be atomic hence the set_bit. */ static inline void sl_lock(struct slip *sl) static inline void sl_lock(struct slip *sl) { netif_stop_queue(sl->dev); } /* Clear the "sending" flag. This must be atomic, hence the ASM. */ static inline void sl_unlock(struct slip *sl) static inline void sl_unlock(struct slip *sl) { netif_wake_queue(sl->dev); } /* Send one completely decapsulated IP datagram to the IP layer. */ static void sl_bump(struct slip *sl) static void sl_bump(struct slip *sl) { struct sk_buff *skb; int count; Loading @@ -322,22 +322,22 @@ sl_bump(struct slip *sl) count = sl->rcount; #ifdef SL_INCLUDE_CSLIP if (sl->mode & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) { unsigned char c; if ((c = sl->rbuff[0]) & SL_TYPE_COMPRESSED_TCP) { unsigned char c = sl->rbuff[0]; if (c & SL_TYPE_COMPRESSED_TCP) { /* ignore compressed packets when CSLIP is off */ if (!(sl->mode & SL_MODE_CSLIP)) { printk(KERN_WARNING "%s: compressed packet ignored\n", sl->dev->name); return; } /* make sure we've reserved enough space for uncompress to use */ /* make sure we've reserved enough space for uncompress to use */ if (count + 80 > sl->buffsize) { sl->rx_over_errors++; return; } count = slhc_uncompress(sl->slcomp, sl->rbuff, count); if (count <= 0) { if (count <= 0) return; } } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) { if (!(sl->mode & SL_MODE_CSLIP)) { /* turn on header compression */ Loading @@ -346,11 +346,10 @@ sl_bump(struct slip *sl) printk(KERN_INFO "%s: header compression turned on\n", sl->dev->name); } sl->rbuff[0] &= 0x4f; if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) { if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) return; } } } #endif /* SL_INCLUDE_CSLIP */ sl->rx_bytes += count; Loading @@ -371,8 +370,7 @@ sl_bump(struct slip *sl) } /* Encapsulate one IP datagram and stuff into a TTY queue. */ static void sl_encaps(struct slip *sl, unsigned char *icp, int len) static void sl_encaps(struct slip *sl, unsigned char *icp, int len) { unsigned char *p; int actual, count; Loading @@ -386,9 +384,8 @@ sl_encaps(struct slip *sl, unsigned char *icp, int len) p = icp; #ifdef SL_INCLUDE_CSLIP if (sl->mode & SL_MODE_CSLIP) { if (sl->mode & SL_MODE_CSLIP) len = slhc_compress(sl->slcomp, p, len, sl->cbuff, &p, 1); } #endif #ifdef CONFIG_SLIP_MODE_SLIP6 if (sl->mode & SL_MODE_SLIP6) Loading Loading @@ -425,12 +422,12 @@ sl_encaps(struct slip *sl, unsigned char *icp, int len) static void slip_write_wakeup(struct tty_struct *tty) { int actual; struct slip *sl = (struct slip *) tty->disc_data; struct slip *sl = tty->disc_data; /* First make sure we're connected. */ if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) { if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) return; } if (sl->xleft <= 0) { /* Now serial buffer is almost free & we can start * transmission of another packet */ Loading Loading @@ -463,7 +460,8 @@ static void sl_tx_timeout(struct net_device *dev) /* 20 sec timeout not reached */ goto out; } printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ? "bad line quality" : "driver error"); sl->xleft = 0; Loading @@ -471,7 +469,6 @@ static void sl_tx_timeout(struct net_device *dev) sl_unlock(sl); #endif } out: spin_unlock(&sl->lock); } Loading Loading @@ -657,20 +654,19 @@ static void sl_setup(struct net_device *dev) * in parallel */ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) { struct slip *sl = (struct slip *) tty->disc_data; struct slip *sl = tty->disc_data; if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) return; /* Read the characters out of the buffer */ while (count--) { if (fp && *fp++) { if (!test_and_set_bit(SLF_ERROR, &sl->flags)) { if (!test_and_set_bit(SLF_ERROR, &sl->flags)) sl->rx_errors++; } cp++; continue; } Loading @@ -688,7 +684,6 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, ch ************************************/ /* Collect hanged up channels */ static void sl_sync(void) { int i; Loading @@ -696,7 +691,8 @@ static void sl_sync(void) struct slip *sl; for (i = 0; i < slip_maxdev; i++) { if ((dev = slip_devs[i]) == NULL) dev = slip_devs[i]; if (dev == NULL) break; sl = netdev_priv(dev); Loading @@ -709,8 +705,7 @@ static void sl_sync(void) /* Find a free SLIP channel, and link in this `tty' line. */ static struct slip * sl_alloc(dev_t line) static struct slip *sl_alloc(dev_t line) { int i; int sel = -1; Loading Loading @@ -805,7 +800,8 @@ sl_alloc(dev_t line) spin_lock_init(&sl->lock); sl->mode = SL_MODE_DEFAULT; #ifdef CONFIG_SLIP_SMART init_timer(&sl->keepalive_timer); /* initialize timer_list struct */ /* initialize timer_list struct */ init_timer(&sl->keepalive_timer); sl->keepalive_timer.data = (unsigned long)sl; sl->keepalive_timer.function = sl_keepalive; init_timer(&sl->outfill_timer); Loading @@ -813,7 +809,6 @@ sl_alloc(dev_t line) sl->outfill_timer.function = sl_outfill; #endif slip_devs[i] = dev; return sl; } Loading Loading @@ -844,7 +839,7 @@ static int slip_open(struct tty_struct *tty) /* Collect hanged up channels. */ sl_sync(); sl = (struct slip *) tty->disc_data; sl = tty->disc_data; err = -EEXIST; /* First make sure we're not already connected. */ Loading @@ -853,7 +848,8 @@ static int slip_open(struct tty_struct *tty) /* OK. Find a free SLIP channel to use. */ err = -ENFILE; if ((sl = sl_alloc(tty_devnum(tty))) == NULL) sl = sl_alloc(tty_devnum(tty)); if (sl == NULL) goto err_exit; sl->tty = tty; Loading @@ -863,12 +859,14 @@ static int slip_open(struct tty_struct *tty) if (!test_bit(SLF_INUSE, &sl->flags)) { /* Perform the low-level SLIP initialization. */ if ((err = sl_alloc_bufs(sl, SL_MTU)) != 0) err = sl_alloc_bufs(sl, SL_MTU); if (err) goto err_free_chan; set_bit(SLF_INUSE, &sl->flags); if ((err = register_netdevice(sl->dev))) err = register_netdevice(sl->dev); if (err) goto err_free_bufs; } Loading Loading @@ -928,10 +926,9 @@ static int slip_open(struct tty_struct *tty) * This means flushing out any pending queues, and then returning. This * call is serialized against other ldisc functions. */ static void slip_close(struct tty_struct *tty) static void slip_close(struct tty_struct *tty) { struct slip *sl = (struct slip *) tty->disc_data; struct slip *sl = tty->disc_data; /* First make sure we're connected. */ if (!sl || sl->magic != SLIP_MAGIC || sl->tty != tty) Loading @@ -955,8 +952,7 @@ slip_close(struct tty_struct *tty) * STANDARD SLIP ENCAPSULATION * ************************************************************************/ static int slip_esc(unsigned char *s, unsigned char *d, int len) static int slip_esc(unsigned char *s, unsigned char *d, int len) { unsigned char *ptr = d; unsigned char c; Loading Loading @@ -1004,9 +1000,9 @@ static void slip_unesc(struct slip *sl, unsigned char s) clear_bit(SLF_KEEPTEST, &sl->flags); #endif if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) { if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) sl_bump(sl); } clear_bit(SLF_ESCAPE, &sl->flags); sl->rcount = 0; return; Loading @@ -1015,14 +1011,12 @@ static void slip_unesc(struct slip *sl, unsigned char s) set_bit(SLF_ESCAPE, &sl->flags); return; case ESC_ESC: if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) { if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) s = ESC; } break; case ESC_END: if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) { if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) s = END; } break; } if (!test_bit(SLF_ERROR, &sl->flags)) { Loading @@ -1041,8 +1035,7 @@ static void slip_unesc(struct slip *sl, unsigned char s) * 6 BIT SLIP ENCAPSULATION * ************************************************************************/ int slip_esc6(unsigned char *s, unsigned char *d, int len) static int slip_esc6(unsigned char *s, unsigned char *d, int len) { unsigned char *ptr = d; unsigned char c; Loading Loading @@ -1079,8 +1072,7 @@ slip_esc6(unsigned char *s, unsigned char *d, int len) return ptr - d; } void slip_unesc6(struct slip *sl, unsigned char s) static void slip_unesc6(struct slip *sl, unsigned char s) { unsigned char c; Loading @@ -1091,9 +1083,9 @@ slip_unesc6(struct slip *sl, unsigned char s) clear_bit(SLF_KEEPTEST, &sl->flags); #endif if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) { if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) sl_bump(sl); } sl->rcount = 0; sl->xbits = 0; sl->xdata = 0; Loading @@ -1117,16 +1109,16 @@ slip_unesc6(struct slip *sl, unsigned char s) #endif /* CONFIG_SLIP_MODE_SLIP6 */ /* Perform I/O control on an active SLIP channel. */ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct slip *sl = (struct slip *) tty->disc_data; struct slip *sl = tty->disc_data; unsigned int tmp; int __user *p = (int __user *)arg; /* First make sure we're connected. */ if (!sl || sl->magic != SLIP_MAGIC) { if (!sl || sl->magic != SLIP_MAGIC) return -EINVAL; } switch (cmd) { case SIOCGIFNAME: Loading @@ -1144,20 +1136,17 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm if (get_user(tmp, p)) return -EFAULT; #ifndef SL_INCLUDE_CSLIP if (tmp & (SL_MODE_CSLIP|SL_MODE_ADAPTIVE)) { if (tmp & (SL_MODE_CSLIP|SL_MODE_ADAPTIVE)) return -EINVAL; } #else if ((tmp & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) == (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) { (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) /* return -EINVAL; */ tmp &= ~SL_MODE_ADAPTIVE; } #endif #ifndef CONFIG_SLIP_MODE_SLIP6 if (tmp & SL_MODE_SLIP6) { if (tmp & SL_MODE_SLIP6) return -EINVAL; } #endif sl->mode = tmp; sl->dev->type = ARPHRD_SLIP + sl->mode; Loading @@ -1179,12 +1168,13 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm spin_unlock_bh(&sl->lock); return -ENODEV; } if ((sl->keepalive = (unchar) tmp) != 0) { mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ); sl->keepalive = (u8)tmp; if (sl->keepalive != 0) { mod_timer(&sl->keepalive_timer, jiffies + sl->keepalive * HZ); set_bit(SLF_KEEPTEST, &sl->flags); } else { } else del_timer(&sl->keepalive_timer); } spin_unlock_bh(&sl->lock); return 0; Loading @@ -1203,12 +1193,13 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm spin_unlock_bh(&sl->lock); return -ENODEV; } if ((sl->outfill = (unchar) tmp) != 0){ mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ); sl->outfill = (u8)tmp; if (sl->outfill != 0) { mod_timer(&sl->outfill_timer, jiffies + sl->outfill * HZ); set_bit(SLF_OUTWAIT, &sl->flags); } else { } else del_timer(&sl->outfill_timer); } spin_unlock_bh(&sl->lock); return 0; Loading Loading @@ -1251,14 +1242,15 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) spin_unlock_bh(&sl->lock); return -EINVAL; } sl->keepalive = (unchar) *p; sl->keepalive = (u8)*p; if (sl->keepalive != 0) { sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ; mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ); sl->keepalive_timer.expires = jiffies + sl->keepalive * HZ; mod_timer(&sl->keepalive_timer, jiffies + sl->keepalive * HZ); set_bit(SLF_KEEPTEST, &sl->flags); } else { } else del_timer(&sl->keepalive_timer); } break; case SIOCGKEEPALIVE: Loading @@ -1270,12 +1262,13 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) spin_unlock_bh(&sl->lock); return -EINVAL; } if ((sl->outfill = (unchar)*p) != 0){ mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ); sl->outfill = (u8)*p; if (sl->outfill != 0) { mod_timer(&sl->outfill_timer, jiffies + sl->outfill * HZ); set_bit(SLF_OUTWAIT, &sl->flags); } else { } else del_timer(&sl->outfill_timer); } break; case SIOCGOUTFILL: Loading @@ -1286,7 +1279,8 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) /* Resolve race condition, when ioctl'ing hanged up and opened by another process device. */ if (sl->tty != current->signal->tty && sl->pid != current->pid) { if (sl->tty != current->signal->tty && sl->pid != current->pid) { spin_unlock_bh(&sl->lock); return -EPERM; } Loading Loading @@ -1335,14 +1329,16 @@ static int __init slip_init(void) printk(KERN_INFO "SLIP linefill/keepalive option.\n"); #endif slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev, GFP_KERNEL); slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev, GFP_KERNEL); if (!slip_devs) { printk(KERN_ERR "SLIP: Can't allocate slip devices array! Uaargh! (-> No SLIP available)\n"); printk(KERN_ERR "SLIP: Can't allocate slip devices array.\n"); return -ENOMEM; } /* Fill in our line protocol discipline, and register it */ if ((status = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0) { status = tty_register_ldisc(N_SLIP, &sl_ldisc); if (status != 0) { printk(KERN_ERR "SLIP: can't register line discipline (err = %d)\n", status); kfree(slip_devs); } Loading Loading @@ -1402,11 +1398,10 @@ static void __exit slip_exit(void) kfree(slip_devs); slip_devs = NULL; if ((i = tty_unregister_ldisc(N_SLIP))) { i = tty_unregister_ldisc(N_SLIP); if (i != 0) printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i); } } module_init(slip_init); module_exit(slip_exit); Loading @@ -1426,10 +1421,8 @@ static void sl_outfill(unsigned long sls) if (sl->tty == NULL) goto out; if(sl->outfill) { if( test_bit(SLF_OUTWAIT, &sl->flags) ) { if (sl->outfill) { if (test_bit(SLF_OUTWAIT, &sl->flags)) { /* no packets were transmitted, do outfill */ #ifdef CONFIG_SLIP_MODE_SLIP6 unsigned char s = (sl->mode & SL_MODE_SLIP6)?0x70:END; Loading @@ -1437,13 +1430,11 @@ static void sl_outfill(unsigned long sls) unsigned char s = END; #endif /* put END into tty queue. Is it right ??? */ if (!netif_queue_stopped(sl->dev)) { if (!netif_queue_stopped(sl->dev)) { /* if device busy no outfill */ sl->tty->driver->write(sl->tty, &s, 1); } } else } else set_bit(SLF_OUTWAIT, &sl->flags); mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ); Loading @@ -1461,24 +1452,22 @@ static void sl_keepalive(unsigned long sls) if (sl->tty == NULL) goto out; if( sl->keepalive) { if(test_bit(SLF_KEEPTEST, &sl->flags)) { if (sl->keepalive) { if (test_bit(SLF_KEEPTEST, &sl->flags)) { /* keepalive still high :(, we must hangup */ if( sl->outfill ) /* outfill timer must be deleted too */ if (sl->outfill) /* outfill timer must be deleted too */ (void)del_timer(&sl->outfill_timer); printk(KERN_DEBUG "%s: no packets received during keepalive timeout, hangup.\n", sl->dev->name); tty_hangup(sl->tty); /* this must hangup tty & close slip */ /* this must hangup tty & close slip */ tty_hangup(sl->tty); /* I think we need not something else */ goto out; } else } else set_bit(SLF_KEEPTEST, &sl->flags); mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ); } out: spin_unlock(&sl->lock); } Loading Loading
drivers/net/slip.c +178 −189 Original line number Diff line number Diff line Loading @@ -11,9 +11,11 @@ * Fixes: * Alan Cox : Sanity checks and avoid tx overruns. * Has a new sl->mtu field. * Alan Cox : Found cause of overrun. ifconfig sl0 mtu upwards. * Driver now spots this and grows/shrinks its buffers(hack!). * Memory leak if you run out of memory setting up a slip driver fixed. * Alan Cox : Found cause of overrun. ifconfig sl0 * mtu upwards. Driver now spots this * and grows/shrinks its buffers(hack!). * Memory leak if you run out of memory * setting up a slip driver fixed. * Matt Dillon : Printable slip (borrowed from NET2E) * Pauline Middelink : Slip driver fixes. * Alan Cox : Honours the old SL_COMPRESSED flag Loading @@ -29,7 +31,8 @@ * buffering from 4096 to 256 bytes. * Improving SLIP response time. * CONFIG_SLIP_MODE_SLIP6. * ifconfig sl? up & down now works correctly. * ifconfig sl? up & down now works * correctly. * Modularization. * Alan Cox : Oops - fix AX.25 buffer lengths * Dmitry Gorodchanin : Even more cleanups. Preserve CSLIP Loading @@ -43,15 +46,18 @@ * device entries, just reg./unreg. them * as they are needed. We kfree() them * at module cleanup. * With MODULE-loading ``insmod'', user can * issue parameter: slip_maxdev=1024 * (Or how much he/she wants.. Default is 256) * * Stanislav Voronyi : Slip line checking, with ideas taken * from multislip BSDI driver which was written * by Igor Chechik, RELCOM Corp. Only algorithms * have been ported to Linux SLIP driver. * With MODULE-loading ``insmod'', user * can issue parameter: slip_maxdev=1024 * (Or how much he/she wants.. Default * is 256) * Stanislav Voronyi : Slip line checking, with ideas taken * from multislip BSDI driver which was * written by Igor Chechik, RELCOM Corp. * Only algorithms have been ported to * Linux SLIP driver. * Vitaly E. Lavrov : Sane behaviour on tty hangup. * Alexey Kuznetsov : Cleanup interfaces to tty&netdevice modules. * Alexey Kuznetsov : Cleanup interfaces to tty & netdevice * modules. */ #define SL_CHECK_TRANSMIT Loading Loading @@ -117,8 +123,7 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd); Allocate channel buffers. */ static int sl_alloc_bufs(struct slip *sl, int mtu) static int sl_alloc_bufs(struct slip *sl, int mtu) { int err = -ENOBUFS; unsigned long len; Loading Loading @@ -195,8 +200,7 @@ sl_alloc_bufs(struct slip *sl, int mtu) } /* Free a SLIP channel buffers. */ static void sl_free_bufs(struct slip *sl) static void sl_free_bufs(struct slip *sl) { /* Free all SLIP frame buffers. */ kfree(xchg(&sl->rbuff, NULL)); Loading Loading @@ -248,7 +252,6 @@ static int sl_realloc_bufs(struct slip *sl, int mtu) } goto done; } spin_lock_bh(&sl->lock); err = -ENODEV; Loading Loading @@ -298,23 +301,20 @@ static int sl_realloc_bufs(struct slip *sl, int mtu) /* Set the "sending" flag. This must be atomic hence the set_bit. */ static inline void sl_lock(struct slip *sl) static inline void sl_lock(struct slip *sl) { netif_stop_queue(sl->dev); } /* Clear the "sending" flag. This must be atomic, hence the ASM. */ static inline void sl_unlock(struct slip *sl) static inline void sl_unlock(struct slip *sl) { netif_wake_queue(sl->dev); } /* Send one completely decapsulated IP datagram to the IP layer. */ static void sl_bump(struct slip *sl) static void sl_bump(struct slip *sl) { struct sk_buff *skb; int count; Loading @@ -322,22 +322,22 @@ sl_bump(struct slip *sl) count = sl->rcount; #ifdef SL_INCLUDE_CSLIP if (sl->mode & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) { unsigned char c; if ((c = sl->rbuff[0]) & SL_TYPE_COMPRESSED_TCP) { unsigned char c = sl->rbuff[0]; if (c & SL_TYPE_COMPRESSED_TCP) { /* ignore compressed packets when CSLIP is off */ if (!(sl->mode & SL_MODE_CSLIP)) { printk(KERN_WARNING "%s: compressed packet ignored\n", sl->dev->name); return; } /* make sure we've reserved enough space for uncompress to use */ /* make sure we've reserved enough space for uncompress to use */ if (count + 80 > sl->buffsize) { sl->rx_over_errors++; return; } count = slhc_uncompress(sl->slcomp, sl->rbuff, count); if (count <= 0) { if (count <= 0) return; } } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) { if (!(sl->mode & SL_MODE_CSLIP)) { /* turn on header compression */ Loading @@ -346,11 +346,10 @@ sl_bump(struct slip *sl) printk(KERN_INFO "%s: header compression turned on\n", sl->dev->name); } sl->rbuff[0] &= 0x4f; if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) { if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) return; } } } #endif /* SL_INCLUDE_CSLIP */ sl->rx_bytes += count; Loading @@ -371,8 +370,7 @@ sl_bump(struct slip *sl) } /* Encapsulate one IP datagram and stuff into a TTY queue. */ static void sl_encaps(struct slip *sl, unsigned char *icp, int len) static void sl_encaps(struct slip *sl, unsigned char *icp, int len) { unsigned char *p; int actual, count; Loading @@ -386,9 +384,8 @@ sl_encaps(struct slip *sl, unsigned char *icp, int len) p = icp; #ifdef SL_INCLUDE_CSLIP if (sl->mode & SL_MODE_CSLIP) { if (sl->mode & SL_MODE_CSLIP) len = slhc_compress(sl->slcomp, p, len, sl->cbuff, &p, 1); } #endif #ifdef CONFIG_SLIP_MODE_SLIP6 if (sl->mode & SL_MODE_SLIP6) Loading Loading @@ -425,12 +422,12 @@ sl_encaps(struct slip *sl, unsigned char *icp, int len) static void slip_write_wakeup(struct tty_struct *tty) { int actual; struct slip *sl = (struct slip *) tty->disc_data; struct slip *sl = tty->disc_data; /* First make sure we're connected. */ if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) { if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) return; } if (sl->xleft <= 0) { /* Now serial buffer is almost free & we can start * transmission of another packet */ Loading Loading @@ -463,7 +460,8 @@ static void sl_tx_timeout(struct net_device *dev) /* 20 sec timeout not reached */ goto out; } printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ? "bad line quality" : "driver error"); sl->xleft = 0; Loading @@ -471,7 +469,6 @@ static void sl_tx_timeout(struct net_device *dev) sl_unlock(sl); #endif } out: spin_unlock(&sl->lock); } Loading Loading @@ -657,20 +654,19 @@ static void sl_setup(struct net_device *dev) * in parallel */ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) { struct slip *sl = (struct slip *) tty->disc_data; struct slip *sl = tty->disc_data; if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) return; /* Read the characters out of the buffer */ while (count--) { if (fp && *fp++) { if (!test_and_set_bit(SLF_ERROR, &sl->flags)) { if (!test_and_set_bit(SLF_ERROR, &sl->flags)) sl->rx_errors++; } cp++; continue; } Loading @@ -688,7 +684,6 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, ch ************************************/ /* Collect hanged up channels */ static void sl_sync(void) { int i; Loading @@ -696,7 +691,8 @@ static void sl_sync(void) struct slip *sl; for (i = 0; i < slip_maxdev; i++) { if ((dev = slip_devs[i]) == NULL) dev = slip_devs[i]; if (dev == NULL) break; sl = netdev_priv(dev); Loading @@ -709,8 +705,7 @@ static void sl_sync(void) /* Find a free SLIP channel, and link in this `tty' line. */ static struct slip * sl_alloc(dev_t line) static struct slip *sl_alloc(dev_t line) { int i; int sel = -1; Loading Loading @@ -805,7 +800,8 @@ sl_alloc(dev_t line) spin_lock_init(&sl->lock); sl->mode = SL_MODE_DEFAULT; #ifdef CONFIG_SLIP_SMART init_timer(&sl->keepalive_timer); /* initialize timer_list struct */ /* initialize timer_list struct */ init_timer(&sl->keepalive_timer); sl->keepalive_timer.data = (unsigned long)sl; sl->keepalive_timer.function = sl_keepalive; init_timer(&sl->outfill_timer); Loading @@ -813,7 +809,6 @@ sl_alloc(dev_t line) sl->outfill_timer.function = sl_outfill; #endif slip_devs[i] = dev; return sl; } Loading Loading @@ -844,7 +839,7 @@ static int slip_open(struct tty_struct *tty) /* Collect hanged up channels. */ sl_sync(); sl = (struct slip *) tty->disc_data; sl = tty->disc_data; err = -EEXIST; /* First make sure we're not already connected. */ Loading @@ -853,7 +848,8 @@ static int slip_open(struct tty_struct *tty) /* OK. Find a free SLIP channel to use. */ err = -ENFILE; if ((sl = sl_alloc(tty_devnum(tty))) == NULL) sl = sl_alloc(tty_devnum(tty)); if (sl == NULL) goto err_exit; sl->tty = tty; Loading @@ -863,12 +859,14 @@ static int slip_open(struct tty_struct *tty) if (!test_bit(SLF_INUSE, &sl->flags)) { /* Perform the low-level SLIP initialization. */ if ((err = sl_alloc_bufs(sl, SL_MTU)) != 0) err = sl_alloc_bufs(sl, SL_MTU); if (err) goto err_free_chan; set_bit(SLF_INUSE, &sl->flags); if ((err = register_netdevice(sl->dev))) err = register_netdevice(sl->dev); if (err) goto err_free_bufs; } Loading Loading @@ -928,10 +926,9 @@ static int slip_open(struct tty_struct *tty) * This means flushing out any pending queues, and then returning. This * call is serialized against other ldisc functions. */ static void slip_close(struct tty_struct *tty) static void slip_close(struct tty_struct *tty) { struct slip *sl = (struct slip *) tty->disc_data; struct slip *sl = tty->disc_data; /* First make sure we're connected. */ if (!sl || sl->magic != SLIP_MAGIC || sl->tty != tty) Loading @@ -955,8 +952,7 @@ slip_close(struct tty_struct *tty) * STANDARD SLIP ENCAPSULATION * ************************************************************************/ static int slip_esc(unsigned char *s, unsigned char *d, int len) static int slip_esc(unsigned char *s, unsigned char *d, int len) { unsigned char *ptr = d; unsigned char c; Loading Loading @@ -1004,9 +1000,9 @@ static void slip_unesc(struct slip *sl, unsigned char s) clear_bit(SLF_KEEPTEST, &sl->flags); #endif if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) { if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) sl_bump(sl); } clear_bit(SLF_ESCAPE, &sl->flags); sl->rcount = 0; return; Loading @@ -1015,14 +1011,12 @@ static void slip_unesc(struct slip *sl, unsigned char s) set_bit(SLF_ESCAPE, &sl->flags); return; case ESC_ESC: if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) { if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) s = ESC; } break; case ESC_END: if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) { if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) s = END; } break; } if (!test_bit(SLF_ERROR, &sl->flags)) { Loading @@ -1041,8 +1035,7 @@ static void slip_unesc(struct slip *sl, unsigned char s) * 6 BIT SLIP ENCAPSULATION * ************************************************************************/ int slip_esc6(unsigned char *s, unsigned char *d, int len) static int slip_esc6(unsigned char *s, unsigned char *d, int len) { unsigned char *ptr = d; unsigned char c; Loading Loading @@ -1079,8 +1072,7 @@ slip_esc6(unsigned char *s, unsigned char *d, int len) return ptr - d; } void slip_unesc6(struct slip *sl, unsigned char s) static void slip_unesc6(struct slip *sl, unsigned char s) { unsigned char c; Loading @@ -1091,9 +1083,9 @@ slip_unesc6(struct slip *sl, unsigned char s) clear_bit(SLF_KEEPTEST, &sl->flags); #endif if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) { if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) sl_bump(sl); } sl->rcount = 0; sl->xbits = 0; sl->xdata = 0; Loading @@ -1117,16 +1109,16 @@ slip_unesc6(struct slip *sl, unsigned char s) #endif /* CONFIG_SLIP_MODE_SLIP6 */ /* Perform I/O control on an active SLIP channel. */ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct slip *sl = (struct slip *) tty->disc_data; struct slip *sl = tty->disc_data; unsigned int tmp; int __user *p = (int __user *)arg; /* First make sure we're connected. */ if (!sl || sl->magic != SLIP_MAGIC) { if (!sl || sl->magic != SLIP_MAGIC) return -EINVAL; } switch (cmd) { case SIOCGIFNAME: Loading @@ -1144,20 +1136,17 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm if (get_user(tmp, p)) return -EFAULT; #ifndef SL_INCLUDE_CSLIP if (tmp & (SL_MODE_CSLIP|SL_MODE_ADAPTIVE)) { if (tmp & (SL_MODE_CSLIP|SL_MODE_ADAPTIVE)) return -EINVAL; } #else if ((tmp & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) == (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) { (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) /* return -EINVAL; */ tmp &= ~SL_MODE_ADAPTIVE; } #endif #ifndef CONFIG_SLIP_MODE_SLIP6 if (tmp & SL_MODE_SLIP6) { if (tmp & SL_MODE_SLIP6) return -EINVAL; } #endif sl->mode = tmp; sl->dev->type = ARPHRD_SLIP + sl->mode; Loading @@ -1179,12 +1168,13 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm spin_unlock_bh(&sl->lock); return -ENODEV; } if ((sl->keepalive = (unchar) tmp) != 0) { mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ); sl->keepalive = (u8)tmp; if (sl->keepalive != 0) { mod_timer(&sl->keepalive_timer, jiffies + sl->keepalive * HZ); set_bit(SLF_KEEPTEST, &sl->flags); } else { } else del_timer(&sl->keepalive_timer); } spin_unlock_bh(&sl->lock); return 0; Loading @@ -1203,12 +1193,13 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm spin_unlock_bh(&sl->lock); return -ENODEV; } if ((sl->outfill = (unchar) tmp) != 0){ mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ); sl->outfill = (u8)tmp; if (sl->outfill != 0) { mod_timer(&sl->outfill_timer, jiffies + sl->outfill * HZ); set_bit(SLF_OUTWAIT, &sl->flags); } else { } else del_timer(&sl->outfill_timer); } spin_unlock_bh(&sl->lock); return 0; Loading Loading @@ -1251,14 +1242,15 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) spin_unlock_bh(&sl->lock); return -EINVAL; } sl->keepalive = (unchar) *p; sl->keepalive = (u8)*p; if (sl->keepalive != 0) { sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ; mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ); sl->keepalive_timer.expires = jiffies + sl->keepalive * HZ; mod_timer(&sl->keepalive_timer, jiffies + sl->keepalive * HZ); set_bit(SLF_KEEPTEST, &sl->flags); } else { } else del_timer(&sl->keepalive_timer); } break; case SIOCGKEEPALIVE: Loading @@ -1270,12 +1262,13 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) spin_unlock_bh(&sl->lock); return -EINVAL; } if ((sl->outfill = (unchar)*p) != 0){ mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ); sl->outfill = (u8)*p; if (sl->outfill != 0) { mod_timer(&sl->outfill_timer, jiffies + sl->outfill * HZ); set_bit(SLF_OUTWAIT, &sl->flags); } else { } else del_timer(&sl->outfill_timer); } break; case SIOCGOUTFILL: Loading @@ -1286,7 +1279,8 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) /* Resolve race condition, when ioctl'ing hanged up and opened by another process device. */ if (sl->tty != current->signal->tty && sl->pid != current->pid) { if (sl->tty != current->signal->tty && sl->pid != current->pid) { spin_unlock_bh(&sl->lock); return -EPERM; } Loading Loading @@ -1335,14 +1329,16 @@ static int __init slip_init(void) printk(KERN_INFO "SLIP linefill/keepalive option.\n"); #endif slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev, GFP_KERNEL); slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev, GFP_KERNEL); if (!slip_devs) { printk(KERN_ERR "SLIP: Can't allocate slip devices array! Uaargh! (-> No SLIP available)\n"); printk(KERN_ERR "SLIP: Can't allocate slip devices array.\n"); return -ENOMEM; } /* Fill in our line protocol discipline, and register it */ if ((status = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0) { status = tty_register_ldisc(N_SLIP, &sl_ldisc); if (status != 0) { printk(KERN_ERR "SLIP: can't register line discipline (err = %d)\n", status); kfree(slip_devs); } Loading Loading @@ -1402,11 +1398,10 @@ static void __exit slip_exit(void) kfree(slip_devs); slip_devs = NULL; if ((i = tty_unregister_ldisc(N_SLIP))) { i = tty_unregister_ldisc(N_SLIP); if (i != 0) printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i); } } module_init(slip_init); module_exit(slip_exit); Loading @@ -1426,10 +1421,8 @@ static void sl_outfill(unsigned long sls) if (sl->tty == NULL) goto out; if(sl->outfill) { if( test_bit(SLF_OUTWAIT, &sl->flags) ) { if (sl->outfill) { if (test_bit(SLF_OUTWAIT, &sl->flags)) { /* no packets were transmitted, do outfill */ #ifdef CONFIG_SLIP_MODE_SLIP6 unsigned char s = (sl->mode & SL_MODE_SLIP6)?0x70:END; Loading @@ -1437,13 +1430,11 @@ static void sl_outfill(unsigned long sls) unsigned char s = END; #endif /* put END into tty queue. Is it right ??? */ if (!netif_queue_stopped(sl->dev)) { if (!netif_queue_stopped(sl->dev)) { /* if device busy no outfill */ sl->tty->driver->write(sl->tty, &s, 1); } } else } else set_bit(SLF_OUTWAIT, &sl->flags); mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ); Loading @@ -1461,24 +1452,22 @@ static void sl_keepalive(unsigned long sls) if (sl->tty == NULL) goto out; if( sl->keepalive) { if(test_bit(SLF_KEEPTEST, &sl->flags)) { if (sl->keepalive) { if (test_bit(SLF_KEEPTEST, &sl->flags)) { /* keepalive still high :(, we must hangup */ if( sl->outfill ) /* outfill timer must be deleted too */ if (sl->outfill) /* outfill timer must be deleted too */ (void)del_timer(&sl->outfill_timer); printk(KERN_DEBUG "%s: no packets received during keepalive timeout, hangup.\n", sl->dev->name); tty_hangup(sl->tty); /* this must hangup tty & close slip */ /* this must hangup tty & close slip */ tty_hangup(sl->tty); /* I think we need not something else */ goto out; } else } else set_bit(SLF_KEEPTEST, &sl->flags); mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ); } out: spin_unlock(&sl->lock); } Loading