diff options
-rw-r--r-- | drivers/char/tty_ioctl.c | 58 | ||||
-rw-r--r-- | include/asm-x86/ioctls.h | 4 | ||||
-rw-r--r-- | include/linux/termios.h | 15 | ||||
-rw-r--r-- | include/linux/tty.h | 1 | ||||
-rw-r--r-- | include/linux/tty_driver.h | 9 |
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 | |||
595 | static 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 | |||
582 | static unsigned long inq_canon(struct tty_struct *tty) | 626 | static 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 | |||
9 | struct 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); |