diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2008-06-27 15:21:55 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-07-02 20:46:14 -0700 |
commit | 2a739dd53ad7ee010ae6e155438507f329dce788 (patch) | |
tree | e708d4cba463f4ac6a6813491f10e993e0953ca2 | |
parent | 3ad3367cdc36ff6ce4efd2159c39923a2b334f94 (diff) | |
download | lwn-2a739dd53ad7ee010ae6e155438507f329dce788.tar.gz lwn-2a739dd53ad7ee010ae6e155438507f329dce788.zip |
TTY: fix for tty operations bugs
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 <alan@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/net/hamradio/6pack.c | 2 | ||||
-rw-r--r-- | drivers/net/hamradio/mkiss.c | 8 | ||||
-rw-r--r-- | drivers/net/irda/irtty-sir.c | 4 | ||||
-rw-r--r-- | drivers/net/ppp_async.c | 3 | ||||
-rw-r--r-- | drivers/net/ppp_synctty.c | 3 | ||||
-rw-r--r-- | drivers/net/slip.c | 14 | ||||
-rw-r--r-- | drivers/net/wan/x25_asy.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/strip.c | 3 |
8 files changed, 37 insertions, 10 deletions
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 0a9b75139e0f..756e1bb04253 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -601,6 +601,8 @@ static int sixpack_open(struct tty_struct *tty) 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) { diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 30c9b3b0d131..f650da30ece8 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -529,6 +529,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len) 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, struct net_device *dev) /* 20 sec timeout not reached */ return 1; } + if (ax->tty->driver->chars_in_buffer) + cib = ax->tty->driver->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 *tty) 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) { diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index fc753d7f674e..df755f501e67 100644 --- 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 sir_dev *dev) 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->driver->chars_in_buffer) + return priv->tty->driver->chars_in_buffer(priv->tty); + return 0; } /* Wait (sleep) until underlaying hardware finished transmission diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index f023d5b67e6e..098bf441b376 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c @@ -158,6 +158,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); if (!ap) diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index 0d80fa546719..73729383e976 100644 --- 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) diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 5a55ede352f4..9d138bf021a6 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -460,10 +460,14 @@ 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, - (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 *tty) 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 diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 0f8aca8a4d43..f5b9a7124111 100644 --- 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 tty_struct *tty) 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_device *dev) * 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_struct *tty) 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; diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index 88efe1bae58f..5536a9493e21 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -802,7 +802,8 @@ static void set_baud(struct tty_struct *tty, unsigned int baudcode) 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); } /* |