aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2014-09-10 15:06:32 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-09-24 00:19:35 -0400
commit01adc80706f80a583948db6768c5571204cd5f99 (patch)
tree070bd77695ad97ee4d8541a4f97dc78d049a04d8 /drivers/tty
parentf9e053dcfc02b0ad29daec8524fb1afe09774976 (diff)
tty: Move packet mode flow control notifications to pty driver
When a master pty is set to packet mode, flow control changes to the slave pty cause notifications to the master pty via reads and polls. However, these tests are occurring for all ttys, not just ptys. Implement flow control packet mode notifications in the pty driver. Only the slave side implements the flow control handlers since packet mode is asymmetric; the master pty receives notifications for slave-side changes, but not vice versa. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/pty.c41
-rw-r--r--drivers/tty/tty_io.c31
2 files changed, 45 insertions, 27 deletions
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index 9bbdb1de12e2..7c4447a5c0f4 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -24,6 +24,7 @@
24#include <linux/devpts_fs.h> 24#include <linux/devpts_fs.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/mutex.h> 26#include <linux/mutex.h>
27#include <linux/poll.h>
27 28
28 29
29#ifdef CONFIG_UNIX98_PTYS 30#ifdef CONFIG_UNIX98_PTYS
@@ -313,6 +314,42 @@ done:
313} 314}
314 315
315/** 316/**
317 * pty_start - start() handler
318 * pty_stop - stop() handler
319 * @tty: tty being flow-controlled
320 *
321 * Propagates the TIOCPKT status to the master pty.
322 *
323 * NB: only the master pty can be in packet mode so only the slave
324 * needs start()/stop() handlers
325 */
326static void pty_start(struct tty_struct *tty)
327{
328 unsigned long flags;
329
330 spin_lock_irqsave(&tty->ctrl_lock, flags);
331 if (tty->link && tty->link->packet) {
332 tty->ctrl_status &= ~TIOCPKT_STOP;
333 tty->ctrl_status |= TIOCPKT_START;
334 wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
335 }
336 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
337}
338
339static void pty_stop(struct tty_struct *tty)
340{
341 unsigned long flags;
342
343 spin_lock_irqsave(&tty->ctrl_lock, flags);
344 if (tty->link && tty->link->packet) {
345 tty->ctrl_status &= ~TIOCPKT_START;
346 tty->ctrl_status |= TIOCPKT_STOP;
347 wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
348 }
349 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
350}
351
352/**
316 * pty_common_install - set up the pty pair 353 * pty_common_install - set up the pty pair
317 * @driver: the pty driver 354 * @driver: the pty driver
318 * @tty: the tty being instantiated 355 * @tty: the tty being instantiated
@@ -471,6 +508,8 @@ static const struct tty_operations slave_pty_ops_bsd = {
471 .set_termios = pty_set_termios, 508 .set_termios = pty_set_termios,
472 .cleanup = pty_cleanup, 509 .cleanup = pty_cleanup,
473 .resize = pty_resize, 510 .resize = pty_resize,
511 .start = pty_start,
512 .stop = pty_stop,
474 .remove = pty_remove 513 .remove = pty_remove
475}; 514};
476 515
@@ -646,6 +685,8 @@ static const struct tty_operations pty_unix98_ops = {
646 .chars_in_buffer = pty_chars_in_buffer, 685 .chars_in_buffer = pty_chars_in_buffer,
647 .unthrottle = pty_unthrottle, 686 .unthrottle = pty_unthrottle,
648 .set_termios = pty_set_termios, 687 .set_termios = pty_set_termios,
688 .start = pty_start,
689 .stop = pty_stop,
649 .shutdown = pty_unix98_shutdown, 690 .shutdown = pty_unix98_shutdown,
650 .cleanup = pty_cleanup, 691 .cleanup = pty_cleanup,
651}; 692};
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index b8ddfef6b5d8..c249ff1d51ce 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -908,8 +908,7 @@ void no_tty(void)
908 * stop_tty - propagate flow control 908 * stop_tty - propagate flow control
909 * @tty: tty to stop 909 * @tty: tty to stop
910 * 910 *
911 * Perform flow control to the driver. For PTY/TTY pairs we 911 * Perform flow control to the driver. May be called
912 * must also propagate the TIOCKPKT status. May be called
913 * on an already stopped device and will not re-call the driver 912 * on an already stopped device and will not re-call the driver
914 * method. 913 * method.
915 * 914 *
@@ -919,24 +918,14 @@ void no_tty(void)
919 * but not always. 918 * but not always.
920 * 919 *
921 * Locking: 920 * Locking:
922 * ctrl_lock
923 * flow_lock 921 * flow_lock
924 */ 922 */
925 923
926void __stop_tty(struct tty_struct *tty) 924void __stop_tty(struct tty_struct *tty)
927{ 925{
928 unsigned long flags;
929
930 if (tty->stopped) 926 if (tty->stopped)
931 return; 927 return;
932 tty->stopped = 1; 928 tty->stopped = 1;
933 spin_lock_irqsave(&tty->ctrl_lock, flags);
934 if (tty->link && tty->link->packet) {
935 tty->ctrl_status &= ~TIOCPKT_START;
936 tty->ctrl_status |= TIOCPKT_STOP;
937 wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
938 }
939 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
940 if (tty->ops->stop) 929 if (tty->ops->stop)
941 (tty->ops->stop)(tty); 930 (tty->ops->stop)(tty);
942} 931}
@@ -955,33 +944,21 @@ EXPORT_SYMBOL(stop_tty);
955 * start_tty - propagate flow control 944 * start_tty - propagate flow control
956 * @tty: tty to start 945 * @tty: tty to start
957 * 946 *
958 * Start a tty that has been stopped if at all possible. Perform 947 * Start a tty that has been stopped if at all possible. If this
959 * any necessary wakeups and propagate the TIOCPKT status. If this 948 * tty was previous stopped and is now being started, the driver
960 * is the tty was previous stopped and is being started then the 949 * start method is invoked and the line discipline woken.
961 * driver start method is invoked and the line discipline woken.
962 * 950 *
963 * Locking: 951 * Locking:
964 * ctrl_lock
965 * flow_lock 952 * flow_lock
966 */ 953 */
967 954
968void __start_tty(struct tty_struct *tty) 955void __start_tty(struct tty_struct *tty)
969{ 956{
970 unsigned long flags;
971
972 if (!tty->stopped || tty->flow_stopped) 957 if (!tty->stopped || tty->flow_stopped)
973 return; 958 return;
974 tty->stopped = 0; 959 tty->stopped = 0;
975 spin_lock_irqsave(&tty->ctrl_lock, flags);
976 if (tty->link && tty->link->packet) {
977 tty->ctrl_status &= ~TIOCPKT_STOP;
978 tty->ctrl_status |= TIOCPKT_START;
979 wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
980 }
981 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
982 if (tty->ops->start) 960 if (tty->ops->start)
983 (tty->ops->start)(tty); 961 (tty->ops->start)(tty);
984 /* If we have a running line discipline it may need kicking */
985 tty_wakeup(tty); 962 tty_wakeup(tty);
986} 963}
987 964