compat: backport tty_set_termios
authorHauke Mehrtens <hauke@hauke-m.de>
Mon, 21 Feb 2011 22:32:24 +0000 (14:32 -0800)
committerLuis R. Rodriguez <lrodriguez@atheros.com>
Tue, 22 Feb 2011 20:53:26 +0000 (12:53 -0800)
This code is copied from the kernel sources.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
compat/Makefile
compat/compat-2.6.39.c [new file with mode: 0644]
include/linux/compat-2.6.39.h

index 9c042caa0da19467c2d2fd88c86e0e317e1c9335..f87b024ac10ba4386b53b7ea43dfd98ac0414218 100644 (file)
@@ -29,3 +29,4 @@ compat-$(CONFIG_COMPAT_KERNEL_35) += compat-2.6.35.o
 compat-$(CONFIG_COMPAT_KERNEL_36) += compat-2.6.36.o
 compat-$(CONFIG_COMPAT_KERNEL_37) += compat-2.6.37.o
 compat-$(CONFIG_COMPAT_KERNEL_38) += compat-2.6.38.o
+compat-$(CONFIG_COMPAT_KERNEL_39) += compat-2.6.39.o
diff --git a/compat/compat-2.6.39.c b/compat/compat-2.6.39.c
new file mode 100644 (file)
index 0000000..c2966f7
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2011    Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Compatibility file for Linux wireless for kernels 2.6.39.
+ */
+
+#include <linux/compat.h>
+#include <linux/tty.h>
+
+/*
+ *             Termios Helper Methods
+ */
+static void unset_locked_termios(struct ktermios *termios,
+                                struct ktermios *old,
+                                struct ktermios *locked)
+{
+       int     i;
+
+#define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z)))
+
+       if (!locked) {
+               printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n");
+               return;
+       }
+
+       NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
+       NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
+       NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
+       NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
+       termios->c_line = locked->c_line ? old->c_line : termios->c_line;
+       for (i = 0; i < NCCS; i++)
+               termios->c_cc[i] = locked->c_cc[i] ?
+                       old->c_cc[i] : termios->c_cc[i];
+       /* FIXME: What should we do for i/ospeed */
+}
+
+/**
+ *     tty_set_termios         -       update termios values
+ *     @tty: tty to update
+ *     @new_termios: desired new value
+ *
+ *     Perform updates to the termios values set on this terminal. There
+ *     is a bit of layering violation here with n_tty in terms of the
+ *     internal knowledge of this function.
+ *
+ *     Locking: termios_mutex
+ */
+int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
+{
+       struct ktermios old_termios;
+       struct tty_ldisc *ld;
+       unsigned long flags;
+
+       /*
+        *      Perform the actual termios internal changes under lock.
+        */
+
+
+       /* FIXME: we need to decide on some locking/ordering semantics
+          for the set_termios notification eventually */
+       mutex_lock(&tty->termios_mutex);
+       old_termios = *tty->termios;
+       *tty->termios = *new_termios;
+       unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
+
+       /* See if packet mode change of state. */
+       if (tty->link && tty->link->packet) {
+               int extproc = (old_termios.c_lflag & EXTPROC) |
+                               (tty->termios->c_lflag & EXTPROC);
+               int old_flow = ((old_termios.c_iflag & IXON) &&
+                               (old_termios.c_cc[VSTOP] == '\023') &&
+                               (old_termios.c_cc[VSTART] == '\021'));
+               int new_flow = (I_IXON(tty) &&
+                               STOP_CHAR(tty) == '\023' &&
+                               START_CHAR(tty) == '\021');
+               if ((old_flow != new_flow) || extproc) {
+                       spin_lock_irqsave(&tty->ctrl_lock, flags);
+                       if (old_flow != new_flow) {
+                               tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
+                               if (new_flow)
+                                       tty->ctrl_status |= TIOCPKT_DOSTOP;
+                               else
+                                       tty->ctrl_status |= TIOCPKT_NOSTOP;
+                       }
+                       if (extproc)
+                               tty->ctrl_status |= TIOCPKT_IOCTL;
+                       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+                       wake_up_interruptible(&tty->link->read_wait);
+               }
+       }
+
+       if (tty->ops->set_termios)
+               (*tty->ops->set_termios)(tty, &old_termios);
+       else
+               tty_termios_copy_hw(tty->termios, &old_termios);
+
+       ld = tty_ldisc_ref(tty);
+       if (ld != NULL) {
+               if (ld->ops->set_termios)
+                       (ld->ops->set_termios)(tty, &old_termios);
+               tty_ldisc_deref(ld);
+       }
+       mutex_unlock(&tty->termios_mutex);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(tty_set_termios);
+
index c0c98fdb6d610e08fb4b5d8eef54235f62cde8fa..1c7b322c9b5027f184989cc65dffb3eee106ee12 100644 (file)
@@ -5,6 +5,8 @@
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
 
+#include <linux/tty.h>
+
 /*
  * This is not part of The 2.6.37 kernel yet but we
  * we use it to optimize the backport code we
 #define br_port_exists(dev)    (dev->br_port)
 #endif
 
+#define tiocmget(tty) tiocmget(tty, NULL)
+#define tiocmset(tty, set, clear) tiocmset(tty, NULL, set, clear)
+
+extern int tty_set_termios(struct tty_struct *tty, struct ktermios *kt);
+
 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)) */
 
 #endif /* LINUX_26_39_COMPAT_H */