summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2008-06-27 15:21:55 +0100
committerGreg Kroah-Hartman <gregkh@suse.de>2008-07-02 20:46:14 -0700
commit2a739dd53ad7ee010ae6e155438507f329dce788 (patch)
treee708d4cba463f4ac6a6813491f10e993e0953ca2
parent3ad3367cdc36ff6ce4efd2159c39923a2b334f94 (diff)
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.c2
-rw-r--r--drivers/net/hamradio/mkiss.c8
-rw-r--r--drivers/net/irda/irtty-sir.c4
-rw-r--r--drivers/net/ppp_async.c3
-rw-r--r--drivers/net/ppp_synctty.c3
-rw-r--r--drivers/net/slip.c14
-rw-r--r--drivers/net/wan/x25_asy.c10
-rw-r--r--drivers/net/wireless/strip.c3
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);
}
/*