2.6.25-stable review patch. If anyone has any objections, please let us know. ------------------ From: Alan Cox This is fixed with the recent tty operations rewrite in mainline in a different way, this is a selective backport of the relevant portions to the -stable tree. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/net/hamradio/6pack.c | 2 ++ drivers/net/hamradio/mkiss.c | 8 ++++++-- drivers/net/irda/irtty-sir.c | 4 +++- drivers/net/ppp_async.c | 3 +++ drivers/net/ppp_synctty.c | 3 +++ drivers/net/slip.c | 14 ++++++++++---- drivers/net/wan/x25_asy.c | 10 ++++++++-- drivers/net/wireless/strip.c | 3 ++- 8 files changed, 37 insertions(+), 10 deletions(-) --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -601,6 +601,8 @@ static int sixpack_open(struct tty_struc if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (!tty->driver->write) + return -EOPNOTSUPP; dev = alloc_netdev(sizeof(struct sixpack), "sp%d", sp_setup); if (!dev) { --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -529,6 +529,7 @@ static void ax_encaps(struct net_device static int ax_xmit(struct sk_buff *skb, struct net_device *dev) { struct mkiss *ax = netdev_priv(dev); + int cib = 0; if (!netif_running(dev)) { printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name); @@ -544,10 +545,11 @@ static int ax_xmit(struct sk_buff *skb, /* 20 sec timeout not reached */ return 1; } + if (ax->tty->drivers->chars_in_buffer) + cib = ax->tty->chars_in_buffer(ax->tty); printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name, - (ax->tty->driver->chars_in_buffer(ax->tty) || ax->xleft) ? - "bad line quality" : "driver error"); + cib || ax->xleft) ? "bad line quality" : "driver error"); ax->xleft = 0; clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags); @@ -736,6 +738,8 @@ static int mkiss_open(struct tty_struct if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (!tty->driver->write) + return -EOPNOTSUPP; dev = alloc_netdev(sizeof(struct mkiss), "ax%d", ax_setup); if (!dev) { --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c @@ -64,7 +64,9 @@ static int irtty_chars_in_buffer(struct IRDA_ASSERT(priv != NULL, return -1;); IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;); - return priv->tty->driver->chars_in_buffer(priv->tty); + if (priv->tty->drivers->chars_in_buffer) + return priv->tty->driver->chars_in_buffer(priv->tty); + return 0; } /* Wait (sleep) until underlaying hardware finished transmission --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c @@ -157,6 +157,9 @@ ppp_asynctty_open(struct tty_struct *tty { struct asyncppp *ap; int err; + + if (!tty->driver->write) + return -EOPNOTSUPP; err = -ENOMEM; ap = kzalloc(sizeof(*ap), GFP_KERNEL); --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c @@ -207,6 +207,9 @@ ppp_sync_open(struct tty_struct *tty) struct syncppp *ap; int err; + if (!tty->driver->write) + return -EOPNOTSUPP; + ap = kzalloc(sizeof(*ap), GFP_KERNEL); err = -ENOMEM; if (!ap) --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -460,10 +460,14 @@ static void sl_tx_timeout(struct net_dev /* 20 sec timeout not reached */ goto out; } - 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"); + { + int cib = 0; + if (sl->tty->driver->chars_in_buffer) + cib = sl->tty->driver->chars_in_buffer(sl->tty); + printk(KERN_WARNING "%s: transmit timed out, %s?\n", + dev->name, (cib || sl->xleft) ? + "bad line quality" : "driver error"); + } sl->xleft = 0; sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); sl_unlock(sl); @@ -829,6 +833,8 @@ static int slip_open(struct tty_struct * if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (!tty->driver->write) + return -EOPNOTSUPP; /* RTnetlink lock is misused here to serialize concurrent opens of slip channels. There are better ways, but it is --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -283,6 +283,10 @@ static void x25_asy_write_wakeup(struct static void x25_asy_timeout(struct net_device *dev) { struct x25_asy *sl = (struct x25_asy*)(dev->priv); + int cib = 0; + + if (sl->tty->driver->chars_in_buffer) + cib = sl->tty->driver->chars_in_buffer(sl->tty); spin_lock(&sl->lock); if (netif_queue_stopped(dev)) { @@ -290,8 +294,7 @@ static void x25_asy_timeout(struct net_d * 14 Oct 1994 Dmitry Gorodchanin. */ 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"); + (cib || sl->xleft) ? "bad line quality" : "driver error"); sl->xleft = 0; sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); x25_asy_unlock(sl); @@ -561,6 +564,9 @@ static int x25_asy_open_tty(struct tty_s return -EEXIST; } + if (!tty->driver->write) + return -EOPNOTSUPP; + /* OK. Find a free X.25 channel to use. */ if ((sl = x25_asy_alloc()) == NULL) { return -ENFILE; --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -802,7 +802,8 @@ static void set_baud(struct tty_struct * struct ktermios old_termios = *(tty->termios); tty->termios->c_cflag &= ~CBAUD; /* Clear the old baud setting */ tty->termios->c_cflag |= baudcode; /* Set the new baud setting */ - tty->driver->set_termios(tty, &old_termios); + if (tty->driver->set_termios) + tty->driver->set_termios(tty, &old_termios); } /* -- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/