X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fslip.c;h=8f7841c0374d38d7caaaf7b6003882c83cc1582b;hb=3d259a949928fe43072ddf0d0317523743fd8e7c;hp=a8967112fb7793bc616933460e40784aa138fadc;hpb=39b607ac274a09883c7fe5f03a7eff28960a1190;p=linux-2.6.git diff --git a/drivers/net/slip.c b/drivers/net/slip.c index a8967112f..8f7841c03 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -57,10 +57,11 @@ #define SL_CHECK_TRANSMIT #include #include +#include #include #include -#include +#include #include #include #include @@ -85,8 +86,8 @@ static struct net_device **slip_devs; -int slip_maxdev = SL_NRUNIT; /* Can be overridden with insmod! */ -MODULE_PARM(slip_maxdev, "i"); +static int slip_maxdev = SL_NRUNIT; +module_param(slip_maxdev, int, 0); MODULE_PARM_DESC(slip_maxdev, "Maximum number of slip devices"); static int slip_esc(unsigned char *p, unsigned char *d, int len); @@ -184,15 +185,12 @@ sl_alloc_bufs(struct slip *sl, int mtu) /* Cleanup */ err_exit: #ifdef SL_INCLUDE_CSLIP - if (cbuff) - kfree(cbuff); + kfree(cbuff); if (slcomp) slhc_free(slcomp); #endif - if (xbuff) - kfree(xbuff); - if (rbuff) - kfree(rbuff); + kfree(xbuff); + kfree(rbuff); return err; } @@ -203,13 +201,13 @@ sl_free_bufs(struct slip *sl) void * tmp; /* Free all SLIP frame buffers. */ - if ((tmp = xchg(&sl->rbuff, NULL)) != NULL) - kfree(tmp); - if ((tmp = xchg(&sl->xbuff, NULL)) != NULL) - kfree(tmp); + tmp = xchg(&sl->rbuff, NULL); + kfree(tmp); + tmp = xchg(&sl->xbuff, NULL); + kfree(tmp); #ifdef SL_INCLUDE_CSLIP - if ((tmp = xchg(&sl->cbuff, NULL)) != NULL) - kfree(tmp); + tmp = xchg(&sl->cbuff, NULL); + kfree(tmp); if ((tmp = xchg(&sl->slcomp, NULL)) != NULL) slhc_free(tmp); #endif @@ -296,13 +294,10 @@ done_on_bh: spin_unlock_bh(&sl->lock); done: - if (xbuff) - kfree(xbuff); - if (rbuff) - kfree(rbuff); + kfree(xbuff); + kfree(rbuff); #ifdef SL_INCLUDE_CSLIP - if (cbuff) - kfree(cbuff); + kfree(cbuff); #endif return err; } @@ -417,7 +412,7 @@ sl_encaps(struct slip *sl, unsigned char *icp, int len) * 14 Oct 1994 Dmitry Gorodchanin. */ sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); - actual = sl->tty->driver->write(sl->tty, 0, sl->xbuff, count); + actual = sl->tty->driver->write(sl->tty, sl->xbuff, count); #ifdef SL_CHECK_TRANSMIT sl->dev->trans_start = jiffies; #endif @@ -451,20 +446,18 @@ static void slip_write_wakeup(struct tty_struct *tty) return; } - actual = tty->driver->write(tty, 0, sl->xhead, sl->xleft); + actual = tty->driver->write(tty, sl->xhead, sl->xleft); sl->xleft -= actual; sl->xhead += actual; } static void sl_tx_timeout(struct net_device *dev) { - struct slip *sl = (struct slip*)(dev->priv); + struct slip *sl = netdev_priv(dev); spin_lock(&sl->lock); if (netif_queue_stopped(dev)) { - struct slip *sl = (struct slip*)(dev->priv); - if (!netif_running(dev)) goto out; @@ -494,7 +487,7 @@ out: static int sl_xmit(struct sk_buff *skb, struct net_device *dev) { - struct slip *sl = (struct slip*)(dev->priv); + struct slip *sl = netdev_priv(dev); spin_lock(&sl->lock); if (!netif_running(dev)) { @@ -528,7 +521,7 @@ sl_xmit(struct sk_buff *skb, struct net_device *dev) static int sl_close(struct net_device *dev) { - struct slip *sl = (struct slip*)(dev->priv); + struct slip *sl = netdev_priv(dev); spin_lock_bh(&sl->lock); if (sl->tty) { @@ -547,7 +540,7 @@ sl_close(struct net_device *dev) static int sl_open(struct net_device *dev) { - struct slip *sl = (struct slip*)(dev->priv); + struct slip *sl = netdev_priv(dev); if (sl->tty==NULL) return -ENODEV; @@ -561,7 +554,7 @@ static int sl_open(struct net_device *dev) static int sl_change_mtu(struct net_device *dev, int new_mtu) { - struct slip *sl = (struct slip*)(dev->priv); + struct slip *sl = netdev_priv(dev); if (new_mtu < 68 || new_mtu > 65534) return -EINVAL; @@ -577,7 +570,7 @@ static struct net_device_stats * sl_get_stats(struct net_device *dev) { static struct net_device_stats stats; - struct slip *sl = (struct slip*)(dev->priv); + struct slip *sl = netdev_priv(dev); #ifdef SL_INCLUDE_CSLIP struct slcompress *comp; #endif @@ -612,7 +605,7 @@ sl_get_stats(struct net_device *dev) static int sl_init(struct net_device *dev) { - struct slip *sl = (struct slip*)(dev->priv); + struct slip *sl = netdev_priv(dev); /* * Finish setting up the DEVICE info. @@ -630,7 +623,7 @@ static int sl_init(struct net_device *dev) static void sl_uninit(struct net_device *dev) { - struct slip *sl = (struct slip*)(dev->priv); + struct slip *sl = netdev_priv(dev); sl_free_bufs(sl); } @@ -672,7 +665,9 @@ static int slip_receive_room(struct tty_struct *tty) * Handle the 'receiver data ready' interrupt. * This function is called by the 'tty_io' module in the kernel when * a block of SLIP data has been received, which can now be decapsulated - * and sent on to some IP layer for further processing. + * and sent on to some IP layer for further processing. This will not + * 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) @@ -717,7 +712,7 @@ static void sl_sync(void) if ((dev = slip_devs[i]) == NULL) break; - sl = dev->priv; + sl = netdev_priv(dev); if (sl->tty || sl->leased) continue; if (dev->flags&IFF_UP) @@ -744,7 +739,7 @@ sl_alloc(dev_t line) if (dev == NULL) break; - sl = dev->priv; + sl = netdev_priv(dev); if (sl->leased) { if (sl->line != line) continue; @@ -786,7 +781,7 @@ sl_alloc(dev_t line) i = sel; dev = slip_devs[i]; if (score > 1) { - sl = dev->priv; + sl = netdev_priv(dev); sl->flags &= (1 << SLF_INUSE); return sl; } @@ -797,7 +792,7 @@ sl_alloc(dev_t line) return NULL; if (dev) { - sl = dev->priv; + sl = netdev_priv(dev); if (test_bit(SLF_INUSE, &sl->flags)) { unregister_netdevice(dev); dev = NULL; @@ -815,7 +810,7 @@ sl_alloc(dev_t line) dev->base_addr = i; } - sl = dev->priv; + sl = netdev_priv(dev); /* Initialize channel control data */ sl->magic = SLIP_MAGIC; @@ -841,9 +836,11 @@ sl_alloc(dev_t line) * SLIP line discipline is called for. Because we are * sure the tty line exists, we only have to link it to * a free SLIP channel... + * + * Called in process context serialized from other ldisc calls. */ -static int -slip_open(struct tty_struct *tty) + +static int slip_open(struct tty_struct *tty) { struct slip *sl; int err; @@ -876,11 +873,11 @@ 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 (tty->ldisc.flush_buffer) - tty->ldisc.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) @@ -923,6 +920,9 @@ 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! @@ -941,9 +941,8 @@ err_exit: /* * Close down a SLIP channel. - * This means flushing out any pending queues, and then restoring the - * TTY line discipline to what it was before it got hooked to SLIP - * (which usually is TTY again). + * 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) @@ -954,7 +953,7 @@ slip_close(struct tty_struct *tty) if (!sl || sl->magic != SLIP_MAGIC || sl->tty != tty) return; - tty->disc_data = 0; + tty->disc_data = NULL; sl->tty = NULL; if (!sl->leased) sl->line = 0; @@ -1254,7 +1253,7 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) { - struct slip *sl = (struct slip*)(dev->priv); + struct slip *sl = netdev_priv(dev); unsigned long *p = (unsigned long *)&rq->ifr_ifru; if (sl == NULL) /* Allocation failed ?? */ @@ -1400,7 +1399,7 @@ static void __exit slip_exit(void) dev = slip_devs[i]; if (!dev) continue; - sl = dev->priv; + sl = netdev_priv(dev); spin_lock_bh(&sl->lock); if (sl->tty) { busy++; @@ -1417,7 +1416,7 @@ static void __exit slip_exit(void) continue; slip_devs[i] = NULL; - sl = dev->priv; + sl = netdev_priv(dev); if (sl->tty) { printk(KERN_ERR "%s: tty discipline still running\n", dev->name); @@ -1469,7 +1468,7 @@ static void sl_outfill(unsigned long sls) if (!netif_queue_stopped(sl->dev)) { /* if device busy no outfill */ - sl->tty->driver->write(sl->tty, 0, &s, 1); + sl->tty->driver->write(sl->tty, &s, 1); } } else