X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fslip.c;h=a0806d262fc6530c1e72c2c75b14a999cc74e529;hb=refs%2Fheads%2Fvserver;hp=8f7841c0374d38d7caaaf7b6003882c83cc1582b;hpb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;p=linux-2.6.git diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 8f7841c03..a0806d262 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -55,7 +55,6 @@ */ #define SL_CHECK_TRANSMIT -#include #include #include @@ -74,6 +73,7 @@ #include #include #include +#include #include #include "slip.h" #ifdef CONFIG_INET @@ -113,7 +113,7 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd); * on actively running device. *********************************/ -/* +/* Allocate channel buffers. */ @@ -198,22 +198,16 @@ err_exit: static void sl_free_bufs(struct slip *sl) { - void * tmp; - /* Free all SLIP frame buffers. */ - tmp = xchg(&sl->rbuff, NULL); - kfree(tmp); - tmp = xchg(&sl->xbuff, NULL); - kfree(tmp); + kfree(xchg(&sl->rbuff, NULL)); + kfree(xchg(&sl->xbuff, NULL)); #ifdef SL_INCLUDE_CSLIP - tmp = xchg(&sl->cbuff, NULL); - kfree(tmp); - if ((tmp = xchg(&sl->slcomp, NULL)) != NULL) - slhc_free(tmp); + kfree(xchg(&sl->cbuff, NULL)); + slhc_free(xchg(&sl->slcomp, NULL)); #endif } -/* +/* Reallocate slip channel buffers. */ @@ -235,10 +229,10 @@ static int sl_realloc_bufs(struct slip *sl, int mtu) if (len < 576 * 2) len = 576 * 2; - xbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC); - rbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC); + xbuff = kmalloc(len + 4, GFP_ATOMIC); + rbuff = kmalloc(len + 4, GFP_ATOMIC); #ifdef SL_INCLUDE_CSLIP - cbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC); + cbuff = kmalloc(len + 4, GFP_ATOMIC); #endif @@ -360,7 +354,7 @@ sl_bump(struct slip *sl) #endif /* SL_INCLUDE_CSLIP */ sl->rx_bytes+=count; - + skb = dev_alloc_skb(count); if (skb == NULL) { printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", sl->dev->name); @@ -608,7 +602,7 @@ static int sl_init(struct net_device *dev) struct slip *sl = netdev_priv(dev); /* - * Finish setting up the DEVICE info. + * Finish setting up the DEVICE info. */ dev->mtu = sl->mtu; @@ -656,11 +650,6 @@ static void sl_setup(struct net_device *dev) ******************************************/ -static int slip_receive_room(struct tty_struct *tty) -{ - return 65536; /* We can handle an infinite amount of data. :-) */ -} - /* * Handle the 'receiver data ready' interrupt. * This function is called by the 'tty_io' module in the kernel when @@ -669,7 +658,7 @@ static int slip_receive_room(struct tty_struct *tty) * be re-entered while running but other ldisc functions may be called * in parallel */ - + 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; @@ -731,7 +720,7 @@ sl_alloc(dev_t line) struct net_device *dev = NULL; struct slip *sl; - if (slip_devs == NULL) + if (slip_devs == NULL) return NULL; /* Master array missing ! */ for (i = 0; i < slip_maxdev; i++) { @@ -799,7 +788,7 @@ sl_alloc(dev_t line) slip_devs[i] = NULL; } } - + if (!dev) { char name[IFNAMSIZ]; sprintf(name, "sl%d", i); @@ -826,7 +815,7 @@ sl_alloc(dev_t line) sl->outfill_timer.function=sl_outfill; #endif slip_devs[i] = dev; - + return sl; } @@ -847,7 +836,7 @@ static int slip_open(struct tty_struct *tty) if(!capable(CAP_NET_ADMIN)) return -EPERM; - + /* RTnetlink lock is misused here to serialize concurrent opens of slip channels. There are better ways, but it is the simplest one. @@ -873,11 +862,7 @@ static int slip_open(struct tty_struct *tty) tty->disc_data = sl; sl->line = tty_devnum(tty); sl->pid = current->pid; - - /* FIXME: already done before we were called - seems this can go */ - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - + if (!test_bit(SLF_INUSE, &sl->flags)) { /* Perform the low-level SLIP initialization. */ if ((err = sl_alloc_bufs(sl, SL_MTU)) != 0) @@ -902,6 +887,7 @@ static int slip_open(struct tty_struct *tty) /* Done. We have linked the TTY line to a channel. */ rtnl_unlock(); + tty->receive_room = 65536; /* We don't flow control */ return sl->dev->base_addr; err_free_bufs: @@ -922,7 +908,7 @@ err_exit: /* FIXME: 1,2 are fixed 3 was never true anyway. - + Let me to blame a bit. 1. TTY module calls this funstion on soft interrupt. 2. TTY module calls this function WITH MASKED INTERRUPTS! @@ -934,7 +920,7 @@ err_exit: By-product (not desired): sl? does not feel hangups and remains open. It is supposed, that user level program (dip, diald, slattach...) - will catch SIGHUP and make the rest of work. + will catch SIGHUP and make the rest of work. I see no way to make more with current tty code. --ANK */ @@ -1305,7 +1291,7 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) break; case SIOCSLEASE: - /* Resolve race condition, when ioctl'ing hanged up + /* Resolve race condition, when ioctl'ing hanged up and opened by another process device. */ if (sl->tty != current->signal->tty && sl->pid != current->pid) { @@ -1334,7 +1320,6 @@ static struct tty_ldisc sl_ldisc = { .close = slip_close, .ioctl = slip_ioctl, .receive_buf = slip_receive_buf, - .receive_room = slip_receive_room, .write_wakeup = slip_write_wakeup, }; @@ -1365,7 +1350,7 @@ static int __init slip_init(void) } /* Clear the pointer array, we allocate devices when we need them */ - memset(slip_devs, 0, sizeof(struct net_device *)*slip_maxdev); + memset(slip_devs, 0, sizeof(struct net_device *)*slip_maxdev); /* Fill in our line protocol discipline, and register it */ if ((status = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0) { @@ -1383,16 +1368,14 @@ static void __exit slip_exit(void) unsigned long timeout = jiffies + HZ; int busy = 0; - if (slip_devs == NULL) + if (slip_devs == NULL) return; /* First of all: check for active disciplines and hangup them. */ do { - if (busy) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ / 10); - } + if (busy) + msleep_interruptible(100); busy = 0; for (i = 0; i < slip_maxdev; i++) { @@ -1422,7 +1405,7 @@ static void __exit slip_exit(void) dev->name); /* Intentionally leak the control block. */ dev->destructor = NULL; - } + } unregister_netdev(dev); } @@ -1430,7 +1413,7 @@ static void __exit slip_exit(void) kfree(slip_devs); slip_devs = NULL; - if ((i = tty_register_ldisc(N_SLIP, NULL))) + if ((i = tty_unregister_ldisc(N_SLIP))) { printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i); }