X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fslip.c;h=0c1995bc284863d282e214611587f756ce8a21b0;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=e783ac0fa71e6b241871b652cfc90206b99cef25;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/net/slip.c b/drivers/net/slip.c index e783ac0fa..0c1995bc2 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -672,7 +672,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) @@ -841,9 +843,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 +880,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 +927,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 +948,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 +960,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; @@ -1138,6 +1144,7 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm { struct slip *sl = (struct slip *) tty->disc_data; unsigned int tmp; + int __user *p = (int __user *)arg; /* First make sure we're connected. */ if (!sl || sl->magic != SLIP_MAGIC) { @@ -1147,17 +1154,17 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm switch(cmd) { case SIOCGIFNAME: tmp = strlen(sl->dev->name) + 1; - if (copy_to_user((void *)arg, sl->dev->name, tmp)) + if (copy_to_user((void __user *)arg, sl->dev->name, tmp)) return -EFAULT; return 0; case SIOCGIFENCAP: - if (put_user(sl->mode, (int *)arg)) + if (put_user(sl->mode, p)) return -EFAULT; return 0; case SIOCSIFENCAP: - if (get_user(tmp,(int *)arg)) + if (get_user(tmp, p)) return -EFAULT; #ifndef SL_INCLUDE_CSLIP if (tmp & (SL_MODE_CSLIP|SL_MODE_ADAPTIVE)) { @@ -1185,7 +1192,7 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm #ifdef CONFIG_SLIP_SMART /* VSV changes start here */ case SIOCSKEEPALIVE: - if (get_user(tmp,(int *)arg)) + if (get_user(tmp, p)) return -EFAULT; if (tmp > 255) /* max for unchar */ return -EINVAL; @@ -1205,12 +1212,12 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm return 0; case SIOCGKEEPALIVE: - if (put_user(sl->keepalive, (int *)arg)) + if (put_user(sl->keepalive, p)) return -EFAULT; return 0; case SIOCSOUTFILL: - if (get_user(tmp,(int *)arg)) + if (get_user(tmp, p)) return -EFAULT; if (tmp > 255) /* max for unchar */ return -EINVAL; @@ -1229,7 +1236,7 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm return 0; case SIOCGOUTFILL: - if (put_user(sl->outfill, (int *)arg)) + if (put_user(sl->outfill, p)) return -EFAULT; return 0; /* VSV changes end */ @@ -1254,6 +1261,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); + unsigned long *p = (unsigned long *)&rq->ifr_ifru; if (sl == NULL) /* Allocation failed ?? */ return -ENODEV; @@ -1268,11 +1276,11 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) switch(cmd){ case SIOCSKEEPALIVE: /* max for unchar */ - if (((unsigned int)((unsigned long)rq->ifr_data)) > 255) { + if ((unsigned)*p > 255) { spin_unlock_bh(&sl->lock); return -EINVAL; } - sl->keepalive = (unchar) ((unsigned long)rq->ifr_data); + sl->keepalive = (unchar) *p; if (sl->keepalive != 0) { sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ; mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ); @@ -1283,15 +1291,15 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) break; case SIOCGKEEPALIVE: - rq->ifr_data=(caddr_t)((unsigned long)sl->keepalive); + *p = sl->keepalive; break; case SIOCSOUTFILL: - if (((unsigned)((unsigned long)rq->ifr_data)) > 255) { /* max for unchar */ + if ((unsigned)*p > 255) { /* max for unchar */ spin_unlock_bh(&sl->lock); return -EINVAL; } - if ((sl->outfill = (unchar)((unsigned long) rq->ifr_data)) != 0){ + if ((sl->outfill = (unchar)*p) != 0){ mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ); set_bit(SLF_OUTWAIT, &sl->flags); } else { @@ -1300,7 +1308,7 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) break; case SIOCGOUTFILL: - rq->ifr_data=(caddr_t)((unsigned long)sl->outfill); + *p = sl->outfill; break; case SIOCSLEASE: @@ -1312,12 +1320,12 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) return -EPERM; } sl->leased = 0; - if ((unsigned long)rq->ifr_data) + if (*p) sl->leased = 1; break; case SIOCGLEASE: - rq->ifr_data=(caddr_t)((unsigned long)sl->leased); + *p = sl->leased; }; spin_unlock_bh(&sl->lock); return 0;