termios: start unifying non-UAPI parts of asm/termios.h
[sfrench/cifs-2.6.git] / drivers / tty / tty_ioctl.c
index 2a76b330e1089eb935da2a4439f4835ed6394209..ce511557b98b1f6c58f9b9e608693fbe0c00fd76 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/bitops.h>
 #include <linux/mutex.h>
 #include <linux/compat.h>
+#include <linux/termios_internal.h>
 #include "tty.h"
 
 #include <asm/io.h>
@@ -219,7 +220,7 @@ EXPORT_SYMBOL(tty_wait_until_sent);
  *             Termios Helper Methods
  */
 
-static void unset_locked_termios(struct tty_struct *tty, struct ktermios *old)
+static void unset_locked_termios(struct tty_struct *tty, const struct ktermios *old)
 {
        struct ktermios *termios = &tty->termios;
        struct ktermios *locked  = &tty->termios_locked;
@@ -249,7 +250,7 @@ static void unset_locked_termios(struct tty_struct *tty, struct ktermios *old)
  *     in some cases where only minimal reconfiguration is supported
  */
 
-void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old)
+void tty_termios_copy_hw(struct ktermios *new, const struct ktermios *old)
 {
        /* The bits a dumb device handles in software. Smart devices need
           to always provide a set_termios method */
@@ -374,6 +375,80 @@ int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
 }
 EXPORT_SYMBOL_GPL(tty_set_termios);
 
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+__weak int user_termio_to_kernel_termios(struct ktermios *termios,
+                                               struct termio __user *termio)
+{
+       struct termio v;
+
+       if (copy_from_user(&v, termio, sizeof(struct termio)))
+               return -EFAULT;
+
+       termios->c_iflag = (0xffff0000 & termios->c_iflag) | v.c_iflag;
+       termios->c_oflag = (0xffff0000 & termios->c_oflag) | v.c_oflag;
+       termios->c_cflag = (0xffff0000 & termios->c_cflag) | v.c_cflag;
+       termios->c_lflag = (0xffff0000 & termios->c_lflag) | v.c_lflag;
+       termios->c_line = (0xffff0000 & termios->c_lflag) | v.c_line;
+       memcpy(termios->c_cc, v.c_cc, NCC);
+       return 0;
+}
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+__weak int kernel_termios_to_user_termio(struct termio __user *termio,
+                                               struct ktermios *termios)
+{
+       struct termio v;
+       memset(&v, 0, sizeof(struct termio));
+       v.c_iflag = termios->c_iflag;
+       v.c_oflag = termios->c_oflag;
+       v.c_cflag = termios->c_cflag;
+       v.c_lflag = termios->c_lflag;
+       v.c_line = termios->c_line;
+       memcpy(v.c_cc, termios->c_cc, NCC);
+       return copy_to_user(termio, &v, sizeof(struct termio));
+}
+
+#ifdef TCGETS2
+__weak int user_termios_to_kernel_termios(struct ktermios *k,
+                                                struct termios2 __user *u)
+{
+       return copy_from_user(k, u, sizeof(struct termios2));
+}
+__weak int kernel_termios_to_user_termios(struct termios2 __user *u,
+                                                struct ktermios *k)
+{
+       return copy_to_user(u, k, sizeof(struct termios2));
+}
+__weak int user_termios_to_kernel_termios_1(struct ktermios *k,
+                                                  struct termios __user *u)
+{
+       return copy_from_user(k, u, sizeof(struct termios));
+}
+__weak int kernel_termios_to_user_termios_1(struct termios __user *u,
+                                                  struct ktermios *k)
+{
+       return copy_to_user(u, k, sizeof(struct termios));
+}
+
+#else
+
+__weak int user_termios_to_kernel_termios(struct ktermios *k,
+                                                struct termios __user *u)
+{
+       return copy_from_user(k, u, sizeof(struct termios));
+}
+__weak int kernel_termios_to_user_termios(struct termios __user *u,
+                                                struct ktermios *k)
+{
+       return copy_to_user(u, k, sizeof(struct termios));
+}
+#endif /* TCGETS2 */
+
 /**
  *     set_termios             -       set termios values for a tty
  *     @tty: terminal device