aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-10-13 05:38:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 12:51:40 -0400
commit1d65b4a088de407e99714fdc27862449db04fb5c (patch)
tree89f378767b9e0fe1a902d73bf43be382c6110f72
parent5aaa70a80f5bbfcc4d6a1f844bdd1c5d6b445b5f (diff)
tty: Add termiox
We need a way to describe the various additional modes and flow control features that random weird hardware shows up and software such as wine wants to emulate as Windows supports them. TCGETX/TCSETX and the termiox ioctl are a SYS5 extension that we might as well adopt. This patches adds the structures and the basic ioctl interfaces when the TCGETX etc defines are added for an architecture. Drivers wishing to use this stuff need to add new methods. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/char/tty_ioctl.c58
-rw-r--r--include/asm-x86/ioctls.h4
-rw-r--r--include/linux/termios.h15
-rw-r--r--include/linux/tty.h1
-rw-r--r--include/linux/tty_driver.h9
5 files changed, 87 insertions, 0 deletions
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index bf34e4597421..93bfa1d6cc92 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -579,6 +579,50 @@ static int get_termio(struct tty_struct *tty, struct termio __user *termio)
579 return 0; 579 return 0;
580} 580}
581 581
582
583#ifdef TCGETX
584
585/**
586 * set_termiox - set termiox fields if possible
587 * @tty: terminal
588 * @arg: termiox structure from user
589 * @opt: option flags for ioctl type
590 *
591 * Implement the device calling points for the SYS5 termiox ioctl
592 * interface in Linux
593 */
594
595static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
596{
597 struct termiox tnew;
598 struct tty_ldisc *ld;
599
600 if (tty->termiox == NULL)
601 return -EINVAL;
602 if (copy_from_user(&tnew, arg, sizeof(struct termiox)))
603 return -EFAULT;
604
605 ld = tty_ldisc_ref(tty);
606 if (ld != NULL) {
607 if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
608 ld->ops->flush_buffer(tty);
609 tty_ldisc_deref(ld);
610 }
611 if (opt & TERMIOS_WAIT) {
612 tty_wait_until_sent(tty, 0);
613 if (signal_pending(current))
614 return -EINTR;
615 }
616
617 mutex_lock(&tty->termios_mutex);
618 if (tty->ops->set_termiox)
619 tty->ops->set_termiox(tty, &tnew);
620 mutex_unlock(&tty->termios_mutex);
621 return 0;
622}
623
624#endif
625
582static unsigned long inq_canon(struct tty_struct *tty) 626static unsigned long inq_canon(struct tty_struct *tty)
583{ 627{
584 int nr, head, tail; 628 int nr, head, tail;
@@ -936,6 +980,20 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
936 return -EFAULT; 980 return -EFAULT;
937 return 0; 981 return 0;
938#endif 982#endif
983#ifdef TCGETX
984 case TCGETX:
985 if (real_tty->termiox == NULL)
986 return -EINVAL;
987 if (copy_to_user(p, real_tty->termiox, sizeof(struct termiox)))
988 return -EFAULT;
989 return 0;
990 case TCSETX:
991 return set_termiox(real_tty, p, 0);
992 case TCSETXW:
993 return set_termiox(real_tty, p, TERMIOS_WAIT);
994 case TCSETXF:
995 return set_termiox(real_tty, p, TERMIOS_FLUSH);
996#endif
939 case TIOCGSOFTCAR: 997 case TIOCGSOFTCAR:
940 /* FIXME: for correctness we may need to take the termios 998 /* FIXME: for correctness we may need to take the termios
941 lock here - review */ 999 lock here - review */
diff --git a/include/asm-x86/ioctls.h b/include/asm-x86/ioctls.h
index 1a8ac45b28be..06752a649044 100644
--- a/include/asm-x86/ioctls.h
+++ b/include/asm-x86/ioctls.h
@@ -56,6 +56,10 @@
56#define TIOCGPTN _IOR('T', 0x30, unsigned int) 56#define TIOCGPTN _IOR('T', 0x30, unsigned int)
57 /* Get Pty Number (of pty-mux device) */ 57 /* Get Pty Number (of pty-mux device) */
58#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ 58#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */
59#define TCGETX 0x5432 /* SYS5 TCGETX compatibility */
60#define TCSETX 0x5433
61#define TCSETXF 0x5434
62#define TCSETXW 0x5435
59 63
60#define FIONCLEX 0x5450 64#define FIONCLEX 0x5450
61#define FIOCLEX 0x5451 65#define FIOCLEX 0x5451
diff --git a/include/linux/termios.h b/include/linux/termios.h
index 478662889f48..2acd0c1f8a2a 100644
--- a/include/linux/termios.h
+++ b/include/linux/termios.h
@@ -4,4 +4,19 @@
4#include <linux/types.h> 4#include <linux/types.h>
5#include <asm/termios.h> 5#include <asm/termios.h>
6 6
7#define NFF 5
8
9struct termiox
10{
11 __u16 x_hflag;
12 __u16 x_cflag;
13 __u16 x_rflag[NFF];
14 __u16 x_sflag;
15};
16
17#define RTSXOFF 0x0001 /* RTS flow control on input */
18#define CTSXON 0x0002 /* CTS flow control on output */
19#define DTRXOFF 0x0004 /* DTR flow control on input */
20#define DSRXON 0x0008 /* DCD flow control on output */
21
7#endif 22#endif
diff --git a/include/linux/tty.h b/include/linux/tty.h
index b6e6c26883ee..b64d10b66548 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -219,6 +219,7 @@ struct tty_struct {
219 spinlock_t ctrl_lock; 219 spinlock_t ctrl_lock;
220 /* Termios values are protected by the termios mutex */ 220 /* Termios values are protected by the termios mutex */
221 struct ktermios *termios, *termios_locked; 221 struct ktermios *termios, *termios_locked;
222 struct termiox *termiox; /* May be NULL for unsupported */
222 char name[64]; 223 char name[64];
223 struct pid *pgrp; /* Protected by ctrl lock */ 224 struct pid *pgrp; /* Protected by ctrl lock */
224 struct pid *session; 225 struct pid *session;
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index 16d27944c321..ac6e58e26b73 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -180,6 +180,14 @@
180 * not force errors here if they are not resizable objects (eg a serial 180 * not force errors here if they are not resizable objects (eg a serial
181 * line). See tty_do_resize() if you need to wrap the standard method 181 * line). See tty_do_resize() if you need to wrap the standard method
182 * in your own logic - the usual case. 182 * in your own logic - the usual case.
183 *
184 * void (*set_termiox)(struct tty_struct *tty, struct termiox *new);
185 *
186 * Called when the device receives a termiox based ioctl. Passes down
187 * the requested data from user space. This method will not be invoked
188 * unless the tty also has a valid tty->termiox pointer.
189 *
190 * Optional: Called under the termios lock
183 */ 191 */
184 192
185#include <linux/fs.h> 193#include <linux/fs.h>
@@ -220,6 +228,7 @@ struct tty_operations {
220 unsigned int set, unsigned int clear); 228 unsigned int set, unsigned int clear);
221 int (*resize)(struct tty_struct *tty, struct tty_struct *real_tty, 229 int (*resize)(struct tty_struct *tty, struct tty_struct *real_tty,
222 struct winsize *ws); 230 struct winsize *ws);
231 int (*set_termiox)(struct tty_struct *tty, struct termiox *tnew);
223#ifdef CONFIG_CONSOLE_POLL 232#ifdef CONFIG_CONSOLE_POLL
224 int (*poll_init)(struct tty_driver *driver, int line, char *options); 233 int (*poll_init)(struct tty_driver *driver, int line, char *options);
225 int (*poll_get_char)(struct tty_driver *driver, int line); 234 int (*poll_get_char)(struct tty_driver *driver, int line);