]> git.hungrycats.org Git - linux/commitdiff
TTY: fix for tty operations bugs
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 27 Jun 2008 14:21:55 +0000 (15:21 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 3 Jul 2008 03:46:14 +0000 (20:46 -0700)
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>
drivers/net/hamradio/6pack.c
drivers/net/hamradio/mkiss.c
drivers/net/irda/irtty-sir.c
drivers/net/ppp_async.c
drivers/net/ppp_synctty.c
drivers/net/slip.c
drivers/net/wan/x25_asy.c
drivers/net/wireless/strip.c

index 0a9b75139e0f1f82e648df994b79aa9b05a7d20f..756e1bb042535178512c67e3f41f1cde392c80c7 100644 (file)
@@ -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) {
index 30c9b3b0d1319fe0c18b4906594748ee3ddaa6e0..f650da30ece8a6a24a509cdbd559f5b46ae1e798 100644 (file)
@@ -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) {
index fc753d7f674e41b0a231ac45663806c7b84ab06a..df755f501e67f169b4f0c5a8f085b2a643fde725 100644 (file)
@@ -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
index f023d5b67e6efcc38d1673ef56b9de8536371392..098bf441b376e7f947552eae9b9767c2ca026196 100644 (file)
@@ -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)
index 0d80fa54671963a002540d29eefdcaf042c7aa8d..73729383e976da37f8044d419baca64082c0a8eb 100644 (file)
@@ -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)
index 5a55ede352f4bc79dbceb5ee73bc2a6c0afb59d6..9d138bf021a6175230879971cdb25df20d633c99 100644 (file)
@@ -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
index 0f8aca8a4d4331b484226f749f6f33012c1a9cf3..f5b9a7124111096d48d4fd67fca4bc3b43583e67 100644 (file)
@@ -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;
index 88efe1bae58f5333d933c93ec21ac0b6aa09c42b..5536a9493e21a922a2f7fc44781fb0f2d229034a 100644 (file)
@@ -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);
 }
 
 /*